Release 2.0.20 (#4028)

* max duration per entry increased from 8 to 10 hours
* fixes #3981 - clickable area in dropdown too small
* fixes #4008 - duplicate activities in project-details report
* headers and summary styling in project-details report
* show billable stats in project-details report
* added new invoice variable for entry.duration_format
This commit is contained in:
Kevin Papst
2023-05-15 22:30:37 +02:00
committed by GitHub
parent 04422f3530
commit 29624354a2
28 changed files with 248 additions and 174 deletions

View File

@@ -145,6 +145,7 @@
<div class="row">
<div class="col-xs-12 table-responsive">
<table class="table table-hover dataTable">
<thead>
<tr>
<th>{{ 'username'|trans }}</th>
<th></th>
@@ -152,6 +153,8 @@
<th class="text-center">{{ monthName }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% set yearTotal = 0 %}
{% for userYearStat in userYearStats|sort((a, b) => b.duration <=> a.duration) %}
{% set user = userYearStat.user %}
@@ -175,11 +178,13 @@
{% endfor %}
</tr>
{% endfor %}
<tr>
<th></th>
<th class="text-nowrap text-center total">
</tbody>
<tfoot>
<tr class="summary">
<td></td>
<td class="text-nowrap text-center total">
{{ yearTotal|duration }}
</th>
</td>
{% for monthNumber in 1..12 %}
{% set total = 0 %}
{% for userYearStat in userYearStats %}
@@ -188,11 +193,12 @@
{% set total = total + month.duration %}
{% endif %}
{% endfor %}
<th class="text-nowrap text-center total">
<td class="text-nowrap text-center total">
{{ total|duration }}
</th>
</td>
{% endfor %}
</tr>
</tfoot>
</table>
</div>
</div>
@@ -211,8 +217,25 @@
<div class="row">
<div class="col-xs-12 col-sm-9 col-md-8 col-lg-6">
<table class="table table-hover dataTable">
<thead>
<tr>
<th></th>
<th class="text-nowrap text-end">{{ 'duration'|trans }}</th>
{% if view_revenue %}
<th class="text-nowrap text-end">{{ 'billable'|trans }}</th>
<th class="text-nowrap text-end">{{ 'stats.amountTotal'|trans }}</th>
{% endif %}
<th></th>
</tr>
</thead>
<tbody>
{% set totalRate = 0.0 %}
{% set billable = 0 %}
{% for stat in activities|sort((a, b) => b.duration <=> a.duration) %}
{% set dataset = dataset|merge([{'value': stat.duration, 'name': stat.name, 'color': stat.activity.color|colorize(stat.activity.name), 'duration': stat.duration|duration, 'rate': stat.rate|money(currency)}]) %}
{% set rate = stat.rate %}
{% set totalRate = totalRate + rate %}
{% set billable = billable + stat.rateBillable %}
{% set dataset = dataset|merge([{'value': stat.duration, 'name': stat.name, 'color': stat.activity.color|colorize(stat.activity.name), 'duration': stat.duration|duration, 'rate': rate|money(currency)}]) %}
{% set percentage = 0 %}
{% if totalDuration > 0 and stat.duration > 0 %}
{% set percentage = (100 / (totalDuration / stat.duration)) %}
@@ -221,11 +244,24 @@
<td>{{ widgets.label_activity(stat.activity, {'inherit': false, 'random': true}) }}</td>
<td class="text-nowrap text-end">{{ stat.duration|duration }}</td>
{% if view_revenue %}
<td class="text-nowrap text-end">{{ stat.rateBillable|money(currency) }}</td>
<td class="text-nowrap text-end">{{ stat.rate|money(currency) }}</td>
{% endif %}
<td class="text-nowrap text-end">{{ percentage|number_format(1) }} %</td>
</tr>
{% endfor %}
</tbody>
<tfoot>
<tr class="summary">
<td></td>
<td class="text-nowrap text-end">{{ totalDuration|duration }}</td>
{% if view_revenue %}
<td class="text-nowrap text-end">{{ billable|money(currency) }}</td>
<td class="text-nowrap text-end">{{ totalRate|money(currency) }}</td>
{% endif %}
<td></td>
</tr>
</tfoot>
</table>
</div>
<div class="col-xs-12 col-sm-3 col-md-4 col-lg-6">
@@ -430,7 +466,20 @@
<div class="row">
<div class="col-xs-12 col-sm-9 col-md-8 col-lg-6">
<table class="table table-hover dataTable">
<thead>
<tr>
<th></th>
<th class="text-nowrap text-end">{{ 'duration'|trans }}</th>
{% if view_revenue %}
<th class="text-nowrap text-end">{{ 'billable'|trans }}</th>
<th class="text-nowrap text-end">{{ 'stats.amountTotal'|trans }}</th>
{% endif %}
<th></th>
</tr>
</thead>
<tbody>
{% set rateTotal = 0 %}
{% set rateTotalBillable = 0 %}
{% set totalDuration = 0 %}
{% set datasets = [] %}
{% set labels = [] %}
@@ -438,6 +487,7 @@
{% set user = userStat.user %}
{% set color = user.color|colorize(user.displayName) %}
{% set rateTotal = rateTotal + userStat.rate %}
{% set rateTotalBillable = rateTotalBillable + userStat.rateBillable %}
{% set totalDuration = totalDuration + userStat.duration %}
{% set datasets = datasets|merge([{'name': user.displayName, 'duration': userStat.duration|duration, 'value': userStat.duration, 'color': color, 'rate': userStat.rate|money(currency)}]) %}
{% set percentage = 0 %}
@@ -452,6 +502,9 @@
{{ userStat.duration|duration }}
</td>
{% if view_revenue %}
<td class="text-nowrap text-end">
{{ userStat.rateBillable|money(currency) }}
</td>
<td class="text-nowrap text-end">
{{ userStat.rate|money(currency) }}
</td>
@@ -461,14 +514,18 @@
</td>
</tr>
{% endfor %}
<tr>
</tbody>
<tfoot>
<tr class="summary">
<td></td>
<th class="text-nowrap text-end total">{{ totalDuration|duration }}</th>
<td class="text-nowrap text-end total">{{ totalDuration|duration }}</td>
{% if view_revenue %}
<th class="text-nowrap text-end total">{{ rateTotal|money(currency) }}</th>
<td class="text-nowrap text-end total">{{ rateTotalBillable|money(currency) }}</td>
<td class="text-nowrap text-end total">{{ rateTotal|money(currency) }}</td>
{% endif %}
<td></td>
</tr>
</tfoot>
</table>
</div>
<div class="col-xs-12 col-sm-3 col-md-4 col-lg-6">