diff --git a/gen_cons.py b/gen_cons.py index 8227009..fcf65b6 100644 --- a/gen_cons.py +++ b/gen_cons.py @@ -482,11 +482,12 @@ def main( weeks_to_rota=weeks, balance_offset_modifier=bom, use_previous_shifts=True, - name="cons rota feb 2026", + name="cons rota feb 2026 run 2", allow_force_assignment_with_leave_conflict=True, constraint_options=RotaConstraintOptions( balance_weekends=True, max_shifts_per_week=6, + max_weekend_frequency=3, max_days_per_week_block=[(4, 2), (4, 4)], #balance_weekend_days=True, balance_weekend_days_quadratic=True, @@ -509,7 +510,8 @@ def main( assign_as_block=False, constraints=[ PreShiftConstraint(days=2, start_date="2025-11-17", exclude_days=("Fri", "Sat", "Sun"), exclude_dates=["2026-04-06", "2026-05-04", "2026-05-25"]), - PostShiftConstraint(days=1, start_date="2025-11-17", exclude_days=("Fri", "Sat", "Sun"), allow_self=True), + PreShiftConstraint(days=1, start_date="2025-11-17", exclude_days=("Fri", "Sat", "Sun"), allow_self=False), + MaxShiftsPerWeekConstraint(max_shifts=1, days=days[:5]), ], ), SingleShift( @@ -528,6 +530,7 @@ def main( SingleShift( sites=("rota b", "rota c"), name="weekend b", + end_date="2026-07-20", workers_required=1, length=12.5, days=days[5:], diff --git a/rota_generator/shifts.py b/rota_generator/shifts.py index 113634e..458438e 100644 --- a/rota_generator/shifts.py +++ b/rota_generator/shifts.py @@ -293,6 +293,7 @@ class RequireRemoteSitePresenceConstraint(BaseShiftConstraint): class MaxShiftsPerWeekConstraint(BaseShiftConstraint): max_shifts: int | None = None + days: Optional[List[str]] = None class MaxShiftsPerWeekBlockConstraint(BaseShiftConstraint): week_block : int @@ -3007,20 +3008,19 @@ class RotaBuilder(object): shift_number = constraint.max_shifts else: shift_number = constraint_shift.get_shift_number() - try: + # If the constraint specifies particular days, only count those days, + # otherwise count the shift's own days. + constraint_days = ( + constraint.days if constraint.days is not None else self.days + ) + self.model.constraints.add( shift_number >= sum( - self.model.works[ - worker.id, w, day, constraint_shift.name - ] - # for shiftname in self.get_shift_names_by_week_day(week, day) - # for day in self.days - for w, day in self.get_week_day_combinations_for_shift( - constraint_shift - ) - if w == week + self.model.works[worker.id, w, day, constraint_shift.name] + for w, day in self.get_week_day_combinations_for_shift(constraint_shift) + if w == week and day in constraint_days ) ) except ValueError: