From 695234d1821d19ce44feb4b659868c2672ccaa75 Mon Sep 17 00:00:00 2001 From: "fefe.clochette" Date: Tue, 17 Feb 2026 20:58:20 +0100 Subject: [PATCH] update epargne auto --- modules/budget/includes/api/save-budget.php | 149 ++++++++++++++++++++ modules/budget/views/budget_prev.php | 121 +++++++++++++++- 2 files changed, 263 insertions(+), 7 deletions(-) diff --git a/modules/budget/includes/api/save-budget.php b/modules/budget/includes/api/save-budget.php index 01c679a..159a79c 100644 --- a/modules/budget/includes/api/save-budget.php +++ b/modules/budget/includes/api/save-budget.php @@ -81,4 +81,153 @@ if ($action === 'delete_category') { // Redirection vers la page précédente header("Location: " . $_SERVER['HTTP_REFERER']); exit; +} + +// 6. VALIDATION DES VIREMENTS (Complex Business Logic) +if ($action === 'validate_transfers') { + header('Content-Type: application/json'); + + $person = $_POST['person']; // Alex ou Laia + $monthDate = $_POST['month_date']; + + try { + $pdo->beginTransaction(); + + // 1. Récupérer tous les virements prévus pour ce mois/personne dans le BUDGET + // On joint avec les catégories pour avoir le nom et la cible + $stmt = $pdo->prepare(" + SELECT v.*, c.name as cat_name, c.target + FROM pf_alloc_values v + JOIN pf_alloc_categories c ON v.cat_id = c.id + WHERE v.month_date = ? + "); + $stmt->execute([$monthDate]); + $budgetLines = $stmt->fetchAll(PDO::FETCH_ASSOC); + + // On prépare les totaux à transférer par Cible + // Structure : ['Alex' => ['total'=>100, 'cats'=>['Noel'=>50, 'Eco'=>50]], 'Pol' => ...] + $transfersToDo = []; + + foreach ($budgetLines as $line) { + $amount = ($person === 'Alex') ? $line['amount_alex'] : $line['amount_laia']; + if ($amount <= 0) continue; // Rien à virer + + $target = trim($line['target']); + $catName = trim($line['cat_name']); + + // MAPPING DES PROPRIÉTAIRES CIBLES + $targetOwner = null; + if ($target === 'vers L.Perso') { + $targetOwner = $person; // Alex -> Alex, Laia -> Laia + } elseif ($target === 'vers L.Pol') { + $targetOwner = 'Pol'; + } elseif ($target === 'vers L.Pep') { + $targetOwner = 'Pep'; + } elseif ($target === 'vers commune') { + continue; // On ignore (Business Rule) + } + + if ($targetOwner) { + if (!isset($transfersToDo[$targetOwner])) { + $transfersToDo[$targetOwner] = ['total_add' => 0, 'cats' => []]; + } + $transfersToDo[$targetOwner]['total_add'] += $amount; + + if (!isset($transfersToDo[$targetOwner]['cats'][$catName])) { + $transfersToDo[$targetOwner]['cats'][$catName] = 0; + } + $transfersToDo[$targetOwner]['cats'][$catName] += $amount; + } + } + + // 2. Traiter chaque Propriétaire Cible (Alex, Laia, Pol, Pep) + foreach ($transfersToDo as $owner => $data) { + + // A. VÉRIFIER SI LE MOIS EXISTE EN EPARGNE + $stmtCheck = $pdo->prepare("SELECT COUNT(*) FROM pf_savings WHERE owner = ? AND month_date = ? AND category = 'TOTAL_BANQUE'"); + $stmtCheck->execute([$owner, $monthDate]); + $exists = $stmtCheck->fetchColumn() > 0; + + if (!$exists) { + // SCENARIO : LE MOIS N'EXISTE PAS -> DUPLICATION DEPUIS M-1 + $prevDate = date('Y-m-d', strtotime($monthDate . ' -1 month')); + + // Récup M-1 + $stmtPrev = $pdo->prepare("SELECT category, amount FROM pf_savings WHERE owner = ? AND month_date = ?"); + $stmtPrev->execute([$owner, $prevDate]); + $prevLines = $stmtPrev->fetchAll(PDO::FETCH_KEY_PAIR); // [Cat => Montant] + + if (empty($prevLines)) { + // Si M-1 n'existe pas non plus, on initialise à 0 (ou on lève une erreur selon préférence) + $prevLines = ['TOTAL_BANQUE' => 0]; + } + + // Insertion M (Copie de M-1) + $stmtInsert = $pdo->prepare("INSERT INTO pf_savings (month_date, owner, category, amount) VALUES (?, ?, ?, ?)"); + foreach ($prevLines as $cat => $amt) { + $stmtInsert->execute([$monthDate, $owner, $cat, $amt]); + } + } + + // B. MISE À JOUR DU TOTAL_BANQUE + // On ajoute le montant du virement au montant existant (qu'il vienne d'être créé ou non) + $stmtUpdTotal = $pdo->prepare("UPDATE pf_savings SET amount = amount + ? WHERE owner = ? AND month_date = ? AND category = 'TOTAL_BANQUE'"); + $stmtUpdTotal->execute([$data['total_add'], $owner, $monthDate]); + + // C. MISE À JOUR / CRÉATION DES CATÉGORIES + foreach ($data['cats'] as $catName => $catAmount) { + // On utilise ON DUPLICATE KEY UPDATE pour gérer "Créer ou Sommer" en une seule requête + // Note: category est-il unique par (month, owner)? Si ta table pf_savings n'a pas de clé unique là-dessus, il faut faire un SELECT avant. + // Supposons qu'il n'y a pas de contrainte UNIQUE stricte, faisons le check manuel PHP pour être sûr. + + $stmtCheckCat = $pdo->prepare("SELECT id FROM pf_savings WHERE owner = ? AND month_date = ? AND category = ?"); + $stmtCheckCat->execute([$owner, $monthDate, $catName]); + $catId = $stmtCheckCat->fetchColumn(); + + if ($catId) { + // Update : Sommer + $stmtUpdateCat = $pdo->prepare("UPDATE pf_savings SET amount = amount + ? WHERE id = ?"); + $stmtUpdateCat->execute([$catAmount, $catId]); + } else { + // Insert : Créer + $stmtInsertCat = $pdo->prepare("INSERT INTO pf_savings (month_date, owner, category, amount) VALUES (?, ?, ?, ?)"); + $stmtInsertCat->execute([$monthDate, $owner, $catName, $catAmount]); + } + } + } + + // 3. ENREGISTRER LA VALIDATION (Mise à jour table existante) + + // a. Trouver l'ID de la catégorie système + $stmtSys = $pdo->prepare("SELECT id FROM pf_alloc_categories WHERE name = 'SYSTEM_VALIDATION' LIMIT 1"); + $stmtSys->execute(); + $sysCatId = $stmtSys->fetchColumn(); + + if ($sysCatId) { + // b. Mettre à jour la valeur (1 = Validé) + // On utilise une astuce SQL : on met à jour uniquement la colonne de la personne concernée + // Si la ligne n'existe pas, on l'insère avec 1 pour la personne et 0 pour l'autre. + + if ($person === 'Alex') { + $sql = "INSERT INTO pf_alloc_values (month_date, cat_id, amount_alex, amount_laia) + VALUES (?, ?, 1, 0) + ON DUPLICATE KEY UPDATE amount_alex = 1"; + } else { + $sql = "INSERT INTO pf_alloc_values (month_date, cat_id, amount_alex, amount_laia) + VALUES (?, ?, 0, 1) + ON DUPLICATE KEY UPDATE amount_laia = 1"; + } + + $stmtVal = $pdo->prepare($sql); + $stmtVal->execute([$monthDate, $sysCatId]); + } + + $pdo->commit(); + echo json_encode(['success' => true]); + + } catch (Exception $e) { + $pdo->rollBack(); + echo json_encode(['success' => false, 'error' => $e->getMessage()]); + } + exit; } \ No newline at end of file diff --git a/modules/budget/views/budget_prev.php b/modules/budget/views/budget_prev.php index a6fd62f..4a50521 100644 --- a/modules/budget/views/budget_prev.php +++ b/modules/budget/views/budget_prev.php @@ -44,6 +44,30 @@ $allocs = []; while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { $allocs[$row['month_date']][$row['cat_id']] = $row; } + +// 5. Récupération de l'ID de la catégorie système +// On cherche l'ID de la catégorie 'SYSTEM_VALIDATION' +$sysCatId = null; +foreach ($cats as $key => $c) { + if ($c['name'] === 'SYSTEM_VALIDATION') { + $sysCatId = $c['id']; + // IMPORTANT : On retire cette catégorie de la liste affichable ($cats) + // pour qu'elle n'apparaisse pas dans le tableau HTML ! + unset($cats[$key]); + break; + } +} + +// 6. Lecture des statuts de validation (1 = Validé, 0 = Non) +$focusDate = $months[0]; +$isValidatedAlex = false; +$isValidatedLaia = false; + +if ($sysCatId && isset($allocs[$focusDate][$sysCatId])) { + $row = $allocs[$focusDate][$sysCatId]; + $isValidatedAlex = ($row['amount_alex'] == 1); + $isValidatedLaia = ($row['amount_laia'] == 1); +} ?>
@@ -221,18 +245,46 @@ while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
0, 'Laia' => 0]; + + foreach ($cats as $cat) { + $t = trim($cat['target']); + if (empty($t)) continue; + + $val = $allocs[$focusMonth][$cat['id']] ?? ['amount_alex'=>0, 'amount_laia'=>0]; + + if (!isset($summaryData[$t])) { + $summaryData[$t] = ['Alex' => 0, 'Laia' => 0]; + } + + $summaryData[$t]['Alex'] += $val['amount_alex']; + $summaryData[$t]['Laia'] += $val['amount_laia']; + } + + // Récupération des totaux pour le footer + $grandTotalAlex = 0; + $grandTotalLaia = 0; + $grandTotalGlobal = 0; ?>
@@ -245,8 +297,37 @@ while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { Destination - Alex - Laia + + +
+ ALEX + +
+ ✓ FAIT +
+ + + +
+ + + +
+ LAIA + +
+ ✓ FAIT +
+ + + +
+ + Global @@ -618,4 +699,30 @@ document.addEventListener('DOMContentLoaded', function() { }); } }); + +function validateTransfers(person, month) { + if (!confirm(`Confirmer que ${person} a bien effectué tous ses virements pour ${month} ?\n\nCela mettra à jour l'Épargne automatiquement.`)) return; + + const formData = new FormData(); + formData.append('action', 'validate_transfers'); + formData.append('person', person); + formData.append('month_date', month); + + // On récupère aussi les données calculées du tableau pour les envoyer au backend + // Mais pour plus de sécurité, le backend recalculera tout lui-même. + + fetch('/modules/budget/includes/api/save-budget.php', { + method: 'POST', + body: formData + }) + .then(r => r.json()) + .then(data => { + if(data.success) { + window.location.reload(); + } else { + alert("Erreur: " + data.error); + } + }) + .catch(e => alert("Erreur technique")); +} \ No newline at end of file