<?php
//! Page des requêtes AJAX de la page devis

global $Session;
global $Conf;
global $Route;

$fk_user = $Session->_user["rowid"];
$fk_role = $Session->_user["fk_role"];

switch ($Route->_action) {
  case "duplic_devis":
    // duplication d'un devis
    if ($_POST) {
      $rowid = nettoie_input($_POST["rid"]);

      //! 1. Recherche du devis d'origine par son rowid
      $rowidSafe = intval($rowid);
      $sql = 'SELECT rowid FROM devis WHERE rowid = ' . $rowidSafe . ';';
      $leDevis = getinfos($sql, 'gen');

      //! 2. S'il existe on crée un nouveau devis et on récupère son id
      if (count($leDevis) == 1) {
        $sql = 'INSERT INTO devis (fk_user, fk_client, fk_marche, dossier, chk_devis_photos, chk_speciaux, montant_total_ht, montant_total_ht_remise, marge_totale, seuil_marge_rr, seuil_marge_dv, ';
        $sql .= 'lib_new_client, type_new_client, adresse1_new_client, adresse2_new_client, adresse3_new_client, cp_new_client, ville_new_client, ';
        $sql .= 'contact_new_nom, contact_new_prenom, contact_new_fonction, new_telephone, new_mobile, new_email, date_creat, fk_user_creat) ';
        $sql .= 'SELECT d.fk_user, d.fk_client, d.fk_marche, d.dossier, d.chk_devis_photos, d.chk_speciaux, d.montant_total_ht, d.montant_total_ht_remise, d.marge_totale, d.seuil_marge_rr, d.seuil_marge_dv, ';
        $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, ';
        $sql .= 'd.contact_new_nom, d.contact_new_prenom, d.contact_new_fonction, d.new_telephone, d.new_mobile, d.new_email, "' . date("Y-m-d H:i:s") . '" as date_creat, d.fk_user_creat ';
        $sql .= 'FROM devis d WHERE d.rowid = ' . $rowidSafe . ';';
        eLog($sql);
        $newRowid = qSQL($sql, 'gen', true);

        if ($newRowid > 0) {
          //! 3. Si son nouvel id est bien récupéré, on duplique les lignes produits
          $sql = 'SELECT * FROM devis_produits WHERE fk_devis = ' . $rowidSafe . ';';
          $aProduits = getinfos($sql, 'gen');

          eLog(count($aProduits) . " lignes produits trouvées");
          foreach ($aProduits as $aProd) {
            $sql = 'INSERT INTO devis_produits SET fk_devis = ' . $newRowid . ', fk_produit = ' . $aProd["fk_produit"] . ', code="' . $aProd["code"] . '", libelle="' . $aProd["libelle"] . '", ';
            $sql .= 'qte = ' . $aProd["qte"] . ', totalht = ' . $aProd["totalht"] . ', remise = ' . $aProd["remise"] . ', marge = ' . $aProd["marge"] . ', ';
            $sql .= 'prix_achat_net = ' . $aProd["prix_achat_net"] . ', prix_vente = ' . $aProd["prix_vente"] . ', pu_vente_remise = ' . $aProd["pu_vente_remise"] . ', ';
            $sql .= 'prc_discount_1 = ' . $aProd["prc_discount_1"] . ', quantite_1 = ' . $aProd["quantite_1"] . ', prc_discount_2 = ' . $aProd["prc_discount_2"] . ', ';
            $sql .= 'quantite_2 = ' . $aProd["quantite_2"] . ', prc_discount_3 = ' . $aProd["prc_discount_3"] . ', quantite_3 = ' . $aProd["quantite_3"] . ', ';
            $sql .= 'prc_discount_4 = ' . $aProd["prc_discount_4"] . ', quantite_4 = ' . $aProd["quantite_4"] . ', prc_discount_5 = ' . $aProd["prc_discount_5"] . ', ';
            $sql .= 'quantite_5 = ' . $aProd["quantite_5"] . ', prc_discount_6 = ' . $aProd["prc_discount_6"] . ', quantite_6 = ' . $aProd["quantite_6"] . ', ';
            $sql .= 'commentaire = "' . $aProd["commentaire"] . '", chk_variante = ' . $aProd["chk_variante"] . ';';
            eLog($sql);
            qSQL($sql, "gen");
          }

          eLog("Duplication de ses " . count($aProduits) . " lignes produits");

          //! 4. On met à jour la date_demande, date_remise, num_opportunite et fk_statut_devis du nouveau devis
          $newRowidSafe = intval($newRowid);
          $sql = 'UPDATE devis SET date_demande = "' . date("Y-m-d H:i:s") . '", date_remise = NULL, num_opportunite = "", fk_statut_devis = 1 WHERE rowid = ' . $newRowidSafe . ';';
          eLog($sql);
          qSQL($sql, "gen");

          //! 5. On inscrit la duplication dans le journal
          $fkUserSafe = intval($fk_user);
          $sql = 'INSERT INTO devis_histo SET fk_user = ' . $fkUserSafe . ', fk_devis = ' . $newRowidSafe . ', commentaire="Création du devis par duplication (' . $rowidSafe . ')", date_histo = "' . date("Y-m-d H:i:s") . '", fk_statut_devis=1;';
          eLog($sql);
          qSQL($sql, "gen");

          // on met à jour la session avec le rowid de ce nouveau devis dupliqué
          $_SESSION["lastDevis"] = $newRowid;

          eLog("Mise à jour des infos du nouveau devis");
        }
      }
    }
    break;

  case "reactiver_devis":
    // Réactivation d'un devis archivé
    if ($_POST) {
      $rowid = nettoie_input($_POST["rid"]);
      $rowidSafe = intval($rowid);
      
      // Vérifier que le devis existe et est bien archivé (statut 20)
      $sql = 'SELECT rowid, fk_statut_devis FROM devis WHERE rowid = ' . $rowidSafe . ' AND fk_statut_devis = 20;';
      $leDevis = getinfos($sql, 'gen');
      
      if (count($leDevis) == 1) {
        // Mettre à jour le statut du devis de 20 (Archivé) à 1 (En cours)
        $sql = 'UPDATE devis SET fk_statut_devis = 1, date_modif = "' . date("Y-m-d H:i:s") . '", fk_user_modif = ' . intval($fk_user) . ' WHERE rowid = ' . $rowidSafe . ';';
        qSQL($sql, "gen");
        
        // Ajouter une entrée dans l'historique
        $sql = 'INSERT INTO devis_histo SET fk_user = ' . intval($fk_user) . ', fk_devis = ' . $rowidSafe . ', commentaire = "Réactivation du devis archivé", date_histo = "' . date("Y-m-d H:i:s") . '", fk_statut_devis = 1;';
        qSQL($sql, "gen");
        
        // Mettre à jour la session avec ce devis réactivé
        $_SESSION["lastDevis"] = $rowidSafe;
        
        eLog("Réactivation du devis archivé #" . $rowidSafe);
        
        echo json_encode(array("success" => true, "message" => "Devis réactivé avec succès"));
      } else {
        echo json_encode(array("success" => false, "message" => "Devis introuvable ou non archivé"));
      }
    }
    break;

  case "load_all_devis":
    $fkUserSession = intval($Session->_user["rowid"]);
    $sql = 'SELECT d.rowid, d.date_demande, d.fk_client, d.montant_total_ht_remise, c.libelle FROM devis d LEFT JOIN clients c ON c.rowid=d.fk_client where d.fk_user=' . $fkUserSession . ' ORDER BY d.date_demande DESC;';
    $upls = array();
    $upls = getinfos($sql, "gen");
    echo json_encode($upls);
    break;

  case "load_devis":
    //! On récupère les infos du devis (en-tête)
    $data = json_decode(file_get_contents("php://input"));
    if (isset($data->cid)) {
      $cid = nettoie_input($data->cid);

      //! si ce n'est pas le RR ou un super-admin, on remet à zéro le chk_maj pour ne plus avoir l'info de mise à jour
      $cidSafe = intval($cid);
      if ($Session->_user["fk_role"] != 3 && $Session->_user["fk_role"] != 90) {
        $sql = 'UPDATE devis SET chk_maj = 0 WHERE rowid = ' . $cidSafe . ';';
        qSQL($sql, "gen");
      }
      $sql = 'SELECT d.rowid, d.fk_user, d.fk_client, d.fk_contact, d.fk_marche, m.libelle AS lib_marche, d.fk_statut_devis, d.dossier, d.num_opportunite, d.montant_total_ht, ';
      $sql .= 'd.date_demande, d.date_remise, d.montant_total_ht_remise, d.marge_totale, d.commentaire, d.comment_devis, d.chk_clients_secteur, d.chk_speciaux, ';
      $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,';
      $sql .= 'd.contact_new_nom, d.contact_new_prenom, d.contact_new_fonction, d.new_telephone, d.new_mobile, d.new_email, ';
      $sql .= 'd.comment_geste_comm, d.comment_validat, d.chk_validat, d.fk_user_validat, d.date_validat, ';
      $sql .= 'xs.libelle as lib_statut_devis, c.code, c.libelle, c.adresse1, c.adresse2, c.adresse3, c.cp, c.ville, c.type_client, ';
      $sql .= 'cc.rowid as contact_rowid, cc.nom as contact_nom, cc.prenom as contact_prenom, cc.fonction as contact_fonction, cc.telephone, cc.mobile, cc.email, d.chk_devis_photos ';
      $sql .= 'FROM devis d LEFT JOIN clients c ON d.fk_client = c.rowid ';
      $sql .= 'LEFT JOIN clients_contacts cc ON d.fk_contact = cc.rowid ';
      $sql .= 'LEFT JOIN x_statuts_devis xs ON d.fk_statut_devis = xs.rowid ';
      $sql .= 'LEFT JOIN marches m ON d.fk_marche = m.rowid ';
      $sql .= 'WHERE d.rowid = ' . $cidSafe . ';';
      echo getinfos($sql, "gen", "json");
    } else {
      $ret = array('ret' => "ko", 'msg' => 'Erreur lors du chargement du devis (en-tête)');
      echo json_encode($ret);
    }
    break;

  case "load_devis_produits":
    // On récupère les infos des produits enregistrés pour ce devis
    // ainsi que les seuils de marge RR et DV enregistrés dans la table produits_familles
    $data = json_decode(file_get_contents("php://input"));
    if (isset($data->cid)) {
      $cid = nettoie_input($data->cid);
      $cidSafe = intval($cid);
      $sql = 'SELECT dp.*, pf.marge_rr, pf.marge_dv FROM devis_produits dp LEFT JOIN produits p ON dp.fk_produit=p.rowid LEFT JOIN produits_familles pf ON p.groupe=pf.groupe WHERE dp.fk_devis = ' . $cidSafe . ' ORDER BY dp.ordre;';
      echo getinfos($sql, "gen", "json");
    } else {
      $ret = array('ret' => "ko", 'msg' => 'Erreur lors du chargement des produits du devis');
      echo json_encode($ret);
    }
    break;

  case "duplicate_ligne_produit":
    $data = json_decode(file_get_contents("php://input"));
    if (isset($data->rowid_ligne)) {
      $rowidLigneSafe = intval(nettoie_input($data->rowid_ligne));

      $sql = 'SELECT * FROM devis_produits WHERE rowid = ' . $rowidLigneSafe . ';';
      $ligne = getinfos($sql, 'gen');

      if (count($ligne) > 0) {
        $l = $ligne[0];
        $fk_devis = $l['fk_devis'];

        // Récupérer toutes les lignes du devis pour recalculer les ordres
        $sql = 'SELECT rowid, ordre FROM devis_produits WHERE fk_devis = ' . $fk_devis . ' ORDER BY rowid;';
        $lignes_devis = getinfos($sql, 'gen');

        // Recalculer tous les ordres si nécessaire (au cas où il y a des doublons à 0)
        $ordre_actuel = 0;
        $position_source = -1;
        foreach ($lignes_devis as $idx => $ligne_devis) {
          if ($ligne_devis['rowid'] == $rowidLigneSafe) {
            $position_source = $ordre_actuel;
          }
          if ($ligne_devis['ordre'] != $ordre_actuel) {
            $sql = 'UPDATE devis_produits SET ordre = ' . $ordre_actuel . ' WHERE rowid = ' . $ligne_devis['rowid'] . ';';
            qSQL($sql, 'gen');
          }
          $ordre_actuel++;
        }

        // Le nouvel ordre sera juste après la ligne source
        $nouvel_ordre = $position_source + 1;

        // Décaler toutes les lignes après la position d'insertion
        $sql = 'UPDATE devis_produits SET ordre = ordre + 1 WHERE fk_devis = ' . $fk_devis . ' AND ordre >= ' . $nouvel_ordre . ';';
        qSQL($sql, 'gen');

        $gratuite = false;
        if (isset($data->gratuite) && $data->gratuite === true) {
          $gratuite = true;
        }

        $sql = 'INSERT INTO devis_produits SET ';
        $sql .= 'fk_devis = ' . $l['fk_devis'] . ', ';
        $sql .= 'fk_produit = ' . $l['fk_produit'] . ', ';
        $sql .= 'ordre = ' . $nouvel_ordre . ', ';
        $sql .= 'code = "' . $l['code'] . '", ';
        $sql .= 'libelle = "' . $l['libelle'] . '", ';
        $sql .= 'qte = ' . $l['qte'] . ', ';

        if ($gratuite) {
          $sql .= 'prix_vente = 0, ';
          $sql .= 'pu_vente_remise = 0, ';
          $sql .= 'totalht = 0, ';
          $sql .= 'marge = ' . (-floatval($l['prix_achat_net']) * intval($l['qte'])) . ', ';
          $sql .= 'remise = 100, ';
        } else {
          $sql .= 'totalht = ' . $l['totalht'] . ', ';
          $sql .= 'remise = ' . $l['remise'] . ', ';
          $sql .= 'marge = ' . $l['marge'] . ', ';
          $sql .= 'prix_vente = ' . $l['prix_vente'] . ', ';
          $sql .= 'pu_vente_remise = ' . $l['pu_vente_remise'] . ', ';
        }

        $sql .= 'prix_achat_net = ' . $l['prix_achat_net'] . ', ';
        $sql .= 'prc_discount_1 = ' . $l['prc_discount_1'] . ', ';
        $sql .= 'quantite_1 = ' . $l['quantite_1'] . ', ';
        $sql .= 'prc_discount_2 = ' . $l['prc_discount_2'] . ', ';
        $sql .= 'quantite_2 = ' . $l['quantite_2'] . ', ';
        $sql .= 'prc_discount_3 = ' . $l['prc_discount_3'] . ', ';
        $sql .= 'quantite_3 = ' . $l['quantite_3'] . ', ';
        $sql .= 'prc_discount_4 = ' . $l['prc_discount_4'] . ', ';
        $sql .= 'quantite_4 = ' . $l['quantite_4'] . ', ';
        $sql .= 'prc_discount_5 = ' . $l['prc_discount_5'] . ', ';
        $sql .= 'quantite_5 = ' . $l['quantite_5'] . ', ';
        $sql .= 'prc_discount_6 = ' . $l['prc_discount_6'] . ', ';
        $sql .= 'quantite_6 = ' . $l['quantite_6'] . ', ';
        $sql .= 'chk_variante = ' . $l['chk_variante'] . ', ';
        $sql .= 'chk_prix_net = ' . $l['chk_prix_net'] . ', ';
        $sql .= 'commentaire = "' . $l['commentaire'] . '";';

        eLog($sql);
        qSQL($sql, 'gen');

        $sql = 'SELECT dp.*, pf.marge_rr, pf.marge_dv FROM devis_produits dp ';
        $sql .= 'LEFT JOIN produits p ON dp.fk_produit = p.rowid ';
        $sql .= 'LEFT JOIN produits_familles pf ON p.groupe = pf.groupe ';
        $sql .= 'WHERE dp.fk_devis = ' . $fk_devis . ' ORDER BY dp.ordre;';
        echo getinfos($sql, 'gen', 'json');
      } else {
        echo json_encode(['success' => false, 'msg' => 'Ligne non trouvée']);
      }
    } else {
      echo json_encode(['success' => false, 'msg' => 'rowid_ligne manquant']);
    }
    break;

  case "delete_ligne_produit":
    $data = json_decode(file_get_contents("php://input"));
    if (isset($data->rowid_ligne)) {
      $rowidLigneSafe = intval(nettoie_input($data->rowid_ligne));

      $sql = 'SELECT fk_devis FROM devis_produits WHERE rowid = ' . $rowidLigneSafe . ';';
      $ligne = getinfos($sql, 'gen');

      if (count($ligne) > 0) {
        $fk_devis = $ligne[0]['fk_devis'];

        $sql = 'DELETE FROM devis_produits WHERE rowid = ' . $rowidLigneSafe . ';';
        eLog($sql);
        qSQL($sql, 'gen');

        $sql = 'SELECT dp.*, pf.marge_rr, pf.marge_dv FROM devis_produits dp ';
        $sql .= 'LEFT JOIN produits p ON dp.fk_produit = p.rowid ';
        $sql .= 'LEFT JOIN produits_familles pf ON p.groupe = pf.groupe ';
        $sql .= 'WHERE dp.fk_devis = ' . $fk_devis . ' ORDER BY dp.ordre;';
        echo getinfos($sql, 'gen', 'json');
      } else {
        echo json_encode(['success' => false, 'msg' => 'Ligne non trouvée']);
      }
    } else {
      echo json_encode(['success' => false, 'msg' => 'rowid_ligne manquant']);
    }
    break;

  case "load_clients_devis":
    //! On récupère les infos des clients de son secteur ou de toute la France, suivant le devis chk_clients_secteur, utilisé aussi pour l'autocomplete de la recherche de clients
    $data = json_decode(file_get_contents("php://input"));
    if (isset($data->secteur)) {
      $chkSecteur = nettoie_input($data->secteur);
      $fkUser = nettoie_input($data->user);
      $sql = 'SELECT rowid, code, libelle, CONCAT(libelle, ", ", adresse1, ", ", cp, " ", ville) AS rech, adresse1, adresse2, adresse3, cp, ville, contact_nom, contact_prenom, contact_fonction, telephone, mobile, email, type_client FROM clients WHERE active=1 ';
      if ($chkSecteur == "1") {
        //! on ne prend que les clients du secteur de l'utilisateur
        $fkUserSafe = intval($fkUser);
        $sqlDepts = 'SELECT lst_depts FROM users WHERE rowid=' . $fkUserSafe . ';';
        $lstDepts = getinfos($sqlDepts, "gen");
        $depts = trim($lstDepts[0]["lst_depts"]);
        if ($depts != "") $sql .= ' AND SUBSTR(cp,1,2) IN (' . $depts . ') ';
      }
      $sql .= 'ORDER BY libelle;';
      eLog($sql);
      echo getinfos($sql, "gen", "json");
    } else {
      $ret = array('ret' => "ko", 'msg' => 'Erreur lors du chargement des clients');
      echo json_encode($ret);
    }
    break;

  case "load_familles":
    //! On récupère les infos des familles de produits
    $sql = 'SELECT * FROM x_familles;';
    echo getinfos($sql, "gen", "json");
    break;

  case "load_devis_marche_infos":
    //! On récupère les infos du marché lié au devis
    $data = json_decode(file_get_contents("php://input"));
    if (isset($data->cid)) {
      $cid = nettoie_input($data->cid);
      $cidSafe = intval($cid);
      $sql = 'SELECT m.* FROM marches m WHERE m.rowid = ' . $cidSafe . ';';
      echo getinfos($sql, "gen", "json");
    }
    break;

  case "load_produits_mercurial":
    //! Charge les produits du marché hybride pour l'onglet Mercurial
    $data = json_decode(file_get_contents("php://input"));
    if (isset($data->fk_marche)) {
      $fkMarche = nettoie_input($data->fk_marche);
      $fkMarcheSafe = intval($fkMarche);

      // Vérifier que le marché est bien hybride
      $sql = 'SELECT chk_marche_hybride FROM marches WHERE rowid = ' . $fkMarcheSafe . ';';
      $retSql = getinfos($sql, "gen");

      if (count($retSql) == 1 && $retSql[0]["chk_marche_hybride"] == 1) {
        // Le marché est hybride, on charge tous les produits de ce marché (hors 999)
        $sql = 'SELECT p.*, CONCAT(p.code, " - ", p.libelle) AS rech, pf.fk_famille, xf.libelle AS lib_famille ';
        $sql .= 'FROM produits p LEFT JOIN produits_familles pf ON p.groupe=pf.groupe LEFT JOIN x_familles xf on pf.fk_famille = xf.rowid ';
        $sql .= 'WHERE p.fk_marche = ' . $fkMarcheSafe . ' AND p.fk_marche != 999 AND p.active=1 ORDER BY xf.ordre, pf.ordre;';
        echo getinfos($sql, "gen", "json");
      } else {
        // Le marché n'est pas hybride, on retourne un tableau vide
        echo json_encode(array());
      }
    } else {
      echo json_encode(array());
    }
    break;

  case "load_devis_marche_produits":
    //! Charge les produits enregistrés pour un marché
    $data = json_decode(file_get_contents("php://input"));
    if (isset($data->cid)) {
      $cid = nettoie_input($data->cid);

      // On récupère les terme du marché dans marches_listes
      $cidSafe = intval($cid);
      $sql = 'SELECT * FROM marches_listes WHERE fk_marche = ' . $cidSafe . ';';
      $retSql = getinfos($sql, "gen");
      if (count($retSql) == 1) {
        $termeAchat = $retSql[0]["terme_achat"];
        $termeVente = $retSql[0]["terme_vente"];
      } else {
        $termeAchat = "";
        $termeVente = "";
      }

      if ($cid != "999") {
        // ce n'est pas le hors marché
        // On vérifie d'abord si le marché est hybride, si oui on charge les produits du marché et ceux de la liste tarifaire générale
        $sql = 'SELECT chk_remise_sur_tg, chk_marche_hybride FROM marches WHERE rowid = ' . $cidSafe . ';';
        $retSql = getinfos($sql, "gen");
        $chkTG = $retSql[0]["chk_remise_sur_tg"];
        $chkHybride = $retSql[0]["chk_marche_hybride"];

        if ($chkTG) {
          // On charge uniquement les produits de la liste tarifaire générale TG ou Hors Marché
          $cid = 999;
          $termeAchat = '';
          $termeVente = '';
          $chkHybride = 0;
        }
      }

      $sql = 'SELECT p.*, CONCAT(p.code, " - ", p.libelle) AS rech, pf.fk_famille, xf.libelle AS lib_famille, "0" AS chk_prix_net ';
      $sql .= 'FROM produits p LEFT JOIN produits_familles pf ON p.groupe=pf.groupe LEFT JOIN x_familles xf on pf.fk_famille = xf.rowid ';
      $sql .= 'WHERE p.fk_marche = ' . intval($cid) . ' AND p.active=1 ORDER BY xf.ordre, pf.ordre;';
      $upls = getinfos($sql, "gen");

      if ($cid != "999") {
        // ce n'est pas le hors marché
        // On crée une liste des codes produits récupérés
        $codes = array();
        foreach ($upls as $line) {
          $codes[] = '"' . $line["code"] . '"';
        }
        // et on crée une chaîne de caractères à partir de cette liste avec les codes séparés par des virgules
        $lstCodes = implode(",", $codes);

        if ($termeAchat == 'Purchasing') {
          // cela veut dire qu'on doit aller chercher dans le hors marché le prix d'achat net des produits de ce marché
          foreach ($upls as $index => $line) {
            $sql = 'SELECT p.prix_achat_net, prc_discount_1, quantite_1, prc_discount_2, quantite_2, prc_discount_3, quantite_3, prc_discount_4, quantite_4, prc_discount_5, quantite_5, prc_discount_6, quantite_6 ';
            $sql .= 'FROM produits p WHERE p.code = "' . $line["code"] . '" AND p.fk_marche=999;';
            $retSql = getinfos($sql, "gen");

            if (count($retSql) == 1) {
              $upls[$index]["prix_achat_net"] = $retSql[0]["prix_achat_net"];
              $upls[$index]["prc_discount_1"] = $retSql[0]["prc_discount_1"];
              $upls[$index]["quantite_1"] = $retSql[0]["quantite_1"];
              $upls[$index]["prc_discount_2"] = $retSql[0]["prc_discount_2"];
              $upls[$index]["quantite_2"] = $retSql[0]["quantite_2"];
              $upls[$index]["prc_discount_3"] = $retSql[0]["prc_discount_3"];
              $upls[$index]["quantite_3"] = $retSql[0]["quantite_3"];
              $upls[$index]["prc_discount_4"] = $retSql[0]["prc_discount_4"];
              $upls[$index]["quantite_4"] = $retSql[0]["quantite_4"];
              $upls[$index]["prc_discount_5"] = $retSql[0]["prc_discount_5"];
              $upls[$index]["quantite_5"] = $retSql[0]["quantite_5"];
              $upls[$index]["prc_discount_6"] = $retSql[0]["prc_discount_6"];
              $upls[$index]["quantite_6"] = $retSql[0]["quantite_6"];
            }
          }
        }


        //! On vérifie si des produits ont bien été récupérés, sinon on charge les produits de la liste tarifaire générale
        if ($chkHybride == 1) {
          // AJOUT 20/02/25 : si marché hybride, les produits de ce marché uniquement sont en prix nets
          foreach ($upls as $index => $line) {
            $upls[$index]["chk_prix_net"] = "1";
          }
          // AJOUT 20/02/25 : On ajoute une colonne chk_prix_net qui indique que les autres produits du marché TG n'ont pas de prix_net
          $sql = 'SELECT p.*, CONCAT(p.code, " - ", p.libelle) AS rech, pf.fk_famille, xf.libelle AS lib_famille, "0" AS chk_prix_net ';
          $sql .= 'FROM produits p LEFT JOIN produits_familles pf ON p.groupe=pf.groupe LEFT JOIN x_familles xf on pf.fk_famille = xf.rowid ';
          $sql .= 'WHERE p.fk_marche=999 AND p.code not in (' . $lstCodes . ') AND p.active=1 ORDER BY xf.ordre, pf.ordre;';
          eLog($sql);
          // Et enfin, on fusionne les 2 tableaux
          $upls = array_merge($upls, getinfos($sql, "gen"));
        }
      }
      echo json_encode($upls);
    }
    break;

  case "load_devis_speciaux":
    $data = json_decode(file_get_contents("php://input"));
    if (isset($data->cid)) {
      $cid = nettoie_input($data->cid);
      $cidSafe = intval($cid);
      $sql = 'SELECT * FROM devis_speciaux WHERE fk_devis = ' . $cidSafe . ';';
      echo getinfos($sql, "gen", "json");
    }
    break;

  case "delete_devis":
    $data = json_decode(file_get_contents("php://input"));
    if (isset($data->cid)) {
      $cid = nettoie_input($data->cid);

      $cidSafe = intval($cid);
      $sql = 'SELECT d.fk_user, d.fk_client, d.lib_new_client, d.cp_new_client, d.ville_new_client, d.montant_total_ht_remise FROM devis d WHERE d.rowid = ' . $cidSafe . ';';
      $retSql = getinfos($sql, "gen");
      $devis = $retSql[0];
      if ($devis["fk_client"] > 0) {
        $fkClientSafe = intval($devis["fk_client"]);
        $sql = 'SELECT c.libelle, c.cp, c.ville FROM clients c WHERE c.rowid = ' . $fkClientSafe . ';';
        $ret = getinfos($sql, "gen");
        $client = $ret[0];
        $libClient = $client["libelle"];
        $cpClient = $client["cp"];
        $villeClient = $client["ville"];
      } else {
        $libClient = $devis["lib_new_client"];
        $cpClient = $devis["cp_new_client"];
        $villeClient = $devis["ville_new_client"];
      }
      $fkUserDevis = $devis["fk_user"];

      $sql = 'DELETE FROM devis_speciaux WHERE fk_devis = ' . $cidSafe . ';';
      qSQL($sql, "gen");

      $sql = 'DELETE FROM devis_histo WHERE fk_devis = ' . $cidSafe . ';';
      qSQL($sql, "gen");

      $sql = 'DELETE FROM devis_produits WHERE fk_devis = ' . $cidSafe . ';';
      qSQL($sql, "gen");

      $sql = 'DELETE FROM devis WHERE rowid = ' . $cidSafe . ';';
      qSQL($sql, "gen");
      eLog($sql);

      // On envoie un email au RR pour lui signaler la suppression du devis si ce n'est pas lui qui a supprimé le devis
      if ($fk_user != $fkUserDevis) {
        $fkUserDevisSafe = intval($fkUserDevis);
        $sql = 'SELECT u.prenom, u.libelle, u.email FROM users u WHERE u.rowid = ' . $fkUserDevisSafe . ';';
        $retSql = getinfos($sql, "gen");
        $nom = $retSql[0]["prenom"] . " " . $retSql[0]["libelle"];
        $email = $retSql[0]["email"];

        $sujet = "Suppression d'un de vos devis";
        $message = "Bonjour " . $nom . ",<br><br>";
        $message .= "Votre devis #" . $cid . " vient d'être supprimé.<br><br>";
        $message .= "Client : " . $libClient . ", " . $cpClient . " " . $villeClient . "<br>";
        $message .= "Pour un montant total HT remisé de " . $devis["montant_total_ht_remise"] . " €<br><br>";
        $message .= "Cordialement,<br>";
        $message .= "Message généré automatiquement par l'application CLEO de gestion des devis<br>";
        eLog("Envoi d'un email à " . $email . " pour la suppression du devis #" . $cid);
        envoieMail($email, $sujet, $message);
      }

      echo json_encode(array("success" => true));
    }
    break;

  case "save_devis_entete":
    // Enregistre l'onglet Entête d'un devis en Création ou Modification

    if ($_POST) {
      $rowid = nettoie_input($_POST["rowid"]);
      $fk_client = nettoie_input($_POST["fk_client"]);
      $fk_user = nettoie_input($_POST["fk_user"]);
      $fk_marche = nettoie_input($_POST["fk_marche"]);
      $num_opportunite = nettoie_input($_POST["num_opportunite"]);

      // On récupère les dates au format MySQL
      $date_demande = $_POST["date_demande"];
      if (strlen($date_demande) != 10) $date_demande = "";
      $date_remise = $_POST["date_remise"];
      if (strlen($date_remise) != 10) $date_remise = "";

      if (isset($_POST["chk_devis_photos"])) {
        if ($_POST["chk_devis_photos"] == false || $_POST["chk_devis_photos"] == 0) {
          $chk_devis_photos = 0;
        } else {
          $chk_devis_photos = 1;
        }
      } else {
        $chk_devis_photos = 0;
      }
      $commentaire = nettoie_input($_POST["commentaire"]);
      $newCommentaire = 0;

      // Récupération du contact sélectionné
      $fk_contact = isset($_POST["fk_contact"]) ? intval($_POST["fk_contact"]) : 0;
      if ($fk_contact == 0) $fk_contact = NULL;

      $set = 'fk_client=' . $fk_client . ', fk_contact=' . ($fk_contact === NULL ? 'NULL' : $fk_contact) . ', num_opportunite="' . $num_opportunite . '", date_demande="' . $date_demande . '", date_remise="' . $date_remise . '", ';
      $set .= 'fk_user=' . $fk_user . ', fk_marche=' . $fk_marche . ', commentaire="' . $commentaire . '", chk_devis_photos=' . $chk_devis_photos . ', ';

      if ($_POST["rowid"] == 0) {
        //! C'est un nouveau devis
        //! On le range dans un dossier

        if ($commentaire != "") $newCommentaire = 1;
        $cp = nettoie_input($_POST["cp"]);
        // Si le CP a une longueur de 4, on rajoute un 0 devant
        if (strlen($cp) == 4) $cp = "0" . $cp;
        $dossier = substr($cp, 0, 2);
        $set .= 'dossier="' . $dossier . '", fk_statut_devis=1, date_creat="' . date("Y-m-d H:i:s") . '", fk_user_creat=' . $fk_user;
        $sql = 'INSERT INTO devis SET ' . $set . ';';
        $retid = qSQL($sql, "gen", true);
      } else {
        //! c'est une mise à jour d'un devis existant

        $rowidSafe = intval($rowid);
        $sql = 'SELECT fk_marche, commentaire FROM devis WHERE rowid = ' . $rowidSafe . ';';
        $retSql = getinfos($sql, "gen");
        $commentaireOld = $retSql[0]["commentaire"];
        if ($commentaireOld != $commentaire) {
          // le commentaire a été modifié
          if ($commentaireOld == "") {
            $newCommentaire = 1;
          } else {
            $newCommentaire = 2;
          }
        }
        $oldMarche = $retSql[0]["fk_marche"];
        if ($oldMarche != $fk_marche) {
          // le marché a été modifié, il faut supprimer tous les produits de ce devis !!
          $sql = 'DELETE FROM devis_produits WHERE fk_devis = ' . $rowidSafe . ';';
          eLog($sql);
          qSQL($sql, "gen");
          // et on remet à zéro tous les totaux du devis
          $sql = 'UPDATE devis SET montant_total_ht=0, montant_total_ht_remise=0, marge_totale=0 WHERE rowid=' . $rowidSafe . ';';
          eLog($sql);
          qSQL($sql, "gen");
          // On enregistre cette info dans le chat
          $fkUserSafe = intval($fk_user);
          $sql = 'INSERT INTO devis_histo SET fk_user=' . $fkUserSafe . ', fk_devis=' . $rowidSafe . ', commentaire="Le marché a été modifié, les produits ont été supprimés", date_histo="' . date("Y-m-d H:i:s") . '";';
          eLog($sql);
          qSQL($sql, "gen");
        }
        $set .= 'date_modif="' . date("Y-m-d H:i:s") . '", fk_user_modif=' . $fk_user;
        $sql = 'UPDATE devis SET ' . $set . ' WHERE rowid=' . $rowidSafe . ';';
        qSQL($sql, "gen");
        $retid = $rowid;
      }
      eLog('Entete Devis Save : ' . $sql);

      // NOTE: Les contacts sont maintenant gérés via la table clients_contacts
      // et non plus directement dans la table clients

      // On inscrit l'enregistrement dans le journal si il y a eu un changement de commentaire ou bien si c'est une création avec commentaire
      if ($newCommentaire > 0) {
        if ($newCommentaire == 1) {
          $fkUserSafe = intval($fk_user);
          $retidSafe = intval($retid);
          $sql = 'INSERT INTO devis_histo SET fk_user = ' . $fkUserSafe . ', fk_devis = ' . $retidSafe . ', commentaire="' . $commentaire . '", date_histo = "' . date("Y-m-d H:i:s") . '", chk_comment_devis = 1;';
          eLog('Entete Devis Save Histo : ' . $sql);
          qSQL($sql, "gen");
        } else {
          $fkUserSafe = intval($fk_user);
          $retidSafe = intval($retid);
          $sql = 'UPDATE devis_histo SET fk_user = ' . $fkUserSafe . ', commentaire="' . $commentaire . '", date_histo = "' . date("Y-m-d H:i:s") . '" WHERE fk_devis = ' . $retidSafe . ' AND chk_comment_devis = 1;';
          eLog('Entete Devis Save Histo : ' . $sql);
          qSQL($sql, "gen");
        }
      }

      // on met à jour la session avec le rowid de ce dernier devis créé ou mis à jour
      $_SESSION["lastDevis"] = $retid;

      // on renvoie en json le rowid du devis créé ou mis à jour
      $upls = array("retid" => $retid);
      echo json_encode($upls);
    }
    break;

  case "save_devis_speciaux":
    $data = json_decode(file_get_contents("php://input"));
    if (isset($data->idDevis_speciaux)) {
      $fkDevis = $data->idDevis_speciaux;

      (isset($data->chk_livr_multi)) ? $chk_livr_multi = 1 : $chk_livr_multi = 0;
      $date_livr_1 = $data->date_livr_1;
      $nb_livr = $data->nb_livr;
      if ($nb_livr == "") $nb_livr = 0;
      $email = $data->specialEmail;

      $set = 'chk_livr_multi=' . $chk_livr_multi . ', date_livr_1="' . $date_livr_1 . '", nb_livr=' . $nb_livr . ', email="' . $email . '", ';

      for ($i = 1; $i <= 5; $i++) {
        if ($data->{"specialFkProduit_" . $i} > 0) {
          $fk_produit = $data->{"specialFkProduit_" . $i};
          $code = $data->{"specialCode_" . $i};
          $libelle = $data->{"specialLibe_" . $i};
          $qte = $data->{"specialQte_" . $i};
          $concurrent = $data->{"specialConcurrent_" . $i};
          $surcout = $data->{"specialCout_" . $i} == "" ? 0 : $data->{"specialCout_" . $i};
          (isset($data->{"chk_specialEchantillon_" . $i})) ? $chk_echantillon = 1 : $chk_echantillon = 0;
          $datech = $data->{"specialDate_" . $i};
          $description = $data->{"specialDescription_" . $i};
        } else {
          // on vide les champs sinon
          $fk_produit = 0;
          $code = "";
          $libelle = "";
          $qte = 0;
          $concurrent = "";
          $surcout = 0;
          $chk_echantillon = 0;
          $datech = "";
          $description = "";
        }
        $set .= 'fk_produit_' . $i . '=' . $fk_produit . ', code_produit_' . $i . '="' . $code . '", lib_produit_' . $i . '="' . $libelle . '", qte_' . $i . '=' . $qte . ', ';
        $set .= 'lib_concurrent_' . $i . '="' . $concurrent . '", surcout_' . $i . '=' . $surcout . ', chk_echantillon_' . $i . '=' . $chk_echantillon . ', ';
        $set .= 'date_echantillon_' . $i . '="' . $datech . '", description_' . $i . '="' . $description . '", ';
      }

      if (substr($set, -2) == ", ") {
        $set = substr($set, 0, -2);
      }

      $fkDevisSafe = intval($fkDevis);
      $sql = 'SELECT rowid FROM devis_speciaux WHERE fk_devis = ' . $fkDevisSafe . ';';
      $retSql = getinfos($sql, "gen");
      if (count($retSql) == 0) {
        // c'est une création
        $sql = 'INSERT INTO devis_speciaux SET fk_devis = ' . $fkDevisSafe . ', ' . $set . ';';
        eLog('Devis Speciaux Save : ' . $sql);
        $retid = qSQL($sql, "gen", true);
      } else {
        // c'est une mise à jour
        $sql = 'UPDATE devis_speciaux SET ' . $set . ' WHERE fk_devis = ' . $fkDevisSafe . ';';
        eLog('Devis Speciaux Save : ' . $sql);
        qSQL($sql, "gen");
        $retid = $fkDevis;
      }

      // On boucle sur ces 5 produits spéciaux pour voir s'il faut envoyer un email à un service concerné
      $sql = 'SELECT ds.* FROM devis_speciaux ds WHERE ds.fk_devis = ' . $fkDevisSafe . ';';
      $ret = getinfos($sql, "gen");
      $spec = $ret[0];

      if ($spec["email"] != "" && $spec["chk_email"] == 0) {
        // Un email est renseigné et il n'a pas été encore envoyé

        // on récupère le nom, cp et ville du client
        $sql = 'SELECT d.fk_client, d.lib_new_client, d.cp_new_client, d.ville_new_client FROM devis d WHERE d.rowid = ' . $fkDevisSafe . ';';
        $ret = getinfos($sql, "gen");
        $dev = $ret[0];
        if ($dev["fk_client"] > 0) {
          $fkClientSafe = intval($dev["fk_client"]);
          $sql = 'SELECT c.code, c.libelle, c.cp, c.ville FROM clients c WHERE c.rowid = ' . $fkClientSafe . ';';
          $ret = getinfos($sql, "gen");
          $cli = $ret[0];
          $codeClient = $cli["code"];
          $libelle = $cli["libelle"];
          $cp = $cli["cp"];
          $ville = $cli["ville"];
        } else {
          $codeClient = "Nouveau client";
          $libelle = $dev["lib_new_client"];
          $cp = $dev["cp_new_client"];
          $ville = $dev["ville_new_client"];
        }

        $dest = $spec["email"];
        $subject = "Demande de produits spéciaux";
        $message = "[Ce message est envoyé automatiquement par le système de gestion de devis]<br/><br/>";
        $message .= "Bonjour,<br/><br/>sur le devis #" . $fkDevis . ", <br/>";
        $message .= "pour le client " . $libelle . ", " . $cp . " " . $ville . ", code : " . $codeClient . "<br/><br/>";
        $message .= "Livraisons multiples : ";
        $spec["chk_livr_multi"] == 1 ? $message .= "Oui, en " . $spec["nb_livr"] . " fois" : $message .= "Non";
        $message .= "<br/>Date de la 1ère livraison : " . affiche_date($spec["date_livr_1"]) . "<br/><br/>";
        $message .= "-----------------------------------------------<br/><br/>";
        $message .= "Les produits spéciaux suivants sont demandés :<br/><br/>";

        for ($i = 1; $i <= 5; $i++) {
          if ($spec["fk_produit_" . $i] > 0) {
            $message .= "Produit : " . $spec["code_produit_" . $i] . " - " . $spec["lib_produit_" . $i] . "<br/>";
            $message .= "Quantité : " . $spec["qte_" . $i] . "<br/>";
            $message .= "Concurrent : " . $spec["lib_concurrent_" . $i] . "<br/>";
            $message .= "Surcoût accepté : " . $spec["surcout_" . $i] . "<br/>";
            if ($spec["chk_echantillon_" . $i] == 1) {
              $message .= "Echantillon demandé : Oui<br/>";
              $message .= "Date d'envoi de l'échantillon : " . $spec["date_echantillon_" . $i] . "<br/>";
            } else {
              $message .= "Echantillon demandé : Non<br/><br/>";
            }
            $message .= "Description : " . $spec["description_" . $i] . "<br/>";
            $message .= "------------------<br/><br/>";
          }
        }
        $message .= "-----------------------------------------------<br/><br/>";

        $message .= "Cordialement.<br/>";
        $message .= $Session->_user["prenom"] . " " . $Session->_user["libelle"];
        $copieFrom = $Session->_user["email"];
        $ret = envoieMail($dest, $subject, $message, $copieFrom);
        if ($ret == 1) {
          // on met à jour le devis pour indiquer que l'email a été envoyé
          $sql = 'UPDATE devis_speciaux SET chk_email = 1 WHERE fk_devis = ' . $fkDevisSafe . ';';
          eLog('Devis Speciaux Save : ' . $sql);
          qSQL($sql, "gen");
        }
      }

      // on met enfin à jour le devis pour indiquer qu'il y a des spéciaux
      $sql = 'UPDATE devis SET chk_speciaux = 1 WHERE rowid = ' . $fkDevisSafe . ';';
      eLog('Devis Speciaux Save : ' . $sql);
      qSQL($sql, "gen");

      // on met à jour la session avec le rowid de ce dernier devis créé ou mis à jour
      $_SESSION["lastDevis"] = $fkDevis;

      // on renvoie le rowid du devis et le nombre de produits renseignés
      $upls = array("success" => true, "retid" => $fkDevis);
      echo json_encode($upls);
    }
    break;

  case "load_devis_produits_search":
    if (isset($_POST["term"])) {
      if (strlen($_POST["term"]) > 0) {
        $term = nettoie_input($_POST["term"]);
        try {
          $db = Database::getInstance();
          $sql = 'SELECT rowid, code, libelle, prix_vente FROM produits WHERE active=1 AND (code LIKE :term OR libelle LIKE :term) ORDER BY code';
          $termParam = '%' . $term . '%';
          $upls = $db->fetchAll($sql, [':term' => $termParam]);
        } catch (Exception $e) {
          error_log("Erreur recherche produits : " . $e->getMessage());
          $upls = [];
        }
        echo json_encode($upls);
        break;
      } else {
        $sql = 'SELECT rowid, code, libelle, prix_vente FROM produits WHERE active=1 ORDER BY code;';
      }
    } else {
      $sql = 'SELECT rowid, code, libelle, prix_vente FROM produits WHERE active=1 ORDER BY code;';
    }
    if (!isset($upls)) {
      $upls = array();
      $upls = getinfos($sql, "gen");
      echo json_encode($upls);
    }
    break;

  case "save_devis_produits":
    // Enregistre l'onglet Produits d'un devis (les produits sélectionnés)

    $data = json_decode(file_get_contents("php://input"));
    if (isset($data->cid)) {
      $idDevis = nettoie_input($data->cid);
      eLog("save_devis_produits : idDevis = " . $idDevis);
      // on récupère les anciens produits du devis
      if ($idDevis > 0) {
        // on récupère les anciens produits du devis
        $idDevisSafe = intval($idDevis);
        $sql = 'SELECT fk_produit FROM devis_produits WHERE fk_devis = ' . $idDevisSafe . ';';
        $tempAncProduits = getinfos($sql, 'gen');
        $lstAncProduits = array();
        foreach ($tempAncProduits as $prod) {
          $lstAncProduits[] = $prod['fk_produit'];
        }
        eLog("save_devis_produits : Nb anciens produits = " . count($lstAncProduits));

        // On récupère les terme du marché de ce devis dans marches_listes
        $sql = 'SELECT fk_marche FROM devis WHERE rowid = ' . $idDevisSafe . ';';
        $retSql = getinfos($sql, "gen");
        $idMarche = $retSql[0]["fk_marche"];
        eLog("save_devis_produits : fk_marche = " . $idMarche);
        $idMarcheSafe = intval($idMarche);
        $sql = 'SELECT * FROM marches_listes WHERE fk_marche = ' . $idMarcheSafe . ';';
        $retSql = getinfos($sql, "gen");
        if (count($retSql) == 1) {
          $termeAchat = $retSql[0]["terme_achat"];
          $termeVente = $retSql[0]["terme_vente"];
        } else {
          $termeAchat = "";
          $termeVente = "";
        }

        // On va vérifier le marché de ce devis pour voir s'il est hybride
        $chkHybride = 0;
        $lstCodesHybrides = array();
        $sql = 'SELECT chk_marche_hybride FROM marches WHERE rowid=' . $idMarcheSafe . ';';
        $retSql = getinfos($sql, "gen");
        if (count($retSql) == 1 && $retSql[0]["chk_marche_hybride"] == 1) {
          //! le marché est hybride
          $chkHybride = 1;
          // dans ce cas on récupère les produits de ce marché
          $sql = 'SELECT code FROM produits WHERE fk_marche=' . $idMarcheSafe . ' AND active=1;';
          $tempCodesHybrides = getinfos($sql, 'gen');
          $lstCodesHybrides = array();
          foreach ($tempCodesHybrides as $prod) {
            $lstCodesHybrides[] = $prod['code'];
          }
        }
        eLog("on a " . count($lstCodesHybrides) . " codes hybrides");


        if (!empty($data->produits)) {
          //! il y a au moins 1 produit sélectionné à enregistrer
          $lstProduits = $data->produits;
          //! on supprime le premier caractère séparateur
          $lstProduits = substr($lstProduits, 1);
          //! et on transforme la chaîne en tableau
          $newProduits = explode(";", $lstProduits);

          eLog("save_devis_produits : on a " . count($newProduits) . " produits à enregistrer");

          foreach ($newProduits as $newProd) {
            //! pour chaque produit sélectionné
            eLog("save_devis_produits : on va tester si le produit " . $newProd . " existe dans la liste des ancien produits (anciennes lignes)");
            //! 1. on regarde s'il est déjà enregistré
            if (!in_array($newProd, $lstAncProduits)) {
              //! ce produit n'existe pas, on le rajoute
              eLog("save_devis_produits : le produit " . $newProd . " n'existe pas dans la liste des ancien produits (anciennes lignes)");
              //! on récupère d'abord les prix d'achat et de vente du produit
              $sql = 'SELECT code, libelle, prix_achat_net, prix_vente, prc_discount_1, quantite_1, prc_discount_2, quantite_2, ';
              $sql .= 'prc_discount_3, quantite_3, prc_discount_4, quantite_4, prc_discount_5, quantite_5, prc_discount_6, quantite_6 ';
              $sql .= 'FROM produits WHERE rowid=' . $newProd . ';';
              $prodInfos = getinfos($sql);
              eLog(count($prodInfos));
              $prix_achat_net = $prodInfos[0]["prix_achat_net"];
              $prix_vente = $prodInfos[0]["prix_vente"];
              $code = $prodInfos[0]["code"];
              $libelle = $prodInfos[0]["libelle"];

              eLog("On teste s'il est hybride dans les " . count($lstCodesHybrides) . " codes hybrides ? ");
              // on vérifie si le code produit existe dans la liste des codes hybrides
              if (in_array($code, $lstCodesHybrides)) {
                $chk_prix_net = 1;
              } else {
                $chk_prix_net = 0;
              }
              eLog("Produit " . $code . " existe dans la liste des codes hybrides ? " . $chk_prix_net);

              if ($prix_achat_net == 0 && $termeAchat == "Purchasing") {
                //! le prix d'achat est à 0, et le marché n'enregistre que les prix de vente donc on va cherche le prix d'achat net dans le hors marché
                $sql = 'SELECT p.prix_achat_net, prc_discount_1, quantite_1, prc_discount_2, quantite_2, prc_discount_3, quantite_3, ';
                $sql .= 'prc_discount_4, quantite_4, prc_discount_5, quantite_5, prc_discount_6, quantite_6 ';
                $sql .= 'FROM produits p WHERE p.code="' . $code . '" AND fk_marche=999;';
                $prodInfos = getinfos($sql, "gen");
                $prix_achat_net = $prodInfos[0]["prix_achat_net"];
              }
              $discount1 = $prodInfos[0]["prc_discount_1"];
              $quantite1 = $prodInfos[0]["quantite_1"];
              $discount2 = $prodInfos[0]["prc_discount_2"];
              $quantite2 = $prodInfos[0]["quantite_2"];
              $discount3 = $prodInfos[0]["prc_discount_3"];
              $quantite3 = $prodInfos[0]["quantite_3"];
              $discount4 = $prodInfos[0]["prc_discount_4"];
              $quantite4 = $prodInfos[0]["quantite_4"];
              $discount5 = $prodInfos[0]["prc_discount_5"];
              $quantite5 = $prodInfos[0]["quantite_5"];
              $discount6 = $prodInfos[0]["prc_discount_6"];
              $quantite6 = $prodInfos[0]["quantite_6"];

              //! puis on l'enregistre
              $sql = 'INSERT INTO devis_produits SET fk_devis=' . $idDevis . ', fk_produit=' . $newProd . ', code="' . $code . '", libelle="' . $libelle . '", ';
              $sql .= 'prix_achat_net=' . $prix_achat_net . ', prix_vente=' . $prix_vente . ', prc_discount_1=' . $discount1 . ', quantite_1=' . $quantite1 . ', ';
              $sql .= 'prc_discount_2=' . $discount2 . ', quantite_2=' . $quantite2 . ', prc_discount_3=' . $discount3 . ', quantite_3=' . $quantite3 . ', ';
              $sql .= 'prc_discount_4=' . $discount4 . ', quantite_4=' . $quantite4 . ', prc_discount_5=' . $discount5 . ', quantite_5=' . $quantite5 . ', ';
              $sql .= 'prc_discount_6=' . $discount6 . ', quantite_6=' . $quantite6 . ', chk_prix_net=' . $chk_prix_net . ';';
              eLog($sql);
              qSQL($sql, "gen");
            }
          }
          //! Enfin, on compare les 2 listes et on supprime les produits enregistrés mais non sélectionnés
          if (count($lstAncProduits) > 0) {
            foreach ($lstAncProduits as $ancProd) {
              if (!in_array($ancProd, $newProduits)) {
                if ($ancProd != "") {
                  //! ce produit était enregistré, mais n'est plus dans la nouvelle sélection, on le supprime
                  $sql = 'DELETE FROM devis_produits WHERE fk_devis=' . $idDevis . ' AND fk_produit=' . $ancProd . ';';
                  eLog($sql);
                  qSQL($sql, "gen");
                }
              }
            }
          }
        } else {
          //! Aucun produit sélectionné : on supprime les éventuels anciens produits enregistrés de ce devis
          $sql = 'DELETE FROM devis_produits WHERE fk_devis = ' . $idDevis . ';';
          eLog($sql);
          qSQL($sql, "gen");
        }

        // on met à jour la session avec le rowid de ce dernier devis créé ou mis à jour
        $_SESSION["lastDevis"] = $idDevis;

        //! on retourne la liste des produits du devis à jour
        $sql = 'SELECT dp.*, pf.marge_rr, pf.marge_dv FROM devis_produits dp LEFT JOIN produits p ON dp.fk_produit=p.rowid LEFT JOIN produits_familles pf ON p.groupe=pf.groupe WHERE dp.fk_devis = ' . $idDevis . ';';
        $result = getinfos($sql, "gen", "json");
        elog("result : " . $result);
        // Vérification si le résultat est vide
        if (empty($result) || $result === "null" || $result === "[]") {
          echo json_encode([]);
        } else {
          echo $result;
        }
      }
    }
    break;

  case "save_devis":
    //! on enregistre la page finale du devis
    $data = json_decode(file_get_contents("php://input"));

    if (isset($data->inpIdDevis)) {
      $idDevis = nettoie_input($data->inpIdDevis);
      eLog("save_devis final : idDevis = " . $idDevis);

      $sql = 'SELECT rowid FROM devis_produits WHERE fk_devis = ' . $idDevis . ';';
      $lignesProduits = getinfos($sql, 'gen');

      if (count($lignesProduits) > 0) {
        foreach ($lignesProduits as $ligne) {
          $rowidLigne = $ligne['rowid'];

          if (isset($data->{"inpQte_" . $rowidLigne})) {
            $qte = nettoie_input($data->{"inpQte_" . $rowidLigne});
            $qte = $qte == "" ? 0 : $qte;
            $rem = nettoie_input($data->{"inpRemise_" . $rowidLigne});
            $rem = $rem == "" ? 0 : $rem;

            $ht = nettoie_input($data->{"inpHT_" . $rowidLigne});
            $ht = $ht == "" ? 0 : $ht;
            $ht = str_replace(" ", "", $ht);

            $mg = nettoie_input($data->{"inpMG_" . $rowidLigne});
            $mg = $mg == "" ? 0 : $mg;

            $ha = nettoie_input($data->{"achat_" . $rowidLigne});
            $ha = $ha == "" ? 0 : $ha;
            $ha = str_replace(" ", "", $ha);

            $pv = nettoie_input($data->{"vente_" . $rowidLigne});
            $pv = $pv == "" ? 0 : $pv;
            $pv = str_replace(" ", "", $pv);

            $pu = nettoie_input($data->{"inpPUVenteRem_" . $rowidLigne});
            $pu = $pu == "" ? 0 : $pu;
            $pu = str_replace(" ", "", $pu);

            $varOpt = 0;
            if (isset($data->{"chkVariante_" . $rowidLigne})) {
              $varOpt = 1;
            }

            $comment = nettoie_input($data->{"inpCom_" . $rowidLigne});
            $ordre = nettoie_input($data->{"inpOrdre_" . $rowidLigne});
            if ($ordre == "") {
              $ordre = 0;
            }
            $sql = 'UPDATE devis_produits SET qte=' . $qte . ', remise=' . $rem . ', totalht=' . $ht . ', marge=' . $mg . ', prix_achat_net=' . $ha . ', ';
            $sql .= 'prix_vente=' . $pv . ', pu_vente_remise=' . $pu . ', chk_variante=' . $varOpt . ', commentaire="' . $comment . '", ordre=' . $ordre . ' ';
            $sql .= 'WHERE rowid = ' . $rowidLigne . ';';
            eLog($sql);
            qSQL($sql, "gen");
          }
        }
      }

      //! on enregistre les totaux dans la table devis
      $totalHT = nettoie_input($data->inpTotalHT);
      $totalRemHT = nettoie_input($data->inpTotalRemHT);
      $totalMarge = nettoie_input($data->inpTotalMarge);
      $totalHT == "" ? 0 : $totalHT;
      // si $totalHT contient un espace (délimiteur millier), on le supprime
      $totalHT = str_replace(" ", "", $totalHT);
      $totalRemHT == "" ? 0 : $totalRemHT;
      $totalRemHT = str_replace(" ", "", $totalRemHT);
      $totalMarge == "" ? 0 : $totalMarge;
      $totalMarge = str_replace(" ", "", $totalMarge);
      $commentDevis = nettoie_input($data->commentDevis);
      $commentGesteComm = nettoie_input($data->commentGesteComm);
      $sql = 'UPDATE devis SET montant_total_ht=' . $totalHT . ', montant_total_ht_remise=' . $totalRemHT . ', marge_totale=' . $totalMarge . ', comment_devis="' . $commentDevis . '", comment_geste_comm="' . $commentGesteComm . '", ';
      $sql .= 'date_modif="' . date("Y-m-d H:i:s") . '", fk_user_modif=' . $fk_user . ' ';
      $sql .= 'WHERE rowid=' . $idDevis . ';';
      eLog($sql);
      qSQL($sql, "gen");

      // On vérifie le statut du devis
      $sql = 'SELECT d.fk_statut_devis, d.chk_validat, d.fk_user_validat, d.fk_user FROM devis d WHERE d.rowid=' . $idDevis . ';';
      $res = getinfos($sql, "gen");
      $statutDevis = $res[0]["fk_statut_devis"];
      $fkUserDevis = $res[0]["fk_user"];
      $chkValidat = $res[0]["chk_validat"];
      $fkUserValidat = $res[0]["fk_user_validat"];

      if ($statutDevis > 1 && $statutDevis < 7) {
        //! le devis n'est plus en statut "En cours de création" : il faut prévenir les interlocuteurs qu'il a fait une mise à jour
        switch ($statutDevis) {
          case 2:
            //! le devis est en statut "En attente de validation du DIR-CO" : on lui envoie un mail et on check la nouveauté dans le devis
            $sqlMail = "";
            if ($fkUserDevis != $fk_user) {
              //! l'utilisateur qui a créé le devis n'est pas celui qui le modifie : on prévient l'utilisateur initial
              $sqlMail = 'SELECT u.prenom, u.libelle, u.email FROM users u WHERE u.rowid = ' . $res[0]["fk_user"] . ';';
            } else {
              //! l'utilisateur qui a créé le devis est celui qui le modifie : on prévient le DIR-CO
              $fkUserDirCo = 0;
              if ($fk_role == 3) {
                // C'est un commercial RR, on va chercher le parent de son DV
                if ($Session->_user["fk_parent"] > 0) {
                  $sql = 'SELECT u.fk_parent FROM users u WHERE u.rowid = ' . $Session->_user["fk_parent"] . ' AND u.fk_role=2;';
                  $res = getinfos($sql, "gen");
                  $fkUserDirCo = $res[0]["fk_parent"];
                }
              } else {
                // C'est le DV, on récupère son responsable le DIR-CO
                $fkUserDirCo = $Session->_user["fk_parent"];
              }
              if ($fkUserDirCo > 0) {
                $sqlMail = 'SELECT u.prenom, u.libelle, u.email FROM users u WHERE u.rowid = ' . $fkUserDirCo . ';';
              }
            }
            if ($sqlMail != "") {
              $res = getinfos($sqlMail, "gen");
              $dest = $res[0];
              $nomDest = $dest["prenom"] . " " . $dest["libelle"];
              $emailDest = $dest["email"];
            }
            break;

          case 3:
            //! le devis est en statut "En attente de validation du DV" : on lui envoie un mail et on check la nouveauté dans le devis
            $sqlMail = "";
            if ($fkUserDevis != $fk_user) {
              //! l'utilisateur qui a créé le devis n'est pas celui qui le modifie : on prévient l'utilisateur initial
              $sqlMail = 'SELECT u.prenom, u.libelle, u.email FROM users u WHERE u.rowid = ' . $res[0]["fk_user"] . ';';
            } else {
              //! l'utilisateur qui a créé le devis est celui qui le modifie : on prévient le DV
              if ($Session->_user["fk_parent"] > 0) {
                $sqlMail = 'SELECT u.prenom, u.libelle, u.email FROM users u WHERE u.rowid = ' . $Session->_user["fk_parent"] . ' AND u.fk_role=2;';
              }
            }
            if ($sqlMail != "") {
              $res = getinfos($sqlMail, "gen");
              $dest = $res[0];
              $nomDest = $dest["prenom"] . " " . $dest["libelle"];
              $emailDest = $dest["email"];
            }
            break;

          default:
            // Pour tous les autres cas il faut prévenir l'ADV
            break;
        }

        if (isset($emailDest)) {
          $sujet = "Mise à jour du devis n°" . $idDevis . " en cours de validation";
          $message = "Bonjour " . $nomDest . ",<br><br>";
          $message .= "Le devis n°" . $idDevis . " a été mis à jour par " . $Session->_user["prenom"] . " " . $Session->_user["libelle"] . ".<br>";
          $message .= "<a href='https://cleo.unikoffice.com/devis'>Vous pouvez le consulter en cliquant sur ce lien</a><br><br>";
          $message .= "Cordialement,<br>";
          $message .= "Email généré automatiquement par l'application CLEO de gestion des devis";
          eLog("Envoi d'un email à : " . $emailDest . " - Sujet : " . $sujet . " - Message : " . $message);
          envoieMail($emailDest, $sujet, $message);
        }

        if ($fkUserDevis == $fk_user) {
          if ($chkValidat == 0 && $fkUserValidat > 0) {
            //! le devis a été refusé par le DIR-CO ou le DV, et ce devis vient d'être à nouveau modifié par le commercial, on supprime les traces du refus
            $sql = 'UPDATE devis SET fk_user_validat=0, date_validat="", comment_validat="" WHERE rowid=' . $idDevis . ';';
            eLog($sql);
            qSQL($sql, "gen");
          }
        }
        // On enregistre cette info dans le chat du devis
        $sql = 'INSERT INTO devis_histo SET fk_devis=' . $idDevis . ', fk_user=' . $fk_user . ', date_histo="' . date("Y-m-d H:i:s") . '", commentaire="Mise à jour du devis";';
        eLog($sql);
        qSQL($sql, "gen");

        // On check la nouveauté du devis
        $sql = 'UPDATE devis SET chk_maj=1 WHERE rowid=' . $idDevis . ';';
        eLog($sql);
        qSQL($sql, "gen");
      }

      if (strlen($commentDevis) > 0) {
        //! on enregistre le commentaire dans la table devis_histo (table historique des commentaires des devis pour le chat)
        $sql = 'SELECT dh.commentaire FROM devis_histo dh WHERE dh.fk_devis=' . $idDevis . ' AND chk_comment_devis_pro=1;';
        $res = getinfos($sql, "gen");
        if (count($res) == 1) {
          //! on met à jour le commentaire
          $sql = 'UPDATE devis_histo SET commentaire="' . $commentDevis . '", date_histo="' . date("Y-m-d H:i:s") . '", fk_user=' . $fk_user . ' ';
          $sql .= 'WHERE fk_devis=' . $idDevis . ' AND chk_comment_devis_pro=1;';
          eLog($sql);
          qSQL($sql, "gen");
        } else {
          //! on insère le commentaire
          $sql = 'INSERT INTO devis_histo (fk_devis, fk_user, date_histo, commentaire, chk_comment_devis_pro) VALUES (' . $idDevis . ', ' . $fk_user . ', "' . date("Y-m-d H:i:s") . '", "' . $commentDevis . '", 1);';
          eLog($sql);
          qSQL($sql, "gen");
        }
      } else {
        // Si le commentaire est vide on supprime un éventuel commentaire existant
        $sql = 'DELETE FROM devis_histo WHERE fk_devis = ' . $idDevis . ' AND chk_comment_devis_pro = 1;';
        eLog($sql);
        qSQL($sql, "gen");
      }

      // on met à jour la session avec le rowid de ce dernier devis créé ou mis à jour
      $_SESSION["lastDevis"] = $idDevis;

      $upls = array("ret" => "ok", "rid" => $idDevis, "totalremht" => $totalRemHT, "totalmarge" => $totalMarge);
      echo json_encode($upls);
    } else {
      $upls = array("ret" => "ko", "rid" => 0, "totalremht" => 0);
      echo json_encode($upls);
    }
    break;

  case "validat_devis":
    // Validation ou refus du devis par le DV ou le DIR-CO
    $data = json_decode(file_get_contents("php://input"));
    if (isset($data->cid)) {
      $idDevis = nettoie_input($data->cid);
      $chk_validat = nettoie_input($data->chk_validat);
      $commentaire = nettoie_input($data->commentaire);

      $sql = 'UPDATE devis SET comment_validat="' . $commentaire . '", chk_validat=' . $chk_validat . ', date_validat="' . date("Y-m-d H:i:s") . '", fk_user_validat=' . $fk_user . ' WHERE rowid=' . $idDevis . ';';
      eLog($sql);
      qSQL($sql, "gen");

      $comment_histo = $chk_validat == 1 ? "Devis validé : " : "Devis refusé : ";
      $comment_histo .= $commentaire;
      $sql = 'INSERT INTO devis_histo SET fk_devis=' . $idDevis . ', fk_user=' . $fk_user . ', date_histo="' . date("Y-m-d H:i:s") . '", commentaire="' . $comment_histo . '";';
      eLog($sql);
      qSQL($sql, "gen");

      if ($chk_validat == 1) {
        // On change le statut du devis pour le mettre directement en Traitement SAP : 4
        $sql = 'UPDATE devis SET fk_statut_devis=4 WHERE rowid=' . $idDevis . ';';
        eLog($sql);
        qSQL($sql, "gen");
      }

      // On envoie un email au responsable du devis pour le prévenir que son devis a été validé ou refusé
      $sql = 'SELECT d.fk_user, u.email, u.libelle, u.prenom, u.fk_role, u.fk_parent FROM users u LEFT JOIN devis d ON d.fk_user=u.rowid WHERE d.rowid=' . $idDevis . ';';
      $res = getinfos($sql, "gen");
      if (count($res) == 1) {
        $respDevis = $res[0];
        $email = $respDevis["email"];
        $nom = $respDevis["prenom"] . " " . $res[0]["libelle"];
        $sujet = $chk_validat == 1 ? "Devis validé" : "Devis refusé";
        $etat = $chk_validat == 1 ? "validé" : "refusé";
        $message = "Bonjour " . $nom . ",<br><br>";
        $message .= "Votre devis n°" . $idDevis . " a été " . $etat . " par " . $Session->_user["prenom"] . " " . $Session->_user["libelle"] . ".<br>";
        $message .= "<a href='https://cleo.unikoffice.com/devis'>Vous pouvez le consulter en cliquant sur ce lien</a><br><br>";
        $message .= "Cordialement,<br>";
        $message .= "Email généré automatiquement par l'application CLEO de gestion des devis";
        eLog("Envoi d'un email au responsable du devis : " . $email . " - Sujet : " . $sujet . " - Message : " . $message);
        envoieMail($email, $sujet, $message);

        // On vérifie que le responsable de ce devis est bien un RR Commercial, si c'est le cas il faut aussi envoyer un email à son DV
        if ($respDevis["fk_role"] == 3) {
          $sql = 'SELECT u.email, u.libelle, u.prenom FROM users u WHERE u.rowid=' . $respDevis["fk_parent"] . ';';
          $res = getinfos($sql, "gen");
          $dv = $res[0];
          $email = $dv["email"];
          $nomDV = $dv["prenom"] . " " . $dv["libelle"];
          $message = "Bonjour " . $nomDV . ",<br><br>";
          $message .= "Le devis n°" . $idDevis . " de " . $nom . " a été " . $etat . " par " . $Session->_user["prenom"] . " " . $Session->_user["libelle"] . ".<br>";
          $message .= "<a href='https://cleo.unikoffice.com/devis'>Vous pouvez le consulter en cliquant sur ce lien</a><br><br>";
          $message .= "Cordialement,<br>";
          $message .= "Email généré automatiquement par l'application CLEO de gestion des devis";
          eLog("Envoi d'un email au DV : " . $email . " - Sujet : " . $sujet . " - Message : " . $message);
          envoieMail($email, $sujet, $message);
        }
      }
    }
    break;

  case "statut_devis":
    $data = json_decode(file_get_contents("php://input"));
    if (isset($data->cid)) {
      $idDevis = nettoie_input($data->cid);
      $statut = nettoie_input($data->statut);
      $commentaire = nettoie_input($data->commentaire);

      eLog("statut_devis : idDevis = " . $idDevis . ", statut = " . $statut . ", commentaire = " . $commentaire);
      $sql = 'UPDATE devis SET fk_statut_devis=' . $statut . ', date_modif="' . date("Y-m-d H:i:s") . '", fk_user_modif=' . $fk_user . ' WHERE rowid=' . $idDevis . ';';
      eLog($sql);
      qSQL($sql, "gen");

      $sql = 'INSERT INTO devis_histo SET fk_devis=' . $idDevis . ', fk_statut_devis=' . $statut . ', fk_user=' . $fk_user . ', date_histo="' . date("Y-m-d H:i:s") . '", commentaire="' . $commentaire . '";';
      eLog($sql);
      qSQL($sql, "gen");

      elog("statut_devis : Ensuite on envoie un email suivant son statut : " . $statut);
      switch ($statut) {
        case 2:
          // Le devis part en Validation DIR-CO, on envoie un email au DIR-CO
          // 1. On récupère les infos du DIR-CO
          // Si c'est un DV qui envoie le devis, on utilise son fk_parent
          if ($fkRole == 2) {
            $sql = 'SELECT u.email, u.prenom, u.libelle, u.rowid 
            FROM users u 
            WHERE u.rowid = (SELECT fk_parent FROM users WHERE rowid = ' . intval($fk_user) . ') 
            AND u.fk_role = 1 AND u.active = 1';
          }
          // Si c'est un RR, on remonte à travers son DV pour trouver le DC
          else if ($fkRole == 3) {
            $sql = 'SELECT u.email, u.prenom, u.libelle, u.rowid 
            FROM users u 
            WHERE u.rowid = (SELECT fk_parent FROM users WHERE rowid = (SELECT fk_parent FROM users WHERE rowid = ' . intval($fk_user) . ')) 
            AND u.fk_role = 1 AND u.active = 1';
          }
          // Si c'est une autre personne, on cherche juste le premier DC actif
          else {
            $sql = 'SELECT u.email, u.prenom, u.libelle, u.rowid 
            FROM users u 
            WHERE u.fk_role = 1 AND u.fk_region=18 AND u.active = 1 LIMIT 1';
          }
          $dest = getinfos($sql, "gen");

          if (count($dest) == 1) {
            $to = $dest[0]["email"];
            $nom = $dest[0]["prenom"] . " " . $dest[0]["libelle"];

            // 2. On récupère les infos du devis
            $idDevisSafe = intval($idDevis);
            $sql = 'SELECT d.rowid, d.montant_total_ht_remise, d.fk_client, d.lib_new_client, d.cp_new_client, d.ville_new_client, u.prenom, u.libelle FROM devis d LEFT JOIN users u ON d.fk_user=u.rowid WHERE d.rowid=' . $idDevisSafe . ';';
            $devis = getinfos($sql, "gen");
            if (count($devis) == 1) {
              $montant = $devis[0]["montant_total_ht_remise"];
              $idClient = $devis[0]["fk_client"];
              $nomClient = "";
              $nomRR = $devis[0]["prenom"] . " " . $devis[0]["libelle"];
              if ($idClient == 0) {
                $nomClient = $devis[0]["lib_new_client"] . ", (" . $devis[0]["cp_new_client"] . " - " . $devis[0]["ville_new_client"] . ")";
              } else {
                $idClientSafe = intval($idClient);
                $sql = 'SELECT c.libelle, c.cp, c.ville FROM clients c WHERE c.rowid=' . $idClientSafe . ';';
                $client = getinfos($sql, "gen");
                if (count($client) == 1) {
                  $nomClient = $client[0]["libelle"] . " (" . $client[0]["cp"] . " - " . $client[0]["ville"] . ")";
                }
              }

              $sujet = "Nouveau devis à valider";
              $message = "Bonjour " . $nom . ",<br/><a href='https://cleo.unikoffice.com'>Un nouveau devis est à valider.</a><br/><br/>";
              $message .= "Devis n°" . $idDevis . " de " . $nomRR . "<br/>";
              $message .= "Client : " . $nomClient . "<br/>";
              $message .= "Montant HT avec remise : " . $montant . "€.<br/><br/>";
              $message .= "Cordialement.<br/>";
              $message .= "Email généré automatiquement par l'application CLEO de gestion des devis";
              envoieMail($to, $sujet, $message);
              eLog("Mail envoyé à " . $to . " pour le devis " . $idDevis . " de " . $nomRR . " en statut " . $statut);
            }
          }
          break;

        case 3:
          // Le devis part en Validation DV, on envoie un email au DV
          // 1. On récupère les infos du DV responsable de ce RR

          elog("statut_devis : on est dans le cas 3 envoi à son DV");
          $fkRole = $Session->_user["fk_role"];
          $fkParent = $Session->_user["fk_parent"];

          eLog("statut_devis : fkRole=" . $fkRole . ", fkParent=" . $fkParent);
          if ($fkRole == 3) {
            // c'est un RR donc on peut envoyer à son DV
            if ($fkParent > 0) {
              $fkParentSafe = intval($fkParent);
              $sql = 'SELECT u.email, u.prenom, u.libelle FROM users u WHERE u.fk_role=2 AND u.rowid=' . $fkParentSafe . ' AND u.active=1;';
              eLog("statut_devis : sql=" . $sql);
              $dest = getinfos($sql, "gen");
            } else {
              // c'est un RR sans DV, on envoie au 1er DV trouvé
              $sql = 'SELECT u.email, u.prenom, u.libelle FROM users u WHERE u.fk_role=2 AND u.active=1 LIMIT 1;';
              $dest = getinfos($sql, "gen");
            }

            if (count($dest) == 1) {
              $to = $dest[0]["email"];
              $nom = $dest[0]["prenom"] . " " . $dest[0]["libelle"];
              eLog("Envoi mail à " . $to . " pour le devis " . $idDevis . " de " . $nom);
              // 2. On récupère les infos du devis
              $idDevisSafe = intval($idDevis);
            $sql = 'SELECT d.rowid, d.montant_total_ht_remise, d.fk_client, d.lib_new_client, d.cp_new_client, d.ville_new_client, u.prenom, u.libelle FROM devis d LEFT JOIN users u ON d.fk_user=u.rowid WHERE d.rowid=' . $idDevisSafe . ';';
              $devis = getinfos($sql, "gen");
              if (count($devis) == 1) {
                $montant = $devis[0]["montant_total_ht_remise"];
                $idClient = $devis[0]["fk_client"];
                $nomRR = $devis[0]["prenom"] . " " . $devis[0]["libelle"];
                if ($idClient == 0) {
                  $nomClient = $devis[0]["lib_new_client"] . ", (" . $devis[0]["cp_new_client"] . " - " . $devis[0]["ville_new_client"] . ")";
                } else {
                  $idClientSafe = intval($idClient);
                $sql = 'SELECT c.libelle, c.cp, c.ville FROM clients c WHERE c.rowid=' . $idClientSafe . ';';
                  $client = getinfos($sql, "gen");
                  if (count($client) == 1) {
                    $nomClient = $client[0]["libelle"] . " (" . $client[0]["cp"] . " - " . $client[0]["ville"] . ")";
                  }
                }

                $sujet = "Nouveau devis à valider";
                $message = "Bonjour " . $nom . ",<br/><a href='https://cleo.unikoffice.com'>Un nouveau devis est à valider.</a><br/><br/>";
                $message .= "Devis n°" . $idDevis . " de " . $nomRR . "<br/>";
                $message .= "Client : " . $nomClient . "<br/>";
                $message .= "Montant HT avec remise : " . $montant . "€.<br/><br/>";
                $message .= "Cordialement.<br/>";
                $message .= "Email généré automatiquement par l'application CLEO de gestion des devis";
                envoieMail($to, $sujet, $message);
                eLog("Mail envoyé à " . $to . " pour le devis " . $idDevis . " de " . $nomRR . " en statut " . $statut);
              }
            }
          }
          break;

        case 4:
          $statut = "Refusé";
          break;
        case 5:
          $statut = "Annulé";
          break;
        default:
          $statut = "Inconnu";
          break;
      }


      // on met à jour la session avec le rowid de ce dernier devis créé ou mis à jour
      $_SESSION["lastDevis"] = $idDevis;

      echo json_encode(array("ret" => "ok"));
    }
    break;

  case "valide_devis":
    $data = json_decode(file_get_contents("php://input"));
    if (isset($data->cid)) {
      $idDevis = nettoie_input($data->cid);
      $comment = nettoie_input($data->comment);

      eLog("valide_devis : idDevis = " . $idDevis . ", commentaire = " . $comment);
      $idDevisSafe = intval($idDevis);
      $fkUserSafe = intval($fk_user);
      $sql = 'UPDATE devis SET fk_statut_devis=4, date_modif="' . date("Y-m-d H:i:s") . '", fk_user_modif=' . $fkUserSafe . ' WHERE rowid=' . $idDevisSafe . ';';
      eLog($sql);
      qSQL($sql, "gen");

      $sql = 'INSERT INTO devis_histo SET fk_devis=' . $idDevis . ', fk_statut_devis=4, fk_user=' . $fk_user . ', date_histo="' . date("Y-m-d H:i:s") . '", commentaire="' . $comment . '";';
      eLog($sql);
      qSQL($sql, "gen");

      // on met à jour la session avec le rowid de ce dernier devis créé ou mis à jour
      $_SESSION["lastDevis"] = $idDevis;

      echo json_encode(array("success" => "true", "message" => "Devis validé avec succès"));
    }
    break;

  case "refuse_devis":
    $data = json_decode(file_get_contents("php://input"));
    if (isset($data->cid)) {
      $idDevis = nettoie_input($data->cid);
      $comment = nettoie_input($data->comment);

      eLog("refuse_devis : idDevis = " . $idDevis . ", commentaire = " . $comment);
      $sql = 'INSERT INTO devis_histo SET fk_devis=' . $idDevis . ', fk_user=' . $fk_user . ', date_histo="' . date("Y-m-d H:i:s") . '", commentaire="' . $comment . '";';
      eLog($sql);
      qSQL($sql, "gen");

      // on met à jour la session avec le rowid de ce dernier devis créé ou mis à jour
      $_SESSION["lastDevis"] = $idDevis;

      echo json_encode(array("success" => "true", "message" => "Devis refusé avec succès"));
    }
    break;

  case "save_new_client":
    $data = json_decode(file_get_contents("php://input"));
    if (isset($data->libelle)) {
      try {
        $db = Database::getInstance();

        $libelle = nettoie_input($data->libelle);
        $typeClient = nettoie_input($data->type_client);
        $adresse1 = nettoie_input($data->adresse1);
        $adresse2 = nettoie_input($data->adresse2);
        $adresse3 = nettoie_input($data->adresse3);
        $cp = nettoie_input($data->cp);
        if (strlen($cp) == 4) $cp = "0" . $cp;
        $ville = nettoie_input($data->ville);
        $fkUserSafe = intval($fk_user);

        $sqlMaxCode = 'SELECT MAX(code) as max_code FROM clients';
        $resultCode = $db->fetchOne($sqlMaxCode);
        $newCode = ($resultCode && $resultCode['max_code']) ? intval($resultCode['max_code']) + 1 : 1;

        $sql = 'INSERT INTO clients SET code = :code, libelle = :libelle, type_client = :type_client, adresse1 = :adresse1, adresse2 = :adresse2, adresse3 = :adresse3, ';
        $sql .= 'cp = :cp, ville = :ville, fk_user_creat = :fk_user_creat, date_creat = NOW(), active = 1';

        $params = [
          ':code' => $newCode,
          ':libelle' => $libelle,
          ':type_client' => $typeClient,
          ':adresse1' => $adresse1,
          ':adresse2' => $adresse2,
          ':adresse3' => $adresse3,
          ':cp' => $cp,
          ':ville' => $ville,
          ':fk_user_creat' => $fkUserSafe
        ];

        $db->query($sql, $params);
        $newClientId = $db->lastInsertId();

        if ($newClientId > 0) {
          $sql = 'INSERT INTO clients_contacts SET fk_client = :fk_client, nom = :nom, prenom = :prenom, principal = 1, active = 1, date_creat = NOW()';

          $params = [
            ':fk_client' => $newCode,
            ':nom' => 'À compléter',
            ':prenom' => ''
          ];

          $db->query($sql, $params);

          eLog("Nouveau client créé : ID=" . $newClientId . ", code=" . $newCode);
          echo json_encode(array("success" => true, "rowid" => $newClientId, "code" => $newCode, "message" => "Client créé avec succès"));
        } else {
          eLog("save_new_client ERREUR: newClientId = 0");
          echo json_encode(array("success" => false, "message" => "Erreur lors de la création du client - ID non récupéré"));
        }
      } catch (Exception $e) {
        $errorMsg = $e->getMessage();
        error_log("Erreur création client : " . $errorMsg);
        eLog("save_new_client EXCEPTION: " . $errorMsg);
        echo json_encode(array("success" => false, "message" => "Erreur : " . $errorMsg));
      }
    }
    break;

  case "search_devis":
    eLog("=== search_devis case appelé ===");
    $rawData = file_get_contents("php://input");
    eLog("Raw data: " . $rawData);
    $data = json_decode($rawData);
    eLog("Data decoded: " . print_r($data, true));
    eLog("isset term: " . (isset($data->term) ? 'YES' : 'NO'));

    if (isset($data->term)) {
      $term = nettoie_input($data->term);
      $context = nettoie_input($data->context);

      if (strlen($term) < 3) {
        echo json_encode(array("success" => false, "message" => "Le terme de recherche doit contenir au moins 3 caractères"));
        break;
      }

      $termSafe = '%' . $term . '%';

      $whereParams = [];
      switch ($fk_role) {
        case 1:
          $whereRole = 'd.fk_user = :fkUser OR d.fk_statut_devis >= 2';
          $whereParams[':fkUser'] = $fk_user;
          break;
        case 2:
          try {
            $db = Database::getInstance();
            $sql = 'SELECT rowid FROM users WHERE fk_parent = :fkParent';
            $aRR = $db->fetchAll($sql, [':fkParent' => $fk_user]);

            $rrIds = array_column($aRR, 'rowid');
            if (!empty($rrIds)) {
              $placeholders = [];
              foreach ($rrIds as $index => $id) {
                $placeholder = ':rr' . $index;
                $placeholders[] = $placeholder;
                $whereParams[$placeholder] = $id;
              }
              $whereRole = 'd.fk_user = :fkUser OR (d.fk_statut_devis >= 3 AND d.fk_user IN (' . implode(',', $placeholders) . '))';
              $whereParams[':fkUser'] = $fk_user;
            } else {
              $whereRole = 'd.fk_user = :fkUser';
              $whereParams[':fkUser'] = $fk_user;
            }
          } catch (Exception $e) {
            error_log("Erreur récupération RR : " . $e->getMessage());
            $whereRole = 'd.fk_user = :fkUser';
            $whereParams[':fkUser'] = $fk_user;
          }
          break;
        default:
          $whereRole = 'd.fk_user = :fkUser';
          $whereParams[':fkUser'] = $fk_user;
          break;
      }

      if ($context === "archives") {
        $whereStatut = ' AND d.fk_statut_devis = 20';
      } else {
        $whereStatut = ' AND d.fk_statut_devis != 20';
      }

      $whereParams[':term1'] = $termSafe;
      $whereParams[':term2'] = $termSafe;
      $whereParams[':term3'] = $termSafe;
      $whereParams[':term4'] = $termSafe;
      $whereParams[':term5'] = $termSafe;
      $whereParams[':term6'] = $termSafe;
      $whereParams[':term7'] = $termSafe;
      $whereParams[':term8'] = $termSafe;
      $whereParams[':term9'] = $termSafe;
      $whereParams[':term10'] = $termSafe;
      $whereParams[':term11'] = $termSafe;
      $whereParams[':term12'] = $termSafe;
      $whereParams[':term13'] = $termSafe;
      $whereParams[':term14'] = $termSafe;
      $whereParams[':term15'] = $termSafe;
      $whereParams[':term16'] = $termSafe;
      $whereParams[':term17'] = $termSafe;

      try {
        $db = Database::getInstance();
        $sql = 'SELECT DISTINCT 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 ';
        $sql .= 'LEFT JOIN clients c ON c.rowid=d.fk_client ';
        $sql .= 'LEFT JOIN x_statuts_devis xs ON xs.rowid=d.fk_statut_devis ';
        $sql .= 'LEFT JOIN marches m ON m.rowid=d.fk_marche ';
        $sql .= 'LEFT JOIN users u ON u.rowid=d.fk_user ';
        $sql .= 'LEFT JOIN clients_contacts ct ON ct.fk_client=d.fk_client ';
        $sql .= 'WHERE (' . $whereRole . ')' . $whereStatut . ' AND (';
        $sql .= 'd.rowid LIKE :term1 OR ';
        $sql .= 'c.libelle LIKE :term2 OR ';
        $sql .= 'c.adresse1 LIKE :term3 OR ';
        $sql .= 'c.adresse2 LIKE :term4 OR ';
        $sql .= 'c.adresse3 LIKE :term5 OR ';
        $sql .= 'c.cp LIKE :term6 OR ';
        $sql .= 'c.ville LIKE :term7 OR ';
        $sql .= 'm.libelle LIKE :term8 OR ';
        $sql .= 'd.num_opportunite LIKE :term9 OR ';
        $sql .= 'd.lib_new_client LIKE :term10 OR ';
        $sql .= 'd.cp_new_client LIKE :term11 OR ';
        $sql .= 'd.ville_new_client LIKE :term12 OR ';
        $sql .= 'ct.nom LIKE :term13 OR ';
        $sql .= 'ct.prenom LIKE :term14 OR ';
        $sql .= 'ct.fonction LIKE :term15 OR ';
        $sql .= 'ct.email LIKE :term16 OR ';
        $sql .= 'd.commentaire LIKE :term17) ';
        $sql .= 'ORDER BY d.dossier, d.date_remise DESC';

        eLog("=== SEARCH DEVIS DEBUG ===");
        eLog("Terme recherché: " . $term);
        eLog("Context: " . $context);
        eLog("SQL: " . $sql);
        eLog("Params: " . print_r($whereParams, true));

        $pdo = $db->getPDO();
        $stmt = $pdo->prepare($sql);
        $stmt->execute($whereParams);
        $devis = $stmt->fetchAll(PDO::FETCH_ASSOC);

        eLog("Nombre de devis trouvés: " . count($devis));

        $nb_devis = array();
        foreach ($devis as $dev) {
          if (!isset($nb_devis[$dev["fk_statut_devis"]])) {
            $nb_devis[$dev["fk_statut_devis"]] = 1;
          } else {
            $nb_devis[$dev["fk_statut_devis"]]++;
          }
        }

        $dossiers = array();
        foreach ($devis as $dev) {
          if (!in_array($dev["dossier"], array_column($dossiers, 'dossier'))) {
            $dossiers[] = array("dossier" => $dev["dossier"]);
          }
        }

        echo json_encode(array(
          "success" => true,
          "devis" => $devis,
          "nb_devis" => $nb_devis,
          "dossiers" => $dossiers
        ));
      } catch (Exception $e) {
        error_log("Erreur recherche devis : " . $e->getMessage());
        echo json_encode(array("success" => false, "message" => "Erreur lors de la recherche : " . $e->getMessage()));
      }
    }
    break;

  case "search_devis_sap":
    eLog("=== search_devis_sap case appelé ===");
    $rawData = file_get_contents("php://input");
    eLog("Raw data: " . $rawData);
    $data = json_decode($rawData);
    eLog("Data decoded: " . print_r($data, true));
    eLog("isset term: " . (isset($data->term) ? 'YES' : 'NO'));

    if (isset($data->term)) {
      $term = nettoie_input($data->term);
      $context = nettoie_input($data->context);

      if (strlen($term) < 3) {
        echo json_encode(array("success" => false, "message" => "Le terme de recherche doit contenir au moins 3 caractères"));
        break;
      }

      $termSafe = '%' . $term . '%';

      $whereParams = [];
      $whereRole = '1=1';

      if ($context === "archives") {
        $whereStatut = ' AND d.fk_statut_devis = 20';
      } else {
        $whereStatut = ' AND d.fk_statut_devis != 20';
      }

      $whereParams[':term1'] = $termSafe;
      $whereParams[':term2'] = $termSafe;
      $whereParams[':term3'] = $termSafe;
      $whereParams[':term4'] = $termSafe;
      $whereParams[':term5'] = $termSafe;
      $whereParams[':term6'] = $termSafe;
      $whereParams[':term7'] = $termSafe;
      $whereParams[':term8'] = $termSafe;
      $whereParams[':term9'] = $termSafe;
      $whereParams[':term10'] = $termSafe;
      $whereParams[':term11'] = $termSafe;
      $whereParams[':term12'] = $termSafe;
      $whereParams[':term13'] = $termSafe;
      $whereParams[':term14'] = $termSafe;
      $whereParams[':term15'] = $termSafe;
      $whereParams[':term16'] = $termSafe;
      $whereParams[':term17'] = $termSafe;

      try {
        $db = Database::getInstance();
        $sql = 'SELECT DISTINCT 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, c.code ';
        $sql .= 'FROM devis d ';
        $sql .= 'LEFT JOIN clients c ON c.rowid=d.fk_client ';
        $sql .= 'LEFT JOIN x_statuts_devis xs ON xs.rowid=d.fk_statut_devis ';
        $sql .= 'LEFT JOIN marches m ON m.rowid=d.fk_marche ';
        $sql .= 'LEFT JOIN users u ON u.rowid=d.fk_user ';
        $sql .= 'LEFT JOIN clients_contacts ct ON ct.fk_client=d.fk_client ';
        $sql .= 'WHERE (' . $whereRole . ')' . $whereStatut . ' AND (';
        $sql .= 'd.rowid LIKE :term1 OR ';
        $sql .= 'c.libelle LIKE :term2 OR ';
        $sql .= 'c.adresse1 LIKE :term3 OR ';
        $sql .= 'c.adresse2 LIKE :term4 OR ';
        $sql .= 'c.adresse3 LIKE :term5 OR ';
        $sql .= 'c.cp LIKE :term6 OR ';
        $sql .= 'c.ville LIKE :term7 OR ';
        $sql .= 'c.code LIKE :term8 OR ';
        $sql .= 'm.libelle LIKE :term9 OR ';
        $sql .= 'd.num_opportunite LIKE :term10 OR ';
        $sql .= 'd.lib_new_client LIKE :term11 OR ';
        $sql .= 'd.cp_new_client LIKE :term12 OR ';
        $sql .= 'd.ville_new_client LIKE :term13 OR ';
        $sql .= 'ct.nom LIKE :term14 OR ';
        $sql .= 'ct.prenom LIKE :term15 OR ';
        $sql .= 'ct.fonction LIKE :term16 OR ';
        $sql .= 'ct.email LIKE :term17) ';
        $sql .= 'ORDER BY d.dossier, d.date_remise DESC';

        eLog("=== SEARCH DEVIS SAP DEBUG ===");
        eLog("Terme recherché: " . $term);
        eLog("Context: " . $context);
        eLog("SQL: " . $sql);
        eLog("Params: " . print_r($whereParams, true));

        $pdo = $db->getPDO();
        $stmt = $pdo->prepare($sql);
        $stmt->execute($whereParams);
        $devis = $stmt->fetchAll(PDO::FETCH_ASSOC);

        eLog("Nombre de devis trouvés: " . count($devis));

        $nb_devis = array();
        foreach ($devis as $dev) {
          if (!isset($nb_devis[$dev["fk_statut_devis"]])) {
            $nb_devis[$dev["fk_statut_devis"]] = 1;
          } else {
            $nb_devis[$dev["fk_statut_devis"]]++;
          }
        }

        $dossiers = array();
        foreach ($devis as $dev) {
          if (!in_array($dev["dossier"], array_column($dossiers, 'dossier'))) {
            $dossiers[] = array("dossier" => $dev["dossier"]);
          }
        }

        echo json_encode(array(
          "success" => true,
          "devis" => $devis,
          "nb_devis" => $nb_devis,
          "dossiers" => $dossiers
        ));
      } catch (Exception $e) {
        error_log("Erreur recherche devis SAP : " . $e->getMessage());
        echo json_encode(array("success" => false, "message" => "Erreur lors de la recherche : " . $e->getMessage()));
      }
    }
    break;
}
exit();
