start working on shift paring balancing
This commit is contained in:
+5
-1
@@ -598,7 +598,11 @@ class TestDemoRotaBalanceShiftSites:
|
||||
self.Rota.constraint_options["balance_nights"] = False
|
||||
self.Rota.constraint_options["constrain_time_off_after_nights"] = False
|
||||
|
||||
self.Rota.terminate_on_warning.remove("Worker/no valid shifts")
|
||||
try:
|
||||
self.Rota.terminate_on_warning.remove("Worker/no valid shifts")
|
||||
except ValueError:
|
||||
# Seems to happen with sequential test running
|
||||
pass
|
||||
self.Rota.build_and_solve(options={"ratio": 0.1})
|
||||
|
||||
group_workers = self.Rota.get_workers_by_group()
|
||||
|
||||
+163
-2
@@ -2,7 +2,7 @@ import datetime
|
||||
import pytest
|
||||
from rota.shifts import InvalidShift, NoWorkers, RotaBuilder, SingleShift, WarningTermination, days
|
||||
|
||||
from rota.workers import Worker
|
||||
from rota.workers import NotAvailableToWork, WorkRequests, Worker
|
||||
|
||||
import itertools
|
||||
|
||||
@@ -438,4 +438,165 @@ class TestShiftDates:
|
||||
|
||||
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)
|
||||
assert Rota.get_worker_shift_list_string(worker).endswith("-"*28)
|
||||
|
||||
def test_shift_start_date_end_date_block_more_workers(self):
|
||||
Rota = generate_basic_rota(workers=10)
|
||||
|
||||
Rota.add_shifts(
|
||||
SingleShift(
|
||||
sites=("group1", "group2"), name="a", length= 12.5, days=days[:4],
|
||||
assign_as_block=True,
|
||||
force_as_block=True,
|
||||
workers_required=4,
|
||||
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))),
|
||||
),
|
||||
SingleShift(
|
||||
sites=("group1", "group2"), name="b", length= 12.5, days=days[4:],
|
||||
assign_as_block=True,
|
||||
force_as_block=True,
|
||||
workers_required=4,
|
||||
constraint=[{"name": "max_shifts_per_week", "options": 4},
|
||||
{"name": "pre", "options": 3}, {"name": "post", "options": 3}],
|
||||
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"
|
||||
|
||||
total_shifts = Rota.get_workers_total_shifts()
|
||||
for worker in Rota.get_workers():
|
||||
print(Rota.get_worker_shift_list_string(worker))
|
||||
assert total_shifts[worker.name] == 22
|
||||
assert "ab" not in Rota.get_worker_shift_list_string(worker)
|
||||
assert "ba" not in Rota.get_worker_shift_list_string(worker)
|
||||
|
||||
|
||||
def test_shift_start_date_end_date_block_with_requests(self):
|
||||
Rota = generate_basic_rota(workers=7)
|
||||
|
||||
|
||||
request_date = Rota.start_date + datetime.timedelta(days=(7*6)+4)
|
||||
request = [WorkRequests(date=request_date, shift="c")]
|
||||
|
||||
Rota.add_workers(
|
||||
[
|
||||
Worker(name=f"worker-wr-{i}", site="group2", grade=1, work_requests=request) for i in range(1, 4)
|
||||
#Worker(name="worker2", site="group1", grade=1),
|
||||
]
|
||||
)
|
||||
|
||||
Rota.add_shifts(
|
||||
SingleShift(
|
||||
sites=("group1", "group2"), name="a", length= 12.5, days=days[:4],
|
||||
assign_as_block=True,
|
||||
force_as_block=True,
|
||||
workers_required=4,
|
||||
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))),
|
||||
),
|
||||
SingleShift(
|
||||
sites=("group1", "group2"), name="b", length= 12.5, days=days[4:],
|
||||
assign_as_block=True,
|
||||
force_as_block=True,
|
||||
workers_required=4,
|
||||
constraint=[{"name": "max_shifts_per_week", "options": 4},
|
||||
{"name": "pre", "options": 3}, {"name": "post", "options": 3}],
|
||||
start_date=(Rota.start_date + datetime.timedelta(days=7)),
|
||||
end_date=(Rota.start_date + datetime.timedelta(days=((7*6)-1))),
|
||||
),
|
||||
SingleShift(
|
||||
sites=("group1", "group2"), name="c", length= 12.5, days=days[4:],
|
||||
assign_as_block=True,
|
||||
force_as_block=True,
|
||||
workers_required=4,
|
||||
constraint=[{"name": "max_shifts_per_week", "options": 4},
|
||||
{"name": "pre", "options": 3}, {"name": "post", "options": 3}],
|
||||
start_date=(Rota.start_date + datetime.timedelta(days=(7*6))),
|
||||
),
|
||||
)
|
||||
|
||||
Rota.build_and_solve(options={"ratio": 0.1})
|
||||
Rota.export_rota_to_html("test_shift_start_date")
|
||||
|
||||
assert Rota.results.solver.status == "ok"
|
||||
assert Rota.results.solver.termination_condition == "optimal"
|
||||
|
||||
total_shifts = Rota.get_workers_total_shifts()
|
||||
for worker in Rota.get_workers():
|
||||
print(Rota.get_worker_shift_list_string(worker))
|
||||
assert total_shifts[worker.name] in range(24,30)
|
||||
shift_string = Rota.get_worker_shift_list_string(worker)
|
||||
assert "ab" not in shift_string
|
||||
assert "ba" not in shift_string
|
||||
|
||||
# Check all has been assigned as block
|
||||
assert shift_string.count("aaaa") == shift_string.count("a") / 4
|
||||
assert shift_string.count("bbb") == shift_string.count("b") / 3
|
||||
assert shift_string.count("ccc") == shift_string.count("c") / 3
|
||||
|
||||
# TODO test the request assignment
|
||||
for worker in Rota.get_workers_by_group()["group2"]:
|
||||
assert Rota.get_worker_shifts_by_date(worker)[request_date] == "c"
|
||||
|
||||
def test_shift_start_date_end_date_block_paired(self):
|
||||
Rota = generate_basic_rota(workers=7)
|
||||
|
||||
|
||||
request_date = Rota.start_date + datetime.timedelta(days=(7*6)+4)
|
||||
|
||||
no_work = [NotAvailableToWork(date=d, shift="*") for d in date_generator(request_date, 18)]
|
||||
|
||||
Rota.add_workers(
|
||||
[
|
||||
Worker(name=f"worker-wr-{i}", site="group2", grade=1, not_available_to_work=no_work) for i in range(1, 4)
|
||||
#Worker(name="worker2", site="group1", grade=1),
|
||||
]
|
||||
)
|
||||
a, b, c = (SingleShift(
|
||||
sites=("group1", "group2"), name="a", length= 12.5, days=days[:4],
|
||||
workers_required=8,
|
||||
constraint=[{"name": "max_shifts_per_week", "options": 4}],
|
||||
end_date=(Rota.start_date + datetime.timedelta(days=7)),
|
||||
#end_date=(Rota.start_date + datetime.timedelta(days=((7*6)-1))),
|
||||
),
|
||||
SingleShift(
|
||||
sites=("group1", "group2"), name="b", length= 12.5, days=days[4:],
|
||||
assign_as_block=True,
|
||||
force_as_block=True,
|
||||
workers_required=4,
|
||||
constraint=[{"name": "max_shifts_per_week", "options": 4},
|
||||
{"name": "pre", "options": 3}, {"name": "post", "options": 3}],
|
||||
start_date=(Rota.start_date + datetime.timedelta(days=7)),
|
||||
end_date=(Rota.start_date + datetime.timedelta(days=((7*6)-1))),
|
||||
),
|
||||
SingleShift(
|
||||
sites=("group1", "group2"), name="c", length= 12.5, days=days[4:],
|
||||
assign_as_block=True,
|
||||
force_as_block=True,
|
||||
workers_required=4,
|
||||
constraint=[{"name": "max_shifts_per_week", "options": 4},
|
||||
{"name": "pre", "options": 3}, {"name": "post", "options": 3}],
|
||||
start_date=(Rota.start_date + datetime.timedelta(days=(7*6))),
|
||||
))
|
||||
|
||||
|
||||
Rota.add_shifts(
|
||||
a,
|
||||
b, c
|
||||
)
|
||||
Rota.pair_shifts(b, c)
|
||||
|
||||
Rota.build_and_solve(options={"ratio": 0.01})
|
||||
Rota.export_rota_to_html("test_shift_start_date")
|
||||
|
||||
assert Rota.results.solver.status == "ok"
|
||||
assert Rota.results.solver.termination_condition == "optimal"
|
||||
Reference in New Issue
Block a user