work towards paring of shifts

This commit is contained in:
Ross
2024-12-24 10:41:46 +00:00
parent 70dc279a02
commit 1ed5f4fbcd
4 changed files with 238 additions and 37 deletions
+132 -5
View File
@@ -1,13 +1,13 @@
import datetime
import pytest
from rota.shifts import InvalidShift, NoWorkers, RotaBuilder, SingleShift, days
from rota.shifts import InvalidShift, NoWorkers, RotaBuilder, SingleShift, WarningTermination, days
from rota.workers import Worker
import itertools
def generate_basic_rota(weeks_to_rota=10):
def generate_basic_rota(weeks_to_rota=10, workers=2):
start_date = datetime.date(2022, 3, 7)
Rota = RotaBuilder(
@@ -18,8 +18,8 @@ def generate_basic_rota(weeks_to_rota=10):
# Add a few workers
Rota.add_workers(
[
Worker(name="worker1", site="group1", grade=1),
Worker(name="worker2", site="group1", grade=1),
Worker(name=f"worker{i}", site="group1", grade=1) for i in range(1, workers+1)
#Worker(name="worker2", site="group1", grade=1),
]
)
@@ -311,4 +311,131 @@ class TestShiftConstraints:
Rota.build_and_solve(options={"ratio": 0.000})
Rota.export_rota_to_html("post")
assert Rota.results.solver.status in ("warning", "error")
assert Rota.results.solver.status in ("warning", "error")
class TestShiftDates:
def test_shift_start_date(self):
Rota = generate_basic_rota(workers=2)
Rota.add_shifts(
SingleShift(
sites=("group1", "group2"), name="a", length= 12.5, days=days,
constraint=[{"name": "max_shifts_per_week", "options": 4}],
start_date=(Rota.start_date + datetime.timedelta(days=7)),
),
)
Rota.build_and_solve(options={"ratio": 0.000})
#Rota.export_rota_to_html("test_shift_start_date")
assert Rota.results.solver.status == "ok"
assert Rota.results.solver.termination_condition == "optimal"
assert Rota.get_workers_total_shifts()["worker1"] in (31, 32)
assert Rota.get_workers_total_shifts()["worker2"] in (31, 32)
def test_shift_start_date_end_date(self):
Rota = generate_basic_rota(workers=2)
Rota.add_shifts(
SingleShift(
sites=("group1", "group2"), name="a", length= 12.5, days=days,
constraint=[{"name": "max_shifts_per_week", "options": 4}],
start_date=(Rota.start_date + datetime.timedelta(days=7)),
end_date=(Rota.start_date + datetime.timedelta(days=((7*6)-1))),
),
)
Rota.build_and_solve(options={"ratio": 0.000})
#Rota.export_rota_to_html("test_shift_start_date")
assert Rota.results.solver.status == "ok"
assert Rota.results.solver.termination_condition == "optimal"
assert Rota.get_workers_total_shifts()["worker1"] in (17, 18)
assert Rota.get_workers_total_shifts()["worker2"] in (17, 18)
for worker in Rota.get_workers():
assert Rota.get_worker_shift_list_string(worker).startswith("-"*7)
assert Rota.get_worker_shift_list_string(worker).endswith("-"*28)
def test_shift_invalid_start_date(self):
Rota = generate_basic_rota(workers=2)
Rota.add_shifts(
SingleShift(
sites=("group1", "group2"), name="a", length= 12.5, days=days,
constraint=[{"name": "max_shifts_per_week", "options": 4}],
start_date=(Rota.start_date - datetime.timedelta(days=6)),
),
)
with pytest.raises(WarningTermination):
Rota.build_and_solve(options={"ratio": 0.000})
def test_shift_invalid_start_date2(self):
Rota = generate_basic_rota(workers=2)
Rota.add_shifts(
SingleShift(
sites=("group1", "group2"), name="a", length= 12.5, days=days,
constraint=[{"name": "max_shifts_per_week", "options": 4}],
start_date=(Rota.rota_end_date + datetime.timedelta(days=1)),
),
)
with pytest.raises(WarningTermination):
Rota.build_and_solve(options={"ratio": 0.000})
def test_shift_invalid_end_date(self):
Rota = generate_basic_rota(workers=2)
Rota.add_shifts(
SingleShift(
sites=("group1", "group2"), name="a", length= 12.5, days=days,
constraint=[{"name": "max_shifts_per_week", "options": 4}],
end_date=(Rota.rota_end_date + datetime.timedelta(days=1)),
),
)
with pytest.raises(WarningTermination):
Rota.build_and_solve(options={"ratio": 0.000})
def test_shift_invalid_end_date2(self):
Rota = generate_basic_rota(workers=2)
Rota.add_shifts(
SingleShift(
sites=("group1", "group2"), name="a", length= 12.5, days=days,
constraint=[{"name": "max_shifts_per_week", "options": 4}],
end_date=(Rota.start_date - datetime.timedelta(days=1)),
),
)
with pytest.raises(WarningTermination):
Rota.build_and_solve(options={"ratio": 0.000})
def test_shift_start_date_end_date_block(self):
Rota = generate_basic_rota(workers=2)
Rota.add_shifts(
SingleShift(
sites=("group1", "group2"), name="a", length= 12.5, days=days,
assign_as_block=True,
constraint=[{"name": "max_shifts_per_week", "options": 4}],
start_date=(Rota.start_date + datetime.timedelta(days=7)),
end_date=(Rota.start_date + datetime.timedelta(days=((7*6)-1))),
),
)
Rota.build_and_solve(options={"ratio": 0.000})
#Rota.export_rota_to_html("test_shift_start_date")
assert Rota.results.solver.status == "ok"
assert Rota.results.solver.termination_condition == "optimal"
assert Rota.get_workers_total_shifts()["worker1"] in (17, 18)
assert Rota.get_workers_total_shifts()["worker2"] in (17, 18)
for worker in Rota.get_workers():
assert Rota.get_worker_shift_list_string(worker).startswith("-"*7)
assert Rota.get_worker_shift_list_string(worker).endswith("-"*28)