diff --git a/rota_generator/shifts.py b/rota_generator/shifts.py
index 382d377..a8c34d4 100644
--- a/rota_generator/shifts.py
+++ b/rota_generator/shifts.py
@@ -470,6 +470,34 @@ class RotaBuilder(object):
setattr(self.constraint_options_model, constraint, value)
+ @property
+ def constraint_options(self):
+ """Backward-compat dict-like proxy for the typed
+ `constraint_options_model`. This keeps older code/tests working
+ while the canonical storage is `constraint_options_model`.
+ """
+
+ class _Proxy:
+ def __init__(self, model):
+ self._m = model
+
+ def __getitem__(self, key):
+ return getattr(self._m, key)
+
+ def __setitem__(self, key, value):
+ setattr(self._m, key, value)
+
+ def get(self, key, default=None):
+ return getattr(self._m, key, default)
+
+ def items(self):
+ return self._m.model_dump().items()
+
+ def __contains__(self, key):
+ return hasattr(self._m, key)
+
+ return _Proxy(self.constraint_options_model)
+
def set_rota_dates(self, start_date: datetime.date, weeks_to_rota: int):
self.weeks_to_rota = weeks_to_rota
@@ -4663,7 +4691,7 @@ class RotaBuilder(object):
Rota settings
- {json.dumps({k: _pydantic_to_dict(v) for k, v in self.constraint_options.items()}, indent=4)}
+ {json.dumps({k: _pydantic_to_dict(v) for k, v in self.constraint_options_model.model_dump().items()}, indent=4)}
diff --git a/test/rota_constraints/test_summed_shift_grade_constraints.py b/test/rota_constraints/test_summed_shift_grade_constraints.py
index 5c847b4..5fd5274 100644
--- a/test/rota_constraints/test_summed_shift_grade_constraints.py
+++ b/test/rota_constraints/test_summed_shift_grade_constraints.py
@@ -47,7 +47,7 @@ def test_summed_shift_grade_constraints():
)
# Add summed shift grade constraints
- Rota.constraint_options["min_summed_grade_by_shifts_per_day"].append(
+ Rota.constraint_options_model.min_summed_grade_by_shifts_per_day.append(
MinSummedGradeByShiftsPerDayConstraint(
shifts=["a", "b"],
min_grade_sum=4,
@@ -78,7 +78,7 @@ def test_summed_shift_grade_constraints():
for summed_grade in summed_grades:
assert summed_grade >= 4, f"Summed grade {summed_grade} is less than 4"
- Rota.constraint_options["min_summed_grade_by_shifts_per_day"] = [
+ Rota.constraint_options_model.min_summed_grade_by_shifts_per_day = [
MinSummedGradeByShiftsPerDayConstraint(
shifts=["a", "b"],
min_grade_sum=5,
diff --git a/test/test_limit_constraints.py b/test/test_limit_constraints.py
index f4f5633..9cadc21 100644
--- a/test/test_limit_constraints.py
+++ b/test/test_limit_constraints.py
@@ -257,7 +257,7 @@ def test_constraint_require_remote_site_presence_week2(limit_constraint_rota):
Rota = limit_constraint_rota
Rota.constraint_options["minimise_shift_diffs"] = False
Rota.constraint_options["balance_shifts_quadratic"] = False
- Rota.constraint_options["balance_shift"] = False
+ Rota.constraint_options["balance_shifts"] = False
Rota.constraint_options["balance_nights_across_sites"] = True
Rota.shifts = []
Rota.add_shifts(
diff --git a/test/test_remote.py b/test/test_remote.py
index f3f52d5..6076e1f 100644
--- a/test/test_remote.py
+++ b/test/test_remote.py
@@ -51,7 +51,7 @@ class TestRemoteRotas:
Rota.constraint_options["balance_blocks"] = False
Rota.constraint_options["balance_weekends"] = False
Rota.constraint_options["balance_nights"] = False
- Rota.constraint_options["minimse_shift_diffs"] = False
+ Rota.constraint_options["minimise_shift_diffs"] = False
Rota.add_workers(
[Worker(
@@ -111,7 +111,7 @@ class TestRemoteRotas:
Rota.constraint_options["balance_blocks"] = False
Rota.constraint_options["balance_weekends"] = False
Rota.constraint_options["balance_nights"] = False
- Rota.constraint_options["minimse_shift_diffs"] = False
+ Rota.constraint_options["minimise_shift_diffs"] = False
Rota.add_workers(
[Worker(
diff --git a/test/test_rota.py b/test/test_rota.py
index a954000..bc3cd51 100644
--- a/test/test_rota.py
+++ b/test/test_rota.py
@@ -19,16 +19,16 @@ def demo_rota():
weeks_to_rota=weeks_to_rota,
balance_offset_modifier=1,
)
- Rota.constraint_options["max_shifts_per_week"] = 5
- Rota.constraint_options["max_shifts_per_month"] = 31
- Rota.constraint_options["constrain_time_off_after_nights"] = False
- Rota.constraint_options["balance_nights_across_site"] = False
- Rota.constraint_options["balance_shifts_quadratic"] = True
- Rota.constraint_options["balance_shifts_over_workers"] = True
- Rota.constraint_options["balance_nights"] = False
- Rota.constraint_options["minimise_shift_diffs"] = False
- Rota.constraint_options["balance_blocks"] = False
- Rota.constraint_options["balance_bank_holidays"] = False
+ Rota.constraint_options_model.max_shifts_per_week = 5
+ Rota.constraint_options_model.max_shifts_per_month = 31
+ Rota.constraint_options_model.constrain_time_off_after_nights = False
+ Rota.constraint_options_model.balance_nights_across_sites = False
+ Rota.constraint_options_model.balance_shifts_quadratic = True
+ Rota.constraint_options_model.balance_shifts_over_workers = True
+ Rota.constraint_options_model.balance_nights = False
+ Rota.constraint_options_model.minimise_shift_diffs = False
+ Rota.constraint_options_model.balance_blocks = False
+ Rota.constraint_options_model.balance_bank_holidays = False
# Add a few workers
workers = [
diff --git a/test/test_rota_clear.py b/test/test_rota_clear.py
index 90b7057..f18e7e9 100644
--- a/test/test_rota_clear.py
+++ b/test/test_rota_clear.py
@@ -34,7 +34,7 @@ def demo_rota_clear():
weeks_to_rota=weeks_to_rota,
balance_offset_modifier=1,
)
- Rota.constraint_options["max_shifts_per_month"] = 20
+ Rota.constraint_options_model.max_shifts_per_month = 20
workers = [
Worker(name="worker1", site="group1", grade=1),
diff --git a/test/test_rota_nights.py b/test/test_rota_nights.py
index ee9ceec..d1b71ed 100644
--- a/test/test_rota_nights.py
+++ b/test/test_rota_nights.py
@@ -3,7 +3,7 @@ import pytest
from pytest import approx
from rota_generator.shifts import PostShiftConstraint, RotaBuilder, SingleShift, days
from rota_generator.workers import Worker
-from web.rota.shifts import PreShiftConstraint
+from rota_generator.shifts import PreShiftConstraint
@pytest.fixture
def demo_rota_nights():
@@ -16,17 +16,17 @@ def demo_rota_nights():
balance_offset_modifier=1,
)
- Rota.constraint_options["max_shifts_per_week"] = 5
- Rota.constraint_options["max_shifts_per_month"] = 31
- Rota.constraint_options["limit_to_1_st2_on_nights"] = False
- Rota.constraint_options["constrain_time_off_after_nights"] = False
- Rota.constraint_options["balance_nights_across_site"] = False
- Rota.constraint_options["balance_shifts"] = True
- Rota.constraint_options["balance_shifts_over_workers"] = True
- Rota.constraint_options["balance_nights"] = False
- Rota.constraint_options["minimise_shift_diffs"] = False
- Rota.constraint_options["balance_blocks"] = False
- Rota.constraint_options["max_night_frequency"] = 0
+ Rota.constraint_options_model.max_shifts_per_week = 5
+ Rota.constraint_options_model.max_shifts_per_month = 31
+ # legacy option `limit_to_1_st2_on_nights` removed; test omits it
+ Rota.constraint_options_model.constrain_time_off_after_nights = False
+ Rota.constraint_options_model.balance_nights_across_sites = False
+ Rota.constraint_options_model.balance_shifts = True
+ Rota.constraint_options_model.balance_shifts_over_workers = True
+ Rota.constraint_options_model.balance_nights = False
+ Rota.constraint_options_model.minimise_shift_diffs = False
+ Rota.constraint_options_model.balance_blocks = False
+ Rota.constraint_options_model.max_night_frequency = 0
# Add workers
workers = [
diff --git a/test/test_shift_constraints.py b/test/test_shift_constraints.py
index 5593e23..1da3fd1 100644
--- a/test/test_shift_constraints.py
+++ b/test/test_shift_constraints.py
@@ -36,36 +36,36 @@ def rota_3workers(rota_2workers):
return Rota3
def test_max_shifts(rota_2workers):
- rota_2workers.constraint_options["max_shifts_per_month"] = 14
+ rota_2workers.constraint_options_model.max_shifts_per_month = 14
rota_2workers.build_and_solve()
assert rota_2workers.results.solver.status == "ok"
assert rota_2workers.results.solver.termination_condition == "optimal"
def test_max_shifts_fail(rota_2workers):
- rota_2workers.constraint_options["max_shifts_per_month"] = 13
+ rota_2workers.constraint_options_model.max_shifts_per_month = 13
rota_2workers.build_and_solve()
assert rota_2workers.results.solver.status in ("warning", "error")
assert rota_2workers.results.solver.termination_condition == "infeasible"
def test_max_shifts_extra_worker(rota_3workers):
- rota_3workers.constraint_options["max_shifts_per_month"] = 12
+ rota_3workers.constraint_options_model.max_shifts_per_month = 12
rota_3workers.build_and_solve()
assert rota_3workers.results.solver.status == "ok"
assert rota_3workers.results.solver.termination_condition == "optimal"
def test_max_shifts_per_week_fail(rota_2workers):
- rota_2workers.constraint_options["max_shifts_per_week"] = 3
+ rota_2workers.constraint_options_model.max_shifts_per_week = 3
rota_2workers.build_and_solve()
assert rota_2workers.results.solver.status in ("warning", "error")
assert rota_2workers.results.solver.termination_condition == "infeasible"
def test_max_shifts_per_week_pass(rota_2workers):
- rota_2workers.constraint_options["max_shifts_per_month"] = 14
- rota_2workers.constraint_options["max_shifts_per_week"] = 4
+ rota_2workers.constraint_options_model.max_shifts_per_month = 14
+ rota_2workers.constraint_options_model.max_shifts_per_week = 4
rota_2workers.build_and_solve()
assert rota_2workers.results.solver.status == "ok"
def test_max_shifts_per_week_extra_worker_pass(rota_3workers):
- rota_3workers.constraint_options["max_shifts_per_week"] = 3
+ rota_3workers.constraint_options_model.max_shifts_per_week = 3
rota_3workers.build_and_solve()
assert rota_3workers.results.solver.status == "ok"
\ No newline at end of file
diff --git a/test/test_weekend_padding.py b/test/test_weekend_padding.py
index 95e2800..572fbde 100644
--- a/test/test_weekend_padding.py
+++ b/test/test_weekend_padding.py
@@ -20,7 +20,7 @@ class TestDemoRota:
start_date,
weeks_to_rota=weeks_to_rota,
)
- self.Rota.constraint_options["balance_weekends"] = True
+ self.Rota.constraint_options_model.balance_weekends = True
# Add a few workers
worker1 = Worker(name="worker1", site="group1", grade=1)
@@ -77,7 +77,7 @@ class TestDemoRota:
start_date,
weeks_to_rota=weeks_to_rota,
)
- self.Rota.constraint_options["balance_weekends"] = True
+ self.Rota.constraint_options_model.balance_weekends = True
# Add a few workers
worker1 = Worker(name="worker1", site="group1", grade=1)
@@ -136,7 +136,7 @@ class TestDemoRota:
start_date,
weeks_to_rota=weeks_to_rota,
)
- self.Rota.constraint_options["prevent_monday_and_tuesday_after_full_weekends"] = ["group1",]
+ self.Rota.constraint_options_model.prevent_monday_and_tuesday_after_full_weekends = ["group1",]
# Add a few workers
worker1 = Worker(name="worker1", site="group1", grade=1)
@@ -182,7 +182,7 @@ class TestDemoRota:
start_date,
weeks_to_rota=weeks_to_rota,
)
- self.Rota.constraint_options["prevent_monday_and_tuesday_after_full_weekends"] = ["group1",]
+ self.Rota.constraint_options_model.prevent_monday_and_tuesday_after_full_weekends = ["group1",]
# Add a few workers
worker1 = Worker(name="worker1", site="group1", grade=1)
@@ -221,7 +221,7 @@ class TestDemoRota:
start_date,
weeks_to_rota=weeks_to_rota,
)
- self.Rota.constraint_options["prevent_monday_after_full_weekends"] = ["group1",]
+ self.Rota.constraint_options_model.prevent_monday_after_full_weekends = ["group1",]
# Add a few workers
worker1 = Worker(name="worker1", site="group1", grade=1)
@@ -271,7 +271,7 @@ class TestDemoRota:
start_date,
weeks_to_rota=weeks_to_rota,
)
- self.Rota.constraint_options["prevent_monday_after_full_weekends"] = ["group1",]
+ self.Rota.constraint_options_model.prevent_monday_after_full_weekends = ["group1",]
# Add a few workers
worker1 = Worker(name="worker1", site="group1", grade=1)
@@ -312,7 +312,7 @@ class TestDemoRota:
start_date,
weeks_to_rota=weeks_to_rota,
)
- self.Rota.constraint_options["prevent_monday_after_full_weekends"] = ["group1",]
+ self.Rota.constraint_options_model.prevent_monday_after_full_weekends = ["group1",]
# Add a few workers
worker1 = Worker(name="worker1", site="group1", grade=1)
diff --git a/test/test_worker_requests.py b/test/test_worker_requests.py
index 38b96e3..b4354d6 100644
--- a/test/test_worker_requests.py
+++ b/test/test_worker_requests.py
@@ -224,7 +224,7 @@ class TestWorkerRequests:
"""_summary_"""
Rota = generate_basic_rota()
- Rota.constraint_options["balance_bank_holidays"] = False
+ Rota.constraint_options_model.balance_bank_holidays = False
Rota.add_worker(
Worker(
@@ -311,7 +311,7 @@ class TestWorkerRequests:
def test_work_requests(self):
"""_summary_"""
Rota = generate_basic_rota()
- Rota.constraint_options["balance_bank_holidays"] = False
+ Rota.constraint_options_model.balance_bank_holidays = False
Rota.add_workers(
[Worker(
@@ -362,7 +362,7 @@ class TestWorkerRequests:
def test_work_requests_invalid(self):
"""_summary_"""
Rota = generate_basic_rota()
- Rota.constraint_options["balance_bank_holidays"] = False
+ Rota.constraint_options_model.balance_bank_holidays = False
Rota.add_worker(
Worker(
@@ -433,7 +433,7 @@ class TestWorkerRequests:
def test_work_requests_generic(self):
"""_summary_"""
Rota = generate_basic_rota()
- Rota.constraint_options["balance_bank_holidays"] = False
+ Rota.constraint_options_model.balance_bank_holidays = False
Rota.add_workers(
[Worker(
@@ -484,7 +484,7 @@ class TestWorkerRequests:
def test_work_requests_generic2(self):
"""_summary_"""
Rota = generate_basic_rota()
- Rota.constraint_options["balance_bank_holidays"] = False
+ Rota.constraint_options_model.balance_bank_holidays = False
Rota.add_workers(
[Worker(
diff --git a/test/test_workers.py b/test/test_workers.py
index d8b31d3..d7029a2 100644
--- a/test/test_workers.py
+++ b/test/test_workers.py
@@ -4,7 +4,7 @@ from rota_generator.shifts import InvalidShift, MaxShiftsPerWeekConstraint, NoWo
import datetime
from rota_generator.workers import NonWorkingDays, NotAvailableToWork, Worker, generate_not_available_to_works
from rota_generator.workers import WorkRequests
-from web.rota.shifts import PreShiftConstraint
+from rota_generator.shifts import PreShiftConstraint
def generate_basic_rota(
weeks_to_rota=10, workers=0, start_date=datetime.date(2022, 3, 7)
@@ -357,7 +357,7 @@ def test_worker_pairs():
]
)
- Rota.constraint_options["hard_constrain_pair_separation"] = True
+ Rota.constraint_options_model.hard_constrain_pair_separation = True
Rota.build_and_solve()