pre repalce
This commit is contained in:
+38
-44
@@ -3,6 +3,8 @@ import datetime
|
|||||||
import itertools
|
import itertools
|
||||||
from typing import Dict, Iterable, List, Sequence, Tuple, Set
|
from typing import Dict, Iterable, List, Sequence, Tuple, Set
|
||||||
|
|
||||||
|
from pydantic import BaseModel, Extra
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
@@ -45,7 +47,7 @@ SHIFT_BOUNDS = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class SingleShift(object):
|
class SingleShift(BaseModel):
|
||||||
"""Class to hold all details for a shift
|
"""Class to hold all details for a shift
|
||||||
|
|
||||||
|
|
||||||
@@ -68,56 +70,49 @@ class SingleShift(object):
|
|||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
sites: Iterable[str]
|
||||||
|
name: str
|
||||||
|
length: float
|
||||||
|
shift_days: Sequence[str]
|
||||||
|
balance_offset: float | None = None,
|
||||||
|
balance_weighting: float = 1,
|
||||||
|
workers_required: float = 1,
|
||||||
|
rota_on_nwds: bool = False,
|
||||||
|
assign_as_block: bool = False,
|
||||||
|
force_as_block: bool = False,
|
||||||
|
force_as_block_unless_nwd: bool = False,
|
||||||
|
hard_constrain_shift: bool = True,
|
||||||
|
bank_holidays_only: bool = False,
|
||||||
|
constraint: Iterable[str] = [],
|
||||||
|
|
||||||
def __init__(
|
class Config:
|
||||||
self,
|
extra = Extra.allow
|
||||||
sites: Iterable[str],
|
|
||||||
name: str,
|
def __init__(self, **data: Any):
|
||||||
length: float,
|
super().__init__(**data)
|
||||||
shift_days: Sequence[str],
|
#self.site = sites
|
||||||
# balance_by_site=True,
|
#self.name = name
|
||||||
balance_offset: float | None = None,
|
#self.length = length
|
||||||
balance_weighting: float = 1,
|
#self.shift_days = shift_days
|
||||||
workers_required: float = 1,
|
|
||||||
rota_on_nwds: bool = False,
|
|
||||||
assign_as_block: bool = False,
|
|
||||||
force_as_block: bool = False,
|
|
||||||
force_as_block_unless_nwd: bool = False,
|
|
||||||
hard_constrain_shift: bool = True,
|
|
||||||
bank_holidays_only: bool = False,
|
|
||||||
constraints: Iterable[str] = [],
|
|
||||||
):
|
|
||||||
self.site = sites
|
|
||||||
self.name = name
|
|
||||||
self.length = length
|
|
||||||
self.shift_days = shift_days
|
|
||||||
# self.balance_by_site = balance_by_site
|
# self.balance_by_site = balance_by_site
|
||||||
# balance_offset defines the max difference in allocated shifts
|
# balance_offset defines the max difference in allocated shifts
|
||||||
# versus target shifts (hard constraint)
|
# versus target shifts (hard constraint)
|
||||||
# if 0 exactly equal shifts must be assigend (unlikely to be possible)
|
# if 0 exactly equal shifts must be assigend (unlikely to be possible)
|
||||||
|
|
||||||
if balance_offset is None:
|
|
||||||
self.balance_offset = len(shift_days)
|
|
||||||
else:
|
|
||||||
self.balance_offset = balance_offset
|
|
||||||
|
|
||||||
# weight the shift for balancing, default is 1
|
|
||||||
self.balance_weighting = balance_weighting
|
|
||||||
self.hard_constrain_shift = hard_constrain_shift
|
|
||||||
|
|
||||||
self.workers_required = workers_required
|
if self.balance_offset is None:
|
||||||
self.rota_on_nwds = rota_on_nwds
|
self.balance_offset = len(self.shift_days)
|
||||||
self.force_as_block = force_as_block
|
|
||||||
self.force_as_block_unless_nwd = force_as_block_unless_nwd
|
|
||||||
|
|
||||||
if force_as_block_unless_nwd:
|
|
||||||
|
if self.force_as_block_unless_nwd:
|
||||||
self.assign_as_block = True
|
self.assign_as_block = True
|
||||||
|
|
||||||
self.assign_as_block = assign_as_block
|
#self.assign_as_block = assign_as_block
|
||||||
|
|
||||||
self.constraint_options = {}
|
self.constraint_options = {}
|
||||||
self.constraints = []
|
self.constraints = []
|
||||||
for c in constraints:
|
for c in self.constraint:
|
||||||
match c:
|
match c:
|
||||||
case (constraint, options):
|
case (constraint, options):
|
||||||
self.constraints.append(constraint)
|
self.constraints.append(constraint)
|
||||||
@@ -125,9 +120,6 @@ class SingleShift(object):
|
|||||||
case constraint:
|
case constraint:
|
||||||
self.constraints.append(constraint)
|
self.constraints.append(constraint)
|
||||||
|
|
||||||
self.bank_holidays_only = bank_holidays_only
|
|
||||||
|
|
||||||
# self.total_shifts = length * len(days) * len(shift_days)
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"name: {self.name}, site: {self.site}, length: {self.length}, balance weighting: {self.balance_weighting}, balance offset: {self.balance_offset}, hard_constrain: {self.hard_constrain_shift}, workers required : {self.workers_required}, rota on nwds {self.rota_on_nwds}, assign as block: {self.assign_as_block}, force as block: {self.force_as_block}, constraints: {self.constraints}, constraint_options: {self.constraint_options}" # , total shifts: {self.total_shifts}"
|
return f"name: {self.name}, site: {self.site}, length: {self.length}, balance weighting: {self.balance_weighting}, balance offset: {self.balance_offset}, hard_constrain: {self.hard_constrain_shift}, workers required : {self.workers_required}, rota on nwds {self.rota_on_nwds}, assign as block: {self.assign_as_block}, force as block: {self.force_as_block}, constraints: {self.constraints}, constraint_options: {self.constraint_options}" # , total shifts: {self.total_shifts}"
|
||||||
@@ -154,6 +146,7 @@ class RotaBuilder(object):
|
|||||||
use_previous_shifts: bool = False,
|
use_previous_shifts: bool = False,
|
||||||
use_shift_balance_extra: bool = False,
|
use_shift_balance_extra: bool = False,
|
||||||
use_bank_holiday_extra: bool = False,
|
use_bank_holiday_extra: bool = False,
|
||||||
|
SHIFT_BOUNDS = SHIFT_BOUNDS
|
||||||
):
|
):
|
||||||
|
|
||||||
print(f"Start time: {datetime.datetime.now()}")
|
print(f"Start time: {datetime.datetime.now()}")
|
||||||
@@ -161,6 +154,7 @@ class RotaBuilder(object):
|
|||||||
print(f"Use previous shifts {use_previous_shifts}")
|
print(f"Use previous shifts {use_previous_shifts}")
|
||||||
print(f"Use previous shifts (balance_extra) {use_shift_balance_extra}")
|
print(f"Use previous shifts (balance_extra) {use_shift_balance_extra}")
|
||||||
|
|
||||||
|
self.SHIFT_BOUNDS = SHIFT_BOUNDS
|
||||||
self.shifts = [] # type List[SingleShift]
|
self.shifts = [] # type List[SingleShift]
|
||||||
|
|
||||||
self.days = days
|
self.days = days
|
||||||
@@ -341,7 +335,7 @@ class RotaBuilder(object):
|
|||||||
((worker.id) for worker in self.workers),
|
((worker.id) for worker in self.workers),
|
||||||
within=NonNegativeIntegers,
|
within=NonNegativeIntegers,
|
||||||
initialize=0,
|
initialize=0,
|
||||||
bounds=SHIFT_BOUNDS["bank_holiday"],
|
bounds=self.SHIFT_BOUNDS["bank_holiday"],
|
||||||
)
|
)
|
||||||
self.model.bank_holiday_count_w = Var(
|
self.model.bank_holiday_count_w = Var(
|
||||||
((worker.id) for worker in self.workers),
|
((worker.id) for worker in self.workers),
|
||||||
@@ -428,7 +422,7 @@ class RotaBuilder(object):
|
|||||||
),
|
),
|
||||||
domain=NonNegativeReals,
|
domain=NonNegativeReals,
|
||||||
initialize=0,
|
initialize=0,
|
||||||
bounds=SHIFT_BOUNDS["shift_count"],
|
bounds=self.SHIFT_BOUNDS["shift_count"],
|
||||||
)
|
)
|
||||||
|
|
||||||
self.model.shift_count_diff = Var(
|
self.model.shift_count_diff = Var(
|
||||||
@@ -501,7 +495,7 @@ class RotaBuilder(object):
|
|||||||
((worker.id) for worker in self.workers),
|
((worker.id) for worker in self.workers),
|
||||||
domain=NonNegativeReals,
|
domain=NonNegativeReals,
|
||||||
initialize=0,
|
initialize=0,
|
||||||
bounds=SHIFT_BOUNDS["night_shift_count"],
|
bounds=self.SHIFT_BOUNDS["night_shift_count"],
|
||||||
)
|
)
|
||||||
|
|
||||||
self.model.night_shift_count_t1 = Var(
|
self.model.night_shift_count_t1 = Var(
|
||||||
@@ -565,7 +559,7 @@ class RotaBuilder(object):
|
|||||||
((worker.id) for worker in self.workers),
|
((worker.id) for worker in self.workers),
|
||||||
domain=NonNegativeIntegers,
|
domain=NonNegativeIntegers,
|
||||||
initialize=0,
|
initialize=0,
|
||||||
bounds=SHIFT_BOUNDS["weekend_count"],
|
bounds=self.SHIFT_BOUNDS["weekend_count"],
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.constraint_options["balance_weekends"]:
|
if self.constraint_options["balance_weekends"]:
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ class TestBalancing:
|
|||||||
balance_weighting=4,
|
balance_weighting=4,
|
||||||
workers_required=1,
|
workers_required=1,
|
||||||
force_as_block=False,
|
force_as_block=False,
|
||||||
constraints=["preclear2", "postclear2"],
|
constraint=["preclear2", "postclear2"],
|
||||||
),
|
),
|
||||||
SingleShift(
|
SingleShift(
|
||||||
("group1", "group2"),
|
("group1", "group2"),
|
||||||
@@ -118,7 +118,7 @@ class TestBalancing:
|
|||||||
#balance_weighting=4,
|
#balance_weighting=4,
|
||||||
workers_required=1,
|
workers_required=1,
|
||||||
force_as_block=False,
|
force_as_block=False,
|
||||||
#constraints=["preclear2", "postclear2"],
|
#constraint=["preclear2", "postclear2"],
|
||||||
),
|
),
|
||||||
SingleShift(
|
SingleShift(
|
||||||
("group1", "group2"),
|
("group1", "group2"),
|
||||||
@@ -163,7 +163,7 @@ class TestBalancing:
|
|||||||
#balance_weighting=4,
|
#balance_weighting=4,
|
||||||
workers_required=1,
|
workers_required=1,
|
||||||
force_as_block=False,
|
force_as_block=False,
|
||||||
#constraints=["preclear2", "postclear2"],
|
#constraint=["preclear2", "postclear2"],
|
||||||
),
|
),
|
||||||
SingleShift(
|
SingleShift(
|
||||||
("group1", "group2"),
|
("group1", "group2"),
|
||||||
@@ -214,7 +214,7 @@ class TestBalancing:
|
|||||||
balance_weighting=8,
|
balance_weighting=8,
|
||||||
workers_required=2,
|
workers_required=2,
|
||||||
force_as_block=False,
|
force_as_block=False,
|
||||||
#constraints=["preclear2", "postclear2"],
|
#constraint=["preclear2", "postclear2"],
|
||||||
),
|
),
|
||||||
SingleShift(
|
SingleShift(
|
||||||
("group2","group3"),
|
("group2","group3"),
|
||||||
@@ -255,7 +255,7 @@ class TestBalancing:
|
|||||||
#balance_weighting=8,
|
#balance_weighting=8,
|
||||||
workers_required=2,
|
workers_required=2,
|
||||||
force_as_block=False,
|
force_as_block=False,
|
||||||
#constraints=["preclear2", "postclear2"],
|
#constraint=["preclear2", "postclear2"],
|
||||||
),
|
),
|
||||||
SingleShift(
|
SingleShift(
|
||||||
("group2","group3"),
|
("group2","group3"),
|
||||||
|
|||||||
+5
-5
@@ -37,7 +37,7 @@ class TestRemoteRotas:
|
|||||||
workers_required=1,
|
workers_required=1,
|
||||||
balance_offset=100,
|
balance_offset=100,
|
||||||
force_as_block=False,
|
force_as_block=False,
|
||||||
constraints=[("require_remote_site_presence_week", ("group2", 2))],
|
constraint=[("require_remote_site_presence_week", ("group2", 2))],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ class TestRemoteRotas:
|
|||||||
workers_required=1,
|
workers_required=1,
|
||||||
balance_offset=10,
|
balance_offset=10,
|
||||||
force_as_block=True,
|
force_as_block=True,
|
||||||
constraints=[("require_remote_site_presence_week", ("group2", 1))],
|
constraint=[("require_remote_site_presence_week", ("group2", 1))],
|
||||||
),
|
),
|
||||||
SingleShift(
|
SingleShift(
|
||||||
("group1", "group2"),
|
("group1", "group2"),
|
||||||
@@ -86,7 +86,7 @@ class TestRemoteRotas:
|
|||||||
workers_required=1,
|
workers_required=1,
|
||||||
balance_offset=10,
|
balance_offset=10,
|
||||||
force_as_block=False,
|
force_as_block=False,
|
||||||
#constraints=[("require_remote_site_presence_week", ("group2", 1))],
|
#constraint=[("require_remote_site_presence_week", ("group2", 1))],
|
||||||
#constraint=["balance_shifts_over_workers"]
|
#constraint=["balance_shifts_over_workers"]
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@@ -142,7 +142,7 @@ class TestRemoteRotas:
|
|||||||
workers_required=1,
|
workers_required=1,
|
||||||
balance_offset=10,
|
balance_offset=10,
|
||||||
force_as_block=False,
|
force_as_block=False,
|
||||||
constraints=[("require_remote_site_presence", ("group2", 1))],
|
constraint=[("require_remote_site_presence", ("group2", 1))],
|
||||||
),
|
),
|
||||||
SingleShift(
|
SingleShift(
|
||||||
("group1", "group2"),
|
("group1", "group2"),
|
||||||
@@ -152,7 +152,7 @@ class TestRemoteRotas:
|
|||||||
workers_required=1,
|
workers_required=1,
|
||||||
balance_offset=10,
|
balance_offset=10,
|
||||||
force_as_block=False,
|
force_as_block=False,
|
||||||
#constraints=[("require_remote_site_presence_week", ("group2", 1))],
|
#constraint=[("require_remote_site_presence_week", ("group2", 1))],
|
||||||
#constraint=["balance_shifts_over_workers"]
|
#constraint=["balance_shifts_over_workers"]
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
+27
-27
@@ -228,8 +228,8 @@ class TestDemoRotaNights:
|
|||||||
12.5,
|
12.5,
|
||||||
days[:4],
|
days[:4],
|
||||||
workers_required=1,
|
workers_required=1,
|
||||||
constraints=["preclear2", "postclear2"],
|
constraint=["preclear2", "postclear2"],
|
||||||
# constraints=["night"],
|
# constraint=["night"],
|
||||||
force_as_block=True
|
force_as_block=True
|
||||||
# We use a different balance weighting for each shift as otherwise
|
# We use a different balance weighting for each shift as otherwise
|
||||||
# the shifts can be treated equally (and no target diff)
|
# the shifts can be treated equally (and no target diff)
|
||||||
@@ -241,8 +241,8 @@ class TestDemoRotaNights:
|
|||||||
12.5,
|
12.5,
|
||||||
days[4:],
|
days[4:],
|
||||||
# balance_weighting=0.5
|
# balance_weighting=0.5
|
||||||
constraints=["preclear2", "postclear2"],
|
constraint=["preclear2", "postclear2"],
|
||||||
# constraints=["night"],
|
# constraint=["night"],
|
||||||
force_as_block=True,
|
force_as_block=True,
|
||||||
),
|
),
|
||||||
SingleShift(
|
SingleShift(
|
||||||
@@ -252,12 +252,12 @@ class TestDemoRotaNights:
|
|||||||
days[:5],
|
days[:5],
|
||||||
# balance_weighting=0.5
|
# balance_weighting=0.5
|
||||||
workers_required=2,
|
workers_required=2,
|
||||||
# constraints=["preclear2", "postclear2"],
|
# constraint=["preclear2", "postclear2"],
|
||||||
),
|
),
|
||||||
# SingleShift(("group1","group2"), "atwilight", 12.5, days[:5], balance_offset=40,
|
# SingleShift(("group1","group2"), "atwilight", 12.5, days[:5], balance_offset=40,
|
||||||
##balance_weighting=0.5
|
##balance_weighting=0.5
|
||||||
# workers_required=2,
|
# workers_required=2,
|
||||||
# #constraints=["postclear2"],
|
# #constraint=["postclear2"],
|
||||||
# ),
|
# ),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -329,7 +329,7 @@ class TestDemoRotaClear:
|
|||||||
days[:5],
|
days[:5],
|
||||||
balance_offset=40,
|
balance_offset=40,
|
||||||
workers_required=2,
|
workers_required=2,
|
||||||
constraints=["preclear"],
|
constraint=["preclear"],
|
||||||
),
|
),
|
||||||
SingleShift(
|
SingleShift(
|
||||||
("group1", "group2"),
|
("group1", "group2"),
|
||||||
@@ -346,7 +346,7 @@ class TestDemoRotaClear:
|
|||||||
days[3],
|
days[3],
|
||||||
balance_offset=40,
|
balance_offset=40,
|
||||||
workers_required=1,
|
workers_required=1,
|
||||||
constraints=["preclear2", "postclear2"],
|
constraint=["preclear2", "postclear2"],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -486,7 +486,7 @@ class TestDemoRotaBalanceShiftSites:
|
|||||||
balance_offset=40,
|
balance_offset=40,
|
||||||
workers_required=2,
|
workers_required=2,
|
||||||
force_as_block=True,
|
force_as_block=True,
|
||||||
constraints=["balance_across_groups"],
|
constraint=["balance_across_groups"],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
self.Rota.constraint_options["balance_nights_across_sites"] = False
|
self.Rota.constraint_options["balance_nights_across_sites"] = False
|
||||||
@@ -522,7 +522,7 @@ class TestDemoRotaBalanceShiftSites:
|
|||||||
balance_offset=40,
|
balance_offset=40,
|
||||||
workers_required=3,
|
workers_required=3,
|
||||||
force_as_block=True,
|
force_as_block=True,
|
||||||
constraints=["balance_across_groups"],
|
constraint=["balance_across_groups"],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
self.Rota.constraint_options["balance_nights_across_sites"] = False
|
self.Rota.constraint_options["balance_nights_across_sites"] = False
|
||||||
@@ -556,7 +556,7 @@ class TestDemoRotaBalanceShiftSites:
|
|||||||
balance_offset=40,
|
balance_offset=40,
|
||||||
workers_required=3,
|
workers_required=3,
|
||||||
force_as_block=True,
|
force_as_block=True,
|
||||||
constraints=["balance_across_groups"],
|
constraint=["balance_across_groups"],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
self.Rota.constraint_options["balance_nights_across_sites"] = False
|
self.Rota.constraint_options["balance_nights_across_sites"] = False
|
||||||
@@ -614,7 +614,7 @@ class TestLimitConstraints:
|
|||||||
balance_offset=40,
|
balance_offset=40,
|
||||||
workers_required=4,
|
workers_required=4,
|
||||||
force_as_block=True,
|
force_as_block=True,
|
||||||
constraints=[("limit_grade_number", {2: 1})],
|
constraint=[("limit_grade_number", {2: 1})],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
# self.Rota.constraint_options["balance_nights_across_sites"] = False
|
# self.Rota.constraint_options["balance_nights_across_sites"] = False
|
||||||
@@ -650,7 +650,7 @@ class TestLimitConstraints:
|
|||||||
balance_offset=40,
|
balance_offset=40,
|
||||||
workers_required=4,
|
workers_required=4,
|
||||||
force_as_block=True,
|
force_as_block=True,
|
||||||
constraints=[("limit_grade_number", {3: 2})],
|
constraint=[("limit_grade_number", {3: 2})],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
# self.Rota.constraint_options["balance_nights_across_sites"] = False
|
# self.Rota.constraint_options["balance_nights_across_sites"] = False
|
||||||
@@ -688,7 +688,7 @@ class TestLimitConstraints:
|
|||||||
balance_offset=40,
|
balance_offset=40,
|
||||||
workers_required=4,
|
workers_required=4,
|
||||||
force_as_block=True,
|
force_as_block=True,
|
||||||
constraints=[("limit_grade_number", {2: 3, 3: 1})],
|
constraint=[("limit_grade_number", {2: 3, 3: 1})],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
# self.Rota.constraint_options["balance_nights_across_sites"] = False
|
# self.Rota.constraint_options["balance_nights_across_sites"] = False
|
||||||
@@ -726,7 +726,7 @@ class TestLimitConstraints:
|
|||||||
balance_offset=40,
|
balance_offset=40,
|
||||||
workers_required=4,
|
workers_required=4,
|
||||||
force_as_block=True,
|
force_as_block=True,
|
||||||
constraints=[("limit_grade_number", {2: 4, 3: 0})],
|
constraint=[("limit_grade_number", {2: 4, 3: 0})],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
# self.Rota.constraint_options["balance_nights_across_sites"] = False
|
# self.Rota.constraint_options["balance_nights_across_sites"] = False
|
||||||
@@ -747,7 +747,7 @@ class TestLimitConstraints:
|
|||||||
balance_offset=40,
|
balance_offset=40,
|
||||||
workers_required=1,
|
workers_required=1,
|
||||||
force_as_block=True,
|
force_as_block=True,
|
||||||
constraints=[("minimum_grade_number", (3, 1))],
|
constraint=[("minimum_grade_number", (3, 1))],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -783,7 +783,7 @@ class TestLimitConstraints:
|
|||||||
balance_offset=40,
|
balance_offset=40,
|
||||||
workers_required=4,
|
workers_required=4,
|
||||||
force_as_block=True,
|
force_as_block=True,
|
||||||
constraints=[("minimum_grade_number", (3, 3))],
|
constraint=[("minimum_grade_number", (3, 3))],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -819,7 +819,7 @@ class TestLimitConstraints:
|
|||||||
balance_offset=40,
|
balance_offset=40,
|
||||||
workers_required=4,
|
workers_required=4,
|
||||||
force_as_block=True,
|
force_as_block=True,
|
||||||
constraints=[("minimum_grade_number", (3, 0))],
|
constraint=[("minimum_grade_number", (3, 0))],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -841,7 +841,7 @@ class TestLimitConstraints:
|
|||||||
balance_offset=40,
|
balance_offset=40,
|
||||||
workers_required=4,
|
workers_required=4,
|
||||||
force_as_block=True,
|
force_as_block=True,
|
||||||
constraints=[("minimum_grade_number", (4, 1))],
|
constraint=[("minimum_grade_number", (4, 1))],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -860,7 +860,7 @@ class TestLimitConstraints:
|
|||||||
balance_offset=40,
|
balance_offset=40,
|
||||||
workers_required=2,
|
workers_required=2,
|
||||||
force_as_block=True,
|
force_as_block=True,
|
||||||
constraints=[("require_remote_site_presence_week", ("group1", 2))],
|
constraint=[("require_remote_site_presence_week", ("group1", 2))],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
self.Rota.build_and_solve(options={"ratio": 0.00})
|
self.Rota.build_and_solve(options={"ratio": 0.00})
|
||||||
@@ -898,7 +898,7 @@ class TestLimitConstraints:
|
|||||||
balance_offset=20,
|
balance_offset=20,
|
||||||
workers_required=3,
|
workers_required=3,
|
||||||
force_as_block=True,
|
force_as_block=True,
|
||||||
constraints=[("require_remote_site_presence_week", ("group2", 2))],
|
constraint=[("require_remote_site_presence_week", ("group2", 2))],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
self.Rota.build_and_solve(options={"ratio": 0.00})
|
self.Rota.build_and_solve(options={"ratio": 0.00})
|
||||||
@@ -930,7 +930,7 @@ class TestLimitConstraints:
|
|||||||
balance_offset=20,
|
balance_offset=20,
|
||||||
workers_required=3,
|
workers_required=3,
|
||||||
force_as_block=True,
|
force_as_block=True,
|
||||||
constraints=[("require_remote_site_presence_week", ("group2", 1))],
|
constraint=[("require_remote_site_presence_week", ("group2", 1))],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
self.Rota.build_and_solve(options={"ratio": 0.00})
|
self.Rota.build_and_solve(options={"ratio": 0.00})
|
||||||
@@ -995,7 +995,7 @@ class TestNightUnavailable:
|
|||||||
# Add a weekday and weekend shift
|
# Add a weekday and weekend shift
|
||||||
self.Rota.add_shifts(
|
self.Rota.add_shifts(
|
||||||
SingleShift(
|
SingleShift(
|
||||||
("group1",), "night_weekend", 12.5, days[5:], constraints=["night"]
|
("group1",), "night_weekend", 12.5, days[5:], constraint=["night"]
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1018,7 +1018,7 @@ class TestNightUnavailable:
|
|||||||
# Add a weekday and weekend shift
|
# Add a weekday and weekend shift
|
||||||
self.Rota.add_shifts(
|
self.Rota.add_shifts(
|
||||||
SingleShift(
|
SingleShift(
|
||||||
("group1",), "night_weekend", 12.5, days[5:], workers_required=2, constraints=["night"]
|
("group1",), "night_weekend", 12.5, days[5:], workers_required=2, constraint=["night"]
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1032,7 +1032,7 @@ class TestNightUnavailable:
|
|||||||
|
|
||||||
self.Rota.add_shifts(
|
self.Rota.add_shifts(
|
||||||
SingleShift(
|
SingleShift(
|
||||||
("group1",), "night_weekend", 12.5, days[5:], workers_required=2, constraints=[]
|
("group1",), "night_weekend", 12.5, days[5:], workers_required=2, constraint=[]
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1053,7 +1053,7 @@ class TestNightUnavailable:
|
|||||||
|
|
||||||
self.Rota.add_shifts(
|
self.Rota.add_shifts(
|
||||||
SingleShift(
|
SingleShift(
|
||||||
("group1",), "night_weekend", 12.5, days[5:], workers_required=3, constraints=[]
|
("group1",), "night_weekend", 12.5, days[5:], workers_required=3, constraint=[]
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1079,7 +1079,7 @@ class TestNightUnavailable:
|
|||||||
#
|
#
|
||||||
# self.Rota.add_shifts(
|
# self.Rota.add_shifts(
|
||||||
# SingleShift(
|
# SingleShift(
|
||||||
# ("group1",), "night_weekend", 12.5, days[5:], workers_required=3, constraints=["night"]
|
# ("group1",), "night_weekend", 12.5, days[5:], workers_required=3, constraint=["night"]
|
||||||
# ),
|
# ),
|
||||||
# )
|
# )
|
||||||
#
|
#
|
||||||
|
|||||||
Reference in New Issue
Block a user