connect_error) { error_log("Erreur connexion DB getLeaveCounters: " . $conn->connect_error); echo json_encode(["success" => false, "message" => "Erreur de connexion à la base de données : " . $conn->connect_error]); exit(); } // Récupère l'ID utilisateur depuis les paramètres de requête GET $userId = $_GET['user_id'] ?? null; error_log("=== DEBUT getLeaveCounters.php ==="); error_log("getLeaveCounters - user_id reçu: " . ($userId ?? 'NULL')); error_log("getLeaveCounters - Toutes les variables GET: " . print_r($_GET, true)); if ($userId === null) { error_log("getLeaveCounters - user_id manquant"); echo json_encode(["success" => false, "message" => "ID utilisateur manquant."]); exit(); } // Fonction pour déterminer l'exercice des congés payés (01/06 au 31/05) function getLeaveYear($date = null) { if ($date === null) { $date = new DateTime(); } else { $date = new DateTime($date); } $currentYear = (int)$date->format('Y'); $currentMonth = (int)$date->format('m'); // Si on est avant le 1er juin, l'exercice a commencé l'année précédente if ($currentMonth < 6) { return $currentYear - 1; } // Si on est le 1er juin ou après, l'exercice a commencé cette année return $currentYear; } // Fonction pour déterminer l'année RTT (01/01 au 31/12) function getRTTYear($date = null) { if ($date === null) { $date = new DateTime(); } else { $date = new DateTime($date); } return (int)$date->format('Y'); } // Récupère l'ID utilisateur depuis les paramètres de requête GET $userId = $_GET['user_id'] ?? null; if ($userId === null) { echo json_encode(["success" => false, "message" => "ID utilisateur manquant."]); exit(); } // Calcul des exercices selon les règles de gestion $leaveYear = getLeaveYear(); // Exercice CP (01/06 au 31/05) $rttYear = getRTTYear(); // Exercice RTT (01/01 au 31/12) $currentDate = date('Y-m-d'); // Date actuelle pour les filtres de demandes // Variables pour les soldes disponibles $cpSolde = 0; $rttSolde = 0; $absSolde = 0; // Variables pour les demandes en cours/validées $cpInProcess = 0; $rttInProcess = 0; $absenteism = 0; // --- FONCTION UTILITAIRE POUR CALCULER LES JOURS OUVRÉS (hors week-ends) --- function getWorkingDays($startDate, $endDate) { $workingDays = 0; $current = new DateTime($startDate); $end = new DateTime($endDate); while ($current <= $end) { $dayOfWeek = (int)$current->format('N'); // 1 (pour Lundi) à 7 (pour Dimanche) if ($dayOfWeek < 6) { // Si ce n'est ni Samedi (6) ni Dimanche (7) $workingDays++; } $current->modify('+1 day'); } return $workingDays; } // ------------------------------------------------------------------------- // --- Récupération du Solde de Congé Payé (CP) --- $queryCPSolde = "SELECT cc.Solde FROM CompteurConges cc JOIN TypeConge tc ON cc.TypeCongeId = tc.Id WHERE cc.EmployeeId = ? AND tc.Nom = 'Congé payé' AND cc.Annee = ?"; $stmtCPSolde = $conn->prepare($queryCPSolde); if ($stmtCPSolde === false) { error_log("Erreur de préparation de la requête CP Solde : " . $conn->error); } else { $stmtCPSolde->bind_param("ii", $userId, $leaveYear); $stmtCPSolde->execute(); $resultCPSolde = $stmtCPSolde->get_result(); if ($rowCPSolde = $resultCPSolde->fetch_assoc()) { $cpSolde = $rowCPSolde['Solde']; } $stmtCPSolde->close(); } // --- Récupération du Solde de RTT --- $queryRTTSolde = "SELECT cc.Solde FROM CompteurConges cc JOIN TypeConge tc ON tc.Id = cc.TypeCongeId WHERE cc.EmployeeId = ? AND tc.Nom = 'RTT' AND cc.Annee = ?"; $stmtRTTSolde = $conn->prepare($queryRTTSolde); if ($stmtRTTSolde === false) { error_log("Erreur de préparation de la requête RTT Solde : " . $conn->error); } else { $stmtRTTSolde->bind_param("ii", $userId, $rttYear); $stmtRTTSolde->execute(); $resultRTTSolde = $stmtRTTSolde->get_result(); if ($rowRTTSolde = $resultRTTSolde->fetch_assoc()) { $rttSolde = $rowRTTSolde['Solde']; } $stmtRTTSolde->close(); } // --- Récupération du Solde de Congé Maladie (ABS) --- $queryABSSolde = "SELECT cc.Solde FROM CompteurConges cc JOIN TypeConge tc ON tc.Id = cc.TypeCongeId WHERE cc.EmployeeId = ? AND tc.Nom = 'Congé maladie' AND cc.Annee = ?"; $stmtABSSolde = $conn->prepare($queryABSSolde); if ($stmtABSSolde === false) { error_log("Erreur de préparation de la requête ABS Solde : " . $conn->error); } else { $stmtABSSolde->bind_param("ii", $userId, $rttYear); $stmtABSSolde->execute(); $resultABSSolde = $stmtABSSolde->get_result(); if ($rowABSSolde = $resultABSSolde->fetch_assoc()) { $absSolde = $rowABSSolde['Solde']; } $stmtABSSolde->close(); } // --- Calcul des Congés Payés (CP) en cours (demandes 'En attente' ou 'Validée' dont la fin est >= date actuelle) --- // Cette requête sélectionne les dates pour le calcul en PHP $queryCPInProcessDates = "SELECT dc.DateDebut, dc.DateFin FROM DemandeConge dc JOIN TypeConge tc ON dc.TypeCongeId = tc.Id WHERE dc.EmployeeId = ? AND tc.Nom = 'Congé payé' AND dc.Statut IN ('En attente', 'Validée') AND dc.DateFin >= ?"; $stmtCPInProcessDates = $conn->prepare($queryCPInProcessDates); if ($stmtCPInProcessDates === false) { error_log("Erreur de préparation de la requête CP en cours dates : " . $conn->error); } else { $stmtCPInProcessDates->bind_param("is", $userId, $currentDate); $stmtCPInProcessDates->execute(); $resultCPInProcessDates = $stmtCPInProcessDates->get_result(); while ($row = $resultCPInProcessDates->fetch_assoc()) { $cpInProcess += getWorkingDays($row['DateDebut'], $row['DateFin']); } $stmtCPInProcessDates->close(); } // --- Calcul des RTT en cours (mêmes critères que CP, mais pour RTT) --- $queryRTTInProcessDates = "SELECT dc.DateDebut, dc.DateFin FROM DemandeConge dc JOIN TypeConge tc ON dc.TypeCongeId = tc.Id WHERE dc.EmployeeId = ? AND tc.Nom = 'RTT' AND dc.Statut IN ('En attente', 'Validée') AND dc.DateFin >= ?"; $stmtRTTInProcessDates = $conn->prepare($queryRTTInProcessDates); if ($stmtRTTInProcessDates === false) { error_log("Erreur de préparation de la requête RTT en cours dates : " . $conn->error); } else { $stmtRTTInProcessDates->bind_param("is", $userId, $currentDate); $stmtRTTInProcessDates->execute(); $resultRTTInProcessDates = $stmtRTTInProcessDates->get_result(); while ($row = $resultRTTInProcessDates->fetch_assoc()) { $rttInProcess += getWorkingDays($row['DateDebut'], $row['DateFin']); } $stmtRTTInProcessDates->close(); } // --- Calcul des jours d'absence (ABS) (somme des jours DATEDIFF à partir de DemandeConge) --- // Note: Ici, on ne modifie pas le calcul, car l'absentéisme maladie est souvent compté sur tous les jours, y compris week-ends, pour le suivi global. // Si vous devez exclure les week-ends pour les ABS, appliquez getWorkingDays ici aussi. $queryABSInProcess = "SELECT SUM(DATEDIFF(dc.DateFin, dc.DateDebut) + 1) AS total_abs FROM DemandeConge dc JOIN TypeConge tc ON dc.TypeCongeId = tc.Id WHERE dc.EmployeeId = ? AND tc.Nom = 'Congé maladie' AND dc.Statut = 'Validée'"; $stmtABSInProcess = $conn->prepare($queryABSInProcess); if ($stmtABSInProcess === false) { error_log("Erreur de préparation de la requête ABS en cours : " . $conn->error); } else { $stmtABSInProcess->bind_param("i", $userId); $stmtABSInProcess->execute(); $resultABSInProcess = $stmtABSInProcess->get_result(); if ($rowABSInProcess = $resultABSInProcess->fetch_assoc()) { $absenteism = $rowABSInProcess['total_abs'] ?? 0; } $stmtABSInProcess->close(); } // --- Calcul des soldes disponibles réels (déduction "douce" pour l'affichage/validation frontend) --- $availableCPCalculated = $cpSolde - $cpInProcess; if ($availableCPCalculated < 0) { $availableCPCalculated = 0; } $availableRTTCalculated = $rttSolde - $rttInProcess; if ($availableRTTCalculated < 0) { $availableRTTCalculated = 0; } // Renvoie les compteurs sous format JSON echo json_encode([ "success" => true, "message" => "Compteurs récupérés avec succès.", "counters" => [ "availableCP" => (int)$availableCPCalculated, // CP: Solde brut - jours ouvrés en cours/validés futurs "availableRTT" => (int)$availableRTTCalculated, // RTT: Solde brut - jours ouvrés en cours/validés futurs "availableABS" => (int)$absSolde, // ABS: Solde brut (sans déduction des jours en cours) "rttInProcess" => (int)$rttInProcess, // RTT: Jours ouvrés en attente/validés futurs (pour information) "absenteism" => (int)$absenteism // ABS: Jours d'absence maladie validés/pris (pour information) ], "debug_values" => [ "initial_cp_solde" => (int)$cpSolde, "cp_en_cours" => (int)$cpInProcess, "calculated_available_cp" => (int)$availableCPCalculated, "initial_rtt_solde" => (int)$rttSolde, "rtt_en_cours" => (int)$rttInProcess, "calculated_available_rtt" => (int)$availableRTTCalculated, "leave_year" => $leaveYear, "rtt_year" => $rttYear, "current_date_php" => $currentDate, "user_id_php" => (int)$userId ] ]); $conn->close(); ?>