- {detail.codein} - {detail.code_centrale && <> · centrale {detail.code_centrale}>} - {fournisseurPrincipal && <> · {fournisseurPrincipal.nomfou}>} + {detail && <>{detail.codein}{" · "}>} + {codeCentrale && <>centrale {codeCentrale}>} + {fournisseurAffiche && <> · {fournisseurAffiche}>}
Aucune ligne de stock pour ce produit.
- ) : ( -| - Mois - | - {months.map((m) => ( -- {formatMonthLabel(m)} - | - ))} -
|---|---|
| - Ventes - | - {months.map((m) => ( -
- |
- ))}
-
| - CA (TTC) - | - {months.map((m) => ( -- {serie[m]?.ca ? Math.round(serie[m].ca).toLocaleString("fr-FR") : "—"} - | - ))} -
| - Stock fin de mois - | - {months.map((m) => ( -- {serie[m]?.stockFinMois ? Math.round(serie[m].stockFinMois).toLocaleString("fr-FR") : "—"} - | - ))} -
Ce produit n'a pas de code centrale : il n'est pas référencé centralement et n'existe donc pas dans Qlik.
@@ -369,18 +233,29 @@ export function ProduitFicheView({ fiche, backQuery }: { fiche: ProduitFiche; ba ) : ( <> -- Période {reseau.periode ?? "12 mois"} · extrait le {formatDate(reseau.fetchedAt)} + Période {reseau.periode ?? "12 mois"} · extrait le {formatDate(reseau.fetchedAt)} · + {" "}mois en cours exclu (incomplet).
{trend.hasData && ( @@ -421,18 +302,14 @@ export function ProduitFicheView({ fiche, backQuery }: { fiche: ProduitFiche; ba - {([ - { key: "qte", label: "Quantité", fmt: (v: number) => fmtQte(v) }, - { key: "ca", label: "CA", fmt: (v: number) => Math.round(v).toLocaleString("fr-FR") }, - { key: "nbMag", label: "Magasins", fmt: (v: number) => fmtQte(v) }, - { key: "margePct", label: "Marge %", fmt: (v: number) => `${fmtDec(Math.abs(v) <= 1 ? v * 100 : v)} %` }, - ] as const).map((row) => ( -+ {fournisseurReseau + ? <>Aucun fournisseur référencé chez nous. Côté réseau, Qlik indique {fournisseurReseau}.> + : "Aucun fournisseur référencé pour ce produit."} +
+ ) : ( ++ Fournisseur côté Qlik : {fournisseurReseau} +
+ )} +Aucune ligne de stock pour ce produit.
+ ) : ( +| + Mois + | + {months.map((m) => ( ++ {formatMonthLabel(m)} + | + ))} +
|---|---|
| + Ventes + | + {months.map((m) => ( +
+ |
+ ))}
+
| + CA (TTC) + | + {months.map((m) => ( ++ {serie[m]?.ca ? Math.round(serie[m].ca).toLocaleString("fr-FR") : "—"} + | + ))} +
| + Stock fin de mois + | + {months.map((m) => ( ++ {serie[m]?.stockFinMois ? Math.round(serie[m].stockFinMois).toLocaleString("fr-FR") : "—"} + | + ))} +
- Par libellé ou par code centrale — ventes sur 12 mois glissants et données réseau Qlik. + Recherche dans Qlik Sense (réseau) puis rapprochement avec notre catalogue — + performance réseau et ventes locales sur 12 mois glissants.
{/* key : remonte le champ quand l'URL change (retour arrière, lien partagé) */}- Recherchez un produit + Recherchez un produit dans le réseau
-+
+ La recherche interroge Qlik Sense (les ~{NB_MAGASINS_RESEAU} magasins du réseau), + puis rapproche chaque produit trouvé de notre catalogue. Saisissez un libellé (ex. « poêle 28 ») ou un code centrale (ex. « 10000167303 »).
+ Interrogation de Qlik Sense… +
++ Recherche des articles du réseau puis extraction de leurs ventes sur 12 mois glissants. + Cela peut prendre jusqu'à une minute. +
- {rows.length} produit{rows.length > 1 ? "s" : ""} trouvé{rows.length > 1 ? "s" : ""} - {rows.length >= 50 && " (50 premiers — affinez la recherche)"} -
+ if (error) { + return ( ++ La recherche a échoué +
+{error}
+ +| Libellé | -Fournisseur | -Code article | -Code centrale | -Famille | -Stock | -Qté réseau | -
|---|---|---|---|---|---|---|
|
+ if (!data) return null;
+
+ const { rows, source, qlikError, tronque, locauxHorsReseau, dureeMs } = data;
+
+ return (
+
+
+
+
+ {source === "db" && (
+
+ {source === "qlik" ? (
+
+
+ )}
+
+ {source === "qlik" && qlikError && (
+
+ Articles trouvés, mais l'extraction des mesures réseau a échoué : {qlikError}
+
+ )}
+
+ {rows.length === 0 ? (
+
+ Aucun article du réseau ne correspond à « {query} ».
+
+ ) : (
+
+ + {locauxHorsReseau.length} produit{locauxHorsReseau.length > 1 ? "s" : ""} de notre catalogue + sans correspondance réseau (pas de code centrale, ou non vendu par le réseau) ++
+
|
- - {r.fournisseur || "—"} - | -- {r.codein} - | -- {r.code_centrale || "—"} - | -- {r.nomenclature || "—"} - | -- {fmtQte(r.stock_total)} - | -
- {r.has_reseau ? (
-
- |
-
| Libellé | +Fournisseur | +Code centrale | +Magasins | +Qté réseau | +Qté / mag. | +Prix moyen | +CA / mag. | +Marge % | +Tendance | +Nous | +
|---|---|---|---|---|---|---|---|---|---|---|
|
+
+ {r.libelle || "—"}
+
+ {r.nomenclature && (
+ {r.nomenclature}
+ )}
+ |
+ + {r.fournisseur || "—"} + | ++ {r.codeCentrale} + | ++ {fmtQte(r.nbMagasinsReseau)} + + {fmtDec(r.tauxPresence * 100, 0)} % + + | ++ {fmtQte(r.qteReseau)} + | ++ {fmtDec(r.qteParMagasinReseau)} + | ++ {r.prixMoyenReseau != null ? fmtEur2(r.prixMoyenReseau) : "—"} + | ++ {r.caParMagasinReseau > 0 ? fmtEur(r.caParMagasinReseau) : "—"} + | ++ {r.margePctReseau != null ? `${fmtDec(r.margePctReseau)} %` : "—"} + | +
+ {trend.hasData ? |
+ + {r.codein ? ( + + stock {fmtQte(r.stockLocal ?? 0)} + + ) : ( + + non référencé + + )} + | +