From bae7303d66fc70b6f273689edbdcebb665cfcb61 Mon Sep 17 00:00:00 2001 From: louispaulb Date: Sun, 5 Jul 2026 00:16:19 -0400 Subject: [PATCH] =?UTF-8?q?fix(ops):=20Sugg=C3=A9rer=20never=20sweeps=20ov?= =?UTF-8?q?erdue=20jobs=20unless=20opted=20in?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le correctif précédent ne couvrait que l'entrée Tournées. Les jobs en retard (scheduled_date < fenêtre) ou sans date étaient encore balayés sur le jour choisi via d'autres chemins (bouton SUGGÉRER hors Tournées, solveur ⚡ Optimiser). Corrigé À LA SOURCE + au placement : - suggestJobs() (source unique — utilisée aussi par le solveur qui reçoit job_names) : exclut désormais les jobs hors fenêtre (retard/sans date/ autre jour) SAUF si l'utilisateur coche « ⏰ en retard » / « Sans date » ou fait une sélection lasso. Sélectionner un seul jour ne dispatche donc QUE les jobs dus ce jour-là. - buildSuggestion() : la branche fourre-tout `else cand = win` ne place plus les retards/sans-date automatiquement — même garde (lasso ou chips explicites) en défense. Vérifié live (Tournées, 06/07) : plan de 25 jobs, tous sur « 07-06 » (aucune date antérieure), 0 nouvelle erreur. Co-Authored-By: Claude Opus 4.8 --- apps/ops/src/pages/PlanificationPage.vue | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/apps/ops/src/pages/PlanificationPage.vue b/apps/ops/src/pages/PlanificationPage.vue index 7b8c757..98ddca8 100644 --- a/apps/ops/src/pages/PlanificationPage.vue +++ b/apps/ops/src/pages/PlanificationPage.vue @@ -4342,7 +4342,14 @@ function buildSuggestion () { if (j._reDate && winSet.has(j._reDate)) cand = [j._reDate] // date re-choisie (dans la fenêtre) else if (sched && winSet.has(sched)) cand = [sched] // daté DANS la fenêtre → ce jour else if (sched && sched > winMax) continue // daté APRÈS la fenêtre → PAS dispatché maintenant (on ne planifie pas loin) - else cand = win // en retard / sans date / avant la fenêtre → placé dans la fenêtre + else { + // En retard (date < fenêtre) ou sans date : NE PLUS balayer automatiquement sur le(s) jour(s) choisi(s). + // Seulement si EXPLICITEMENT demandé : sélection lasso, ou chip « ⏰ en retard » / « Sans date » coché. + // → sélectionner un seul jour ne dispatche QUE les jobs dus ce jour-là (retour terrain : les retards ne doivent pas s'inviter). + const wantBacklog = useSel || (assignDateFilter.value || []).includes('__overdue__') || (assignDateFilter.value || []).includes('Sans date') + if (!wantBacklog) continue + cand = win + } if (!cand.length) continue let best = null for (const t of techs) { @@ -4463,8 +4470,14 @@ const suggestJobs = () => { let jobs = (assignJobsFiltered.value || []).filter(j => j.status !== 'On Hold') // pool tel qu'affiché (type + date) // Par DÉFAUT (aucun chip de date coché) : ne répartir QUE les jobs DATÉS sur le(s) jour(s) de la fenêtre — jamais les // jobs en retard/sans date/d'autres jours (souvent faits mais pas encore fermés) qui pollueraient la simulation. - // (Pour dispatcher les retards, cocher explicitement le chip « ⏰ en retard ».) - if (!assignDateFilter.value.length) { const win = new Set(suggestWindow.value); jobs = jobs.filter(j => win.has(j.scheduled_date)) } + // (Pour dispatcher les retards, cocher explicitement le chip « ⏰ en retard » ou « Sans date ».) + // Filtre appliqué à la SOURCE (couvre aussi le solveur ⚡ Optimiser qui prend suggestJobs()) : seuls les jobs + // datés DANS la fenêtre passent, SAUF si l'utilisateur demande explicitement les retards/sans-date. + const wantBacklog = (assignDateFilter.value || []).includes('__overdue__') || (assignDateFilter.value || []).includes('Sans date') + if (!wantBacklog) { + const win = new Set(suggestWindow.value) + jobs = jobs.filter(j => j.scheduled_date && j.scheduled_date !== 'Sans date' && win.has(j.scheduled_date)) + } return jobs } const suggestJobCount = computed(() => suggestJobs().length)