Files
kimai2/templates/reporting/team_summary.html.twig
root baab938326
Some checks failed
Actions Security Analysis / Scan workflows (push) Has been cancelled
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
Fix Team Summary report — all 3 pivot tables + proper Kimai layout
- Billable Projects (billable=1), Non-Billable (billable=0), Unproductive (billable=2)
- Uses Twig macro for DRY pivot table rendering
- Extends Kimai reporting/layout.html.twig for proper navbar/breadcrumb
- Team selector + date range in card header
2026-06-18 22:59:58 +00:00

102 lines
4.7 KiB
Twig
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% extends 'reporting/layout.html.twig' %}
{% block report %}
<div class="card">
<div class="card-header">
<form method="get" class="row g-2 align-items-center">
<div class="col-auto">
<select name="team" class="form-select form-select-sm" onchange="this.form.submit()">
<option value="">-- Select Team --</option>
{% for t in teams %}
<option value="{{ t.id }}" {% if selectedTeamId == t.id %}selected{% endif %}>{{ t.name }}</option>
{% endfor %}
</select>
</div>
<div class="col-auto">
<input type="date" name="from" value="{{ from }}" class="form-control form-control-sm" onchange="this.form.submit()">
</div>
<div class="col-auto">
<input type="date" name="to" value="{{ to }}" class="form-control form-control-sm" onchange="this.form.submit()">
</div>
</form>
</div>
{% if team %}
<div class="card-body">
<h3>Time Analysis — {{ team.name }}</h3>
<small class="text-muted">{{ from }} {{ to }}</small>
{% if rows is empty %}
<div class="alert alert-info mt-3">No time entries found for this period.</div>
{% else %}
<table class="table table-striped table-hover table-sm mt-3">
<thead>
<tr>
<th>Name</th>
<th class="text-end">Billable</th>
<th class="text-end">Non-Billable</th>
<th class="text-end">Unproductive</th>
<th class="text-end">Total Hours</th>
</tr>
</thead>
<tbody>
{% set tb = 0 %}{% set tn = 0 %}{% set tu = 0 %}{% set tt = 0 %}
{% for r in rows %}
{% set tb = tb + r.billable_hours %}
{% set tn = tn + r.nonbillable_hours %}
{% set tu = tu + r.unproductive_hours %}
{% set tt = tt + r.total_hours %}
<tr>
<td>{{ r.alias ?: r.username }}</td>
<td class="text-end">{{ r.billable_hours|number_format(2) }}</td>
<td class="text-end">{{ r.nonbillable_hours|number_format(2) }}</td>
<td class="text-end">{{ r.unproductive_hours|number_format(2) }}</td>
<td class="text-end"><strong>{{ r.total_hours|number_format(2) }}</strong></td>
</tr>
{% endfor %}
<tr class="table-active fw-bold">
<td>TOTAL</td>
<td class="text-end">{{ tb|number_format(2) }}</td>
<td class="text-end">{{ tn|number_format(2) }}</td>
<td class="text-end">{{ tu|number_format(2) }}</td>
<td class="text-end">{{ tt|number_format(2) }}</td>
</tr>
</tbody>
</table>
{% macro pivot(rows, cols, title) %}
{% if rows is not empty %}
<h4 class="mt-4">{{ title }}</h4>
<div class="table-responsive">
<table class="table table-striped table-hover table-sm" style="font-size:11px">
<thead><tr>
<th>Company</th><th>Project</th>
{% for uc in cols %}<th class="text-end">{{ uc }}</th>{% endfor %}
<th class="text-end">TOTAL</th>
</tr></thead>
<tbody>
{% for pr in rows %}
<tr>
<td>{{ pr.company }}</td>
<td>{{ pr.project }}</td>
{% for uc in cols %}
<td class="text-end">{{ pr.users[uc]|default(0) > 0 ? pr.users[uc]|number_format(1) }}</td>
{% endfor %}
<td class="text-end"><strong>{{ pr.total|number_format(1) }}</strong></td>
</tr>
{% endfor %}
</tbody>
</table></div>
{% endif %}
{% endmacro %}
{% import _self as self %}
{{ self.pivot(projectRows, userColumns, 'Billable Projects') }}
{{ self.pivot(nonbillRows, userColumnsNB, 'Non-Billable Projects') }}
{{ self.pivot(unprodRows, userColumnsUP, 'Unproductive Projects') }}
{% endif %}
</div>
{% endif %}
</div>
{% endblock %}