feat: add exact shifts display in worker details and update HTML export functionality

This commit is contained in:
Ross
2026-07-08 22:38:38 +01:00
parent 0f31dfe1a9
commit 13c5ae598a
4 changed files with 66 additions and 5 deletions
+10
View File
@@ -445,9 +445,19 @@ $("#rota-table tr td:first-child").each((n, td) => {
function viewWorker(worker) {
ds = worker.dataset;
let exactShiftsText = "(none)";
if (ds.exactShifts) {
try {
let parsed = JSON.parse(ds.exactShifts);
if (Object.keys(parsed).length > 0) {
exactShiftsText = Object.entries(parsed).map(([s, c]) => `${s}: ${c}`).join(", ");
}
} catch(e) {}
}
dlg = $(`<div class='dialog' title='${ds.worker}'>
Site: ${ds.site}</br>
FTE: ${ds.fte} (${ds.fte_adj})</br>
Exact shifts: ${exactShiftsText}</br>
Start date: ${ds.start_date}</br>
End date: ${ds.end_date}</br>
Non working days: ${ds.nwds}</br>
+10
View File
@@ -1783,9 +1783,19 @@ $("#rota-table tr td:first-child").each((n, td) => {
function viewWorker(worker) {
ds = worker.dataset;
let exactShiftsText = "(none)";
if (ds.exactShifts) {
try {
let parsed = JSON.parse(ds.exactShifts);
if (Object.keys(parsed).length > 0) {
exactShiftsText = Object.entries(parsed).map(([s, c]) => `${s}: ${c}`).join(", ");
}
} catch(e) {}
}
dlg = $(`<div class='dialog' title='${ds.worker}'>
Site: ${ds.site}</br>
FTE: ${ds.fte} (${ds.fte_adj})</br>
Exact shifts: ${exactShiftsText}</br>
Start date: ${ds.start_date}</br>
End date: ${ds.end_date}</br>
Non working days: ${ds.nwds}</br>
+9 -4
View File
@@ -5175,6 +5175,10 @@ class RotaBuilder(object):
l4.extend([worker.fte for worker in self.workers])
wr.writerow(l4)
l5 = ["Exact Shifts"]
l5.extend([json.dumps(getattr(worker, "exact_shifts", {})) for worker in self.workers])
wr.writerow(l5)
for week, day in self.get_week_day_combinations():
d = [f"Week {week} Day {day}"]
@@ -5504,9 +5508,7 @@ class RotaBuilder(object):
# --- Highlight force assigned shifts ---
if force_assigned:
css_class += " force-assigned"
title = f"{shift_name} ({d}) [FORCE ASSIGNED]"
else:
title = f"{shift_name} ({d})"
title = f"{title} [FORCE ASSIGNED]"
bank_holiday = ""
if d in self.bank_holidays:
@@ -5546,8 +5548,9 @@ class RotaBuilder(object):
if shift.has_constraint(NightConstraint):
css_class = " ".join((css_class, "night-shift"))
title_escaped = title.replace("'", "&apos;").replace('"', "&quot;")
shift_tds.append(
f"<td title='{','.join(shift_names)} ({d})' class='rota-day {css_class}'"
f"<td title='{title_escaped}' class='rota-day {css_class}'"
f" data-shift='{','.join(assigned_shift_names)}'"
f" data-shift-display='{','.join(shift_names)}'"
f" data-available='{available}'"
@@ -5758,6 +5761,7 @@ class RotaBuilder(object):
data-weekend-sat='{weekend_sat}'
data-weekend-sun='{weekend_sun}'
data-previous-shifts='{previous_shifts}'
data-exact-shifts='{exact_shifts}'
data-shift-diff='{shift_diff}'
data-shift-diff-summed='{shift_diff_summed}'
>
@@ -5781,6 +5785,7 @@ class RotaBuilder(object):
weekend_sun=sun_count,
worker_summary_html=worker_summary_html,
previous_shifts=json.dumps(prior_map),
exact_shifts=json.dumps(getattr(worker, "exact_shifts", {})),
pair=worker.pair,
shift_balance_extra=json.dumps(worker.shift_balance_extra),
shift_diff=json.dumps(shift_diff_dict),
+36
View File
@@ -1833,3 +1833,39 @@ def test_exact_shifts_exceed_total_warning():
warnings = Rota.get_warnings("Exact shifts exceed total shifts")
assert len(warnings) > 0
assert "total exact shifts (4) exceeds total required shifts" in warnings[0][1]
def test_html_export_worker_details_and_unavailable_reason():
weeks_to_rota = 2
start_date = datetime.date(2022, 3, 7)
Rota = RotaBuilder(
start_date,
weeks_to_rota=weeks_to_rota,
)
Rota.add_workers([
Worker(
name="worker1",
site="group1",
grade=1,
fte=100,
exact_shifts={"a": 1},
start_date=datetime.date(2022, 3, 14)
),
])
Rota.add_shifts(
SingleShift(
sites=("group1",),
name="a",
length=12.5,
days=("Mon",),
workers_required=1,
),
)
Rota.build_workers()
Rota.build_model()
html = Rota.get_worker_timetable_html()
assert 'data-exact-shifts=\'{"a": 1}\'' in html
assert 'title=\' (2022-03-07) / START DATE: 2022-03-14\'' in html