diff --git a/docs/qlik-integration.md b/docs/qlik-integration.md index 682900c..c418c25 100644 --- a/docs/qlik-integration.md +++ b/docs/qlik-integration.md @@ -35,6 +35,17 @@ ceux-là qu'on veut voir. Repli : si Qlik est injoignable, la recherche retombe sur `pgSearchProduits()` et la réponse le signale (`source: "db"`). Résultats mis en cache mémoire 10 min. +Les noms des champs libellé / fournisseur varient d'une app Qlik à l'autre : ils +sont détectés par heuristique, et l'inventaire complet des champs est loggué +(`[qlik-search] champs disponibles=…`). Si la détection tombe à côté, forcer : + +``` +QLIK_FIELD_ARTICLE_LIBELLE= +QLIK_FIELD_FOURNISSEUR= +``` + +Sans champ libellé exploitable, la recherche fonctionne encore par code centrale. + ## Tendance réseau = 12 mois glissants stricts `computeNetworkTrend()` reconstruit sa fenêtre à partir de la date du jour : diff --git a/src/lib/qlik-search.ts b/src/lib/qlik-search.ts index 5a11278..f85815d 100644 --- a/src/lib/qlik-search.ts +++ b/src/lib/qlik-search.ts @@ -128,8 +128,9 @@ export async function searchQlikArticles( if (!csrfToken) throw new Error("[qlik-search] qlik-csrf-token introuvable (client Qlik non chargé ?)"); const result = (await page.evaluate( - ({ app, dim, token, terme, limite, maxFieldMatches }: { + ({ app, dim, token, terme, limite, maxFieldMatches, champLibelleForce, champFournisseurForce }: { app: string; dim: string; token: string; terme: string; limite: number; maxFieldMatches: number; + champLibelleForce: string; champFournisseurForce: string; }) => new Promise((resolve) => { const loc = (window as unknown as { location: Location }).location; @@ -182,12 +183,20 @@ export async function searchQlikArticles( const champCode = champs.find((c) => c === "Article Code") ?? champs.find((c) => has(c, /article/i) && has(c, /code/i)) ?? "Article Code"; - const champLibelle = champs.find((c) => has(c, /article/i) && has(c, /(libell|designation|désignation|denomination|dénomination)/i)) + // Les noms exacts varient selon l'app Qlik : détection par + // heuristique, surchargeable par variable d'environnement si + // l'app expose un intitulé inattendu (cf. les logs [qlik-search]). + const champLibelle = (champLibelleForce && champs.includes(champLibelleForce) ? champLibelleForce : null) + ?? champs.find((c) => has(c, /article/i) && has(c, /(libell|designation|désignation|denomination|dénomination)/i)) ?? champs.find((c) => has(c, /(libell|designation|désignation)/i) && !has(c, /(magasin|region|région|famille|rayon|fournisseur)/i)) ?? null; - const champFournisseur = champs.find((c) => has(c, /fournisseur/i)) + const champFournisseur = (champFournisseurForce && champs.includes(champFournisseurForce) ? champFournisseurForce : null) + ?? champs.find((c) => has(c, /fournisseur/i)) ?? champs.find((c) => has(c, /(fabricant|supplier)/i)) ?? null; + // Inventaire complet en trace : sans accès Qlik depuis le poste + // de dev, c'est le seul moyen de régler les surcharges ci-dessus. + trace.push("champs disponibles=" + JSON.stringify(champs)); trace.push("code=" + champCode + " libelle=" + champLibelle + " fournisseur=" + champFournisseur); // ─── 2. Recherche globale Qlik ─────────────────────────── @@ -295,6 +304,8 @@ export async function searchQlikArticles( terme: cleaned, limite: limit, maxFieldMatches: MAX_FIELD_MATCHES, + champLibelleForce: (process.env.QLIK_FIELD_ARTICLE_LIBELLE ?? "").trim(), + champFournisseurForce: (process.env.QLIK_FIELD_FOURNISSEUR ?? "").trim(), }, )) as InPageSearchResult;