Object.defineProperties(Array.prototype, { count: { value: function (query) { /* Counts number of occurrences of query in array, an integer >= 0 Uses the javascript == notion of equality. */ var count = 0; for (let i = 0; i < this.length; i++) if (this[i] == query) count++; return count; } } }); const mean = arr => arr.reduce((p, c) => p + c, 0) / arr.length; tables = $(".table-div"); $("#extra-div").append("
"); function generateExtra() { $(".auto-generated").remove(); global_shifts = new Set(); total_summed_shift_diffs = 0; total_summed_shift_diffs_abs = 0; tables.each((n, table) => { rows = $(table).find(".worker-row"); workers = {}; rows.each((n, tr) => { worker_td = $(tr).find("td:first"); worker = worker_td.attr("data-worker"); shift_tds = $(tr).find(".rota-day"); shifts = [] shift_tds.each((n, td) => { let data_shift = $(td).attr("data-shift"); if (data_shift && data_shift !== "") { // Split by comma for multiple shifts per day let split_shifts = data_shift.split(","); split_shifts.forEach(s => { if (s && s.trim() !== "") { shifts.push(s.trim()); } }); } }) shifts_unique = new Set(shifts); shifts_unique.delete(""); global_shifts = new Set([...global_shifts, ...shifts_unique]); weekends_worked = 0; weeks = shift_tds.length / 7; whole_weekends_worked = 0; for (var i = 1; i <= weeks; i++) { if ($(tr).find(`[data-week='${i}'][data-day='Sat']`).attr("data-shift") != "" || $(tr).find(`[data-week='${i}'][data-day='Sun']`).attr("data-shift") != "") { weekends_worked = weekends_worked + 1; } if ($(tr).find(`[data-week='${i}'][data-day='Sat']`).attr("data-shift") != "" && $(tr).find(`[data-week='${i}'][data-day='Sun']`).attr("data-shift") != "") { whole_weekends_worked = whole_weekends_worked + 1; } } shift_counts = {}; total_shifts = 0; days_lost = 0; shifts_unique.forEach(el => { shift_counts[el] = shifts.count(el); total_shifts = total_shifts + shifts.count(el); // why like this? if (el == "night_weekend") { whole_weekends_worked = whole_weekends_worked - shifts.count(el) / 3 } if ($("#global-settings").length == 1) { n = $(`#${el}-tdl`).val(); if (!isNaN(n)) { days_lost = days_lost + shifts.count(el) * n; } } // // 5 days for weekday nights // if(el == "night_weekday") { days_lost = days_lost + shifts.count(el) / 4 * 5 } // // 4 days for weekend nights // if(el == "night_weekend") { // days_lost = days_lost + shifts.count(el) / 3 * 4 // //whole_weekends_worked = whole_weekends_worked - shifts.count(el) / 3 // } // // 0.5 for twilights // if(el.includes("twilight")) { // twilight_days_lost = shifts.count(el) / 2 // days_lost = days_lost + twilight_days_lost // } }); // Also 1 day for a whole weekend days_lost = days_lost + whole_weekends_worked // Highlight non working days nwds = JSON.parse(worker_td.attr("data-nwds")); nwds.forEach(element => { // Restrict to date ranges start_date = new Date(Date.parse(element[1])) end_date = new Date(Date.parse(element[2])) $(shift_tds).filter(`.${element[0]}`).each( (n, td_el) => { td_date = new Date(Date.parse(td_el.dataset.date)); if (td_date >= start_date && td_date < end_date) { $(td_el).addClass("nwd"); } } ) }); workers[worker] = { "site": worker_td.attr("data-site"), "nwds": worker_td.attr("data-nwds"), "fte": worker_td.attr("data-fte_adj"), "end_date": worker_td.attr("data-end_date"), "shift_diff": worker_td.attr("data-shift-diff"), "shifts": shifts, "shift_types": shifts_unique, "weekends_worked": weekends_worked, "shift_counts": shift_counts, "days_lost": days_lost, //"shifts" } sc = JSON.stringify(shift_counts); bank_holidays = shift_tds.filter(".bank-holiday").filter(function (i) { return $(this).attr('data-shift') != ""; }); bank_holidays_worked = bank_holidays.length; nights_worked = $(tr).find(".night-shift").length; shift_diff = JSON.parse(worker_td.attr("data-shift-diff")); summed_shift_diff = Object.values(shift_diff).reduce((a, b) => a + b); total_summed_shift_diffs = total_summed_shift_diffs + summed_shift_diff; total_summed_shift_diffs_abs = total_summed_shift_diffs_abs + Math.abs(summed_shift_diff); worker_td.get(0).dataset.shiftDiffSummed = summed_shift_diff.toPrecision(2); worker_td.after(`| Date | Week | Day | Worker(s) | "); table.append(headerRow); $("table#main-table th.date").each((n, th) => { let date = th.dataset.date; let week = ""; let day = ""; let firstTd = $(`table#main-table td[data-date='${date}']`).first(); if (firstTd.length) { week = firstTd.attr("data-week") || ""; day = firstTd.attr("data-day") || ""; } let row = $("|
|---|---|---|---|---|
| ${date} | `); row.append(`${week} | `); row.append(`${day} | `); let workerCells = []; $(`table#main-table td[data-date='${date}']`).filter(function () { let shifts = $(this).attr("data-shift"); if (!shifts) return false; let cell_shifts = shifts.split(",").map(s => s.trim()); return Array.from(selectedShifts).some(s => cell_shifts.includes(s)); }).each((n, td) => { let workerTd = $(td).closest("tr").children("td:first"); let workerName = workerTd.find("span.name").text().trim(); if (!workerMatchesFilter(workerName)) return; let cell_shifts = $(td).attr("data-shift").split(",").map(s => s.trim()); let matchedShifts = Array.from(selectedShifts).filter(s => cell_shifts.includes(s)); let color = "#fff"; if (matchedShifts.length === 1) { color = shiftColors[matchedShifts[0]]; } else if (matchedShifts.length > 1) { color = `linear-gradient(90deg, ${shiftColors[matchedShifts[0]]} 0 50%, ${shiftColors[matchedShifts[1]]} 50% 100%)`; } workerCells.push(`${workerName} | `); }); if (workerCells.length === 0) { row.append(""); } else { row.append(workerCells.join("")); } table.append(row); }); $("#shift-timetable-div").append(table); return; } // Grid view let weeks = []; let daysOfWeek = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; $("table#main-table td[data-week]").each(function () { let week = $(this).attr("data-week"); if (week && !weeks.includes(week)) weeks.push(week); }); weeks = weeks.sort((a, b) => parseInt(a) - parseInt(b)); let workerIds = []; let workerIdToName = {}; $("table#main-table td.worker").each(function () { let workerId = $(this).attr("data-worker-id"); if (workerId && !workerIds.includes(workerId)) { let workerName = $(this).find("span.name").text().trim(); if (workerMatchesFilter(workerName)) { workerIds.push(workerId); workerIdToName[workerId] = workerName; } } }); let cellMap = {}; $("table#main-table td.worker").each(function () { let workerId = $(this).attr("data-worker-id"); let workerName = $(this).find("span.name").text().trim(); if (!cellMap[workerId]) cellMap[workerId] = { name: workerName, cells: {} }; }); $("table#main-table td[data-week][data-day]").each(function () { let td = $(this); let tr = td.closest("tr"); let workerTd = tr.find("td.worker"); let workerId = workerTd.attr("data-worker-id"); let week = td.attr("data-week"); let day = td.attr("data-day"); let shifts = (td.attr("data-shift") || "").split(",").map(s => s.trim()).filter(Boolean); if (workerId && week && day) { if (!cellMap[workerId].cells[week]) cellMap[workerId].cells[week] = {}; cellMap[workerId].cells[week][day] = shifts; } }); let gridTable = $(` |