Initial commit - Application CLEO de gestion de devis
- Architecture MVC avec framework maison d6 - Modules : devis, clients, marchés, SAP - Documentation initiale (README et TODO) - Configuration Composer avec dépendances 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
425
pub/res/js/jproduits.js
Normal file
425
pub/res/js/jproduits.js
Normal file
@@ -0,0 +1,425 @@
|
||||
// jproduits.js
|
||||
|
||||
let idProduit = 0;
|
||||
let oldColorLn;
|
||||
let oldIdLn;
|
||||
let idNewFamille = 999999; // Pour les familles ajoutées, un rowid qui commence à 999999
|
||||
window.addEventListener('DOMContentLoaded', (event) => {
|
||||
console.log('#');
|
||||
|
||||
// Initialisation des éléments utilisés
|
||||
let elCelProduits = document.getElementsByClassName("celProduit");
|
||||
let elBtnImport = document.getElementById("btnImport");
|
||||
let elBtnModProduit = document.getElementsByClassName("btnModProduit");
|
||||
let elBtnQuitModProduit = document.getElementById("btnQuitModProduit");
|
||||
let elBtnCancelImport = document.getElementById("btnCancelImport");
|
||||
let elBtnSubmitImport = document.getElementById("btnSubmitImport");
|
||||
let elBtnSearch = document.getElementById("btnSearch");
|
||||
let elBtnFamilles = document.getElementById("btnFamilles");
|
||||
let elBtnCancelFamilles = document.getElementById("btnCancelFamilles");
|
||||
let elBtnSubmitFamilles = document.getElementById("btnSubmitFamilles");
|
||||
let elBtnAddFamille = document.getElementById("btnAddFamille");
|
||||
|
||||
let clickLigProduit = function () {
|
||||
//! Event Click sur une cellule d'une ligne d'un produit qui a la classe celProduit
|
||||
idProduit = this.getAttribute("data-rowid");
|
||||
|
||||
let thisColor;
|
||||
|
||||
Array.from(elCelProduits).forEach(function (lngProduit) {
|
||||
if (lngProduit.getAttribute("data-rowid") == oldIdLn) {
|
||||
lngProduit.style.backgroundColor = oldColorLn;
|
||||
} else if (lngProduit.getAttribute("data-rowid") == idProduit) {
|
||||
thisColor = lngProduit.style.backgroundColor;
|
||||
lngProduit.style.backgroundColor = "#9bbce7";
|
||||
}
|
||||
});
|
||||
|
||||
oldColorLn = thisColor;
|
||||
oldIdLn = idProduit;
|
||||
};
|
||||
|
||||
function clickModProduit() {
|
||||
//! Fonction appelée lors du click sur un bouton de modification du tableau des produits
|
||||
idProduit = this.getAttribute("data-rowid");
|
||||
|
||||
document.getElementById("loadingDiv").style.display = "block";
|
||||
// Va chercher la 1ère cellule de la ligne pour lancer la function click() => clickLigProduit
|
||||
let firstCellOfRow = this.parentNode.parentNode.cells[0];
|
||||
firstCellOfRow.click();
|
||||
|
||||
let xhttp = new XMLHttpRequest();
|
||||
xhttp.open("POST", "/jxpost/load_produit", 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 produit = ret[0];
|
||||
document.getElementById("rowid").value = produit.rowid;
|
||||
document.getElementById("libelle").value = produit.libelle;
|
||||
document.getElementById("code").value = produit.code;
|
||||
document.getElementById("groupe").value = produit.groupe;
|
||||
document.getElementById("prix_achat_brut_reel").value = produit.prix_achat_brut_reel;
|
||||
document.getElementById("prix_achat_net").value = produit.prix_achat_net;
|
||||
document.getElementById("prix_vente_public").value = produit.prix_vente_public;
|
||||
} else {
|
||||
showNotification("Modification", "Erreur lors de la récupération du produit", "error");
|
||||
}
|
||||
document.getElementById("loadingDiv").style.display = "none";
|
||||
}
|
||||
};
|
||||
xhttp.send(JSON.stringify({cid: idProduit}));
|
||||
showModal(document.getElementById("modalModProduit"));
|
||||
}
|
||||
|
||||
//! Fonction appelée lors du click sur le bouton de fermeture de la fenêtre de modification d'un produit
|
||||
function clickQuitModProduit() {
|
||||
hideModal(document.getElementById("modalModProduit"));
|
||||
}
|
||||
|
||||
//! Fonction appelée lors du click sur le bouton d'importation des produits
|
||||
function clickImport() {
|
||||
showModal(document.getElementById("modalImport"));
|
||||
}
|
||||
|
||||
//! Fonction appelée lors du click sur le bouton d'annulation de l'importation des produits
|
||||
function clickCancelImport() {
|
||||
hideModal(document.getElementById("modalImport"));
|
||||
}
|
||||
|
||||
//! Fonction appelée lors du click sur le bouton de soumission de l'importation des produits
|
||||
function clickSubmitImport() {
|
||||
hideModal(document.getElementById("modalImport"));
|
||||
document.getElementById("loadingDiv").style.display = "block";
|
||||
let xhttp = new XMLHttpRequest();
|
||||
xhttp.open("POST", "/jximport/upload_catalogue", true);
|
||||
xhttp.onreadystatechange = function () {
|
||||
if (this.readyState == XMLHttpRequest.DONE && this.status == 200) {
|
||||
let retour = JSON.parse(this.responseText);
|
||||
let msg = "";
|
||||
document.getElementById("loadingDiv").style.display = "none";
|
||||
if (retour.ret == "ok") {
|
||||
msg = (retour.message) ? retour.message : "L'importation des produits a été effectuée avec succès";
|
||||
showNotification("Importation", msg, "success");
|
||||
} else {
|
||||
msg = (retour.message) ? retour.message : "Erreur lors de l'importation des produits";
|
||||
showNotification("Importation", msg, "error");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let frmData = new FormData();
|
||||
frmData.append("file1", document.getElementById("importFile").files[0]);
|
||||
frmData.append("MAX_FILE_SIZE", document.getElementById("MAX_FILE_SIZE").value)
|
||||
frmData.append("importListe", document.getElementById("importListe").value);
|
||||
xhttp.send(frmData);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
document.getElementById("schProduits").addEventListener("keypress", function (event) {
|
||||
if (event.key === "Enter") {
|
||||
// Traitement de la touche "entrée"
|
||||
clickSearchProduits();
|
||||
}
|
||||
});
|
||||
|
||||
let clickSearchProduits = function () {
|
||||
document.getElementById("loadingDiv").style.display = "block";
|
||||
let search = document.getElementById("schProduits").value;
|
||||
let xhttp = new XMLHttpRequest();
|
||||
xhttp.open("POST", "/jxpost/search_produits", true);
|
||||
xhttp.setRequestHeader("Content-Type", "application/json");
|
||||
xhttp.onreadystatechange = function () {
|
||||
if (this.readyState == XMLHttpRequest.DONE && this.status == 200) {
|
||||
let retour = JSON.parse(this.responseText);
|
||||
document.getElementById("loadingDiv").style.display = "none";
|
||||
if (retour.ret) {
|
||||
showNotification("Recherche", "La recherche ne s'est pas déroulée correctement", "error");
|
||||
} else {
|
||||
let tblBody = document.getElementById("tblProduits").getElementsByTagName("tbody")[0];
|
||||
// on vide le body de cette table
|
||||
tblBody.innerHTML = "";
|
||||
|
||||
if (retour.length > 0) {
|
||||
// au moins un produit trouvé dans cette recherche
|
||||
let nbProduits = retour.length;
|
||||
let nbLignes = 0;
|
||||
|
||||
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(0);
|
||||
|
||||
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 celFamille = newRow.insertCell(3);
|
||||
celFamille.innerHTML = val['famille'];
|
||||
let celAchatBrut = newRow.insertCell(4);
|
||||
celAchatBrut.className = "text-right";
|
||||
celAchatBrut.innerHTML = val['prix_achat_brut_reel'] + " €";
|
||||
let celAchatNet = newRow.insertCell(5);
|
||||
celAchatNet.className = "text-right";
|
||||
celAchatNet.innerHTML = val['prix_achat_net'] + " €";
|
||||
let celVentePub = newRow.insertCell(6);
|
||||
celVentePub.className = "text-right";
|
||||
celVentePub.innerHTML = val['prix_vente_public'] + " €";
|
||||
nbLignes++;
|
||||
let celActions = newRow.insertCell(7);
|
||||
celActions.className = "text-center";
|
||||
celActions.innerHTML = '<button type="button" class="btn btn-primary btn-xs btnModProduit" data-rowid="' + val["rowid"] + '"><i class="fa fa-edit"></i></button>';
|
||||
}
|
||||
}
|
||||
document.getElementById("pnlProduitsTitre").innerHTML = '<i class="fa fa-cubes"></i> Liste des ' + nbLignes + ' produits trouvés';
|
||||
} else {
|
||||
// Aucun produit trouvé dans cette recherche
|
||||
document.getElementById("pnlProduitsTitre").innerHTML = '<i class="fa fa-cubes"></i> Liste des produits de la liste tarifaire générale';
|
||||
let newRow = tblBody.insertRow(0);
|
||||
let celCode = newRow.insertCell(0);
|
||||
celCode.innerHTML = "Aucun produit trouvé";
|
||||
celCode.setAttribute("colspan", "4");
|
||||
celCode.setAttribute("class", "text-center");
|
||||
}
|
||||
|
||||
showNotification("Recherche", "Recherche terminée", "success");
|
||||
}
|
||||
}
|
||||
}
|
||||
let data = {search: search};
|
||||
xhttp.send(JSON.stringify(data));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
let clickModFamilles = function () {
|
||||
document.getElementById("loadingDiv").style.display = "block";
|
||||
|
||||
//! 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);
|
||||
document.getElementById("loadingDiv").style.display = "none";
|
||||
|
||||
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 celActions = newRow.insertCell(3);
|
||||
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");
|
||||
}
|
||||
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"));
|
||||
document.getElementById("loadingDiv").style.display = "block";
|
||||
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);
|
||||
document.getElementById("loadingDiv").style.display = "none";
|
||||
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();
|
||||
}
|
||||
|
||||
//! 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(elCelProduits).forEach(function (lnProduit) {
|
||||
lnProduit.addEventListener('click', clickLigProduit);
|
||||
});
|
||||
|
||||
//! Sur chaque bouton de modification du tableau des produits, on affecte un événement click qui appelle la fonction clickModProduit()
|
||||
Array.from(elBtnModProduit).forEach(function (modProduit) {
|
||||
modProduit.addEventListener('click', clickModProduit);
|
||||
});
|
||||
|
||||
elBtnImport.addEventListener('click', clickImport);
|
||||
elBtnCancelImport.addEventListener('click', clickCancelImport);
|
||||
elBtnSubmitImport.addEventListener('click', clickSubmitImport);
|
||||
elBtnQuitModProduit.addEventListener('click', clickQuitModProduit);
|
||||
elBtnSearch.addEventListener('click', clickSearchProduits);
|
||||
elBtnFamilles.addEventListener('click', clickModFamilles);
|
||||
elBtnCancelFamilles.addEventListener('click', clickCancelFamilles);
|
||||
elBtnSubmitFamilles.addEventListener('click', clickSubmitFamilles);
|
||||
elBtnAddFamille.addEventListener('click', clickAddFamille);
|
||||
});
|
||||
Reference in New Issue
Block a user