Attendance: detect rest day in enrich → render 休息 instead of 缺勤

When roster says the shift rests on a given weekday (e.g. Sunday for S2/S3),
the employee wasn't scheduled to work. Import still marks the record
status_code='missing' because no shift times were available, but the
right user-facing label is '休息' not '缺勤'.

Enrich now: if status_code='missing' and get_shift_schedule_full returns
None (shift defined no schedule for that weekday), override to
status_code='rest' / status_text='休息'.

Added '休息' to the basic-status vocabulary: dropdown option, filter
condition, StatusBadge (slate grey + coffee icon), and row highlight.
This commit is contained in:
IT狗
2026-07-21 23:54:57 +08:00
parent 811b9991c9
commit 404329d3fa
3 changed files with 20 additions and 2 deletions
+13 -1
View File
@@ -126,6 +126,16 @@ def enrich_attendance_with_leave(records, db):
if not r.date:
continue
# Rest day detection: roster says the shift rests on this weekday
# (e.g. Sunday for S2/S3) but raw status is 'missing'. Don't flag as 缺勤
# when the employee wasn't scheduled to work.
if (r.status_code or '').lower() == 'missing' and r.shift_code and r.weekday:
shift_info = get_shift_schedule_full(r.shift_code, r.weekday)
if shift_info is None:
r.status_code = 'rest'
r.status_text = '休息'
continue
if r.date in holidays_by_date:
h = holidays_by_date[r.date]
# Check roster: if shift's public_holiday == 'Yes', employee works on holidays
@@ -1106,7 +1116,7 @@ async def attendance_status_texts(
raw status_text variant (e.g. '異常-遲到39分'). Keeping it server-driven
so client and server agree on the filter vocabulary.
"""
return ['正常', '異常', '缺勤', '公假', '請假']
return ['正常', '異常', '缺勤', '公假', '請假', '休息']
@app.get("/api/attendance/stats")
async def attendance_stats(
@@ -1335,6 +1345,8 @@ async def attendance_records(
for tag in ('SL', 'AL', 'CL'))]
elif status_text in ('normal', '正常'):
rows = [r for r in all_rows if (r.status_code or '').lower() == 'normal']
elif status_text in ('rest', '休息'):
rows = [r for r in all_rows if (r.status_code or '').lower() == 'rest']
else:
# Fallback to raw status_text substring search
rows = [r for r in all_rows