146 lines
4.3 KiB
Python
146 lines
4.3 KiB
Python
import pytest
|
|
import datetime
|
|
from rota_generator.shifts import NightConstraint, RotaBuilder, SingleShift, days
|
|
from rota_generator.workers import Worker
|
|
|
|
@pytest.fixture
|
|
def demo_rota_night_unavailable():
|
|
weeks_to_rota = 10
|
|
start_date = datetime.date(2022, 3, 7)
|
|
Rota = RotaBuilder(
|
|
start_date,
|
|
weeks_to_rota=weeks_to_rota,
|
|
)
|
|
worker1 = Worker(
|
|
name="worker1",
|
|
site="group1",
|
|
grade=1,
|
|
not_available_to_work=[
|
|
{
|
|
"date": datetime.datetime.strptime("15/03/22", "%d/%m/%y").date(),
|
|
"reason": "****",
|
|
},
|
|
],
|
|
)
|
|
worker2 = Worker(
|
|
name="worker2",
|
|
site="group1",
|
|
grade=1,
|
|
not_available_to_work=[
|
|
{
|
|
"date": datetime.datetime.strptime("14/03/22", "%d/%m/%y").date(),
|
|
"reason": "****",
|
|
}
|
|
],
|
|
)
|
|
Rota.add_workers((worker1, worker2))
|
|
return Rota
|
|
|
|
def test_basic_assignment(demo_rota_night_unavailable):
|
|
Rota = demo_rota_night_unavailable
|
|
Rota.shifts = []
|
|
Rota.add_shifts(
|
|
SingleShift(
|
|
sites=("group1",),
|
|
name="night_weekend",
|
|
length=12.5,
|
|
days=days[5:],
|
|
constraints=[NightConstraint()],
|
|
),
|
|
)
|
|
Rota.build_and_solve(options={"ratio": 0.00})
|
|
Rota.export_rota_to_html("testnight")
|
|
assert Rota.results.solver.status == "ok"
|
|
assert Rota.results.solver.termination_condition == "optimal"
|
|
summary = Rota.get_shift_summary_dict()
|
|
for worker in summary:
|
|
assert summary[worker]["night_weekend"] == 10
|
|
|
|
def test_assign_night_prior_to_unavailablity(demo_rota_night_unavailable):
|
|
Rota = demo_rota_night_unavailable
|
|
Rota.shifts = []
|
|
Rota.add_shifts(
|
|
SingleShift(
|
|
sites=("group1",),
|
|
name="night_weekend",
|
|
length=12.5,
|
|
days=days[5:],
|
|
workers_required=2,
|
|
constraints=[NightConstraint()],
|
|
),
|
|
)
|
|
Rota.build_and_solve(options={"ratio": 0.00})
|
|
Rota.export_rota_to_html("testnight_unavail")
|
|
assert Rota.results.solver.status in ("warning", "error")
|
|
assert Rota.results.solver.termination_condition == "infeasible"
|
|
|
|
def test_assign_non_night_prior_to_unavailablity(demo_rota_night_unavailable):
|
|
Rota = demo_rota_night_unavailable
|
|
Rota.shifts = []
|
|
Rota.add_shifts(
|
|
SingleShift(
|
|
sites=("group1",),
|
|
name="night_weekend",
|
|
length=12.5,
|
|
days=days[5:],
|
|
workers_required=2,
|
|
#constraint=[{"name": "night"}],
|
|
),
|
|
)
|
|
Rota.build_and_solve(options={"ratio": 0.00})
|
|
Rota.export_rota_to_html("testnight_unavail")
|
|
assert Rota.results.solver.status == "ok"
|
|
|
|
def test_assign_prior_to_unavailablity_non_night(demo_rota_night_unavailable):
|
|
Rota = demo_rota_night_unavailable
|
|
Rota.shifts = []
|
|
Rota.add_shifts(
|
|
SingleShift(
|
|
sites=("group1",),
|
|
name="night_weekend",
|
|
length=12.5,
|
|
days=days[5:],
|
|
workers_required=2,
|
|
constraints=[],
|
|
),
|
|
)
|
|
Rota.build_and_solve(options={"ratio": 0.00})
|
|
Rota.export_rota_to_html("testnight")
|
|
assert Rota.results.solver.status == "ok"
|
|
|
|
def test_assign_split(demo_rota_night_unavailable):
|
|
Rota = demo_rota_night_unavailable
|
|
Rota.shifts = []
|
|
worker3 = Worker(
|
|
name="worker3",
|
|
site="group1",
|
|
grade=1,
|
|
not_available_to_work=(
|
|
{"date": datetime.datetime.strptime("13/03/22", "%d/%m/%y").date()},
|
|
),
|
|
)
|
|
worker4 = Worker(
|
|
name="worker4",
|
|
site="group1",
|
|
grade=1,
|
|
not_available_to_work=(
|
|
{"date": datetime.datetime.strptime("12/03/22", "%d/%m/%y").date()},
|
|
),
|
|
)
|
|
Rota.add_workers((worker3, worker4))
|
|
Rota.add_shifts(
|
|
SingleShift(
|
|
sites=("group1",),
|
|
name="night_weekend",
|
|
length=12.5,
|
|
days=days[5:],
|
|
workers_required=3,
|
|
constraints=[],
|
|
),
|
|
)
|
|
Rota.build_and_solve(options={"ratio": 0.00})
|
|
Rota.export_rota_to_html("testnight")
|
|
assert Rota.results.solver.status == "ok"
|
|
summary = Rota.get_shift_summary_dict()
|
|
for worker in summary:
|
|
assert summary[worker]["night_weekend"] == 15 |