Fix: use roster public_holiday column to determine if employee works on holidays, instead of checking clock-in
This commit is contained in:
+24
-8
@@ -128,8 +128,19 @@ def enrich_attendance_with_leave(records, db):
|
||||
|
||||
if r.date in holidays_by_date:
|
||||
h = holidays_by_date[r.date]
|
||||
# Only mark as holiday if no clock-in record
|
||||
# (employee who worked on holiday should keep attendance status)
|
||||
# Check roster: if shift's public_holiday == 'Yes', employee works on holidays
|
||||
# Don't override with holiday status in that case
|
||||
shift_holiday = '休息' # default: assume rest on holiday
|
||||
if r.shift_code:
|
||||
shift_info = get_shift_schedule_full(r.shift_code, r.weekday or '')
|
||||
if shift_info and len(shift_info) >= 3:
|
||||
shift_holiday = shift_info[2]
|
||||
if shift_holiday == 'Yes':
|
||||
# Employee works on public holidays - keep attendance status, append holiday note
|
||||
base = r.status_text or "正常"
|
||||
r.status_text = f"{base} (🎉{h.name})"
|
||||
continue
|
||||
# Employee rests on public holidays - mark as holiday unless already has clock-in
|
||||
has_clock_in = (
|
||||
(r.check_in is not None) or
|
||||
(r.actual_in and r.actual_in not in ("", "-"))
|
||||
@@ -138,9 +149,10 @@ def enrich_attendance_with_leave(records, db):
|
||||
r.status_code = "holiday"
|
||||
r.status_text = f"\U0001F3D6\uFE0F{h.name}"
|
||||
continue
|
||||
# Has clock-in on holiday: keep computed attendance status but append holiday flag
|
||||
base = r.status_text or "正常"
|
||||
r.status_text = f"{base} (🎉{h.name})"
|
||||
# Has clock-in but roster says rest on holiday - still show holiday
|
||||
r.status_code = "holiday"
|
||||
r.status_text = f"\U0001F3D6\uFE0F{h.name}"
|
||||
continue
|
||||
|
||||
emp_leaves = leave_by_emp_date.get(r.employee_name, {}).get(r.date, [])
|
||||
if not emp_leaves:
|
||||
@@ -504,7 +516,8 @@ async def _import_attendance_to_db(db: Session, headers, rows, user_id: int) ->
|
||||
# ============ Attendance Calculation ============
|
||||
def get_shift_schedule_full(shift_code: str, weekday: str) -> Optional[tuple]:
|
||||
"""Get the expected start and end time for a shift on a given weekday.
|
||||
Returns (start_time, end_time) tuple.
|
||||
Returns (start_time, end_time, public_holiday) tuple.
|
||||
public_holiday is 'Yes' if the shift requires working on public holidays, '休息' otherwise.
|
||||
"""
|
||||
roster_path = get_excel_path("roster")
|
||||
if not os.path.exists(roster_path):
|
||||
@@ -518,10 +531,12 @@ def get_shift_schedule_full(shift_code: str, weekday: str) -> Optional[tuple]:
|
||||
|
||||
# Find column indices
|
||||
shift_col = None
|
||||
ph_col = None
|
||||
for i, h in enumerate(headers):
|
||||
if h == '班次':
|
||||
shift_col = i
|
||||
break
|
||||
elif h == 'public holiday':
|
||||
ph_col = i
|
||||
|
||||
if shift_col is None:
|
||||
return None
|
||||
@@ -549,6 +564,7 @@ def get_shift_schedule_full(shift_code: str, weekday: str) -> Optional[tuple]:
|
||||
# Find the shift row
|
||||
for row in ws.iter_rows(min_row=2, values_only=True):
|
||||
if row[shift_col] == shift_code:
|
||||
public_holiday = str(row[ph_col]).strip() if ph_col is not None else '休息'
|
||||
day_col = day_col_map.get(target_day)
|
||||
if day_col is not None:
|
||||
schedule = row[day_col]
|
||||
@@ -561,7 +577,7 @@ def get_shift_schedule_full(shift_code: str, weekday: str) -> Optional[tuple]:
|
||||
end_str = parts[1].strip()
|
||||
start_time = datetime.strptime(start_str, '%H:%M').time()
|
||||
end_time = datetime.strptime(end_str, '%H:%M').time()
|
||||
return (start_time, end_time)
|
||||
return (start_time, end_time, public_holiday)
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
Reference in New Issue
Block a user