add prtial shifts
This commit is contained in:
@@ -3738,6 +3738,22 @@ class RotaBuilder(object):
|
||||
)
|
||||
)
|
||||
|
||||
# Shift-specific active dates constraint
|
||||
for shift in self.get_shifts():
|
||||
if (worker.id, week, day, shift.name) in self.model.works:
|
||||
calc_start = getattr(worker, "calculated_shift_start_dates", {}).get(shift.name, worker.calculated_start_date)
|
||||
calc_end = getattr(worker, "calculated_shift_end_dates", {}).get(shift.name, worker.calculated_end_date)
|
||||
if calc_start is not None and calc_end is not None:
|
||||
date = self.week_day_date_map[(week, day)]
|
||||
if date < calc_start or date >= calc_end:
|
||||
self.model.constraints.add(
|
||||
self.model.works[worker.id, week, day, shift.name] == 0
|
||||
)
|
||||
if self.get_locum_workers() and (worker.id, week, day, shift.name) in self.model.locum_works:
|
||||
self.model.constraints.add(
|
||||
self.model.locum_works[worker.id, week, day, shift.name] == 0
|
||||
)
|
||||
|
||||
# single shift per day (unless multi-shift allowed)
|
||||
# This is signifantly slower so only enable if required
|
||||
shifts_today = self.get_shift_names_by_week_day(week, day)
|
||||
@@ -4323,6 +4339,38 @@ class RotaBuilder(object):
|
||||
"Invalid exact shift",
|
||||
f"Worker {worker.name} requested exact shifts for non-existent shift {s_name}",
|
||||
)
|
||||
|
||||
# Validate shift-dependent start/end dates
|
||||
start_dates = getattr(worker, "shift_start_dates", [])
|
||||
end_dates = getattr(worker, "shift_end_dates", [])
|
||||
|
||||
start_dict = {}
|
||||
if isinstance(start_dates, dict):
|
||||
start_dict = start_dates
|
||||
elif isinstance(start_dates, list):
|
||||
for item in start_dates:
|
||||
if hasattr(item, "shift"):
|
||||
start_dict[item.shift] = item.start_date
|
||||
|
||||
end_dict = {}
|
||||
if isinstance(end_dates, dict):
|
||||
end_dict = end_dates
|
||||
elif isinstance(end_dates, list):
|
||||
for item in end_dates:
|
||||
if hasattr(item, "shift"):
|
||||
end_dict[item.shift] = item.end_date
|
||||
|
||||
for s_name in set(list(start_dict.keys()) + list(end_dict.keys())):
|
||||
if s_name not in self.shifts_by_name:
|
||||
raise InvalidShift(
|
||||
f"Worker {worker.name} specified shift-dependent dates for non-existent shift {s_name}"
|
||||
)
|
||||
s = self.get_shift_by_name(s_name)
|
||||
if not self.is_worker_eligible_for_shift(worker, s):
|
||||
self.add_warning(
|
||||
"Worker/ineligible shift date constraint",
|
||||
f"Worker {worker.name} specified shift-dependent dates for shift {s_name} but is not eligible to work it"
|
||||
)
|
||||
wid = worker.id
|
||||
if wid in self.workers_id_map:
|
||||
message = f"Worker with id '{wid}' has been added twice"
|
||||
|
||||
Reference in New Issue
Block a user