option to use decimal format in user timesheet export (#1489)

This commit is contained in:
Kevin Papst
2020-02-24 18:03:30 +01:00
committed by GitHub
parent 0e507804b1
commit 34d2228d5d
13 changed files with 84 additions and 25 deletions

View File

@@ -35,7 +35,7 @@ class TimesheetFixtures extends Fixture implements DependentFixtureInterface
public const MIN_TIMESHEETS_PER_USER = 50; public const MIN_TIMESHEETS_PER_USER = 50;
public const MAX_TIMESHEETS_PER_USER = 500; public const MAX_TIMESHEETS_PER_USER = 500;
public const MAX_TIMESHEETS_TOTAL = 5000; public const MAX_TIMESHEETS_TOTAL = 5000;
public const MAX_RUNNING_TIMESHEETS_PER_USER = 2; public const MAX_RUNNING_TIMESHEETS_PER_USER = 1;
public const TIMERANGE_DAYS = 1095; // 3 years public const TIMERANGE_DAYS = 1095; // 3 years
public const TIMERANGE_RUNNING = 1047; // in minutes = 17:45 hours public const TIMERANGE_RUNNING = 1047; // in minutes = 17:45 hours
public const MIN_MINUTES_PER_ENTRY = 15; public const MIN_MINUTES_PER_ENTRY = 15;

View File

@@ -158,6 +158,12 @@ class UserPreferenceSubscriber implements EventSubscriberInterface
->setValue(false) ->setValue(false)
->setOrder(800) ->setOrder(800)
->setType(CheckboxType::class), ->setType(CheckboxType::class),
(new UserPreference())
->setName('timesheet.export_decimal')
->setValue(false)
->setOrder(900)
->setType(CheckboxType::class),
]; ];
} }

View File

@@ -53,6 +53,18 @@ class HtmlRenderer
return $event->getFields(); return $event->getFields();
} }
protected function getOptions(TimesheetQuery $query): array
{
$decimal = false;
if (null !== $query->getCurrentUser()) {
$decimal = (bool) $query->getCurrentUser()->getPreferenceValue('timesheet.export_decimal', $decimal);
} elseif (null !== $query->getUser()) {
$decimal = (bool) $query->getUser()->getPreferenceValue('timesheet.export_decimal', $decimal);
}
return ['decimal' => $decimal];
}
/** /**
* @param ExportItemInterface[] $timesheets * @param ExportItemInterface[] $timesheets
* @param TimesheetQuery $query * @param TimesheetQuery $query
@@ -75,7 +87,7 @@ class HtmlRenderer
$this->dispatcher->dispatch($event); $this->dispatcher->dispatch($event);
$userPreferences = $event->getPreferences(); $userPreferences = $event->getPreferences();
$content = $this->twig->render('export/renderer/default.html.twig', [ $content = $this->twig->render('export/renderer/default.html.twig', array_merge([
'entries' => $timesheets, 'entries' => $timesheets,
'query' => $query, 'query' => $query,
'summaries' => $this->calculateSummary($timesheets), 'summaries' => $this->calculateSummary($timesheets),
@@ -84,7 +96,7 @@ class HtmlRenderer
'projectMetaFields' => $projectMetaFields, 'projectMetaFields' => $projectMetaFields,
'activityMetaFields' => $activityMetaFields, 'activityMetaFields' => $activityMetaFields,
'userPreferences' => $userPreferences, 'userPreferences' => $userPreferences,
]); ], $this->getOptions($query)));
$response = new Response(); $response = new Response();
$response->setContent($content); $response->setContent($content);

View File

@@ -46,6 +46,18 @@ class PDFRenderer
return 'export/renderer/pdf.html.twig'; return 'export/renderer/pdf.html.twig';
} }
protected function getOptions(TimesheetQuery $query): array
{
$decimal = false;
if (null !== $query->getCurrentUser()) {
$decimal = (bool) $query->getCurrentUser()->getPreferenceValue('timesheet.export_decimal', $decimal);
} elseif (null !== $query->getUser()) {
$decimal = (bool) $query->getUser()->getPreferenceValue('timesheet.export_decimal', $decimal);
}
return ['decimal' => $decimal];
}
/** /**
* @param ExportItemInterface[] $timesheets * @param ExportItemInterface[] $timesheets
* @param TimesheetQuery $query * @param TimesheetQuery $query
@@ -56,12 +68,13 @@ class PDFRenderer
*/ */
public function render(array $timesheets, TimesheetQuery $query): Response public function render(array $timesheets, TimesheetQuery $query): Response
{ {
$content = $this->twig->render($this->getTemplate(), [ $content = $this->twig->render($this->getTemplate(), array_merge([
'entries' => $timesheets, 'entries' => $timesheets,
'query' => $query, 'query' => $query,
'now' => $this->dateTime->createDateTime(), 'now' => $this->dateTime->createDateTime(),
'summaries' => $this->calculateSummary($timesheets), 'summaries' => $this->calculateSummary($timesheets),
]); 'decimal' => false,
], $this->getOptions($query)));
$content = $this->converter->convertToPdf($content); $content = $this->converter->convertToPdf($content);

View File

@@ -34,6 +34,18 @@ final class HtmlRenderer implements TimesheetExportInterface
$this->dispatcher = $dispatcher; $this->dispatcher = $dispatcher;
} }
private function getOptions(TimesheetQuery $query): array
{
$decimal = false;
if (null !== $query->getCurrentUser()) {
$decimal = (bool) $query->getCurrentUser()->getPreferenceValue('timesheet.export_decimal', $decimal);
} elseif (null !== $query->getUser()) {
$decimal = (bool) $query->getUser()->getPreferenceValue('timesheet.export_decimal', $decimal);
}
return ['decimal' => $decimal];
}
/** /**
* @param Timesheet[] $timesheets * @param Timesheet[] $timesheets
* @param TimesheetQuery $query * @param TimesheetQuery $query
@@ -53,11 +65,12 @@ final class HtmlRenderer implements TimesheetExportInterface
$this->dispatcher->dispatch($event); $this->dispatcher->dispatch($event);
$timesheetMetaFields = $event->getFields(); $timesheetMetaFields = $event->getFields();
$content = $this->twig->render('timesheet/export.html.twig', [ $content = $this->twig->render('timesheet/export.html.twig', array_merge([
'entries' => $timesheets, 'entries' => $timesheets,
'query' => $query, 'query' => $query,
'metaColumns' => $timesheetMetaFields, 'metaColumns' => $timesheetMetaFields,
]); 'decimal' => false,
], $this->getOptions($query)));
$response = new Response(); $response = new Response();
$response->setContent($content); $response->setContent($content);

View File

@@ -2,6 +2,7 @@
{% import "macros/datatables.html.twig" as tables %} {% import "macros/datatables.html.twig" as tables %}
{% extends 'export/layout.html.twig' %} {% extends 'export/layout.html.twig' %}
{% set decimal = decimal|default(false) %}
{% set columnTitles = {} %} {% set columnTitles = {} %}
{% set columns = { {% set columns = {
'date': true, 'date': true,
@@ -201,7 +202,7 @@
{% if customer is not same as(summary.customer) %} {% if customer is not same as(summary.customer) %}
<tr class="summary"> <tr class="summary">
<td colspan="2"></td> <td colspan="2"></td>
<td class="totals duration summary-duration">{{ customerDuration|duration }}</td> <td class="totals duration summary-duration">{{ customerDuration|duration(decimal) }}</td>
<td class="totals cost summary-rate">{{ customerRate|money(customerCurrency) }}</td> <td class="totals cost summary-rate">{{ customerRate|money(customerCurrency) }}</td>
</tr> </tr>
{% set customerCurrency = summary.currency %} {% set customerCurrency = summary.currency %}
@@ -212,7 +213,7 @@
<tr> <tr>
<td>{{ summary.customer }}</td> <td>{{ summary.customer }}</td>
<td>{{ summary.project }}</td> <td>{{ summary.project }}</td>
<td class="duration summary-duration">{{ summary.duration|duration }}</td> <td class="duration summary-duration">{{ summary.duration|duration(decimal) }}</td>
<td class="cost summary-rate">{{ summary.rate|money(summary.currency) }}</td> <td class="cost summary-rate">{{ summary.rate|money(summary.currency) }}</td>
</tr> </tr>
{% set customerDuration = customerDuration + summary.duration %} {% set customerDuration = customerDuration + summary.duration %}
@@ -221,7 +222,7 @@
{% if customer is not same as(null) %} {% if customer is not same as(null) %}
<tr class="summary"> <tr class="summary">
<td colspan="2"></td> <td colspan="2"></td>
<td class="totals duration summary-duration">{{ customerDuration|duration }}</td> <td class="totals duration summary-duration">{{ customerDuration|duration(decimal) }}</td>
<td class="totals cost summary-rate">{{ customerRate|money(customerCurrency) }}</td> <td class="totals cost summary-rate">{{ customerRate|money(customerCurrency) }}</td>
</tr> </tr>
{% endif %} {% endif %}
@@ -251,7 +252,7 @@
{% if customer is not same as(summary.customer) %} {% if customer is not same as(summary.customer) %}
<tr class="summary"> <tr class="summary">
<td colspan="3"></td> <td colspan="3"></td>
<td class="totals duration summary-duration">{{ customerDuration|duration }}</td> <td class="totals duration summary-duration">{{ customerDuration|duration(decimal) }}</td>
<td class="totals cost summary-rate">{{ customerRate|money(customerCurrency) }}</td> <td class="totals cost summary-rate">{{ customerRate|money(customerCurrency) }}</td>
</tr> </tr>
{% set customerCurrency = summary.currency %} {% set customerCurrency = summary.currency %}
@@ -264,7 +265,7 @@
<td>{{ summary.customer }}</td> <td>{{ summary.customer }}</td>
<td>{{ summary.project }}</td> <td>{{ summary.project }}</td>
<td>{{ activitySummary.activity }}</td> <td>{{ activitySummary.activity }}</td>
<td class="duration summary-duration">{{ activitySummary.duration|duration }}</td> <td class="duration summary-duration">{{ activitySummary.duration|duration(decimal) }}</td>
<td class="cost summary-rate">{{ activitySummary.rate|money(activitySummary.currency) }}</td> <td class="cost summary-rate">{{ activitySummary.rate|money(activitySummary.currency) }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
@@ -274,7 +275,7 @@
{% if customer is not same as(null) %} {% if customer is not same as(null) %}
<tr class="summary"> <tr class="summary">
<td colspan="3"></td> <td colspan="3"></td>
<td class="totals duration summary-duration">{{ customerDuration|duration }}</td> <td class="totals duration summary-duration">{{ customerDuration|duration(decimal) }}</td>
<td class="totals cost summary-rate">{{ customerRate|money(customerCurrency) }}</td> <td class="totals cost summary-rate">{{ customerRate|money(customerCurrency) }}</td>
</tr> </tr>
{% endif %} {% endif %}
@@ -384,7 +385,7 @@
{{ entry.fixedRate|money(entry.project.customer.currency) }} {{ entry.fixedRate|money(entry.project.customer.currency) }}
</td> </td>
<td class="column-duration text-nowrap" {% if not columns.duration %}style="display: none"{% endif %}> <td class="column-duration text-nowrap" {% if not columns.duration %}style="display: none"{% endif %}>
{{ entry.duration|duration }} {{ entry.duration|duration(decimal) }}
</td> </td>
<td class="column-rate text-nowrap" {% if not columns.rate %}style="display: none"{% endif %}> <td class="column-rate text-nowrap" {% if not columns.rate %}style="display: none"{% endif %}>
{{ entry.rate|money(entry.project.customer.currency) }} {{ entry.rate|money(entry.project.customer.currency) }}
@@ -399,7 +400,7 @@
{% endif %} {% endif %}
{% endfor %} {% endfor %}
<th class="text-nowrap column-duration"> <th class="text-nowrap column-duration">
{{- timeWorked|duration -}} {{- timeWorked|duration(decimal) -}}
</th> </th>
<th class="text-nowrap column-rate"> <th class="text-nowrap column-rate">
{%- if currency is not null and currency is not same as(false) %} {%- if currency is not null and currency is not same as(false) %}

View File

@@ -1,5 +1,6 @@
{% set showUserColumn = true %} {% set showUserColumn = true %}
{% set showRateColumn = true %} {% set showRateColumn = true %}
{% set decimal = decimal|default(false) %}
{% if query.user %} {% if query.user %}
{# this is only triggered, if a user exports from his personal timesheet screen#} {# this is only triggered, if a user exports from his personal timesheet screen#}
{% set showUserColumn = false %} {% set showUserColumn = false %}
@@ -106,7 +107,7 @@ mpdf-->
{% if customer is not same as(summary.customer) %} {% if customer is not same as(summary.customer) %}
<tr class="summary"> <tr class="summary">
<td colspan="2"></td> <td colspan="2"></td>
<td class="totals duration">{{ customerDuration|duration }}</td> <td class="totals duration">{{ customerDuration|duration(decimal) }}</td>
{% if showRateColumn %} {% if showRateColumn %}
<td class="totals cost">{{ customerRate|money(customerCurrency) }}</td> <td class="totals cost">{{ customerRate|money(customerCurrency) }}</td>
{% endif %} {% endif %}
@@ -120,7 +121,7 @@ mpdf-->
<tr class="{{ cycle(['odd', 'even'], customerCount) }}"> <tr class="{{ cycle(['odd', 'even'], customerCount) }}">
<td>{{ summary.customer }}</td> <td>{{ summary.customer }}</td>
<td>{{ summary.project }}</td> <td>{{ summary.project }}</td>
<td class="duration">{{ summary.duration|duration }}</td> <td class="duration">{{ summary.duration|duration(decimal) }}</td>
{% if showRateColumn %} {% if showRateColumn %}
<td class="cost">{{ summary.rate|money(summary.currency) }}</td> <td class="cost">{{ summary.rate|money(summary.currency) }}</td>
{% endif %} {% endif %}
@@ -132,7 +133,7 @@ mpdf-->
{% if customer is not same as(null) %} {% if customer is not same as(null) %}
<tr class="summary"> <tr class="summary">
<td colspan="2"></td> <td colspan="2"></td>
<td class="totals duration">{{ customerDuration|duration }}</td> <td class="totals duration">{{ customerDuration|duration(decimal) }}</td>
{% if showRateColumn %} {% if showRateColumn %}
<td class="totals cost">{{ customerRate|money(customerCurrency) }}</td> <td class="totals cost">{{ customerRate|money(customerCurrency) }}</td>
{% endif %} {% endif %}
@@ -189,7 +190,7 @@ mpdf-->
<i>{{ entry.description|escape|desc2html }}</i> <i>{{ entry.description|escape|desc2html }}</i>
{% endif %} {% endif %}
</td> </td>
<td class="duration">{{ entry.duration|duration }}</td> <td class="duration">{{ entry.duration|duration(decimal) }}</td>
{% if showRateColumn %} {% if showRateColumn %}
<td class="cost"> <td class="cost">
{% if is_granted('view_rate', entry) %} {% if is_granted('view_rate', entry) %}
@@ -208,7 +209,7 @@ mpdf-->
{% else %} {% else %}
<td colspan="2"></td> <td colspan="2"></td>
{% endif %} {% endif %}
<td class="totals duration">{{ duration|duration }}</td> <td class="totals duration">{{ duration|duration(decimal) }}</td>
{% if showRateColumn %} {% if showRateColumn %}
<td class="totals cost">{% if currency is not null %}{{ rate|money(currency) }}{% endif %}</td> <td class="totals cost">{% if currency is not null %}{{ rate|money(currency) }}{% endif %}</td>
{% endif %} {% endif %}

View File

@@ -38,6 +38,10 @@
{% set actions = actions|merge({'repeat': {'url': path('restart_timesheet', {'id' : timesheet.id}), 'class': 'api-link', 'attr': {'data-payload': '{"copy": "all"}', 'data-event': 'kimai.timesheetStart kimai.timesheetUpdate', 'data-method': 'PATCH', 'data-msg-error': 'timesheet.start.error', 'data-msg-success': 'timesheet.start.success'}}}) %} {% set actions = actions|merge({'repeat': {'url': path('restart_timesheet', {'id' : timesheet.id}), 'class': 'api-link', 'attr': {'data-payload': '{"copy": "all"}', 'data-event': 'kimai.timesheetStart kimai.timesheetUpdate', 'data-method': 'PATCH', 'data-msg-error': 'timesheet.start.error', 'data-msg-success': 'timesheet.start.success'}}}) %}
{% endif %} {% endif %}
{% if is_granted('duplicate', timesheet) %}
{% set actions = actions|merge({'copy': {'url': path('duplicate_timesheet', {'id' : timesheet.id}), 'class': 'api-link', 'attr': {'data-payload': '{"copy": "all"}', 'data-event': 'kimai.timesheetStart kimai.timesheetUpdate', 'data-method': 'PATCH', 'data-msg-error': 'action.update.error', 'data-msg-success': 'action.update.success'}}}) %}
{% endif %}
{% if is_granted('edit', timesheet) %} {% if is_granted('edit', timesheet) %}
{% set class = '' %} {% set class = '' %}
{% if view != 'edit' %} {% if view != 'edit' %}

View File

@@ -40,7 +40,7 @@
{% endif %} {% endif %}
{% if is_granted('duplicate', timesheet) %} {% if is_granted('duplicate', timesheet) %}
{% set actions = actions|merge({'copy': {'url': path('duplicate_timesheet', {'id' : timesheet.id}), 'class': 'api-link', 'attr': {'data-payload': '{"copy": "all"}', 'data-event': 'kimai.timesheetStart kimai.timesheetUpdate', 'data-method': 'PATCH', 'data-msg-error': 'timesheet.update.error', 'data-msg-success': 'timesheet.update.success'}}}) %} {% set actions = actions|merge({'copy': {'url': path('duplicate_timesheet', {'id' : timesheet.id}), 'class': 'api-link', 'attr': {'data-payload': '{"copy": "all"}', 'data-event': 'kimai.timesheetStart kimai.timesheetUpdate', 'data-method': 'PATCH', 'data-msg-error': 'action.update.error', 'data-msg-success': 'action.update.success'}}}) %}
{% endif %} {% endif %}
{% if is_granted('edit', timesheet) %} {% if is_granted('edit', timesheet) %}

View File

@@ -4,6 +4,7 @@
{% block title %}{{ 'menu.export'|trans }}{% endblock %} {% block title %}{{ 'menu.export'|trans }}{% endblock %}
{% block invoice %} {% block invoice %}
{% set decimal = decimal|default(false) %}
{% set showUserColumn = true %} {% set showUserColumn = true %}
{% if query.user %} {% if query.user %}
{% set showUserColumn = false %} {% set showUserColumn = false %}
@@ -72,7 +73,7 @@
{% for field in metaColumns %} {% for field in metaColumns %}
<td>{{ tables.datatable_meta_column(entry, field) }}</td> <td>{{ tables.datatable_meta_column(entry, field) }}</td>
{% endfor %} {% endfor %}
<td class="text-nowrap">{{ entry.duration|duration }}</td> <td class="text-nowrap">{{ entry.duration|duration(decimal) }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
@@ -86,7 +87,7 @@
<th></th> <th></th>
{% endfor %} {% endfor %}
<th>{{ 'invoice.total_working_time'|trans }}</th> <th>{{ 'invoice.total_working_time'|trans }}</th>
<th class="text-nowrap">{{ timeWorked|duration }}</th> <th class="text-nowrap">{{ timeWorked|duration(decimal) }}</th>
</tr> </tr>
</tfoot> </tfoot>
</table> </table>

View File

@@ -1,8 +1,8 @@
{% extends 'base.html.twig' %} {% extends 'base.html.twig' %}
{% import "user/actions.html.twig" as actions %} {% import "user/actions.html.twig" as actions %}
{% block page_title %}{{ 'profile.title'|trans }}{% endblock %} {% block page_title %}{% if not user.alias is empty %}{{ user.alias }}{% else %}{{ user.username }}{% endif %}{% endblock %}
{% block page_subtitle %}{% if not user.alias is empty %}{{ user.alias }} - {% endif %}{{ user.username }}{% endblock %} {% block page_subtitle %}{% if not user.alias is empty %}{{ user.username }}{% endif %}{% endblock %}
{% block page_actions %}{{ actions.user(user, tab) }}{% endblock %} {% block page_actions %}{{ actions.user(user, tab) }}{% endblock %}
{% block main %} {% block main %}

View File

@@ -505,6 +505,10 @@
<source>label.timesheet.daily_stats</source> <source>label.timesheet.daily_stats</source>
<target>Tägliche Statistiken im Timesheet anzeigen</target> <target>Tägliche Statistiken im Timesheet anzeigen</target>
</trans-unit> </trans-unit>
<trans-unit id="label.timesheet.export_decimal">
<source>label.timesheet.export_decimal</source>
<target>Dezimal Format für Export nutzen</target>
</trans-unit>
<!-- <!--
User timesheet calendar User timesheet calendar

View File

@@ -505,6 +505,10 @@
<source>label.timesheet.daily_stats</source> <source>label.timesheet.daily_stats</source>
<target>Show daily stats in timesheet</target> <target>Show daily stats in timesheet</target>
</trans-unit> </trans-unit>
<trans-unit id="label.timesheet.export_decimal">
<source>label.timesheet.export_decimal</source>
<target>Use decimal duration in export</target>
</trans-unit>
<!-- <!--
User timesheet calendar User timesheet calendar