diff --git a/includes/lang/ca.php b/includes/lang/ca.php index e758616..1e51c0b 100644 --- a/includes/lang/ca.php +++ b/includes/lang/ca.php @@ -586,7 +586,6 @@ return [ 'bs_currency_label' => 'Divisa de la llar', 'bs_currency_desc' => 'Divisa principal utilitzada per mostrar els vostres comptes i pressupostos.', 'bs_currency_updated' => 'Divisa actualitzada correctament!', - 'bud_settings_dyn_title' => 'Estimacions Dinàmiques (Nens)', 'bud_dyn_nanny_fixed' => 'Sou fix Cangur (€)', 'bud_dyn_nanny_daily' => 'Despeses diàries de manteniment (€)', 'bud_dyn_nanny_aid' => 'Ajuda del govern (€)', @@ -600,7 +599,16 @@ return [ 'bud_audit_child' => '👦 %s :', 'bud_audit_school_fee' => 'Menjador (%dd) + Acollida (%dd) + Casal (%dd) = %.2f€', 'bud_audit_sick' => 'Dies de malaltia deduïts : %dd', - 'bud_audit_nanny_full' => '💼 %s : Fix (%.2f€) + Despeses (%dd x %.2f€ = %.2f€) - Ajut (%.2f€) - CESU (%.2f€) = %.2f€', + 'bud_audit_nanny_full' => '💼 %s : Fix (%.2f€) + Despeses (%dd x %.2f€ = %.2f€) - CMG (%.2f€) - %s (%.2f€) = %.2f€', + 'bud_audit_cesu_avg' => 'CESU (Mitj.)', + 'bud_audit_cesu_adj' => 'CESU (Ajustat)', + 'bud_dyn_cesu_overrides' => 'Ajustaments puntuals del CESU', + 'bud_dyn_cesu_add' => 'Afegir un mes', + 'bud_dyn_cesu_empty' => 'Cap ajustament registrat.', + 'bud_settings_dyn_title' => 'Cura i Escola', + 'bud_settings_dyn_desc' => 'Tarifes per al càlcul automatitzat de les despeses.', + 'bud_dyn_sub_nanny' => 'Cangur', + 'bud_dyn_sub_school' => 'Extraescolars i Casal', // CSV 'bs_csv_title' => 'Format de la importació CSV', diff --git a/includes/lang/en.php b/includes/lang/en.php index 3686f26..bfa6593 100644 --- a/includes/lang/en.php +++ b/includes/lang/en.php @@ -588,7 +588,6 @@ return [ 'bs_currency_label' => 'Household Currency', 'bs_currency_desc' => 'Main currency used for displaying your accounts and budgets.', 'bs_currency_updated' => 'Currency updated successfully!', - 'bud_settings_dyn_title' => 'Dynamic Estimates (Children)', 'bud_dyn_nanny_fixed' => 'Nanny fixed salary (€)', 'bud_dyn_nanny_daily' => 'Daily maintenance fee (€)', 'bud_dyn_nanny_aid' => 'Government aid (€)', @@ -602,7 +601,16 @@ return [ 'bud_audit_child' => '👦 %s :', 'bud_audit_school_fee' => 'Canteen (%dd) + Aftercare (%dd) + Center (%dd) = %.2f€', 'bud_audit_sick' => 'Sick days deducted : %dd', - 'bud_audit_nanny_full' => '💼 %s : Fixed (%.2f€) + Fees (%dd x %.2f€ = %.2f€) - Aid (%.2f€) - CESU (%.2f€) = %.2f€', + 'bud_audit_nanny_full' => '💼 %s : Fixed (%.2f€) + Fees (%dd x %.2f€ = %.2f€) - Aid (%.2f€) - %s (%.2f€) = %.2f€', + 'bud_audit_cesu_avg' => 'CESU (Avg.)', + 'bud_audit_cesu_adj' => 'CESU (Adjusted)', + 'bud_dyn_cesu_overrides' => 'Specific CESU adjustments', + 'bud_dyn_cesu_add' => 'Add a month', + 'bud_dyn_cesu_empty' => 'No adjustments recorded.', + 'bud_settings_dyn_title' => 'Care & School', + 'bud_settings_dyn_desc' => 'Rates for automated childcare fee calculations.', + 'bud_dyn_sub_nanny' => 'Nanny', + 'bud_dyn_sub_school' => 'Afterschool & Center', // CSV Mapping (Budget) 'bs_csv_title' => 'CSV Import Format', diff --git a/includes/lang/fr.php b/includes/lang/fr.php index b53d154..d12abc2 100644 --- a/includes/lang/fr.php +++ b/includes/lang/fr.php @@ -588,7 +588,6 @@ return [ 'bs_currency_label' => 'Devise du Foyer', 'bs_currency_desc' => 'Devise principale utilisée pour l\'affichage de vos comptes et budgets.', 'bs_currency_updated' => 'Devise mise à jour avec succès !', - 'bud_settings_dyn_title' => 'Estimations Dynamiques (Enfants)', 'bud_dyn_nanny_fixed' => 'Salaire fixe Assistante Maternelle (€)', 'bud_dyn_nanny_daily' => 'Frais d\'entretien journaliers (€)', 'bud_dyn_nanny_aid' => 'Aide de l\'État (CMG) (€)', @@ -602,7 +601,16 @@ return [ 'bud_audit_child' => '👦 %s :', 'bud_audit_school_fee' => 'Cantine (%dj) + Garderie (%dj) + Centre (%dj) = %.2f€', 'bud_audit_sick' => 'Jours maladie déduits : %dj', - 'bud_audit_nanny_full' => '💼 %s : Fixe (%.2f€) + Frais (%dj x %.2f€ = %.2f€) - Aide (%.2f€) - CESU (%.2f€) = %.2f€', + 'bud_audit_nanny_full' => '💼 %s : Fixe (%.2f€) + Frais (%dj x %.2f€ = %.2f€) - CMG (%.2f€) - %s (%.2f€) = %.2f€', + 'bud_audit_cesu_avg' => 'CESU (Moy.)', + 'bud_audit_cesu_adj' => 'CESU (Ajusté)', + 'bud_dyn_cesu_overrides' => 'Ajustements ponctuels du CESU', + 'bud_dyn_cesu_add' => 'Ajouter un mois', + 'bud_dyn_cesu_empty' => 'Aucun ajustement enregistré.', + 'bud_settings_dyn_title' => 'Garde & École', + 'bud_settings_dyn_desc' => 'Tarifs pour le calcul automatisé des frais de garde.', + 'bud_dyn_sub_nanny' => 'Nounou', + 'bud_dyn_sub_school' => 'Périscolaire', // CSV Mapping (Budget) 'bs_csv_title' => 'Format de l\'import CSV', diff --git a/modules/budget/budget.css b/modules/budget/budget.css index 5cde7ed..fe9916e 100644 --- a/modules/budget/budget.css +++ b/modules/budget/budget.css @@ -2701,3 +2701,36 @@ body.sum-mode-active .sum-target { text-align: right; white-space: nowrap; } + +/* --- 16. AJUSTEMENTS CESU (JSON OVERRIDES) --- */ +.bs-cesu-wrapper { + margin-top: 20px; + padding: 16px; + background: var(--bg-page); + border-radius: 8px; + border: 1px solid var(--border-light); +} +.bs-cesu-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 12px; +} +.bs-cesu-list { + display: flex; + flex-direction: column; + gap: 10px; +} +.bs-cesu-row { + display: flex; + gap: 10px; + align-items: center; +} +.bs-cesu-row input[type="month"] { + width: 140px; + flex-shrink: 0; +} +.bs-cesu-row input[type="number"] { + width: 100px; + flex-shrink: 0; +} diff --git a/modules/budget/includes/DynamicBudgetCalculator.php b/modules/budget/includes/DynamicBudgetCalculator.php index 663143f..23fca7e 100644 --- a/modules/budget/includes/DynamicBudgetCalculator.php +++ b/modules/budget/includes/DynamicBudgetCalculator.php @@ -32,6 +32,10 @@ class DynamicBudgetCalculator { return isset($this->settings[$key]) ? (float)$this->settings[$key] : (float)$default; } + private function getSettingString(string $key, string $default = ''): string { + return isset($this->settings[$key]) ? (string)$this->settings[$key] : $default; + } + private function loadPeople(): void { // 1. Chargement des enfants sans doublons $stmt = $this->pdo->query("SELECT id, name, care_modes FROM pf_people WHERE role IN ('enfant', 'child') AND is_active = 1"); @@ -85,10 +89,11 @@ class DynamicBudgetCalculator { $zone = $this->foyerSettings['zone_scolaire'] ?? 'C'; try { - // 🔥 FIX : On récupère les DEUX années scolaires qui chevauchent l'année calendaire (ex: 2025-2026 ET 2026-2027) + // 🔥 FIX STATE OF THE ART : On cible uniquement la population "Élèves" $prevYear = $this->year - 1; $nextYear = $this->year + 1; - $where = "(annee_scolaire='{$prevYear}-{$this->year}' OR annee_scolaire='{$this->year}-{$nextYear}') AND zones LIKE '%Zone {$zone}%'"; + $where = "(annee_scolaire='{$prevYear}-{$this->year}' OR annee_scolaire='{$this->year}-{$nextYear}') AND zones LIKE '%Zone {$zone}%' AND population = 'Élèves'"; + $url = "https://data.education.gouv.fr/api/explore/v2.1/catalog/datasets/fr-en-calendrier-scolaire/records?where=" . urlencode($where) . "&limit=100"; $jsonVacances = @file_get_contents($url); @@ -127,7 +132,16 @@ class DynamicBudgetCalculator { $nannyFixed = $this->getSetting('budget_nanny_fixed', 700); $nannyDaily = $this->getSetting('budget_nanny_daily', 4); $nannyAid = $this->getSetting('budget_nanny_aid', 120); - $cesuAvg = $this->getSetting('budget_nanny_cesu_avg', 170); + + $cesuAvg = $this->getSetting('budget_nanny_cesu_avg', 170); + $overridesJson = $this->getSettingString('budget_cesu_overrides', '{}'); + $cesuOverrides = json_decode($overridesJson, true) ?: []; + + $monthKey = sprintf("%04d-%02d", $this->year, $this->month); + $isCesuOverride = isset($cesuOverrides[$monthKey]); + $cesuApplied = $isCesuOverride ? (float)$cesuOverrides[$monthKey] : $cesuAvg; + $cesuLabelText = $isCesuOverride ? tr('bud_audit_cesu_adj') : tr('bud_audit_cesu_avg'); + // ------------------------------------ $schoolMeal = $this->getSetting('budget_school_meal', 5.62); $schoolAftercare = $this->getSetting('budget_school_aftercare', 1.97); @@ -168,6 +182,8 @@ class DynamicBudgetCalculator { if (in_array($dateStr, $offDays['feries'])) continue; $isVacances = in_array($dateStr, $offDays['vacances']); + + $events = $this->calendarEvents[$dateStr] ?? []; $nannyOffToday = false; @@ -216,13 +232,15 @@ class DynamicBudgetCalculator { } $totalNannyFees = $totalNannyDays * $nannyDaily; - $nannyGlobalCost = $nannyFixed + $totalNannyFees - $nannyAid - $cesuAvg; + // On soustrait $cesuApplied au lieu de $cesuAvg + $nannyGlobalCost = $nannyFixed + $totalNannyFees - $nannyAid - $cesuApplied; // 3. Rédaction du Bilan if ($hasNanny) { $totalCost += max(0, $nannyGlobalCost); + // On passe $cesuLabelText au sprintf $details .= sprintf(tr('bud_audit_nanny_full') . "\n", - $this->helperName, $nannyFixed, $totalNannyDays, $nannyDaily, $totalNannyFees, $nannyAid, $cesuAvg, max(0, $nannyGlobalCost)); + $this->helperName, $nannyFixed, $totalNannyDays, $nannyDaily, $totalNannyFees, $nannyAid, $cesuLabelText, $cesuApplied, max(0, $nannyGlobalCost)); if ($nannyOffDays > 0) { $details .= sprintf(tr('bud_audit_nanny_abs') . "\n", $this->helperName, $nannyOffDays); diff --git a/modules/budget/includes/api/settings.php b/modules/budget/includes/api/settings.php index bb58567..38761cf 100644 --- a/modules/budget/includes/api/settings.php +++ b/modules/budget/includes/api/settings.php @@ -205,7 +205,8 @@ try { if ($action === 'save_dynamic_estimates') { $keys = [ 'budget_nanny_fixed', 'budget_nanny_daily', 'budget_nanny_aid', 'budget_nanny_cesu_avg', - 'budget_school_meal', 'budget_school_aftercare', 'budget_school_fullday' + 'budget_school_meal', 'budget_school_aftercare', 'budget_school_fullday', + 'budget_cesu_overrides' ]; $pdo->beginTransaction(); diff --git a/modules/budget/views/settings_modal.php b/modules/budget/views/settings_modal.php index dcf6628..c7974e8 100644 --- a/modules/budget/views/settings_modal.php +++ b/modules/budget/views/settings_modal.php @@ -224,10 +224,11 @@ if (!defined('CURRENCY')) {
Configurez ici les tarifs pour le calcul dynamique des frais de garde et de cantine.
+= tr('bud_settings_dyn_desc') ?>