fix(dashboard): include abnormal-override records in component counts
status_code='abnormal' records (>30 min) hide the underlying late/early/ot component from by_status. Use *_minutes>0 union to surface them so the dashboard count matches the real data. Late: 9 → 23, Early: 0 → 17, OT: 15 → 28 Note: component totals may now exceed total_records because each record can carry multiple status components (e.g. late_ot).
This commit is contained in:
+25
-3
@@ -1085,6 +1085,25 @@ async def dashboard_summary(
|
|||||||
if r.employee_name:
|
if r.employee_name:
|
||||||
staff_set.add(r.employee_name)
|
staff_set.add(r.employee_name)
|
||||||
|
|
||||||
|
# Component counts: union of status_code match AND minutes field
|
||||||
|
# (handles abnormal override where status_code='abnormal' hides
|
||||||
|
# the underlying late/early/ot component from by_status)
|
||||||
|
late_count = (
|
||||||
|
sum(v for k, v in by_status.items() if "late" in k)
|
||||||
|
+ sum(1 for r in rows if r.late_minutes and r.late_minutes > 0
|
||||||
|
and (r.status_code or "").lower() == "abnormal")
|
||||||
|
)
|
||||||
|
early_count = (
|
||||||
|
sum(v for k, v in by_status.items() if "early" in k)
|
||||||
|
+ sum(1 for r in rows if r.early_minutes and r.early_minutes > 0
|
||||||
|
and (r.status_code or "").lower() == "abnormal")
|
||||||
|
)
|
||||||
|
ot_count = (
|
||||||
|
sum(v for k, v in by_status.items() if "ot" in k)
|
||||||
|
+ sum(1 for r in rows if r.ot_minutes and r.ot_minutes > 0
|
||||||
|
and (r.status_code or "").lower() == "abnormal")
|
||||||
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
# Backend / dashboard canonical fields
|
# Backend / dashboard canonical fields
|
||||||
"total": len(rows),
|
"total": len(rows),
|
||||||
@@ -1094,11 +1113,14 @@ async def dashboard_summary(
|
|||||||
"by_department": by_department,
|
"by_department": by_department,
|
||||||
"trend": [],
|
"trend": [],
|
||||||
# Frontend-expected fields (alias for legacy UI)
|
# Frontend-expected fields (alias for legacy UI)
|
||||||
|
# Component counts: late + early + ot may exceed total because
|
||||||
|
# a single record can carry multiple status components
|
||||||
|
# (e.g. status_code='late_ot' contributes to both late and ot).
|
||||||
"total_records": len(rows),
|
"total_records": len(rows),
|
||||||
"normal_count": by_status.get("normal", 0),
|
"normal_count": by_status.get("normal", 0),
|
||||||
"late_count": sum(v for k, v in by_status.items() if "late" in k),
|
"late_count": late_count,
|
||||||
"early_count": sum(v for k, v in by_status.items() if "early" in k),
|
"early_count": early_count,
|
||||||
"ot_count": sum(v for k, v in by_status.items() if "ot" in k),
|
"ot_count": ot_count,
|
||||||
"missing_count": by_status.get("missing", 0),
|
"missing_count": by_status.get("missing", 0),
|
||||||
"abnormal_count": by_status.get("abnormal", 0),
|
"abnormal_count": by_status.get("abnormal", 0),
|
||||||
"staff_count": len(staff_set),
|
"staff_count": len(staff_set),
|
||||||
|
|||||||
Reference in New Issue
Block a user