Sep 16 - Optimize code, part 2

This commit is contained in:
2026-09-16 14:31:41 -04:00
parent 2c5627354e
commit 13b56fb1d1
9 changed files with 632 additions and 140 deletions
+66 -17
View File
@@ -85,6 +85,20 @@ def _overnight_aware_sort_key(record):
seconds_total += 24 * 3600
return seconds_total
def _pair_is_regular(check_in_record, check_out_record) -> bool:
"""
True when a completed pair counts toward the 40-hour overtime rule.
SP / PW / PT / C hours are paid but never build toward overtime (§13). The
OUT record's work type wins, mirroring effective_work_type elsewhere, so a
Regular IN paired with an SP OUT counts as SP.
"""
in_work_type = getattr(check_in_record, 'work_type', None)
out_work_type = getattr(check_out_record, 'work_type', None)
effective = out_work_type or in_work_type
return effective not in ('SP', 'PW', 'PT', 'C')
def _qtr(decimal_hours: float) -> float:
"""
Round a decimal-hours value to the nearest quarter hour (.00/.25/.50/.75).
@@ -596,6 +610,10 @@ def export_time_attendance_excel(records, project_name_for_filename, date_range_
current_week_start = None
grand_regular_hours = 0
grand_ot_hours = 0
# Regular-only hours feeding the 40-hour overtime rule. SP/PW/PT/C hours
# are worked and paid, but they do NOT build toward overtime (§13), so
# they are excluded here while column H still shows every hour worked.
weekly_regular_hours = 0
# Accumulate SP/PW/PT/C hours from cross-type pairs (where the calculator
# could not detect them because it processes each work-type stream independently).
cross_type_sp_hours = 0.0
@@ -624,20 +642,22 @@ def export_time_attendance_excel(records, project_name_for_filename, date_range_
_report_start = start_date
week_start = (_report_start + timedelta(days=((date_obj.date() - _report_start).days // 7) * 7))
if current_week_start is not None and week_start != current_week_start:
# Write weekly total row
week_regular = min(weekly_total_hours, 40.0)
week_overtime = max(0, weekly_total_hours - 40.0)
# Write weekly total row. Column H = every hour worked; Regular
# and OT are computed from regular hours only (SP/PW/PT/C excluded).
week_regular = min(weekly_regular_hours, 40.0)
week_overtime = max(0, weekly_regular_hours - 40.0)
ws.cell(row=current_row, column=7, value='Weekly Total: ').font = bold_font
ws.cell(row=current_row, column=8, value=_qtr(weekly_total_hours)).font = bold_font
ws.cell(row=current_row, column=9, value=_qtr(week_regular)).font = bold_font
ws.cell(row=current_row, column=10, value=_qtr(week_overtime)).font = bold_font
grand_regular_hours += week_regular
grand_ot_hours += week_overtime
current_row += 1
weekly_total_hours = 0
weekly_regular_hours = 0
current_week_start = week_start
@@ -666,6 +686,8 @@ def export_time_attendance_excel(records, project_name_for_filename, date_range_
# group, and sum only complete pairs. This ensures the daily total in
# column H matches exactly the pairs rendered in the export rows.
_day_total_hours = 0.0
# Same pairs, minus SP/PW/PT/C: the overtime base (§13)
_day_regular_hours = 0.0
# Track which records are consumed by same-building pairing so the
# cross-building pass only considers true orphans.
_same_building_used_ids = set()
@@ -704,6 +726,8 @@ def export_time_attendance_excel(records, project_name_for_filename, date_range_
if _duration > 24:
continue
_day_total_hours += _duration
if _pair_is_regular(_in_r, _out_r):
_day_regular_hours += _duration
_out_used[_oi2] = True
_same_building_used_ids.add(id(_in_r))
_same_building_used_ids.add(id(_out_r))
@@ -768,6 +792,8 @@ def export_time_attendance_excel(records, project_name_for_filename, date_range_
'hours': _cb_dur,
})
_day_total_hours += _cb_dur
if _pair_is_regular(_cb_in, _cb_out):
_day_regular_hours += _cb_dur
logger_handler.logger.info(
f"[TA Export] Cross-building pair for employee {employee_id} on {date_str}: "
f"IN {_cb_in.location_name} @ {_cb_in.check_in_time}"
@@ -788,6 +814,7 @@ def export_time_attendance_excel(records, project_name_for_filename, date_range_
total_hours = _qtr(_day_total_hours)
weekly_total_hours += total_hours
weekly_regular_hours += _qtr(_day_regular_hours)
# Daily total display (only shown on last location's last row)
daily_total_display = _qtr(total_hours) if total_hours > 0 else ''
@@ -1282,10 +1309,10 @@ def export_time_attendance_excel(records, project_name_for_filename, date_range_
# END CROSS-BUILDING PAIR ROW WRITING
# -------------------------------------------------------------------
# Write final weekly total for this employee
# Write final weekly total for this employee (Regular/OT from regular hours only)
if weekly_total_hours > 0:
week_regular = min(weekly_total_hours, 40.0)
week_overtime = max(0, weekly_total_hours - 40.0)
week_regular = min(weekly_regular_hours, 40.0)
week_overtime = max(0, weekly_regular_hours - 40.0)
ws.cell(row=current_row, column=7, value='Weekly Total: ').font = bold_font
ws.cell(row=current_row, column=8, value=_qtr(weekly_total_hours)).font = bold_font
@@ -1757,7 +1784,21 @@ def export_time_attendance_by_building_excel(records, project_name_for_filename,
date_cell.font = Font(name='Aptos Narrow', size=11)
date_cell.alignment = Alignment(horizontal='left')
current_row += 1
# Row 5: how the totals in this sheet are calculated. Overtime here is per
# BUILDING (each block counts only that building's hours), so an employee
# split across two buildings shows no overtime even past 40 hours — the main
# Time Attendance export totals the week across all buildings.
ws.merge_cells(f'A{current_row}:N{current_row}')
ot_note_cell = ws.cell(
row=current_row, column=1,
value=('Note: Weekly Total / Regular / OT below are per building, and overtime excludes '
'SP / PW / PT / C hours. Use the main Time Attendance export for payroll totals.')
)
ot_note_cell.font = Font(name='Aptos Narrow', size=10, italic=True)
ot_note_cell.alignment = Alignment(horizontal='left')
current_row += 1
# Empty rows before first building
current_row += 2
@@ -1967,6 +2008,9 @@ def export_time_attendance_by_building_excel(records, project_name_for_filename,
current_week_start = None
grand_regular_hours = 0
grand_ot_hours = 0
# Regular-only hours for the 40-hour rule (SP/PW/PT/C excluded, §13).
# Note: per BUILDING in this sheet — see the note under the date range.
weekly_regular_hours = 0
# Accumulate raw regular-only (non-SP/PW/PT) pair hours.
# Used for the "Regular" summary row when the employee also has
# special work-type hours.
@@ -1993,9 +2037,10 @@ def export_time_attendance_by_building_excel(records, project_name_for_filename,
_report_start = start_date
week_start = (_report_start + timedelta(days=((date_obj.date() - _report_start).days // 7) * 7))
if current_week_start is not None and week_start != current_week_start:
# Write weekly total row
week_regular = min(weekly_total_hours, 40.0)
week_overtime = max(0, weekly_total_hours - 40.0)
# Write weekly total row. Column H = every hour worked at this
# building; Regular and OT come from regular hours only.
week_regular = min(weekly_regular_hours, 40.0)
week_overtime = max(0, weekly_regular_hours - 40.0)
ws.cell(row=current_row, column=7, value='Weekly Total: ').font = bold_font
ws.cell(row=current_row, column=8, value=_qtr(weekly_total_hours)).font = bold_font
@@ -2005,8 +2050,9 @@ def export_time_attendance_by_building_excel(records, project_name_for_filename,
grand_regular_hours += week_regular
grand_ot_hours += week_overtime
current_row += 1
weekly_total_hours = 0
weekly_regular_hours = 0
current_week_start = week_start
@@ -2145,6 +2191,7 @@ def export_time_attendance_by_building_excel(records, project_name_for_filename,
# Calculate daily hours
daily_hours = 0
_bb_day_non_sp_hours = 0.0 # weekly summary sheet excludes SP time
_bb_day_regular_hours = 0.0 # overtime base: excludes SP/PW/PT/C
for pair in pairs:
if pair['check_in'] and pair['check_out'] and not pair['is_miss_punch']:
pair_in = datetime.combine(date_obj, pair['check_in'].check_in_time)
@@ -2165,11 +2212,13 @@ def export_time_attendance_by_building_excel(records, project_name_for_filename,
_bb_eff_wt = _bb_out_wt or _bb_in_wt # prefer OUT's type (mirrors main export)
if _bb_eff_wt not in ('SP', 'PW', 'PT', 'C'):
regular_only_hours += _bb_dur
_bb_day_regular_hours += _bb_dur
if _bb_eff_wt != 'SP':
_bb_day_non_sp_hours += _bb_dur
daily_hours = _qtr(daily_hours)
weekly_total_hours += daily_hours
weekly_regular_hours += _qtr(_bb_day_regular_hours)
# Same week anchoring as the Weekly Total rows (report start date)
_bb_week_idx = (date_obj.date() - start_date).days // 7
@@ -2250,10 +2299,10 @@ def export_time_attendance_by_building_excel(records, project_name_for_filename,
current_row += 1
# Write final weekly total
# Write final weekly total (Regular/OT from regular hours only)
if weekly_total_hours > 0:
week_regular = min(weekly_total_hours, 40.0)
week_overtime = max(0, weekly_total_hours - 40.0)
week_regular = min(weekly_regular_hours, 40.0)
week_overtime = max(0, weekly_regular_hours - 40.0)
ws.cell(row=current_row, column=7, value='Weekly Total: ').font = bold_font
ws.cell(row=current_row, column=8, value=_qtr(weekly_total_hours)).font = bold_font