Files
Cleo/pub/res/js/jmarches.js
Pierre 99021b4f42 Initial commit: CLEO ERP avec améliorations debug
- Configuration du debug conditionnel pour dev/recette
- Fonction debug() globale avec niveaux
- Logging des requêtes SQL
- Handlers d'exceptions et d'erreurs globaux

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-04 10:24:52 +02:00

847 lines
37 KiB
JavaScript

//! jmarches.js
let idMarche;
let libMarche;
let oldColorLn;
let oldIdLn;
let idNewFamille = 999999; // Pour les familles ajoutées, un rowid qui commence à 999999
window.addEventListener('load', function () {
const pageWidth = document.documentElement.scrollWidth;
var pageHeight = Math.max(document.body.scrollHeight, document.body.offsetHeight,
document.documentElement.clientHeight, document.documentElement.scrollHeight,
document.documentElement.offsetHeight);
console.log("pageHeight: " + pageHeight + " pageWidth: " + pageWidth);
// On adapte la hauteur des modales XL en fonction de la hauteur de la page
// document.querySelector('.modal-xl').style.height = (pageHeight * 0.7) + 'px important!';
// document.querySelector('.modal-xl').style.width = (pageWidth * 0.8) + 'px important!';
});
window.addEventListener('DOMContentLoaded', (event) => {
console.log('#');
// Initialisation des éléments utilisés
let elLigMarches = document.getElementsByClassName("ligMarche");
let elCelMarches = document.getElementsByClassName("celMarche");
let elBtnCreateMarche = document.getElementById("btnCreateMarche");
let elBtnModMarches = document.getElementsByClassName("btnModMarche");
let elBtnCancelModMarche = document.getElementById("btnCancelModMarche");
let elBtnSubmitModMarche = document.getElementById("btnSubmitModMarche");
let elBtnSuppMarches = document.getElementsByClassName("btnSuppMarche");
let elBtnImportProduits = document.getElementById("btnImportProduits");
let elBtnCancelImportMarche = document.getElementById("btnCancelImportMarche");
let elBtnSubmitImportMarche = document.getElementById("btnSubmitImportMarche");
let elBtnGestionListes = document.getElementById("btnGestionListes");
let elBtnCancelListes = document.getElementById("btnCancelListes");
let elBtnSubmitListes = document.getElementById("btnSubmitListes");
let elBtnFamilles = document.getElementById("btnFamilles");
let elBtnCancelFamilles = document.getElementById("btnCancelFamilles");
let elBtnSubmitFamilles = document.getElementById("btnSubmitFamilles");
let elBtnAddFamille = document.getElementById("btnAddFamille");
let clickLigMarche = function () {
//! Event Click sur une cellule d'une ligne d'un marché qui a la classe celMarches
idMarche = this.getAttribute("data-rowid");
libMarche = this.getAttribute("data-libelle");
showLoading();
Array.from(elCelMarches).forEach(function (lngMarche) {
if (lngMarche.getAttribute("data-rowid") == oldIdLn) {
lngMarche.style.backgroundColor = oldColorLn;
} else if (lngMarche.getAttribute("data-rowid") == idMarche) {
oldColorLn = lngMarche.style.backgroundColor;
lngMarche.style.backgroundColor = "#9bbce7";
}
});
oldIdLn = idMarche;
// effectue la requête ajax fetch pour charger les produits du marché
fetch('/jxpost/load_produits_marche',
{
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 produits de ce marché n'a pas pu s'effectuer", "error");
} else {
const ret = response.json();
//! Boucle sur le résultat de la requête ajax
ret.then(function (ret) {
showProduits(ret);
});
}
})
.catch((error) => {
console.error('Error:', error);
showNotification("Erreur", "Le chargement des produits de ce marché n'a pas pu s'effectuer", "error");
});
hideLoading();
return false;
};
let clickCreateMarche = function () {
//! Event Click sur le bouton de création d'un marché
//! on reset les champs du formulaire
form = document.getElementById("frmMarche");
form.reset();
//! on reset le champ caché rowid
document.getElementById("marcheRowid").value = "0";
//! on met tous les input de type number à 0
let inputs = document.querySelectorAll('input[type=number]');
for (let i = 0; i < inputs.length; i++) {
inputs[i].value = 0;
}
document.getElementById("modMarcheTitre").innerHTML = "Création d'un nouveau marché";
showModal(document.getElementById("modalEditMarche"));
document.getElementById("marcheLibelle").focus();
}
let clickModMarche = function () {
//! Event Click sur un bouton de modification d'une ligne d'un marché
idMarche = this.getAttribute("data-rowid");
libMarche = this.getAttribute("data-libelle");
showLoading();
// Va chercher la 1ère cellule de la ligne pour lancer la function click() => clickLigMarche
let firstCellOfRow = this.parentNode.parentNode.cells[0];
firstCellOfRow.click();
let xhttp = new XMLHttpRequest();
xhttp.open("POST", "/jxpost/load_marche", true);
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.onreadystatechange = function () {
if (this.readyState == XMLHttpRequest.DONE && this.status == 200) {
// Response
let ret = JSON.parse(this.responseText);
if (ret.length == 1) {
// 1 marché récupéré
let marche = ret[0];
document.getElementById("marcheAct").value = "M";
document.getElementById("marcheRowid").value = marche.rowid;
document.getElementById("marcheLibelle").value = marche.libelle;
document.getElementById("marcheNumero").value = marche.numero;
document.getElementById("marcheNom").value = marche.nom;
if (marche.chk_remise_sur_tg == '1') {
document.getElementById("marcheChk_remise_sur_tg").checked = true;
} else {
document.getElementById("marcheChk_remise_sur_tg").checked = false;
}
if (marche.chk_prix_nets == '1') {
document.getElementById("marcheChk_prix_nets").checked = true;
} else {
document.getElementById("marcheChk_prix_nets").checked = false;
}
if (marche.chk_marche_public == '1') {
document.getElementById("marcheChk_marche_public").checked = true;
} else {
document.getElementById("marcheChk_marche_public").checked = false;
}
document.getElementById("marcheTaux_remise_trimestrielle").value = marche.taux_remise_trimestrielle;
document.getElementById("marcheTaux_remise_semestrielle").value = marche.taux_remise_semestrielle;
document.getElementById("marcheTaux_remise_annuelle").value = marche.taux_remise_annuelle;
document.getElementById("marcheDate_debut").value = new Date(marche.date_debut).toLocaleDateString("fr");
document.getElementById("marcheDate_fin").value = new Date(marche.date_fin).toLocaleDateString("fr");
document.getElementById("marcheDate_validite_prix").value = new Date(marche.date_validite_prix).toLocaleDateString("fr");
document.getElementById("marcheFranco_de_port").value = marche.franco_de_port;
document.getElementById("marcheGarantie").value = marche.garantie;
document.getElementById("marcheDelai_de_livraison").value = marche.delai_de_livraison;
document.getElementById("marcheRemises_commerciales").value = marche.remises_commerciales;
document.getElementById("marcheRemise_palier_1").value = marche.remise_palier_1;
document.getElementById("marcheRemise_taux_1").value = marche.remise_taux_1;
document.getElementById("marcheRemise_palier_2").value = marche.remise_palier_2;
document.getElementById("marcheRemise_taux_2").value = marche.remise_taux_2;
document.getElementById("marcheRemise_palier_3").value = marche.remise_palier_3;
document.getElementById("marcheRemise_taux_3").value = marche.remise_taux_3;
document.getElementById("marcheRemise_palier_4").value = marche.remise_palier_4;
document.getElementById("marcheRemise_taux_4").value = marche.remise_taux_4;
document.getElementById("marcheCommentaire").value = marche.commentaire;
if (marche.active == '1') {
document.getElementById("marcheActive").checked = true;
} else {
document.getElementById("marcheActive").checked = false;
}
if (marche.chk_cache_commerciaux == '1') {
document.getElementById("marcheChk_cache_commerciaux").checked = true;
} else {
document.getElementById("marcheChk_cache_commerciaux").checked = false;
}
if (marche.chk_marche_hybride == '1') {
document.getElementById("marcheChk_marche_hybride").checked = true;
} else {
document.getElementById("marcheChk_marche_hybride").checked = false;
}
if (marche.chk_regle_seuils_marge == '1') {
document.getElementById("marcheChk_regle_seuils_marge").checked = true;
} else {
document.getElementById("marcheChk_regle_seuils_marge").checked = false;
}
document.getElementById("modMarcheTitre").innerHTML = "Modification de la fiche du marché " + libMarche;
showModal(document.getElementById("modalEditMarche"));
document.getElementById("marcheLibelle").focus();
}
hideLoading();
}
};
let data = {cid: idMarche};
xhttp.send(JSON.stringify(data));
return false;
}
let clickCancelModMarche = function () {
//! Event Click sur le bouton Annuler de la modale d'un marché
hideModal(document.getElementById("modalEditMarche"));
}
let clickSubmitModMarche = function () {
//! Event Click sur le bouton Enregistrer de la modale d'un marché
if (!document.getElementById("marcheLibelle").value) {
showNotification("Enregistrement impossible", "Le marché doit au moins avoir un titre", "warning");
document.getElementById("marcheLibelle").focus();
return false;
}
let xhttp = new XMLHttpRequest();
xhttp.open("POST", "/jxpost/save_marche", true);
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.onloadstart = function () {
document.getElementById("loadingDiv").style.display = "block";
};
xhttp.onreadystatechange = function () {
if (this.readyState == XMLHttpRequest.DONE && this.status == 200) {
let retour = JSON.parse(this.responseText);
if (retour.ret == "ok") {
showNotification("Enregistrement", "L'enregistrement de cette fiche marché a été effectué avec succès", "success");
} else {
showNotification("Enregistrement", "Erreur lors de l'enregistrement de cette fiche marché", "error");
}
}
};
xhttp.onloadend = function () {
document.getElementById("loadingDiv").style.display = "none";
};
let frmData = new FormData(document.getElementById('frmMarche'));
let objData = {};
frmData.forEach(function (value, key) {
objData[key] = value;
});
xhttp.send(JSON.stringify(objData));
if (document.getElementById("marcheRowid").value == "0") {
//! si c'était une création, on ajoute le nouveau marché en bas de tableau
// TODO: on ajoute la ligne créée dans le tableau
} else {
//! on recherche la ligne du tableau à mettre à jour
let cell;
Array.from(elLigMarches).forEach(function (lngMarche) {
cell = lngMarche.cells[0];
if (cell.getAttribute("data-rowid") == idMarche) {
lngMarche.cells[0].innerHTML = document.getElementById("marcheLibelle").value;
if (document.getElementById("marcheActive").checked) {
lngMarche.cells[1].innerHTML = "Oui";
} else {
lngMarche.cells[1].innerHTML = "Non";
}
lngMarche.cells[2].innerHTML = document.getElementById("marcheDate_debut").value;
lngMarche.cells[3].innerHTML = document.getElementById("marcheDate_fin").value;
lngMarche.cells[4].innerHTML = document.getElementById("marcheDate_validite_prix").value;
}
})
}
hideModal(document.getElementById("modalEditMarche"));
return false;
}
let clickSuppMarche = function () {
//! Event Click sur le bouton Supprimer d'un marché
idMarche = this.getAttribute("data-rowid");
libMarche = this.getAttribute("data-libelle");
if (confirm("Voulez-vous vraiment supprimer le marché " + libMarche + " ?")) {
if (confirm("ATTENTION ! Cette suppression est définitive et supprimera aussi tous ses produits rattachés (sauf hors marché évidemment). Voulez-vous vraiment supprimer le marché " + libMarche + " ?")) {
let xhttp = new XMLHttpRequest();
xhttp.open("POST", "/jxpost/delete_marche", true);
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.onloadstart = function () {
showLoading();
};
xhttp.onreadystatechange = function () {
if (this.readyState == XMLHttpRequest.DONE && this.status == 200) {
let retour = JSON.parse(this.responseText);
if (retour.ret == "ok") {
//! on recherche la ligne du tableau à supprimer
let cell;
Array.from(elLigMarches).forEach(function (lngMarche) {
cell = lngMarche.cells[0];
if (cell.getAttribute("data-rowid") == idMarche) {
lngMarche.remove();
}
});
showNotification("Suppression", "La suppression de ce marché a été effectuée avec succès", "success");
} else {
showNotification("Suppression", "Erreur lors de la suppression de ce marché", "error");
}
}
};
xhttp.onloadend = function () {
hideLoading();
};
let data = {cid: idMarche};
xhttp.send(JSON.stringify(data));
}
}
return false;
}
let clickImportProduitsMarche = function () {
//! Event Click sur le bouton d'importation des produits d'un marché
document.getElementById("modImportTitre").innerHTML = "Importation des produits de marché";
showModal(document.getElementById("modalImportMarche"));
}
let clickCancelImportMarche = function () {
//! Event Click sur le bouton Annuler de la modale d'importation des produits d'un marché
hideModal(document.getElementById("modalImportMarche"));
}
let clickSubmitImportProduitsMarche = function () {
//! Click Importation du CSV des produits d'un marché
const file = document.getElementById("importFileMarche").files[0];
if (file === undefined) {
showNotification('Veuillez sélectionner un fichier CSV à importer', 'warning');
return false;
}
// TODO: prévoir une progress bar
showLoading();
// Récupération des données du formulaire
// let frmData = new FormData(document.getElementById('frmImportMarche'));
let frmData = new FormData();
frmData.append("file", file);
fetch('/jximport/upload_marche_produits',
{
method: 'POST',
body: frmData,
})
.then((response) => {
const ret = response.json();
ret.then(function (ret) {
const status = ret.ret;
const msg = ret.msg;
if (status == "ok") {
showNotification("Importation", msg, "success");
hideLoading();
hideModal(document.getElementById("modalImportMarche"));
} else {
showNotification("Importation", msg, "error");
hideLoading();
hideModal(document.getElementById("modalImportMarche"));
}
});
})
.catch((error) => {
console.error('Error:', error);
showNotification("Importation", "Erreur : " + error, "error");
});
return false;
}
let clickGestionListes = function () {
//! Click sur le bouton de gestion des listes tarifaires par marché
// TODO: On appelle la liste de tous les marchés, et pour chaque marché on récupère son éventuelle ligne dans marches_listes
showLoading();
let xhttp1 = new XMLHttpRequest();
xhttp1.open("POST", "/jxpost/load_marches_listes", true);
xhttp1.setRequestHeader("Content-Type", "application/json");
xhttp1.onreadystatechange = function () {
if (this.readyState == XMLHttpRequest.DONE && this.status == 200) {
let listes = JSON.parse(this.responseText);
//! on alimente dynamiquement les lignes suivant les marchés actuels
let xhttp2 = new XMLHttpRequest();
xhttp2.open("POST", "/jxpost/load_marches", true);
xhttp2.setRequestHeader("Content-Type", "application/json");
xhttp2.onreadystatechange = function () {
if (this.readyState == XMLHttpRequest.DONE && this.status == 200) {
let tblBody = document.getElementById("tblListes").getElementsByTagName("tbody")[0];
// on vide le body de cette table
tblBody.innerHTML = "";
let mar = JSON.parse(this.responseText);
if (mar.length > 0) {
// au moins un marché trouvé
let nameInputMotCle;
let valInputMotCle;
let nameInputAchat;
let valInputAchat;
let nameInputVente;
let valInputVente;
let laListe;
for (let key in mar) {
if (mar.hasOwnProperty(key)) {
// Récupération des valeurs de la ligne
let val = mar[key];
// ## Comment chercher une valeur dans un tableau en javascript
laListe = listes.find(({fk_marche}) => fk_marche === val["rowid"]);
if (laListe) {
valInputMotCle = laListe["mot_cle"] ? laListe["mot_cle"] : "";
valInputAchat = laListe["terme_achat"] ? laListe["terme_achat"] : "";
valInputVente = laListe["terme_vente"] ? laListe["terme_vente"] : "";
} else {
valInputMotCle = "";
valInputAchat = "";
valInputVente = "";
}
// Insertion d'une nouvelle ligne et création de ses colonnes
let newRow = tblBody.insertRow(0);
let celId = newRow.insertCell(0);
celId.innerHTML = val['rowid'];
let celLibelle = newRow.insertCell(1);
celLibelle.innerHTML = val['libelle'];
let celMotCle = newRow.insertCell(2);
nameInputMotCle = "motcle_" + val["rowid"];
celMotCle.innerHTML = '<input type="text" class="form-control" name="' + nameInputMotCle + '" placeholder="Mot clé du marché" maxlength="30" value="' + valInputMotCle + '" />';
let celTermeAchat = newRow.insertCell(3);
nameInputAchat = "motcleachat_" + val["rowid"];
celTermeAchat.innerHTML = '<input type="text" class="form-control" name="' + nameInputAchat + '" placeholder="Mot clé pour achat" maxlength="30" value="' + valInputAchat + '" />';
let celTermeVente = newRow.insertCell(4);
nameInputVente = "motclevente_" + val["rowid"];
celTermeVente.innerHTML = '<input type="text" class="form-control" name="' + nameInputVente + '" placeholder="Mot clé pour vente" maxlength="30" value="' + valInputVente + '" />';
}
}
}
hideLoading();
}
}
xhttp2.send();
}
}
xhttp1.send();
showModal(document.getElementById("modalEditListes"));
}
let clickCancelListes = function () {
//! Click sur le bouton Annuler de la modale d'importation des produits d'un marché
hideModal(document.getElementById("modalEditListes"));
}
let clickSubmitListes = function () {
//! Click sur le bouton Enregistrer de la modale de la gestion des listes tarifaires par marché
hideModal(document.getElementById("modalEditListes"));
showLoading();
let xhttp = new XMLHttpRequest();
xhttp.open("POST", "/jxpost/save_marches_listes", true);
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.onreadystatechange = function () {
if (this.readyState == XMLHttpRequest.DONE && this.status == 200) {
let retour = JSON.parse(this.responseText);
if (retour.ret == "ok") {
showNotification("Enregistrement", "L'enregistrement de la gestion des listes tarifaires par marché a été effectué avec succès", "success");
} else {
showNotification("Enregistrement", "Erreur lors de l'enregistrement", "error");
}
hideLoading();
}
};
let frmData = new FormData(document.getElementById('frmListes'));
let objData = {};
frmData.forEach(function (value, key) {
objData[key] = value;
});
xhttp.send(JSON.stringify(objData));
}
let clickModFamilles = function () {
showLoading();
//! on charge d'abord la liste des x_familles
let familles;
let xhttp1 = new XMLHttpRequest();
xhttp1.open("POST", "/jxpost/load_familles", false);
xhttp1.setRequestHeader("Content-Type", "application/json");
xhttp1.onreadystatechange = function () {
if (this.readyState == XMLHttpRequest.DONE && this.status == 200) {
familles = JSON.parse(this.responseText);
}
}
let data1 = {};
xhttp1.send(JSON.stringify(data1));
//! Ensuite on charge les familles de groupes
let xhttp2 = new XMLHttpRequest();
xhttp2.open("POST", "/jxpost/load_familles_groupes", true);
xhttp2.setRequestHeader("Content-Type", "application/json");
xhttp2.onreadystatechange = function () {
if (this.readyState == XMLHttpRequest.DONE && this.status == 200) {
let retour = JSON.parse(this.responseText);
let tblBody = document.getElementById("tblFamilles").getElementsByTagName("tbody")[0];
// on vide le body de cette table
tblBody.innerHTML = "";
if (retour.length > 0) {
// au moins une famille trouvée dans cette recherche
let nbFamilles = retour.length;
for (let key in retour) {
if (retour.hasOwnProperty(key)) {
// Récupération des valeurs de la ligne
let val = retour[key];
// Insertion d'une nouvelle ligne et création de ses colonnes
let newRow = tblBody.insertRow(-1);
let celCode = newRow.insertCell(0);
celCode.innerHTML = '<input type="text" class="form-control" name="id_' + val["rowid"] + '" maxlength="4" value="' + val["rowid"] + '" disabled />';
let celGroupe = newRow.insertCell(1);
celGroupe.innerHTML = '<input type="text" class="form-control" name="groupe_' + val["rowid"] + '" placeholder="Nom du groupe" maxlength="30" value="' + val["groupe"] + '" />';
let celFamille = newRow.insertCell(2);
//! on insère dans cette cellule le select des familles
let selFamille = '<select class="form-control" name="famille_' + val["rowid"] + '">';
for (let key2 in familles) {
if (familles.hasOwnProperty(key2)) {
// Récupération des valeurs de la ligne familles
let val2 = familles[key2];
if (val2["rowid"] == val["fk_famille"]) {
selFamille += '<option value="' + val2["rowid"] + '" selected>' + val2["libelle"] + '</option>';
} else {
selFamille += '<option value="' + val2["rowid"] + '">' + val2["libelle"] + '</option>';
}
}
}
selFamille += '</select>';
celFamille.innerHTML = selFamille;
let celMaintenance = newRow.insertCell(3);
celMaintenance.innerHTML = '<input type="text" class="form-control" name="maintenance_' + val["rowid"] + '" placeholder="Code maintenance" maxlength="30" value="' + val["code_maintenance"] + '" />';
let celMarge_rr = newRow.insertCell(4);
celMarge_rr.innerHTML = '<div class="input-group"><input type="number" class="form-control" name="margerr_' + val["rowid"] + '" placeholder="Marge RR" step="1" min="0" max="99" lang="fr" value="' + val["marge_rr"] + '" /><span class="input-group-addon">&percnt;</span></div>';
let celMarge_dv = newRow.insertCell(5);
celMarge_dv.innerHTML = '<div class="input-group"><input type="number" class="form-control" name="margedv_' + val["rowid"] + '" placeholder="Marge DV" step="1" min="0" max="99" lang="fr" value="' + val["marge_dv"] + '" /><span class="input-group-addon">&percnt;</span></div>';
let celActions = newRow.insertCell(6);
celActions.className = "text-center";
celActions.innerHTML = '<button type="button" class="btn btn-danger btn-xs btnSuppFamille" data-rowid="' + val["rowid"] + '"><i class="fa fa-trash"></i></button>';
}
}
document.getElementById("modFamillesTitre").innerHTML = '<i class="fa fa-stack-exchange fa-lg"></i> Liste des ' + nbFamilles + ' familles de produits trouvées';
} else {
// Aucune famille trouvée dans cette recherche
document.getElementById("modFamillesTitre").innerHTML = '<i class="fa fa-stack-exchange fa-lg"></i> Liste des familles de produits';
let newRow = tblBody.insertRow(0);
let celCode = newRow.insertCell(0);
celCode.innerHTML = "Aucune famille trouvée";
celCode.setAttribute("colspan", "4");
}
hideLoading();
showModal(document.getElementById("modalFamilles"));
}
}
let data2 = {};
xhttp2.send(JSON.stringify(data2));
}
let clickCancelFamilles = function () {
hideModal(document.getElementById("modalFamilles"));
}
let clickSubmitFamilles = function () {
hideModal(document.getElementById("modalFamilles"));
showLoading();
let xhttp = new XMLHttpRequest();
xhttp.open("POST", "/jxpost/save_familles", true);
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.onreadystatechange = function () {
if (this.readyState == XMLHttpRequest.DONE && this.status == 200) {
let retour = JSON.parse(this.responseText);
hideLoading();
if (retour["ret"] == "ok") {
showNotification("Familles", retour["msg"], "success");
} else {
showNotification("Familles", retour["msg"], "error");
}
}
}
let data = {};
let elTblFamilles = document.getElementById("tblFamilles").getElementsByTagName("tbody")[0];
// on récupère les lignes du tableau
let elLignes = elTblFamilles.getElementsByTagName("tr");
let nbLignes = elLignes.length;
let elLigne = null;
let dataLigne = {};
// on parcourt les lignes du tableau
for (let i = 0; i < nbLignes; i++) {
elLigne = elLignes[i];
// on récupère les cellules de la ligne
let elCellules = elLigne.getElementsByTagName("td");
let nbCellules = elCellules.length;
let elCellule = null;
dataLigne = {};
// on parcourt les cellules de la ligne
for (let j = 0; j < nbCellules; j++) {
elCellule = elCellules[j];
// on récupère les inputs de la cellule
let elInputs = elCellule.getElementsByTagName("input");
let nbInputs = elInputs.length;
if (nbInputs == 1) {
let elInput = elInputs[0];
// on récupère le début du nom de l'input jusqu'au _
let nameInput = elInput.getAttribute("name").split("_")[0];
// on récupère la valeur de l'input
let valueInput = elInput.value;
// on ajoute le couple nom/valeur dans le tableau data
dataLigne[nameInput] = valueInput;
}
let elSel = elCellule.getElementsByTagName("select");
let nbSel = elSel.length;
if (nbSel == 1) {
let elS = elSel[0];
// on récupère le début du nom de l'input jusqu'au _
let nameInput = elS.getAttribute("name").split("_")[0];
// on récupère la valeur de l'input
let valueInput = elS.value;
// on ajoute le couple nom/valeur dans le tableau data
dataLigne[nameInput] = valueInput;
}
}
// on ajoute le tableau dataLigne dans le tableau data
data[i] = dataLigne;
}
xhttp.send(JSON.stringify(data));
}
let clickSuppFamille = function () {
}
let clickAddFamille = function () {
// On incrémente l'id des nouvelles familles
idNewFamille++;
//! on charge d'abord la liste des x_familles
let familles;
let xhttp1 = new XMLHttpRequest();
xhttp1.open("POST", "/jxpost/load_familles", false);
xhttp1.setRequestHeader("Content-Type", "application/json");
xhttp1.onreadystatechange = function () {
if (this.readyState == XMLHttpRequest.DONE && this.status == 200) {
familles = JSON.parse(this.responseText);
}
}
let data1 = {};
xhttp1.send(JSON.stringify(data1));
let tblBody = document.getElementById("tblFamilles").getElementsByTagName("tbody")[0];
let newRow = tblBody.insertRow(0);
let celCode = newRow.insertCell(0);
celCode.innerHTML = '<input type="text" class="form-control" name="id_' + idNewFamille + '" maxlength="4" value="' + idNewFamille + '" disabled />';
let celGroupe = newRow.insertCell(1);
celGroupe.innerHTML = '<input type="text" class="form-control" name="groupe_' + idNewFamille + '" placeholder="Nom du groupe" maxlength="30" value="" />';
let celFamille = newRow.insertCell(2);
celFamille.innerHTML = '<input type="text" class="form-control" name="famille_' + idNewFamille + '" placeholder="Nom de la famille" maxlength="30" value="" />';
//! on insère dans cette cellule le select des familles
let selFamille = '<select class="form-control" name="famille_' + idNewFamille + '">';
selFamille += '<option value="0" selected>Sélectionner une famille</option>';
for (let key in familles) {
if (familles.hasOwnProperty(key)) {
// Récupération des valeurs de la ligne
let val = familles[key];
selFamille += '<option value="' + val["rowid"] + '">' + val["libelle"] + '</option>';
}
}
selFamille += '</select>';
celFamille.innerHTML = selFamille;
let celActions = newRow.insertCell(3);
celActions.className = "text-center";
celActions.innerHTML = '<button type="button" class="btn btn-danger btn-xs btnSuppFamille" data-rowid="' + idNewFamille + '"><i class="fa fa-trash"></i></button>';
//! on met le focus sur le nouveau champ groupe
celGroupe.getElementsByTagName("input")[0].focus();
}
function showProduits(list) {
// on vide le body de cette table
let tblBody = document.getElementById("tblMarchesProduits").getElementsByTagName("tbody")[0];
tblBody.innerHTML = "";
if (list.length > 0) {
// au moins un produit trouvé pour ce marché
let nbProduits = list.length;
document.getElementById("pnlProduitsTitre").innerHTML = libMarche.substring(0, 20) + " (" + nbProduits + ")";
let nbLignes = 0;
for (let key in list) {
if (list.hasOwnProperty(key)) {
// Récupération des valeurs de la ligne
let val = list[key];
showLigneProduit(tblBody, val);
nbLignes++;
if (nbLignes > 8000) {
break;
} // on limite à 8000 lignes
}
}
// On affiche la zone de recherche et on initialise l'autocomplete avec les données des produits retournés
document.getElementById("inpSearchProduit").style.visibility = "visible";
autocompleteProduit(document.getElementById('inpSearchProduit'), list);
} else {
// aucun produit trouvé pour ce marché
document.getElementById("pnlProduitsTitre").innerHTML = libMarche;
let newRow = tblBody.insertRow(0);
let celCode = newRow.insertCell(0);
celCode.innerHTML = "Aucun produit trouvé";
celCode.colSpan = 5;
document.getElementById("inpSearchProduit").style.visibility = "hidden";
}
}
function showLigneProduit(tblBody, val) {
// Insertion d'une nouvelle ligne et création de ses colonnes
let newRow = tblBody.insertRow(0);
let prixAchat = parseFloat(val['prix_achat_net']);
const prc_discount = parseFloat(val['prc_discount_1']);
let bDiscount = "";
if (prc_discount > 0) {
prixAchat = prixAchat - (prixAchat * prc_discount / 100);
bDiscount = ' data-after-text="' + prc_discount + '%" data-after-type="orange pill" title="% discount"';
}
const prixVente = parseFloat(val['prix_vente']);
let pb = false;
let neg = false;
if ((prixAchat == 0 && prixVente > 0) || (prixAchat > 0 && prixVente == 0)) {
pb = true;
} else if (prixAchat > prixVente) {
neg = true;
}
let celCode = newRow.insertCell(0);
celCode.innerHTML = val['code'];
let celLibelle = newRow.insertCell(1);
celLibelle.innerHTML = val['libelle'];
let celGroupe = newRow.insertCell(2);
celGroupe.innerHTML = val['groupe'];
let celAchatNet = newRow.insertCell(3);
celAchatNet.className = "text-right";
if (pb) {
celAchatNet.classList.add('bg-warning');
} else if (neg) {
celAchatNet.classList.add('bg-danger');
}
celAchatNet.innerHTML = '<span ' + bDiscount + '>' + formatAmount(prixAchat) + ' €</span>';
let celVente = newRow.insertCell(4);
celVente.className = "text-right";
if (pb) {
celVente.classList.add('bg-warning');
} else if (neg) {
celVente.classList.add('bg-danger');
}
celVente.innerHTML = formatAmount(prixVente) + " €";
}
function autocompleteProduit(input, list) {
//! Autocomplete pour la recherche de produits
//Add an event listener to compare the input value with list items
input.addEventListener('input', function () {
// si l'input est vide, on sort
if (!this.value) {
showProduits(list);
return false;
}
// ou si sa longueur est inférieure à 2 caractères
if (this.value.length < 2)
return false;
let tblBody = document.getElementById("tblMarchesProduits").getElementsByTagName("tbody")[0];
tblBody.innerHTML = "";
let nbSuggestionsFound = 0;
for (let key in list) {
if (list.hasOwnProperty(key)) {
// Récupération des valeurs de la ligne
let val = list[key];
if (val["rech"].toUpperCase().includes(this.value.toUpperCase())) {
// On affiche la ligne
showLigneProduit(tblBody, val);
}
}
}
});
return false;
}
//! Configuration des événements
//! Sur chaque cellule du tableau des marchés ayant la classe celMarches, on affecte un événement click qui appelle la fonction clickLnMarche()
Array.from(elCelMarches).forEach(function (lnMarche) {
lnMarche.addEventListener('click', clickLigMarche);
});
//! Sur chaque bouton de modification du tableau des marchés ayant la classe btnModMarche, on affecte un événement click qui appelle la fonction clickModMarche()
Array.from(elBtnModMarches).forEach(function (modMarche) {
modMarche.addEventListener('click', clickModMarche);
});
//! Sur chaque bouton de suppression du tableau des marchés ayant la classe btnSuppMarche, on affecte un événement click qui appelle la fonction clickSuppMarche()
Array.from(elBtnSuppMarches).forEach(function (suppMarche) {
suppMarche.addEventListener('click', clickSuppMarche);
});
elBtnCancelModMarche.addEventListener('click', clickCancelModMarche);
elBtnSubmitModMarche.addEventListener('click', clickSubmitModMarche);
elBtnCreateMarche.addEventListener('click', clickCreateMarche);
elBtnImportProduits.addEventListener('click', clickImportProduitsMarche);
elBtnCancelImportMarche.addEventListener('click', clickCancelImportMarche);
elBtnSubmitImportMarche.addEventListener('click', clickSubmitImportProduitsMarche);
elBtnGestionListes.addEventListener('click', clickGestionListes);
elBtnCancelListes.addEventListener('click', clickCancelListes);
elBtnSubmitListes.addEventListener('click', clickSubmitListes);
elBtnFamilles.addEventListener('click', clickModFamilles);
elBtnCancelFamilles.addEventListener('click', clickCancelFamilles);
elBtnSubmitFamilles.addEventListener('click', clickSubmitFamilles);
elBtnAddFamille.addEventListener('click', clickAddFamille);
});