feat(attendance): 'Chybějící hodiny' (manko) row — real hours below the fond
manko = max(0, fond − (worked_total + dovolená + nemoc + neplacené volno)) using REAL clock time, not the paušál. Supplement next to Přesčas — the verified binding formulas are untouched. Why: the paušál Odpracováno can nominally cover the fond while dozens of real hours are missing (Dominik 6/2026: 21 days × 8 + 8h dovolená = 176 = fond exactly, thanks to weekend shifts compensating 3 recordless weekdays — yet real worked time was 136,5h). Přesčas = 0 correctly, and the 31,5h gap vanished from every total. Now it's a permanent summary line, red+bold when positive, plus a 'Chybí: Xh' chip on the admin screen cards. +4 tests incl. the real June dataset as a pinned acceptance case (also pins noc 6,75 — early shifts starting 05:30/05:45 legitimately count night minutes before 06:00). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -97,6 +97,7 @@ interface UserTotal {
|
||||
weekend_hours?: number;
|
||||
night_minutes?: number;
|
||||
worked_holiday_hours?: number; // sum of hours worked ON a holiday
|
||||
manko?: number; // Chybějící hodiny: real clock time below the fond
|
||||
records?: AttendanceRecord[];
|
||||
}
|
||||
|
||||
@@ -243,6 +244,7 @@ function computeUserTotals(
|
||||
t.weekend_hours = s.weekendHours;
|
||||
t.night_minutes = s.nightMinutes;
|
||||
t.worked_holiday_hours = s.svatekHours;
|
||||
t.manko = s.manko;
|
||||
}
|
||||
|
||||
return totals;
|
||||
@@ -427,6 +429,10 @@ export function buildUserSectionHtml(
|
||||
<span class="summary-label">Přesčas:</span>
|
||||
<span class="summary-value">${formatHoursDecimal(s.prescas * 60)}h</span>
|
||||
</div>
|
||||
<div class="summary-row${s.manko > 0 ? " summary-alert" : ""}">
|
||||
<span class="summary-label">Chybějící hodiny:</span>
|
||||
<span class="summary-value">${formatHoursDecimal(s.manko * 60)}h</span>
|
||||
</div>
|
||||
<div class="summary-row">
|
||||
<span class="summary-label">Svátek:</span>
|
||||
<span class="summary-value">${formatHoursDecimal(s.svatekHours * 60)}h</span>
|
||||
@@ -547,6 +553,9 @@ export function buildPrintHtml(
|
||||
}
|
||||
.user-summary .summary-label { color: #555; }
|
||||
.user-summary .summary-value { font-weight: 600; }
|
||||
/* Chybějící hodiny > 0 — must jump out of the sheet, not hide in it. */
|
||||
.user-summary .summary-alert .summary-label,
|
||||
.user-summary .summary-alert .summary-value { color: #b00020; font-weight: 700; }
|
||||
.user-summary .summary-fund {
|
||||
border-top: 1px solid #ddd; margin-top: 4px; padding-top: 6px;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user