- Correction affichage email contact dans SAP (models/msap.php) - Ajout fonctionnalité tri des tableaux devis (jsap.js, jdevis.js) - Améliorations diverses vues devis et SAP - Mise à jour contrôleurs et modèles export 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1154 lines
45 KiB
JavaScript
1154 lines
45 KiB
JavaScript
// 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;
|
|
let selectedXmlDevis = new Set();
|
|
let searchSapTimeout = null;
|
|
|
|
const tableSortStates = new Map();
|
|
|
|
function initTableSort() {
|
|
const allTables = document.querySelectorAll('[id^="tblDos"], [id^="tblDosArch"]');
|
|
|
|
allTables.forEach(table => {
|
|
const tableId = table.id;
|
|
const headers = table.querySelectorAll('th[data-sortable="true"]');
|
|
const tbody = table.querySelector('tbody');
|
|
|
|
if (!tbody) return;
|
|
|
|
if (!tableSortStates.has(tableId)) {
|
|
tableSortStates.set(tableId, {
|
|
originalOrder: null,
|
|
currentSort: { column: null, direction: null }
|
|
});
|
|
}
|
|
|
|
headers.forEach(header => {
|
|
header.addEventListener('click', function() {
|
|
const columnIndex = parseInt(this.getAttribute('data-column-index'));
|
|
const sortType = this.getAttribute('data-sort-type');
|
|
sortTable(tableId, columnIndex, sortType, this);
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
function sortTable(tableId, columnIndex, sortType, headerElement) {
|
|
const table = document.getElementById(tableId);
|
|
const tbody = table.querySelector('tbody');
|
|
const rows = Array.from(tbody.querySelectorAll('tr'));
|
|
const state = tableSortStates.get(tableId);
|
|
|
|
if (!state.originalOrder) {
|
|
state.originalOrder = rows.slice();
|
|
}
|
|
|
|
const allHeaders = table.querySelectorAll('th[data-sortable="true"]');
|
|
allHeaders.forEach(h => h.style.fontWeight = 'normal');
|
|
|
|
let sortedRows;
|
|
|
|
if (state.currentSort.column === columnIndex && state.currentSort.direction === 'desc') {
|
|
sortedRows = state.originalOrder.slice();
|
|
state.currentSort = { column: null, direction: null };
|
|
} else {
|
|
const direction = (state.currentSort.column === columnIndex && state.currentSort.direction === 'asc') ? 'desc' : 'asc';
|
|
|
|
sortedRows = rows.slice().sort((a, b) => {
|
|
const aCell = a.cells[columnIndex];
|
|
const bCell = b.cells[columnIndex];
|
|
|
|
if (!aCell || !bCell) return 0;
|
|
|
|
let aValue = aCell.textContent.trim();
|
|
let bValue = bCell.textContent.trim();
|
|
|
|
if (sortType === 'number') {
|
|
aValue = aValue.replace(/[^\d,.-]/g, '').replace(',', '.');
|
|
bValue = bValue.replace(/[^\d,.-]/g, '').replace(',', '.');
|
|
aValue = parseFloat(aValue) || 0;
|
|
bValue = parseFloat(bValue) || 0;
|
|
return direction === 'asc' ? aValue - bValue : bValue - aValue;
|
|
} else if (sortType === 'date') {
|
|
aValue = parseDateFromText(aValue);
|
|
bValue = parseDateFromText(bValue);
|
|
if (!aValue && !bValue) return 0;
|
|
if (!aValue) return direction === 'asc' ? 1 : -1;
|
|
if (!bValue) return direction === 'asc' ? -1 : 1;
|
|
return direction === 'asc' ? aValue - bValue : bValue - aValue;
|
|
} else {
|
|
const comparison = aValue.localeCompare(bValue, 'fr');
|
|
return direction === 'asc' ? comparison : -comparison;
|
|
}
|
|
});
|
|
|
|
state.currentSort = { column: columnIndex, direction };
|
|
headerElement.style.fontWeight = 'bold';
|
|
}
|
|
|
|
tbody.innerHTML = '';
|
|
sortedRows.forEach(row => tbody.appendChild(row));
|
|
}
|
|
|
|
function parseDateFromText(dateText) {
|
|
const match = dateText.match(/(\d{2})\/(\d{2})[\/\s](\d{4})/);
|
|
if (!match) return null;
|
|
const [, day, month, year] = match;
|
|
return new Date(year, month - 1, day);
|
|
}
|
|
|
|
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 elBtnExportDevisEnCours = document.getElementsByClassName('btnExportDevisEnCours');
|
|
let elBtnExportDevisXMLEnCours = document.getElementsByClassName('btnExportDevisXMLEnCours');
|
|
let elBtnExportSelectedXML = document.querySelector('.btnExportSelectedXML');
|
|
let elExportCheckboxes = document.getElementsByClassName('exportXMLCheckbox');
|
|
|
|
let elBtnImportPDFEnCours = document.getElementsByClassName('btnImportPDFEnCours');
|
|
let elBtnUploadPDF = document.getElementById('btnUploadPDF');
|
|
let elBtnClosePDF = document.getElementById('btnClosePDF');
|
|
let elBtnDeleteDevis = document.getElementsByClassName('btnDeleteDevis');
|
|
let elBtnViewDevisArchives = document.getElementsByClassName('btnViewDevisArchives');
|
|
let elChatBtnSendEnCours = document.getElementById('chatBtnSendEnCours');
|
|
let elBtnSaveComment = document.getElementById('btnSaveComment');
|
|
|
|
let elBtnDevisEnvoye = document.getElementsByClassName('btnDevisEnvoye');
|
|
|
|
// 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
|
|
console.log('click ligne devis en cours');
|
|
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;
|
|
let chkSpeciaux = false;
|
|
|
|
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();
|
|
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);
|
|
}
|
|
} 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);
|
|
}
|
|
}
|
|
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;
|
|
console.log(data.code);
|
|
if (data.code === null) {
|
|
document.getElementById('inp_lib_client').value = data.lib_new_client;
|
|
document.getElementById('inp_type_client').value = data.type_new_client;
|
|
document.getElementById('inp_adresse1').value = data.adresse1_new_client;
|
|
document.getElementById('inp_adresse2').value = data.adresse2_new_client;
|
|
document.getElementById('inp_adresse3').value = data.adresse3_new_client;
|
|
document.getElementById('inp_cp').value = data.cp_new_client;
|
|
document.getElementById('inp_ville').value = data.ville_new_client;
|
|
document.getElementById('inp_contact_nom').value = data.contact_new_nom;
|
|
document.getElementById('inp_contact_prenom').value = data.contact_new_prenom;
|
|
document.getElementById('inp_contact_fonction').value = data.contact_new_fonction;
|
|
document.getElementById('inp_email').value = data.new_email;
|
|
document.getElementById('inp_telephone').value = data.new_telephone;
|
|
document.getElementById('inp_mobile').value = data.new_mobile;
|
|
} else {
|
|
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_email').value = data.email;
|
|
document.getElementById('inp_telephone').value = data.telephone;
|
|
document.getElementById('inp_mobile').value = data.mobile;
|
|
}
|
|
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_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];
|
|
$('#tdTxRemiseTrim').text(line.taux_remise_trimestrielle + ' %');
|
|
$('#tdTxRemiseSeme').text(line.taux_remise_semestrielle + ' %');
|
|
$('#tdTxRemiseAnnu').text(line.taux_remise_annuelle + ' %');
|
|
$('#tdDebutFin').text(convertMySQLDateToFrenchDate(line.date_fin));
|
|
$('#tdGarantie').text(line.garantie);
|
|
$('#tdDelaiLivr').text(line.delai_de_livraison);
|
|
$('#tdRemisesCo').text(line.remises_commerciales);
|
|
} else {
|
|
$('#tdTxRemiseTrim').text('-');
|
|
$('#tdTxRemiseSeme').text('-');
|
|
$('#tdTxRemiseAnnu').text('-');
|
|
$('#tdDebutFin').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 =
|
|
'<input type="number" class="form-control numeric" id="inpQte_' +
|
|
val['fk_produit'] +
|
|
'" name="inpQte_' +
|
|
val['fk_produit'] +
|
|
'" data-rid="' +
|
|
val['fk_produit'] +
|
|
'" data-achat="' +
|
|
val['prix_achat_net'] +
|
|
'" data-vente="' +
|
|
val['prix_vente'] +
|
|
'" value="' +
|
|
val['qte'] +
|
|
'" min="0" max="1000" step="1" style="width: 100px; text-align: right;" disabled>';
|
|
|
|
let celRemisePro = newRowPro.insertCell(4);
|
|
celRemisePro.innerHTML =
|
|
'<div class="input-group"><input type="number" class="form-control numeric" id="inpRemise_' +
|
|
val['fk_produit'] +
|
|
'" name="inpRemise_' +
|
|
val['fk_produit'] +
|
|
'" data-rid="' +
|
|
val['fk_produit'] +
|
|
'" data-achat="' +
|
|
val['prix_achat_net'] +
|
|
'" data-vente="' +
|
|
val['prix_vente'] +
|
|
'" value="' +
|
|
val['remise'] +
|
|
'" min="0" max="100" step="1" style="width: 80px; text-align: right; border-color: #8DB255!important; border-width: 4px;" disabled/><div class="input-group-addon">%</div></div>';
|
|
|
|
let celHTPro = newRowPro.insertCell(5);
|
|
celHTPro.innerHTML = '<div class="input-group"><input type="text" class="form-control numeric" id="inpHT_' + val['fk_produit'] + '" name="inpHT_' + val['fk_produit'] + '" value="' + val['totalht'] + '" style="width: 100px; text-align: right;" readonly tabindex="-1" /><div class="input-group-addon">€</div></div>';
|
|
|
|
let celVariante = newRowPro.insertCell(6);
|
|
celVariante.className = 'text-center';
|
|
celVariante.innerHTML =
|
|
'<input type="checkbox" id="chkVariante_' + val['fk_produit'] + '" name="chkVariante_' + val['fk_produit'] + '" data-rid="' + val['fk_produit'] + '" data-achat="' + val['prix_achat_net'] + '" data-vente="' + val['prix_vente'] + '" value="' + val['chk_variante'] + '" ' + (val['chk_variante'] == 1 ? 'checked' : '') + ' disabled />';
|
|
|
|
let celMargePro = newRowPro.insertCell(7);
|
|
celMargePro.innerHTML =
|
|
'<div class="input-group"><input type="text" class="form-control numeric" id="inpMG_' + val['fk_produit'] + '" name="inpMG_' + val['fk_produit'] + '" value="' + val['marge'] + '" style="width: 80px; text-align: right; border-color: #DC3023!important; border-width: 4px;" readonly tabindex="-1" /><div class="input-group-addon">%</div></div>';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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);
|
|
|
|
refreshChat();
|
|
}
|
|
};
|
|
|
|
let clickExportDevisEnCours = function () {
|
|
idDevisEncours = this.getAttribute('data-rid');
|
|
const url = '/expxls/export_sap_devis/' + idDevisEncours.toString();
|
|
console.log('Export Excel : ' + url);
|
|
window.open(url, '_blank');
|
|
|
|
panel = 'enCours';
|
|
refreshChat();
|
|
return false;
|
|
};
|
|
|
|
let clickExportDevisXMLEnCours = function () {
|
|
idDevisEncours = this.getAttribute('data-rid');
|
|
const url = '/jxexport/xml_devis/' + idDevisEncours.toString();
|
|
console.log('Export xml : ' + url);
|
|
window.open(url, '_blank');
|
|
return false;
|
|
};
|
|
|
|
function refreshChat() {
|
|
console.log('refreshChat()');
|
|
if ((idDevisEnCours > 0 && panel == 'enCours') || (idDevisArchives > 0 && panel == 'archives')) {
|
|
console.log('refreshChat()');
|
|
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);
|
|
}
|
|
|
|
nbCommentChat = data.length;
|
|
|
|
// 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)
|
|
|
|
let clickSaveComment = function () {
|
|
commentaire = document.getElementById('inpComment').value;
|
|
if (commentaire == '') {
|
|
showNotification('Veuillez saisir un commentaire', 'warning');
|
|
return false;
|
|
}
|
|
// 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: idDevisEnCours,
|
|
message: commentaire,
|
|
fkuser: fkUser,
|
|
}),
|
|
}).then((response) => {
|
|
const ret = response.json();
|
|
ret.then(function (data) {
|
|
hideModal(document.getElementById('modalViewDevis'));
|
|
refreshChat();
|
|
});
|
|
});
|
|
};
|
|
|
|
let clickImportPDFEnCours = function () {
|
|
idDevisEnCours = this.getAttribute('data-rid');
|
|
panel = 'enCours';
|
|
|
|
//! On va chercher les éventuels fichiers déjà uploadés
|
|
fetch('/jximport/get_files', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json;charset=utf-8',
|
|
Accept: 'application/json;charset=utf-8',
|
|
},
|
|
body: JSON.stringify({
|
|
cid: idDevisEnCours,
|
|
sup: 'devis_pdf_sap',
|
|
}),
|
|
}).then(function (response) {
|
|
const tblBodyPJ = document.getElementById('tblPJ').getElementsByTagName('tbody')[0];
|
|
tblBodyPJ.innerHTML = '';
|
|
|
|
if (response.ok) {
|
|
const ret = response.json();
|
|
ret.then(function (data) {
|
|
if (data.length > 0) {
|
|
data.forEach(function (val, idx) {
|
|
let newRowPJ = tblBodyPJ.insertRow(-1);
|
|
newRowPJ.className = 'text-center';
|
|
let celPJ = newRowPJ.insertCell(0);
|
|
celPJ.innerHTML = '<a href="/' + val['dir0'] + val['fichier'] + '" target="_blank">' + val['fichier'] + '</a>';
|
|
let celSup = newRowPJ.insertCell(1);
|
|
celSup.innerHTML = '<button type="button" class="btn btn-danger btn-sm" id="btnSupPJ_' + val['rowid'] + '" data-rid="' + val['rowid'] + '"><i class="fa fa-trash"></i></button>';
|
|
document.getElementById('btnSupPJ_' + val['rowid']).addEventListener('click', clickDeletePJ);
|
|
});
|
|
}
|
|
});
|
|
}
|
|
refreshChat();
|
|
});
|
|
|
|
showModal(document.getElementById('modalUploadPDF'));
|
|
|
|
panel = 'enCours';
|
|
return false;
|
|
};
|
|
|
|
let clickUploadPDF = function () {
|
|
let file = document.getElementById('txtUploadPDF').files[0];
|
|
if (file == undefined) {
|
|
showNotification('Veuillez sélectionner un fichier PDF', 'warning');
|
|
return false;
|
|
}
|
|
let formData = new FormData();
|
|
formData.append('file', file);
|
|
formData.append('cid', idDevisEnCours);
|
|
fetch('/jximport/upload_sap_pdf', {
|
|
method: 'POST',
|
|
body: formData,
|
|
}).then((response) => {
|
|
const ret = response.json();
|
|
ret.then(function (data) {
|
|
if (data.ret == 'ok') {
|
|
showNotification(data.msg, 'success');
|
|
} else {
|
|
showNotification(data.msg, 'error');
|
|
}
|
|
hideModal(document.getElementById('modalUploadPDF'));
|
|
location.reload();
|
|
});
|
|
});
|
|
};
|
|
|
|
let clickClosePDF = function () {
|
|
hideModal(document.getElementById('modalUploadPDF'));
|
|
};
|
|
|
|
function clickDeletePJ() {
|
|
const idMedia = this.getAttribute('data-rid');
|
|
|
|
if (confirm('Voulez-vous vraiment supprimer ce fichier ?')) {
|
|
let id = this.getAttribute('data-rid');
|
|
fetch('/jximport/delete_file', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json;charset=utf-8',
|
|
Accept: 'application/json;charset=utf-8',
|
|
},
|
|
body: JSON.stringify({
|
|
cid: idMedia,
|
|
}),
|
|
}).then(function (response) {
|
|
if (response.ok) {
|
|
const ret = response.json();
|
|
ret.then(function () {
|
|
showNotification('Fichier supprimé avec succès !');
|
|
// On rafraichit la liste des PJ
|
|
const tblBodyPJ = document.getElementById('tblPJ').getElementsByTagName('tbody')[0];
|
|
// On supprime la ligne correspondant à la PJ supprimée
|
|
Array.from(tblBodyPJ.rows).forEach(function (row) {
|
|
if (row.cells[1].firstChild.getAttribute('data-rid') == idMedia) {
|
|
row.remove();
|
|
}
|
|
});
|
|
});
|
|
}
|
|
});
|
|
}
|
|
return false;
|
|
}
|
|
|
|
let clickDevisEnvoye = function () {
|
|
idDevisEnCours = this.getAttribute('data-rid');
|
|
panel = 'enCours';
|
|
refreshChat();
|
|
|
|
if (confirm('Ce devis a bien été envoyé au client ? Il sera archivé et ne pourra plus être mis à jour.')) {
|
|
let data = {};
|
|
data['cid'] = idDevisEnCours;
|
|
data['statut'] = 20;
|
|
data['commentaire'] = 'Devis envoyé au client et archivé';
|
|
|
|
fetch('/jxdevis/statut_devis', {
|
|
method: 'POST',
|
|
body: JSON.stringify(data),
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
Accept: 'application/json',
|
|
},
|
|
});
|
|
showNotification('Devis archivé', 'Le devis est maintenant archivé', 'success');
|
|
setTimeout(function () {
|
|
location.reload();
|
|
}, 2000); // 2000 millisecondes = 2 secondes
|
|
}
|
|
return false;
|
|
};
|
|
|
|
let clickDeleteDevis = function () {
|
|
idDevisEnCours = this.getAttribute('data-rid');
|
|
panel = 'enCours';
|
|
refreshChat();
|
|
|
|
if (confirm('Voulez-vous vraiment supprimer ce devis ?')) {
|
|
let data = {};
|
|
data['cid'] = idDevisEnCours;
|
|
|
|
fetch('/jxdevis/delete_devis', {
|
|
method: 'POST',
|
|
body: JSON.stringify(data),
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
Accept: 'application/json',
|
|
},
|
|
});
|
|
showNotification('Devis supprimé', 'Le devis a été supprimé', 'success');
|
|
setTimeout(function () {
|
|
location.reload();
|
|
}, 2000); // 2000 millisecondes = 2 secondes
|
|
}
|
|
return false;
|
|
};
|
|
|
|
// Fonctions de recherche SAP
|
|
let elSearchSAP = document.getElementById('searchSAP');
|
|
let elBtnResetSearchSAP = document.getElementById('btnResetSearchSAP');
|
|
|
|
function restoreSearchSAP() {
|
|
const storageKey = panel === 'enCours' ? 'sapSearchTermEnCours' : 'sapSearchTermArchives';
|
|
const savedTerm = sessionStorage.getItem(storageKey);
|
|
if (savedTerm && savedTerm.length >= 3) {
|
|
elSearchSAP.value = savedTerm;
|
|
elBtnResetSearchSAP.style.display = 'inline-block';
|
|
performSearchSAP(savedTerm);
|
|
} else {
|
|
elSearchSAP.value = '';
|
|
elBtnResetSearchSAP.style.display = 'none';
|
|
}
|
|
}
|
|
|
|
function performSearchSAP(term) {
|
|
if (term.length < 3) {
|
|
return;
|
|
}
|
|
|
|
const context = panel === 'archives' ? 'archives' : 'encours';
|
|
|
|
fetch('/jxdevis/search_devis_sap', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
term: term,
|
|
context: context,
|
|
}),
|
|
})
|
|
.then((response) => response.json())
|
|
.then((data) => {
|
|
if (data.success) {
|
|
const devisIds = data.devis.map((d) => d.rowid);
|
|
filterDevisTablesSAP(devisIds, context);
|
|
updateBadgesSAP(data.nb_devis);
|
|
} else {
|
|
console.error('Erreur recherche:', data.message);
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
console.error('Erreur AJAX:', error);
|
|
});
|
|
}
|
|
|
|
function filterDevisTablesSAP(devisIds, context) {
|
|
if (context === 'encours') {
|
|
const statuts = document.querySelectorAll('[id^="tblBodyDos"]');
|
|
statuts.forEach((tbody) => {
|
|
const rows = tbody.querySelectorAll('tr.ligEnCours');
|
|
rows.forEach((row) => {
|
|
const cells = row.querySelectorAll('.celEnCours');
|
|
if (cells.length > 0) {
|
|
const rowId = parseInt(cells[0].getAttribute('data-rid'));
|
|
if (devisIds.includes(rowId)) {
|
|
row.style.display = '';
|
|
} else {
|
|
row.style.display = 'none';
|
|
}
|
|
}
|
|
});
|
|
});
|
|
} else {
|
|
const archives = document.querySelectorAll('[id^="tblBodyDosArch"]');
|
|
archives.forEach((tbody) => {
|
|
const rows = tbody.querySelectorAll('tr');
|
|
rows.forEach((row) => {
|
|
if (row.id && (row.id.startsWith('trArch_') || row.id.startsWith('trArchTous_'))) {
|
|
const rowId = parseInt(row.id.replace('trArch_', '').replace('trArchTous_', ''));
|
|
if (devisIds.includes(rowId)) {
|
|
row.style.display = '';
|
|
} else {
|
|
row.style.display = 'none';
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
function updateBadgesSAP(nbDevis) {
|
|
Object.keys(nbDevis).forEach((statutId) => {
|
|
const liElements = document.querySelectorAll('[id^="liStat"]');
|
|
liElements.forEach((li) => {
|
|
li.setAttribute('data-after-text', nbDevis[statutId] || '0');
|
|
li.setAttribute('data-after-type', 'orange badge top left');
|
|
});
|
|
});
|
|
}
|
|
|
|
function resetSearchSAP() {
|
|
elSearchSAP.value = '';
|
|
elBtnResetSearchSAP.style.display = 'none';
|
|
const storageKey = panel === 'enCours' ? 'sapSearchTermEnCours' : 'sapSearchTermArchives';
|
|
sessionStorage.removeItem(storageKey);
|
|
|
|
const context = panel === 'archives' ? 'archives' : 'encours';
|
|
if (context === 'encours') {
|
|
const statuts = document.querySelectorAll('[id^="tblBodyDos"]');
|
|
statuts.forEach((tbody) => {
|
|
const rows = tbody.querySelectorAll('tr');
|
|
rows.forEach((row) => {
|
|
row.style.display = '';
|
|
});
|
|
});
|
|
} else {
|
|
const archives = document.querySelectorAll('[id^="tblBodyDosArch"]');
|
|
archives.forEach((tbody) => {
|
|
const rows = tbody.querySelectorAll('tr');
|
|
rows.forEach((row) => {
|
|
row.style.display = '';
|
|
});
|
|
});
|
|
const tbodyTous = document.getElementById('tblBodyDosArchTous');
|
|
if (tbodyTous) {
|
|
const rowsTous = tbodyTous.querySelectorAll('tr');
|
|
rowsTous.forEach((row) => {
|
|
row.style.display = '';
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
elSearchSAP.addEventListener('input', function () {
|
|
const term = this.value.trim();
|
|
|
|
if (searchSapTimeout) {
|
|
clearTimeout(searchSapTimeout);
|
|
}
|
|
|
|
if (term.length >= 3) {
|
|
elBtnResetSearchSAP.style.display = 'inline-block';
|
|
const storageKey = panel === 'enCours' ? 'sapSearchTermEnCours' : 'sapSearchTermArchives';
|
|
sessionStorage.setItem(storageKey, term);
|
|
searchSapTimeout = setTimeout(() => {
|
|
performSearchSAP(term);
|
|
}, 300);
|
|
} else if (term.length === 0) {
|
|
resetSearchSAP();
|
|
} else {
|
|
elBtnResetSearchSAP.style.display = 'none';
|
|
}
|
|
});
|
|
|
|
elBtnResetSearchSAP.addEventListener('click', function () {
|
|
resetSearchSAP();
|
|
});
|
|
|
|
// Hook sur changement d'onglet pour restaurer la recherche appropriée
|
|
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
|
|
if ($(this).attr('href') == '#tabEnCours') {
|
|
panel = 'enCours';
|
|
restoreSearchSAP();
|
|
} else if ($(this).attr('href') == '#tabArchives') {
|
|
panel = 'archives';
|
|
restoreSearchSAP();
|
|
}
|
|
});
|
|
|
|
restoreSearchSAP();
|
|
|
|
initTableSort();
|
|
|
|
// Gestion des états actifs des onglets départements (multiples <ul>)
|
|
// Utiliser l'événement Bootstrap 'shown.bs.tab' au lieu de 'click'
|
|
const allDeptTabs = document.querySelectorAll('.dept-tab a');
|
|
allDeptTabs.forEach((tab) => {
|
|
$(tab).on('shown.bs.tab', function(e) {
|
|
// Retirer 'active' de tous les onglets départements sauf celui-ci
|
|
document.querySelectorAll('.dept-tab').forEach((li) => {
|
|
if (li !== this.parentElement) {
|
|
li.classList.remove('active');
|
|
}
|
|
});
|
|
// Retirer 'active' de l'onglet "Tous"
|
|
const tousLi = document.querySelector('a[href="#dosArchTous"]').parentElement;
|
|
tousLi.classList.remove('active');
|
|
});
|
|
});
|
|
|
|
// Gestion du clic sur "Tous"
|
|
const tousTab = document.querySelector('a[href="#dosArchTous"]');
|
|
if (tousTab) {
|
|
$(tousTab).on('shown.bs.tab', function(e) {
|
|
// Retirer 'active' de tous les onglets départements
|
|
document.querySelectorAll('.dept-tab').forEach((li) => {
|
|
li.classList.remove('active');
|
|
});
|
|
});
|
|
}
|
|
|
|
// Add new functions
|
|
function updateExportButton() {
|
|
if (selectedXmlDevis.size > 0) {
|
|
elBtnExportSelectedXML.classList.remove('hidden');
|
|
} else {
|
|
elBtnExportSelectedXML.classList.add('hidden');
|
|
}
|
|
}
|
|
|
|
function handleCheckboxChange(e) {
|
|
const devisId = e.target.getAttribute('data-rid');
|
|
if (e.target.checked) {
|
|
selectedXmlDevis.add(devisId);
|
|
} else {
|
|
selectedXmlDevis.delete(devisId);
|
|
}
|
|
updateExportButton();
|
|
}
|
|
|
|
function exportSelectedDevis() {
|
|
selectedXmlDevis.forEach((devisId) => {
|
|
const url = '/jxexport/xml_devis/' + devisId;
|
|
window.open(url, '_blank');
|
|
});
|
|
|
|
// Reset checkboxes
|
|
Array.from(elExportCheckboxes).forEach((checkbox) => {
|
|
checkbox.checked = false;
|
|
});
|
|
|
|
// Clear Set and hide export button
|
|
selectedXmlDevis.clear();
|
|
updateExportButton();
|
|
}
|
|
|
|
// 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(elBtnExportDevisEnCours).forEach(function (expDevis) {
|
|
expDevis.addEventListener('click', clickExportDevisEnCours);
|
|
});
|
|
Array.from(elBtnExportDevisXMLEnCours).forEach(function (expDevis) {
|
|
expDevis.addEventListener('click', clickExportDevisXMLEnCours);
|
|
});
|
|
Array.from(elBtnImportPDFEnCours).forEach(function (impDevis) {
|
|
impDevis.addEventListener('click', clickImportPDFEnCours);
|
|
});
|
|
Array.from(elBtnViewDevisEnCours).forEach(function (viewDevis) {
|
|
viewDevis.addEventListener('click', clickViewDevis);
|
|
});
|
|
Array.from(elBtnViewDevisArchives).forEach(function (viewDevis) {
|
|
viewDevis.addEventListener('click', clickViewDevis);
|
|
});
|
|
Array.from(elBtnDeleteDevis).forEach(function (delDevis) {
|
|
delDevis.addEventListener('click', clickDeleteDevis);
|
|
});
|
|
|
|
elChatBtnSendEnCours.addEventListener('click', chatSendMessage);
|
|
elBtnSaveComment.addEventListener('click', clickSaveComment);
|
|
elBtnUploadPDF.addEventListener('click', clickUploadPDF);
|
|
elBtnClosePDF.addEventListener('click', clickClosePDF);
|
|
Array.from(elBtnDevisEnvoye).forEach(function (devisEnvoye) {
|
|
devisEnvoye.addEventListener('click', clickDevisEnvoye);
|
|
});
|
|
|
|
Array.from(elExportCheckboxes).forEach((checkbox) => {
|
|
checkbox.addEventListener('change', handleCheckboxChange);
|
|
});
|
|
|
|
elBtnExportSelectedXML.addEventListener('click', exportSelectedDevis);
|
|
});
|