From 3930f5f1be6b102f8b1046fd0a8483e23ddef0d4 Mon Sep 17 00:00:00 2001 From: "fefe.clochette" Date: Mon, 30 Mar 2026 12:55:51 +0200 Subject: [PATCH] fix order --- modules/holidays/holidays.js | 23 ++--- .../holidays/includes/api/save_checkpoint.php | 91 +++++++++---------- modules/holidays/views/detail.php | 19 ++-- 3 files changed, 60 insertions(+), 73 deletions(-) diff --git a/modules/holidays/holidays.js b/modules/holidays/holidays.js index 75180a0..ee47470 100644 --- a/modules/holidays/holidays.js +++ b/modules/holidays/holidays.js @@ -272,7 +272,7 @@ function openCheckpointModal(mode, data = null) { const container = document.getElementById("cpExpensesContainer"); const btnDel = document.getElementById("btnDeleteCp"); - container.innerHTML = ""; // Reset des lignes + container.innerHTML = ""; if (mode === "add") { document.getElementById("cpModalTitle").innerText = @@ -280,27 +280,20 @@ function openCheckpointModal(mode, data = null) { searchBlock.style.display = "block"; formBlock.style.display = "none"; btnDel.style.display = "none"; - - document.getElementById("searchPlaceInput").value = ""; - document.getElementById("searchResults").innerHTML = ""; - - document.getElementById("cp_old_name").value = ""; + document.getElementById("cp_old_sort_order").value = ""; // Important : vide pour ajout document.getElementById("cp_name").value = ""; - - // Ajout d'une ligne vide par défaut addCpExpenseLine(); } else if (mode === "edit" && data) { document.getElementById("cpModalTitle").innerText = "✏️ Modifier l'étape"; - searchBlock.style.display = "none"; // On cache la recherche en mode édition + searchBlock.style.display = "none"; formBlock.style.display = "block"; btnDel.style.display = "block"; document.getElementById("cp_lat").value = data.lat; document.getElementById("cp_lng").value = data.lng; - document.getElementById("cp_old_name").value = data.location_name; + document.getElementById("cp_old_sort_order").value = data.sort_order; // On stocke l'index unique document.getElementById("cp_name").value = data.location_name; - // Remplissage des lignes existantes (en filtrant le point technique) if (data.items && data.items.length > 0) { let visibleCount = 0; data.items.forEach((it) => { @@ -309,15 +302,11 @@ function openCheckpointModal(mode, data = null) { visibleCount++; } }); - // Si l'étape ne contenait QUE le point technique, on affiche une ligne vide pour inviter à la saisie - if (visibleCount === 0) { - addCpExpenseLine(); - } + if (visibleCount === 0) addCpExpenseLine(); } else { - addCpExpenseLine(); // Sécurité + addCpExpenseLine(); } } - document.getElementById("checkpointModal").style.display = "flex"; } diff --git a/modules/holidays/includes/api/save_checkpoint.php b/modules/holidays/includes/api/save_checkpoint.php index c9fa577..623eaea 100644 --- a/modules/holidays/includes/api/save_checkpoint.php +++ b/modules/holidays/includes/api/save_checkpoint.php @@ -1,31 +1,62 @@ prepare("DELETE FROM pf_holidays_items WHERE holiday_id = ? AND location_name = ?")->execute([$holiday_id, $loc]); + $pdo->prepare("DELETE FROM pf_holidays_items WHERE holiday_id = ? AND sort_order = ?")->execute([$holiday_id, $old_sort_order]); header("Location: /holidays.php?tab=holiday_detail&id=" . $holiday_id); exit; } -// Ajout / Modification d'une étape -$location_name = trim($_POST['location_name']); -$old_location = trim($_POST['old_location_name'] ?? ''); -$lat = (float)$_POST['lat']; -$lng = (float)$_POST['lng']; - if ($holiday_id > 0 && !empty($location_name)) { try { $pdo->beginTransaction(); - // 1. GESTION DES FAVORIS + // 2. DÉTERMINER L'ORDRE (Identifiant de l'étape) + if ($old_sort_order !== null) { + // Modification : on supprime l'ancien contenu de cette étape précise + $pdo->prepare("DELETE FROM pf_holidays_items WHERE holiday_id = ? AND sort_order = ?")->execute([$holiday_id, $old_sort_order]); + $target_order = $old_sort_order; + } else { + // Ajout : on place à la fin (Max + 1) + $stmtMax = $pdo->prepare("SELECT MAX(sort_order) FROM pf_holidays_items WHERE holiday_id = ?"); + $stmtMax->execute([$holiday_id]); + $max = $stmtMax->fetchColumn(); + $target_order = ($max !== null) ? (int)$max + 1 : 0; + } + + // 3. INSERTION DES LIGNES + $stmt = $pdo->prepare("INSERT INTO pf_holidays_items (holiday_id, category, name, amount, is_paid, location_name, lat, lng, sort_order) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"); + $validItemsCount = 0; + + if (isset($_POST['items']['name'])) { + foreach ($_POST['items']['name'] as $i => $raw_name) { + $name = trim($raw_name); + $amount_raw = $_POST['items']['amount'][$i]; + if ($name !== '' || $amount_raw !== '') { + $cat = $_POST['items']['cat'][$i] ?? 'activity'; + $amount = (float)$amount_raw; + $paid = isset($_POST['items']['paid'][$i]) ? 1 : 0; + $stmt->execute([$holiday_id, $cat, $name ?: 'Dépense', $amount, $paid, $location_name, $lat, $lng, $target_order]); + $validItemsCount++; + } + } + } + + if ($validItemsCount === 0) { + $stmt->execute([$holiday_id, 'activity', 'PF_TECHNICAL_POINT', 0, 1, $location_name, $lat, $lng, $target_order]); + } + + // 4. GESTION DES FAVORIS if (isset($_POST['save_favorite']) && $_POST['save_favorite'] == '1') { $stmtFav = $pdo->query("SELECT content FROM pf_notes WHERE note_type = 'holiday_favorites'"); $favs = json_decode($stmtFav->fetchColumn() ?: '[]', true); @@ -37,44 +68,8 @@ if ($holiday_id > 0 && !empty($location_name)) { } } - // 2. GESTION DES DÉPENSES - if (!empty($old_location)) { - $pdo->prepare("DELETE FROM pf_holidays_items WHERE holiday_id = ? AND location_name = ?")->execute([$holiday_id, $old_location]); - } - - $stmt = $pdo->prepare("INSERT INTO pf_holidays_items (holiday_id, category, name, amount, is_paid, location_name, lat, lng) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); - $validItemsCount = 0; - - if (isset($_POST['items']['name'])) { - $count = count($_POST['items']['name']); - for ($i = 0; $i < $count; $i++) { - $name = trim($_POST['items']['name'][$i]); - $amount_raw = $_POST['items']['amount'][$i]; - - // Si la ligne n'est pas totalement vide - if ($name !== '' || $amount_raw !== '') { - $cat = $_POST['items']['cat'][$i] ?? 'activity'; - $amount = (float)$amount_raw; - if ($name === '') $name = 'Dépense liée'; - $paid = isset($_POST['items']['paid'][$i]) ? 1 : 0; - - $stmt->execute([$holiday_id, $cat, $name, $amount, $paid, $location_name, $lat, $lng]); - $validItemsCount++; - } - } - } - - // 3. ÉTAPE SANS DÉPENSE (Point de passage) - // Si l'utilisateur n'a saisi aucune dépense, on crée une ligne technique invisible pour forcer l'affichage du point GPS - if ($validItemsCount === 0) { - $stmt->execute([$holiday_id, 'activity', 'PF_TECHNICAL_POINT', 0, 1, $location_name, $lat, $lng]); - } - $pdo->commit(); - } catch (Exception $e) { - $pdo->rollBack(); - die("Erreur de sauvegarde : " . $e->getMessage()); - } + } catch (Exception $e) { $pdo->rollBack(); die($e->getMessage()); } } header("Location: /holidays.php?tab=holiday_detail&id=" . $holiday_id); diff --git a/modules/holidays/views/detail.php b/modules/holidays/views/detail.php index 642599e..380d5a1 100644 --- a/modules/holidays/views/detail.php +++ b/modules/holidays/views/detail.php @@ -24,28 +24,30 @@ $items = $stmtItems->fetchAll(PDO::FETCH_ASSOC); $stmtFav = $pdo->query("SELECT content FROM pf_notes WHERE note_type = 'holiday_favorites'"); $favorites = json_decode($stmtFav->fetchColumn() ?: '[]', true); -// GROUPEMENT PAR LIEU (Pour la carte et l'affichage) +// GROUPEMENT PAR INDEX D'ORDRE (Pour autoriser les doublons de lieux comme "Maison") $steps = []; $generalItems = []; foreach ($items as $it) { - if (!empty($it['location_name'])) { - $loc = $it['location_name']; - if (!isset($steps[$loc])) { - $steps[$loc] = [ - 'location_name' => $loc, + if ($it['location_name'] !== null) { + $orderKey = $it['sort_order']; // On utilise l'ordre comme clé unique de l'étape + if (!isset($steps[$orderKey])) { + $steps[$orderKey] = [ + 'location_name' => $it['location_name'], 'lat' => (float)$it['lat'], 'lng' => (float)$it['lng'], + 'sort_order' => $it['sort_order'], 'total_amount' => 0, 'items' => [] ]; } - $steps[$loc]['items'][] = $it; - $steps[$loc]['total_amount'] += (float)$it['amount']; + $steps[$orderKey]['items'][] = $it; + $steps[$orderKey]['total_amount'] += (float)$it['amount']; } else { $generalItems[] = $it; } } +ksort($steps); $mapPoints = array_values($steps); // Calculs d'affichage (Dates & Finances) @@ -210,6 +212,7 @@ $pctSaved = $cost > 0 ? min(100 - $pctPaid, ($saved / $cost) * 100) : 0; +