diff --git a/apps/ops/src/pages/PlanificationPage.vue b/apps/ops/src/pages/PlanificationPage.vue index 0d52db2..3a7bee6 100644 --- a/apps/ops/src/pages/PlanificationPage.vue +++ b/apps/ops/src/pages/PlanificationPage.vue @@ -572,11 +572,32 @@ function saveTemplate () { }) } function deleteTemplate (i) { weekTemplates.value = weekTemplates.value.filter((_, j) => j !== i); localStorage.setItem(LS_TPL, JSON.stringify(weekTemplates.value)) } +function countPatternDays (tm, techId) { let n = 0; for (const d of dayList.value) { const map = tm.byDow[dowOf(d.iso)]; if (map && map[techId]) n++ } return n } +// Application « consciente des absences » : on n'assigne pas un tech absent ce jour-là. +// Absent toute la semaine (≈ congé permanent: maternité/blessure) → flag « à remplacer ». +// Absent quelques jours (≈ vacances) → on saute juste ces jours, le reste du patron tient. function applyTemplate (tm) { pushHistory() - for (const d of dayList.value) { const map = tm.byDow[dowOf(d.iso)]; if (!map) continue - for (const techId in map) { const tpl = tplByName.value[map[techId]]; if (!tpl) continue; const t = techs.value.find(x => x.id === techId); setCellReplace(techId, t ? t.name : techId, d.iso, tpl) } } - $q.notify({ type: 'info', message: 'Modèle « ' + tm.name + ' » appliqué — Publier pour confirmer' }) + const skipped = {}; let applied = 0 + for (const d of dayList.value) { + const map = tm.byDow[dowOf(d.iso)]; if (!map) continue + for (const techId in map) { + if (isAbsent(techId, d.iso)) { skipped[techId] = (skipped[techId] || 0) + 1; continue } + const tpl = tplByName.value[map[techId]]; if (!tpl) continue + const t = techs.value.find(x => x.id === techId); setCellReplace(techId, t ? t.name : techId, d.iso, tpl); applied++ + } + } + const fullOut = []; const partial = [] + for (const techId in skipped) { + const t = techs.value.find(x => x.id === techId); const name = (t ? t.name : techId) + const type = absByTechDay.value[techId + '|' + (dayList.value.find(d => isAbsent(techId, d.iso)) || {}).iso] || '' + const lbl = name + (type ? ' (' + type + ')' : '') + if (skipped[techId] >= countPatternDays(tm, techId)) fullOut.push(lbl); else partial.push(lbl) + } + let msg = 'Modèle « ' + tm.name + ' » appliqué (' + applied + ' assignations)' + if (partial.length) msg += ' · absence partielle ignorée : ' + partial.join(', ') + if (fullOut.length) msg += ' · ABSENT toute la semaine — à remplacer : ' + fullOut.join(', ') + $q.notify({ type: fullOut.length ? 'warning' : 'positive', message: msg, timeout: fullOut.length ? 9000 : 4500, multiLine: true }) } // édition + sélection