diff --git a/background.js b/background.js index 5a0d0e2..dc2b16a 100644 --- a/background.js +++ b/background.js @@ -644,34 +644,19 @@ async function submitDouchette(origin, phpsessid, opts) { async function deletePlanningItem(origin, phpsessid, actionId, kind) { if (!actionId) throw new Error("actionId manquant"); - // v5.0.1 : plusieurs function_name à tester dans l'ordre (du plus probable - // au moins probable). Le premier qui renvoie 200 ET non-login est considéré OK. - const fnNames = kind === "reservation" - ? [ - "Planning_delete_reservation", - "delete_reservation", - "fc_delete_reservation", - "delete_act_reservation", - "delete_planning_reservation", - "remove_reservation", - // v5.0.2 : réservations sont parfois traitées comme absences côté API - "Planning_delete_absence", - "delete_absence", - "fc_delete_absence" - ] - : [ - // v5.0.2 : élargir la liste, on a essayé 3 sans succès. Les variantes - // plausibles vues dans les API EasyVista : - "Planning_delete_absence", // le plus "officiel" - "delete_absence", // le nom JS dans le onclick - "fc_delete_absence", // pattern fc_* - "delete_act_absence", // parfois "act_" dans les noms - "Planning_delete_holiday", // en anglais - "delete_holiday", - "fc_delete_holiday", - "delete_planning_absence", // variation complète - "remove_absence" - ]; + // v5.0.14 : confirmé par capture Network réelle — EasyVista utilise + // "Planning_delete_absence" pour TOUS les types d'entrée planning (absences, + // réservations, événements, etc.). Réponse XML : true + // On met donc ce nom en PREMIER pour tout, et on garde les autres en fallback. + const fnNames = [ + "Planning_delete_absence", // ← le seul qui marche vraiment côté EV + // Fallbacks historiques (au cas où EV change un jour) : + "Planning_delete_reservation", + "delete_absence", + "delete_reservation", + "fc_delete_absence", + "fc_delete_reservation" + ]; let lastErr = null; let lastBody = null; @@ -703,22 +688,34 @@ async function deletePlanningItem(origin, phpsessid, actionId, kind) { throw new Error("session_expired"); } - // v5.0.1 : heuristique pour détecter si la suppression a marché. - // v5.0.13 : élargie pour détecter aussi le script de redirection CSRF - // (si evFetch n'a pas suffi) et les réponses vides. - const trimmed = (body || "").trim().toLowerCase(); - const looksLikeError = trimmed.includes("error") - || trimmed.includes("erreur") - || trimmed.includes("unknown function") - || trimmed.includes("fonction inconnue") - || trimmed.includes("true + const trimmed = (body || "").trim(); + const lower = trimmed.toLowerCase(); + + // Succès explicite : réponse XML du type true + if (/^<\w+>true<\/\w+>\s*$/i.test(trimmed)) { + console.log(`[bg] → SUCCÈS confirmé par XML <...>true avec function_name=${fn}`); + return { status: r.status, functionName: fn, body: trimmed }; } - console.log(`[bg] → réponse ressemble à une erreur, on tente le prochain nom`); - lastBody = body; + + // Détection d'échec : false, erreurs, html, redirect, etc. + const looksLikeError = /^<\w+>false<\/\w+>\s*$/i.test(trimmed) + || lower.includes("error") + || lower.includes("erreur") + || lower.includes("unknown function") + || lower.includes("fonction inconnue") + || lower.includes(" { + if (ab.isPompier) return false; + const s = timeToMinutes(ab.startTime); + const e = timeToMinutes(ab.endTime); + if (s === null || e === null) return false; + // Absence qui couvre PAS toute la journée → c'est partiel + return !(s <= DAY_START && e >= DAY_END); + }); + + if (realInterventions.length === 0 && !isPompier && !hasPartialAbsences) { if (isPillonelFriday) { const note = document.createElement("div"); note.className = "tech-absence-recurring";