Add warning for forced assignments in HardDayDependency
This commit is contained in:
@@ -1702,6 +1702,103 @@ class RotaBuilder(object):
|
||||
)
|
||||
|
||||
for week in weeks_to_apply:
|
||||
# If the worker has any forced assignment in the dependency group,
|
||||
# emit a concise warning. For visibility include every day in the
|
||||
# group showing the worker's forced shifts (if any) and other
|
||||
# workers' forced shifts on those days so blocking days are visible.
|
||||
worker_has_forced_in_group = False
|
||||
for (fw, fd, fs) in getattr(worker, "forced_assignments", []):
|
||||
if fw == week and fd in day_group:
|
||||
worker_has_forced_in_group = True
|
||||
break
|
||||
if not worker_has_forced_in_group:
|
||||
try:
|
||||
for (d_date, d_shift) in getattr(worker, "forced_assignments_by_date", []):
|
||||
ww, dd = self.date_week_day_map.get(d_date, (None, None))
|
||||
if ww == week and dd in day_group:
|
||||
worker_has_forced_in_group = True
|
||||
break
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if worker_has_forced_in_group:
|
||||
forced_day_details = []
|
||||
try:
|
||||
date_map_for_week = {self.get_date_by_week_day(week, d): d for d in day_group}
|
||||
except Exception:
|
||||
date_map_for_week = {}
|
||||
|
||||
for day in day_group:
|
||||
worker_forced_shifts = set()
|
||||
# week-based forced assignments
|
||||
for (fw, fd, fs) in getattr(worker, "forced_assignments", []):
|
||||
if fw == week and fd == day:
|
||||
worker_forced_shifts.add(fs)
|
||||
# date-based forced assignments
|
||||
try:
|
||||
date = self.get_date_by_week_day(week, day)
|
||||
for (d_date, d_shift) in getattr(worker, "forced_assignments_by_date", []):
|
||||
try:
|
||||
ww, dd = self.date_week_day_map.get(d_date, (None, None))
|
||||
except Exception:
|
||||
ww = dd = None
|
||||
if ww == week and dd == day:
|
||||
worker_forced_shifts.add(d_shift)
|
||||
else:
|
||||
try:
|
||||
if str(d_date) == str(date):
|
||||
worker_forced_shifts.add(d_shift)
|
||||
except Exception:
|
||||
pass
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# collect other workers' forced shifts on this day
|
||||
others_forced = {}
|
||||
try:
|
||||
date_for_day = self.get_date_by_week_day(week, day)
|
||||
except Exception:
|
||||
date_for_day = None
|
||||
|
||||
for other in self.workers:
|
||||
if other is worker:
|
||||
continue
|
||||
other_shifts = set()
|
||||
# week-based forced assignments
|
||||
for (ofw, ofd, ofs) in getattr(other, "forced_assignments", []):
|
||||
if ofw == week and ofd == day:
|
||||
other_shifts.add(ofs)
|
||||
# date-based forced assignments: try mapping then fallback
|
||||
for (odate, oshift) in getattr(other, "forced_assignments_by_date", []):
|
||||
try:
|
||||
oww, odd = self.date_week_day_map.get(odate, (None, None))
|
||||
except Exception:
|
||||
oww = odd = None
|
||||
if oww == week and odd == day:
|
||||
other_shifts.add(oshift)
|
||||
continue
|
||||
try:
|
||||
if date_for_day is not None and str(odate) == str(date_for_day):
|
||||
other_shifts.add(oshift)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if other_shifts:
|
||||
others_forced[other.name] = sorted(list(other_shifts))
|
||||
|
||||
forced_day_details.append((day, sorted(list(worker_forced_shifts)), others_forced))
|
||||
|
||||
parts = []
|
||||
for d, wfs, others in forced_day_details:
|
||||
olist = ", ".join([f"{n}: {', '.join(s)}" for n, s in others.items()]) or "none"
|
||||
wfs_str = ", ".join(wfs) or "none"
|
||||
parts.append(f"{d} - worker forced: {wfs_str}; others forced: {olist}")
|
||||
details = "; ".join(parts)
|
||||
logger.warning(f"HardDayDependency forced-assignment warning for worker={worker.name} week={week}: {details}")
|
||||
self.add_warning(
|
||||
"HardDayDependency forced assignment",
|
||||
f"Worker '{worker.name}' has hard_day_dependency {set(day_group)} in week {week}; forced assignments on dependency days: {details}. If the rota is not infeasible this is unlikely to be an issue.",
|
||||
)
|
||||
assigned_any_shift = {}
|
||||
for day in day_group:
|
||||
shifts_today = self.get_shift_names_by_week_day(week, day)
|
||||
|
||||
Reference in New Issue
Block a user