Add constraints for maximum days and unique shifts per week block in worker model

This commit is contained in:
Ross
2026-05-19 21:23:09 +01:00
parent a071b1b027
commit dee80ed4fa
5 changed files with 192 additions and 4 deletions
+73 -1
View File
@@ -1,11 +1,19 @@
import datetime
import pytest
from pydantic import ValidationError
from rota_generator.shifts import (
InvalidShift, MaxShiftsPerWeekBlockConstraint, MaxShiftsPerWeekConstraint,
NoWorkers, PostShiftConstraint, PreShiftConstraint, RotaBuilder, SingleShift,
WarningTermination, days, WorkerRequirement
)
from rota_generator.workers import NotAvailableToWork, WorkRequests, Worker, generate_not_available_to_works
from rota_generator.workers import (
MaxDaysPerWeekBlockConstraint,
MaxUniqueShiftsPerWeekBlockConstraint,
NotAvailableToWork,
WorkRequests,
Worker,
generate_not_available_to_works,
)
def generate_basic_rota(weeks_to_rota=10, workers=2, start_date=datetime.date(2022, 3, 7)):
Rota = RotaBuilder(
@@ -89,6 +97,70 @@ def test_max_shifts_per_week_block_shift_number_fail():
Rota.export_rota_to_html("max_shifts_per_week_block")
assert Rota.results.solver.status in ("warning", "error")
def test_worker_max_days_per_week_block_fail():
Rota = RotaBuilder(datetime.date(2022, 3, 7), weeks_to_rota=2)
Rota.add_worker(
Worker(
name="worker1",
site="group1",
grade=1,
max_days_per_week_block=[
MaxDaysPerWeekBlockConstraint(max_days=1, week_block=1)
],
)
)
Rota.add_shifts(
SingleShift(
sites=("group1",),
name="a",
length=12.5,
days=days[:3],
workers_required=1,
)
)
Rota.build_and_solve(options={"ratio": 0.000})
assert Rota.results.solver.termination_condition == "infeasible"
def test_worker_max_unique_shifts_per_week_block_fail():
Rota = RotaBuilder(datetime.date(2022, 3, 7), weeks_to_rota=2)
Rota.add_worker(
Worker(
name="worker1",
site="group1",
grade=1,
max_unique_shifts_per_week_block=[
MaxUniqueShiftsPerWeekBlockConstraint(max_unique_shifts=1, week_block=1)
],
)
)
Rota.add_shifts(
SingleShift(
sites=("group1",),
name="a",
length=12.5,
days=["Mon"],
workers_required=1,
),
SingleShift(
sites=("group1",),
name="b",
length=12.5,
days=["Tue"],
workers_required=1,
),
)
Rota.build_and_solve(options={"ratio": 0.000})
assert Rota.results.solver.termination_condition == "infeasible"
def test_worker_block_constraint_validation():
with pytest.raises(ValidationError):
MaxDaysPerWeekBlockConstraint(max_days=0, week_block=1)
with pytest.raises(ValidationError):
MaxUniqueShiftsPerWeekBlockConstraint(max_unique_shifts=0, week_block=1)
def test_pre_shift_constraint():
Rota = generate_basic_rota()
for i, d in enumerate(days[:6]):