.
This commit is contained in:
+21
-29
@@ -3,7 +3,7 @@ import datetime
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
from rota_generator.shifts import MaxShiftsPerWeekConstraint, NoWorkers, PostShiftConstraint, PreShiftConstraint, RotaBuilder, SingleShift, WorkerRequirement, days
|
||||
from rota_generator.shifts import MaxShiftsPerWeekConstraint, NoWorkers, PostShiftConstraint, PreShiftConstraint, RotaBuilder, SingleShift, WorkerRequirement, days, RotaConstraintOptions
|
||||
import typer
|
||||
import subprocess
|
||||
import pandas as pd
|
||||
@@ -38,11 +38,11 @@ def extract_leave_and_rota_from_calender(calender_df):
|
||||
|
||||
# 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
|
||||
rota_row = calender_df.iloc[0]
|
||||
#rota_row = calender_df.iloc[0]
|
||||
#rota_data = {}
|
||||
for i, worker in enumerate(worker_names):
|
||||
assignment = str(rota_row.iloc[5 + i]).strip() if len(rota_row) > 5 + i else ""
|
||||
#rota_data[worker] = f"rota {assignment.lower()}"
|
||||
#for i, worker in enumerate(worker_names):
|
||||
# assignment = str(rota_row.iloc[5 + i]).strip() if len(rota_row) > 5 + i else ""
|
||||
# #rota_data[worker] = f"rota {assignment.lower()}"
|
||||
|
||||
leave_requests = []
|
||||
work_requests = []
|
||||
@@ -55,6 +55,9 @@ def extract_leave_and_rota_from_calender(calender_df):
|
||||
date = datetime.datetime.strptime(date_str, "%Y-%m-%d").date()
|
||||
except Exception:
|
||||
continue # skip rows with invalid date
|
||||
|
||||
if date < datetime.date(2026, 2, 16):
|
||||
continue # skip rows before rota start date
|
||||
for i, worker in enumerate(worker_names):
|
||||
if not worker or worker.lower() == "nan":
|
||||
continue
|
||||
@@ -91,6 +94,7 @@ def extract_shift_assignments_from_rota(rota_df):
|
||||
shifts = ["twilight", "oncall"]
|
||||
assignments = []
|
||||
|
||||
skipped_rows = 0
|
||||
for idx, row in rota_df.iloc[2:].iterrows():
|
||||
week_start_str = str(row.iloc[0]).strip().split(" ")[0] # Get the week start date from the first column (index 0)
|
||||
try:
|
||||
@@ -99,6 +103,10 @@ def extract_shift_assignments_from_rota(rota_df):
|
||||
print(f"Invalid date format in row {idx}: {week_start_str}")
|
||||
continue # skip rows with invalid date
|
||||
|
||||
if week_start < datetime.date(2026, 2, 16):
|
||||
skipped_rows += 1
|
||||
continue # skip rows before rota start date
|
||||
|
||||
for i, day in enumerate(days):
|
||||
for j, shift in enumerate(shifts):
|
||||
if i < 5:
|
||||
@@ -122,7 +130,7 @@ def extract_shift_assignments_from_rota(rota_df):
|
||||
shift = "weekend"
|
||||
assignments.append({
|
||||
"week_start": week_start,
|
||||
"week": idx-1, # 1-indexed week number
|
||||
"week": idx-1-skipped_rows, # 1-indexed week number
|
||||
"day": day,
|
||||
"date": week_start + datetime.timedelta(days=i),
|
||||
"shift": shift,
|
||||
@@ -147,7 +155,7 @@ def load_workers():
|
||||
|
||||
# Extract sheets
|
||||
days_df = xls["Days"]
|
||||
calender_df = xls["Calender"]
|
||||
calender_df = xls["Calendar"]
|
||||
rota_df = xls["Rota"]
|
||||
|
||||
|
||||
@@ -193,7 +201,7 @@ def load_workers():
|
||||
for i, day in enumerate(weekday_cols):
|
||||
val = row.iloc[3 + i]
|
||||
# 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() or str(val).strip().lower() == "yes*")
|
||||
availability[day] = available
|
||||
workers_days.append({"initial": initial, "name": name, "availability": availability, "requests": requests})
|
||||
|
||||
@@ -329,14 +337,12 @@ def main(
|
||||
balance_offset_modifier=bom,
|
||||
name="cons rota feb 2026",
|
||||
allow_force_assignment_with_leave_conflict=True,
|
||||
constraint_options=RotaConstraintOptions(
|
||||
balance_weekends=True,
|
||||
max_shifts_per_week=6,
|
||||
max_days_per_week_block=[(4, 2), (6, 3)],
|
||||
),
|
||||
)
|
||||
# Rota = RotaBuilder(start_date, weeks_to_rota=20, balance_offset_modifier=1)
|
||||
Rota.constraint_options["balance_weekends"] = True
|
||||
#Rota.constraint_options["max_weekend_frequency"] = 2
|
||||
Rota.constraint_options["max_shifts_per_week"] = 6
|
||||
Rota.constraint_options["max_days_worked_per_week"] = 3
|
||||
# Rota.constraint_options["avoid_st2_first_month"] = True
|
||||
Rota.constraint_options["max_days_per_week_block"] = [(4, 2), (6, 3)] # (max_days, week_block)
|
||||
|
||||
#Rota.enable_unavailabilities = False
|
||||
|
||||
@@ -351,10 +357,6 @@ def main(
|
||||
constraints=[
|
||||
PreShiftConstraint(days=2, start_date="2025-11-17", exclude_days=("Fri", "Sat", "Sun")),
|
||||
PostShiftConstraint(days=1, start_date="2025-11-17", exclude_days=("Fri", "Sat", "Sun"), allow_self=True),
|
||||
#{
|
||||
# "name": "max_shifts_per_week",
|
||||
# "options": 3,
|
||||
#}
|
||||
],
|
||||
),
|
||||
SingleShift(
|
||||
@@ -365,9 +367,6 @@ def main(
|
||||
days=days[5:],
|
||||
balance_offset=1,
|
||||
constraints=[
|
||||
#{"name": "pre", "options": 2},
|
||||
|
||||
#{"name": "post", "options": 1},
|
||||
PostShiftConstraint(days=1, start_date="2025-11-17", ignore_shifts=["oncall"]),
|
||||
],
|
||||
display_char="a",
|
||||
@@ -380,10 +379,6 @@ def main(
|
||||
length=12.5,
|
||||
days=days[5:],
|
||||
balance_offset=2,
|
||||
#constraint=[
|
||||
# {"name": "pre", "options": 1},
|
||||
# {"name": "post", "options": 1},
|
||||
#],
|
||||
display_char="b",
|
||||
),
|
||||
SingleShift(
|
||||
@@ -398,11 +393,8 @@ def main(
|
||||
days=days[:5],
|
||||
balance_offset=1,
|
||||
constraints=[
|
||||
#PreShiftConstraint(days=1, start_date="2025-11-17", ignore_shifts=["oncall"]),
|
||||
PreShiftConstraint(days=1, start_date="2025-11-17", ignore_shifts=["oncall"], exclude_days=("Sat", "Sun")),
|
||||
#PostShiftConstraint(days=1, start_date="2025-11-17", ignore_shifts=["oncall", "weekend a", "weekend b"], include_weekends=False),
|
||||
MaxShiftsPerWeekConstraint(max_shifts=1),
|
||||
#{"name": "post", "options": 1},
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
@@ -383,6 +383,7 @@ class RotaBuilder(object):
|
||||
SHIFT_BOUNDS=SHIFT_BOUNDS,
|
||||
name: str = "",
|
||||
bank_holidays: dict[datetime.date, str] = bank_holiday_map,
|
||||
constraint_options: RotaConstraintOptions | dict | None = None,
|
||||
):
|
||||
self.name = name
|
||||
|
||||
|
||||
Reference in New Issue
Block a user