add shift worker names constraint

This commit is contained in:
Ross
2023-12-27 19:12:08 +00:00
parent 740836e31a
commit 3d064a75b9
2 changed files with 227 additions and 0 deletions
+31
View File
@@ -252,6 +252,7 @@ class RotaBuilder(object):
"avoid_st2_first_month": False,
"hard_constrain_pair_separation": False,
"avoid_shifts_by_grades": [],
"avoid_shifts_by_worker_names": [],
}
self.results = None
@@ -1175,6 +1176,7 @@ class RotaBuilder(object):
)
# Most of our constraints apply per worker
worker: Worker
for worker in self.workers:
console.rule(
f"Generate worker constraints: [bold blue]{worker.name}[/bold blue]"
@@ -1209,6 +1211,28 @@ class RotaBuilder(object):
)
pass
for constraint_dict in self.constraint_options["avoid_shifts_by_worker_names"]:
if invalid_shifts := set(constraint_dict["shifts"]).difference(
set(self.get_shift_names())
):
if self.ignore_valid_shifts:
continue # Skip if we don't want to raise an error
else:
raise InvalidShift(
f"avoid shifts by grade constraint contains a non existent shift: {invalid_shifts}"
)
if worker.name in constraint_dict["names"]:
self.model.constraints.add(
0
== sum(
self.model.works[worker.id, week, day, shift]
for week, day, shift in self.get_all_shiftname_combinations()
if week in constraint_dict["weeks"]
and shift in constraint_dict["shifts"]
)
)
for constraint_dict in self.constraint_options["avoid_shifts_by_grades"]:
if invalid_shifts := set(constraint_dict["shifts"]).difference(
set(self.get_shift_names())
@@ -2522,6 +2546,13 @@ class RotaBuilder(object):
for p in pairs:
self.worker_pairs.append(tuple(pairs[p]))
def add_worker_name_constraint_by_week(
self, names: Iterable[str], weeks: Iterable[int], shifts
):
self.constraint_options["avoid_shifts_by_worker_names"].append(
{"names": names, "weeks": weeks, "shifts": shifts}
)
def add_grade_constraint_by_week(
self, grades: Iterable[int], weeks: Iterable[int], shifts
):