diff --git a/modules/family-calendar/family-calendar.js b/modules/family-calendar/family-calendar.js index 3c5ba3f..85ec5f2 100644 --- a/modules/family-calendar/family-calendar.js +++ b/modules/family-calendar/family-calendar.js @@ -444,6 +444,13 @@ function renderMemberLeavesView(personId, memberLeaves) { +
+ + +
`; @@ -455,6 +462,8 @@ async function addMemberLeave(personId) { const leaveCode = document.getElementById("new-member-leave-type").value; const allowance = document.getElementById("new-member-leave-allowance").value; const resetMonth = document.getElementById("new-member-leave-reset").value; + const method = document.getElementById("new-member-leave-method").value; // <-- Ajout + fd.append("method", method); if (!leaveCode) return showToast("Veuillez sélectionner un type", "error"); @@ -1265,15 +1274,16 @@ document.addEventListener("DOMContentLoaded", () => { let alertHtml = ""; const cMonth = parseInt(monthsToDisplay[0].split("-")[1]); - if (endBal > 0) { - if (type === "CP" && (cMonth === 5 || cMonth === 6)) - alertHtml = `
🔥
`; - else if ( - type === "JRA" && - (cMonth === 1 || cMonth === 12) && - endBal > 2 - ) - alertHtml = `
🔥
`; + + // On récupère le mois de renouvellement depuis la date (ex: "2000-06-01" -> 6) + if (endBal > 0 && conf.date) { + const resetMonth = parseInt(conf.date.split("-")[1]); + // On alerte le mois même, ou le mois juste avant ! + const alertMonth = resetMonth - 1 === 0 ? 12 : resetMonth - 1; + + if (cMonth === alertMonth || cMonth === resetMonth) { + alertHtml = `
🔥
`; + } } cards += `
${type}${fmt(endBal)}${totalUsed > 0 ? `-${fmt(totalUsed)}` : ""}${alertHtml}
`; diff --git a/modules/family-calendar/includes/api/calendar-settings.php b/modules/family-calendar/includes/api/calendar-settings.php index f61bf4a..ad7bdb7 100644 --- a/modules/family-calendar/includes/api/calendar-settings.php +++ b/modules/family-calendar/includes/api/calendar-settings.php @@ -154,9 +154,12 @@ try { $type = strtoupper(trim($_POST['leave_type'] ?? '')); $allowance = (float)($_POST['allowance'] ?? 0); $resetMonth = (int)($_POST['reset_month'] ?? 1); + + $method = in_array($_POST['method'] ?? '', ['FIXED', 'ACCUMULATED']) ? $_POST['method'] : 'FIXED'; if ($personId <= 0 || empty($type)) throw new Exception("Données invalides."); + // Vérification des doublons $check = $pdo->prepare("SELECT id FROM pf_person_leave_meta WHERE person_id = ? AND leave_type = ?"); $check->execute([$personId, $type]); if ($check->rowCount() > 0) throw new Exception("Ce congé est déjà attribué à cette personne."); @@ -164,8 +167,8 @@ try { // On construit la date anniversaire avec le mois choisi par l'utilisateur $anniversaryDate = "2000-" . str_pad((string)$resetMonth, 2, "0", STR_PAD_LEFT) . "-01"; - $stmt = $pdo->prepare("INSERT INTO pf_person_leave_meta (person_id, leave_type, allowance, method, anniversary_date) VALUES (?, ?, ?, 'FIXED', ?)"); - $stmt->execute([$personId, $type, $allowance, $anniversaryDate]); + $stmt = $pdo->prepare("INSERT INTO pf_person_leave_meta (person_id, leave_type, allowance, method, anniversary_date) VALUES (?, ?, ?, ?, ?)"); + $stmt->execute([$personId, $type, $allowance, $method, $anniversaryDate]); echo json_encode(['success' => true]); exit; diff --git a/modules/family-calendar/includes/api/save-events.php b/modules/family-calendar/includes/api/save-events.php index 9f9fa0e..22dfc66 100644 --- a/modules/family-calendar/includes/api/save-events.php +++ b/modules/family-calendar/includes/api/save-events.php @@ -20,9 +20,12 @@ try { $inserted = []; foreach ($eventsToSave as $event) { - // 🔥 LE CORRECTIF : On initialise à 0 (car NOT NULL en base) - $person_id = 0; + // 🔥 SÉCURITÉ : On ignore l'itération si les données vitales manquent (évite le crash SQL) + if (empty($event['date']) || empty($event['type'])) { + continue; + } + $person_id = 0; if (!empty($event['person_id']) && is_numeric($event['person_id'])) { $person_id = (int)$event['person_id']; } elseif (!empty($event['person']) && is_numeric($event['person'])) { @@ -55,7 +58,7 @@ try { 'inserted' => $inserted, ]); -} catch (Exception $e) { +} catch (\Throwable $e) { // 🔥 LE CORRECTIF PRINCIPAL : \Throwable attrape AUSSI les erreurs fatales PHP ! if (isset($pdo) && $pdo->inTransaction()) { $pdo->rollBack(); } @@ -63,7 +66,7 @@ try { echo json_encode([ 'success' => false, 'status' => 'error', - 'message' => 'Erreur SQL : ' . $e->getMessage() + 'message' => 'Erreur Serveur/SQL : ' . $e->getMessage() ]); } ?> \ No newline at end of file