fix: nomenclature CA - valeurs absolues, GenreMvt IN(3,4,9), traversée hiérarchie
- CA était négatif (MntMvtTTC brut) → filtre mntmvtttc < 0 + ABS comme le endpoint /ca - GenreMvt=3 uniquement → IN(3,4,9) - Niveau 1/2 retournait vide (articles au niveau 3) → remontée via chemin_pere chemin_pere = "no_id_niv1.no_id_niv2" → SPLIT_PART + JOIN NOMENCLATURE parent - Ajout taux_marge dans la réponse Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
c1d6f87a7e
commit
57e9449a58
1 file changed
+25
-14
+25
-14
@@ -91,33 +91,44 @@ router.get('/hitparade', async (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// GET /api/performance/ca/nomenclature?dateDebut=&dateFin=&site=&niveau=
|
// GET /api/performance/ca/nomenclature?dateDebut=&dateFin=&site=&niveau=
|
||||||
|
// Articles sont stockés au niveau 3. Pour niveau=1 ou 2, on remonte via chemin_pere (format "noid_niv1.noid_niv2").
|
||||||
router.get('/ca/nomenclature', async (req, res) => {
|
router.get('/ca/nomenclature', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const pool = getPool();
|
const pool = getPool();
|
||||||
const { dateDebut = '2024-01-01', dateFin = '2099-12-31', site = '', niveau = 1 } = req.query;
|
const { dateDebut = '2024-01-01', dateFin = '2099-12-31', site = '', niveau = 1 } = req.query;
|
||||||
|
const niv = Math.max(1, Math.min(parseInt(niveau) || 1, 3));
|
||||||
|
|
||||||
|
// Pour niveau 1 ou 2 : remonter la hiérarchie via chemin_pere de la nomenclature niveau 3
|
||||||
|
// chemin_pere = "no_id_niv1.no_id_niv2" → SPLIT_PART(..., niv)
|
||||||
|
const joinNom = niv === 3
|
||||||
|
? `JOIN NOMENCLATURE n ON n.NO_ID = a.NOM_NO_ID`
|
||||||
|
: `JOIN NOMENCLATURE n3 ON n3.NO_ID = a.NOM_NO_ID
|
||||||
|
JOIN NOMENCLATURE n ON n.NO_ID = NULLIF(SPLIT_PART(n3.chemin_pere, '.', ${niv}), '')::bigint`;
|
||||||
|
|
||||||
const result = await pool.query(`
|
const result = await pool.query(`
|
||||||
SELECT
|
SELECT
|
||||||
n.CODE AS CODE_NOMEN,
|
n.CODE AS code_nomen,
|
||||||
n.LIBELLE,
|
n.LIBELLE,
|
||||||
n.NIVEAU,
|
${niv} AS niveau,
|
||||||
COUNT(DISTINCT m.ArtNoId) AS NB_ARTICLES,
|
COUNT(DISTINCT m.ArtNoId) AS nb_articles,
|
||||||
SUM(m.QteMvt) AS QTE_VENDUE,
|
ABS(SUM(CASE WHEN m.mntmvtttc < 0 THEN m.qtemvt ELSE 0 END)) AS qte_vendue,
|
||||||
SUM(m.MntMvtHt) AS CA_HT,
|
ABS(SUM(CASE WHEN m.mntmvtttc < 0 THEN m.mntmvtht ELSE 0 END)) AS ca_ht,
|
||||||
SUM(m.MntMvtTTC) AS CA_TTC,
|
ABS(SUM(CASE WHEN m.mntmvtttc < 0 THEN m.mntmvtttc ELSE 0 END)) AS ca_ttc,
|
||||||
SUM(m.MargeMvt) AS MARGE
|
SUM(m.MargeMvt) AS marge,
|
||||||
|
CASE WHEN SUM(m.mntmvtht) != 0
|
||||||
|
THEN ROUND(SUM(m.margemvt) / ABS(SUM(m.mntmvtht)) * 100, 2)
|
||||||
|
ELSE 0 END AS taux_marge
|
||||||
FROM MvtArt m
|
FROM MvtArt m
|
||||||
JOIN ARTICLES a ON a.NO_ID = m.ArtNoId
|
JOIN ARTICLES a ON a.NO_ID = m.ArtNoId
|
||||||
JOIN NOMENCLATURE n ON n.NO_ID = a.NOM_NO_ID
|
${joinNom}
|
||||||
WHERE m.GenreMvt = 3
|
WHERE m.GenreMvt IN (3, 4, 9)
|
||||||
AND m.DatMvt BETWEEN $1 AND $2
|
AND m.DatMvt BETWEEN $1 AND $2
|
||||||
AND m.Site LIKE $3
|
AND m.Site LIKE $3
|
||||||
AND n.NIVEAU = $4
|
GROUP BY n.CODE, n.LIBELLE
|
||||||
GROUP BY n.CODE, n.LIBELLE, n.NIVEAU
|
ORDER BY ca_ttc DESC
|
||||||
ORDER BY CA_TTC DESC
|
`, [dateDebut, dateFin, `%${site}%`]);
|
||||||
`, [dateDebut, dateFin, `%${site}%`, parseInt(niveau)]);
|
|
||||||
|
|
||||||
res.json({ dateDebut, dateFin, niveau: parseInt(niveau), ca_par_nomenclature: result.rows });
|
res.json({ dateDebut, dateFin, niveau: niv, ca_par_nomenclature: result.rows });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
res.status(500).json({ error: err.message });
|
res.status(500).json({ error: err.message });
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user