`;
- const types = this.leaveMatrix[person.id] || [];
+ // Typage strict String(person.id) pour matcher avec le calcul des balances
+ const types = this.leaveMatrix[String(person.id)] || [];
types.forEach((conf) => {
const type = conf.type;
const startBal =
- this.monthlyLeaveBalances[person.id]?.[type]?.[monthsToDisplay[0]]
- ?.availableAtMonthStart || 0;
+ this.monthlyLeaveBalances[String(person.id)]?.[type]?.[
+ monthsToDisplay[0]
+ ]?.availableAtMonthStart || 0;
+
let totalUsed = 0;
- monthsToDisplay.forEach(
- (ym) =>
- (totalUsed +=
- this.monthlyLeaveBalances[person.id]?.[type]?.[ym]
- ?.usedInMonth || 0),
- );
+ monthsToDisplay.forEach((ym) => {
+ totalUsed +=
+ this.monthlyLeaveBalances[String(person.id)]?.[type]?.[ym]
+ ?.usedInMonth || 0;
+ });
+
const endBal = Math.max(0, startBal - totalUsed);
const fmt = (n) =>
n > 0 ? (Number.isInteger(n) ? n : n.toFixed(1)) : "0";
@@ -1275,14 +1289,13 @@ document.addEventListener("DOMContentLoaded", () => {
let alertHtml = "";
const cMonth = parseInt(monthsToDisplay[0].split("-")[1]);
- // On récupère le mois de renouvellement depuis la date (ex: "2000-06-01" -> 6)
+ // Gestion de l'alerte 🔥 (Mois en cours ou Mois précédant le renouvellement)
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 = `
🔥
`;
+ alertHtml = `
🔥
`;
}
}
diff --git a/modules/family-calendar/includes/api/save-events.php b/modules/family-calendar/includes/api/save-events.php
index 22dfc66..4943491 100644
--- a/modules/family-calendar/includes/api/save-events.php
+++ b/modules/family-calendar/includes/api/save-events.php
@@ -20,9 +20,8 @@ try {
$inserted = [];
foreach ($eventsToSave as $event) {
- // 🔥 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;
+ continue; // Sécurité anti-crash
}
$person_id = 0;
@@ -32,11 +31,13 @@ try {
$person_id = (int)$event['person'];
}
+ // 🔥 LE FIX : On tronque à 50 caractères pour éviter l'erreur "Data truncated"
+ $safeType = substr(trim($event['type']), 0, 50);
$duration = isset($event['duration']) ? (float)$event['duration'] : 1.0;
$stmt->execute([
':event_date' => $event['date'],
- ':event_type' => $event['type'],
+ ':event_type' => $safeType,
':person_id' => $person_id,
':duration' => $duration,
]);
@@ -44,7 +45,7 @@ try {
$inserted[] = [
'id' => $pdo->lastInsertId(),
'date' => $event['date'],
- 'type' => $event['type'],
+ 'type' => $safeType,
'duration' => $duration,
'person_id' => $person_id,
];
@@ -58,14 +59,14 @@ try {
'inserted' => $inserted,
]);
-} catch (\Throwable $e) { // 🔥 LE CORRECTIF PRINCIPAL : \Throwable attrape AUSSI les erreurs fatales PHP !
+} catch (\Throwable $e) { // 🔥 LE FIX : \Throwable attrape AUSSI les fatals errors PDO
if (isset($pdo) && $pdo->inTransaction()) {
$pdo->rollBack();
}
http_response_code(500);
echo json_encode([
- 'success' => false,
- 'status' => 'error',
+ 'success' => false,
+ 'status' => 'error',
'message' => 'Erreur Serveur/SQL : ' . $e->getMessage()
]);
}