query("SELECT DISTINCT YEAR(start_date) as yr FROM pf_holidays WHERE start_date IS NOT NULL ORDER BY yr DESC"); $availableYears = $yearStmt->fetchAll(PDO::FETCH_COLUMN); if (!in_array(date('Y'), $availableYears)) { $availableYears[] = date('Y'); rsort($availableYears); } $whereSQL = ""; $params = []; if ($selectedYear !== 'all') { $whereSQL = "WHERE YEAR(h.start_date) = ? OR h.start_date IS NULL"; $params[] = $selectedYear; } // 2. Récupération des voyages + Calculs $sql = " SELECT h.*, (COALESCE(h.budget_food, 0) + COALESCE(h.budget_extra, 0) + COALESCE(SUM(hi.amount), 0)) as total_cost, (SELECT COALESCE(SUM(amount), 0) FROM pf_holidays_items WHERE holiday_id = h.id AND is_paid = 1) as total_paid, (SELECT COALESCE(SUM(amount), 0) FROM pf_savings WHERE holiday_id = h.id) as total_saved FROM pf_holidays h LEFT JOIN pf_holidays_items hi ON h.id = hi.holiday_id $whereSQL GROUP BY h.id ORDER BY COALESCE(start_date, '2999-12-31') ASC "; $stmt = $pdo->prepare($sql); $stmt->execute($params); $holidays = $stmt->fetchAll(PDO::FETCH_ASSOC); $active = array_filter($holidays, fn($h) => in_array($h['status'], ['draft', 'planned', 'booked'])); $history = array_filter($holidays, fn($h) => in_array($h['status'], ['passed', 'archived'])); $globalLeftToPay = 0; foreach ($active as $h) { $globalLeftToPay += max(0, (float)$h['total_cost'] - (float)$h['total_paid']); } ?>

✈️

() :

prepare("SELECT * FROM pf_holidays_items WHERE holiday_id = ?"); $stmt->execute([$h['id']]); $items = $stmt->fetchAll(PDO::FETCH_ASSOC); $json = htmlspecialchars(json_encode(['main' => $h, 'items' => $items]), ENT_QUOTES, 'UTF-8'); $dateDisplay = htmlspecialchars($h['period_hint'] ?? ''); if (empty($dateDisplay) && $h['start_date']) { // 💡 Format Jour/Mois uniquement $dateDisplay = date('d/m', strtotime($h['start_date'])); if ($h['end_date']) $dateDisplay .= ' → ' . date('d/m', strtotime($h['end_date'])); } $statusClass = match($h['status']) { 'booked' => 'bg-green-100 text-green-800', 'planned' => 'bg-blue-100 text-blue-800', 'passed' => 'bg-gray-100 text-gray-600', default => 'bg-yellow-50 text-yellow-800' }; $cost = (float)$h['total_cost']; $paid = (float)$h['total_paid']; $saved = (float)$h['total_saved']; $leftToPay = max(0, $cost - $paid); $pctPaid = $cost > 0 ? min(100, ($paid / $cost) * 100) : 0; $pctSaved = $cost > 0 ? min(100 - $pctPaid, ($saved / $cost) * 100) : 0; $statusLabel = tr('hdl_status_' . $h['status']); echo "

".htmlspecialchars($h['title'])."

".strtoupper($statusLabel)."
👁️
🗓️ ".($dateDisplay ?: tr('hdl_dates_to_define'))."
".tr('hdl_total_budget')." ".number_format($cost, 0, ',', ' ')." €
✓ ".tr('hdl_paid')." : ".number_format($paid, 0, ',', ' ')." €
💼 ".tr('hdl_saved')." : ".number_format($saved, 0, ',', ' ')." €
⏳ ".tr('hdl_left_to_pay')." : ".number_format($leftToPay, 0, ',', ' ')." €
"; } ?>