refactor and add some more tests

This commit is contained in:
Ross
2022-05-16 19:35:38 +01:00
parent ff03358119
commit f887257a55
6 changed files with 427 additions and 56 deletions
+92 -42
View File
@@ -2,10 +2,10 @@ import datetime
from collections import defaultdict
from typing import List
#from .shifts import RotaBuilder, days, sites
# from .shifts import RotaBuilder, days, sites
import uuid
#from rota.shifts import RotaBuilder
# from rota.shifts import RotaBuilder
from typing import TYPE_CHECKING
if TYPE_CHECKING:
@@ -21,9 +21,10 @@ class Worker:
grade: int,
id=None,
fte: int = 100,
nwd: list[str] | list[str, datetime.datetime, datetime.datetime]=[],
end_date: datetime.datetime | None =None,
oop=None,
nwd: list[str] | list[str, datetime.datetime, datetime.datetime] = [],
start_date: datetime.datetime | None = None,
end_date: datetime.datetime | None = None,
oop:list[(datetime.datetime, datetime.datetime, str)] | None = None,
not_available_to_work=None,
pref_not_to_work=None,
work_requests=None,
@@ -57,57 +58,106 @@ class Worker:
self.shift_target_number = defaultdict(int)
days_to_work = Rota.rota_days_length
#days_to_work = Rota.rota_days_length
# if no start date default to the start of the rota
if start_date is None:
self.start_date = Rota.start_date
else:
# ? test if start date is valid
self.start_date = start_date
if end_date is None:
self.end_date = None
self.end_date = Rota.rota_end_date
else:
self.end_date = datetime.datetime.strptime(end_date, "%d/%m/%y").date()
if isinstance(end_date, datetime.date):
self.end_date = end_date
else:
self.end_date = datetime.datetime.strptime(end_date, "%d/%m/%y").date()
if self.end_date > Rota.rota_end_date:
self.end_date = Rota.rota_end_date
else:
if self.end_date > Rota.start_date:
days_to_work = (self.end_date - Rota.start_date).days
# add unavalabilities
for weeks_days in Rota.weeks_days_product[days_to_work:]:
week, day = weeks_days
Rota.unavailable_to_work.add((self.id, week, day))
Rota.unavailable_to_work_reason[
(self.id, week, day)
] = "END DATE"
#if self.start_date >= self.end_date:
# raise ValueError("End date must be after start date")
days_to_work = (self.end_date - self.start_date).days
for week, day in Rota.weeks_days_product:
date = Rota.week_day_date_map[(week, day)]
if date < self.start_date:
Rota.unavailable_to_work.add((self.id, week, day))
Rota.unavailable_to_work_reason[
(self.id, week, day)
] = f"START DATE: {self.start_date}"
if date >= self.end_date:
Rota.unavailable_to_work.add((self.id, week, day))
Rota.unavailable_to_work_reason[
(self.id, week, day)
] = f"END DATE: {self.end_date}"
#if self.start_date > Rota.start_date:
# # add unavalabilities
# for weeks_days in Rota.weeks_days_product[:days_to_work]:
# week, day = weeks_days
# Rota.unavailable_to_work.add((self.id, week, day))
# Rota.unavailable_to_work_reason[
# (self.id, week, day)
# ] = f"START DATE: {self.start_date}"
#if self.end_date < Rota.rota_end_date:
# # add unavalabilities
# for weeks_days in Rota.weeks_days_product[days_to_work:]:
# week, day = weeks_days
# Rota.unavailable_to_work.add((self.id, week, day))
# Rota.unavailable_to_work_reason[
# (self.id, week, day)
# ] = f"END DATE: {self.end_date}"
if oop is not None:
start_oop, end_oop = oop
start_oop_date = datetime.datetime.strptime(start_oop, "%d/%m/%y").date()
end_oop_date = datetime.datetime.strptime(end_oop, "%d/%m/%y").date()
# ignore oops if they finish before the rota start date
print(end_oop_date, Rota.start_date)
if end_oop_date > Rota.start_date:
if start_oop_date > Rota.rota_end_date:
pass
for start_oop, end_oop, oop_name in oop:
#start_oop, end_oop = oop
if isinstance(start_oop, datetime.date):
start_oop_date = start_oop
else:
if end_oop_date > Rota.rota_end_date:
end_oop_date = Rota.rota_end_date
start_oop_date = datetime.datetime.strptime(start_oop, "%d/%m/%y").date()
if start_oop_date < Rota.start_date:
start_oop_date = Rota.start_date
if isinstance(end_oop, datetime.date):
end_oop_date = end_oop
else:
end_oop_date = datetime.datetime.strptime(end_oop, "%d/%m/%y").date()
oop_length = (end_oop_date - start_oop_date).days
days_to_work = days_to_work - oop_length
if start_oop_date >= end_oop_date:
raise ValueError("End OOP date must be after start date")
days_until_oop = (start_oop_date - Rota.start_date).days
# ignore oops if they finish before the rota (or worker) start date
if end_oop_date > self.start_date:
if start_oop_date > self.end_date:
pass
else:
if end_oop_date > Rota.rota_end_date:
end_oop_date = Rota.rota_end_date
for weeks_days in Rota.weeks_days_product[
days_until_oop : days_until_oop + oop_length
]:
week, day = weeks_days
Rota.unavailable_to_work.add((self.id, week, day))
Rota.unavailable_to_work_reason[
(self.id, week, day)
] = "OOP ()".format(oop)
if start_oop_date < Rota.start_date:
start_oop_date = Rota.start_date
oop_length = (end_oop_date - start_oop_date).days
days_to_work = days_to_work - oop_length
days_until_oop = (start_oop_date - Rota.start_date).days
for weeks_days in Rota.weeks_days_product[
days_until_oop : days_until_oop + oop_length
]:
week, day = weeks_days
Rota.unavailable_to_work.add((self.id, week, day))
Rota.unavailable_to_work_reason[
(self.id, week, day)
] = f"OOP ({oop_name})".format(oop)
if pref_not_to_work is not None:
# loop throught dates converting to week / day combination