// jsap.js // Déclaration des variables globales let idDevisEnCours = 0; let idDevisArchives = 0; let panel = "enCours"; let fkUser = 0; let oldColorLnEnCours = ""; let oldColorLnArchives = ""; let oldIdLnEnCours; let oldIdLnArchives; let nbCommentChat = 0; window.addEventListener('DOMContentLoaded', (event) => { console.log('#'); // Initialisation des éléments utilisés let elCelDevisEnCours = document.getElementsByClassName("celEnCours"); let elCelDevisArchives = document.getElementsByClassName("celArchives"); let elBtnViewDevisEnCours = document.getElementsByClassName("btnViewDevisEnCours"); let elBtnValideDevis = document.getElementById("btnValideDevis"); let elBtnRefuseDevis = document.getElementById("btnRefuseDevis"); let elBtnViewDevisArchives = document.getElementsByClassName("btnViewDevisArchives"); let elChatBtnSendEnCours = document.getElementById("chatBtnSendEnCours"); // Par défaut, on n'affiche pas les chats document.getElementById("chat-container-enCours").style.display = "none"; document.getElementById("chat-container-archives").style.display = "none"; //! On récupère les données contextuelles propres à l'utilisateur fetch('/jxpost/get_context', { method: 'POST', headers: { 'Content-Type': 'application/json;charset=utf-8', 'Accept': 'application/json;charset=utf-8', } }).then((response) => { const ret = response.json(); ret.then(function (data) { const user = data.user; fkUser = user.rowid; const session = data.session; }); }); //! Si on clique sur l'onglet "En cours", met à jour le panel $('a[data-toggle="tab"]').on('show.bs.tab', function (e) { if ($(this).attr('href') == "#tabEnCours") { panel = "enCours"; } else if ($(this).attr('href') == "#tabArchives") { panel = "archives"; } console.log('panel: ' + panel); }); // Fonctions let clickLigDevisEnCours = function () { panel = "enCours"; //! On ne fait rien si l'utilisateur clique sur le même devis if (this.getAttribute("data-rid") != idDevisEnCours) { idDevisEnCours = this.getAttribute("data-rid"); //! On met enfin en évidence la ligne cliquée Array.from(elCelDevisEnCours).forEach(function (ligDevis) { if (ligDevis.getAttribute("data-rid") == oldIdLnEnCours) { ligDevis.style.backgroundColor = oldColorLnEnCours; } else if (ligDevis.getAttribute("data-rid") == idDevisEnCours) { oldColorLnEnCours = ligDevis.style.backgroundColor; ligDevis.style.backgroundColor = "#9bbce7"; } }); oldIdLnEnCours = idDevisEnCours; console.log('idDevisEnCours: ' + idDevisEnCours); refreshChat(); } }; let clickViewDevis = function () { if (panel == "enCours") { idDevisEnCours = this.getAttribute("data-rid"); } else { idDevisArchives = this.getAttribute("data-rid"); } const idDevis = (panel == "enCours") ? idDevisEnCours : idDevisArchives; showLoading(); // on charge les infos de l'en-tête du devis fetch('/jxdevis/load_devis', { method: 'POST', body: JSON.stringify({cid: idDevis}), headers: { 'Content-Type': 'application/json;charset=utf-8', 'Accept': 'application/json;charset=utf-8', } }) .then((response) => { if (!response.ok) { showNotification("Erreur", "Le chargement des infos de l'en-tête de ce devis n'a pas abouti", "error"); } else { const ret = response.json(); ret.then(function (data) { fkUser = data[0].fk_user; idMarche = data[0].fk_marche; chkClientsSecteur = data[0].chk_clients_secteur; chkSpeciaux = data[0].chk_speciaux == "1" ? true : false; if (chkSpeciaux) { document.getElementById("panSpeciaux").classList.remove("hidden"); } else { document.getElementById("panSpeciaux").classList.add("hidden"); } showDevisEnTete(data); showDevisTotaux(data); }).then(function () { //! Une fois le marché trouvé, on charge les infos du marché préchargé dans l'en-tête du devis fetch('/jxdevis/load_devis_marche_infos', { method: 'POST', body: JSON.stringify({cid: idMarche}), headers: { 'Content-Type': 'application/json;charset=utf-8', 'Accept': 'application/json;charset=utf-8', } }) .then((response) => { if (!response.ok) { showNotification("Erreur", "Le chargement des infos du marché n'a pas abouti", "error"); } else { const ret = response.json(); //! Boucle sur le résultat de la requête ajax ret.then(function (data) { showDevisMarcheInfos(data); }); } }); if (chkSpeciaux) { //! On charge les infos des produits spéciaux fetch('/jxdevis/load_devis_speciaux', { method: 'POST', body: JSON.stringify({cid: idDevis}), headers: { 'Content-Type': 'application/json;charset=utf-8', 'Accept': 'application/json;charset=utf-8', } }) .then((response) => { if (!response.ok) { showNotification("Erreur", "Le chargement des produits spéciaux de ce devis n'a pas abouti", "error"); } else { const retSpeciaux = response.json(); retSpeciaux.then(function (dataSpeciaux) { // on vide les 5 lignes de produits spéciaux pour éviter de reprendre des données d'un autre devis for (i = 1; i <= 5; i++) { document.getElementById('inp_specialCode_' + i).value = ""; document.getElementById('inp_specialLibe_' + i).value = ""; document.getElementById('inp_specialQte_' + i).value = ""; document.getElementById('inp_specialCout_' + i).value = ""; document.getElementById('inp_chk_specialEchantillon_' + i).checked = false; document.getElementById('inp_specialDate_' + i).value = ""; document.getElementById('inp_specialConcurrent_' + i).value = ""; document.getElementById('inp_specialDescription_' + i).value = ""; } if (dataSpeciaux.length > 0) { // on a trouvé une ligne dans la table devis_speciaux const data = dataSpeciaux[0]; console.log("on a trouvé une ligne dans la table devis_speciaux"); console.log(data); // on charge les données dans le formulaire if (data.chk_livr_multi == "1") { document.getElementById("inp_chk_livr_multi").checked = true; } else { document.getElementById("inp_chk_livr_multi").checked = false; } document.getElementById('inp_nb_livr').value = data.nb_livr; document.getElementById('inp_date_livr_1').value = data.date_livr_1; for (i = 1; i <= 5; i++) { document.getElementById('inp_specialCode_' + i).value = data[`code_produit_${i}`]; document.getElementById('inp_specialLibe_' + i).value = data[`lib_produit_${i}`]; document.getElementById('inp_specialQte_' + i).value = data[`qte_${i}`]; document.getElementById('inp_specialCout_' + i).value = data[`surcout_${i}`]; if (data[`chk_echantillon_${i}`] == "1") { document.getElementById('inp_chk_specialEchantillon_' + i).checked = true; } else { document.getElementById('inp_chk_specialEchantillon_' + i).checked = false; } if (data[`date_echantillon_${i}`] != "0000-00-00") { document.getElementById('inp_specialDate_' + i).value = data[`date_echantillon_${i}`]; } document.getElementById('inp_specialConcurrent_' + i).value = data[`lib_concurrent_${i}`]; document.getElementById('inp_specialDescription_' + i).value = data[`description_${i}`]; } } else { // on n'a pas trouvé de ligne dans la table devis_speciaux console.log("on n'a pas trouvé de ligne dans la table devis_speciaux"); // on vide les champs du formulaire document.getElementById('inp_idDevis_speciaux').value = idDevis; document.getElementById("frmSpeciaux").reset(); } }); } }); } }); } }) .catch((error) => { showNotification("Erreur", "Le chargement des infos de l'en-tête de ce devis n'a pas abouti", "error"); }); // on charge les produits enregistrés pour ce devis dans 2 tableaux distincts tblProduitsSelect (2ème onglet) et tblDevisPro (3ème onglet) fetch('/jxdevis/load_devis_produits', { method: 'POST', body: JSON.stringify({cid: idDevis}), headers: { 'Content-Type': 'application/json;charset=utf-8', 'Accept': 'application/json;charset=utf-8', } }) .then((response) => { if (!response.ok) { showNotification("Erreur", "Le chargement des produits de ce devis n'a pas abouti", "error"); } else { const ret = response.json(); //! Boucle sur le résultat de la requête ajax ret.then(function (data) { showDevisProduits(data); }); } }); hideLoading(); if (panel == "enCours") { //! On ne fait rien si l'utilisateur clique sur le même devis if (this.getAttribute("data-rid") != idDevisEnCours) { idDevisEnCours = this.getAttribute("data-rid"); //! On met enfin en évidence la ligne cliquée Array.from(elCelDevisEnCours).forEach(function (ligDevis) { if (ligDevis.getAttribute("data-rid") == oldIdLnEnCours) { ligDevis.style.backgroundColor = oldColorLnEnCours; } else if (ligDevis.getAttribute("data-rid") == idDevisEnCours) { oldColorLnEnCours = ligDevis.style.backgroundColor; ligDevis.style.backgroundColor = "#9bbce7"; } }); oldIdLnEnCours = idDevisEnCours; console.log('idDevisEnCours: ' + idDevisEnCours); } // On affiche les bouton de refus, de validation et le commentaire document.getElementById("btnRefuseDevis").style.display = "inline-block"; document.getElementById("btnValideDevis").style.display = "inline-block"; document.getElementById("labelComment").style.display = "inline-block"; document.getElementById("inpComment").style.display = "inline-block"; } else { //! On ne fait rien si l'utilisateur clique sur le même devis if (this.getAttribute("data-rid") != idDevisArchives) { idDevisArchives = this.getAttribute("data-rid"); //! On met enfin en évidence la ligne cliquée Array.from(elCelDevisArchives).forEach(function (ligDevis) { if (ligDevis.getAttribute("data-rid") == oldIdLnArchives) { ligDevis.style.backgroundColor = oldColorLnArchives; } else if (ligDevis.getAttribute("data-rid") == idDevisArchives) { oldColorLnArchives = ligDevis.style.backgroundColor; ligDevis.style.backgroundColor = "#9bbce7"; } }); oldIdLnArchives = idDevisArchives; console.log('idDevisArchives: ' + idDevisArchives); } // On cache les bouton de refus, de validation et le commentaire document.getElementById("btnRefuseDevis").style.display = "none"; document.getElementById("btnValideDevis").style.display = "none"; document.getElementById("labelComment").style.display = "none"; document.getElementById("inpComment").style.display = "none"; } refreshChat(); document.getElementById("modViewDevisTitre").innerHTML = "Consultation du devis n°" + idDevis; showModal(document.getElementById("modalViewDevis")); } document.getElementById("btnCloseModViewDevis").addEventListener("click", function () { hideModal(document.getElementById("modalViewDevis")); }); function showDevisEnTete(ret) { // Affiche les données de l'en-tête du devis const data = ret[0]; document.getElementById("inp_num_opportunite").value = data.num_opportunite; document.getElementById("inp_date_demande").value = data.date_demande; document.getElementById("inp_date_remise").value = data.date_remise; document.getElementById("inp_lib_client").value = data.libelle; document.getElementById("inp_type_client").value = data.type_client; document.getElementById("inp_adresse1").value = data.adresse1; document.getElementById("inp_adresse2").value = data.adresse2; document.getElementById("inp_adresse3").value = data.adresse3; document.getElementById("inp_cp").value = data.cp; document.getElementById("inp_ville").value = data.ville; document.getElementById("inp_contact_nom").value = data.contact_nom; document.getElementById("inp_contact_prenom").value = data.contact_prenom; document.getElementById("inp_contact_fonction").value = data.contact_fonction; document.getElementById("inp_lib_marche").value = data.lib_marche; if (data.chk_devis_photos == "1") { document.getElementById("inp_chk_devis_photos").checked = true; } else { document.getElementById("inp_chk_devis_photos").checked = false; } document.getElementById("inp_email").value = data.email; document.getElementById("inp_telephone").value = data.telephone; document.getElementById("inp_mobile").value = data.mobile; document.getElementById("inp_commentaire").value = data.commentaire; } function showDevisTotaux(ret) { // Affiche les totaux du devis const data = ret[0]; document.getElementById("inpTotalHT").value = data.montant_total_ht; document.getElementById("inpTotalRemHT").value = data.montant_total_ht_remise; document.getElementById("inpTotalMarge").value = data.marge_totale; } function showDevisMarcheInfos(ret) { // On affiche les infos du marché if (ret.length == 1) { let line = ret[0]; document.getElementById('inp_latitudeRR').value = line.latitude_marge_rr_max; document.getElementById('inp_latitudeDV').value = line.latitude_marge_dv_max; $('#tdTxRemiseTrim').text(line.taux_remise_trimestrielle + " %"); $('#tdTxRemiseSeme').text(line.taux_remise_semestrielle + " %"); $('#tdTxRemiseAnnu').text(line.taux_remise_annuelle + " %"); $('#tdDebutFin').text(convertMySQLDateToFrenchDate(line.date_fin)); $('#tdFrancoPort').text(line.franco_de_port); $('#tdGarantie').text(line.garantie); $('#tdDelaiLivr').text(line.delai_de_livraison); $('#tdRemisesCo').text(line.remises_commerciales); } else { $('#tdTxRemiseTrim').text("-"); $('#tdTxRemiseSeme').text("-"); $('#tdTxRemiseAnnu').text("-"); $('#tdDebutFin').text("-"); $('#tdFrancoPort').text("-"); $('#tdGarantie').text("-"); $('#tdDelaiLivr').text("-"); $('#tdRemisesCo').text("-"); } } function showDevisProduits(ret) { //! On affiche les produits du devis dans le tableau tblDevisPro // On vide son body let tblBodyPro = document.getElementById("tblDevisPro").getElementsByTagName("tbody")[0]; tblBodyPro.innerHTML = ""; if (ret.length > 0) { // au moins un produit trouvé pour ce devis let nbProduits = ret.length; for (let key in ret) { if (ret.hasOwnProperty(key)) { // Récupération des valeurs de la ligne let val = ret[key]; // Insertion d'une nouvelle ligne et création de ses colonnes : on prend ici le rowid de devis_produits let newRowPro = tblBodyPro.insertRow(0); let celCodePro = newRowPro.insertCell(0); celCodePro.innerHTML = val['code']; let celLibellePro = newRowPro.insertCell(1); celLibellePro.innerHTML = val['libelle']; let celPrixVentePro = newRowPro.insertCell(2); celPrixVentePro.className = "text-right"; celPrixVentePro.innerHTML = val['prix_vente'] + " €"; let celQtePro = newRowPro.insertCell(3); celQtePro.innerHTML = ''; let celRemisePro = newRowPro.insertCell(4); celRemisePro.innerHTML = '
%
'; let celHTPro = newRowPro.insertCell(5); celHTPro.innerHTML = '
'; let celVariante = newRowPro.insertCell(6); celVariante.className = "text-center"; celVariante.innerHTML = ''; let celMargePro = newRowPro.insertCell(7); celMargePro.innerHTML = '
%
'; } } } }; let clickLigDevisArchives = function () { panel = "archives"; //! On ne fait rien si l'utilisateur clique sur le même devis if (this.getAttribute("data-rid") != idDevisArchives) { idDevisArchives = this.getAttribute("data-rid"); //! On met enfin en évidence la ligne cliquée Array.from(elCelDevisArchives).forEach(function (ligDevis) { if (ligDevis.getAttribute("data-rid") == oldIdLnArchives) { ligDevis.style.backgroundColor = oldColorLnArchives; } else if (ligDevis.getAttribute("data-rid") == idDevisArchives) { oldColorLnArchives = ligDevis.style.backgroundColor; ligDevis.style.backgroundColor = "#9bbce7"; } }); oldIdLnArchives = idDevisArchives; console.log('idDevisArchives: ' + idDevisArchives); } }; let clickExportDevisEnCours = function () { const idDevis = this.getAttribute("data-rid"); console.log('idDevis: ' + idDevis); const url = "/expxls/export_sap_devis/" + idDevis; window.open(url); panel = "enCours"; return false; }; let clickValideDevis = function () { const commentaire = document.getElementById('inpComment').value; if (commentaire == '') { showNotification('Veuillez saisir un commentaire avant de valider le devis', 'warning'); return false; } if (confirm("Confirmez-vous la validation du devis ?")) { fetch("/jxdevis/valide_devis", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ cid: idDevisEnCours, comment: commentaire }) }); hideModal(document.getElementById("modalViewDevis")); refreshChat(); } }; let clickRefuseDevis = function () { const commentaire = document.getElementById('inpComment').value; if (commentaire == '') { showNotification('Veuillez saisir un commentaire avant de refuser le devis', 'warning'); return false; } if (confirm("Confirmez-vous le refus du devis ?")) { fetch("/jxdevis/refuse_devis", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ cid: idDevisEnCours, comment: commentaire }) }); hideModal(document.getElementById("modalViewDevis")); refreshChat(); } }; function refreshChat() { if ((idDevisEnCours > 0 && panel == "enCours") || (idDevisArchives > 0 && panel == "archives")) { let idDevis = 0; if (panel == "enCours") { idDevis = idDevisEnCours; } else { idDevis = idDevisArchives; } //! On récupère les données de devis_histo fetch('/jxchat/refresh', { method: 'POST', headers: { 'Content-Type': 'application/json;charset=utf-8', 'Accept': 'application/json;charset=utf-8', }, body: JSON.stringify({ cid: idDevis, }) }).then((response) => { const ret = response.json(); ret.then(function (data) { // on vérifie si le nombre de commentaires a changé if (nbCommentChat != data.length) { // Si c'est le cas on rafraîchit tous les commentaires // On supprime tous les commentaires const chatContainer = document.getElementById("chat-bubbles-" + panel); const chatBubbles = chatContainer.getElementsByClassName("chat-bubble"); while (chatBubbles.length > 0) { chatBubbles[0].parentNode.removeChild(chatBubbles[0]); } // On ajoute tous les commentaires for (let i = 0; i < data.length; i++) { const chatBubble = document.createElement("div"); chatBubble.classList.add("chat-bubble"); if (data[i].fk_user == fkUser) { chatBubble.classList.add("right-chat-bubble"); } else { chatBubble.classList.add("left-chat-bubble"); } const initiales = data[i].prenom.substring(0, 1) + data[i].libelle.substring(0, 1); const userInfo = document.createElement("div"); userInfo.classList.add("user-info"); const userInitials = document.createElement("div"); userInitials.classList.add("user-initials"); userInitials.innerHTML = initiales; userInfo.appendChild(userInitials); const usernameDate = document.createElement("div"); usernameDate.classList.add("username-date"); const username = document.createElement("span"); username.classList.add("username"); username.innerHTML = data[i].prenom + " " + data[i].libelle; usernameDate.appendChild(username); const date = document.createElement("span"); date.classList.add("date"); date.innerHTML = data[i].date_histo; usernameDate.appendChild(date); userInfo.appendChild(usernameDate); chatBubble.appendChild(userInfo); const message = document.createElement("div"); message.classList.add("message"); message.innerHTML = data[i].commentaire; chatBubble.appendChild(message); chatContainer.appendChild(chatBubble); } // et on vide le champ de saisie s'il n'a pas le focus if (!document.getElementById("chatInputMessage").hasFocus) { document.getElementById("chatInputMessage").value = ""; } } const chatCont = document.getElementById("chat-container-" + panel); chatCont.style.display = "block"; }); }); console.log('Chat refreshed at ' + new Date()); } } let chatSendMessage = function () { // On récupère le message à envoyer const message = document.getElementById("chatInputMessage").value; // On récupère l'id du devis let idDevis = 0; if (panel == "enCours") { idDevis = idDevisEnCours; } else { idDevis = idDevisArchives; } // On envoie le message fetch('/jxchat/save_message', { method: 'POST', headers: { 'Content-Type': 'application/json;charset=utf-8', 'Accept': 'application/json;charset=utf-8', }, body: JSON.stringify({ cid: idDevis, message: message, fkuser: fkUser, }) }).then((response) => { const ret = response.json(); ret.then(function (data) { refreshChat(); }); }); }; setInterval(refreshChat, 60000); // Refresh every 60 seconds (1000 ms = 1 second) // Initialisation des événements Array.from(elCelDevisEnCours).forEach(function (lnDevis) { lnDevis.addEventListener('click', clickLigDevisEnCours); }); Array.from(elCelDevisArchives).forEach(function (lnDevis) { lnDevis.addEventListener('click', clickLigDevisArchives); }); Array.from(elBtnViewDevisEnCours).forEach(function (viewDevis) { viewDevis.addEventListener('click', clickViewDevis); }); Array.from(elBtnViewDevisArchives).forEach(function (viewDevis) { viewDevis.addEventListener('click', clickViewDevis); }); elChatBtnSendEnCours.addEventListener('click', chatSendMessage); elBtnValideDevis.addEventListener('click', clickValideDevis); elBtnRefuseDevis.addEventListener('click', clickRefuseDevis); });