_user["rowid"]); // SÉCURITÉ : Validation de l'ID utilisateur $fkRole = intval($Session->_user["fk_role"]); // SÉCURITÉ : Validation du rôle // SÉCURITÉ : Construction de la clause WHERE avec des paramètres sécurisés $whereParams = []; switch ($fkRole) { case 1: // DIR-CO $where = 'd.fk_user = :fkUser OR d.fk_statut_devis >= 2'; $whereParams[':fkUser'] = $fkUser; break; case 2: // DV : on récupère tous les RR de son périmètre try { $db = Database::getInstance(); $sql = 'SELECT rowid FROM users WHERE fk_parent = :fkParent'; $stmt = $db->prepare($sql); $stmt->execute([':fkParent' => $fkUser]); $aRR = $stmt->fetchAll(PDO::FETCH_ASSOC); $rrIds = array_column($aRR, 'rowid'); if (!empty($rrIds)) { // Création de placeholders pour la requête IN $placeholders = []; foreach ($rrIds as $index => $id) { $placeholder = ':rr' . $index; $placeholders[] = $placeholder; $whereParams[$placeholder] = $id; } $where = 'd.fk_user = :fkUser OR (d.fk_statut_devis >= 3 AND d.fk_user IN (' . implode(',', $placeholders) . '))'; $whereParams[':fkUser'] = $fkUser; } else { $where = 'd.fk_user = :fkUser'; $whereParams[':fkUser'] = $fkUser; } } catch (Exception $e) { error_log("Erreur récupération RR : " . $e->getMessage()); $where = 'd.fk_user = :fkUser'; $whereParams[':fkUser'] = $fkUser; } break; default: // RR $where = 'd.fk_user = :fkUser'; $whereParams[':fkUser'] = $fkUser; break; } // SÉCURITÉ : Requête avec paramètres préparés try { $db = Database::getInstance(); $sql = 'SELECT d.rowid, d.dossier, d.date_demande, d.date_remise, d.num_opportunite, d.fk_client, d.montant_total_ht_remise, d.marge_totale, d.commentaire, d.chk_speciaux, c.libelle, c.ville, c.cp, d.fk_statut_devis, '; $sql .= 'd.lib_new_client, d.type_new_client, d.adresse1_new_client, d.adresse2_new_client, d.adresse3_new_client, d.cp_new_client, d.ville_new_client, d.comment_devis, d.comment_geste_comm, '; $sql .= 'd.contact_new_nom, d.contact_new_prenom, d.new_telephone, d.new_mobile, d.new_email, d.contact_new_fonction, LEFT(u.prenom,1) AS prenom, u.libelle as nom, '; $sql .= 'xs.libelle as lib_statut, d.chk_new_statut, m.libelle as lib_marche, d.chk_validat, d.fk_user_validat, d.date_validat '; $sql .= 'FROM devis d LEFT JOIN clients c ON c.rowid=d.fk_client LEFT JOIN x_statuts_devis xs ON xs.rowid=d.fk_statut_devis LEFT JOIN marches m ON m.rowid=d.fk_marche LEFT JOIN users u ON u.rowid=d.fk_user '; $sql .= 'WHERE ' . $where . ' ORDER BY d.dossier, d.date_remise DESC'; $pdo = $db->getPDO(); $stmt = $pdo->prepare($sql); $stmt->execute($whereParams); $aModel["devis"] = $stmt->fetchAll(PDO::FETCH_ASSOC); } catch (Exception $e) { error_log("Erreur récupération devis : " . $e->getMessage()); $aModel["devis"] = []; } //! on compte le nombre de devis par statut $aModel["nb_devis"] = array(); foreach ($aModel["devis"] as $devis) { if (!isset($aModel["nb_devis"][$devis["fk_statut_devis"]])) { $aModel["nb_devis"][$devis["fk_statut_devis"]] = 1; } else { $aModel["nb_devis"][$devis["fk_statut_devis"]]++; } } //! On récupère la liste des dossiers des devis // SÉCURITÉ : Requête avec paramètres préparés try { $sql = 'SELECT DISTINCT d.dossier FROM devis d WHERE ' . $where . ' ORDER BY d.dossier'; $stmt = $pdo->prepare($sql); $stmt->execute($whereParams); $aModel["dossiers"] = $stmt->fetchAll(PDO::FETCH_ASSOC); } catch (Exception $e) { error_log("Erreur récupération dossiers : " . $e->getMessage()); $aModel["dossiers"] = []; } //! Tous les produits du catalogue $sql = 'SELECT rowid, code, libelle, prix_vente, prix_achat_net FROM produits WHERE active=1;'; $aModel["produits"] = getinfos($sql, "gen"); //! toutes les familles de produits $sql = 'SELECT rowid, libelle, ordre FROM x_familles WHERE active=1 ORDER BY ordre;'; $aModel["familles"] = getinfos($sql, "gen"); $sql = 'SELECT m.* FROM marches m WHERE m.active=1 AND m.chk_cache_commerciaux=0 ORDER BY m.libelle;'; $aModel["marches"] = getinfos($sql, "gen"); //! les types de clients $sql = 'SELECT rowid, code, libelle FROM x_clients_types WHERE active=1 ORDER BY code;'; $aModel["types_clients"] = getinfos($sql, "gen"); //! les statuts de devis sans le 20 - Archivés $sql = 'SELECT rowid, libelle FROM x_statuts_devis WHERE active=1 AND rowid<20 ORDER BY rowid;'; $aModel["statuts_devis"] = getinfos($sql, "gen"); // On récupère le dernier numéro de devis mis à jour de la session if (isset($_SESSION["lastDevis"])) { $aModel["last_devis"] = $_SESSION["lastDevis"]; } else { $aModel["last_devis"] = 0; }