From 331d57dd8f9a0727442bf7edf0bc465e98b3d8fb Mon Sep 17 00:00:00 2001 From: Ross Date: Wed, 17 Sep 2025 22:25:28 +0100 Subject: [PATCH] Enhance leave request handling and improve error logging in RotaBuilder --- gen_cons.py | 24 +++++++++++++++--------- rota/shifts.py | 15 ++++++++++++++- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/gen_cons.py b/gen_cons.py index d0a3506..84a274d 100644 --- a/gen_cons.py +++ b/gen_cons.py @@ -69,8 +69,12 @@ def extract_leave_and_rota_from_calender(calender_df): "date": date, "worker": worker, }) - else: - logger.warning(f"Unknown leave value for {worker} on {date}: {leave_val}") + elif leave_val != "" and leave_val != "nan": + leave_requests.append({ + "date": date, + "worker": worker, + }) + #print(leave_requests) return leave_requests, work_requests, rota_data @@ -242,12 +246,12 @@ def load_workers(): nwds=non_working_days, ) - if initial == "L1": - w.oop = [OutOfProgramme( - start_date="2025-09-15", - end_date="2025-10-14", - reason="even out shifts", - )] + #if initial == "L1": + # w.oop = [OutOfProgramme( + # start_date="2025-09-15", + # end_date="2025-10-14", + # reason="even out shifts", + # )] if initial == "ND": print(w.not_available_to_work) @@ -331,6 +335,8 @@ def main( Rota.constraint_options["max_days_worked_per_week"] = 3 # Rota.constraint_options["avoid_st2_first_month"] = True + #Rota.enable_unavailabilities = False + Rota.add_shifts( SingleShift( sites=("rota a",), @@ -368,7 +374,7 @@ def main( workers_required=1, length=12.5, days=days[5:], - balance_offset=1, + balance_offset=2, #constraint=[ # {"name": "pre", "options": 1}, # {"name": "post", "options": 1}, diff --git a/rota/shifts.py b/rota/shifts.py index c9d4364..838802a 100644 --- a/rota/shifts.py +++ b/rota/shifts.py @@ -431,6 +431,8 @@ class RotaBuilder(object): self.exported_rota_file = None + self.enable_unavailabilities = True + self.MAX_SHIFTS_PER_DAY = 2 def set_rota_constraint(self, constraint: str, value: Any): @@ -987,6 +989,10 @@ class RotaBuilder(object): f"Worker '{worker.name}' has a forced assignment for shift '{shift_name}' on week {week}, day {day} (date: {self.get_date_by_week_day(week, day)}), which conflicts with a leave request.", ) + if not self.enable_unavailabilities: + self.unavailable_to_work = set() + self.unavailable_to_work_reason = {} + def availability_init(model, wid, week, day): # This needs to be higher than the max number of possible shifts per day if (wid, week, day) in self.unavailable_to_work: @@ -3462,7 +3468,14 @@ class RotaBuilder(object): return self.shifts_by_name[name].length def get_date_by_week_day(self, week: WeekInt, day: DayStr) -> datetime.date: - return self.week_day_date_map[(week, day)] + try: + return self.week_day_date_map[(week, day)] + except KeyError: + self.add_warning( + "Rota/week day date map", + f"Week {week}, Day {day} not found in week_day_date_map", + ) + return datetime.date(1900, 1, 1) def get_weeks_by_date_range(self, start_date: datetime.date | None, end_date: datetime.date | None) -> list[WeekInt]: """Get a list of weeks that fall within a date range.