option to use decimal format in user timesheet export (#1489)
This commit is contained in:
@@ -35,7 +35,7 @@ class TimesheetFixtures extends Fixture implements DependentFixtureInterface
|
||||
public const MIN_TIMESHEETS_PER_USER = 50;
|
||||
public const MAX_TIMESHEETS_PER_USER = 500;
|
||||
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_RUNNING = 1047; // in minutes = 17:45 hours
|
||||
public const MIN_MINUTES_PER_ENTRY = 15;
|
||||
|
||||
@@ -158,6 +158,12 @@ class UserPreferenceSubscriber implements EventSubscriberInterface
|
||||
->setValue(false)
|
||||
->setOrder(800)
|
||||
->setType(CheckboxType::class),
|
||||
|
||||
(new UserPreference())
|
||||
->setName('timesheet.export_decimal')
|
||||
->setValue(false)
|
||||
->setOrder(900)
|
||||
->setType(CheckboxType::class),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -53,6 +53,18 @@ class HtmlRenderer
|
||||
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 TimesheetQuery $query
|
||||
@@ -75,7 +87,7 @@ class HtmlRenderer
|
||||
$this->dispatcher->dispatch($event);
|
||||
$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,
|
||||
'query' => $query,
|
||||
'summaries' => $this->calculateSummary($timesheets),
|
||||
@@ -84,7 +96,7 @@ class HtmlRenderer
|
||||
'projectMetaFields' => $projectMetaFields,
|
||||
'activityMetaFields' => $activityMetaFields,
|
||||
'userPreferences' => $userPreferences,
|
||||
]);
|
||||
], $this->getOptions($query)));
|
||||
|
||||
$response = new Response();
|
||||
$response->setContent($content);
|
||||
|
||||
@@ -46,6 +46,18 @@ class PDFRenderer
|
||||
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 TimesheetQuery $query
|
||||
@@ -56,12 +68,13 @@ class PDFRenderer
|
||||
*/
|
||||
public function render(array $timesheets, TimesheetQuery $query): Response
|
||||
{
|
||||
$content = $this->twig->render($this->getTemplate(), [
|
||||
$content = $this->twig->render($this->getTemplate(), array_merge([
|
||||
'entries' => $timesheets,
|
||||
'query' => $query,
|
||||
'now' => $this->dateTime->createDateTime(),
|
||||
'summaries' => $this->calculateSummary($timesheets),
|
||||
]);
|
||||
'decimal' => false,
|
||||
], $this->getOptions($query)));
|
||||
|
||||
$content = $this->converter->convertToPdf($content);
|
||||
|
||||
|
||||
@@ -34,6 +34,18 @@ final class HtmlRenderer implements TimesheetExportInterface
|
||||
$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 TimesheetQuery $query
|
||||
@@ -53,11 +65,12 @@ final class HtmlRenderer implements TimesheetExportInterface
|
||||
$this->dispatcher->dispatch($event);
|
||||
$timesheetMetaFields = $event->getFields();
|
||||
|
||||
$content = $this->twig->render('timesheet/export.html.twig', [
|
||||
$content = $this->twig->render('timesheet/export.html.twig', array_merge([
|
||||
'entries' => $timesheets,
|
||||
'query' => $query,
|
||||
'metaColumns' => $timesheetMetaFields,
|
||||
]);
|
||||
'decimal' => false,
|
||||
], $this->getOptions($query)));
|
||||
|
||||
$response = new Response();
|
||||
$response->setContent($content);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
{% import "macros/datatables.html.twig" as tables %}
|
||||
{% extends 'export/layout.html.twig' %}
|
||||
|
||||
{% set decimal = decimal|default(false) %}
|
||||
{% set columnTitles = {} %}
|
||||
{% set columns = {
|
||||
'date': true,
|
||||
@@ -201,7 +202,7 @@
|
||||
{% if customer is not same as(summary.customer) %}
|
||||
<tr class="summary">
|
||||
<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>
|
||||
</tr>
|
||||
{% set customerCurrency = summary.currency %}
|
||||
@@ -212,7 +213,7 @@
|
||||
<tr>
|
||||
<td>{{ summary.customer }}</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>
|
||||
</tr>
|
||||
{% set customerDuration = customerDuration + summary.duration %}
|
||||
@@ -221,7 +222,7 @@
|
||||
{% if customer is not same as(null) %}
|
||||
<tr class="summary">
|
||||
<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>
|
||||
</tr>
|
||||
{% endif %}
|
||||
@@ -251,7 +252,7 @@
|
||||
{% if customer is not same as(summary.customer) %}
|
||||
<tr class="summary">
|
||||
<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>
|
||||
</tr>
|
||||
{% set customerCurrency = summary.currency %}
|
||||
@@ -264,7 +265,7 @@
|
||||
<td>{{ summary.customer }}</td>
|
||||
<td>{{ summary.project }}</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>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
@@ -274,7 +275,7 @@
|
||||
{% if customer is not same as(null) %}
|
||||
<tr class="summary">
|
||||
<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>
|
||||
</tr>
|
||||
{% endif %}
|
||||
@@ -384,7 +385,7 @@
|
||||
{{ entry.fixedRate|money(entry.project.customer.currency) }}
|
||||
</td>
|
||||
<td class="column-duration text-nowrap" {% if not columns.duration %}style="display: none"{% endif %}>
|
||||
{{ entry.duration|duration }}
|
||||
{{ entry.duration|duration(decimal) }}
|
||||
</td>
|
||||
<td class="column-rate text-nowrap" {% if not columns.rate %}style="display: none"{% endif %}>
|
||||
{{ entry.rate|money(entry.project.customer.currency) }}
|
||||
@@ -399,7 +400,7 @@
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<th class="text-nowrap column-duration">
|
||||
{{- timeWorked|duration -}}
|
||||
{{- timeWorked|duration(decimal) -}}
|
||||
</th>
|
||||
<th class="text-nowrap column-rate">
|
||||
{%- if currency is not null and currency is not same as(false) %}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{% set showUserColumn = true %}
|
||||
{% set showRateColumn = true %}
|
||||
{% set decimal = decimal|default(false) %}
|
||||
{% if query.user %}
|
||||
{# this is only triggered, if a user exports from his personal timesheet screen#}
|
||||
{% set showUserColumn = false %}
|
||||
@@ -106,7 +107,7 @@ mpdf-->
|
||||
{% if customer is not same as(summary.customer) %}
|
||||
<tr class="summary">
|
||||
<td colspan="2"></td>
|
||||
<td class="totals duration">{{ customerDuration|duration }}</td>
|
||||
<td class="totals duration">{{ customerDuration|duration(decimal) }}</td>
|
||||
{% if showRateColumn %}
|
||||
<td class="totals cost">{{ customerRate|money(customerCurrency) }}</td>
|
||||
{% endif %}
|
||||
@@ -120,7 +121,7 @@ mpdf-->
|
||||
<tr class="{{ cycle(['odd', 'even'], customerCount) }}">
|
||||
<td>{{ summary.customer }}</td>
|
||||
<td>{{ summary.project }}</td>
|
||||
<td class="duration">{{ summary.duration|duration }}</td>
|
||||
<td class="duration">{{ summary.duration|duration(decimal) }}</td>
|
||||
{% if showRateColumn %}
|
||||
<td class="cost">{{ summary.rate|money(summary.currency) }}</td>
|
||||
{% endif %}
|
||||
@@ -132,7 +133,7 @@ mpdf-->
|
||||
{% if customer is not same as(null) %}
|
||||
<tr class="summary">
|
||||
<td colspan="2"></td>
|
||||
<td class="totals duration">{{ customerDuration|duration }}</td>
|
||||
<td class="totals duration">{{ customerDuration|duration(decimal) }}</td>
|
||||
{% if showRateColumn %}
|
||||
<td class="totals cost">{{ customerRate|money(customerCurrency) }}</td>
|
||||
{% endif %}
|
||||
@@ -189,7 +190,7 @@ mpdf-->
|
||||
<i>{{ entry.description|escape|desc2html }}</i>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="duration">{{ entry.duration|duration }}</td>
|
||||
<td class="duration">{{ entry.duration|duration(decimal) }}</td>
|
||||
{% if showRateColumn %}
|
||||
<td class="cost">
|
||||
{% if is_granted('view_rate', entry) %}
|
||||
@@ -208,7 +209,7 @@ mpdf-->
|
||||
{% else %}
|
||||
<td colspan="2"></td>
|
||||
{% endif %}
|
||||
<td class="totals duration">{{ duration|duration }}</td>
|
||||
<td class="totals duration">{{ duration|duration(decimal) }}</td>
|
||||
{% if showRateColumn %}
|
||||
<td class="totals cost">{% if currency is not null %}{{ rate|money(currency) }}{% endif %}</td>
|
||||
{% endif %}
|
||||
|
||||
@@ -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'}}}) %}
|
||||
{% 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) %}
|
||||
{% set class = '' %}
|
||||
{% if view != 'edit' %}
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
{% 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': '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 %}
|
||||
|
||||
{% if is_granted('edit', timesheet) %}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
{% block title %}{{ 'menu.export'|trans }}{% endblock %}
|
||||
{% block invoice %}
|
||||
{% set decimal = decimal|default(false) %}
|
||||
{% set showUserColumn = true %}
|
||||
{% if query.user %}
|
||||
{% set showUserColumn = false %}
|
||||
@@ -72,7 +73,7 @@
|
||||
{% for field in metaColumns %}
|
||||
<td>{{ tables.datatable_meta_column(entry, field) }}</td>
|
||||
{% endfor %}
|
||||
<td class="text-nowrap">{{ entry.duration|duration }}</td>
|
||||
<td class="text-nowrap">{{ entry.duration|duration(decimal) }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
@@ -86,7 +87,7 @@
|
||||
<th></th>
|
||||
{% endfor %}
|
||||
<th>{{ 'invoice.total_working_time'|trans }}</th>
|
||||
<th class="text-nowrap">{{ timeWorked|duration }}</th>
|
||||
<th class="text-nowrap">{{ timeWorked|duration(decimal) }}</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
{% import "user/actions.html.twig" as actions %}
|
||||
|
||||
{% block page_title %}{{ 'profile.title'|trans }}{% endblock %}
|
||||
{% block page_subtitle %}{% if not user.alias is empty %}{{ user.alias }} - {% endif %}{{ user.username }}{% 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.username }}{% endif %}{% endblock %}
|
||||
{% block page_actions %}{{ actions.user(user, tab) }}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
|
||||
@@ -505,6 +505,10 @@
|
||||
<source>label.timesheet.daily_stats</source>
|
||||
<target>Tägliche Statistiken im Timesheet anzeigen</target>
|
||||
</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
|
||||
|
||||
@@ -505,6 +505,10 @@
|
||||
<source>label.timesheet.daily_stats</source>
|
||||
<target>Show daily stats in timesheet</target>
|
||||
</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
|
||||
|
||||
Reference in New Issue
Block a user