Add max days per week block constraint and exclude days for shift constraints

This commit is contained in:
Ross
2025-09-18 21:00:31 +01:00
parent fdce572f6d
commit 3f4d8068eb
2 changed files with 26 additions and 2 deletions
+18
View File
@@ -92,10 +92,12 @@ class NightConstraint(BaseShiftConstraint):
class PreShiftConstraint(BaseShiftConstraint):
days: Any = None
ignore_shifts: List[str] = []
exclude_days: List[str] = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
class PostShiftConstraint(BaseShiftConstraint):
days: Any = None
ignore_shifts: List[str] = []
exclude_days: List[str] = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
class BalanceAcrossGroupsConstraint(BaseShiftConstraint):
""""""
@@ -385,6 +387,7 @@ class RotaBuilder(object):
"max_night_frequency_week_exclusions": [],
"max_shifts_per_week": 7,
"max_shifts_per_month": 40,
"max_days_per_week_block": [(3, 2)], # (max_days, week_block)
# The following will cause an unsolvable problem if a shift
# is forced as a block and spans the time peroid
"prevent_monday_after_full_weekends": [],
@@ -1840,6 +1843,17 @@ class RotaBuilder(object):
>= -self.constraint_options["maximum_allowed_shift_diff"]
)
for max_days, weeks in self.constraint_options["max_days_per_week_block"]:
for week_blocks in self.get_week_block_iterator(weeks):
self.model.constraints.add(
sum(
self.model.works_day[worker.id, week, day]
for week, day in self.get_week_day_combinations()
if week in week_blocks
)
<= max_days
)
for week_blocks in self.get_week_block_iterator(4):
# Prevent more than n number shifts per 4 weeks
try:
@@ -2922,6 +2936,8 @@ class RotaBuilder(object):
if week not in constraint.weeks:
continue
for n in range(0, constraint.days):
if day in constraint.exclude_days:
continue
if day in constraint_shift.days:
# Only apply if worker can work this shift
if worker.site not in constraint_shift.sites:
@@ -2957,6 +2973,8 @@ class RotaBuilder(object):
if week not in constraint.weeks:
continue
for n in range(0, constraint.days):
if day in constraint.exclude_days:
continue
if day in constraint_shift.days:
# Only apply if worker can work this shift
if worker.site not in constraint_shift.sites: