get_data(); //! où on récupère le fk_tiers sur lequel l'utilisateur travaille if (isset($session_data["tiers"])) { $fk_tiers = $session_data["tiers"]; } else { $fk_tiers = 0; } $fk_user = $Session->_user["rowid"]; eLog("jxpost action : " . $Route->_action); function cleanData(&$str) { // Fonction de nettoyage des données pour l'export Excel if ($str == 't') $str = 'TRUE'; if ($str == 'f') $str = 'FALSE'; if (preg_match("/^0/", $str) || preg_match("/^\+?\d{8,}$/", $str) || preg_match("/^\d{4}.\d{1,2}.\d{1,2}/", $str)) { $str = "'$str"; } if (strstr($str, '"')) $str = '"' . str_replace('"', '""', $str) . '"'; $str = mb_convert_encoding($str, 'UTF-16LE', 'UTF-8'); } function filterData(&$str) { $str = preg_replace("/\t/", "\\t", $str); $str = preg_replace("/\r?\n/", "\\n", $str); if (strstr($str, '"')) $str = '"' . str_replace('"', '""', $str) . '"'; } switch ($Route->_action) { case "filter": $idfilter = $_POST["idfilter"]; switch ($idfilter) { case "filtertiers": $Session->set_data($idfilter . "_search", $_POST["filter_search"]); $Session->set_data($idfilter . "_contact", $_POST["filter_contact"]); $Session->set_data($idfilter . "_ape", $_POST["filter_ape"]); if (isset($_POST["filter_recent"])) { $recent = 1; } else { $recent = 0; } $Session->set_data($idfilter . "_recent", $recent); if (isset($_POST["filter_agenda"])) { $agenda = 1; } else { $agenda = 0; } $Session->set_data($idfilter . "_agenda", $agenda); if (isset($_POST["filter_archive"])) { $archive = 1; } else { $archive = 0; } $Session->set_data($idfilter . "_archive", $archive); $Session->set_data($idfilter . "_type_tiers", $_POST["filter_type_tiers"]); $Session->set_data($idfilter . "_ville", $_POST["filter_villeA"]); //! filter_villeA parce que c'est un autocomplete : retourne le rowid qui est en fait la ville ! break; } break; case "upfind": $tab = $_POST["win"]; $lid = $Route->_param1; if ($Conf::erp) { $sql = 'SELECT * FROM medias WHERE dir2="' . $tab . '" AND support_rowid=' . $lid . ';'; } else { $sql = 'SELECT * FROM medias WHERE support="' . $tab . '" AND support_rowid=' . $lid . ';'; } $upls = array(); $upls = getinfos($sql, "groupe"); echo json_encode($upls); break; case "updelete": updelete($_POST); break; case "upload": if ($Conf::erp) { upload($_POST); } else { upload_old($_POST); } break; case "medias": $user = $Session->_user["rowid"]; $type = $Route->_param1; //! facture par exemple if (isset($_POST["rowid"])) { $rowid = $_POST["rowid"]; //! c'est le rowid de la facture par exemple if ($type == "facture" || $type == "devis") { //! on doit aller chercher le num_facture pour avoir le nom du fichier if ($type == "facture") { $num_facture = getdata("devis", $rowid, "num_facture"); } else { $num_facture = getdata("devis", $rowid, "num_devis"); } $fk_tiers = getdata("devis", $rowid, "fk_soc"); $nom_tiers = str_normalize(getdata("clients", $fk_tiers, "libelle", "groupe")); if ($Conf->_entite["raz_num_devis"]) { $num_facture = substr('000' . $num_facture, -3); } else { $num_facture = substr('0000' . $num_facture, -4); } $support = $fk_tiers; $filename = $fk_tiers . "_" . $type . "_" . $num_facture . ".pdf"; if (isset($_POST["relance"])) { $filename = $fk_tiers . "_" . $type . "_" . $num_facture . "_relance_" . date("Ymd") . ".pdf"; } $typ = "pdf"; $dir0 = "tiers"; $dir1 = $nom_tiers; } else { $support = $type; $filename = $rowid . ".pdf"; $typ = "pdf"; $rep = $type . DS . $rowid . DS . "pdf"; $dir0 = "tiers"; $dir1 = "dir1"; } $dir2 = $type; $des = ""; $pos = "L"; $hau = 0; $lar = 0; //! On vérifie d'abord qu'il n'y ait pas un média existant pour le même support, le même support_rowid et le même nom de fichier : doublon ! $sql = 'SELECT * FROM medias WHERE dir0="' . $dir0 . '" AND dir1="' . $dir1 . '" AND dir2="' . $dir2 . '" AND fichier="' . $filename . '";'; $doublon = getinfos($sql, "groupe"); if (count($doublon) == 0) { //! il n'y a pas de doublon, on peut créer l'enregistrement $sql = 'INSERT INTO medias SET dir0="' . $dir0 . '", dir1="' . $dir1 . '", dir2="' . $dir2 . '", support_rowid=' . $rowid . ', fichier="' . $filename . '", fk_user_creat=' . $user . ', '; $sql .= 'type_fichier="' . $typ . '", date_creat="' . date("Y-m-d H:i:s") . '", description="' . $des . '", position="' . $pos . '", hauteur=' . $hau . ', largeur=' . $lar . ';'; } else { //! l'enregistrement existe déjà : on met à jour date_modif et fk_user_modif $sql = 'UPDATE medias SET date_modif="' . date("Y-m-d H:i:s") . '", fk_user_modif=' . $user . ' WHERE dir0="' . $dir0 . '" AND dir1="' . $dir1 . '" AND dir2="' . $dir2 . '" AND fichier="' . $filename . '";'; } eLog("jxpost medias : " . $sql); qSQL($sql, "groupe"); } break; case "refresh": $win = $Route->_param1; if ($win != "") { if (isset($_POST["input"])) { $input = $_POST["input"]; switch ($win) { case "winaction": //! un refresh dans la fenêtre modale winaction if ($input == "fk_contact") { $sql = "SELECT rowid, CONCAT(firstname, ' ', name) AS libelle FROM contacts WHERE fk_soc=" . $fk_tiers . " ORDER BY libelle;"; $res = qSQL($sql, "groupe"); $arr = array(); if ($res instanceof PDOStatement) { while ($rec = $res->fetch(PDO::FETCH_ASSOC)) { $arr[] = $rec; } } $jsonresult = json_encode($arr); $lignes = $jsonresult; echo $lignes; } break; } } } break; case "mediafind": $tab = $_POST["win"]; $lid = $Route->_param1; if ($Conf::erp) { $sql = 'SELECT * FROM medias WHERE dir2="' . $tab . '" AND support_rowid=' . $lid . ';'; } else { $sql = 'SELECT * FROM medias WHERE support="' . $tab . '" AND support_rowid=' . $lid . ';'; } $upls = array(); $upls = getinfos($sql, "groupe"); $upls = $upls[0]; echo json_encode($upls); break; case "getdata": $chp = $_POST["chp"]; $typ = $Route->_param1; $upls = array(); switch ($typ) { case "tiers": // SÉCURITÉ : Liste blanche des colonnes autorisées $allowedColumns = ['code', 'libelle', 'adresse1', 'adresse2', 'adresse3', 'cp', 'ville', 'contact_nom', 'contact_prenom', 'contact_fonction', 'telephone', 'mobile', 'email']; if (!in_array($chp, $allowedColumns)) { echo json_encode(array('error' => 'Colonne non autorisée')); break; } try { $db = Database::getInstance(); // SÉCURITÉ : Utilisation de requête préparée pour l'ID $sql = "SELECT `$chp` AS data FROM clients WHERE rowid = :id"; $result = $db->fetchOne($sql, [':id' => intval($fk_tiers)]); if ($result) { $upls = $result; } } catch (Exception $e) { error_log("Erreur getdata : " . $e->getMessage()); } break; } echo json_encode($upls); break; case "setsession": if (isset($_POST["key"]) && isset($_POST["val"])) { $Session->set_data($_POST["key"], $_POST["val"]); } break; // case "autocomplete" supprimé car non utilisé dans l'application // L'autocomplétion est gérée côté client JavaScript case "get_context": //! Renvoie le contexte de l'utilisateur $ajson = array(); $ajson["user"] = $Session->_user; $ajson["session"] = $Session->get_data(); $ajson["devip"] = $Conf->_devIp ? "1" : "0"; echo json_encode($ajson); break; case "load_client": //! Charge les infos d'un client //! Réception et lecture de la demande en json $data = json_decode(file_get_contents("php://input")); if (isset($data->cid)) { // SÉCURITÉ : Validation de l'ID et requête préparée $cid = intval($data->cid); if ($cid <= 0) { echo json_encode(array('error' => 'ID client invalide')); break; } try { $db = Database::getInstance(); $result = $db->getById('clients', $cid); echo json_encode($result ?: array()); } catch (Exception $e) { error_log("Erreur load_client : " . $e->getMessage()); echo json_encode(array('error' => 'Erreur lors du chargement du client')); } } else { echo json_encode(array('error' => 'Pas de client spécifié')); } break; case "search_clients": //! Cherche les clients correspondant à un libellé, une adresse, un code postal, une ville, un nom, un prénom, une fonction ou un email //! Réception et lecture de la demande en json $data = json_decode(file_get_contents("php://input")); if (isset($data->search)) { // SÉCURITÉ : Utilisation de requêtes préparées pour la recherche $search = trim($data->search); try { $db = Database::getInstance(); $sql = 'SELECT c.rowid, c.libelle, c.type_client, c.adresse1, c.cp, c.ville FROM clients c WHERE c.libelle LIKE :search OR c.adresse1 LIKE :search OR c.cp LIKE :search OR c.ville LIKE :search OR c.contact_nom LIKE :search OR c.contact_prenom LIKE :search OR c.contact_fonction LIKE :search OR c.email LIKE :search ORDER BY c.libelle'; $searchParam = '%' . $search . '%'; $results = $db->fetchAll($sql, [':search' => $searchParam]); echo json_encode($results); } catch (Exception $e) { error_log("Erreur search_clients : " . $e->getMessage()); echo json_encode(array('error' => 'Erreur lors de la recherche')); } } else { echo json_encode(array('ret' => "ko")); } break; case "load_marches": //! charge des infos de tous les marchés $sql = 'SELECT m.rowid, m.libelle FROM marches m ORDER BY m.libelle DESC;'; echo getinfos($sql, "gen", "json"); break; case "load_marche": //! Charge les infos d'un marché //! Réception et lecture de la demande en json $data = json_decode(file_get_contents("php://input")); if (isset($data->cid)) { $cid = nettoie_input($data->cid); $sql = 'SELECT m.* FROM marches m WHERE m.rowid=' . $cid . ';'; echo getinfos($sql, "gen", "json"); } else { $ret = array('ret' => "ko"); echo json_encode($ret); } break; case "search_produits": //! Cherche les produits correspondant à un code ou à un libellé //! Réception et lecture de la demande en json $data = json_decode(file_get_contents("php://input")); if (isset($data->search)) { $search = nettoie_input($data->search); $sql = 'SELECT p.*, pf.famille FROM produits p LEFT JOIN produits_familles pf ON p.fk_famille_produit=pf.rowid '; $sql .= 'WHERE (p.code LIKE "%' . $search . '%" OR p.libelle LIKE "%' . $search . '%" OR p.groupe LIKE "%' . $search . '%" OR pf.famille LIKE "%' . $search . '%") AND p.prix_vente>0 AND p.active=1 '; $sql .= 'ORDER BY p.libelle;'; echo getinfos($sql, "gen", "json"); } else { $ret = array('ret' => "ko"); echo json_encode($ret); } break; case "load_familles": //! Charge les familles de produits existantes $sql = 'SELECT xf.* FROM x_familles xf ORDER BY xf.ordre;'; echo getinfos($sql, "gen", "json"); break; case "load_familles_groupes": //! Charge les familles par groupes de produits existantes $sql = 'SELECT pf.* FROM produits_familles pf ORDER BY pf.ordre, pf.groupe;'; echo getinfos($sql, "gen", "json"); break; case "save_familles": //! Réception et lecture de la demande en json $data = json_decode(file_get_contents("php://input")); //! on récupère les familles existantes $sql = 'SELECT pf.rowid FROM produits_familles pf ORDER BY pf.rowid;'; $pf = getinfos($sql, "gen"); //! on les désactive toutes $sql = 'UPDATE produits_familles SET active=0;'; qSQL($sql); //! on boucle sur les familles reçues foreach ($data as $row) { $rowid = nettoie_input($row->id); $set = 'groupe="' . nettoie_input(trim($row->groupe)) . '", '; $set .= 'ordre="' . nettoie_input(trim($row->ordre)) . '", '; $set .= 'fk_famille="' . nettoie_input(trim($row->famille)) . '", '; $set .= 'code_maintenance="' . nettoie_input(trim($row->maintenance)) . '", '; $set .= 'marge_rr="' . nettoie_input(trim($row->margerr)) . '", '; $set .= 'marge_dv="' . nettoie_input(trim($row->margedv)) . '", '; $set .= 'active=1 '; //! on recherche si la famille existe déjà $found = false; foreach ($pf as $p) { if ($p["rowid"] == $rowid) { $found = true; break; } } if (!$found) { //! Si la famille n'existe pas, on la crée $sql = 'INSERT INTO produits_familles SET ' . $set . ';'; } else { //! Sinon on la met à jour $sql = 'UPDATE produits_familles SET ' . $set . ' '; $sql .= 'WHERE rowid=' . $rowid . ';'; } eLog($sql); qSQL($sql, "gen"); } //! enfin, on supprime toutes les familles qui n'ont pas été reçues, active=0 $sql = 'DELETE FROM produits_familles WHERE active=0;'; eLog($sql); qSQL($sql, "gen"); $ret = array('ret' => "ok", 'msg' => "Enregistrement des familles effectué"); echo json_encode($ret); break; case "save_marche": //! Réception et lecture de la demande en json $data = json_decode(file_get_contents("php://input")); if (isset($data->rowid)) { $cid = nettoie_input($data->rowid); $act = nettoie_input($data->act); $set = 'SET libelle="' . nettoie_input(trim($data->libelle)) . '"'; $set .= ', numero="' . nettoie_input($data->numero) . '"'; $set .= ', nom="' . nettoie_input($data->nom) . '"'; $set .= isset($data->chk_remise_sur_tg) ? ', chk_remise_sur_tg=1' : ', chk_remise_sur_tg=0'; $set .= isset($data->chk_prix_nets) ? ', chk_prix_nets=1' : ', chk_prix_nets=0'; $set .= isset($data->chk_marche_public) ? ', chk_marche_public=1' : ', chk_marche_public=0'; if ($data->taux_remise_trimestrielle == "") { $set .= ', taux_remise_trimestrielle=0'; } else { $set .= ', taux_remise_trimestrielle=' . $data->taux_remise_trimestrielle; } if ($data->taux_remise_semestrielle == "") { $set .= ', taux_remise_semestrielle=0'; } else { $set .= ', taux_remise_semestrielle=' . $data->taux_remise_semestrielle; } if ($data->taux_remise_annuelle == "") { $set .= ', taux_remise_annuelle=0'; } else { $set .= ', taux_remise_annuelle=' . $data->taux_remise_annuelle; } $set .= ', date_debut="' . d6GetDate($data->date_debut, "FM") . '"'; $set .= ', date_fin="' . d6GetDate($data->date_fin, "FM") . '"'; $set .= ', date_validite_prix="' . d6GetDate($data->date_validite_prix, "FM") . '"'; $set .= ', franco_de_port="' . nettoie_input(trim($data->franco_de_port)) . '"'; $set .= ', garantie="' . nettoie_input(trim($data->garantie)) . '"'; $set .= ', delai_de_livraison="' . nettoie_input(trim($data->delai_de_livraison)) . '"'; $set .= ', remises_commerciales="' . nettoie_input(trim($data->remises_commerciales)) . '"'; if ($data->remise_palier_1 == "") { $set .= ', remise_palier_1=0'; } else { $set .= ', remise_palier_1=' . $data->remise_palier_1; } if ($data->remise_taux_1 == "") { $set .= ', remise_taux_1=0'; } else { $set .= ', remise_taux_1=' . $data->remise_taux_1; } if ($data->remise_palier_2 == "") { $set .= ', remise_palier_2=0'; } else { $set .= ', remise_palier_2=' . $data->remise_palier_2; } if ($data->remise_taux_2 == "") { $set .= ', remise_taux_2=0'; } else { $set .= ', remise_taux_2=' . $data->remise_taux_2; } if ($data->remise_palier_3 == "") { $set .= ', remise_palier_3=0'; } else { $set .= ', remise_palier_3=' . $data->remise_palier_3; } if ($data->remise_taux_3 == "") { $set .= ', remise_taux_3=0'; } else { $set .= ', remise_taux_3=' . $data->remise_taux_3; } if ($data->remise_palier_4 == "") { $set .= ', remise_palier_4=0'; } else { $set .= ', remise_palier_4=' . $data->remise_palier_4; } if ($data->remise_taux_4 == "") { $set .= ', remise_taux_4=0'; } else { $set .= ', remise_taux_4=' . $data->remise_taux_4; } $set .= ', commentaire="' . nettoie_input(trim($data->commentaire)) . '"'; $set .= isset($data->chk_cache_commerciaux) ? ', chk_cache_commerciaux=1' : ', chk_cache_commerciaux=0'; $set .= isset($data->chk_marche_hybride) ? ', chk_marche_hybride=1' : ', chk_marche_hybride=0'; $set .= isset($data->chk_regle_seuils_marge) ? ', chk_regle_seuils_marge=1' : ', chk_regle_seuils_marge=0'; $set .= isset($data->active) ? ', active=1' : ', active=0'; if ($cid == 0) { $set .= ', date_creat = "' . date("Y-m-d H:i:s") . '", fk_user_creat=' . $fk_user; $sql = 'INSERT INTO marches ' . $set . ';'; } else { $set .= ', date_modif = "' . date("Y-m-d H:i:s") . '", fk_user_modif=' . $fk_user; $sql = 'UPDATE marches ' . $set . ' WHERE rowid=' . $cid . ';'; } eLog($sql); qSQL($sql, "gen"); $ret = array('ret' => "ok"); echo json_encode($ret); } else { $ret = array('ret' => "ko"); echo json_encode($ret); } break; case "delete_marche": //! Supprime un marché //! Réception de l'id du marché à supprimer $data = json_decode(file_get_contents("php://input")); if (isset($data->cid)) { // SÉCURITÉ : Validation de l'ID comme entier $cid = intval($data->cid); if ($cid <= 0) { echo json_encode(array('ret' => "ko", 'msg' => 'ID invalide')); break; } try { $db = Database::getInstance(); // Utilisation de requêtes préparées pour la suppression $sql1 = 'DELETE FROM marches WHERE rowid = :id'; $db->query($sql1, ['id' => $cid]); $sql2 = 'DELETE FROM marches_listes WHERE fk_marche = :id'; $db->query($sql2, ['id' => $cid]); $sql3 = 'DELETE FROM produits WHERE fk_marche = :id'; $db->query($sql3, ['id' => $cid]); eLog("Marché supprimé : ID=$cid"); $ret = array('ret' => "ok", 'msg' => 'Marché supprimé'); echo json_encode($ret); } catch (Exception $e) { eLog("Erreur suppression marché : " . $e->getMessage()); echo json_encode(array('ret' => "ko", 'msg' => 'Erreur lors de la suppression')); } } else { $ret = array('ret' => "ko", 'msg' => 'Marché non supprimé'); echo json_encode($ret); } break; case "save_marches_listes": //! Enregistre les mises à jour du tableau des listes tarifaires par marché //! Réception du tableau des mots clés par marché en json $data = json_decode(file_get_contents("php://input")); if (isset($data->idListe)) { if ($data->idListe == "1") { foreach ($data as $key => $val) { if (substr($key, 0, 7) == "motcle_") { $fk_marche = trim(substr($key, 7)); $motCle = trim($val); $motCleAchat = ""; $motCleVente = ""; foreach ($data as $keyAV => $valAV) { if ($keyAV == "motcleachat_" . $fk_marche) { $motCleAchat = trim($valAV); } else { if ($keyAV == "motclevente_" . $fk_marche) { $motCleVente = trim($valAV); } } } $sql = 'SELECT l.rowid FROM marches_listes l WHERE l.fk_marche=' . $fk_marche . ';'; $retour = getinfos($sql, "gen"); if (count($retour) > 0) { $sql = 'UPDATE marches_listes SET mot_cle="' . $motCle . '", terme_achat="' . $motCleAchat . '", terme_vente="' . $motCleVente . '" WHERE fk_marche=' . $fk_marche . ';'; qSQL($sql, "gen"); } else { $sql = 'INSERT INTO marches_listes SET fk_marche=' . $fk_marche . ', mot_cle="' . $motCle . '", terme_achat="' . $motCleAchat . '", terme_vente="' . $motCleVente . '";'; qSQL($sql, "gen"); } } } $ret = array('ret' => "ok", "msg" => "Enregistrement des données effectué"); echo json_encode($ret); } else { $ret = array('ret' => "ko", "msg" => "Erreur lors de la réception des données à enregistrer"); echo json_encode($ret); } } else { $ret = array('ret' => "ko", "msg" => "Erreur lors de la réception des données à enregistrer"); echo json_encode($ret); } break; case "load_produits_marche": //! Charge les produits d'un marché $data = json_decode(file_get_contents("php://input")); if (isset($data->cid)) { $cid = nettoie_input($data->cid); // On récupère certaines infos du marché pour savoir si on doit appliquer des filtres $sql = 'SELECT m.chk_remise_sur_tg FROM marches m WHERE m.rowid=' . $cid . ';'; $retour = getinfos($sql, "gen"); $chk_remise_sur_tg = $retour[0]["chk_remise_sur_tg"]; if ($cid == 999 || $chk_remise_sur_tg == 1) { // c'est directement le TG, on ne fait rien de spécial $sql = 'SELECT p.rowid, p.code, p.libelle, concat(p.code, " # ", p.libelle) as rech, p.groupe, p.prix_achat_net, p.prix_vente, p.prc_discount_1 '; $sql .= 'FROM produits p WHERE p.fk_marche=' . $cid . ' AND p.active=1 ORDER BY p.code DESC;'; echo getinfos($sql, "gen", "json"); } else { // On regarde le terme_achat du marché $sql = 'SELECT l.terme_achat FROM marches_listes l WHERE l.fk_marche=' . $cid . ';'; $retour = getinfos($sql, "gen"); $terme_achat = $retour[0]["terme_achat"]; if ($terme_achat == "Purchasing") { // On doit alors récupérer leur prix d'achat dans le marché TG $sql = 'SELECT p.rowid, p.code, p.libelle, concat(p.code, " # ", p.libelle) as rech, p.groupe, p.prix_achat_net, p.prix_vente, p.prc_discount_1 '; $sql .= 'FROM produits p WHERE p.fk_marche=' . $cid . ' AND p.active=1 ORDER BY p.code DESC;'; $retour = getinfos($sql, "gen"); if (count($retour) > 0) { foreach ($retour as &$prod) { $sql = 'SELECT p.prix_achat_net, p.prc_discount_1 FROM produits p WHERE p.fk_marche=999 AND p.code="' . $prod["code"] . '";'; $retour2 = getinfos($sql, "gen"); if (count($retour2) == 1) { $prod["prix_achat_net"] = $retour2[0]["prix_achat_net"]; $prod["prc_discount_1"] = $retour2[0]["prc_discount_1"]; } } } echo json_encode($retour); } else { $sql = 'SELECT p.rowid, p.code, p.libelle, concat(p.code, " # ", p.libelle) as rech, p.groupe, p.prix_achat_net, p.prix_vente, p.prc_discount_1 '; $sql .= 'FROM produits p WHERE p.fk_marche=' . $cid . ' AND p.active=1 ORDER BY p.code DESC;'; echo getinfos($sql, "gen", "json"); } } } else { $ret = array("ret" => "ko", "msg" => "Erreur lors de l'envoi du marché à charger"); echo json_encode($ret); } break; case "load_marches_listes": //! Charge la liste des mots clés des marchés à retrouver dans les fichiers d'importation $sql = 'SELECT l.* FROM marches_listes l;'; echo getinfos($sql, "gen", "json"); break; case "load_user": $data = json_decode(file_get_contents("php://input")); if (isset($data->cid)) { $cid = nettoie_input($data->cid); $sql = 'SELECT u.* FROM users u WHERE u.rowid=' . $cid . ';'; echo getinfos($sql, "gen", "json"); } else { $ret = array("ret" => "ko", "msg" => "Erreur lors de la récupération des infos de l'utilisateur"); echo json_encode($ret); } break; case "save_user": //! Réception et lecture de la demande en json $data = json_decode(file_get_contents("php://input")); if (isset($data->rowid)) { $cid = nettoie_input($data->rowid); $act = nettoie_input($data->act); $set = 'SET libelle="' . nettoie_input(trim($data->libelle)) . '"'; $set .= ', prenom="' . nettoie_input(trim($data->prenom)) . '"'; $set .= ', mobile="' . nettoie_input(trim($data->mobile)) . '"'; $set .= ', email="' . nettoie_input(trim($data->email)) . '"'; $set .= ', username="' . nettoie_input(trim($data->username)) . '"'; $set .= ', fk_role=' . nettoie_input(trim($data->fk_role)); $set .= ', fk_region=' . nettoie_input(trim($data->fk_region)); if (isset($data->fk_parent)) { $set .= ', fk_parent=' . nettoie_input(trim($data->fk_parent)); } else { $set .= ', fk_parent=0'; } $set .= ', lst_depts="' . nettoie_input(trim($data->lst_depts)) . '"'; $set .= isset($data->chk_grands_comptes) ? ', chk_grands_comptes=1' : ', chk_grands_comptes=0'; $set .= isset($data->active) ? ', active=1' : ', active=0'; if ($cid == 0) { // on lui crée un mot de passe par défaut : initiale prénom en majuscule + initiale nom Maj + 3 caractères suivants du nom en minuscules + . + mois + année // On supprime les espaces dans le nom de l'utilisateur et on ne garde que les 3 premiers caractères $libUser = str_replace(" ", "", nettoie_input(trim($data->libelle))); $pwd = strtoupper(substr(nettoie_input(trim($data->prenom)), 0, 1)) . strtoupper(substr($libUser, 0, 1)) . strtolower(substr($libUser, 1, 3)) . "." . date("mY"); eLog($pwd); $set .= ', userpswd="' . hashPsswd($pwd) . '"'; $set .= ', date_creat = "' . date("Y-m-d H:i:s") . '", fk_user_creat=' . $fk_user; $sql = 'INSERT INTO users ' . $set . ';'; } else { $set .= ', date_modif = "' . date("Y-m-d H:i:s") . '", fk_user_modif=' . $fk_user; $sql = 'UPDATE users ' . $set . ' WHERE rowid=' . $cid . ';'; } eLog($sql); qSQL($sql, "gen"); $ret = array('ret' => "ok"); echo json_encode($ret); } else { $ret = array('ret' => "ko"); echo json_encode($ret); } break; case "delete_user": //! Réception et lecture de la demande en json $data = json_decode(file_get_contents("php://input")); if (isset($data->cid)) { // SÉCURITÉ : Validation de l'ID comme entier $cid = intval($data->cid); if ($cid <= 0) { echo json_encode(array('ret' => "ko", 'msg' => 'ID invalide')); break; } try { $db = Database::getInstance(); // TODO : Supprimer les devis créés par cet utilisateur // Utilisation de la fonction sécurisée deleteById $result = $db->deleteById('users', $cid); if ($result) { eLog("Utilisateur supprimé : ID=$cid"); echo json_encode(array('ret' => "ok")); } else { echo json_encode(array('ret' => "ko", 'msg' => 'Utilisateur non trouvé')); } } catch (Exception $e) { eLog("Erreur suppression utilisateur : " . $e->getMessage()); echo json_encode(array('ret' => "ko", 'msg' => 'Erreur lors de la suppression')); } } else { echo json_encode(array('ret' => "ko", 'msg' => 'ID manquant')); } break; case "maintenance": if ($Conf->_devIp) { // Mise à jour des mots de passe Utilisateurs $sql = 'SELECT u.rowid, u.prenom, u.libelle FROM users u WHERE u.active=1 AND u.rowid=39;'; $users = getinfos($sql, "gen"); foreach ($users as $user) { $uId = $user["rowid"]; $libUser = str_replace(" ", "", nettoie_input(trim($user["libelle"]))); $pwd = strtoupper(substr(nettoie_input(trim($user["prenom"])), 0, 1)) . strtoupper(substr($libUser, 0, 1)) . strtolower(substr($libUser, 1, 3)) . "." . date("mY"); eLog($pwd); $sql = 'UPDATE users SET userpswd="' . hashPsswd($pwd) . '" WHERE rowid=' . $uId . ';'; eLog($sql); qSQL($sql, "gen"); } } break; case "load_roles": $sql = 'SELECT xro.rowid, xro.libelle FROM x_roles xro WHERE xro.active=1 ORDER BY xro.rowid;'; echo getinfos($sql, "gen", "json"); break; case "load_regions": $sql = 'SELECT xre.rowid, xre.libelle FROM x_regions xre WHERE xre.active=1 ORDER BY xre.rowid;'; echo getinfos($sql, "gen", "json"); break; case "export_sap_devis": $data = json_decode(file_get_contents("php://input")); eLog("export_sap_devis: "); if (isset($data->cid)) { $cid = nettoie_input($data->cid); $sql = 'SELECT d.* FROM devis d WHERE d.rowid=' . $cid . ';'; $dev = getinfos($sql, "gen"); $devis = $dev[0]; eLog("export_sap_devis: " . $cid . " & " . $devis["fk_client"]); $filename = "devis_" . $cid . "_" . date('Y_m_d_hi') . ".csv"; $fields = array("Code", "Etablissement", "Adresse 1", "Adresse 2"); // SÉCURITÉ : Utilisation de requête préparée pour l'ID client try { $db = Database::getInstance(); $sql = 'SELECT c.code, c.libelle, c.adresse1, c.adresse2 FROM clients c WHERE c.rowid = :id'; $client = $db->fetchOne($sql, [':id' => intval($devis["fk_client"])]); if (!$client) { $client = ['code' => '', 'libelle' => '', 'adresse1' => '', 'adresse2' => '']; } } catch (Exception $e) { error_log("Erreur export_sap_devis : " . $e->getMessage()); $client = ['code' => '', 'libelle' => '', 'adresse1' => '', 'adresse2' => '']; } $excelData = implode("\t", array_values($fields)) . "\n"; eLog($excelData); array_walk($client, 'filterData'); $excelData .= implode("\t", array_values($client)) . "\n"; $sql = 'SELECT p.code, p.libelle, p.prix_achat_net, p.prix_vente, dp.qte, dp.remise, dp.totalht FROM devis_produits dp LEFT JOIN produits p ON dp.fk_produit=p.rowid WHERE dp.fk_devis=' . $cid . ';'; eLog($sql); $data = getinfos($sql, "gen"); // une ligne vierge de séparation $excelData .= "\n"; $fields = array("Code", "Désignation", "Prix Achat", "Prix Vente", "Quantité", "Remise", "Total HT"); $excelData .= implode("\t", array_values($fields)) . "\n"; foreach ($data as $row) { array_walk($row, 'filterData'); $excelData .= implode("\t", $row) . "\n"; } eLog($excelData); header("Content-Type: application/vnd.ms-excel; charset=UTF-16LE"); header("Content-Disposition: attachment; filename=$filename"); header("Content-Disposition: attachment; filename=\"$filename\""); echo $excelData; exit; } break; case "load_info": $data = json_decode(file_get_contents("php://input")); if (isset($data->cid)) { $cid = nettoie_input($data->cid); $sql = 'SELECT i.* FROM infos i WHERE i.rowid=' . $cid . ';'; echo getinfos($sql, "gen", "json"); } break; case "save_info": //! Réception et lecture de la demande en json $data = json_decode(file_get_contents("php://input")); if (isset($data->cid)) { $cid = nettoie_input($data->cid); $set = 'SET date_infos="' . nettoie_input($data->cdate) . '" '; $set .= ', titre_infos="' . nettoie_input(trim($data->ctitre)) . '" '; $set .= ', text_infos="' . nettoie_input(trim($data->ctexte)) . '" '; if (isset($data->cpublie)) { if ($data->cpublie == false || $data->cpublie == 0) { $set .= ', chk_publie=0'; } else { $set .= ', chk_publie=1'; } } else { $set .= ', chk_publie=0'; } if ($cid == 0) { $set .= ', date_creat = "' . date("Y-m-d H:i:s") . '", fk_user_creat=' . $fk_user; $sql = 'INSERT INTO infos ' . $set . ';'; } else { $set .= ', date_modif = "' . date("Y-m-d H:i:s") . '", fk_user_modif=' . $fk_user; $sql = 'UPDATE infos ' . $set . ' WHERE rowid=' . $cid . ';'; } eLog($sql); qSQL($sql, "gen"); $ret = array('ret' => "ok"); echo json_encode($ret); } else { $ret = array('ret' => "ko"); echo json_encode($ret); } break; case "supp_info": //! Réception et lecture de la demande en json $data = json_decode(file_get_contents("php://input")); if (isset($data->cid)) { // SÉCURITÉ : Validation de l'ID comme entier $cid = intval($data->cid); if ($cid <= 0) { echo json_encode(array('ret' => "ko", 'msg' => 'ID invalide')); break; } try { $db = Database::getInstance(); $sql = 'DELETE FROM infos WHERE rowid = :id'; $stmt = $db->query($sql, ['id' => $cid]); $result = $stmt->rowCount() > 0; if ($result) { eLog("Info supprimée : ID=$cid"); echo json_encode(array('ret' => "ok")); } else { echo json_encode(array('ret' => "ko", 'msg' => 'Info non trouvée')); } } catch (Exception $e) { eLog("Erreur suppression info : " . $e->getMessage()); echo json_encode(array('ret' => "ko", 'msg' => 'Erreur lors de la suppression')); } } break; } exit();