mirror of
https://github.com/R0m1k3/CollectFlow.git
synced 2026-10-15 19:28:52 +02:00
Prix de vente : tenir compte d'un prix non ventilé par magasin
`cube_pv` a une clé `(artnoid, site)`, mais la base n'en porte qu'une ligne par article — 428 530 lignes pour 427 857 articles, là où deux magasins tarifés en donneraient le double. Le prix n'est donc pas ventilé : la colonne serait restée vide dès qu'on consulte le magasin qui n'a pas la ligne, alors même que l'article a un prix. La cellule couvre maintenant les quatre cas : le prix du magasin consulté quand il existe ; le prix unique quand il n'y a qu'un tarif, avec la mention « prix unique, non ventilé par magasin » ; rien quand plusieurs prix coexistent sans concerner ce magasin — celui du voisin n'est pas le sien ; et, en « tous magasins », le prix commun ou le plus élevé assorti du « ≠ ». Vérifié sur build de production, quatre articles couvrant les quatre cas, dans les trois modes de magasin. Le cas décisif : prix porté par le seul site 292, consulté depuis Houdemont — 12,90 € et la mention, au lieu du « - » d'avant. La route de diagnostic est retirée : `cube_pv` est confirmé alimenté et synchronisé, elle a fait son office. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EYGgoQCG1VCe42HzbzhAXR
This commit is contained in:
2 files changed
+29
-183
No files matched your search
@@ -96,29 +96,43 @@ const fmtEuro2 = (v: number) =>
|
||||
/**
|
||||
* Prix de vente à montrer pour le magasin consulté.
|
||||
*
|
||||
* Sur un magasin donné, c'est SON prix. En « tous magasins », c'est le prix
|
||||
* commun — et s'ils divergent, le plus élevé assorti d'un signal : une cellule
|
||||
* ne peut afficher qu'un nombre, mais taire l'écart ferait passer le prix d'un
|
||||
* magasin pour celui des deux.
|
||||
* `cube_pv` a une clé `(artnoid, site)`, mais notre base n'y met en pratique
|
||||
* qu'une ligne par article : le prix n'est pas ventilé par magasin. La colonne
|
||||
* doit donc rester lisible dans les deux cas de figure —
|
||||
*
|
||||
* · magasin consulté tarifé → SON prix ;
|
||||
* · prix unique, non ventilé → ce prix vaut pour tous les magasins ;
|
||||
* · plusieurs prix mais aucun pour ce magasin → rien, plutôt que celui du
|
||||
* voisin ;
|
||||
* · en « tous magasins » : le prix commun, et s'ils divergent le plus élevé
|
||||
* assorti d'un signal. Une cellule ne peut afficher qu'un nombre, mais
|
||||
* taire l'écart ferait passer le prix d'un magasin pour celui des deux.
|
||||
*/
|
||||
function prixVenteAffiche(row: ProductRow, activeMagasin: string): { valeur: number | null; divergent: boolean; detail: string | null } {
|
||||
const parSite = row.prixVenteByStore;
|
||||
const entrees = Object.entries(row.prixVenteByStore ?? {});
|
||||
|
||||
if (activeMagasin !== "TOTAL") {
|
||||
const pv = parSite?.[activeMagasin];
|
||||
return { valeur: pv ?? null, divergent: false, detail: null };
|
||||
}
|
||||
|
||||
const entrees = Object.entries(parSite ?? {});
|
||||
// Aucun prix ventilé : reste le PV de la fiche article, s'il existe.
|
||||
if (entrees.length === 0) return { valeur: row.prixVente ?? null, divergent: false, detail: null };
|
||||
|
||||
// Comparaison au centime : deux flottants issus du même prix peuvent différer
|
||||
// dans les décimales lointaines sans que le prix affiché change.
|
||||
const distincts = new Set(entrees.map(([, pv]) => Math.round(pv * 100)));
|
||||
const detail = entrees
|
||||
.sort(([a], [b]) => a.localeCompare(b))
|
||||
.map(([site, pv]) => `${SITE_LABELS[site]?.nom ?? site} : ${fmtEuro2(pv)}`)
|
||||
.join(" · ");
|
||||
|
||||
if (activeMagasin !== "TOTAL") {
|
||||
const pv = row.prixVenteByStore?.[activeMagasin];
|
||||
if (pv != null) return { valeur: pv, divergent: false, detail: null };
|
||||
if (distincts.size === 1) {
|
||||
return { valeur: entrees[0][1], divergent: false, detail: "prix unique, non ventilé par magasin" };
|
||||
}
|
||||
return { valeur: null, divergent: false, detail: null };
|
||||
}
|
||||
|
||||
const detail = entrees.length > 1
|
||||
? entrees
|
||||
.sort(([a], [b]) => a.localeCompare(b))
|
||||
.map(([site, pv]) => `${SITE_LABELS[site]?.nom ?? site} : ${fmtEuro2(pv)}`)
|
||||
.join(" · ")
|
||||
: null;
|
||||
|
||||
return {
|
||||
valeur: Math.max(...entrees.map(([, pv]) => pv)),
|
||||
|
||||
Reference in new issue
Block a user