.
This commit is contained in:
@@ -1,25 +1,25 @@
|
||||
Rota 2021/2022,,, (POSSIBLE IDT),,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,80% until dec 1st,,,,,,,,,,,,,,,,
|
||||
Name,,Stephanie Bailey,Luciana Calovi Motschenbacher,Layla Bell,Seren Peters,Alex wood,Salma Aslam,Max Ireland,Charles Finan,Paul Ward,Tom Welsh,Delilah Trimmer,Max Finzel,Zainab Sharaf,Maththew O'Brien,Kyaw Tint,Nicolas Dziadulewicz,Jean Skumar,Michael Tomek,Vilim Kalamar,Dhuvresh Patel,Khalil Madbak,Georgina Edwards,Jenn Haw fong,Paul Jenkins,Jenna Millington,Amoolya Mannava,Ross Kruger,Sophie McGlade,Rebecca Murphy,Fiona Lyall,Joel Lim,Wijhdan Abusrewil,Mark Haley,Andrew MacCormick,Alexander Sanchez - cabello,Sayed Hashim Alqarooni,Chong Yew Ng,Matthew Thorley,Harriet Conley,Jon Skinner,Cameron Bullock,Alexander Wijnberg,Christian Greer,Alan Eccles,Hannah Lewis,Sarath Vennam,Amina Odeh,Mo Babsail,Richard Chaytor,Sherafghan PROC,Madalina Drumea,Mark Fellows,Clement Leung
|
||||
Rotation,,Exeter,Exeter,Exeter,Exeter,Exeter,Exeter,Exeter,Exeter,Exeter,Exeter,Exeter,Derriford,Derriford,Derriford,Derriford,Derriford,Derriford,Derriford,Derriford,Derriford,Derriford,Derriford,Derriford,Derriford,Derriford,Derriford,Derriford,Derriford,Derriford,Derriford Twilights,Torbay,Torbay,Torbay,Torbay,Torbay,Torbay,Torbay,Torbay,Torbay,Torbay Twilights,Truro,Truro,Truro,Truro,Truro,Truro,Truro,Truro,Truro,Truro no PROC,Barnstaple,Taunton,Taunton
|
||||
Rotation,,Exeter,Exeter,Exeter,Exeter,Exeter,Exeter,Exeter,Exeter,Exeter,Exeter,Exeter,Derriford,Derriford,Derriford,Derriford,Derriford,Derriford,Derriford,Derriford,Derriford,Derriford,Derriford,Derriford,Derriford,Derriford no proc,Derriford,Derriford,Derriford,Derriford,Derriford Twilights,Torbay,Torbay,Torbay,Torbay,Torbay,Torbay,Torbay,Torbay,Torbay,Torbay Twilights,Truro,Truro,Truro,Truro,Truro,Truro,Truro,Truro,Truro,Truro no PROC,Barnstaple,Taunton,Taunton
|
||||
Grade,,ST2,ST2,ST2,ST3,ST3,ST3,ST3,ST4,ST4,ST5,ST5,ST2,ST2,ST2,ST2,ST3,ST3,ST3,ST3,ST3,ST4,ST4,ST4,ST4,ST4,ST5,ST5,ST5,ST5,ST6,ST2,ST2,ST2,ST2,ST3,ST4,ST4,ST4,ST5,ST6,ST2,ST2,ST3,ST3,ST3,ST4,ST4,ST5,ST5,ST5 (until dec),ST3,ST2,ST4
|
||||
PROC site,,Derriford,,exeter,Torbay,Exeter,,Derriford,Derriford,Exeter,Exeter,Derriford,Derriford,torbay,Torbay,derriford,,derriford,exeter,,Exeter,,,derriford,Derriford,,derriford,Derriford,Derriford,Exeter,NA,derriford,Torbay,Derriford,Derriford,,torbay,Derriford,Derriford,Torbay,NA,Exeter,Derriford,Truro,Truro,Derriford,Truro,Truro,Derriford,derriford,Derriford,Barnstaple,NA,NA
|
||||
%FTE,,100,0,100,100,100,60,100,100,100,100,80,100,100,100,100,100,60,80,100,100,0,80,100,100,60,100,100,80,100,60,100,100,100,100,100,100,100,100,60,100,100,100,100,80,100,100,100,100,100,100,80,0,0
|
||||
%FTE,,0,0,100,100,100,0,100,100,100,100,80,100,100,100,100,100,60,80,100,100,0,80,100,100,0,100,100,0,100,60,100,100,100,100,100,100,100,100,60,100,100,100,100,80,100,100,100,100,100,100,80,0,0
|
||||
NWD,,,,,,,"Thursday,Friday",,"Tuesday,Thursday",,,wednesday,,,,,,"Wednesday,thursday",Wednesday,,,,Friday,,,"thursday, friday",,,Friday,,"monday,friday",,"thursday, friday",,,,,,,"monday,thursday",,,,,"wednesday, thursday,Friday",,,,,,,,,
|
||||
Flexible NWD,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
End Date,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
OOP,,,,,,,6/9/21-31/3/22,,,,,,,,,,,,,,,,,,,6/9/21-2/5/22,,,1/1/22-5/9/22,6/9/21-28/2/22,,,,,,,,,,6/9/21-20/9/21,,,,,,,,,,,,,,
|
||||
OOP,,,,,,,6/9/21-31/3/22,,,,,,,,,,,,,,,,,,,6/9/21-2/5/22,,,1/1/22-5/9/22,6/9/21-28/2/22,,,1/3/22-31/3/22,,,,,,,6/9/21-20/9/21,,,,,,,,,1/8/22-4/9/22,23/7/22-4/9/22,,,,
|
||||
Group,,Y1G1,Y1G1,Y1G2,Y3G1,Y3G1,Y3G2,Y3G2,,,,,Y2G1,Y2G2,Y2G2,Y2G2,Y3G1,Y3G1,Y3G2,Y3G2,Y3G2,,,,,,,,,,,Y2G1,Y2G1,Y2G2,Y2G2,Y3G2,,,,,,Y2G1,Y2G2,Y3G1,Y3G1,Y3G2,,,,,,,Y2G1,
|
||||
?PROC,,,,,,,,,,,,,,,,,,,,,,NO,,,,WEEKEND ONLY,,,,,No,,,,,,,,,,No,,,,,,,,,,Yes - until ST6 in dec,???,NO,NO
|
||||
Pair,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,2,,,
|
||||
Extra_night_weekend,,3.72,,-0.28,-0.28,-0.28,,-0.28,-0.28,-0.28,-0.28,0.63,-0.28,-0.28,-0.28,-0.28,-0.28,4.63,2.17,-0.28,3.72,,2.17,-0.28,-0.28,,-0.28,-0.28,,0.3,0,-0.28,-0.28,-0.28,3.72,-0.28,-0.28,-1.06,-0.28,0.27,,-0.28,-0.28,-0.28,-1.83,-0.28,-0.28,-0.28,-0.28,-0.28,0,7.72,,
|
||||
Extra_night_weekday,,-0.21,,-0.21,-0.21,-0.21,,-0.21,-0.21,-0.21,-0.21,0.47,-0.21,2.79,2.79,2.79,-0.21,-2.53,-1.37,-0.21,-0.21,,-1.37,-0.21,-0.21,,-0.21,-0.21,,0.22,0,-0.21,-0.21,-0.21,-0.21,-0.21,-0.21,2.21,-0.21,0.21,,-0.21,-0.21,-0.21,1.63,-0.21,-0.21,-0.21,-0.21,-0.21,0,5.79,,
|
||||
Extra_twilight,,-1.97,,-0.97,1.03,1.03,,-0.97,-1.97,1.03,1.03,-0.38,0.47,0.47,-1.53,0.47,-0.53,-3.92,-2.23,0.47,-2.53,,-2.23,0.47,0.47,,0.47,0.47,,0.33,0.08,1.95,-0.05,1.95,-1.05,1.95,1.95,1.56,3.95,1.73,,-1.39,-1.39,0.61,0.49,-1.39,-0.39,1.61,2.61,-1.39,0.61,0,,
|
||||
Extra_weekend,,-0.73,,2.27,-0.73,-0.73,,2.27,2.27,-0.73,-0.73,-1.04,,,,,,,,,,,,,,,,,,,,1.46,3.46,1.46,0.46,1.46,1.46,0.42,0.46,-0.2,,1.96,-1.04,-1.04,-0.63,1.96,0.96,-1.04,-2.04,1.96,-1.04,0,,
|
||||
Extra_night_weekday,,3.72,,-0.28,-0.28,-0.28,,-0.28,-0.28,-0.28,-0.28,0.63,-0.28,-0.28,-0.28,-0.28,-0.28,4.63,2.17,-0.28,3.72,,2.17,-0.28,-0.28,,-0.28,-0.28,,0.3,0,-0.28,-0.28,-0.28,3.72,-0.28,-0.28,-1.06,-0.28,0.27,,-0.28,-0.28,-0.28,-1.83,-0.28,-0.28,-0.28,-0.28,-0.28,0,-0.28,,
|
||||
Extra_night_weekend,,-0.21,,-0.21,-0.21,-0.21,,-0.21,-0.21,-0.21,-0.21,0.47,-0.21,2.79,2.79,2.79,-0.21,-2.53,-1.37,-0.21,-0.21,,-1.37,-0.21,-0.21,,-0.21,-0.21,,0.22,0,-0.21,-0.21,-0.21,-0.21,-0.21,-0.21,2.21,-0.21,0.21,,-0.21,-0.21,-0.21,1.63,-0.21,-0.21,-0.21,-0.21,-0.21,0,2.79,,
|
||||
Extra_twilight,,-1.97,,-0.97,1.03,1.03,,-0.97,-1.97,1.03,1.03,-0.38,0.47,0.47,-1.53,0.47,-0.53,-3.92,-2.23,0.47,-2.53,,-2.23,0.47,0.47,,0.47,0.47,,0.33,0.08,,,,,,,,,,,-1.39,-1.39,0.61,0.49,-1.39,-0.39,1.61,2.61,-1.39,0.61,0,,
|
||||
Extra_weekend,,-0.73,,2.27,-0.73,-0.73,,2.27,2.27,-0.73,-0.73,-1.04,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1.96,-1.04,-1.04,-0.63,1.96,0.96,-1.04,-2.04,1.96,-1.04,0,,
|
||||
Extra_weekend_plymouth1,,,,,,,,,,,,,-2.22,-0.22,-2.22,-0.22,-0.22,2.27,-0.98,-2.22,-0.22,,1.02,1.78,-0.22,,1.78,1.78,,0.15,0,,,,,,,,,,,,,,,,,,,,,,,
|
||||
Extra_weekend_plymouth2,,,,,,,,,,,,,1.78,-2.22,1.78,-2.22,-0.22,0.27,3.02,1.78,-0.22,,1.02,-2.22,-0.22,,-2.22,-0.22,,0.15,0,,,,,,,,,,,,,,,,,,,,,,,
|
||||
Extra_plymouth_bank_holiday,,,,,,,,,,,,,0.2,0.2,0.2,0.2,0.2,0.12,-0.84,0.2,0.2,,0.16,0.2,0.2,,0.2,-1.8,,0.01,0.12,,,,,,,,,,,,,,,,,,,,,,,
|
||||
bank_holidays_worked,,,,1,,,,1,,2,1,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,2,1,2,,2,1,,3,,,,,,2,2,,,,2,,2,,1,,1,2,,,,2,2,,,,2,,,1,,,
|
||||
bank_holidays_worked,,,,1,,,,1,,2,1,3,,2,1,2,,2,1,,3,,,,,,2,2,,,,2,,2,,1,,1,2,,,,2,2,,,,2,,,1,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
Date,Exams,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
6/9/21,,,NO ONCALL,,,POST ONCALL,Mat leave,,exeter_twilight,,exeter_twilight,,,A/L,,,,,A/L,,,No Oncall,POST ONCALL,POST ONCALL,POST ONCALL,Mat leave,,,plymouth_twilight,OOPT,NO oncals,,POST ONCALL,,,,A/L,torbay_twilight,torbay_twilight,Mat leave,POST ONCALL,,,,,truro_twilight,truro_twilight,,A/L,POST ONCALL,,,,
|
||||
7/9/21,,,NO ONCALL,,,POST ONCALL,Mat leave,,exeter_twilight,,exeter_twilight,,,A/L,,,,,A/L,,,No Oncall,POST ONCALL,POST ONCALL,POST ONCALL,Mat leave,,,plymouth_twilight,OOPT,NO oncals,,POST ONCALL,,,,A/L,torbay_twilight,torbay_twilight,Mat leave,POST ONCALL,,,,,truro_twilight,truro_twilight,,A/L,POST ONCALL,,,,
|
||||
@@ -205,14 +205,14 @@ Date,Exams,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
6/3/22,,,NO ONCALL,,,,Mat leave,,,,OOPT,,,,,,,,,A/L,,No Oncall,,,,Mat leave,,,OOPT,,IR oncall,,OOPC,,,,,,A/L,,,,,,,,,A/L,A/L,A/L,,,,
|
||||
7/3/22,,OFF ONCALL,IDT,POST ONCALL,POST ONCALL,,OOPT,,,,OOPT,,,,,,,POST ONCALL,,,,No Oncall,,POST ONCALL,,Mat leave,,POST ONCALL,OOPT,,,,OOPC,,,POST ONCALL,POST ONCALL,,A/L,,,,,A/L,POST ONCALL,,,,,A/L,,,,
|
||||
8/3/22,,OFF ONCALL,IDT,POST ONCALL,POST ONCALL,,OOPT,,,,OOPT,,,,,,,POST ONCALL,,,,No Oncall,,POST ONCALL,,Mat leave,,POST ONCALL,OOPT,,,,OOPC,,,POST ONCALL,POST ONCALL,,A/L,,,,,A/L,POST ONCALL,,,,,A/L,,,,
|
||||
9/3/22,,OFF ONCALL,IDT,,,,OOPT,,,,OOPT,,,,,,,,,,,No Oncall,,,,Mat leave,,,OOPT,,,,OOPC,,,,,,A/L,,,,,A/L,,,,,,A/L,,,,
|
||||
9/3/22,,OFF ONCALL,IDT,,,,OOPT,,,,OOPT,,,,,,,,,,,No Oncall,,,,Mat leave,POST ONCALL,,OOPT,,,,OOPC,,,,,,A/L,,,,,A/L,,,,,,A/L,,,,
|
||||
10/3/22,,OFF ONCALL,IDT,,,,OOPT,,,,OOPT,,,,,,,,,,,No Oncall,,,,Mat leave,,,OOPT,,,,OOPC,,,,,,A/L,,,,,A/L,,,,,,A/L,,,,
|
||||
11/3/22,,OFF ONCALL,IDT,,,,OOPT,,,,OOPT,,,,,,,,,,,No Oncall,,,,Mat leave,,,OOPT,,,,OOPC,,,,,,A/L,,,,,A/L,,,,,,A/L,,,,
|
||||
12/3/22,,OFF ONCALL,IDT,,,,OOPT,,,,OOPT,A/L,,,,,,,,,,No Oncall,,,,Mat leave,,,OOPT,,,,OOPC,,,A/L,,,A/L,,,,,A/L,,A/L,,,,A/L,,,,
|
||||
12/3/22,,OFF ONCALL,IDT,POST ONCALL,,,OOPT,,,,OOPT,A/L,,,,,,POST ONCALL,,,,No Oncall,,,,Mat leave,,,OOPT,,,,OOPC,,,A/L,POST ONCALL,,A/L,,,,,A/L,,A/L,,,,A/L,,,,
|
||||
13/3/22,,OFF ONCALL,IDT,,,,OOPT,,,,OOPT,A/L,,,,,,,,,,No Oncall,,,,Mat leave,,,OOPT,,,,OOPC,,,A/L,,,A/L,,,,,A/L,,A/L,,,,A/L,,,,
|
||||
14/3/22,pre 2b,OFF ONCALL,IDT,,,,OOPT,,,,OOPT,A/L,,,,,,,,,,No Oncall,,,,Mat leave,,,OOPT,,,,OOPC,,,A/L,,,,,,,,A/L,,A/L,,pre 2b,,,,,,
|
||||
15/3/22,pre 2b,OFF ONCALL,IDT,,,,OOPT,,,,OOPT,A/L,,,,,,,,,,No Oncall,,,,Mat leave,,,OOPT,,,,OOPC,,,A/L,,,,,,,,A/L,,A/L,,pre 2b,,,,,,
|
||||
16/3/22,pre 2b,OFF ONCALL,IDT,,,,OOPT,,,,OOPT,A/L,,,,,,,,,,No Oncall,,,,Mat leave,,,OOPT,,,,OOPC,,,A/L,,,,,,,,A/L,,A/L,,pre 2b,A/L,,,,,
|
||||
16/3/22,pre 2b,OFF ONCALL,IDT,,,,OOPT,,,,OOPT,A/L,,,,,,,,,,No Oncall,,,,Mat leave,,,OOPT,,,,OOPC,,,A/L,,,,,,,POST ONCALL,A/L,,A/L,,pre 2b,A/L,,,,,
|
||||
17/3/22,pre 2b,OFF ONCALL,IDT,,,,OOPT,,A/L,,OOPT,A/L,,,,A/L,,,,,,No Oncall,,,,Mat leave,,,OOPT,,,,OOPC,,,A/L,,,,,,,,A/L,,A/L,,pre 2b,,,,,,
|
||||
18/3/22,pre 2b,OFF ONCALL,IDT,,,,OOPT,,,,OOPT,A/L,,,,A/L,,,,,,No Oncall,,,,Mat leave,,,OOPT,,,,OOPC,,,A/L,,,,,,,,A/L,,A/L,,pre 2b,,,,,,
|
||||
19/3/22,pre 2b,OFF ONCALL,IDT,,,,OOPT,A/L,,,OOPT,A/L,,,,A/L,,,,,,No Oncall,,,,Mat leave,,,OOPT,,,,OOPC,,,A/L,,,,,IR ONCALL,,,A/L,,A/L,,pre 2b,,A/L,,,,
|
||||
|
||||
|
@@ -35,7 +35,8 @@ def load_leave(Rota, use_live_rota):
|
||||
workers[name]["leave"] = []
|
||||
workers[name]["requests"] = []
|
||||
workers[name]["site_pref"] = []
|
||||
workers[name]["shift_balance_extra"]
|
||||
workers[name]["shift_balance_extra"] = {}
|
||||
workers[name]["bank_holiday_extra"] = 0
|
||||
|
||||
for i in range(len(r)):
|
||||
try:
|
||||
@@ -88,7 +89,16 @@ def load_leave(Rota, use_live_rota):
|
||||
elif row_title.startswith("Extra_"):
|
||||
if lower_item:
|
||||
shift = row_title[len("Extra_") :]
|
||||
worker["shift_balance_extra"] = shift
|
||||
if shift == "twilight":
|
||||
shift = f"{worker['site']}_{shift}"
|
||||
elif shift == "weekend":
|
||||
shift = f"weekend_{worker['site']}"
|
||||
worker["shift_balance_extra"][shift] = float(lower_item)
|
||||
|
||||
elif row_title == "bank_holidays_worked":
|
||||
if lower_item:
|
||||
print("BH", lower_item)
|
||||
worker["bank_holiday_extra"] = int(lower_item)
|
||||
|
||||
elif re.match(date_re, row_title) is not None:
|
||||
|
||||
|
||||
@@ -1,60 +1,95 @@
|
||||
"Name","Madalina Drumea","Layla Bell","Stephanie Bailey","Salma Aslam","Alex wood","Max Ireland","Seren Peters","Charles Finan","Paul Ward","Delilah Trimmer","Matt Murphey","Tom Welsh","Kyaw Tint","Maththew O'Brien","Max Finzel","Zainab Sharaf","Jean Skumar","Michael Tomek","Dhuvresh Patel","Nicolas Dziadulewicz","Vilim Kalamar","Jenna Millington","Georgina Edwards","Jenn Haw fong","Paul Jenkins","Rebecca Murphy","Sophie McGlade","Amoolya Mannava","Ross Kruger","Fiona Lyall","Jon Skinner","Andrew MacCormick","Mark Haley","Wijhdan Abusrewil","Alexander Sanchez - cabello","Chong Yew Ng","Matthew Thorley","Sayed Hashim Alqarooni","Harriet Conley","Alexander Wijnberg","Cameron Bullock","Alan Eccles","Christian Greer","Hannah Lewis","Amina Odeh","Sarath Vennam","Mo Babsail","Richard Chaytor","Sherafghan PROC"
|
||||
"Site","barnstaple","exeter","exeter","exeter","exeter","exeter","exeter","exeter","exeter","exeter","exeter","exeter","plymouth","plymouth","plymouth","plymouth","plymouth","plymouth","plymouth","plymouth","plymouth","plymouth","plymouth","plymouth","plymouth","plymouth","plymouth","plymouth","plymouth","plymouth_twilights","plymouth_twilights","torbay","torbay","torbay","torbay","torbay","torbay","torbay","torbay","truro","truro","truro","truro","truro","truro","truro","truro","truro","truro no proc"
|
||||
"Grade","3","2","2","3","3","3","3","4","4","5","5","5","2","2","2","2","3","3","3","3","3","4","4","4","4","5","5","5","5","6","6","2","2","2","3","4","4","4","5","2","2","3","3","3","4","4","5","5","5"
|
||||
"FTE","100","100","100","60","100","100","100","100","100","60","100","100","100","100","100","100","60","80","100","100","100","60","80","100","100","100","80","100","100","60","100","100","100","100","100","90","100","100","60","100","100","80","100","100","100","100","100","100","100"
|
||||
"Week 1 Day Mon","night_weekday","","","","","","","exeter_twilight","","","","","","","","","","","","","","","","","","","plymouth_twilight","night_weekday","","","","","","","","","torbay_twilight","","","","","night_weekday","","","","truro_twilight","","",""
|
||||
"Week 1 Day Tue","night_weekday","","","","","","","","","","exeter_twilight","","","","","","","","","","","","","","","","plymouth_twilight","night_weekday","","","","","","","","","torbay_twilight","","","","","night_weekday","","truro_twilight","","","","",""
|
||||
"Week 1 Day Wed","night_weekday","","","","","","","","","exeter_twilight","","","","","","","","","","","","","","","plymouth_twilight","","","night_weekday","","","","torbay_twilight","","","","","","","","","","night_weekday","truro_twilight","","","","","",""
|
||||
"Week 1 Day Thu","night_weekday","","","","exeter_twilight","","","","","","","","plymouth_twilight","","","","","","","","","","","","","","","night_weekday","","","","torbay_twilight","","","","","","","","","truro_twilight","night_weekday","","","","","","",""
|
||||
"Week 1 Day Fri","","","","","","","","","weekend_exeter","","","","","plymouth_twilight","","","","","night_weekend","","","","","","","","","","","","","","","","","night_weekend","","weekend_torbay","","","","","","","night_weekend","weekend_truro","","",""
|
||||
"Week 1 Day Sat","","","","","","","","","weekend_exeter","","","","","","weekend_plymouth1","","","","night_weekend","","","","","weekend_plymouth2","","","","","","","","","","","","night_weekend","","weekend_torbay","","","","","","","night_weekend","weekend_truro","","",""
|
||||
"Week 1 Day Sun","","","","","","","","","weekend_exeter","","","","","","weekend_plymouth1","","","","night_weekend","","","","","weekend_plymouth2","","","","","","","","","","","","night_weekend","","weekend_torbay","","","","","","","night_weekend","weekend_truro","","",""
|
||||
"Week 2 Day Mon","","","","","","night_weekday","","exeter_twilight","","","","","","","","plymouth_twilight","","","","","","","","","","","","","night_weekday","","","","","","","","torbay_twilight","","","","","","night_weekday","","","","truro_twilight","",""
|
||||
"Week 2 Day Tue","","","exeter_twilight","","","night_weekday","","","","","","","plymouth_twilight","","","","","","","","","","","","","","","","night_weekday","","","","","","","","torbay_twilight","","","truro_twilight","","","night_weekday","","","","","",""
|
||||
"Week 2 Day Wed","","","","","","night_weekday","","exeter_twilight","","","","","","","plymouth_twilight","","","","","","","","","","","","","","night_weekday","","","","","","","","torbay_twilight","","","","","","night_weekday","","truro_twilight","","","",""
|
||||
"Week 2 Day Thu","","","","","","night_weekday","","","exeter_twilight","","","","","","plymouth_twilight","","","","","","","","","","","","","","night_weekday","","","","","","","","torbay_twilight","","","","","","night_weekday","","truro_twilight","","","",""
|
||||
"Week 2 Day Fri","","","weekend_exeter","","","","","","","","","","","","","plymouth_twilight","","","","","","","night_weekend","","night_weekend","","","","","","","","","weekend_torbay","night_weekend","","","","","","","","","weekend_truro","","","","",""
|
||||
"Week 2 Day Sat","","","weekend_exeter","","","","","","","","","","weekend_plymouth2","","","","","","","","","","night_weekend","","night_weekend","","","weekend_plymouth1","","","","","","weekend_torbay","night_weekend","","","","","","","","","weekend_truro","","","","",""
|
||||
"Week 2 Day Sun","","","weekend_exeter","","","","","","","","","","weekend_plymouth2","","","","","","","","","","night_weekend","","night_weekend","","","weekend_plymouth1","","","","","","weekend_torbay","night_weekend","","","","","","","","","weekend_truro","","","","",""
|
||||
"Week 3 Day Mon","","","","","","exeter_twilight","night_weekday","","","","","","","","plymouth_twilight","","","","night_weekday","","","","","","","","","","","","","torbay_twilight","","","","","","","","","truro_twilight","","","","","","night_weekday","",""
|
||||
"Week 3 Day Tue","","","","","exeter_twilight","","night_weekday","","","","","","","","","","","plymouth_twilight","night_weekday","","","","","","","","","","","","","torbay_twilight","","","","","","","","truro_twilight","","","","","","","night_weekday","",""
|
||||
"Week 3 Day Wed","","exeter_twilight","","","","","night_weekday","","","","","","","","","plymouth_twilight","","","night_weekday","","","","","","","","","","","","","torbay_twilight","","","","","","","","truro_twilight","","","","","","","night_weekday","",""
|
||||
"Week 3 Day Thu","","","exeter_twilight","","","","night_weekday","","","","","","","","","","","","night_weekday","","","","plymouth_twilight","","","","","","","","","torbay_twilight","","","","","","","","","","","","","","","night_weekday","truro_twilight",""
|
||||
"Week 3 Day Fri","","","","","night_weekend","weekend_exeter","","","","","","","","","","plymouth_twilight","night_weekend","","","","","","","","","","night_weekend","","","","","","weekend_torbay","","","","","","","","weekend_truro","","","","","","","",""
|
||||
"Week 3 Day Sat","","","","","night_weekend","weekend_exeter","","","","","","","","","","","night_weekend","","","","weekend_plymouth2","","","","","","night_weekend","","weekend_plymouth1","","","","weekend_torbay","","","","","","","","weekend_truro","","","","","","","",""
|
||||
"Week 3 Day Sun","","","","","night_weekend","weekend_exeter","","","","","","","","","","","night_weekend","","","","weekend_plymouth2","","","","","","night_weekend","","weekend_plymouth1","","","","weekend_torbay","","","","","","","","weekend_truro","","","","","","","",""
|
||||
"Week 4 Day Mon","","","exeter_twilight","","","","","","","","night_weekday","","","plymouth_twilight","","","","","","night_weekday","","","","","","","","","","","","","","","torbay_twilight","","","","","","","","","night_weekday","","","","","truro_twilight"
|
||||
"Week 4 Day Tue","","","exeter_twilight","","","","","","","","night_weekday","","","","","","","","plymouth_twilight","night_weekday","","","","","","","","","","","","","","","torbay_twilight","","","","","","","","","night_weekday","","","","truro_twilight",""
|
||||
"Week 4 Day Wed","","exeter_twilight","","","","","","","","","night_weekday","","","","","","","","","night_weekday","","","","","","","","","","plymouth_twilight","","","","","torbay_twilight","","","","","","truro_twilight","","","night_weekday","","","","",""
|
||||
"Week 4 Day Thu","","","","","","","exeter_twilight","","","","night_weekday","","","","","plymouth_twilight","","","","night_weekday","","","","","","","","","","","","","","","torbay_twilight","","","","","","","","","night_weekday","","","","truro_twilight",""
|
||||
"Week 4 Day Fri","night_weekend","weekend_exeter","","","","","","","","","","","","","","","","","","","","","","","","","","night_weekend","plymouth_twilight","","","","","weekend_torbay","","","","","","","","","night_weekend","","","","weekend_truro","",""
|
||||
"Week 4 Day Sat","night_weekend","weekend_exeter","","","","","","","","","","","weekend_plymouth2","","","weekend_plymouth1","","","","","","","","","","","","night_weekend","","","","","","weekend_torbay","","","","","","","","","night_weekend","","","","weekend_truro","",""
|
||||
"Week 4 Day Sun","night_weekend","weekend_exeter","","","","","","","","","","","weekend_plymouth2","","","weekend_plymouth1","","","","","","","","","","","","night_weekend","","","","","","weekend_torbay","","","","","","","","","night_weekend","","","","weekend_truro","",""
|
||||
"Week 5 Day Mon","","","night_weekday","","","","","","","","exeter_twilight","","","","plymouth_twilight","","","","","","","","","","night_weekday","","","","","","","","torbay_twilight","","","","","","","","","","","","","","","night_weekday","truro_twilight"
|
||||
"Week 5 Day Tue","","","night_weekday","","","","","","","","","exeter_twilight","","","","","plymouth_twilight","","","","","","","","night_weekday","","","","","","","","","","torbay_twilight","","","","","truro_twilight","","","","","","","","night_weekday",""
|
||||
"Week 5 Day Wed","","exeter_twilight","night_weekday","","","","","","","","","","","","","","","","","","","","","","night_weekday","","plymouth_twilight","","","","","","","","torbay_twilight","","","","","","","","","truro_twilight","","","","night_weekday",""
|
||||
"Week 5 Day Thu","","exeter_twilight","night_weekday","","","","","","","","","","","","","","","","","","","","","","night_weekday","","plymouth_twilight","","","","","","","","torbay_twilight","","","","","","","","","","","","truro_twilight","night_weekday",""
|
||||
"Week 5 Day Fri","","","","","weekend_exeter","","","","","","","night_weekend","","plymouth_twilight","","","","night_weekend","","","","","","","","","","","","","","night_weekend","weekend_torbay","","","","","","","weekend_truro","","","","","","","","",""
|
||||
"Week 5 Day Sat","","","","","weekend_exeter","","","","","","","night_weekend","","","","","","night_weekend","","weekend_plymouth2","","","","weekend_plymouth1","","","","","","","","night_weekend","weekend_torbay","","","","","","","weekend_truro","","","","","","","","",""
|
||||
"Week 5 Day Sun","","","","","weekend_exeter","","","","","","","night_weekend","","","","","","night_weekend","","weekend_plymouth2","","","","weekend_plymouth1","","","","","","","","night_weekend","weekend_torbay","","","","","","","weekend_truro","","","","","","","","",""
|
||||
"Week 6 Day Mon","","","","","","","","night_weekday","exeter_twilight","","","","night_weekday","","","","","","","","","","","","","","","plymouth_twilight","","","","","","torbay_twilight","","","","night_weekday","","","","","truro_twilight","","","","","",""
|
||||
"Week 6 Day Tue","","","","","","","","night_weekday","","","exeter_twilight","","night_weekday","","","","","","","","","","plymouth_twilight","","","","","","","","","","","","","torbay_twilight","","night_weekday","","","","","","","truro_twilight","","","",""
|
||||
"Week 6 Day Wed","","","","","","","","night_weekday","exeter_twilight","","","","night_weekday","","","","plymouth_twilight","","","","","","","","","","","","","","","","","","","torbay_twilight","","night_weekday","","","","","","","","truro_twilight","","",""
|
||||
"Week 6 Day Thu","","","","","","","","night_weekday","","exeter_twilight","","","night_weekday","","","","","","","","plymouth_twilight","","","","","","","","","","","","","","","torbay_twilight","","night_weekday","","","","","","truro_twilight","","","","",""
|
||||
"Week 6 Day Fri","","night_weekend","","","","","","","","","weekend_exeter","","","","","","","","","","","","","","","","","","night_weekend","","plymouth_twilight","","","","weekend_torbay","","night_weekend","","","","","","","","","","","","weekend_truro"
|
||||
"Week 6 Day Sat","","night_weekend","","","","","","","","","weekend_exeter","","","weekend_plymouth2","","weekend_plymouth1","","","","","","","","","","","","","night_weekend","","","","","","weekend_torbay","","night_weekend","","","","","","","","","","","","weekend_truro"
|
||||
"Week 6 Day Sun","","night_weekend","","","","","","","","","weekend_exeter","","","weekend_plymouth2","","weekend_plymouth1","","","","","","","","","","","","","night_weekend","","","","","","weekend_torbay","","night_weekend","","","","","","","","","","","","weekend_truro"
|
||||
"Week 7 Day Mon","","","","","exeter_twilight","","","","","","","","","","","","","","","","","","plymouth_twilight","night_weekday","","","","","","","","","","night_weekday","","","","torbay_twilight","","","","","","","night_weekday","truro_twilight","","",""
|
||||
"Week 7 Day Tue","","","","","","","exeter_twilight","","","","","","","","","","","plymouth_twilight","","","","","","night_weekday","","","","","","","","","","night_weekday","","","","torbay_twilight","","truro_twilight","","","","","night_weekday","","","",""
|
||||
"Week 7 Day Wed","","","","","","","","","","","","exeter_twilight","","plymouth_twilight","","","","","","","","","","night_weekday","","","","","","","","","","night_weekday","","","","torbay_twilight","","","","","truro_twilight","","night_weekday","","","",""
|
||||
"Week 7 Day Thu","","","","","","","","","","","","exeter_twilight","","","","","","plymouth_twilight","","","","","","night_weekday","","","","","","","","","","night_weekday","","","","torbay_twilight","","","","","truro_twilight","","night_weekday","","","",""
|
||||
"Week 7 Day Fri","","","","","","","weekend_exeter","","","","","","","","","","","","plymouth_twilight","night_weekend","","","","","","","","","","","","weekend_torbay","","","","night_weekend","","","","night_weekend","","weekend_truro","","","","","","",""
|
||||
"Week 7 Day Sat","","","","","","","weekend_exeter","","","","","","","","weekend_plymouth1","","","","","night_weekend","weekend_plymouth2","","","","","","","","","","","weekend_torbay","","","","night_weekend","","","","night_weekend","","weekend_truro","","","","","","",""
|
||||
"Week 7 Day Sun","","","","","","","weekend_exeter","","","","","","","","weekend_plymouth1","","","","","night_weekend","weekend_plymouth2","","","","","","","","","","","weekend_torbay","","","","night_weekend","","","","night_weekend","","weekend_truro","","","","","","",""
|
||||
"Week 8 Day Mon","","","","","","","","","night_weekday","","exeter_twilight","","","","","","","","","","","","plymouth_twilight","","","","","","","","","","night_weekday","torbay_twilight","","","","","","","","","","truro_twilight","","night_weekday","","",""
|
||||
"Week 8 Day Tue","","","","","","exeter_twilight","","","night_weekday","","","","","","","","","","","","","","","","","","","","","","plymouth_twilight","","night_weekday","","","","","","torbay_twilight","","","","","","","night_weekday","","","truro_twilight"
|
||||
"Week 8 Day Wed","","","","","","","","exeter_twilight","night_weekday","","","","","","","","","","","","","","","","","","","","","","plymouth_twilight","","night_weekday","","","torbay_twilight","","","","","","","","","","night_weekday","truro_twilight","",""
|
||||
"Week 8 Day Thu","","","","","","exeter_twilight","","","night_weekday","","","","","","","","","plymouth_twilight","","","","","","","","","","","","","","","night_weekday","","","torbay_twilight","","","","","","truro_twilight","","","","night_weekday","","",""
|
||||
"Week 8 Day Fri","","","","","","","","weekend_exeter","","night_weekend","","","","night_weekend","","","","","","","","","","plymouth_twilight","","","","","","","","","","","","","weekend_torbay","","night_weekend","","","","","","","","","weekend_truro",""
|
||||
"Week 8 Day Sat","","","","","","","","weekend_exeter","","night_weekend","","","","night_weekend","","","","","weekend_plymouth1","","","","","","weekend_plymouth2","","","","","","","","","","","","weekend_torbay","","night_weekend","","","","","","","","","weekend_truro",""
|
||||
"Week 8 Day Sun","","","","","","","","weekend_exeter","","night_weekend","","","","night_weekend","","","","","weekend_plymouth1","","","","","","weekend_plymouth2","","","","","","","","","","","","weekend_torbay","","night_weekend","","","","","","","","","weekend_truro",""
|
||||
"Name","Madalina Drumea","Layla Bell","Alex wood","Max Ireland","Seren Peters","Charles Finan","Paul Ward","Delilah Trimmer","Tom Welsh","Kyaw Tint","Maththew O'Brien","Max Finzel","Zainab Sharaf","Jean Skumar","Michael Tomek","Dhuvresh Patel","Nicolas Dziadulewicz","Vilim Kalamar","Georgina Edwards","Jenn Haw fong","Paul Jenkins","Amoolya Mannava","Rebecca Murphy","Ross Kruger","Fiona Lyall","Wijhdan Abusrewil","Andrew MacCormick","Joel Lim","Mark Haley","Alexander Sanchez - cabello","Chong Yew Ng","Matthew Thorley","Sayed Hashim Alqarooni","Harriet Conley","Jon Skinner","Alexander Wijnberg","Cameron Bullock","Alan Eccles","Christian Greer","Hannah Lewis","Amina Odeh","Sarath Vennam","Mo Babsail","Richard Chaytor","Sherafghan PROC"
|
||||
"Site","barnstaple","exeter","exeter","exeter","exeter","exeter","exeter","exeter","exeter","plymouth","plymouth","plymouth","plymouth","plymouth","plymouth","plymouth","plymouth","plymouth","plymouth","plymouth","plymouth","plymouth","plymouth","plymouth","plymouth_twilights","torbay","torbay","torbay","torbay","torbay","torbay","torbay","torbay","torbay","torbay twilights","truro","truro","truro","truro","truro","truro","truro","truro","truro","truro no proc"
|
||||
"Grade","3","2","3","3","3","4","4","5","5","2","2","2","2","3","3","3","3","3","4","4","4","5","5","5","6","2","2","2","2","3","4","4","4","5","6","2","2","3","3","3","4","4","5","5","5"
|
||||
"FTE","80","100","100","100","100","100","100","80","100","100","100","100","100","60","80","100","100","100","80","100","100","100","100","100","60","100","100","100","100","100","100","100","100","60","100","100","100","80","100","100","100","100","100","100","100"
|
||||
"Week 1 Day Mon","","","night_weekday","","","exeter_twilight","","","","","","","","","","","","","night_weekday","","","plymouth_twilight","","","","","night_weekday","","","","","","","","torbay_twilight","","","","","truro_twilight","","","","",""
|
||||
"Week 1 Day Tue","","","night_weekday","","","","","exeter_twilight","","","","","","","","","plymouth_twilight","","night_weekday","","","","","","","","night_weekday","","","","","","","","torbay_twilight","","","","","","","","truro_twilight","",""
|
||||
"Week 1 Day Wed","","","night_weekday","","","exeter_twilight","","","","","","","","","","","","","night_weekday","","","","plymouth_twilight","","","","night_weekday","","","","","","","","torbay_twilight","","","","","","","truro_twilight","","",""
|
||||
"Week 1 Day Thu","","exeter_twilight","night_weekday","","","","","","","","","","plymouth_twilight","","","","","","night_weekday","","","","","","","","night_weekday","","","","","","","","torbay_twilight","","","","","truro_twilight","","","","",""
|
||||
"Week 1 Day Fri","","","","","night_weekend","","weekend_exeter","","","","","night_weekend","","","","plymouth_twilight","","","","","","","","","","","","","weekend_torbay","","","","","","","","","","","","weekend_truro","","night_weekend","",""
|
||||
"Week 1 Day Sat","","","","","night_weekend","","weekend_exeter","","","weekend_plymouth1","","night_weekend","","","","","","","","","weekend_plymouth2","","","","","","","","weekend_torbay","","","","","","","","","","","","weekend_truro","","night_weekend","",""
|
||||
"Week 1 Day Sun","","","","","night_weekend","","weekend_exeter","","","weekend_plymouth1","","night_weekend","","","","","","","","","weekend_plymouth2","","","","","","","","weekend_torbay","","","","","","","","","","","","weekend_truro","","night_weekend","",""
|
||||
"Week 2 Day Mon","","","exeter_twilight","night_weekday","","","","","","","","","","","","night_weekday","","","","","","","plymouth_twilight","","","","torbay_twilight","","","","","","","night_weekday","","","","","","","","","","","truro_twilight"
|
||||
"Week 2 Day Tue","","exeter_twilight","","night_weekday","","","","","","","","","plymouth_twilight","","","night_weekday","","","","","","","","","","","","","","","","torbay_twilight","","night_weekday","","","","truro_twilight","","","","","","",""
|
||||
"Week 2 Day Wed","","","","night_weekday","exeter_twilight","","","","","","","","","","","night_weekday","","plymouth_twilight","","","","","","","","","torbay_twilight","","","","","","","night_weekday","","","","","","","","","","truro_twilight",""
|
||||
"Week 2 Day Thu","","","","night_weekday","","","exeter_twilight","","","","","","","","plymouth_twilight","night_weekday","","","","","","","","","","","torbay_twilight","","","","","","","night_weekday","","","","","","","","","truro_twilight","",""
|
||||
"Week 2 Day Fri","","","","","","weekend_exeter","","","","","","","night_weekend","","","","","","","plymouth_twilight","","","","","","","","","","","weekend_torbay","night_weekend","","","","","weekend_truro","","","","","night_weekend","","",""
|
||||
"Week 2 Day Sat","","","","","","weekend_exeter","","","","","","","night_weekend","","weekend_plymouth2","","weekend_plymouth1","","","","","","","","","","","","","","weekend_torbay","night_weekend","","","","","weekend_truro","","","","","night_weekend","","",""
|
||||
"Week 2 Day Sun","","","","","","weekend_exeter","","","","","","","night_weekend","","weekend_plymouth2","","weekend_plymouth1","","","","","","","","","","","","","","weekend_torbay","night_weekend","","","","","weekend_truro","","","","","night_weekend","","",""
|
||||
"Week 3 Day Mon","","","exeter_twilight","","","","","","","","","","","","","","","","","plymouth_twilight","night_weekday","","","","","","night_weekday","torbay_twilight","","","","","","","","","","night_weekday","","truro_twilight","","","","",""
|
||||
"Week 3 Day Tue","","exeter_twilight","","","","","","","","","","","","","","","","","","","night_weekday","","","","plymouth_twilight","","night_weekday","torbay_twilight","","","","","","","","","","night_weekday","","truro_twilight","","","","",""
|
||||
"Week 3 Day Wed","","","","","","exeter_twilight","","","","","","","","","","","","","plymouth_twilight","","night_weekday","","","","","","night_weekday","","","torbay_twilight","","","","","","","truro_twilight","night_weekday","","","","","","",""
|
||||
"Week 3 Day Thu","","","exeter_twilight","","","","","","","","","plymouth_twilight","","","","","","","","","night_weekday","","","","","","night_weekday","torbay_twilight","","","","","","","","","","night_weekday","","","","","truro_twilight","",""
|
||||
"Week 3 Day Fri","night_weekend","weekend_exeter","","","","","","","","","","","","","","","","","","","","plymouth_twilight","","night_weekend","","","","","","","","","","weekend_torbay","","night_weekend","","","","","","","","","weekend_truro"
|
||||
"Week 3 Day Sat","night_weekend","weekend_exeter","","","","","","","","","","weekend_plymouth2","","","","","","","","weekend_plymouth1","","","","night_weekend","","","","","","","","","","weekend_torbay","","night_weekend","","","","","","","","","weekend_truro"
|
||||
"Week 3 Day Sun","night_weekend","weekend_exeter","","","","","","","","","","weekend_plymouth2","","","","","","","","weekend_plymouth1","","","","night_weekend","","","","","","","","","","weekend_torbay","","night_weekend","","","","","","","","","weekend_truro"
|
||||
"Week 4 Day Mon","","","night_weekday","","exeter_twilight","","","","","","","","night_weekday","","","","","plymouth_twilight","","","","","","","","","","","","torbay_twilight","","night_weekday","","","","","","","","","","","truro_twilight","",""
|
||||
"Week 4 Day Tue","","","night_weekday","","","","","","exeter_twilight","","plymouth_twilight","","night_weekday","","","","","","","","","","","","","","","","","","","night_weekday","","","torbay_twilight","","truro_twilight","","","","","","","",""
|
||||
"Week 4 Day Wed","","","night_weekday","exeter_twilight","","","","","","plymouth_twilight","","","night_weekday","","","","","","","","","","","","","","","","","torbay_twilight","","night_weekday","","","","","","","","","","","","","truro_twilight"
|
||||
"Week 4 Day Thu","","","night_weekday","exeter_twilight","","","","","","","","","night_weekday","","","","","","","","","","","","plymouth_twilight","","","","","torbay_twilight","","night_weekday","","","","","","","","","","","","","truro_twilight"
|
||||
"Week 4 Day Fri","","","","","","night_weekend","","","weekend_exeter","","night_weekend","","","","","","plymouth_twilight","","","","","","","","","","","","","","weekend_torbay","","","","","","weekend_truro","","","","","","","night_weekend",""
|
||||
"Week 4 Day Sat","","","","","","night_weekend","","","weekend_exeter","","night_weekend","","","weekend_plymouth1","","","","","","","","","weekend_plymouth2","","","","","","","","weekend_torbay","","","","","","weekend_truro","","","","","","","night_weekend",""
|
||||
"Week 4 Day Sun","","","","","","night_weekend","","","weekend_exeter","","night_weekend","","","weekend_plymouth1","","","","","","","","","weekend_plymouth2","","","","","","","","weekend_torbay","","","","","","weekend_truro","","","","","","","night_weekend",""
|
||||
"Week 5 Day Mon","","","","","exeter_twilight","","","","","","","","","","","","plymouth_twilight","","","night_weekday","","","","","","","","","night_weekday","","","","torbay_twilight","","","","","","","","truro_twilight","night_weekday","","",""
|
||||
"Week 5 Day Tue","","","","","","","","exeter_twilight","","","","","","","","","","","","night_weekday","","plymouth_twilight","","","","","","","night_weekday","","","","torbay_twilight","","","","","truro_twilight","","","","night_weekday","","",""
|
||||
"Week 5 Day Wed","","","","","exeter_twilight","","","","","","","","","","","","","","","night_weekday","","","","plymouth_twilight","","","","","night_weekday","","","","torbay_twilight","","","","","","","","","night_weekday","","truro_twilight",""
|
||||
"Week 5 Day Thu","","","","","","","","","exeter_twilight","","","","","","","","plymouth_twilight","","","night_weekday","","","","","","","","","night_weekday","","","","torbay_twilight","","","","","","","","","night_weekday","","truro_twilight",""
|
||||
"Week 5 Day Fri","","","","weekend_exeter","","","","","","plymouth_twilight","","","","","","","","night_weekend","","","","","","","","","","night_weekend","","weekend_torbay","","","","","","","","","","weekend_truro","night_weekend","","","",""
|
||||
"Week 5 Day Sat","","","","weekend_exeter","","","","","","","","","","","weekend_plymouth1","","","night_weekend","","","","","","weekend_plymouth2","","","","night_weekend","","weekend_torbay","","","","","","","","","","weekend_truro","night_weekend","","","",""
|
||||
"Week 5 Day Sun","","","","weekend_exeter","","","","","","","","","","","weekend_plymouth1","","","night_weekend","","","","","","weekend_plymouth2","","","","night_weekend","","weekend_torbay","","","","","","","","","","weekend_truro","night_weekend","","","",""
|
||||
"Week 6 Day Mon","","exeter_twilight","","","night_weekday","","","","","night_weekday","","","","","","","","","plymouth_twilight","","","","","","","","","","torbay_twilight","","night_weekday","","","","","","","","","","","","truro_twilight","",""
|
||||
"Week 6 Day Tue","","","exeter_twilight","","night_weekday","","","","","night_weekday","","","","","","","","","","","","","","","plymouth_twilight","","","","torbay_twilight","","night_weekday","","","","","","","truro_twilight","","","","","","",""
|
||||
"Week 6 Day Wed","","","","","night_weekday","","exeter_twilight","","","night_weekday","plymouth_twilight","","","","","","","","","","","","","","","","","","","","night_weekday","","","","torbay_twilight","","","","","","","","truro_twilight","",""
|
||||
"Week 6 Day Thu","","","","","night_weekday","","exeter_twilight","","","night_weekday","","","","","","","","","","","","plymouth_twilight","","","","","","","torbay_twilight","","night_weekday","","","","","","","","truro_twilight","","","","","",""
|
||||
"Week 6 Day Fri","night_weekend","weekend_exeter","","","","","","","night_weekend","","plymouth_twilight","","","","plymouth_bank_holidays","","night_weekend","","","","","","","","","","weekend_torbay","","","","","","","","","","","weekend_truro","","","","","","",""
|
||||
"Week 6 Day Sat","night_weekend","weekend_exeter","","","","","","","night_weekend","","","","","","","","night_weekend","","","weekend_plymouth1","","","weekend_plymouth2","","","","weekend_torbay","","","","","","","","","","","weekend_truro","","","","","","",""
|
||||
"Week 6 Day Sun","night_weekend","weekend_exeter","","","","","","","night_weekend","","","","","","","","night_weekend","","","weekend_plymouth1","","","weekend_plymouth2","","","","weekend_torbay","","","","","","","","","","","weekend_truro","","","","","","",""
|
||||
"Week 7 Day Mon","","","exeter_twilight","","","night_weekday","","","","","night_weekday","","","","","","","","","","","","","plymouth_twilight","","","","","","","","torbay_twilight","","","","","","","","","","night_weekday","truro_twilight","",""
|
||||
"Week 7 Day Tue","","","","","","night_weekday","","exeter_twilight","","","night_weekday","plymouth_twilight","","","","","","","","","","","","","","","","","","","","torbay_twilight","","","","truro_twilight","","","","","","night_weekday","","",""
|
||||
"Week 7 Day Wed","","","exeter_twilight","","","night_weekday","","","","","night_weekday","","","","","","","","","","","plymouth_twilight","","","","","","","","","","torbay_twilight","","","","","","","truro_twilight","","","night_weekday","","",""
|
||||
"Week 7 Day Thu","","exeter_twilight","","","","night_weekday","","","","","night_weekday","","","","","","","","","","","","","plymouth_twilight","","","","","","","","torbay_twilight","","","","truro_twilight","","","","","","night_weekday","","",""
|
||||
"Week 7 Day Fri","","","","weekend_exeter","","","night_weekend","","","","","","","","","","","night_weekend","","","","","plymouth_twilight","","","","","weekend_torbay","","","","","","","","","","","","night_weekend","","","","weekend_truro",""
|
||||
"Week 7 Day Sat","","","","weekend_exeter","","","night_weekend","","","","","","","","","","","night_weekend","weekend_plymouth2","","","weekend_plymouth1","","","","","","weekend_torbay","","","","","","","","","","","","night_weekend","","","","weekend_truro",""
|
||||
"Week 7 Day Sun","","","","weekend_exeter","","","night_weekend","","","","","","","","","","","night_weekend","weekend_plymouth2","","","weekend_plymouth1","","","","","","weekend_torbay","","","","","","","","","","","","night_weekend","","","","weekend_truro",""
|
||||
"Week 8 Day Mon","","","","","","","","night_weekday","exeter_twilight","","","","","night_weekday","","","","","","","","","","plymouth_twilight","","","","","","","torbay_twilight","","night_weekday","","","","","","","","","truro_twilight","","",""
|
||||
"Week 8 Day Tue","","","","","","","","night_weekday","exeter_twilight","plymouth_twilight","","","","night_weekday","","","","","","","","","","","","","","","","","torbay_twilight","","night_weekday","","","","","","","","truro_twilight","","","",""
|
||||
"Week 8 Day Wed","","","","","","exeter_twilight","","night_weekday","","","","","","night_weekday","","","","","","plymouth_twilight","","","","","","","","","","","torbay_twilight","","night_weekday","","","","","","","","","truro_twilight","","",""
|
||||
"Week 8 Day Thu","","","","","exeter_twilight","","","night_weekday","","","","","","night_weekday","","","","","","","plymouth_twilight","","","","","","","","","","torbay_twilight","","night_weekday","","","","","","truro_twilight","","","","","",""
|
||||
"Week 8 Day Fri","","","weekend_exeter","","","","","","","night_weekend","","","","","","","","","","","plymouth_twilight","","","","","","","","","night_weekend","","weekend_torbay","","","","","weekend_truro","","","","night_weekend","","","",""
|
||||
"Week 8 Day Sat","","","weekend_exeter","","","","","","","night_weekend","","","","","weekend_plymouth2","","","","","","","","","weekend_plymouth1","","","","","","night_weekend","","weekend_torbay","","","","","weekend_truro","","","","night_weekend","","","",""
|
||||
"Week 8 Day Sun","","","weekend_exeter","","","","","","","night_weekend","","","","","weekend_plymouth2","","","","","","","","","weekend_plymouth1","","","","","","night_weekend","","weekend_torbay","","","","","weekend_truro","","","","night_weekend","","","",""
|
||||
"Week 9 Day Mon","night_weekday","","","","","exeter_twilight","","","","","","plymouth_twilight","","","","","","","","","plymouth_bank_holidays","","night_weekday","","","","","","","","","","torbay_twilight","","","","","truro_twilight","","","","","","night_weekday",""
|
||||
"Week 9 Day Tue","night_weekday","","","","exeter_twilight","","","","","","plymouth_twilight","","","","","","","","","","","","night_weekday","","","","","","","","","","torbay_twilight","","","truro_twilight","","","","","","","","night_weekday",""
|
||||
"Week 9 Day Wed","night_weekday","","","exeter_twilight","","","","","","","","","","","","","","","","","","","night_weekday","plymouth_twilight","","","","","","","","","torbay_twilight","","","","","","","","truro_twilight","","","night_weekday",""
|
||||
"Week 9 Day Thu","night_weekday","","exeter_twilight","","","","","","","","","","","","","plymouth_twilight","","","","","","","night_weekday","","","","","","","","","","torbay_twilight","","","","","","","","truro_twilight","","","night_weekday",""
|
||||
"Week 9 Day Fri","","weekend_exeter","","","","","","","","","","","","","","","","plymouth_twilight","","","","night_weekend","","","","weekend_torbay","","","night_weekend","","","","","","","","","","night_weekend","","","weekend_truro","","",""
|
||||
"Week 9 Day Sat","","weekend_exeter","","","","","","","","","weekend_plymouth2","","weekend_plymouth1","","","","","","","","","night_weekend","","","","weekend_torbay","","","night_weekend","","","","","","","","","","night_weekend","","","weekend_truro","","",""
|
||||
"Week 9 Day Sun","","weekend_exeter","","","","","","","","","weekend_plymouth2","","weekend_plymouth1","","","","","","","","","night_weekend","","","","weekend_torbay","","","night_weekend","","","","","","","","","","night_weekend","","","weekend_truro","","",""
|
||||
"Week 10 Day Mon","","","","","exeter_twilight","","night_weekday","","","","","","","","","night_weekday","","plymouth_twilight","","","","","","","","","","","","torbay_twilight","","","","","","night_weekday","","","","","truro_twilight","","","",""
|
||||
"Week 10 Day Tue","","","","","exeter_twilight","","night_weekday","","","","","","","","","night_weekday","","","","plymouth_twilight","","","","","","","","","","torbay_twilight","","","","","","night_weekday","","","","","","","truro_twilight","",""
|
||||
"Week 10 Day Wed","","","","","","","night_weekday","","exeter_twilight","","","","","","","night_weekday","","","","","","","plymouth_twilight","","","torbay_twilight","","","","","","","","","","night_weekday","","","truro_twilight","","","","","",""
|
||||
"Week 10 Day Thu","","","","","","","night_weekday","exeter_twilight","","","","","","","plymouth_twilight","night_weekday","","","","","","","","","","","","","","","torbay_twilight","","","","","night_weekday","","","","","","","truro_twilight","",""
|
||||
"Week 10 Day Fri","","","weekend_exeter","","","","","","","","","","","","","","","","","night_weekend","plymouth_twilight","","","","","","night_weekend","","","","","","","weekend_torbay","","","","","","night_weekend","","","","weekend_truro",""
|
||||
"Week 10 Day Sat","","","weekend_exeter","","","","","","","","","","","weekend_plymouth2","","","","","weekend_plymouth1","night_weekend","","","","","","","night_weekend","","","","","","","weekend_torbay","","","","","","night_weekend","","","","weekend_truro",""
|
||||
"Week 10 Day Sun","","","weekend_exeter","","","","","","","","","","","weekend_plymouth2","","","","","weekend_plymouth1","night_weekend","","","","","","","night_weekend","","","","","","","weekend_torbay","","","","","","night_weekend","","","","weekend_truro",""
|
||||
"Week 11 Day Mon","","","","exeter_twilight","","","","night_weekday","","","","","","","night_weekday","","plymouth_twilight","","","","","","","","","","","night_weekday","torbay_twilight","","","","","","","","","","","","truro_twilight","","","",""
|
||||
"Week 11 Day Tue","","","","exeter_twilight","","","","night_weekday","","","","","plymouth_twilight","","night_weekday","","","","","","","","","","","","","night_weekday","torbay_twilight","","","","","","","","","","","","","truro_twilight","","",""
|
||||
"Week 11 Day Wed","","","","","exeter_twilight","","","night_weekday","","","","plymouth_twilight","","","night_weekday","","","","","","","","","","","","","night_weekday","torbay_twilight","","","","","","","","truro_twilight","","","","","","","",""
|
||||
"Week 11 Day Thu","","","","","","","","night_weekday","exeter_twilight","","","plymouth_twilight","","","night_weekday","","","","","","","","","","","","","night_weekday","torbay_twilight","","","","","","","","truro_twilight","","","","","","","",""
|
||||
"Week 11 Day Fri","","night_weekend","","","weekend_exeter","","","","","","","","","","","","","","","plymouth_twilight","","night_weekend","","","","","","","","","","","weekend_torbay","","","weekend_truro","","","","","","","night_weekend","",""
|
||||
"Week 11 Day Sat","","night_weekend","","","weekend_exeter","","","","","","weekend_plymouth2","","","","","","","","","","","night_weekend","weekend_plymouth1","","","","","","","","","","weekend_torbay","","","weekend_truro","","","","","","","night_weekend","",""
|
||||
"Week 11 Day Sun","","night_weekend","","","weekend_exeter","","","","","","weekend_plymouth2","","","","","","","","","","","night_weekend","weekend_plymouth1","","","","","","","","","","weekend_torbay","","","weekend_truro","","","","","","","night_weekend","",""
|
||||
"Week 12 Day Mon","","","","","","","","exeter_twilight","night_weekday","","","plymouth_twilight","","","","","","","","","","","","night_weekday","","night_weekday","","torbay_twilight","","","","","","","","","","","","","","","","","truro_twilight"
|
||||
"Week 12 Day Tue","","","","","","","exeter_twilight","","night_weekday","","","","plymouth_twilight","","","","","","","","","","","night_weekday","","night_weekday","","torbay_twilight","","","","","","","","","","","truro_twilight","","","","","",""
|
||||
"Week 12 Day Wed","","exeter_twilight","","","","","","","night_weekday","","","","","","","","","","","","plymouth_twilight","","","night_weekday","","night_weekday","","torbay_twilight","","","","","","","","","","","","truro_twilight","","","","",""
|
||||
"Week 12 Day Thu","","","","","","","exeter_twilight","","night_weekday","","","","","","","","","","","","","plymouth_twilight","","night_weekday","","night_weekday","","torbay_twilight","","","","","","","","","","","","","","","","","truro_twilight"
|
||||
"Week 12 Day Fri","","","","night_weekend","","","","weekend_exeter","","plymouth_twilight","","night_weekend","","","","","","","","","","","","","","","","","","","night_weekend","weekend_torbay","","","","","","","weekend_truro","","","","","",""
|
||||
"Week 12 Day Sat","","","","night_weekend","","","","weekend_exeter","","","","night_weekend","","","","","","weekend_plymouth2","weekend_plymouth1","","","","","","","","","","","","night_weekend","weekend_torbay","","","","","","","weekend_truro","","","","","",""
|
||||
"Week 12 Day Sun","","","","night_weekend","","","","weekend_exeter","","","","night_weekend","","","","","","weekend_plymouth2","weekend_plymouth1","","","","","","","","","","","","night_weekend","weekend_torbay","","","","","","","weekend_truro","","","","","",""
|
||||
"Week 13 Day Mon","","","","","night_weekday","","exeter_twilight","","","plymouth_twilight","","","","","","","","","","","","","night_weekday","","","","torbay_twilight","","","night_weekday","","","","","","","","truro_twilight","","","","","","",""
|
||||
"Week 13 Day Tue","","","","","night_weekday","","","","exeter_twilight","","","","","","","","","","","","","","night_weekday","plymouth_twilight","","","torbay_twilight","","","night_weekday","","","","","","","","","","","","","","","truro_twilight"
|
||||
"Week 13 Day Wed","","","","","night_weekday","","exeter_twilight","","","","","","","","","plymouth_twilight","","","","","","","night_weekday","","","","torbay_twilight","","","night_weekday","","","","","","","","","truro_twilight","","","","","",""
|
||||
"Week 13 Day Thu","","","","exeter_twilight","night_weekday","","","","","","","","","","","","","plymouth_twilight","","plymouth_bank_holidays","","","night_weekday","","","","torbay_twilight","","","night_weekday","","","","","","","","","","","","","","","truro_twilight"
|
||||
"Week 13 Day Fri","","","","","","weekend_exeter","","","","","","","","","","","night_weekend","plymouth_twilight","plymouth_bank_holidays","","","","","","","weekend_torbay","","","","","","","night_weekend","","","","night_weekend","","","","","weekend_truro","","",""
|
||||
"Week 13 Day Sat","","","","","","weekend_exeter","","","","","","","","","","weekend_plymouth2","night_weekend","","","","weekend_plymouth1","","","","","weekend_torbay","","","","","","","night_weekend","","","","night_weekend","","","","","weekend_truro","","",""
|
||||
"Week 13 Day Sun","","","","","","weekend_exeter","","","","","","","","","","weekend_plymouth2","night_weekend","","","","weekend_plymouth1","","","","","weekend_torbay","","","","","","","night_weekend","","","","night_weekend","","","","","weekend_truro","","",""
|
||||
|
||||
|
@@ -89,12 +89,7 @@ class SingleShift(object):
|
||||
Returns a text summary of the shift
|
||||
"""
|
||||
|
||||
return "{}: {} workers for sites ({}) on days ({})".format(
|
||||
self.name,
|
||||
self.workers_required,
|
||||
", ".join(self.site),
|
||||
", ".join(self.shift_days),
|
||||
)
|
||||
return f"{self.name}: {self.workers_required} workers for sites ({', '.join(self.site)}) on days ({', '.join(self.shift_days)})"
|
||||
|
||||
|
||||
class RotaBuilder(object):
|
||||
@@ -102,18 +97,21 @@ class RotaBuilder(object):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
start_date,
|
||||
weeks_to_rota=26,
|
||||
balance_offset_modifier=1,
|
||||
ltft_balance_offset=2,
|
||||
max_night_frequency=2,
|
||||
max_weekend_frequency=2,
|
||||
use_previous_shifts=False,
|
||||
start_date: datetime.datetime,
|
||||
weeks_to_rota: int = 26,
|
||||
balance_offset_modifier: int = 1,
|
||||
ltft_balance_offset: int = 1,
|
||||
max_night_frequency: int = 2,
|
||||
max_weekend_frequency: int = 2,
|
||||
use_previous_shifts: bool = False,
|
||||
use_shift_balance_extra: bool = False,
|
||||
use_bank_holiday_extra: bool = False,
|
||||
):
|
||||
|
||||
print("Start time: {}".format(datetime.datetime.now()))
|
||||
print("Weeks to rota: {}".format(weeks_to_rota))
|
||||
print("Use previous shifts {}".format(use_previous_shifts))
|
||||
print(f"Start time: {datetime.datetime.now()}")
|
||||
print(f"Weeks to rota: {weeks_to_rota}")
|
||||
print(f"Use previous shifts {use_previous_shifts}")
|
||||
print(f"Use previous shifts (balance_extra) {use_shift_balance_extra}")
|
||||
|
||||
self.shifts = [] # type List[SingleShift]
|
||||
|
||||
@@ -124,12 +122,12 @@ class RotaBuilder(object):
|
||||
self.weeks_days_product = list(itertools.product(self.weeks, days))
|
||||
|
||||
self.use_previous_shifts = use_previous_shifts
|
||||
self.use_shift_balance_extra = use_shift_balance_extra
|
||||
self.use_bank_holiday_extra = use_bank_holiday_extra
|
||||
|
||||
if start_date.weekday() != 0:
|
||||
raise ValueError(
|
||||
"Start date {} must be a Mon (not a {})".format(
|
||||
start_date.isoformat(), days[start_date.weekday()]
|
||||
)
|
||||
f"Start date {start_date.isoformat()} must be a Mon (not a {days[start_date.weekday()]})"
|
||||
)
|
||||
|
||||
self.start_date = start_date
|
||||
@@ -166,6 +164,7 @@ class RotaBuilder(object):
|
||||
"balance_bank_holidays": True,
|
||||
"balance_blocks": True,
|
||||
"balance_shifts": True,
|
||||
"minimise_shift_diffs": True,
|
||||
"balance_weekends": True,
|
||||
"max_weekends": False,
|
||||
"max_shifts_per_week": 4,
|
||||
@@ -353,6 +352,22 @@ class RotaBuilder(object):
|
||||
initialize=0,
|
||||
)
|
||||
|
||||
self.model.shift_count_diff = Var(
|
||||
(
|
||||
(worker.id, shift)
|
||||
for worker in self.workers
|
||||
for shift in self.get_shift_names()
|
||||
),
|
||||
within=Reals,
|
||||
initialize=0,
|
||||
)
|
||||
|
||||
self.model.shift_count_diff_summed = Var(
|
||||
(worker.id for worker in self.workers),
|
||||
within=Reals,
|
||||
initialize=0,
|
||||
)
|
||||
|
||||
if self.constraint_options["balance_shifts"]:
|
||||
|
||||
self.model.shift_count_t1 = Var(
|
||||
@@ -799,6 +814,15 @@ class RotaBuilder(object):
|
||||
# Most of our constraints apply per worker
|
||||
for worker in self.workers:
|
||||
|
||||
if self.constraint_options["minimise_shift_diffs"]:
|
||||
self.model.constraints.add(
|
||||
self.model.shift_count_diff_summed[worker.id]
|
||||
== sum(
|
||||
self.model.shift_count_diff[worker.id, shift.name]
|
||||
for shift in self.get_shifts()
|
||||
)
|
||||
)
|
||||
|
||||
for week_blocks in self.get_week_block_iterator(4):
|
||||
# Prevent weekend shifts more than once every n weeks
|
||||
self.model.constraints.add(
|
||||
@@ -868,6 +892,11 @@ class RotaBuilder(object):
|
||||
target_shifts + float(allocated) - float(worked)
|
||||
)
|
||||
|
||||
if self.use_shift_balance_extra:
|
||||
if shift.name in worker.shift_balance_extra:
|
||||
extra = worker.shift_balance_extra[shift.name]
|
||||
target_shifts = target_shifts + extra
|
||||
|
||||
# print(worker.name, shift.name, target_shifts)
|
||||
worker.shift_target_number[shift.name] = target_shifts
|
||||
|
||||
@@ -917,6 +946,12 @@ class RotaBuilder(object):
|
||||
)
|
||||
)
|
||||
|
||||
self.model.constraints.add(
|
||||
self.model.shift_count_diff[worker.id, shift.name]
|
||||
== self.model.shift_count[worker.id, shift.name]
|
||||
- worker.shift_target_number[shift.name]
|
||||
)
|
||||
|
||||
# Define shift_count_t1 and shift_count_t2 constraints for the object
|
||||
# Thus bypassing the need for a quadratic solver
|
||||
# t1-t2 is the target
|
||||
@@ -928,8 +963,7 @@ class RotaBuilder(object):
|
||||
- self.model.shift_count_t2[worker.id]
|
||||
== sum(
|
||||
(
|
||||
self.model.shift_count[worker.id, shift.name]
|
||||
- worker.shift_target_number[shift.name]
|
||||
self.model.shift_count_diff[worker.id, shift.name]
|
||||
)
|
||||
* shift.balance_weighting
|
||||
for shift in self.get_shifts()
|
||||
@@ -938,6 +972,12 @@ class RotaBuilder(object):
|
||||
# if "night" not in shift.constraints))
|
||||
|
||||
if self.constraint_options["balance_bank_holidays"]:
|
||||
|
||||
extra_bank_holiday = 0
|
||||
if self.use_bank_holiday_extra:
|
||||
print(worker.name, worker.bank_holiday_extra)
|
||||
extra_bank_holiday = worker.bank_holiday_extra
|
||||
|
||||
self.model.constraints.add(
|
||||
self.model.bank_holiday_count[worker.id]
|
||||
== sum(
|
||||
@@ -945,6 +985,7 @@ class RotaBuilder(object):
|
||||
for week, day, shift in self.get_all_shiftname_combinations()
|
||||
if self.week_day_date_map[(week, day)] in bank_holiday_map
|
||||
)
|
||||
+ extra_bank_holiday
|
||||
)
|
||||
|
||||
xU = len(self.get_bank_holiday_week_days()) + 1
|
||||
@@ -1501,6 +1542,16 @@ class RotaBuilder(object):
|
||||
else:
|
||||
shift_balancing = 0
|
||||
|
||||
if self.constraint_options["minimise_shift_diffs"]:
|
||||
shift_diff_modifier_constant = 10
|
||||
shift_diff_balancing = sum(
|
||||
shift_diff_modifier_constant
|
||||
* self.model.shift_count_diff_summed[(worker.id)]
|
||||
for worker in self.workers
|
||||
)
|
||||
else:
|
||||
shift_diff_balancing = 0
|
||||
|
||||
if self.constraint_options["balance_nights"]:
|
||||
night_balance_modifier_constant = 10
|
||||
night_shift_balancing = sum(
|
||||
@@ -1598,6 +1649,7 @@ class RotaBuilder(object):
|
||||
weekend_shift_balancing
|
||||
+ shift_balancing
|
||||
+ night_shift_balancing
|
||||
+ shift_diff_balancing
|
||||
+ preferences
|
||||
+ nights_site_balancing
|
||||
+ bank_holiday_balancing
|
||||
@@ -1882,11 +1934,9 @@ class RotaBuilder(object):
|
||||
|
||||
l = []
|
||||
for site in w:
|
||||
l.append(
|
||||
"{}: {}".format(site, sum(worker.fte_adj for worker in w[site]) / 100)
|
||||
)
|
||||
l.append(f"{site}: {sum(worker.fte_adj for worker in w[site]) / 100}")
|
||||
t = "\n".join(l)
|
||||
return "Full time equivalent trainees by site:\n{}".format(t)
|
||||
return f"Full time equivalent trainees by site:\n{t}"
|
||||
|
||||
def get_bank_holiday_week_days(self):
|
||||
return [
|
||||
@@ -1902,12 +1952,12 @@ class RotaResults(object):
|
||||
# self.results = results
|
||||
|
||||
def export_rota_to_html(self, filename="rota"):
|
||||
with open("{}.html".format(filename), "w") as f:
|
||||
with open(f"{filename}.html", "w") as f:
|
||||
f.write(self.get_worker_timetable_html(True))
|
||||
|
||||
def export_rota_to_csv(self, filename="rota"):
|
||||
works = self.rota.model.works
|
||||
with open("{}.csv".format(filename), "w", newline="") as f:
|
||||
with open(f"{filename}.csv", "w", newline="") as f:
|
||||
wr = csv.writer(f, quoting=csv.QUOTE_ALL)
|
||||
l = ["Name"]
|
||||
l.extend([worker.name for worker in self.rota.workers])
|
||||
@@ -1926,7 +1976,7 @@ class RotaResults(object):
|
||||
wr.writerow(l4)
|
||||
|
||||
for week, day in self.rota.get_week_day_combinations():
|
||||
d = ["Week {} Day {}".format(week, day)]
|
||||
d = [f"Week {week} Day {day}"]
|
||||
|
||||
for worker in self.rota.workers:
|
||||
i = ""
|
||||
@@ -1971,16 +2021,14 @@ class RotaResults(object):
|
||||
self, show_prefs=False, marker_every=30, show_unavailable=False
|
||||
):
|
||||
model = self.rota.model
|
||||
week_string = "{:20}".format("-Week-") + "".join(
|
||||
[7 * str("{}".format(w))[-1:] for w in self.rota.weeks]
|
||||
)
|
||||
days_string = "{:20}".format("-Day-") + "".join(
|
||||
"MTWTFSS" * len(self.rota.weeks)
|
||||
week_string = f"{'-Week-':20}" + "".join(
|
||||
[7 * str(f"{w}")[-1:] for w in self.rota.weeks]
|
||||
)
|
||||
days_string = f"{'-Day-':20}" + "".join("MTWTFSS" * len(self.rota.weeks))
|
||||
timetable = []
|
||||
for worker in self.rota.workers:
|
||||
shifts = []
|
||||
w = ["{:20}".format(worker.name)]
|
||||
w = [f"{worker.name:20}"]
|
||||
for week, day in self.rota.get_week_day_combinations():
|
||||
a = "-"
|
||||
for shift in self.rota.get_shift_names_by_week_day(week, day):
|
||||
@@ -1991,16 +2039,17 @@ class RotaResults(object):
|
||||
|
||||
shift_count = ""
|
||||
for s in set(shifts):
|
||||
shift_count = shift_count + "{}: {}, ".format(s, shifts.count(s))
|
||||
shift_count = shift_count + f"{s}: {shifts.count(s)}, "
|
||||
|
||||
shift_count = shift_count + "#weekends_worked: {}\\#".format(
|
||||
model.worker_weekend_count[worker.id].value
|
||||
shift_count = (
|
||||
shift_count
|
||||
+ f"#weekends_worked: {model.worker_weekend_count[worker.id].value}\\#"
|
||||
)
|
||||
timetable.append("{} {}".format("".join(w), shift_count))
|
||||
timetable.append(f"{''.join(w)} {shift_count}")
|
||||
|
||||
if show_prefs:
|
||||
# prefs
|
||||
w = ["{:20}".format("Preferences")]
|
||||
w = [f"{'Preferences':20}"]
|
||||
for week, day in self.rota.get_week_day_combinations():
|
||||
if model.pref_not_to_work[worker.id, week, day] > 0:
|
||||
w.append("Y")
|
||||
@@ -2010,7 +2059,7 @@ class RotaResults(object):
|
||||
|
||||
if show_unavailable:
|
||||
# prefs
|
||||
w = ["{:20}".format("Unavailable")]
|
||||
w = [f"{'Unavailable':20}"]
|
||||
for week, day in self.rota.get_week_day_combinations():
|
||||
if model.available[worker.id, week, day] > 0:
|
||||
w.append("A")
|
||||
@@ -2037,9 +2086,7 @@ class RotaResults(object):
|
||||
timetable = []
|
||||
|
||||
timetable.append(
|
||||
"<h2>Rota start date: {} ({} weeks)</h2>".format(
|
||||
self.rota.start_date.isoformat(), self.rota.weeks[-1]
|
||||
)
|
||||
f"<h2>Rota start date: {self.rota.start_date.isoformat()} ({self.rota.weeks[-1]} weeks)</h2>"
|
||||
)
|
||||
|
||||
date_row = ["<th class='worker'></th>"]
|
||||
@@ -2047,9 +2094,9 @@ class RotaResults(object):
|
||||
n = 0
|
||||
for week, day in self.rota.get_week_day_combinations():
|
||||
d = self.rota.start_date + datetime.timedelta(n)
|
||||
date_row.append("<th title='{}'>Week {}: {}</th>".format(d, week, day))
|
||||
date_row.append(f"<th title='{d}'>Week {week}: {day}</th>")
|
||||
n = n + 1
|
||||
timetable.append("<tr class='data-row'>{}</tr>".format("".join(date_row)))
|
||||
timetable.append(f"<tr class='data-row'>{''.join(date_row)}</tr>")
|
||||
|
||||
current_site = ""
|
||||
|
||||
@@ -2057,11 +2104,7 @@ class RotaResults(object):
|
||||
if worker.site != current_site:
|
||||
try:
|
||||
timetable.append(
|
||||
"<tr><th class='site-title'>{} n={} fte={}</th><tr>".format(
|
||||
worker.site,
|
||||
len(self.rota.workers_at_sites[worker.site]),
|
||||
self.rota.full_time_equivalent_sites[worker.site],
|
||||
)
|
||||
f"<tr><th class='site-title'>{worker.site} n={len(self.rota.workers_at_sites[worker.site])} fte={self.rota.full_time_equivalent_sites[worker.site]}</th><tr>"
|
||||
)
|
||||
except KeyError as e:
|
||||
print(e)
|
||||
@@ -2095,7 +2138,7 @@ class RotaResults(object):
|
||||
shift_name = shift
|
||||
break
|
||||
# If we haven't run just add the shift
|
||||
title = "{} ({})".format(shift_name, d)
|
||||
title = f"{shift_name} ({d})"
|
||||
css_class = day
|
||||
unavailable_reason = ""
|
||||
if model.available[worker.id, week, day] > 0:
|
||||
@@ -2110,37 +2153,23 @@ class RotaResults(object):
|
||||
except KeyError:
|
||||
print("Error getting reason")
|
||||
print(worker.id, worker.name)
|
||||
print("Week {}, Day {}".format(week, day))
|
||||
print(f"Week {week}, Day {day}")
|
||||
unavailable_reason = "????"
|
||||
title = "{} / {}".format(title, unavailable_reason)
|
||||
title = f"{title} / {unavailable_reason}"
|
||||
|
||||
bank_holiday = ""
|
||||
if d in bank_holiday_map:
|
||||
css_class = " ".join((css_class, "bank-holiday"))
|
||||
bank_holiday = " data-bank-holiday='{}'".format(bank_holiday_map[d])
|
||||
bank_holiday = f" data-bank-holiday='{bank_holiday_map[d]}'"
|
||||
|
||||
requests = ""
|
||||
if (worker.id, week, day) in self.rota.work_requests_map:
|
||||
css_class = " ".join((css_class, "shift-requested"))
|
||||
title = " ".join((title, "[REQUESTED]"))
|
||||
requests = " data-shift-request='{}'".format(
|
||||
self.rota.work_requests_map[(worker.id, week, day)]
|
||||
)
|
||||
requests = f" data-shift-request='{self.rota.work_requests_map[worker.id, week, day]}'"
|
||||
|
||||
shift_tds.append(
|
||||
"<td title='{}' class='rota-day {}' data-shift='{}' data-available='{}' data-unavailable_reason='{}' data-date='{}' data-week='{}' data-day='{}'{}{}>{}</td>".format(
|
||||
title,
|
||||
css_class,
|
||||
shift_name,
|
||||
available,
|
||||
unavailable_reason,
|
||||
d,
|
||||
week,
|
||||
day,
|
||||
requests,
|
||||
bank_holiday,
|
||||
a,
|
||||
)
|
||||
f"<td title='{title}' class='rota-day {css_class}' data-shift='{shift_name}' data-available='{available}' data-unavailable_reason='{unavailable_reason}' data-date='{d}' data-week='{week}' data-day='{day}'{requests}{bank_holiday}>{a}</td>"
|
||||
)
|
||||
|
||||
shift_count = ""
|
||||
@@ -2148,9 +2177,28 @@ class RotaResults(object):
|
||||
for s in set(shifts):
|
||||
c = shifts.count(s)
|
||||
shift_count_dict[s] = c
|
||||
shift_count = shift_count + "{}: {}, ".format(s, c)
|
||||
shift_count = shift_count + f"{s}: {c}, "
|
||||
|
||||
worker_td = "<td title='Site: {site}' class='worker {site}' data-nwds='{nwds}' data-site='{site}' data-worker='{name}' data-fte='{fte}' data-fte_adj='{fte_adj}' data-end_date='{end_date}' data-worker-targets='{targets}' data-shift-counts='{shift_counts}' data-weekend-target='{weekend_target}' data-night-at-derriford='{nights_at_derriford}' data-pair='{pair}'><span class='name' title='{name}'>{name}</span> ({grade}) [{fte}]</td>".format(
|
||||
|
||||
shift_diff_dict = {}
|
||||
for shift in self.rota.get_shifts():
|
||||
diff = model.shift_count_diff[worker.id, shift.name].value
|
||||
shift_diff_dict[shift.name] = diff
|
||||
|
||||
|
||||
worker_td = """<td title='Site: {site}' class='worker {site}'
|
||||
data-nwds='{nwds}' data-site='{site}' data-worker='{name}'
|
||||
data-fte='{fte}' data-fte_adj='{fte_adj}' data-end_date='{end_date}'
|
||||
data-worker-targets='{targets}' data-shift-counts='{shift_counts}'
|
||||
data-weekend-target='{weekend_target}'
|
||||
data-night-at-derriford='{nights_at_derriford}'
|
||||
data-pair='{pair}'
|
||||
data-shift-balance-extra='{shift_balance_extra}'
|
||||
data-bank-holiday-extra='{bank_holiday_extra}'
|
||||
data-shift-diff='{shift_diff}'
|
||||
data-shift-diff_summed='{shift_diff_summed}'
|
||||
>
|
||||
<span class='name' title='{name}'>{name}</span> ({grade}) [{fte}]</td>""".format(
|
||||
site=worker.site,
|
||||
nwds=nwds,
|
||||
name=worker.name,
|
||||
@@ -2163,17 +2211,22 @@ class RotaResults(object):
|
||||
nights_at_derriford=worker.night_at_derriford,
|
||||
grade=worker.grade,
|
||||
pair=worker.pair,
|
||||
shift_balance_extra=json.dumps(worker.shift_balance_extra),
|
||||
shift_diff=json.dumps(shift_diff_dict),
|
||||
shift_diff_summed=model.shift_count_diff_summed[worker.id].value,
|
||||
bank_holiday_extra=worker.bank_holiday_extra,
|
||||
)
|
||||
|
||||
shift_count = shift_count + "#weekends_worked: {}\\#".format(
|
||||
model.worker_weekend_count[worker.id].value
|
||||
shift_count = (
|
||||
shift_count
|
||||
+ f"#weekends_worked: {model.worker_weekend_count[worker.id].value}\\#"
|
||||
)
|
||||
|
||||
bank_holiday_count = model.bank_holiday_count[worker.id].value
|
||||
bank_holiday_count_w = model.bank_holiday_count_w[worker.id].value - 1
|
||||
# print(worker.name, bank_holiday_count, bank_holiday_count_w)
|
||||
timetable.append(
|
||||
"<tr class='worker-row'>{}{}</tr>".format(worker_td, "".join(shift_tds))
|
||||
f"<tr class='worker-row'>{worker_td}{''.join(shift_tds)}</tr>"
|
||||
)
|
||||
# timetable.append("<tr>{}</tr>".format("".join(w), shift_count))
|
||||
|
||||
@@ -2237,15 +2290,13 @@ class RotaResults(object):
|
||||
"""
|
||||
|
||||
if include_html_tag:
|
||||
html = """<html>
|
||||
html = f"""<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="timetable.css">
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
|
||||
<script src="timetable.js" defer></script>
|
||||
</head>
|
||||
{}</html>""".format(
|
||||
html
|
||||
)
|
||||
{html}</html>"""
|
||||
|
||||
return html
|
||||
|
||||
@@ -2271,15 +2322,11 @@ class RotaResults(object):
|
||||
for day in days
|
||||
].count(1)
|
||||
if c > 0:
|
||||
l.append("{} ({})".format(shift, c))
|
||||
l.append(f"{shift} ({c})")
|
||||
total_shifts = total_shifts + c
|
||||
# print(worker.id, shift)
|
||||
timetable[worker.get_details()][shift[0]] = c
|
||||
t.append(
|
||||
"{} [{}]: {}".format(
|
||||
worker.get_full_details(), total_shifts, ", ".join(l)
|
||||
)
|
||||
)
|
||||
t.append(f"{worker.get_full_details()} [{total_shifts}]: {', '.join(l)}")
|
||||
return "\n".join(t)
|
||||
|
||||
def get_shift_summary_html(self):
|
||||
@@ -2304,15 +2351,11 @@ class RotaResults(object):
|
||||
for day in days
|
||||
].count(1)
|
||||
if c > 0:
|
||||
l.append("{} ({})".format(shift, c))
|
||||
l.append(f"{shift} ({c})")
|
||||
total_shifts = total_shifts + c
|
||||
# print(worker.id, shift)
|
||||
timetable[worker.get_details()][shift[0]] = c
|
||||
t.append(
|
||||
"{} [{}]: {}".format(
|
||||
worker.get_full_details(), total_shifts, ", ".join(l)
|
||||
)
|
||||
)
|
||||
t.append(f"{worker.get_full_details()} [{total_shifts}]: {', '.join(l)}")
|
||||
return "\n".join(t)
|
||||
|
||||
# def get_no_preference(no_pref):
|
||||
|
||||
@@ -13,21 +13,22 @@ import os
|
||||
|
||||
use_neos = False
|
||||
use_cplex = False
|
||||
solve = False
|
||||
solve = True
|
||||
|
||||
weeks_to_rota = 26
|
||||
|
||||
time_to_run = 158500
|
||||
time_to_run = 258500
|
||||
# allow = 5000
|
||||
ratio = 0.05
|
||||
ratio = 0.01
|
||||
|
||||
use_live_rota = False
|
||||
suspend_on_finish = False
|
||||
suspend_on_finish = True
|
||||
|
||||
|
||||
sites = ("truro", "exeter", "torbay", "barnstaple", "plymouth", "proc", "truro no proc")
|
||||
|
||||
Rota = RotaBuilder(
|
||||
# datetime.date(2022, 6, 6),
|
||||
datetime.date(2022, 3, 7),
|
||||
# Rota = RotaBuilder(datetime.date(2021, 12, 6),
|
||||
# Rota = RotaBuilder(datetime.date(2021, 11, 8),
|
||||
@@ -35,6 +36,8 @@ Rota = RotaBuilder(
|
||||
balance_offset_modifier=1,
|
||||
max_weekend_frequency=2,
|
||||
max_night_frequency=2,
|
||||
use_shift_balance_extra=True,
|
||||
use_bank_holiday_extra=True,
|
||||
)
|
||||
|
||||
Rota.constraint_options["limit_to_1_st2_on_nights"] = True
|
||||
@@ -44,19 +47,27 @@ Rota.constraint_options["constrain_time_off_after_nights"] = True
|
||||
Rota.constraint_options["balance_nights_across_sites"] = True
|
||||
Rota.constraint_options["balance_blocks"] = True
|
||||
Rota.constraint_options["balance_weekends"] = True
|
||||
Rota.constraint_options["balance_shifts"] = True
|
||||
Rota.constraint_options["balance_bank_holidays"] = True
|
||||
Rota.constraint_options["avoid_st2_first_month"] = True
|
||||
Rota.constraint_options["avoid_st2_first_month"] = False
|
||||
Rota.constraint_options["hard_constrain_pair_separation"] = True
|
||||
Rota.constraint_options["max_weekends"] = 20
|
||||
Rota.constraint_options["max_weekends"] = 7
|
||||
Rota.constraint_options["prevent_monday_and_tuesday_after_full_weekends"] = [
|
||||
"truro",
|
||||
"torbay",
|
||||
"exeter",
|
||||
"plymouth",
|
||||
"plymouth no proc",
|
||||
"truro no proc",
|
||||
]
|
||||
Rota.constraint_options["prevent_monday_after_full_weekends"] = ["plymouth"]
|
||||
Rota.constraint_options["prevent_fridays_before_full_weekends"] = ["plymouth"]
|
||||
Rota.constraint_options["prevent_monday_after_full_weekends"] = [
|
||||
"plymouth",
|
||||
"plymouth no proc",
|
||||
]
|
||||
Rota.constraint_options["prevent_fridays_before_full_weekends"] = [
|
||||
"plymouth",
|
||||
"plymouth no proc",
|
||||
]
|
||||
Rota.constraint_options["prevent_thursdays_before_full_weekends"] = [
|
||||
"truro",
|
||||
"torbay",
|
||||
@@ -70,11 +81,12 @@ Rota.add_shifts(
|
||||
"exeter_twilight",
|
||||
12.5,
|
||||
days[:4],
|
||||
balance_offset=1.5,
|
||||
constraints=["max_2_shifts_per_week"],
|
||||
),
|
||||
SingleShift(("truro", "truro no proc"), "truro_twilight", 12.5, days[:4]),
|
||||
SingleShift(
|
||||
("torbay",),
|
||||
("torbay", "torbay twilights"),
|
||||
"torbay_twilight",
|
||||
12.5,
|
||||
days[:4],
|
||||
@@ -86,7 +98,7 @@ Rota.add_shifts(
|
||||
"plymouth_twilight",
|
||||
12.5,
|
||||
days[:5],
|
||||
balance_offset=3,
|
||||
balance_offset=1.5,
|
||||
workers_required=1,
|
||||
constraints=["max_2_shifts_per_week"],
|
||||
),
|
||||
@@ -95,7 +107,7 @@ Rota.add_shifts(
|
||||
"weekend_exeter",
|
||||
12.5,
|
||||
days[4:],
|
||||
balance_offset=3,
|
||||
balance_offset=3.5,
|
||||
rota_on_nwds=True,
|
||||
force_as_block=True,
|
||||
),
|
||||
@@ -104,7 +116,7 @@ Rota.add_shifts(
|
||||
"weekend_truro",
|
||||
12.5,
|
||||
days[4:],
|
||||
balance_offset=3,
|
||||
balance_offset=3.5,
|
||||
rota_on_nwds=True,
|
||||
force_as_block=True,
|
||||
# force_as_block_unless_nwd=True
|
||||
@@ -114,7 +126,7 @@ Rota.add_shifts(
|
||||
"weekend_torbay",
|
||||
12.5,
|
||||
days[4:],
|
||||
balance_offset=3,
|
||||
balance_offset=3.5,
|
||||
rota_on_nwds=True,
|
||||
force_as_block=True,
|
||||
# force_as_block_unless_nwd=True
|
||||
@@ -124,7 +136,7 @@ Rota.add_shifts(
|
||||
"weekend_plymouth1",
|
||||
8,
|
||||
days[5:],
|
||||
balance_offset=3,
|
||||
balance_offset=2.5,
|
||||
workers_required=1,
|
||||
rota_on_nwds=True,
|
||||
force_as_block=True,
|
||||
@@ -134,7 +146,7 @@ Rota.add_shifts(
|
||||
"weekend_plymouth2",
|
||||
8,
|
||||
days[5:],
|
||||
balance_offset=3,
|
||||
balance_offset=2.5,
|
||||
workers_required=1,
|
||||
rota_on_nwds=True,
|
||||
force_as_block=True,
|
||||
@@ -144,7 +156,7 @@ Rota.add_shifts(
|
||||
"plymouth_bank_holidays",
|
||||
8,
|
||||
days[5:],
|
||||
balance_offset=3,
|
||||
balance_offset=1.5,
|
||||
workers_required=1,
|
||||
rota_on_nwds=True,
|
||||
force_as_block=False,
|
||||
@@ -155,7 +167,7 @@ Rota.add_shifts(
|
||||
"night_weekday",
|
||||
12.25,
|
||||
days[:4],
|
||||
balance_offset=4,
|
||||
balance_offset=5,
|
||||
balance_weighting=1,
|
||||
# hard_constrain_shift=False,
|
||||
workers_required=3,
|
||||
@@ -168,7 +180,7 @@ Rota.add_shifts(
|
||||
"night_weekend",
|
||||
12.25,
|
||||
days[4:],
|
||||
balance_offset=3,
|
||||
balance_offset=4,
|
||||
balance_weighting=1,
|
||||
# hard_constrain_shift=False,
|
||||
workers_required=3,
|
||||
@@ -203,10 +215,10 @@ if use_test_workers:
|
||||
[
|
||||
Worker(
|
||||
Rota,
|
||||
i,
|
||||
"Truro {}".format(i),
|
||||
"truro",
|
||||
4,
|
||||
id=i,
|
||||
)
|
||||
for i in range(1, 9)
|
||||
]
|
||||
@@ -298,10 +310,10 @@ else:
|
||||
Rota.add_worker(
|
||||
Worker(
|
||||
Rota,
|
||||
n,
|
||||
worker_name,
|
||||
site.lower(),
|
||||
int(grade[2]),
|
||||
n,
|
||||
int(fte),
|
||||
nwds,
|
||||
end_date,
|
||||
@@ -311,6 +323,8 @@ else:
|
||||
proc_site=site_pref,
|
||||
previous_shifts=previous_shifts,
|
||||
pair=pair,
|
||||
shift_balance_extra=w["shift_balance_extra"],
|
||||
bank_holiday_extra=w["bank_holiday_extra"],
|
||||
)
|
||||
)
|
||||
|
||||
@@ -329,11 +343,7 @@ if not solve:
|
||||
ResultsHolder.export_rota_to_html()
|
||||
sys.exit(0)
|
||||
|
||||
solver_options = {
|
||||
"ratio" : ratio,
|
||||
"seconds" : time_to_run,
|
||||
"threads" : 10
|
||||
}
|
||||
solver_options = {"ratio": ratio, "seconds": time_to_run, "threads": 10}
|
||||
|
||||
Rota.solve_model(options=solver_options)
|
||||
|
||||
|
||||
+16
-6
@@ -2,28 +2,36 @@ import datetime
|
||||
from collections import defaultdict
|
||||
|
||||
# from shifts import RotaBuilder, days, sites
|
||||
import uuid
|
||||
|
||||
|
||||
class Worker:
|
||||
def __init__(
|
||||
self,
|
||||
Rota,
|
||||
id,
|
||||
name,
|
||||
site,
|
||||
grade,
|
||||
fte=100,
|
||||
grade: int,
|
||||
id=None,
|
||||
fte: int = 100,
|
||||
nwd=None,
|
||||
end_date=None,
|
||||
oop=None,
|
||||
not_available_to_work=None,
|
||||
pref_not_to_work=None,
|
||||
work_requests=None,
|
||||
proc_site="plymouth", # We set a default proc_site
|
||||
previous_shifts={},
|
||||
pair=0,
|
||||
proc_site: str = "plymouth", # We set a default proc_site
|
||||
previous_shifts: dict = {},
|
||||
shift_balance_extra: dict = {},
|
||||
bank_holiday_extra: int = 0,
|
||||
pair: int = 0,
|
||||
):
|
||||
|
||||
# We can either have a user generated ID
|
||||
if id is not None:
|
||||
self.id = id
|
||||
else:
|
||||
self.id = uuid.uuid4()
|
||||
self.name = name
|
||||
self.site = site
|
||||
# Grade are equivalent to roles, by keeping them integer defining model
|
||||
@@ -33,6 +41,8 @@ class Worker:
|
||||
self.nwd = nwd
|
||||
self.proportion_rota_to_work = 1
|
||||
self.pair = pair
|
||||
self.shift_balance_extra = shift_balance_extra
|
||||
self.bank_holiday_extra = bank_holiday_extra
|
||||
|
||||
self.proc_site = proc_site
|
||||
if proc_site == "plymouth" or proc_site == "":
|
||||
|
||||
Reference in New Issue
Block a user