Enhance weekend shift handling by adding per-day adjustments and improving prior allocation parsing

This commit is contained in:
Ross
2025-12-17 12:13:56 +00:00
parent 710a2aa7c8
commit 0851b992fb
3 changed files with 99 additions and 15 deletions
+34 -1
View File
@@ -339,7 +339,9 @@ $(".table-div .worker-row .worker").each((n, tr) => {
})
// Build per-shift prior-adjust spans from data-previous-shifts
// Try both the raw attribute and jQuery-parsed data for robustness
let prev_attr = jtr.attr("data-previous-shifts");
if (!prev_attr) prev_attr = jtr.data("previous-shifts");
let partsHtml = "";
let sat_adj = null;
let sun_adj = null;
@@ -347,8 +349,10 @@ $(".table-div .worker-row .worker").each((n, tr) => {
try {
let prev_map = (typeof prev_attr === 'object') ? prev_attr : JSON.parse(prev_attr);
let parts = [];
// Build parts for non-weekend shifts first; we'll always render weekend per-day below.
for (let k in prev_map) {
if (!prev_map.hasOwnProperty(k)) continue;
if (k === 'weekend') continue;
let entry = prev_map[k];
let adj = null;
if (entry && typeof entry === 'object' && !Array.isArray(entry)) {
@@ -367,8 +371,8 @@ $(".table-div .worker-row .worker").each((n, tr) => {
// compute per-day weekend adjustments if present under 'weekend'
if ('weekend' in prev_map) {
let w = prev_map['weekend'];
// Prefer explicit per-day entries when present
if (w && typeof w === 'object' && !Array.isArray(w)) {
// case: { 'Sat': {worked:.., allocated:..}, 'Sun': {...} } OR tuples
if ('Sat' in w) {
let e = w['Sat'];
if (e && typeof e === 'object' && 'allocated' in e && 'worked' in e) sat_adj = parseFloat(e.allocated) - parseFloat(e.worked);
@@ -379,6 +383,20 @@ $(".table-div .worker-row .worker").each((n, tr) => {
if (e && typeof e === 'object' && 'allocated' in e && 'worked' in e) sun_adj = parseFloat(e.allocated) - parseFloat(e.worked);
else if (Array.isArray(e) && e.length >= 2) sun_adj = parseFloat(e[1]) - parseFloat(e[0]);
}
// If no per-day entries but there is an overall weekend value, split it evenly
if (sat_adj === null && sun_adj === null && 'allocated' in w && 'worked' in w) {
try {
let total = parseFloat(w.allocated) - parseFloat(w.worked);
if (isFinite(total)) {
sat_adj = sun_adj = total / 2.0;
}
} catch (err) {
// leave as null on parse error
}
}
// Handle a '__all__' bucket (tuple or object) as fallback
if (sat_adj === null && sun_adj === null && '__all__' in w) {
let e = w['__all__'];
if (Array.isArray(e) && e.length >= 2) {
@@ -394,6 +412,16 @@ $(".table-div .worker-row .worker").each((n, tr) => {
let total = parseFloat(w[1]) - parseFloat(w[0]);
sat_adj = sun_adj = total / 2.0;
}
// Always append per-day prior-adjust parts for weekend so the section is per-day
if (sat_adj !== null && Math.abs(sat_adj) > 0.0001) {
let s = (sat_adj > 0 ? '+' : '') + Number(sat_adj).toFixed(2);
partsHtml += `<span class='prior-adjust-part' data-shift='weekend' data-day='Sat' data-adj='${sat_adj}' style='display:inline-block;padding:0 6px;margin-right:6px;border-radius:3px'>Sat:${s}</span>`;
}
if (sun_adj !== null && Math.abs(sun_adj) > 0.0001) {
let s = (sun_adj > 0 ? '+' : '') + Number(sun_adj).toFixed(2);
partsHtml += `<span class='prior-adjust-part' data-shift='weekend' data-day='Sun' data-adj='${sun_adj}' style='display:inline-block;padding:0 6px;margin-right:6px;border-radius:3px'>Sun:${s}</span>`;
}
}
} catch (e) {
@@ -408,7 +436,9 @@ $(".table-div .worker-row .worker").each((n, tr) => {
if (!isFinite(adjf)) return '';
let sign = (adjf > 0) ? '+' : '';
let text = `${sign}${adjf.toFixed(2)}`;
// scale alpha by magnitude but ensure a minimum so small adjustments remain visible
let mag = Math.min(1.0, Math.abs(adjf) / 3.0);
if (mag < 0.12) mag = 0.12;
let bg, color;
if (adjf > 0) { bg = `rgba(0,128,0,${mag.toFixed(2)})`; color = '#fff'; }
else if (adjf < 0) { bg = `rgba(196,0,0,${mag.toFixed(2)})`; color = '#fff'; }
@@ -436,6 +466,9 @@ $(".table-div .worker-row .worker").each((n, tr) => {
// fallback: leave counts at 0
}
console.log("Computed weekend counts and adjustments for worker:", jtr.data("worker"));
console.log(`sat_count: ${sat_count}, sun_count: ${sun_count}, sat_adj: ${sat_adj}, sun_adj: ${sun_adj}`);
// Insert worker summary now that we have per-day adjustment badges
// Hidden by default so summaries only appear when rota days are hidden
let workerSummaryHtml = `<div class='worker-summary auto-generated' style='display: none;'>