support different formats in user timesheet exports (#1222)
This commit is contained in:
@@ -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 %}
|
||||
–
|
||||
{{ '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 }} – {{ 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 %}
|
||||
–
|
||||
{% 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>
|
||||
|
||||
@@ -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) }}
|
||||
<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>
|
||||
|
||||
@@ -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') %}
|
||||
|
||||
@@ -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 %}
|
||||
@@ -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') %}
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
Reference in New Issue
Block a user