app/Controllers/AdminBudgetController.php:32:        $this->requireAdminOrAbort();
app/Controllers/AdminBudgetController.php:34:        $this->db     = Database::getSyndicosConnection();
app/Controllers/AdminBudgetController.php:35:        $this->db->exec('SET NAMES utf8mb4');
app/Controllers/AdminBudgetController.php:45:            $synId = (int)\Database::q($this->db, "SELECT id FROM users WHERE LOWER(mail) = ? AND admin = 1 LIMIT 1", [strtolower($email)])
app/Controllers/AdminBudgetController.php:58:        $this->synUser = \Database::q($this->db, "SELECT * FROM users WHERE id = ?", [$synId])
app/Controllers/AdminBudgetController.php:60:        $this->coproId = (int)$this->synUser['copro'];
app/Controllers/AdminBudgetController.php:64:        $this->csrf = $_SESSION['csrf_token'];
app/Controllers/AdminBudgetController.php:74:    $st = $this->db->prepare(
app/Controllers/AdminBudgetController.php:78:    $st->execute([$this->coproId]);
app/Controllers/AdminBudgetController.php:85:    $syn = $this->db->prepare(
app/Controllers/AdminBudgetController.php:89:    $syn->execute([$this->coproId]);
app/Controllers/AdminBudgetController.php:127:    $batStmt = $this->db->prepare(
app/Controllers/AdminBudgetController.php:132:    $batStmt->execute([$this->coproId]);
app/Controllers/AdminBudgetController.php:149:    $appelsData = $this->loadAppelsData();
app/Controllers/AdminBudgetController.php:153:    $csrf       = $this->csrf;                   // utilisé dans les modales
app/Controllers/AdminBudgetController.php:164:    $db = $this->db;
app/Controllers/AdminBudgetController.php:165:    $coproId = $this->coproId;
app/Controllers/AdminBudgetController.php:241:    $exercice = $this->fetchExerciceOrDie($exoId);
app/Controllers/AdminBudgetController.php:244:    $types = $this->db->query('SELECT id,type FROM types')
app/Controllers/AdminBudgetController.php:248:    $cles = $this->db->prepare(
app/Controllers/AdminBudgetController.php:252:    $cles->execute([$this->coproId]);
app/Controllers/AdminBudgetController.php:256:    $rq = $this->db->prepare(
app/Controllers/AdminBudgetController.php:260:    $rq->execute([$exoId, $this->coproId]);
app/Controllers/AdminBudgetController.php:284:    $rq = $this->db->prepare(
app/Controllers/AdminBudgetController.php:298:    $rq->execute([$exoId, $this->coproId]);
app/Controllers/AdminBudgetController.php:308:    $debugEau = $this->db->prepare(
app/Controllers/AdminBudgetController.php:317:    $debugEau->execute([$exoId, $this->coproId]);
app/Controllers/AdminBudgetController.php:319:    error_log("=== DEBUG BUDGET EAU (exo=$exoId, copro={$this->coproId}) ===");
app/Controllers/AdminBudgetController.php:327:    $taux_fond_travaux = $this->db->prepare(
app/Controllers/AdminBudgetController.php:330:    $taux_fond_travaux->execute([$exoId, $this->coproId]);
app/Controllers/AdminBudgetController.php:334:    $lots      = $this->fetchLotsByEau(1);   // eau = 1
app/Controllers/AdminBudgetController.php:335:    $lotsElec  = $this->fetchLotsElec();
app/Controllers/AdminBudgetController.php:339:    $this->fetchRepart('repartition_eau' , $exoId);
app/Controllers/AdminBudgetController.php:341:    $this->fetchRepart('repartition_elec', $exoId);
app/Controllers/AdminBudgetController.php:349:$coproId     = $this->coproId;
app/Controllers/AdminBudgetController.php:353:    $stmt = $this->db->prepare(
app/Controllers/AdminBudgetController.php:360:    $stmt->execute([$exoId, $this->coproId]);
app/Controllers/AdminBudgetController.php:379:        if (!$id) $this->json(['success'=>false,'message'=>'ID manquant']);
app/Controllers/AdminBudgetController.php:382:        $checkStmt = $this->db->prepare('SELECT cloture FROM exercices WHERE id = ? AND id_copro = ?');
app/Controllers/AdminBudgetController.php:383:        $checkStmt->execute([$id, $this->coproId]);
app/Controllers/AdminBudgetController.php:387:            $this->json(['success'=>false,'message'=>'Exercice non trouvé']);
app/Controllers/AdminBudgetController.php:392:            $this->json(['success'=>false,'message'=>'Impossible de définir un exercice clôturé comme exercice en cours']);
app/Controllers/AdminBudgetController.php:396:        $this->db->prepare('UPDATE exercices SET encours=0 WHERE id_copro=?')
app/Controllers/AdminBudgetController.php:397:                 ->execute([$this->coproId]);
app/Controllers/AdminBudgetController.php:398:        $this->db->prepare(
app/Controllers/AdminBudgetController.php:400:                 ->execute([$id,$this->coproId]);
app/Controllers/AdminBudgetController.php:402:        $this->json(['success'=>true]);
app/Controllers/AdminBudgetController.php:410:            $this->json(['success'=>false,'message'=>'Dates manquantes']);
app/Controllers/AdminBudgetController.php:417:        $this->db->prepare(
app/Controllers/AdminBudgetController.php:422:                 $this->coproId,$d['debut'],$d['fin'],$nom,$code
app/Controllers/AdminBudgetController.php:425:        $this->json(['success'=>true]);
app/Controllers/AdminBudgetController.php:432:            $this->json(['success'=>false,'message'=>'ID manquant']);
app/Controllers/AdminBudgetController.php:437:        $ex = \Database::q($this->db,
app/Controllers/AdminBudgetController.php:439:            [$id, $this->coproId])->fetch(PDO::FETCH_ASSOC);
app/Controllers/AdminBudgetController.php:442:            $this->json(['success'=>false,'message'=>'Exercice non trouvé']);
app/Controllers/AdminBudgetController.php:447:            $this->json(['success'=>false,'message'=>'Impossible de supprimer l\'exercice en cours. Définissez d\'abord un autre exercice comme exercice en cours.']);
app/Controllers/AdminBudgetController.php:466:                $count = (int)\Database::q($this->db,
app/Controllers/AdminBudgetController.php:470:                    $this->json([
app/Controllers/AdminBudgetController.php:481:        $this->db->prepare('DELETE FROM exercices WHERE id=? AND id_copro=?')
app/Controllers/AdminBudgetController.php:482:                 ->execute([$id, $this->coproId]);
app/Controllers/AdminBudgetController.php:483:        $this->json(['success'=>true,'message'=>'Exercice « '.$ex['nom'].' » supprimé.']);
app/Controllers/AdminBudgetController.php:495:    $j = $this->jsonPayload();
app/Controllers/AdminBudgetController.php:496:    $this->checkCsrf($j['csrf_token'] ?? '');
app/Controllers/AdminBudgetController.php:497:    $exo = $this->fetchExerciceOrDie((int)$j['id_exercice']);
app/Controllers/AdminBudgetController.php:515:$this->db->prepare($sql)->execute([
app/Controllers/AdminBudgetController.php:516:    'copro'    => $this->coproId,
app/Controllers/AdminBudgetController.php:528:        $this->db->prepare(
app/Controllers/AdminBudgetController.php:534:                 $this->coproId,
app/Controllers/AdminBudgetController.php:540:    $this->json(['success' => true]);
app/Controllers/AdminBudgetController.php:543:    public function validateBudget()   { $this->toggleBudget(true);  }
app/Controllers/AdminBudgetController.php:544:    public function unvalidateBudget() { $this->toggleBudget(false); }
app/Controllers/AdminBudgetController.php:548:        $j   = $this->jsonPayload();
app/Controllers/AdminBudgetController.php:549:        $this->checkCsrf($j['csrf_token'] ?? '');
app/Controllers/AdminBudgetController.php:550:        $exo = $this->fetchExerciceOrDie((int)$j['id_exercice']);
app/Controllers/AdminBudgetController.php:552:        $this->db->prepare(
app/Controllers/AdminBudgetController.php:555:             ->execute([(int)$state,$exo['id'],$this->coproId]);
app/Controllers/AdminBudgetController.php:557:        $this->json(['success'=>true]);
app/Controllers/AdminBudgetController.php:566:        $j = $this->jsonPayload();
app/Controllers/AdminBudgetController.php:567:        $this->checkCsrf($j['csrf_token'] ?? '');
app/Controllers/AdminBudgetController.php:572:        $this->db->prepare(
app/Controllers/AdminBudgetController.php:580:                 $this->coproId,
app/Controllers/AdminBudgetController.php:584:        $this->json(['success'=>true]);
app/Controllers/AdminBudgetController.php:587:    public function validateRepartition()   { $this->toggleRep(true);  }
app/Controllers/AdminBudgetController.php:588:    public function unvalidateRepartition() { $this->toggleRep(false); }
app/Controllers/AdminBudgetController.php:592:        $j = $this->jsonPayload();
app/Controllers/AdminBudgetController.php:593:        $this->checkCsrf($j['csrf_token'] ?? '');
app/Controllers/AdminBudgetController.php:599:            $q = $this->db->prepare(
app/Controllers/AdminBudgetController.php:603:            $q->execute([(int)$j['id_exercice'],$this->coproId]);
app/Controllers/AdminBudgetController.php:605:                $this->json(['success'=>false,
app/Controllers/AdminBudgetController.php:610:        $this->db->prepare(
app/Controllers/AdminBudgetController.php:613:             ->execute([(int)$state,(int)$j['id_exercice'],$this->coproId]);
app/Controllers/AdminBudgetController.php:615:        $this->json(['success'=>true]);
app/Controllers/AdminBudgetController.php:624:        $q = $this->db->prepare(
app/Controllers/AdminBudgetController.php:629:        $q->execute([$eau,$this->coproId]);
app/Controllers/AdminBudgetController.php:635:        $q = $this->db->prepare(
app/Controllers/AdminBudgetController.php:640:        $q->execute([$this->coproId]);
app/Controllers/AdminBudgetController.php:646:        $q = $this->db->prepare(
app/Controllers/AdminBudgetController.php:650:        $q->execute([$exoId,$this->coproId]);
app/Controllers/AdminBudgetController.php:663:        $q = $this->db->prepare(
app/Controllers/AdminBudgetController.php:665:        $q->execute([$id,$this->coproId]);
app/Controllers/AdminBudgetController.php:667:        if (!$e) $this->abort(404,'Exercice introuvable');
app/Controllers/AdminBudgetController.php:677:        if (!hash_equals($this->csrf,$tok))
app/Controllers/AdminBudgetController.php:678:            $this->abort(403,'Token CSRF invalide');
app/Controllers/AdminBudgetController.php:699:            $this->db->beginTransaction();
app/Controllers/AdminBudgetController.php:703:        $ex = $this->db->prepare(
app/Controllers/AdminBudgetController.php:706:        $ex->execute([$this->coproId]);
app/Controllers/AdminBudgetController.php:709:            $this->json(['success'=>false,'message'=>'Aucun exercice en cours']);
app/Controllers/AdminBudgetController.php:715:            $this->db->prepare(
app/Controllers/AdminBudgetController.php:726:        $miss = $this->db->prepare(
app/Controllers/AdminBudgetController.php:732:        $miss->execute([$exerciceId, $this->coproId]);
app/Controllers/AdminBudgetController.php:735:            $this->db->rollBack();
app/Controllers/AdminBudgetController.php:736:            $this->json([
app/Controllers/AdminBudgetController.php:744:        $stmtTot = $this->db->prepare(
app/Controllers/AdminBudgetController.php:747:        $stmtTot->execute([$this->coproId]);
app/Controllers/AdminBudgetController.php:752:        $stmt = $this->db->prepare(
app/Controllers/AdminBudgetController.php:770:            $exDates = $this->db->prepare('SELECT debut, fin FROM exercices WHERE id = ?');
app/Controllers/AdminBudgetController.php:774:                $stmt = $this->db->prepare(
app/Controllers/AdminBudgetController.php:792:        $stmtType = $this->db->prepare(
app/Controllers/AdminBudgetController.php:799:        $stmtProvEau = $this->db->prepare(
app/Controllers/AdminBudgetController.php:804:        $stmtProvEau->execute([$exerciceId, $this->coproId, $eauType]);
app/Controllers/AdminBudgetController.php:808:        $stmtRealEau = $this->db->prepare(
app/Controllers/AdminBudgetController.php:815:        $stmtRealEau->execute([$exerciceId, $eauType, $this->coproId]);
app/Controllers/AdminBudgetController.php:819:        $repInitStmt = $this->db->prepare(
app/Controllers/AdminBudgetController.php:824:        $repInitStmt->execute([$exerciceId, $this->coproId]);
app/Controllers/AdminBudgetController.php:860:        $provStmt = $this->db->prepare(
app/Controllers/AdminBudgetController.php:864:        $provStmt->execute([$exerciceId, $this->coproId]);
app/Controllers/AdminBudgetController.php:867:        $realStmt = $this->db->prepare(
app/Controllers/AdminBudgetController.php:882:            'copro'   => $this->coproId,
app/Controllers/AdminBudgetController.php:894:        $lotStmt = $this->db->prepare('SELECT id,tantieme FROM lots WHERE copro=?');
app/Controllers/AdminBudgetController.php:895:        $lotStmt->execute([$this->coproId]);
app/Controllers/AdminBudgetController.php:907:        $typesMapStmt = $this->db->query('SELECT id, type FROM types');
app/Controllers/AdminBudgetController.php:940:        $stmtUser = $this->db->prepare(
app/Controllers/AdminBudgetController.php:943:        $stmtUser->execute([$this->coproId]);
app/Controllers/AdminBudgetController.php:947:        $ins = $this->db->prepare(
app/Controllers/AdminBudgetController.php:977:                    $this->coproId,
app/Controllers/AdminBudgetController.php:989:        $this->db->prepare(
app/Controllers/AdminBudgetController.php:998:        $next = $this->db->prepare(
app/Controllers/AdminBudgetController.php:1001:        $next->execute([$this->coproId]);
app/Controllers/AdminBudgetController.php:1008:            $accStmt = $this->db->prepare('SELECT id FROM bank_account WHERE id_copro = ?');
app/Controllers/AdminBudgetController.php:1009:            $accStmt->execute([$this->coproId]);
app/Controllers/AdminBudgetController.php:1013:                $bal = (float)\Database::q($this->db, "SELECT COALESCE(SUM(credit)-SUM(debit),0) 
app/Controllers/AdminBudgetController.php:1021:                $ins = $this->db->prepare(
app/Controllers/AdminBudgetController.php:1033:                    $this->coproId
app/Controllers/AdminBudgetController.php:1041:        $trav = $this->db->prepare("
app/Controllers/AdminBudgetController.php:1062:        $this->db->commit();
app/Controllers/AdminBudgetController.php:1089:            $this->json(['success'=>false,'message'=>'id_exercice manquant'], 400);
app/Controllers/AdminBudgetController.php:1093:        $ex = $this->fetchExerciceOrDie($exoId);
app/Controllers/AdminBudgetController.php:1096:        $st = $this->db->prepare(
app/Controllers/AdminBudgetController.php:1106:        $st->execute([$this->coproId, $exoId]);
app/Controllers/AdminBudgetController.php:1118:                $q = $this->db->prepare('SELECT u.id, u.nom, u.prenom
app/Controllers/AdminBudgetController.php:1121:                $q->execute([(int)$r['lot_id'], $this->coproId]);
app/Controllers/AdminBudgetController.php:1143:        $this->json([
app/Controllers/AdminBudgetController.php:1159:        if ($exoId <= 0) { $this->abort(400, 'id_exercice manquant'); }
app/Controllers/AdminBudgetController.php:1160:        $ex = $this->fetchExerciceOrDie($exoId);
app/Controllers/AdminBudgetController.php:1163:        $st = $this->db->prepare(
app/Controllers/AdminBudgetController.php:1173:        $st->execute([$this->coproId, $exoId]);
app/Controllers/AdminBudgetController.php:1184:                $q = $this->db->prepare('SELECT u.id, u.nom, u.prenom
app/Controllers/AdminBudgetController.php:1187:                $q->execute([(int)$r['lot_id'], $this->coproId]);
app/Controllers/AdminBudgetController.php:1208:        $j = $this->jsonPayload();
app/Controllers/AdminBudgetController.php:1209:        $this->checkCsrf($j['csrf_token'] ?? '');
app/Controllers/AdminBudgetController.php:1212:        if ($exoId <= 0) { $this->json(['success'=>false,'message'=>'id_exercice manquant'], 400); }
app/Controllers/AdminBudgetController.php:1213:        $ex = $this->fetchExerciceOrDie($exoId);
app/Controllers/AdminBudgetController.php:1215:        $this->db->beginTransaction();
app/Controllers/AdminBudgetController.php:1217:        $del = $this->db->prepare('DELETE FROM regul_exercices WHERE id_copro = ? AND id_exercice = ?');
app/Controllers/AdminBudgetController.php:1218:        $del->execute([$this->coproId, $exoId]);
app/Controllers/AdminBudgetController.php:1221:            $this->db->prepare('UPDATE exercices SET cloture=0, encours=1 WHERE id=? AND id_copro=?')
app/Controllers/AdminBudgetController.php:1222:                     ->execute([$exoId, $this->coproId]);
app/Controllers/AdminBudgetController.php:1225:        $this->db->commit();
app/Controllers/AdminBudgetController.php:1226:        $this->json(['success'=>true, 'deleted'=>true, 'reopened'=>$reopen]);
app/Controllers/AdminCoproprieteController.php:27:        $this->dbSyn  = Database::getSyndicosConnection();
app/Controllers/AdminCoproprieteController.php:28:        $this->dbSyn->exec('SET NAMES utf8mb4');
app/Controllers/AdminCoproprieteController.php:31:        if (!$authId) { $this->redirectAuth(); }
app/Controllers/AdminCoproprieteController.php:40:                $stmt = $this->dbSyn->prepare('SELECT id FROM users WHERE LOWER(mail)=? LIMIT 1');
app/Controllers/AdminCoproprieteController.php:50:        if (!$sid) { $this->redirectOnboarding(); }
app/Controllers/AdminCoproprieteController.php:52:        $u = \Database::q($this->dbSyn, "SELECT * FROM users WHERE id = ?", [$sid])->fetch(PDO::FETCH_ASSOC);
app/Controllers/AdminCoproprieteController.php:53:        if (!$u) { $this->redirectOnboarding(); }
app/Controllers/AdminCoproprieteController.php:55:        $this->userSyn = $u;
app/Controllers/AdminCoproprieteController.php:56:        $this->coproId = (int)$u['copro'];
app/Controllers/AdminCoproprieteController.php:57:        $_SESSION['copro'] = $this->coproId; // cohérence avec autres contrôleurs
app/Controllers/AdminCoproprieteController.php:88:        [$demandes_ouvertes,$demandes_fermees] = $this->loadDemandes();
app/Controllers/AdminCoproprieteController.php:89:        [$events,$types_agenda] = $this->loadAgenda();
app/Controllers/AdminCoproprieteController.php:90:        [$coproprietaires_with_balance,$coproprietaires_partis,$total_du_general] = $this->loadCoproprietaires();
app/Controllers/AdminCoproprieteController.php:91:        [$stmtLots,$etages,$sum_tantiemes,$total_lots,$lots_habitation_oui,$percentage_habitation_oui,$types_lots,$coproprietaires] = $this->loadLots();
app/Controllers/AdminCoproprieteController.php:113:        $stmt = $this->dbSyn->prepare($sql);
app/Controllers/AdminCoproprieteController.php:114:        $stmt->execute([$this->coproId]);
app/Controllers/AdminCoproprieteController.php:126:        $ev = $this->dbSyn->prepare('SELECT a.*, t.nom AS type_nom FROM agenda a JOIN type_agenda t ON t.id = a.type_agenda WHERE a.id_copro = ?');
app/Controllers/AdminCoproprieteController.php:127:        $ev->execute([$this->coproId]);
app/Controllers/AdminCoproprieteController.php:129:        $types = $this->dbSyn->query('SELECT * FROM type_agenda ORDER BY nom')->fetchAll(PDO::FETCH_ASSOC);
app/Controllers/AdminCoproprieteController.php:136:        $stmt = $this->dbSyn->prepare('SELECT id,prenom,nom,mail,societe,parti,admin FROM users WHERE copro=? ORDER BY prenom,nom');
app/Controllers/AdminCoproprieteController.php:137:        $stmt->execute([$this->coproId]);
app/Controllers/AdminCoproprieteController.php:160:            $c['montant_du'] = $this->calcSolde((int)$c['id']);
app/Controllers/AdminCoproprieteController.php:181:        $q = $this->dbSyn->prepare('SELECT debit, credit FROM bank WHERE coproprietaire = ?');
app/Controllers/AdminCoproprieteController.php:188:        $compte450 = $this->dbSyn->prepare('SELECT compte_450 FROM users WHERE id = ?');
app/Controllers/AdminCoproprieteController.php:193:            $u = $this->dbSyn->prepare('SELECT copro FROM users WHERE id = ?');
app/Controllers/AdminCoproprieteController.php:198:                $q = $this->dbSyn->prepare(
app/Controllers/AdminCoproprieteController.php:221:        $stmtLots = $this->dbSyn->prepare($sqlLots);
app/Controllers/AdminCoproprieteController.php:222:        $stmtLots->execute(['copro' => $this->coproId]);
app/Controllers/AdminCoproprieteController.php:224:        $stmtEtages = $this->dbSyn->prepare('SELECT DISTINCT etage FROM lots WHERE copro = :copro ORDER BY etage');
app/Controllers/AdminCoproprieteController.php:225:        $stmtEtages->execute(['copro' => $this->coproId]);
app/Controllers/AdminCoproprieteController.php:228:        $sum_tantiemes = (float)$this->scalar('SELECT COALESCE(SUM(tantieme),0) FROM lots WHERE copro = :copro', ['copro'=>$this->coproId]);
app/Controllers/AdminCoproprieteController.php:229:        $total_lots = (int)$this->scalar('SELECT COUNT(*) FROM lots WHERE copro = :copro', ['copro'=>$this->coproId]);
app/Controllers/AdminCoproprieteController.php:230:        $lots_habitation_oui = (int)$this->scalar('SELECT COUNT(*) FROM lots WHERE copro = :copro AND habitation = 1', ['copro'=>$this->coproId]);
app/Controllers/AdminCoproprieteController.php:234:        $types_lots = $this->dbSyn->query('SELECT id, type FROM types_lots')->fetchAll(PDO::FETCH_ASSOC);
app/Controllers/AdminCoproprieteController.php:237:        $stmtCopros = $this->dbSyn->prepare('SELECT id, CONCAT(prenom," ",nom) AS nom FROM users WHERE copro = :copro ORDER BY nom');
app/Controllers/AdminCoproprieteController.php:238:        $stmtCopros->execute(['copro' => $this->coproId]);
app/Controllers/AdminCoproprieteController.php:246:        $q = $this->dbSyn->prepare($sql); $q->execute($p); return $q->fetchColumn();
app/Controllers/AdminCoproprieteController.php:256:        $stmt = $this->dbSyn->prepare('SELECT nom FROM syndics WHERE id_copro = ? LIMIT 1');
app/Controllers/AdminCoproprieteController.php:257:        $stmt->execute([$this->coproId]);
