Compare commits
1 Commits
feature/co
...
feature/du
| Author | SHA1 | Date | |
|---|---|---|---|
| 639969ca1b |
204
controllers/cjxdevis.php
Normal file → Executable file
204
controllers/cjxdevis.php
Normal file → Executable file
@@ -158,6 +158,131 @@ switch ($Route->_action) {
|
||||
}
|
||||
break;
|
||||
|
||||
case "duplicate_ligne_produit":
|
||||
$data = json_decode(file_get_contents("php://input"));
|
||||
if (isset($data->rowid_ligne)) {
|
||||
$rowidLigneSafe = intval(nettoie_input($data->rowid_ligne));
|
||||
|
||||
$sql = 'SELECT * FROM devis_produits WHERE rowid = ' . $rowidLigneSafe . ';';
|
||||
$ligne = getinfos($sql, 'gen');
|
||||
|
||||
if (count($ligne) > 0) {
|
||||
$l = $ligne[0];
|
||||
$fk_devis = $l['fk_devis'];
|
||||
|
||||
// Récupérer toutes les lignes du devis pour recalculer les ordres
|
||||
$sql = 'SELECT rowid, ordre FROM devis_produits WHERE fk_devis = ' . $fk_devis . ' ORDER BY rowid;';
|
||||
$lignes_devis = getinfos($sql, 'gen');
|
||||
|
||||
// Recalculer tous les ordres si nécessaire (au cas où il y a des doublons à 0)
|
||||
$ordre_actuel = 0;
|
||||
$position_source = -1;
|
||||
foreach ($lignes_devis as $idx => $ligne_devis) {
|
||||
if ($ligne_devis['rowid'] == $rowidLigneSafe) {
|
||||
$position_source = $ordre_actuel;
|
||||
}
|
||||
if ($ligne_devis['ordre'] != $ordre_actuel) {
|
||||
$sql = 'UPDATE devis_produits SET ordre = ' . $ordre_actuel . ' WHERE rowid = ' . $ligne_devis['rowid'] . ';';
|
||||
qSQL($sql, 'gen');
|
||||
}
|
||||
$ordre_actuel++;
|
||||
}
|
||||
|
||||
// Le nouvel ordre sera juste après la ligne source
|
||||
$nouvel_ordre = $position_source + 1;
|
||||
|
||||
// Décaler toutes les lignes après la position d'insertion
|
||||
$sql = 'UPDATE devis_produits SET ordre = ordre + 1 WHERE fk_devis = ' . $fk_devis . ' AND ordre >= ' . $nouvel_ordre . ';';
|
||||
qSQL($sql, 'gen');
|
||||
|
||||
$gratuite = false;
|
||||
if (isset($data->gratuite) && $data->gratuite === true) {
|
||||
$gratuite = true;
|
||||
}
|
||||
|
||||
$sql = 'INSERT INTO devis_produits SET ';
|
||||
$sql .= 'fk_devis = ' . $l['fk_devis'] . ', ';
|
||||
$sql .= 'fk_produit = ' . $l['fk_produit'] . ', ';
|
||||
$sql .= 'ordre = ' . $nouvel_ordre . ', ';
|
||||
$sql .= 'code = "' . $l['code'] . '", ';
|
||||
$sql .= 'libelle = "' . $l['libelle'] . '", ';
|
||||
$sql .= 'qte = ' . $l['qte'] . ', ';
|
||||
|
||||
if ($gratuite) {
|
||||
$sql .= 'prix_vente = 0, ';
|
||||
$sql .= 'pu_vente_remise = 0, ';
|
||||
$sql .= 'totalht = 0, ';
|
||||
$sql .= 'marge = ' . (-floatval($l['prix_achat_net']) * intval($l['qte'])) . ', ';
|
||||
$sql .= 'remise = 100, ';
|
||||
} else {
|
||||
$sql .= 'totalht = ' . $l['totalht'] . ', ';
|
||||
$sql .= 'remise = ' . $l['remise'] . ', ';
|
||||
$sql .= 'marge = ' . $l['marge'] . ', ';
|
||||
$sql .= 'prix_vente = ' . $l['prix_vente'] . ', ';
|
||||
$sql .= 'pu_vente_remise = ' . $l['pu_vente_remise'] . ', ';
|
||||
}
|
||||
|
||||
$sql .= 'prix_achat_net = ' . $l['prix_achat_net'] . ', ';
|
||||
$sql .= 'prc_discount_1 = ' . $l['prc_discount_1'] . ', ';
|
||||
$sql .= 'quantite_1 = ' . $l['quantite_1'] . ', ';
|
||||
$sql .= 'prc_discount_2 = ' . $l['prc_discount_2'] . ', ';
|
||||
$sql .= 'quantite_2 = ' . $l['quantite_2'] . ', ';
|
||||
$sql .= 'prc_discount_3 = ' . $l['prc_discount_3'] . ', ';
|
||||
$sql .= 'quantite_3 = ' . $l['quantite_3'] . ', ';
|
||||
$sql .= 'prc_discount_4 = ' . $l['prc_discount_4'] . ', ';
|
||||
$sql .= 'quantite_4 = ' . $l['quantite_4'] . ', ';
|
||||
$sql .= 'prc_discount_5 = ' . $l['prc_discount_5'] . ', ';
|
||||
$sql .= 'quantite_5 = ' . $l['quantite_5'] . ', ';
|
||||
$sql .= 'prc_discount_6 = ' . $l['prc_discount_6'] . ', ';
|
||||
$sql .= 'quantite_6 = ' . $l['quantite_6'] . ', ';
|
||||
$sql .= 'chk_variante = ' . $l['chk_variante'] . ', ';
|
||||
$sql .= 'chk_prix_net = ' . $l['chk_prix_net'] . ', ';
|
||||
$sql .= 'commentaire = "' . $l['commentaire'] . '";';
|
||||
|
||||
eLog($sql);
|
||||
qSQL($sql, 'gen');
|
||||
|
||||
$sql = 'SELECT dp.*, pf.marge_rr, pf.marge_dv FROM devis_produits dp ';
|
||||
$sql .= 'LEFT JOIN produits p ON dp.fk_produit = p.rowid ';
|
||||
$sql .= 'LEFT JOIN produits_familles pf ON p.groupe = pf.groupe ';
|
||||
$sql .= 'WHERE dp.fk_devis = ' . $fk_devis . ' ORDER BY dp.ordre;';
|
||||
echo getinfos($sql, 'gen', 'json');
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'msg' => 'Ligne non trouvée']);
|
||||
}
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'msg' => 'rowid_ligne manquant']);
|
||||
}
|
||||
break;
|
||||
|
||||
case "delete_ligne_produit":
|
||||
$data = json_decode(file_get_contents("php://input"));
|
||||
if (isset($data->rowid_ligne)) {
|
||||
$rowidLigneSafe = intval(nettoie_input($data->rowid_ligne));
|
||||
|
||||
$sql = 'SELECT fk_devis FROM devis_produits WHERE rowid = ' . $rowidLigneSafe . ';';
|
||||
$ligne = getinfos($sql, 'gen');
|
||||
|
||||
if (count($ligne) > 0) {
|
||||
$fk_devis = $ligne[0]['fk_devis'];
|
||||
|
||||
$sql = 'DELETE FROM devis_produits WHERE rowid = ' . $rowidLigneSafe . ';';
|
||||
eLog($sql);
|
||||
qSQL($sql, 'gen');
|
||||
|
||||
$sql = 'SELECT dp.*, pf.marge_rr, pf.marge_dv FROM devis_produits dp ';
|
||||
$sql .= 'LEFT JOIN produits p ON dp.fk_produit = p.rowid ';
|
||||
$sql .= 'LEFT JOIN produits_familles pf ON p.groupe = pf.groupe ';
|
||||
$sql .= 'WHERE dp.fk_devis = ' . $fk_devis . ' ORDER BY dp.ordre;';
|
||||
echo getinfos($sql, 'gen', 'json');
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'msg' => 'Ligne non trouvée']);
|
||||
}
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'msg' => 'rowid_ligne manquant']);
|
||||
}
|
||||
break;
|
||||
|
||||
case "load_clients_devis":
|
||||
//! On récupère les infos des clients de son secteur ou de toute la France, suivant le devis chk_clients_secteur, utilisé aussi pour l'autocomplete de la recherche de clients
|
||||
$data = json_decode(file_get_contents("php://input"));
|
||||
@@ -843,53 +968,54 @@ switch ($Route->_action) {
|
||||
$idDevis = nettoie_input($data->inpIdDevis);
|
||||
eLog("save_devis final : idDevis = " . $idDevis);
|
||||
|
||||
// TODO: enregistrer le prix d'achat et de vente de chaque produit au moment du devis
|
||||
$sql = 'SELECT rowid FROM devis_produits WHERE fk_devis = ' . $idDevis . ';';
|
||||
$lignesProduits = getinfos($sql, 'gen');
|
||||
|
||||
//! loop sur les datas commençant par inpQte_
|
||||
foreach ($data as $key => $value) {
|
||||
if (substr($key, 0, 7) == "inpQte_") {
|
||||
//! on a une ligne de produit
|
||||
$idProd = substr($key, 7);
|
||||
$qte = nettoie_input($value);
|
||||
$qte = "" ? 0 : $qte;
|
||||
$rem = nettoie_input($data->{"inpRemise_" . $idProd});
|
||||
$rem = "" ? 0 : $rem;
|
||||
if (count($lignesProduits) > 0) {
|
||||
foreach ($lignesProduits as $ligne) {
|
||||
$rowidLigne = $ligne['rowid'];
|
||||
|
||||
$ht = nettoie_input($data->{"inpHT_" . $idProd});
|
||||
$ht = "" ? 0 : $ht;
|
||||
// si $ht contient un espace (délimiteur millier), on le supprime
|
||||
$ht = str_replace(" ", "", $ht);
|
||||
if (isset($data->{"inpQte_" . $rowidLigne})) {
|
||||
$qte = nettoie_input($data->{"inpQte_" . $rowidLigne});
|
||||
$qte = $qte == "" ? 0 : $qte;
|
||||
$rem = nettoie_input($data->{"inpRemise_" . $rowidLigne});
|
||||
$rem = $rem == "" ? 0 : $rem;
|
||||
|
||||
$mg = nettoie_input($data->{"inpMG_" . $idProd});
|
||||
$mg = "" ? 0 : $mg;
|
||||
$ht = nettoie_input($data->{"inpHT_" . $rowidLigne});
|
||||
$ht = $ht == "" ? 0 : $ht;
|
||||
$ht = str_replace(" ", "", $ht);
|
||||
|
||||
$ha = nettoie_input($data->{"achat_" . $idProd});
|
||||
$ha = "" ? 0 : $ha;
|
||||
$ha = str_replace(" ", "", $ha);
|
||||
$mg = nettoie_input($data->{"inpMG_" . $rowidLigne});
|
||||
$mg = $mg == "" ? 0 : $mg;
|
||||
|
||||
$pv = nettoie_input($data->{"vente_" . $idProd});
|
||||
$pv = "" ? 0 : $pv;
|
||||
$pv = str_replace(" ", "", $pv);
|
||||
$ha = nettoie_input($data->{"achat_" . $rowidLigne});
|
||||
$ha = $ha == "" ? 0 : $ha;
|
||||
$ha = str_replace(" ", "", $ha);
|
||||
|
||||
$pu = nettoie_input($data->{"inpPUVenteRem_" . $idProd});
|
||||
$pu = "" ? 0 : $pu;
|
||||
$pu = str_replace(" ", "", $pu);
|
||||
$pv = nettoie_input($data->{"vente_" . $rowidLigne});
|
||||
$pv = $pv == "" ? 0 : $pv;
|
||||
$pv = str_replace(" ", "", $pv);
|
||||
|
||||
$varOpt = 0;
|
||||
if (isset($data->{"chkVariante_" . $idProd})) {
|
||||
$varOpt = 1;
|
||||
$pu = nettoie_input($data->{"inpPUVenteRem_" . $rowidLigne});
|
||||
$pu = $pu == "" ? 0 : $pu;
|
||||
$pu = str_replace(" ", "", $pu);
|
||||
|
||||
$varOpt = 0;
|
||||
if (isset($data->{"chkVariante_" . $rowidLigne})) {
|
||||
$varOpt = 1;
|
||||
}
|
||||
|
||||
$comment = nettoie_input($data->{"inpCom_" . $rowidLigne});
|
||||
$ordre = nettoie_input($data->{"inpOrdre_" . $rowidLigne});
|
||||
if ($ordre == "") {
|
||||
$ordre = 0;
|
||||
}
|
||||
$sql = 'UPDATE devis_produits SET qte=' . $qte . ', remise=' . $rem . ', totalht=' . $ht . ', marge=' . $mg . ', prix_achat_net=' . $ha . ', ';
|
||||
$sql .= 'prix_vente=' . $pv . ', pu_vente_remise=' . $pu . ', chk_variante=' . $varOpt . ', commentaire="' . $comment . '", ordre=' . $ordre . ' ';
|
||||
$sql .= 'WHERE rowid = ' . $rowidLigne . ';';
|
||||
eLog($sql);
|
||||
qSQL($sql, "gen");
|
||||
}
|
||||
|
||||
$comment = nettoie_input($data->{"inpCom_" . $idProd});
|
||||
$ordre = nettoie_input($data->{"inpOrdre_" . $idProd});
|
||||
if ($ordre == "") {
|
||||
$ordre = 0;
|
||||
}
|
||||
$sql = 'UPDATE devis_produits SET qte=' . $qte . ', remise=' . $rem . ', totalht=' . $ht . ', marge=' . $mg . ', prix_achat_net=' . $ha . ', ';
|
||||
$sql .= 'prix_vente=' . $pv . ', pu_vente_remise=' . $pu . ', chk_variante=' . $varOpt . ', commentaire="' . $comment . '", ordre=' . $ordre . ' ';
|
||||
$sql .= 'WHERE fk_devis=' . $idDevis . ' AND fk_produit=' . $idProd . ';';
|
||||
eLog($sql);
|
||||
qSQL($sql, "gen");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
515
pub/res/js/jdevis.js
Normal file → Executable file
515
pub/res/js/jdevis.js
Normal file → Executable file
@@ -693,16 +693,29 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
// au moins un produit trouvé pour ce devis
|
||||
let nbProduits = ret.length
|
||||
|
||||
// on récupère le premier fk_produit, pour simuler un changement sur ce produit pour recalculer les totaux en fin de boucle
|
||||
const fkProduit1 = ret[0]['fk_produit']
|
||||
// on récupère le premier rowid, pour simuler un changement sur ce produit pour recalculer les totaux en fin de boucle
|
||||
const rowidLigne1 = ret[0]['rowid']
|
||||
|
||||
// Compter les occurrences de chaque produit pour masquer le + si >= 2
|
||||
const produitsCount = {}
|
||||
const produitsUniques = {}
|
||||
for (let key in ret) {
|
||||
if (ret.hasOwnProperty(key)) {
|
||||
// Récupération des valeurs de la ligne
|
||||
let val = ret[key]
|
||||
const fkProduit = ret[key]['fk_produit']
|
||||
produitsCount[fkProduit] = (produitsCount[fkProduit] || 0) + 1
|
||||
// Garder la première occurrence de chaque produit
|
||||
if (!produitsUniques[fkProduit]) {
|
||||
produitsUniques[fkProduit] = ret[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// On initialise le readonlyremise par produit pour gérer les cas de marché hybride où leurs produits sont en Prix Nets
|
||||
readonlyRemiseProduit = readonlyRemise
|
||||
// Remplir le tableau tblProduitsSelect avec des produits uniques
|
||||
for (let fkProduit in produitsUniques) {
|
||||
if (produitsUniques.hasOwnProperty(fkProduit)) {
|
||||
let val = produitsUniques[fkProduit]
|
||||
const count = produitsCount[fkProduit]
|
||||
const badgeCount = count > 1 ? ' <span style="color: #8a2be2; font-weight: bold;">(x' + count + ')</span>' : ''
|
||||
|
||||
// Insertion d'une nouvelle ligne et création de ses colonnes : on prend ici le fk_produit
|
||||
let newRowSelect = tblBodySelect.insertRow(-1)
|
||||
@@ -723,18 +736,29 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
'"/>'
|
||||
|
||||
let celCode = newRowSelect.insertCell(1)
|
||||
celCode.innerHTML = val['code']
|
||||
celCode.innerHTML = val['code'] + badgeCount
|
||||
|
||||
let celLibelle = newRowSelect.insertCell(2)
|
||||
celLibelle.innerHTML = val['libelle']
|
||||
}
|
||||
}
|
||||
|
||||
for (let key in ret) {
|
||||
if (ret.hasOwnProperty(key)) {
|
||||
// Récupération des valeurs de la ligne
|
||||
let val = ret[key]
|
||||
|
||||
// On initialise le readonlyremise par produit pour gérer les cas de marché hybride où leurs produits sont en Prix Nets
|
||||
readonlyRemiseProduit = readonlyRemise
|
||||
|
||||
// Sur le tableau tblBodyPro
|
||||
|
||||
// Insertion d'une nouvelle ligne et création de ses colonnes : on prend ici le rowid de devis_produits
|
||||
let newRowPro = tblBodyPro.insertRow(-1)
|
||||
newRowPro.id = 'trPro_' + val['fk_produit']
|
||||
newRowPro.id = 'trPro_' + val['rowid']
|
||||
newRowPro.dataset.ordre = val['ordre']
|
||||
newRowPro.dataset.rid = val['fk_produit']
|
||||
newRowPro.dataset.rowidligne = val['rowid']
|
||||
newRowPro.dataset.fkproduit = val['fk_produit']
|
||||
newRowPro.dataset.code = val['code']
|
||||
newRowPro.dataset.achat = val['prix_achat_net']
|
||||
newRowPro.dataset.achatdiscount = val['prix_achat_net']
|
||||
@@ -758,36 +782,7 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
newRowPro.addEventListener('drop', handleDrop)
|
||||
|
||||
let celCodePro = newRowPro.insertCell(-1)
|
||||
const svgColor = val['commentaire'] == '' ? 'lightgray' : 'red'
|
||||
const svgComment =
|
||||
'<svg id="commentProd_' +
|
||||
val['fk_produit'] +
|
||||
'" class="clickable" data-rid="' +
|
||||
val['fk_produit'] +
|
||||
'" data-code="' +
|
||||
val['code'] +
|
||||
'"><use xlink:href="pub/res/svg/icons.svg#message" style="fill: ' +
|
||||
svgColor +
|
||||
';"/></svg>'
|
||||
let inputOrdreHidden =
|
||||
'<input type="hidden" id="inpOrdre_' +
|
||||
val['fk_produit'] +
|
||||
'" name="inpOrdre_' +
|
||||
val['fk_produit'] +
|
||||
'" value="' +
|
||||
val['ordre'] +
|
||||
'" />'
|
||||
let inputCommentHidden =
|
||||
'<input type="hidden" id="inpCom_' +
|
||||
val['fk_produit'] +
|
||||
'" name="inpCom_' +
|
||||
val['fk_produit'] +
|
||||
'" value="' +
|
||||
val['commentaire'] +
|
||||
'" />'
|
||||
celCodePro.innerHTML = val['code'] + ' ' + svgComment + inputOrdreHidden + inputCommentHidden
|
||||
|
||||
document.getElementById('commentProd_' + val['fk_produit']).addEventListener('click', showCommentProd)
|
||||
celCodePro.style.whiteSpace = 'nowrap'
|
||||
|
||||
let celLibellePro = newRowPro.insertCell(1)
|
||||
celLibellePro.innerHTML = val['libelle']
|
||||
@@ -799,10 +794,12 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
let celQtePro = newRowPro.insertCell(3)
|
||||
celQtePro.innerHTML =
|
||||
'<input type="number" class="form-control numeric" id="inpQte_' +
|
||||
val['fk_produit'] +
|
||||
val['rowid'] +
|
||||
'" name="inpQte_' +
|
||||
val['fk_produit'] +
|
||||
'" data-rid="' +
|
||||
val['rowid'] +
|
||||
'" data-rowidligne="' +
|
||||
val['rowid'] +
|
||||
'" data-fkproduit="' +
|
||||
val['fk_produit'] +
|
||||
'" data-achat="' +
|
||||
val['prix_achat_net'] +
|
||||
@@ -811,15 +808,15 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
'" value="' +
|
||||
val['qte'] +
|
||||
'" min="0" max="1000" step="1" style="width: 100px; text-align: right;"><input type="hidden" name="achat_' +
|
||||
val['fk_produit'] +
|
||||
val['rowid'] +
|
||||
'" value="' +
|
||||
val['prix_achat_net'] +
|
||||
'"/><input type="hidden" name="vente_' +
|
||||
val['fk_produit'] +
|
||||
val['rowid'] +
|
||||
'" value="' +
|
||||
val['prix_vente'] +
|
||||
'"/>'
|
||||
document.getElementById('inpQte_' + val['fk_produit']).addEventListener('change', calculDevis)
|
||||
document.getElementById('inpQte_' + val['rowid']).addEventListener('change', calculDevis)
|
||||
|
||||
let celRemisePro = newRowPro.insertCell(4)
|
||||
// Nouveau code 21/09
|
||||
@@ -834,6 +831,76 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
}
|
||||
// Fin du nouveau code du 21/09
|
||||
|
||||
// Colorisation si remise à 100% (gratuité)
|
||||
if (parseFloat(remiseProduit) === 100) {
|
||||
newRowPro.style.backgroundColor = 'rgba(138, 43, 226, 0.2)'
|
||||
}
|
||||
|
||||
// Remplissage de la cellule code produit (on le fait ici car on a besoin de remiseProduit)
|
||||
const svgColor = val['commentaire'] == '' ? 'lightgray' : 'red'
|
||||
const svgComment =
|
||||
'<svg id="commentProd_' +
|
||||
val['rowid'] +
|
||||
'" class="clickable" data-rowidligne="' +
|
||||
val['rowid'] +
|
||||
'" data-code="' +
|
||||
val['code'] +
|
||||
'"><use xlink:href="pub/res/svg/icons.svg#message" style="fill: ' +
|
||||
svgColor +
|
||||
';"/></svg>'
|
||||
|
||||
// N'afficher le + que si le produit apparaît moins de 2 fois dans le devis
|
||||
let svgDuplicate = ''
|
||||
if (produitsCount[val['fk_produit']] < 2) {
|
||||
svgDuplicate =
|
||||
'<svg id="duplicateProd_' +
|
||||
val['rowid'] +
|
||||
'" class="clickable" data-rowidligne="' +
|
||||
val['rowid'] +
|
||||
'" data-code="' +
|
||||
val['code'] +
|
||||
'" title="Dupliquer cette ligne"><use xlink:href="pub/res/svg/icons.svg#add" style="fill: green;"/></svg>'
|
||||
}
|
||||
|
||||
// N'afficher la trash que pour les produits dupliqués avec remise à 100%
|
||||
let svgDelete = ''
|
||||
if (parseFloat(remiseProduit) === 100) {
|
||||
svgDelete =
|
||||
'<svg id="deleteProd_' +
|
||||
val['rowid'] +
|
||||
'" class="clickable" data-rowidligne="' +
|
||||
val['rowid'] +
|
||||
'" data-code="' +
|
||||
val['code'] +
|
||||
'" title="Supprimer cette ligne"><use xlink:href="pub/res/svg/icons.svg#trash" style="fill: red;"/></svg>'
|
||||
}
|
||||
|
||||
let inputOrdreHidden =
|
||||
'<input type="hidden" id="inpOrdre_' +
|
||||
val['rowid'] +
|
||||
'" name="inpOrdre_' +
|
||||
val['rowid'] +
|
||||
'" value="' +
|
||||
val['ordre'] +
|
||||
'" />'
|
||||
let inputCommentHidden =
|
||||
'<input type="hidden" id="inpCom_' +
|
||||
val['rowid'] +
|
||||
'" name="inpCom_' +
|
||||
val['rowid'] +
|
||||
'" value="' +
|
||||
val['commentaire'] +
|
||||
'" />'
|
||||
celCodePro.innerHTML = val['code'] + ' ' + svgComment + ' ' + svgDuplicate + ' ' + svgDelete + inputOrdreHidden + inputCommentHidden
|
||||
|
||||
document.getElementById('commentProd_' + val['rowid']).addEventListener('click', showCommentProd)
|
||||
if (produitsCount[val['fk_produit']] < 2) {
|
||||
document.getElementById('duplicateProd_' + val['rowid']).addEventListener('click', duplicateLigneProduit)
|
||||
}
|
||||
if (parseFloat(remiseProduit) === 100) {
|
||||
document.getElementById('deleteProd_' + val['rowid']).addEventListener('click', deleteLigneProduit)
|
||||
}
|
||||
|
||||
// AJOUT DU 20/02/25 : on regarde si ce produit a un chk_prix_net et s'il est à 1 (marché hybride)
|
||||
if (val['chk_prix_net']) {
|
||||
console.log('on a un chk_prix_net : ' + val['chk_prix_net'])
|
||||
@@ -845,10 +912,12 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
|
||||
celRemisePro.innerHTML =
|
||||
'<div class="input-group"><input type="number" class="form-control numeric" id="inpRemise_' +
|
||||
val['fk_produit'] +
|
||||
val['rowid'] +
|
||||
'" name="inpRemise_' +
|
||||
val['fk_produit'] +
|
||||
'" data-rid="' +
|
||||
val['rowid'] +
|
||||
'" data-rowidligne="' +
|
||||
val['rowid'] +
|
||||
'" data-fkproduit="' +
|
||||
val['fk_produit'] +
|
||||
'" data-achat="' +
|
||||
val['prix_achat_net'] +
|
||||
@@ -860,16 +929,16 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
readonlyRemiseProduit +
|
||||
'/><div class="input-group-addon">%</div></div>'
|
||||
if (readonlyRemiseProduit == '') {
|
||||
document.getElementById('inpRemise_' + val['fk_produit']).addEventListener('change', calculDevis)
|
||||
document.getElementById('inpRemise_' + val['rowid']).addEventListener('change', calculDevis)
|
||||
}
|
||||
|
||||
// nouvelle colonne PU vente avec remise
|
||||
let celPUVenteRemPro = newRowPro.insertCell(5)
|
||||
celPUVenteRemPro.innerHTML =
|
||||
'<div class="input-group"><input type="text" class="form-control numeric" id="inpPUVenteRem_' +
|
||||
val['fk_produit'] +
|
||||
val['rowid'] +
|
||||
'" name="inpPUVenteRem_' +
|
||||
val['fk_produit'] +
|
||||
val['rowid'] +
|
||||
'" value="' +
|
||||
formatAmount(val['totalht']) +
|
||||
'" style="width: 100px; text-align: right;" readonly tabindex="-1" /><div class="input-group-addon">€</div></div>'
|
||||
@@ -878,9 +947,9 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
let celHTPro = newRowPro.insertCell(6)
|
||||
celHTPro.innerHTML =
|
||||
'<div class="input-group"><input type="text" class="form-control numeric" id="inpHT_' +
|
||||
val['fk_produit'] +
|
||||
val['rowid'] +
|
||||
'" name="inpHT_' +
|
||||
val['fk_produit'] +
|
||||
val['rowid'] +
|
||||
'" value="' +
|
||||
formatAmount(val['totalht']) +
|
||||
'" style="width: 100px; text-align: right;" readonly tabindex="-1" /><div class="input-group-addon">€</div></div>'
|
||||
@@ -889,10 +958,12 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
celVariante.className = 'text-center'
|
||||
celVariante.innerHTML =
|
||||
'<input type="checkbox" id="chkVariante_' +
|
||||
val['fk_produit'] +
|
||||
val['rowid'] +
|
||||
'" name="chkVariante_' +
|
||||
val['fk_produit'] +
|
||||
'" data-rid="' +
|
||||
val['rowid'] +
|
||||
'" data-rowidligne="' +
|
||||
val['rowid'] +
|
||||
'" data-fkproduit="' +
|
||||
val['fk_produit'] +
|
||||
'" data-achat="' +
|
||||
val['prix_achat_net'] +
|
||||
@@ -903,14 +974,14 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
'" ' +
|
||||
(val['chk_variante'] == 1 ? 'checked' : '') +
|
||||
' />'
|
||||
document.getElementById('chkVariante_' + val['fk_produit']).addEventListener('change', calculDevis)
|
||||
document.getElementById('chkVariante_' + val['rowid']).addEventListener('change', calculDevis)
|
||||
|
||||
let celMargePro = newRowPro.insertCell(8)
|
||||
celMargePro.innerHTML =
|
||||
'<div class="input-group"><input type="text" class="form-control numeric" id="inpMG_' +
|
||||
val['fk_produit'] +
|
||||
val['rowid'] +
|
||||
'" name="inpMG_' +
|
||||
val['fk_produit'] +
|
||||
val['rowid'] +
|
||||
'" value="' +
|
||||
val['marge'] +
|
||||
'" style="width: 80px; text-align: right;" readonly tabindex="-1" /><div class="input-group-addon">%</div></div>'
|
||||
@@ -996,7 +1067,7 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
document.getElementById('inp_latitudeDV').value = seuilMargeDV
|
||||
|
||||
// On simule le changement de quantité sur la première ligne pour recalculer les totaux
|
||||
const inpQte = document.getElementById('inpQte_' + fkProduit1)
|
||||
const inpQte = document.getElementById('inpQte_' + rowidLigne1)
|
||||
const event = new Event('change')
|
||||
inpQte.dispatchEvent(event)
|
||||
|
||||
@@ -2070,8 +2141,17 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
}
|
||||
// Fin de l'ajout du 26 juin 2024
|
||||
|
||||
// on récupère le premier fk_produit, pour simuler un changement sur ce produit pour recalculer les totaux en fin de boucle
|
||||
const fkProduit1 = data[0]['fk_produit']
|
||||
// on récupère le premier rowid, pour simuler un changement sur ce produit pour recalculer les totaux en fin de boucle
|
||||
const rowidLigne1 = data[0]['rowid']
|
||||
|
||||
// Compter les occurrences de chaque produit pour masquer le + si >= 2
|
||||
const produitsCount = {}
|
||||
for (let key in data) {
|
||||
if (data.hasOwnProperty(key)) {
|
||||
const fkProduit = data[key]['fk_produit']
|
||||
produitsCount[fkProduit] = (produitsCount[fkProduit] || 0) + 1
|
||||
}
|
||||
}
|
||||
|
||||
for (let key in data) {
|
||||
if (data.hasOwnProperty(key)) {
|
||||
@@ -2084,27 +2164,28 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
// on insère la ligne pour la saisie du commentaire au-dessus de la ligne du produit
|
||||
let newRowCom = tblBodyPro.insertRow(-1)
|
||||
newRowCom.className = 'hidden'
|
||||
newRowCom.id = 'trCom_' + val['fk_produit']
|
||||
newRowCom.dataset.rid = val['fk_produit']
|
||||
newRowCom.id = 'trCom_' + val['rowid']
|
||||
newRowCom.dataset.rowidligne = val['rowid']
|
||||
let celCom = newRowCom.insertCell(0)
|
||||
celCom.colSpan = 8
|
||||
celCom.innerHTML =
|
||||
'<div class="col-md-2"><label for="inpCom_' +
|
||||
val['fk_produit'] +
|
||||
val['rowid'] +
|
||||
'">Commentaire ' +
|
||||
val['code'] +
|
||||
': </label></div><div class="col-md-9"><input type="text" class="form-control w-75" id="inpCom_' +
|
||||
val['fk_produit'] +
|
||||
val['rowid'] +
|
||||
'" name="inpCom_' +
|
||||
val['fk_produit'] +
|
||||
val['rowid'] +
|
||||
'" value="' +
|
||||
val['commentaire'] +
|
||||
'" /></div>'
|
||||
|
||||
// Insertion d'une nouvelle ligne et création de ses colonnes
|
||||
let newRowPro = tblBodyPro.insertRow(-1)
|
||||
newRowPro.id = 'trPro_' + val['fk_produit']
|
||||
newRowPro.dataset.rid = val['fk_produit']
|
||||
newRowPro.id = 'trPro_' + val['rowid']
|
||||
newRowPro.dataset.rowidligne = val['rowid']
|
||||
newRowPro.dataset.fkproduit = val['fk_produit']
|
||||
newRowPro.dataset.ordre = val['ordre']
|
||||
newRowPro.dataset.code = val['code']
|
||||
newRowPro.dataset.achat = val['prix_achat_net']
|
||||
@@ -2124,27 +2205,7 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
newRowPro.dataset.quantite6 = val['quantite_6']
|
||||
|
||||
let celCodePro = newRowPro.insertCell(0)
|
||||
const svgColor = val['commentaire'] == '' ? 'lightgray' : 'red'
|
||||
const svgComment =
|
||||
'<svg id="commentProd_' +
|
||||
val['fk_produit'] +
|
||||
'" class="clickable" data-rid="' +
|
||||
val['fk_produit'] +
|
||||
'" data-code="' +
|
||||
val['code'] +
|
||||
'"><use xlink:href="pub/res/svg/icons.svg#message" style="fill: ' +
|
||||
svgColor +
|
||||
';"/></svg>'
|
||||
let inputOrdreHidden =
|
||||
'<input type="hidden" id="inpOrdre_' +
|
||||
val['fk_produit'] +
|
||||
'" name="inpOrdre_' +
|
||||
val['fk_produit'] +
|
||||
'" value="' +
|
||||
val['ordre'] +
|
||||
'" />'
|
||||
celCodePro.innerHTML = val['code'] + ' ' + svgComment + inputOrdreHidden
|
||||
document.getElementById('commentProd_' + val['fk_produit']).addEventListener('click', showCommentProd)
|
||||
celCodePro.style.whiteSpace = 'nowrap'
|
||||
|
||||
let celLibellePro = newRowPro.insertCell(1)
|
||||
celLibellePro.innerHTML = val['libelle']
|
||||
@@ -2156,10 +2217,12 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
let celQtePro = newRowPro.insertCell(3)
|
||||
celQtePro.innerHTML =
|
||||
'<input type="number" class="form-control numeric" id="inpQte_' +
|
||||
val['fk_produit'] +
|
||||
val['rowid'] +
|
||||
'" name="inpQte_' +
|
||||
val['fk_produit'] +
|
||||
'" data-rid="' +
|
||||
val['rowid'] +
|
||||
'" data-rowidligne="' +
|
||||
val['rowid'] +
|
||||
'" data-fkproduit="' +
|
||||
val['fk_produit'] +
|
||||
'" data-achat="' +
|
||||
val['prix_achat_net'] +
|
||||
@@ -2168,15 +2231,15 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
'" value="' +
|
||||
val['qte'] +
|
||||
'" min="0" max="1000" step="1" style="width: 100px; text-align: right;"/><input type="hidden" name="achat_' +
|
||||
val['fk_produit'] +
|
||||
val['rowid'] +
|
||||
'" value="' +
|
||||
val['prix_achat_net'] +
|
||||
'"/><input type="hidden" name="vente_' +
|
||||
val['fk_produit'] +
|
||||
val['rowid'] +
|
||||
'" value="' +
|
||||
val['prix_vente'] +
|
||||
'"/>'
|
||||
document.getElementById('inpQte_' + val['fk_produit']).addEventListener('change', calculDevis)
|
||||
document.getElementById('inpQte_' + val['rowid']).addEventListener('change', calculDevis)
|
||||
|
||||
let celRemisePro = newRowPro.insertCell(4)
|
||||
// Nouveau code 21/09
|
||||
@@ -2191,6 +2254,68 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
}
|
||||
// Fin du nouveau code du 21/09
|
||||
|
||||
// Colorisation si remise à 100% (gratuité)
|
||||
if (parseFloat(remiseProduit) === 100) {
|
||||
newRowPro.style.backgroundColor = 'rgba(138, 43, 226, 0.2)'
|
||||
}
|
||||
|
||||
// Remplissage de la cellule code produit (on le fait ici car on a besoin de remiseProduit)
|
||||
const svgColor = val['commentaire'] == '' ? 'lightgray' : 'red'
|
||||
const svgComment =
|
||||
'<svg id="commentProd_' +
|
||||
val['rowid'] +
|
||||
'" class="clickable" data-rowidligne="' +
|
||||
val['rowid'] +
|
||||
'" data-code="' +
|
||||
val['code'] +
|
||||
'"><use xlink:href="pub/res/svg/icons.svg#message" style="fill: ' +
|
||||
svgColor +
|
||||
';"/></svg>'
|
||||
|
||||
// N'afficher le + que si le produit apparaît moins de 2 fois dans le devis
|
||||
let svgDuplicate = ''
|
||||
if (produitsCount[val['fk_produit']] < 2) {
|
||||
svgDuplicate =
|
||||
'<svg id="duplicateProd_' +
|
||||
val['rowid'] +
|
||||
'" class="clickable" data-rowidligne="' +
|
||||
val['rowid'] +
|
||||
'" data-code="' +
|
||||
val['code'] +
|
||||
'" title="Dupliquer cette ligne"><use xlink:href="pub/res/svg/icons.svg#add" style="fill: green;"/></svg>'
|
||||
}
|
||||
|
||||
// N'afficher la trash que pour les produits dupliqués avec remise à 100%
|
||||
let svgDelete = ''
|
||||
if (parseFloat(remiseProduit) === 100) {
|
||||
svgDelete =
|
||||
'<svg id="deleteProd_' +
|
||||
val['rowid'] +
|
||||
'" class="clickable" data-rowidligne="' +
|
||||
val['rowid'] +
|
||||
'" data-code="' +
|
||||
val['code'] +
|
||||
'" title="Supprimer cette ligne"><use xlink:href="pub/res/svg/icons.svg#trash" style="fill: red;"/></svg>'
|
||||
}
|
||||
|
||||
let inputOrdreHidden =
|
||||
'<input type="hidden" id="inpOrdre_' +
|
||||
val['rowid'] +
|
||||
'" name="inpOrdre_' +
|
||||
val['rowid'] +
|
||||
'" value="' +
|
||||
val['ordre'] +
|
||||
'" />'
|
||||
celCodePro.innerHTML = val['code'] + ' ' + svgComment + ' ' + svgDuplicate + ' ' + svgDelete + inputOrdreHidden
|
||||
|
||||
document.getElementById('commentProd_' + val['rowid']).addEventListener('click', showCommentProd)
|
||||
if (produitsCount[val['fk_produit']] < 2) {
|
||||
document.getElementById('duplicateProd_' + val['rowid']).addEventListener('click', duplicateLigneProduit)
|
||||
}
|
||||
if (parseFloat(remiseProduit) === 100) {
|
||||
document.getElementById('deleteProd_' + val['rowid']).addEventListener('click', deleteLigneProduit)
|
||||
}
|
||||
|
||||
// 20/02/2025
|
||||
if (val['chk_prix_net']) {
|
||||
if (val['chk_prix_net'] == 1) {
|
||||
@@ -2201,10 +2326,12 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
|
||||
celRemisePro.innerHTML =
|
||||
'<div class="input-group"><input type="number" class="form-control numeric" id="inpRemise_' +
|
||||
val['fk_produit'] +
|
||||
val['rowid'] +
|
||||
'" name="inpRemise_' +
|
||||
val['fk_produit'] +
|
||||
'" data-rid="' +
|
||||
val['rowid'] +
|
||||
'" data-rowidligne="' +
|
||||
val['rowid'] +
|
||||
'" data-fkproduit="' +
|
||||
val['fk_produit'] +
|
||||
'" data-achat="' +
|
||||
val['prix_achat_net'] +
|
||||
@@ -2216,16 +2343,16 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
readonlyRemiseProduit +
|
||||
' /><div class="input-group-addon">%</div></div>'
|
||||
if (readonlyRemiseProduit == '') {
|
||||
document.getElementById('inpRemise_' + val['fk_produit']).addEventListener('change', calculDevis)
|
||||
document.getElementById('inpRemise_' + val['rowid']).addEventListener('change', calculDevis)
|
||||
}
|
||||
|
||||
// nouvelle colonne PU vente avec remise
|
||||
let celPUVenteRemPro = newRowPro.insertCell(5)
|
||||
celPUVenteRemPro.innerHTML =
|
||||
'<div class="input-group"><input type="text" class="form-control numeric" id="inpPUVenteRem_' +
|
||||
val['fk_produit'] +
|
||||
val['rowid'] +
|
||||
'" name="inpPUVenteRem_' +
|
||||
val['fk_produit'] +
|
||||
val['rowid'] +
|
||||
'" value="' +
|
||||
formatAmount(val['totalht']) +
|
||||
'" style="width: 100px; text-align: right;" readonly tabindex="-1" /><div class="input-group-addon">€</div></div>'
|
||||
@@ -2234,9 +2361,9 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
let celHTPro = newRowPro.insertCell(6)
|
||||
celHTPro.innerHTML =
|
||||
'<div class="input-group"><input type="text" class="form-control numeric" id="inpHT_' +
|
||||
val['fk_produit'] +
|
||||
val['rowid'] +
|
||||
'" name="inpHT_' +
|
||||
val['fk_produit'] +
|
||||
val['rowid'] +
|
||||
'" value="' +
|
||||
formatAmount(val['totalht']) +
|
||||
'" style="width: 100px; text-align: right;" readonly tabindex="-1" /><div class="input-group-addon">€</div></div>'
|
||||
@@ -2245,10 +2372,12 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
celVariante.className = 'text-center'
|
||||
celVariante.innerHTML =
|
||||
'<input type="checkbox" id="chkVariante_' +
|
||||
val['fk_produit'] +
|
||||
val['rowid'] +
|
||||
'" name="chkVariante_' +
|
||||
val['fk_produit'] +
|
||||
'" data-rid="' +
|
||||
val['rowid'] +
|
||||
'" data-rowidligne="' +
|
||||
val['rowid'] +
|
||||
'" data-fkproduit="' +
|
||||
val['fk_produit'] +
|
||||
'" data-achat="' +
|
||||
val['prix_achat_net'] +
|
||||
@@ -2259,14 +2388,14 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
'" ' +
|
||||
(val['chk_variante'] == 1 ? 'checked' : '') +
|
||||
' />'
|
||||
document.getElementById('chkVariante_' + val['fk_produit']).addEventListener('change', calculDevis)
|
||||
document.getElementById('chkVariante_' + val['rowid']).addEventListener('change', calculDevis)
|
||||
|
||||
let celMargePro = newRowPro.insertCell(8)
|
||||
celMargePro.innerHTML =
|
||||
'<div class="input-group"><input type="text" class="form-control numeric" id="inpMG_' +
|
||||
val['fk_produit'] +
|
||||
val['rowid'] +
|
||||
'" name="inpMG_' +
|
||||
val['fk_produit'] +
|
||||
val['rowid'] +
|
||||
'" value="' +
|
||||
val['marge'] +
|
||||
'" style="width: 80px; text-align: right;" readonly tabindex="-1" /><div class="input-group-addon">%</div></div>'
|
||||
@@ -2358,23 +2487,115 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
document.getElementById('inp_latitudeDV').value = seuilMargeDV
|
||||
|
||||
// On simule le changement de quantité sur la première ligne pour recalculer les totaux
|
||||
const inpQte = document.getElementById('inpQte_' + fkProduit1)
|
||||
const inpQte = document.getElementById('inpQte_' + rowidLigne1)
|
||||
const event = new Event('change')
|
||||
inpQte.dispatchEvent(event)
|
||||
}
|
||||
}
|
||||
|
||||
let showCommentProd = function () {
|
||||
console.log('click sur le SVG commentProd de la ligne ' + this.dataset.rid)
|
||||
document.getElementById('inp_commentProdId').value = this.dataset.rid
|
||||
console.log('click sur le SVG commentProd de la ligne ' + this.dataset.rowidligne)
|
||||
document.getElementById('inp_commentProdId').value = this.dataset.rowidligne
|
||||
document.getElementById('modCommentProdTitre').innerHTML = 'Commentaire sur le produit ' + this.dataset.code
|
||||
const inpComment = document.getElementById('inp_commentProd')
|
||||
inpComment.value = document.getElementById('inpCom_' + this.dataset.rid).value
|
||||
inpComment.value = document.getElementById('inpCom_' + this.dataset.rowidligne).value
|
||||
showModal(document.getElementById('modalCommentProd'))
|
||||
inpComment.focus()
|
||||
return false
|
||||
}
|
||||
|
||||
let duplicateLigneProduit = function () {
|
||||
const rowidLigne = this.dataset.rowidligne
|
||||
const codeProduit = this.dataset.code
|
||||
console.log('Duplication de la ligne ' + rowidLigne + ' - produit ' + codeProduit)
|
||||
|
||||
// Duplication directe en gratuité (remise 100%)
|
||||
duplicateLigne(rowidLigne, true)
|
||||
return false
|
||||
}
|
||||
|
||||
function duplicateLigne(rowidLigne, gratuite) {
|
||||
showLoading()
|
||||
|
||||
const data = {
|
||||
rowid_ligne: rowidLigne,
|
||||
gratuite: gratuite
|
||||
}
|
||||
|
||||
fetch('/jxdevis/duplicate_ligne_produit', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
})
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
hideLoading()
|
||||
showNotification('Erreur', 'La duplication de la ligne a échoué', 'error')
|
||||
throw new Error('Erreur lors de la duplication')
|
||||
}
|
||||
return response.json()
|
||||
})
|
||||
.then((ret) => {
|
||||
hideLoading()
|
||||
const message = gratuite ? 'Ligne dupliquée en GRATUITÉ' : 'Ligne dupliquée avec succès'
|
||||
showNotification('Succès', message, 'success')
|
||||
showDevisProduits(ret)
|
||||
chkChange = 1
|
||||
})
|
||||
.catch((error) => {
|
||||
hideLoading()
|
||||
console.error('Erreur:', error)
|
||||
showNotification('Erreur', 'Une erreur est survenue lors de la duplication', 'error')
|
||||
})
|
||||
}
|
||||
|
||||
let deleteLigneProduit = function () {
|
||||
const rowidLigne = this.dataset.rowidligne
|
||||
const codeProduit = this.dataset.code
|
||||
console.log('Suppression de la ligne ' + rowidLigne + ' - produit ' + codeProduit)
|
||||
|
||||
if (!confirm('Êtes-vous sûr de vouloir supprimer cette ligne ?\n\nProduit : ' + codeProduit)) {
|
||||
return false
|
||||
}
|
||||
|
||||
showLoading()
|
||||
|
||||
const data = {
|
||||
rowid_ligne: rowidLigne
|
||||
}
|
||||
|
||||
fetch('/jxdevis/delete_ligne_produit', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
})
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
hideLoading()
|
||||
showNotification('Erreur', 'La suppression de la ligne a échoué', 'error')
|
||||
throw new Error('Erreur lors de la suppression')
|
||||
}
|
||||
return response.json()
|
||||
})
|
||||
.then((ret) => {
|
||||
hideLoading()
|
||||
showNotification('Succès', 'Ligne supprimée avec succès', 'success')
|
||||
showDevisProduits(ret)
|
||||
chkChange = 1
|
||||
})
|
||||
.catch((error) => {
|
||||
hideLoading()
|
||||
console.error('Erreur:', error)
|
||||
showNotification('Erreur', 'Une erreur est survenue lors de la suppression', 'error')
|
||||
})
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
function controlRemisesProduits(totalHT) {
|
||||
// Contrôle des remises du marché en fonction du total HT du devis
|
||||
|
||||
@@ -2424,8 +2645,8 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
}
|
||||
}
|
||||
|
||||
function getPrixAchatAvecDiscount(idProduit, qte) {
|
||||
let trPro = document.getElementById('trPro_' + idProduit)
|
||||
function getPrixAchatAvecDiscount(rowidLigne, qte) {
|
||||
let trPro = document.getElementById('trPro_' + rowidLigne)
|
||||
const prixAchat = parseFloat(trPro.dataset.achat)
|
||||
const qtt = parseInt(qte, 10)
|
||||
// console.log("==== Début de getPrixAchatAvecDiscount pour la ref " + trPro.dataset.code + " : prix achat " + prixAchat + " et qte " + qtt);
|
||||
@@ -2448,8 +2669,8 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
// on applique le prc_discount
|
||||
prixAchatDiscount = prixAchat - (prixAchat * dscnt) / 100
|
||||
console.log(
|
||||
'=== idProduit : ' +
|
||||
idProduit +
|
||||
'=== rowidLigne : ' +
|
||||
rowidLigne +
|
||||
' (prc_discount_' +
|
||||
inc +
|
||||
' applique de ' +
|
||||
@@ -2474,15 +2695,15 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
|
||||
let calculDevis = function () {
|
||||
console.log('calculDevis...')
|
||||
const idProduit = this.dataset.rid
|
||||
const rowidLigne = this.dataset.rowidligne
|
||||
|
||||
// On récupère toutes les infos de ce produit au niveau de sa ligne trPro_XX stockées en dataset
|
||||
let trPro = document.getElementById('trPro_' + idProduit)
|
||||
let trPro = document.getElementById('trPro_' + rowidLigne)
|
||||
const code = trPro.dataset.code
|
||||
let prixAchat = trPro.dataset.achat
|
||||
const prixVente = trPro.dataset.vente
|
||||
|
||||
// console.log("idProduit: " + idProduit + ", code : " + code + ", prixAchat: " + prixAchat + ", prixVente: " + prixVente);
|
||||
// console.log("rowidLigne: " + rowidLigne + ", code : " + code + ", prixAchat: " + prixAchat + ", prixVente: " + prixVente);
|
||||
|
||||
let qte = 0
|
||||
let remise = 0
|
||||
@@ -2491,20 +2712,20 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
if (this.name.indexOf('inpQte') > -1) {
|
||||
// c'est la quantité qui a changé
|
||||
qte = this.value
|
||||
remise = document.getElementById('inpRemise_' + idProduit).value
|
||||
variante = document.getElementById('chkVariante_' + idProduit).checked
|
||||
remise = document.getElementById('inpRemise_' + rowidLigne).value
|
||||
variante = document.getElementById('chkVariante_' + rowidLigne).checked
|
||||
typeInput = 'qte'
|
||||
} else if (this.name.indexOf('inpRemise') > -1) {
|
||||
// c'est la remise qui a changé
|
||||
qte = document.getElementById('inpQte_' + idProduit).value
|
||||
qte = document.getElementById('inpQte_' + rowidLigne).value
|
||||
remise = this.value
|
||||
variante = document.getElementById('chkVariante_' + idProduit).checked
|
||||
variante = document.getElementById('chkVariante_' + rowidLigne).checked
|
||||
typeInput = 'remise'
|
||||
chkSaisieRemise = true
|
||||
} else if (this.name.indexOf('chkVariante') > -1) {
|
||||
// c'est la variante qui a changé
|
||||
qte = document.getElementById('inpQte_' + idProduit).value
|
||||
remise = document.getElementById('inpRemise_' + idProduit).value
|
||||
qte = document.getElementById('inpQte_' + rowidLigne).value
|
||||
remise = document.getElementById('inpRemise_' + rowidLigne).value
|
||||
variante = this.checked
|
||||
typeInput = 'variante'
|
||||
}
|
||||
@@ -2526,7 +2747,7 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
totalHt = (prixVente * 1 - remiseProduit * 1) * (qte * 1)
|
||||
}
|
||||
|
||||
let inpHT = document.getElementById('inpHT_' + idProduit)
|
||||
let inpHT = document.getElementById('inpHT_' + rowidLigne)
|
||||
inpHT.value = parseFloat(totalHt).toFixed(2)
|
||||
|
||||
// Modif du 25/04 : on calcule la marge même si c'est une variante / option
|
||||
@@ -2552,8 +2773,8 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
} else {
|
||||
txMarge = 0
|
||||
console.log(
|
||||
'ERREUR idProduit : ' +
|
||||
idProduit +
|
||||
'ERREUR rowidLigne : ' +
|
||||
rowidLigne +
|
||||
', code : ' +
|
||||
code +
|
||||
' - prixAchat : ' +
|
||||
@@ -2569,22 +2790,22 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
)
|
||||
}
|
||||
//}
|
||||
let inpMG = document.getElementById('inpMG_' + idProduit)
|
||||
let inpMG = document.getElementById('inpMG_' + rowidLigne)
|
||||
inpMG.value = parseFloat(txMarge).toFixed(2)
|
||||
|
||||
console.log('Boucle 1 : calcul Total HT sans remise')
|
||||
//! on boucle sur tous les éléments dont le name commence par inpQte_ pour calculer le total HT sans remise
|
||||
for (let i = 0, elInp; (elInp = document.querySelectorAll("[name ^= 'inpQte_' ]")[i]); i++) {
|
||||
const idProd = elInp.dataset.rid
|
||||
const ligne = document.getElementById('trPro_' + idProd)
|
||||
const rowidLigneProd = elInp.dataset.rowidligne
|
||||
const ligne = document.getElementById('trPro_' + rowidLigneProd)
|
||||
const code = ligne.dataset.code
|
||||
const vente = ligne.dataset.vente * 1
|
||||
const qte = elInp.value * 1
|
||||
// Mise à jour du 09/11 : on calcule le prix d'achat du produit avec éventuel discount suivant sa qté
|
||||
const achat = getPrixAchatAvecDiscount(idProd, elInp.value)
|
||||
const achat = getPrixAchatAvecDiscount(rowidLigneProd, elInp.value)
|
||||
// Fin de la mise à jour du 09/11
|
||||
|
||||
const varOption = document.getElementById('chkVariante_' + idProd).checked
|
||||
const varOption = document.getElementById('chkVariante_' + rowidLigneProd).checked
|
||||
if (!varOption) {
|
||||
// calcul avec juste la quantité et le prix de vente
|
||||
const vente = elInp.dataset.vente * 1
|
||||
@@ -2593,14 +2814,14 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
|
||||
// Mise à jour du 03/11/2023 : nouvelle colonne du Prix de Vente Unitaire (avec remise)
|
||||
// On met à jour le PUVenteRem sur la ligne
|
||||
const remProd = document.getElementById('inpRemise_' + idProd).value
|
||||
const remProd = document.getElementById('inpRemise_' + rowidLigneProd).value
|
||||
const remise = remProd * 1
|
||||
|
||||
let puVenteApresRemise = vente
|
||||
if (remise > 0) {
|
||||
puVenteApresRemise = vente - (vente * remise) / 100
|
||||
}
|
||||
document.getElementById('inpPUVenteRem_' + idProd).value = puVenteApresRemise.toFixed(2)
|
||||
document.getElementById('inpPUVenteRem_' + rowidLigneProd).value = puVenteApresRemise.toFixed(2)
|
||||
console.log('--- 1 Produit : ' + code + ' - PUVenteApresRemise : ' + puVenteApresRemise)
|
||||
// Fin de la mise à jour du 03/11/2023
|
||||
|
||||
@@ -2638,7 +2859,7 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
)
|
||||
}
|
||||
//}
|
||||
let inpMG = document.getElementById('inpMG_' + idProd)
|
||||
let inpMG = document.getElementById('inpMG_' + rowidLigneProd)
|
||||
inpMG.value = parseFloat(txMarge).toFixed(2)
|
||||
}
|
||||
|
||||
@@ -2663,8 +2884,8 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
//! on boucle sur tous les éléments dont le name commence par inpRemise_ pour calculer le total HT avec remise
|
||||
for (let i = 0, elInp; (elInp = document.querySelectorAll("[name ^= 'inpRemise_' ]")[i]); i++) {
|
||||
// calcul avec la quantité, le prix de vente et la remise
|
||||
const idProd = elInp.dataset.rid
|
||||
const ligne = document.getElementById('trPro_' + idProd)
|
||||
const rowidLigneProd = elInp.dataset.rowidligne
|
||||
const ligne = document.getElementById('trPro_' + rowidLigneProd)
|
||||
const vente = ligne.dataset.vente * 1
|
||||
const achat = ligne.dataset.achatdiscount * 1
|
||||
const rem = elInp.value * 1
|
||||
@@ -2689,9 +2910,9 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
// elInp.readOnly = false;
|
||||
}
|
||||
|
||||
const varOption = document.getElementById('chkVariante_' + idProd).checked
|
||||
const varOption = document.getElementById('chkVariante_' + rowidLigneProd).checked
|
||||
if (!varOption) {
|
||||
const inpQte = document.getElementById('inpQte_' + idProd)
|
||||
const inpQte = document.getElementById('inpQte_' + rowidLigneProd)
|
||||
const qte = inpQte.value
|
||||
const remiseProduit = (remise * vente) / 100
|
||||
|
||||
@@ -2701,8 +2922,8 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
console.log(
|
||||
'--- 2 ligne code ' +
|
||||
ligne.dataset.code +
|
||||
' = idProd : ' +
|
||||
idProd +
|
||||
' = rowidLigneProd : ' +
|
||||
rowidLigneProd +
|
||||
', vente : ' +
|
||||
vente +
|
||||
', achat : ' +
|
||||
@@ -3473,7 +3694,7 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
inputs.forEach((input) => (input.disabled = false))
|
||||
|
||||
// Ajouter un événement click à l'élément svg
|
||||
const svgElement = dropElem.querySelector('#commentProd_' + dropElem.dataset.rid)
|
||||
const svgElement = dropElem.querySelector('#commentProd_' + dropElem.dataset.rowidligne)
|
||||
svgElement.addEventListener('click', showCommentProd)
|
||||
|
||||
addDnDHandlers(dropElem)
|
||||
@@ -3495,9 +3716,9 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
const sonCode = row.dataset.code
|
||||
if (sonCode) {
|
||||
row.dataset.ordre = index + 1
|
||||
const fkProduit = row.dataset.rid
|
||||
const rowidLigne = row.dataset.rowidligne
|
||||
console.log('index : ' + index + ' code : ' + sonCode)
|
||||
document.getElementById('inpOrdre_' + fkProduit).value = index
|
||||
document.getElementById('inpOrdre_' + rowidLigne).value = index
|
||||
}
|
||||
})
|
||||
showNotification(
|
||||
|
||||
Reference in New Issue
Block a user