From e099fb80cd2ad019472f665d092731be1384e6f4 Mon Sep 17 00:00:00 2001 From: "fefe.clochette" Date: Wed, 6 May 2026 21:27:03 +0200 Subject: [PATCH] fix etapes duplicate --- modules/holidays/holidays.js | 109 ++++++++---------- .../holidays/includes/api/save_holiday.php | 36 ++++-- modules/holidays/views/detail.php | 2 + 3 files changed, 80 insertions(+), 67 deletions(-) diff --git a/modules/holidays/holidays.js b/modules/holidays/holidays.js index 7d948f8..749f5d4 100644 --- a/modules/holidays/holidays.js +++ b/modules/holidays/holidays.js @@ -115,87 +115,80 @@ function closeHolidayModal() { function editHoliday(data) { const h = data.main; const modal = document.getElementById("holidayModal"); + if (!modal) return; - if (!modal) { - alert(tr("err_modal_missing")); - return; - } + openHolidayModal("edit"); - document.body.appendChild(modal); + document.getElementById("inp_id").value = h.id; + document.getElementById("inp_title").value = h.title; + document.getElementById("inp_status").value = h.status; + document.getElementById("inp_period").value = h.period_hint || ""; + document.getElementById("inp_start").value = h.start_date || ""; + document.getElementById("inp_end").value = h.end_date || ""; + document.getElementById("inp_food").value = + h.budget_food > 0 ? h.budget_food : ""; + document.getElementById("inp_extra").value = + h.budget_extra > 0 ? h.budget_extra : ""; + document.getElementById("inp_notes").value = h.notes || ""; - if (typeof openHolidayModal === "function") { - openHolidayModal("edit"); - } + document.getElementById("list_transport").innerHTML = ""; + document.getElementById("list_accommodation").innerHTML = ""; + document.getElementById("list_activity").innerHTML = ""; - modal.classList.add("open"); - modal.style.setProperty("display", "flex", "important"); - modal.style.setProperty("z-index", "999999", "important"); - document.body.classList.add("no-scroll"); - - try { - document.getElementById("inp_id").value = h.id; - document.getElementById("inp_title").value = h.title; - document.getElementById("inp_status").value = h.status; - document.getElementById("inp_period").value = h.period_hint || ""; - document.getElementById("inp_start").value = h.start_date || ""; - document.getElementById("inp_end").value = h.end_date || ""; - - document.getElementById("inp_food").value = - h.budget_food > 0 ? h.budget_food : ""; - document.getElementById("inp_extra").value = - h.budget_extra > 0 ? h.budget_extra : ""; - document.getElementById("inp_notes").value = h.notes || ""; - } catch (err) { - console.error("Erreur champs textes :", err); - } - - try { - document.getElementById("list_transport").innerHTML = ""; - document.getElementById("list_accommodation").innerHTML = ""; - document.getElementById("list_activity").innerHTML = ""; - - if (data.items && data.items.length > 0) { - data.items.forEach((item) => { - if ( - typeof addItem === "function" && - item.name !== "PF_TECHNICAL_POINT" - ) { - addItem(item.category, item.name, item.amount, item.is_paid); - } - }); - } - } catch (err) { - console.error("Erreur listes :", err); + if (data.items) { + data.items.forEach((item) => { + if (item.name !== "PF_TECHNICAL_POINT") { + // On passe maintenant l'ID et le lieu à addItem + addItem( + item.category, + item.name, + item.amount, + item.is_paid, + item.id, + item.location_name || "", + ); + } + }); } } // --- 2. GESTION DES LISTES DYNAMIQUES DANS LA MODALE --- -function addItem(category, name = "", amount = "", isPaid = 0) { +function addItem( + category, + name = "", + amount = "", + isPaid = 0, + id = "", + location = "", +) { const container = document.getElementById("list_" + category); const div = document.createElement("div"); - - div.style.display = "flex"; - div.style.gap = "8px"; - div.style.alignItems = "center"; + div.className = "savings-line-item"; // Utilisation de ta classe existante div.style.marginBottom = "10px"; const checkedAttr = isPaid == 1 ? "checked" : ""; + // Optimisation : Affichage du badge d'étape si existant + const locationBadge = location + ? `📍 ${location}` + : ""; div.innerHTML = ` + - - + +
+ ${locationBadge} + +
+ - + `; - container.appendChild(div); } diff --git a/modules/holidays/includes/api/save_holiday.php b/modules/holidays/includes/api/save_holiday.php index 26e60df..5e247f5 100644 --- a/modules/holidays/includes/api/save_holiday.php +++ b/modules/holidays/includes/api/save_holiday.php @@ -39,24 +39,42 @@ try { $id = $pdo->lastInsertId(); } - // GESTION DES ITEMS GLOBAUX (On ne supprime QUE les items qui n'ont pas de lieu défini !) - $pdo->prepare("DELETE FROM pf_holidays_items WHERE holiday_id = ? AND (location_name IS NULL OR location_name = '')")->execute([$id]); - + // GESTION INTELLIGENTE DES ITEMS if (!empty($_POST['items']['name'])) { - $stmtItem = $pdo->prepare("INSERT INTO pf_holidays_items (holiday_id, category, name, amount, is_paid) VALUES (?, ?, ?, ?, ?)"); - $count = count($_POST['items']['name']); + // On prépare une requête qui met à jour si l'ID existe, sinon insère + $stmtItem = $pdo->prepare(" + INSERT INTO pf_holidays_items (id, holiday_id, category, name, amount, is_paid, location_name) + VALUES (?, ?, ?, ?, ?, ?, ?) + ON DUPLICATE KEY UPDATE + category = VALUES(category), + name = VALUES(name), + amount = VALUES(amount), + is_paid = VALUES(is_paid) + "); + + $keepIds = []; for ($i = 0; $i < $count; $i++) { - // Utilisation de "?? ''" pour sécuriser si la donnée n'est pas envoyée - $cat = $_POST['items']['cat'][$i] ?? ''; + $itemId = !empty($_POST['items']['id'][$i]) ? (int)$_POST['items']['id'][$i] : null; + $cat = $_POST['items']['cat'][$i] ?? 'activity'; $name = trim($_POST['items']['name'][$i] ?? ''); $amount = floatval($_POST['items']['amount'][$i] ?? 0); - $paid = isset($_POST['items']['paid'][$i]) ? $_POST['items']['paid'][$i] : 0; + $paid = (int)($_POST['items']['paid'][$i] ?? 0); + $loc = !empty($_POST['items']['location'][$i]) ? $_POST['items']['location'][$i] : null; if (!empty($name)) { - $stmtItem->execute([$id, $cat, $name, $amount, $paid]); + $stmtItem->execute([$itemId, $id, $cat, $name, $amount, $paid, $loc]); + $keepIds[] = $itemId ?: $pdo->lastInsertId(); } } + + // Nettoyage : On supprime les items qui ont été retirés de la modale + // (Attention : uniquement ceux du voyage actuel qui ne sont plus dans la liste envoyée) + if (!empty($keepIds)) { + $placeholders = implode(',', array_fill(0, count($keepIds), '?')); + $sqlDel = "DELETE FROM pf_holidays_items WHERE holiday_id = ? AND id NOT IN ($placeholders)"; + $pdo->prepare($sqlDel)->execute(array_merge([$id], $keepIds)); + } } $pdo->commit(); diff --git a/modules/holidays/views/detail.php b/modules/holidays/views/detail.php index c95305e..e6adb78 100644 --- a/modules/holidays/views/detail.php +++ b/modules/holidays/views/detail.php @@ -391,6 +391,8 @@ window.I18N = { 'hdl_ph_notes': "", 'hdl_btn_add_step': "", 'hdl_quick_edit_title': "", + 'hdl_paid': "", + // --- NOUVELLES CLÉS MÉTÉO ICI --- 'weather_sunny': "",