Fix billable mapping (0=billable, 1=non-billable, 2=unproductive)
Some checks failed
Frontend / Frontend verification (push) Has been cancelled
Lint PHP / Linting (8.2) (push) Has been cancelled
Check .lock files / Verify lock file integrity (push) Has been cancelled
Release Drafter / Verify repository (push) Has been cancelled
Release Drafter / Draft next release (push) Has been cancelled
Tests / Integration (8.2) (push) Has been cancelled
Tests / Integration (8.3) (push) Has been cancelled
Tests / Integration (8.4) (push) Has been cancelled
Tests / Integration (8.5) (push) Has been cancelled
Actions Security Analysis / Scan workflows (push) Has been cancelled

- Swapped billable/non-billable SQL values to match migrated data
- All 3 pivot tables always render (empty ones show 'No data')
- Added grand total row to pivot tables
- Initialize unprodRows/userColumnsUP to prevent undefined var error
This commit is contained in:
root
2026-06-18 23:08:43 +00:00
parent baab938326
commit 3cd198c12c
2 changed files with 20 additions and 6 deletions

View File

@@ -35,13 +35,15 @@ final class TeamSummaryController extends AbstractController
$userColumns = []; $userColumns = [];
$nonbillRows = []; $nonbillRows = [];
$userColumnsNB = []; $userColumnsNB = [];
$unprodRows = [];
$userColumnsUP = [];
if ($selectedTeamId > 0) { if ($selectedTeamId > 0) {
$team = $this->teamRepository->find($selectedTeamId); $team = $this->teamRepository->find($selectedTeamId);
if ($team) { if ($team) {
$rows = $this->getUserTimeAnalysis($selectedTeamId, $from, $to); $rows = $this->getUserTimeAnalysis($selectedTeamId, $from, $to);
[$projectRows, $userColumns] = $this->getProjectPivot($selectedTeamId, $from, $to, '= 1'); [$projectRows, $userColumns] = $this->getProjectPivot($selectedTeamId, $from, $to, '= 0');
[$nonbillRows, $userColumnsNB] = $this->getProjectPivot($selectedTeamId, $from, $to, '= 0'); [$nonbillRows, $userColumnsNB] = $this->getProjectPivot($selectedTeamId, $from, $to, '= 1');
[$unprodRows, $userColumnsUP] = $this->getProjectPivot($selectedTeamId, $from, $to, '= 2'); [$unprodRows, $userColumnsUP] = $this->getProjectPivot($selectedTeamId, $from, $to, '= 2');
} }
} }
@@ -68,8 +70,8 @@ final class TeamSummaryController extends AbstractController
$sql = "SELECT $sql = "SELECT
u.username, u.username,
u.alias, u.alias,
COALESCE(SUM(CASE WHEN p.billable = 1 THEN ts.duration END), 0) / 3600 AS billable_hours, COALESCE(SUM(CASE WHEN p.billable = 0 THEN ts.duration END), 0) / 3600 AS billable_hours,
COALESCE(SUM(CASE WHEN p.billable = 0 THEN ts.duration END), 0) / 3600 AS nonbillable_hours, COALESCE(SUM(CASE WHEN p.billable = 1 THEN ts.duration END), 0) / 3600 AS nonbillable_hours,
COALESCE(SUM(CASE WHEN p.billable IS NULL OR p.billable NOT IN (0,1) THEN ts.duration END), 0) / 3600 AS unproductive_hours, COALESCE(SUM(CASE WHEN p.billable IS NULL OR p.billable NOT IN (0,1) THEN ts.duration END), 0) / 3600 AS unproductive_hours,
COALESCE(SUM(ts.duration), 0) / 3600 AS total_hours COALESCE(SUM(ts.duration), 0) / 3600 AS total_hours
FROM kimai2_users u FROM kimai2_users u

View File

@@ -65,7 +65,6 @@
</table> </table>
{% macro pivot(rows, cols, title) %} {% macro pivot(rows, cols, title) %}
{% if rows is not empty %}
<h4 class="mt-4">{{ title }}</h4> <h4 class="mt-4">{{ title }}</h4>
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-striped table-hover table-sm" style="font-size:11px"> <table class="table table-striped table-hover table-sm" style="font-size:11px">
@@ -75,6 +74,9 @@
<th class="text-end">TOTAL</th> <th class="text-end">TOTAL</th>
</tr></thead> </tr></thead>
<tbody> <tbody>
{% if rows is empty %}
<tr><td colspan="{{ cols|length + 3 }}" class="text-center text-muted">No data for this period</td></tr>
{% else %}
{% for pr in rows %} {% for pr in rows %}
<tr> <tr>
<td>{{ pr.company }}</td> <td>{{ pr.company }}</td>
@@ -85,9 +87,19 @@
<td class="text-end"><strong>{{ pr.total|number_format(1) }}</strong></td> <td class="text-end"><strong>{{ pr.total|number_format(1) }}</strong></td>
</tr> </tr>
{% endfor %} {% endfor %}
<tr class="table-active fw-bold">
<td colspan="2">TOTAL</td>
{% set gt = 0 %}
{% for uc in cols %}
{% set ct = 0 %}{% for pr in rows %}{% set ct = ct + pr.users[uc]|default(0) %}{% endfor %}
<td class="text-end"><strong>{{ ct > 0 ? ct|number_format(1) }}</strong></td>
{% set gt = gt + ct %}
{% endfor %}
<td class="text-end"><strong>{{ gt|number_format(1) }}</strong></td>
</tr>
{% endif %}
</tbody> </tbody>
</table></div> </table></div>
{% endif %}
{% endmacro %} {% endmacro %}
{% import _self as self %} {% import _self as self %}