support different formats in user timesheet exports (#1222)

This commit is contained in:
Kevin Papst
2019-11-08 16:10:38 +01:00
committed by GitHub
parent 0705c26513
commit fa1c79e15c
75 changed files with 1872 additions and 951 deletions

View File

@@ -1,3 +1,11 @@
{% set showUserColumn = true %}
{% set showRateColumn = true %}
{% if query.user %}
{# this is only triggered, if a user exports from his personal timesheet screen#}
{% set showUserColumn = false %}
{% set showRateColumn = is_granted('view_rate_own_timesheet') %}
{# TODO if exporting via the admin screen, users without view_rate_own_timesheet might still see their own rates, maybe merge view_rate_own_timesheet and view_rate_other_timesheet into a new view_rate permission? #}
{% endif %}
<html>
<head>
<style>
@@ -48,9 +56,17 @@
<tr>
<td align="left">
{{ 'export.page_of'|trans({'%page%': '{PAGENO}', '%pages%': '{nb}'}) }}
{% if not showUserColumn %}
&ndash;
{{ 'label.user'|trans }}: {{ query.user.displayName }}
{% endif %}
</td>
<td align="right">
{{ 'export.date_copyright'|trans({'%date%': now|date_short ~ ' ' ~ now|date('H:i'), '%kimai%': '<a href="' ~ constant('App\\Constants::HOMEPAGE') ~ '">' ~ constant('App\\Constants::SOFTWARE') ~ '</a>'})|raw }}
{% if kimai_context.branding.company is not empty %}
{{ kimai_context.branding.company }} &ndash; {{ now|date_full }}
{% else %}
{{ 'export.date_copyright'|trans({'%date%': now|date_full, '%kimai%': '<a href="' ~ constant('App\\Constants::HOMEPAGE') ~ '">' ~ constant('App\\Constants::SOFTWARE') ~ '</a>'})|raw }}
{% endif %}
</td>
</tr>
</table>
@@ -62,6 +78,7 @@ mpdf-->
{{ 'export.period'|trans }}:
{{ query.begin|date_short }} - {{ query.end|date_short }}
</p>
<h3>{{ 'export.summary'|trans }}</h3>
<table class="items" width="100%" style="font-size: 9pt; border-collapse: collapse; " cellpadding="8">
<thead>
@@ -69,7 +86,9 @@ mpdf-->
<td>{{ 'label.customer'|trans }}</td>
<td>{{ 'label.project'|trans }}</td>
<td>{{ 'label.duration'|trans }}</td>
{% if showRateColumn %}
<td>{{ 'label.rate'|trans }}</td>
{% endif %}
</tr>
</thead>
<tbody>
@@ -87,7 +106,9 @@ mpdf-->
<tr class="summary">
<td colspan="2"></td>
<td class="totals duration">{{ customerDuration|duration }}</td>
{% if showRateColumn %}
<td class="totals cost">{{ customerRate|money(customerCurrency) }}</td>
{% endif %}
</tr>
{% set customerCurrency = summary.currency %}
{% set customer = summary.customer %}
@@ -99,7 +120,9 @@ mpdf-->
<td>{{ summary.customer }}</td>
<td>{{ summary.project }}</td>
<td class="duration">{{ summary.duration|duration }}</td>
{% if showRateColumn %}
<td class="cost">{{ summary.rate|money(summary.currency) }}</td>
{% endif %}
</tr>
{% set customerDuration = customerDuration + summary.duration %}
{% set customerRate = customerRate + summary.rate %}
@@ -109,7 +132,9 @@ mpdf-->
<tr class="summary">
<td colspan="2"></td>
<td class="totals duration">{{ customerDuration|duration }}</td>
{% if showRateColumn %}
<td class="totals cost">{{ customerRate|money(customerCurrency) }}</td>
{% endif %}
</tr>
{% endif %}
</tbody>
@@ -126,15 +151,19 @@ mpdf-->
<thead>
<tr>
<td>{{ 'label.date'|trans }}</td>
{% if showUserColumn %}
<td>{{ 'label.user'|trans }}</td>
{% endif %}
<td width="">{{ 'label.description'|trans }}</td>
<td>{{ 'label.duration'|trans }}</td>
{% if showRateColumn %}
<td>{{ 'label.rate'|trans }}</td>
{% endif %}
</tr>
</thead>
<tbody>
{% for entry in entries %}
{% set duration = duration + entry.duration %}
{% set rate = rate + entry.rate %}
{% if currency is same as(false) %}
{% set currency = entry.project.customer.currency %}
{% endif %}
@@ -149,6 +178,9 @@ mpdf-->
{{ entry.end|date_time }}
{% endif %}
</td>
{% if showUserColumn %}
<td>{{ entry.user.displayName }}</td>
{% endif %}
<td>
{{ entry.project.customer.name }} - {{ entry.project.name }} - {{ entry.activity.name }}
{% if entry.description is not empty %}
@@ -157,13 +189,28 @@ mpdf-->
{% endif %}
</td>
<td class="duration">{{ entry.duration|duration }}</td>
<td class="cost">{{ entry.rate|money(entry.project.customer.currency) }}</td>
{% if showRateColumn %}
<td class="cost">
{% if is_granted('view_rate', entry) %}
{% set rate = rate + entry.rate %}
{{ entry.rate|money(entry.project.customer.currency) }}
{% else %}
&ndash;
{% endif %}
</td>
{% endif %}
</tr>
{% endfor %}
<tr class="summary">
{% if showUserColumn %}
<td colspan="3"></td>
{% else %}
<td colspan="2"></td>
{% endif %}
<td class="totals duration">{{ duration|duration }}</td>
{% if showRateColumn %}
<td class="totals cost">{{ rate|money(currency) }}</td>
{% endif %}
</tr>
</tbody>
</table>

View File

@@ -301,7 +301,22 @@
<div class="btn-group">
{%- apply spaceless -%}
{%- for icon,values in actions %}
{{ macro.action_button(icon, values, type) }}
{% if values.children is defined %}
<div class="btn-group">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
{{ macro.icon(icon) }}&nbsp;
<span class="caret"></span>
<span class="sr-only">{{ 'label.toggle_dropdown'|trans }}</span>
</button>
<ul class="dropdown-menu" role="menu">
{% for childIcon,childValues in values.children %}
<li>{{ macro.action_button(childIcon, childValues, false) }}</li>
{% endfor %}
</ul>
</div>
{% else %}
{{ macro.action_button(icon, values, type) }}
{% endif %}
{% endfor -%}
{% endapply %}
</div>

View File

@@ -3,7 +3,16 @@
{% set actions = {'search': {'class': 'search-toggle visible-xs-inline'}} %}
{% if is_granted('export_own_timesheet') %}
{% set actions = actions|merge({'download': {'url': path('admin_timesheet_export'), 'class': 'toolbar-action'}}) %}
{% set exporterIds = timesheet_exporter() %}
{% if exporterIds|length == 1 %}
{% set actions = actions|merge({'download': {'url': path('admin_timesheet_export', {'exporter': exporterIds.0}), 'class': 'toolbar-action'}}) %}
{% elseif exporterIds|length > 1 %}
{% set children = {} %}
{% for exporter in exporterIds %}
{% set children = children|merge({(exporter): {'title': ('button.' ~ exporter)|trans, 'url': path('admin_timesheet_export', {'exporter': exporter}), 'class': 'toolbar-action exporter-' ~ exporter}}) %}
{% endfor %}
{% set actions = actions|merge({'download': {'children': children}}) %}
{% endif %}
{% endif %}
{% set actions = actions|merge({'visibility': '#modal_timesheet_admin'}) %}
{% if is_granted('create_other_timesheet') %}

View File

@@ -1,91 +0,0 @@
{% import "macros/widgets.html.twig" as widgets %}
{% import "macros/datatables.html.twig" as tables %}
{% extends 'invoice/layout.html.twig' %}
{% block invoice %}
<div class="row">
<div class="col-xs-12">
<h2 class="page-header">
<span contenteditable="true">
{% if query.begin is not empty and query.end is not empty %}
{% if query.begin|date('m') != query.end|date('m') or query.begin|date('Y') != query.end|date('Y') %}
{{ query.begin|date_short }} - {{ query.end|date_short }}
{% elseif query.end is not empty %}
{{ query.end|month_name|trans }} {{ query.end|date('Y') }}
{% elseif query.begin is not empty %}
{{ query.begin|month_name|trans }} {{ query.begin|date('Y') }}
{% endif %}
{% endif %}
{% if query.user is not empty %}
: {{ widgets.username(query.user) }}
{% endif %}
</span>
</h2>
</div>
</div>
<div class="row">
<div class="col-xs-12 table-responsive">
<table class="table">
<thead>
<tr>
<th>{{ 'label.date'|trans }}</th>
{% if query.user is empty %}
<th>{{ 'label.username'|trans }}</th>
{% endif %}
<th>{{ 'label.description'|trans }}</th>
{% for field in metaColumns %}
<th>{{ field.label|trans }}</th>
{% endfor %}
<th>{{ 'label.hours'|trans }}</th>
</tr>
</thead>
<tbody>
{% set timeWorked = 0 %}
{% for entry in entries %}
{% set timeWorked = timeWorked + entry.duration %}
<tr>
<td class="text-nowrap">{{ entry.begin|date_short }}</td>
{% if query.user is empty %}
<td>{{ widgets.username(entry.user) }}</td>
{% endif %}
<td>
{% if entry.description is not empty %}
<div>
{{ entry.description|escape|desc2html }}
</div>
{% endif %}
<span class="small">
{{ 'label.activity'|trans }}: {{ entry.activity.name }} |
{{ 'label.project'|trans }}: {{ entry.project.name }} |
{{ 'label.customer'|trans }}: {{ entry.project.customer.name }}
</span>
</td>
{% for field in metaColumns %}
<td>{{ tables.datatable_meta_column(entry, field) }}</td>
{% endfor %}
<td class="text-nowrap">{{ entry.duration|duration }}</td>
</tr>
{% endfor %}
</tbody>
<tfoot>
<tr>
<th></th>
{% if query.user is empty %}
<th></th>
{% endif %}
{% for field in metaColumns %}
<th></th>
{% endfor %}
<th>{{ 'invoice.total_working_time'|trans }}</th>
<th>{{ timeWorked|duration }}</th>
</tr>
</tfoot>
</table>
</div>
</div>
{% endblock %}
{% block print_button %}{% endblock %}

View File

@@ -3,7 +3,16 @@
{% set actions = {'search': {'class': 'search-toggle visible-xs-inline'}} %}
{% if is_granted('export_own_timesheet') %}
{% set actions = actions|merge({'download': {'url': path('timesheet_export'), 'class': 'toolbar-action'}}) %}
{% set exporterIds = timesheet_exporter() %}
{% if exporterIds|length == 1 %}
{% set actions = actions|merge({'download': {'url': path('timesheet_export', {'exporter': exporterIds.0}), 'class': 'toolbar-action'}}) %}
{% elseif exporterIds|length > 1 %}
{% set children = {} %}
{% for exporter in exporterIds %}
{% set children = children|merge({(exporter): {'title': ('button.' ~ exporter)|trans, 'url': path('timesheet_export', {'exporter': exporter}), 'class': 'toolbar-action exporter-' ~ exporter}}) %}
{% endfor %}
{% set actions = actions|merge({'download': {'children': children}}) %}
{% endif %}
{% endif %}
{% set actions = actions|merge({'visibility': {'modal': '#modal_timesheet'}}) %}
{% if is_granted('create_own_timesheet') %}

View File

@@ -3,6 +3,10 @@
{% extends 'invoice/layout.html.twig' %}
{% block invoice %}
{% set showUserColumn = true %}
{% if query.user %}
{% set showUserColumn = false %}
{% endif %}
<div class="row">
<div class="col-xs-12">
@@ -10,16 +14,20 @@
<span contenteditable="true">
{% if query.begin is not empty and query.end is not empty %}
{% if query.begin|date('m') != query.end|date('m') or query.begin|date('Y') != query.end|date('Y') %}
{{ query.begin|date_short }} - {{ query.end|date_short }}:
{{ query.begin|date_short }} - {{ query.end|date_short }}
{% elseif query.end is not empty %}
{{ query.end|month_name|trans }} {{ query.end|date('Y') }}:
{{ query.end|month_name|trans }} {{ query.end|date('Y') }}
{% elseif query.begin is not empty %}
{{ query.begin|month_name|trans }} {{ query.begin|date('Y') }}:
{{ query.begin|month_name|trans }} {{ query.begin|date('Y') }}
{% endif %}
{% endif %}
{{ widgets.username(query.user) }}
</span>
</h2>
{% if not showUserColumn %}
<p>
{{ 'label.user'|trans }}: {{ widgets.username(query.user) }}
</p>
{% endif %}
</div>
</div>
@@ -29,6 +37,9 @@
<thead>
<tr>
<th>{{ 'label.date'|trans }}</th>
{% if showUserColumn %}
<th>{{ 'label.username'|trans }}</th>
{% endif %}
<th>{{ 'label.description'|trans }}</th>
{% for field in metaColumns %}
<th>{{ field.label|trans }}</th>
@@ -42,11 +53,14 @@
{% set timeWorked = timeWorked + entry.duration %}
<tr>
<td class="text-nowrap">{{ entry.begin|date_short }}</td>
{% if showUserColumn %}
<td>{{ widgets.username(entry.user) }}</td>
{% endif %}
<td>
{% if entry.description is not empty %}
<div>
{{ entry.description|escape|desc2html }}
</div>
<div>
{{ entry.description|escape|desc2html }}
</div>
{% endif %}
<span class="small">
{{ 'label.activity'|trans }}: {{ entry.activity.name }} |
@@ -64,6 +78,9 @@
<tfoot>
<tr>
<th></th>
{% if showUserColumn %}
<th></th>
{% endif %}
{% for field in metaColumns %}
<th></th>
{% endfor %}