Add ignore_dates field to worker constraints and implement related tests

This commit is contained in:
Ross
2026-05-19 21:31:05 +01:00
parent dee80ed4fa
commit 935b4baaba
4 changed files with 246 additions and 27 deletions
+43 -17
View File
@@ -2405,33 +2405,59 @@ class RotaBuilder(object):
for constraint in worker.max_days_per_week_block:
for week_blocks in self.get_week_block_iterator(constraint.week_block):
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
# Determine which (week, day) combinations to ignore
ignored_week_days = set()
for ignore_date in (constraint.ignore_dates or []):
try:
w, d = self.date_week_day_map.get(ignore_date, (None, None))
if w is not None and d is not None:
ignored_week_days.add((w, d))
except Exception:
pass
included_days = [
(week, day)
for week, day in self.get_week_day_combinations()
if week in week_blocks and (week, day) not in ignored_week_days
]
if included_days:
self.model.constraints.add(
sum(
self.model.works_day[worker.id, week, day]
for week, day in included_days
)
<= constraint.max_days
)
<= constraint.max_days
)
for constraint in worker.max_unique_shifts_per_week_block:
for week_blocks in self.get_week_block_iterator(constraint.week_block):
if not week_blocks:
continue
# Determine which (week, day) combinations to ignore
ignored_week_days = set()
for ignore_date in (constraint.ignore_dates or []):
try:
w, d = self.date_week_day_map.get(ignore_date, (None, None))
if w is not None and d is not None:
ignored_week_days.add((w, d))
except Exception:
pass
block_start_week = week_blocks[0]
used_shift_vars = []
for shift_name in self.get_shift_names():
shift_assignments = [
self.model.works[worker.id, week, day, shift_name]
for week, day in self.get_week_day_combinations()
if week in week_blocks
and shift_name in self.get_shift_names_by_week_day(
week,
day,
return_empty_if_week_day_not_found=True,
)
]
shift_assignments = []
for week, day in self.get_week_day_combinations():
if week in week_blocks and (week, day) not in ignored_week_days:
if shift_name in self.get_shift_names_by_week_day(
week,
day,
return_empty_if_week_day_not_found=True,
):
shift_assignments.append(
self.model.works[worker.id, week, day, shift_name]
)
if not shift_assignments:
continue