Increase max_number in LimitGradeNumberConstraint from 1 to 2 for better shift allocation and add internal leave removal functionality
This commit is contained in:
+38
-1
@@ -243,7 +243,7 @@ def main(
|
|||||||
PreShiftConstraint(days=2),
|
PreShiftConstraint(days=2),
|
||||||
PostShiftConstraint(days=2),
|
PostShiftConstraint(days=2),
|
||||||
RequireRemoteSitePresenceConstraint(site="plymouth", required_number=1),
|
RequireRemoteSitePresenceConstraint(site="plymouth", required_number=1),
|
||||||
LimitGradeNumberConstraint(grade=2, max_number=1),
|
LimitGradeNumberConstraint(grade=2, max_number=2),
|
||||||
MinimumGradeNumberConstraint(grade=4, min_number=1),
|
MinimumGradeNumberConstraint(grade=4, min_number=1),
|
||||||
],
|
],
|
||||||
#end_date=datetime.datetime.strptime("2025-06-01", "%Y-%m-%d").date(),
|
#end_date=datetime.datetime.strptime("2025-06-01", "%Y-%m-%d").date(),
|
||||||
@@ -283,6 +283,8 @@ def main(
|
|||||||
Rota.add_min_summed_grade_by_shifts_per_day_constraint(["weekend_plymouth1", "weekend_plymouth2"], 6)
|
Rota.add_min_summed_grade_by_shifts_per_day_constraint(["weekend_plymouth1", "weekend_plymouth2"], 6)
|
||||||
Rota.add_min_summed_grade_by_shifts_per_day_constraint(["plymouth_twilight", "plymouth_bank_holidays"], 6)
|
Rota.add_min_summed_grade_by_shifts_per_day_constraint(["plymouth_twilight", "plymouth_bank_holidays"], 6)
|
||||||
|
|
||||||
|
Rota.add_min_summed_grade_by_shifts_per_day_constraint(["night_weekday"], 12)
|
||||||
|
|
||||||
Rota.terminate_on_warning.remove("Worker/no valid shifts")
|
Rota.terminate_on_warning.remove("Worker/no valid shifts")
|
||||||
|
|
||||||
load_leave = True
|
load_leave = True
|
||||||
@@ -292,8 +294,43 @@ def main(
|
|||||||
if load_leave:
|
if load_leave:
|
||||||
import leave
|
import leave
|
||||||
|
|
||||||
|
# Internal-only option: remove leave requests between two dates.
|
||||||
|
# Configure by editing the two variables below (not exposed via CLI).
|
||||||
|
# Use strings in 'YYYY-MM-DD' or datetime.date objects. Set either to None to disable.
|
||||||
|
REMOVE_LEAVE_FROM = ""
|
||||||
|
REMOVE_LEAVE_TO = ""
|
||||||
|
|
||||||
workers = leave.load_leave(Rota)
|
workers = leave.load_leave(Rota)
|
||||||
|
|
||||||
|
# If the internal remove range is set, filter out NotAvailableToWork entries
|
||||||
|
if REMOVE_LEAVE_FROM and REMOVE_LEAVE_TO:
|
||||||
|
# Coerce to date objects if strings provided
|
||||||
|
def _to_date(v):
|
||||||
|
if isinstance(v, str):
|
||||||
|
for fmt in ("%Y-%m-%d", "%d/%m/%Y", "%d/%m/%y"):
|
||||||
|
try:
|
||||||
|
return datetime.datetime.strptime(v, fmt).date()
|
||||||
|
except Exception:
|
||||||
|
continue
|
||||||
|
raise ValueError(f"Cannot parse date: {v}")
|
||||||
|
if isinstance(v, datetime.datetime):
|
||||||
|
return v.date()
|
||||||
|
return v
|
||||||
|
|
||||||
|
_from = _to_date(REMOVE_LEAVE_FROM)
|
||||||
|
_to = _to_date(REMOVE_LEAVE_TO)
|
||||||
|
|
||||||
|
for name, w in list(workers.items()):
|
||||||
|
original = w.get("leave", [])
|
||||||
|
before_count = len(original)
|
||||||
|
filtered = [lr for lr in original if not (_from <= lr.date <= _to)]
|
||||||
|
after_count = len(filtered)
|
||||||
|
if after_count != before_count:
|
||||||
|
print(
|
||||||
|
f"Removed {before_count-after_count} leave entries for '{name}' between {_from} and {_to}"
|
||||||
|
)
|
||||||
|
w["leave"] = filtered
|
||||||
|
|
||||||
n = 0
|
n = 0
|
||||||
for worker in workers:
|
for worker in workers:
|
||||||
worker_name = worker
|
worker_name = worker
|
||||||
|
|||||||
Reference in New Issue
Block a user