.
This commit is contained in:
+160
-22
@@ -23,8 +23,6 @@ class TestDemoRota:
|
||||
Rota.constraint_options["max_shifts_per_week"] = 5
|
||||
Rota.constraint_options["max_shifts_per_month"] = 31
|
||||
Rota.constraint_options["ensure_derriford_reg_for_nights"] = False
|
||||
Rota.constraint_options["limit_to_1_st2_on_nights"] = False
|
||||
Rota.constraint_options["ensure_1_st4_plus_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
|
||||
@@ -190,7 +188,6 @@ class TestDemoRotaNights:
|
||||
Rota.constraint_options["max_shifts_per_month"] = 31
|
||||
Rota.constraint_options["ensure_derriford_reg_for_nights"] = False
|
||||
Rota.constraint_options["limit_to_1_st2_on_nights"] = False
|
||||
Rota.constraint_options["ensure_1_st4_plus_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
|
||||
@@ -292,18 +289,8 @@ class TestDemoRotaClear:
|
||||
balance_offset_modifier=1,
|
||||
max_weekend_frequency=1,
|
||||
)
|
||||
#Rota.constraint_options["max_shifts_per_week"] = 5
|
||||
Rota.constraint_options["max_shifts_per_month"] = 20
|
||||
#Rota.constraint_options["ensure_derriford_reg_for_nights"] = False
|
||||
#Rota.constraint_options["limit_to_1_st2_on_nights"] = False
|
||||
#Rota.constraint_options["ensure_1_st4_plus_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
|
||||
|
||||
|
||||
worker1 = Worker(Rota, "worker1", "group1", 1)
|
||||
worker2 = Worker(Rota, "worker2", "group1", 1)
|
||||
@@ -549,12 +536,12 @@ class TestLimitConstraints:
|
||||
)
|
||||
#Rota.constraint_options["max_shifts_per_week"] = 5
|
||||
#Rota.constraint_options["max_shifts_per_month"] = 20
|
||||
worker1 = Worker(Rota, "worker1", "group1", 2)
|
||||
worker2 = Worker(Rota, "worker2", "group1", 2)
|
||||
worker3 = Worker(Rota, "worker3", "group1", 2)
|
||||
worker4 = Worker(Rota, "worker4", "group3", 3)
|
||||
worker5 = Worker(Rota, "worker5", "group3", 3)
|
||||
worker6 = Worker(Rota, "worker6", "group3", 3)
|
||||
worker1 = Worker(Rota, "worker1", "group1", 2, home_site="group1")
|
||||
worker2 = Worker(Rota, "worker2", "group1", 2, home_site="group1")
|
||||
worker3 = Worker(Rota, "worker3", "group1", 2, home_site="group1")
|
||||
worker4 = Worker(Rota, "worker4", "group3", 3, home_site="group2")
|
||||
worker5 = Worker(Rota, "worker5", "group3", 3, home_site="group2")
|
||||
worker6 = Worker(Rota, "worker6", "group3", 3, home_site="group2")
|
||||
|
||||
Rota.add_workers((worker1, worker2, worker3, worker4))
|
||||
Rota.add_workers((worker5, worker6))
|
||||
@@ -673,9 +660,160 @@ class TestLimitConstraints:
|
||||
self.Rota.constraint_options["balance_shifts_quadratic"] = True
|
||||
self.Rota.build_and_solve(options={"ratio": 0.1})
|
||||
|
||||
assert self.Rota.results.solver.termination_condition == "infeasible"
|
||||
|
||||
def test_constraint_minimum_grades(self):
|
||||
self.Rota.shifts = []
|
||||
self.Rota.add_shifts(
|
||||
SingleShift(("group1", "group2", "group3"), "weekday_night", 12.5, days, balance_offset=40,
|
||||
workers_required=1,
|
||||
force_as_block=True,
|
||||
constraints=[("minimum_grade_number", (3, 1))]
|
||||
),
|
||||
)
|
||||
|
||||
self.Rota.constraint_options["balance_shifts_quadratic"] = True
|
||||
self.Rota.build_and_solve(options={"ratio": 0.1})
|
||||
|
||||
self.Rota.export_rota_to_html("test9")
|
||||
|
||||
assert self.Rota.results.solver.termination_condition == "infeasible"
|
||||
grade_workers = self.Rota.get_workers_by_grade()
|
||||
for grade in grade_workers:
|
||||
shift_patterns = []
|
||||
for w in grade_workers[grade]:
|
||||
shift_patterns.append(self.Rota.get_worker_shift_list(w))
|
||||
|
||||
zipped_lists = list(zip(*shift_patterns))
|
||||
|
||||
limit = 0
|
||||
if grade > 2:
|
||||
limit = 1
|
||||
for day_shifts in zipped_lists:
|
||||
assert day_shifts.count("weekday_night") == limit
|
||||
|
||||
assert self.Rota.results.solver.status == "ok"
|
||||
|
||||
def test_constraint_minimum_grades2(self):
|
||||
self.Rota.shifts = []
|
||||
self.Rota.add_shifts(
|
||||
SingleShift(("group1", "group2", "group3"), "weekday_night", 12.5, days, balance_offset=40,
|
||||
workers_required=4,
|
||||
force_as_block=True,
|
||||
constraints=[("minimum_grade_number", (3, 3))]
|
||||
),
|
||||
)
|
||||
|
||||
self.Rota.constraint_options["balance_shifts_quadratic"] = True
|
||||
self.Rota.build_and_solve(options={"ratio": 0.1})
|
||||
|
||||
self.Rota.export_rota_to_html("test9")
|
||||
|
||||
grade_workers = self.Rota.get_workers_by_grade()
|
||||
for grade in grade_workers:
|
||||
shift_patterns = []
|
||||
for w in grade_workers[grade]:
|
||||
shift_patterns.append(self.Rota.get_worker_shift_list(w))
|
||||
|
||||
zipped_lists = list(zip(*shift_patterns))
|
||||
|
||||
limit = 1
|
||||
if grade > 2:
|
||||
limit = 3
|
||||
for day_shifts in zipped_lists:
|
||||
assert day_shifts.count("weekday_night") == limit
|
||||
|
||||
assert self.Rota.results.solver.status == "ok"
|
||||
|
||||
def test_constraint_minimum_grades3(self):
|
||||
self.Rota.shifts = []
|
||||
self.Rota.add_shifts(
|
||||
SingleShift(("group1", "group2", "group3"), "weekday_night", 12.5, days, balance_offset=40,
|
||||
workers_required=4,
|
||||
force_as_block=True,
|
||||
constraints=[("minimum_grade_number", (3, 0))]
|
||||
),
|
||||
)
|
||||
|
||||
self.Rota.constraint_options["balance_shifts_quadratic"] = True
|
||||
self.Rota.build_and_solve(options={"ratio": 0.1})
|
||||
|
||||
self.Rota.export_rota_to_html("test9")
|
||||
|
||||
assert self.Rota.results.solver.status == "ok"
|
||||
|
||||
def test_constraint_minimum_grades_no_valid_worker(self):
|
||||
self.Rota.shifts = []
|
||||
self.Rota.add_shifts(
|
||||
SingleShift(("group1", "group2", "group3"), "weekday_night", 12.5, days, balance_offset=40,
|
||||
workers_required=4,
|
||||
force_as_block=True,
|
||||
constraints=[("minimum_grade_number", (4, 1))]
|
||||
),
|
||||
)
|
||||
|
||||
self.Rota.constraint_options["balance_shifts_quadratic"] = True
|
||||
with pytest.raises(ValueError):
|
||||
self.Rota.build_and_solve(options={"ratio": 0.1})
|
||||
|
||||
|
||||
def test_constraint_require_home_site_presence(self):
|
||||
self.Rota.shifts = []
|
||||
self.Rota.add_shifts(
|
||||
SingleShift(("group1", "group2", "group3"), "weekday_night", 12.5, days, balance_offset=40,
|
||||
workers_required=2,
|
||||
force_as_block=True,
|
||||
constraints=[("require_home_site_presence", ("group1", 2))]
|
||||
),
|
||||
)
|
||||
self.Rota.build_and_solve(options={"ratio": 0.00})
|
||||
self.Rota.export_rota_to_html("test9")
|
||||
|
||||
group_workers = self.Rota.get_workers_by_group()
|
||||
for group in group_workers:
|
||||
shift_patterns = []
|
||||
for w in group_workers[group]:
|
||||
shift_patterns.append(self.Rota.get_worker_shift_list(w))
|
||||
|
||||
zipped_lists = list(zip(*shift_patterns))
|
||||
|
||||
limit = 2
|
||||
if group != "group1":
|
||||
limit = 0
|
||||
for day_shifts in zipped_lists:
|
||||
assert day_shifts.count("weekday_night") == limit
|
||||
|
||||
|
||||
assert self.Rota.results.solver.status == "ok"
|
||||
assert self.Rota.results.solver.termination_condition == "optimal"
|
||||
|
||||
def test_constraint_require_home_site_presence2(self):
|
||||
self.Rota.shifts = []
|
||||
self.Rota.add_shifts(
|
||||
SingleShift(("group1", "group2", "group3"), "weekday_night", 12.5, days, balance_offset=40,
|
||||
workers_required=3,
|
||||
force_as_block=True,
|
||||
constraints=[("require_home_site_presence", ("group2", 2))]
|
||||
),
|
||||
)
|
||||
self.Rota.build_and_solve(options={"ratio": 0.00})
|
||||
self.Rota.export_rota_to_html("test9")
|
||||
|
||||
group_workers = self.Rota.get_workers_by_group()
|
||||
for group in group_workers:
|
||||
shift_patterns = []
|
||||
for w in group_workers[group]:
|
||||
shift_patterns.append(self.Rota.get_worker_shift_list(w))
|
||||
|
||||
zipped_lists = list(zip(*shift_patterns))
|
||||
|
||||
if group == "group2":
|
||||
for day_shifts in zipped_lists:
|
||||
assert day_shifts.count("weekday_night") >= 2
|
||||
|
||||
|
||||
assert self.Rota.results.solver.status == "ok"
|
||||
assert self.Rota.results.solver.termination_condition == "optimal"
|
||||
|
||||
|
||||
#class TestNoWorkerRota:
|
||||
# weeks_to_rota = 10
|
||||
@@ -693,4 +831,4 @@ class TestLimitConstraints:
|
||||
|
||||
if __name__ == "__main__":
|
||||
t = TestLimitConstraints()
|
||||
t.test_constraint_limit_grades4()
|
||||
t.test_constraint_require_home_site_presence()
|
||||
|
||||
Reference in New Issue
Block a user