start updating cons rota

This commit is contained in:
Ross
2025-12-16 20:58:09 +00:00
parent f019d2f565
commit 0b732a0b09
+25 -25
View File
@@ -39,10 +39,10 @@ def extract_leave_and_rota_from_calender(calender_df):
# Get rota data from the second row (index 1), starting from column 5 (index 4) # Get rota data from the second row (index 1), starting from column 5 (index 4)
# Extract the rota data for each worker from the first data row (index 0), columns 5 onwards # Extract the rota data for each worker from the first data row (index 0), columns 5 onwards
rota_row = calender_df.iloc[0] rota_row = calender_df.iloc[0]
rota_data = {} #rota_data = {}
for i, worker in enumerate(worker_names): for i, worker in enumerate(worker_names):
assignment = str(rota_row.iloc[5 + i]).strip() if len(rota_row) > 5 + i else "" assignment = str(rota_row.iloc[5 + i]).strip() if len(rota_row) > 5 + i else ""
rota_data[worker] = f"rota {assignment.lower()}" #rota_data[worker] = f"rota {assignment.lower()}"
leave_requests = [] leave_requests = []
work_requests = [] work_requests = []
@@ -77,7 +77,7 @@ def extract_leave_and_rota_from_calender(calender_df):
#print(leave_requests) #print(leave_requests)
return leave_requests, work_requests, rota_data return leave_requests, work_requests#, rota_data
def extract_shift_assignments_from_rota(rota_df): def extract_shift_assignments_from_rota(rota_df):
""" """
@@ -140,7 +140,7 @@ def extract_shift_assignments_from_rota(rota_df):
def load_workers(): def load_workers():
# Path to the ODS file # Path to the ODS file
ods_path = "cons/Oncall rota requests + New rota (first draft) - September 2025.ods" ods_path = "cons/CONSULTANT TWILIGHT & ONCALL ROTA.ods"
# Read all sheets # Read all sheets
xls = pd.read_excel(ods_path, engine="odf", sheet_name=None) xls = pd.read_excel(ods_path, engine="odf", sheet_name=None)
@@ -151,7 +151,7 @@ def load_workers():
rota_df = xls["Rota"] rota_df = xls["Rota"]
rota_b_path = "cons/Draft Rota B Sept 25-Feb 26.xlsx" rota_b_path = "cons/Rota B Feb -July 2026.xlsx"
rota_b_df = pd.read_excel(rota_b_path, engine="openpyxl", sheet_name="Sheet1", header=None) rota_b_df = pd.read_excel(rota_b_path, engine="openpyxl", sheet_name="Sheet1", header=None)
# Extract rota_b assignments: date in column A, worker in column B # Extract rota_b assignments: date in column A, worker in column B
rota_b_assignments = defaultdict(list) rota_b_assignments = defaultdict(list)
@@ -176,6 +176,7 @@ def load_workers():
#print(days_df.head()) #print(days_df.head())
weekday_cols = ["Mon", "Tue", "Wed", "Thu", "Fri"] weekday_cols = ["Mon", "Tue", "Wed", "Thu", "Fri"]
workers_days = [] workers_days = []
rota_data = {}
for idx, row in days_df.iloc[7:].iterrows(): for idx, row in days_df.iloc[7:].iterrows():
# Extract initials from the name column (assumed to be in brackets at the end) # Extract initials from the name column (assumed to be in brackets at the end)
text = str(row.iloc[1]).strip() text = str(row.iloc[1]).strip()
@@ -188,15 +189,16 @@ def load_workers():
continue continue
availability = {} availability = {}
requests = {} requests = {}
rota_data[name] = f"rota {str(row.iloc[2]).strip().lower()}"
for i, day in enumerate(weekday_cols): for i, day in enumerate(weekday_cols):
val = row.iloc[2 + i] val = row.iloc[3 + i]
# You can adjust the logic below depending on your marking scheme (e.g. "Y", "Yes", "1", etc.) # You can adjust the logic below depending on your marking scheme (e.g. "Y", "Yes", "1", etc.)
available = not ("no" in str(val).strip().lower()) available = not ("no" in str(val).strip().lower())
availability[day] = available availability[day] = available
workers_days.append({"initial": initial, "name": name, "availability": availability, "requests": requests}) workers_days.append({"initial": initial, "name": name, "availability": availability, "requests": requests})
leave_requests, work_requests, rota_data = extract_leave_and_rota_from_calender(calender_df) leave_requests, work_requests = extract_leave_and_rota_from_calender(calender_df)
assignments, assignments_by_worker = extract_shift_assignments_from_rota(rota_df) assignments, assignments_by_worker = extract_shift_assignments_from_rota(rota_df)
print(assignments) print(assignments)
@@ -206,20 +208,20 @@ def load_workers():
worker = worker_day["name"] worker = worker_day["name"]
initial = worker_day["initial"] initial = worker_day["initial"]
start_date = "2025-09-01" # Default start date, can be adjusted later start_date = "2026-02-16" # Default start date, can be adjusted later
if initial == "ND": #if initial == "ND":
start_date = "2025-09-29" # Non-working day worker starts later # start_date = "2025-09-29" # Non-working day worker starts later
if initial == "MF": #if initial == "MF":
start_date = "2026-01-15" # Medical leave worker starts earlier # start_date = "2026-01-15" # Medical leave worker starts earlier
if initial == "AA": #if initial == "AA":
start_date = "2025-11-17" # Absent worker starts later # start_date = "2025-11-17" # Absent worker starts later
end_date = None end_date = None
if initial == "L1": #if initial == "L1":
end_date = "2025-11-17" # L1 worker has a leave request # end_date = "2025-11-17" # L1 worker has a leave request
elif initial == "L2": #elif initial == "L2":
end_date = "2025-09-29" # L2 worker has a leave request # end_date = "2025-09-29" # L2 worker has a leave request
non_working_days = [] non_working_days = []
for day, available in worker_day["availability"].items(): for day, available in worker_day["availability"].items():
@@ -255,8 +257,6 @@ def load_workers():
# reason="even out shifts", # reason="even out shifts",
# )] # )]
if initial == "ND":
print(w.not_available_to_work)
if initial in assignments_by_worker: if initial in assignments_by_worker:
# Add shift assignments for this worker # Add shift assignments for this worker
@@ -291,10 +291,10 @@ def load_workers():
w.add_force_assign_with("weekend", "oncall") w.add_force_assign_with("weekend", "oncall")
if w.name in ("DS",): if w.name in ("DS",):
w.add_hard_day_dependency({"Fri", "Sat", "Sun"}, start_date="2025-11-17") w.add_hard_day_dependency({"Fri", "Sat", "Sun"})
else: else:
w.add_hard_day_dependency({"Fri", "Sun"}, start_date="2025-11-17") w.add_hard_day_dependency({"Fri", "Sun"})
w.add_hard_day_exclusion({"Sat", "Sun"}, start_date="2025-11-17") w.add_hard_day_exclusion({"Sat", "Sun"})
#if w.name == "TB": #if w.name == "TB":
@@ -316,7 +316,7 @@ def main(
solve: bool = True, solve: bool = True,
time_to_run: int = 60 * 60, time_to_run: int = 60 * 60,
ratio: float = 0.001, ratio: float = 0.001,
start_date: datetime.datetime = "2025-09-01", start_date: datetime.datetime = "2026-02-16",
weeks: int = 24, weeks: int = 24,
bom: int = 1, bom: int = 1,
): ):
@@ -327,7 +327,7 @@ def main(
rota_start_date, rota_start_date,
weeks_to_rota=weeks, weeks_to_rota=weeks,
balance_offset_modifier=bom, balance_offset_modifier=bom,
name="cons rota test", name="cons rota feb 2026",
allow_force_assignment_with_leave_conflict=True, allow_force_assignment_with_leave_conflict=True,
) )
# Rota = RotaBuilder(start_date, weeks_to_rota=20, balance_offset_modifier=1) # Rota = RotaBuilder(start_date, weeks_to_rota=20, balance_offset_modifier=1)