mirror of
https://github.com/R0m1k3/CollectFlow.git
synced 2026-10-11 17:26:32 +02:00
feat(qlik): 12 mois glissants contigus via passe complémentaire année N-1
Le graphe sautait de 07/25 à 01/26 : l'astuce COMP ne fournit un mois N-1 que s'il existe un mois N correspondant. L'année N s'arrêtant au mois courant (juillet), les mois août→décembre N-1 étaient introuvables. Ajout d'une passe complémentaire : on sélectionne le champ 'Année' sur N-1, ce qui fait porter les mesures 'N' sur cette année → ses 12 mois sont récupérés directement (prioritaires sur les valeurs COMP dérivées). Les totaux réseau (CA/Qté) ne sont alimentés que par la passe principale pour éviter tout double comptage. Passe ignorée proprement si le champ 'Année' est absent ou si elle échoue. Résultat attendu : mois contigus 2025-08 → 2026-07 dans le modal (l'UI garde les 12 derniers mois triés).
This commit is contained in:
1 file changed
+46
-13
+46
-13
@@ -246,8 +246,13 @@ export async function fetchNetworkMetricsPlaywright(
|
||||
// Handles des champs Date / Article Code.
|
||||
let dfh = -1;
|
||||
let fh = -1;
|
||||
let yfh = -1;
|
||||
const df = await rpc("GetField", { qFieldName: "Date" }, doc);
|
||||
dfh = (df.qReturn as { qHandle: number }).qHandle;
|
||||
try {
|
||||
const yf = await rpc("GetField", { qFieldName: "Année" }, doc);
|
||||
yfh = (yf.qReturn as { qHandle: number }).qHandle;
|
||||
} catch { yfh = -1; }
|
||||
if (codes.length) {
|
||||
const gf = await rpc("GetField", { qFieldName: "Article Code" }, doc);
|
||||
fh = (gf.qReturn as { qHandle: number }).qHandle;
|
||||
@@ -413,7 +418,21 @@ export async function fetchNetworkMetricsPlaywright(
|
||||
|
||||
// Sélectionne toute la fenêtre de dates une fois, puis parcourt les codes par
|
||||
// lots ; un seul cube [Article Code, Mois] par lot donne TOUS les mois d'un coup.
|
||||
const monthDimPath = async (): Promise<void> => {
|
||||
// selectYear = null → passe principale (année N + N-1 dérivée via COMP).
|
||||
// selectYear = 2025 → passe complémentaire : on sélectionne l'année pour
|
||||
// récupérer directement ses mois (seul moyen d'obtenir août→déc N-1, que
|
||||
// COMP ne peut pas fournir puisque l'année N ne va pas jusque-là).
|
||||
const monthDimPath = async (selectYear: number | null): Promise<void> => {
|
||||
const isMainPass = selectYear === null;
|
||||
if (yfh !== -1) {
|
||||
await rpc("Clear", {}, yfh);
|
||||
await sleep(qlikSettleMs);
|
||||
if (selectYear !== null) {
|
||||
const ysel = await rpc("SelectValues", { qFieldValues: [{ qNum: selectYear, qText: String(selectYear) }], qToggleMode: false, qSoftLock: true }, yfh);
|
||||
console.log("[qlik-pw] (mois) sélection Année=" + selectYear + " → " + JSON.stringify(ysel.qReturn));
|
||||
await sleep(qlikSettleMs);
|
||||
}
|
||||
}
|
||||
const allSerials = monthlyPayload.flatMap((m) => m.serials);
|
||||
if (dfh !== -1 && allSerials.length) {
|
||||
await rpc("Clear", {}, dfh);
|
||||
@@ -442,22 +461,20 @@ export async function fetchNetworkMetricsPlaywright(
|
||||
}
|
||||
const got = await timed("cube", "batch", () => fetchMonthCube((code, mois, ca, qte, nbMag, caMag, marge, qteComp) => {
|
||||
if (!code || code === "-") return;
|
||||
out.push([code, ca, qte, nbMag, caMag, marge]);
|
||||
// 12 mois glissants. Le cube ne renvoie que les mois de l'année N
|
||||
// (les mesures "N" sont nulles ailleurs → lignes supprimées).
|
||||
// "Quantité COMP" = comparable N-1 : à la ligne Mois=YYYYMM elle
|
||||
// donne la quantité du MÊME mois l'année précédente. On dérive donc
|
||||
// deux points par ligne : YYYY-MM (N) et (YYYY-1)-MM (N-1).
|
||||
// Les totaux réseau ne viennent QUE de la passe principale
|
||||
// (sinon on doublerait CA/Qté avec la passe N-1).
|
||||
if (isMainPass) out.push([code, ca, qte, nbMag, caMag, marge]);
|
||||
const mm = normMois(mois);
|
||||
const y = parseInt(mm.slice(0, 4), 10);
|
||||
(monthlyByCode[code] ??= {});
|
||||
if (y === yearN) {
|
||||
monthlyByCode[code][mm] = (monthlyByCode[code][mm] ?? 0) + qte;
|
||||
if (isMainPass && y === yearN) {
|
||||
// Mois de l'année N + son comparable N-1 (COMP = même mois, N-1).
|
||||
monthlyByCode[code][mm] = qte;
|
||||
const mmPrev = String(y - 1) + mm.slice(4); // "2026-03" → "2025-03"
|
||||
monthlyByCode[code][mmPrev] = (monthlyByCode[code][mmPrev] ?? 0) + qteComp;
|
||||
if (monthlyByCode[code][mmPrev] === undefined) monthlyByCode[code][mmPrev] = qteComp;
|
||||
} else {
|
||||
// Ligne d'une autre année (cas non observé) : on prend la mesure N.
|
||||
monthlyByCode[code][mm] = (monthlyByCode[code][mm] ?? 0) + qte;
|
||||
// Passe année sélectionnée : valeur directe, prioritaire sur COMP.
|
||||
monthlyByCode[code][mm] = qte;
|
||||
}
|
||||
}, timings, () => { code15Retries++; }), timings);
|
||||
aggBatches++;
|
||||
@@ -549,7 +566,23 @@ export async function fetchNetworkMetricsPlaywright(
|
||||
if (!noDateMode && monthDim) {
|
||||
// Découpage mensuel réel (dimension Mois) — remplace l'itération par mois.
|
||||
console.log("[qlik-pw] extraction via dimension Mois (" + monthlyPayload.length + " mois attendus, moisDim=" + moisDimId + ")");
|
||||
await monthDimPath();
|
||||
await monthDimPath(null);
|
||||
// Passe complémentaire : mois de l'année N-1 absents de l'année N
|
||||
// (ex. août→déc), impossibles à obtenir via COMP. On sélectionne
|
||||
// l'année N-1 pour que les mesures "N" portent sur cette année.
|
||||
if (yfh !== -1) {
|
||||
const before = Object.values(monthlyByCode).reduce((s, m) => s + Object.keys(m).length, 0);
|
||||
try {
|
||||
await monthDimPath(yearN - 1);
|
||||
const after = Object.values(monthlyByCode).reduce((s, m) => s + Object.keys(m).length, 0);
|
||||
console.log("[qlik-pw] (mois) passe N-1 terminée : " + before + " → " + after + " points mensuels");
|
||||
} catch (e2) {
|
||||
console.log("[qlik-pw] (mois) passe N-1 ignorée: " + String((e2 as Error)?.message || e2));
|
||||
}
|
||||
try { await rpc("Clear", {}, yfh); } catch { /* noop */ }
|
||||
} else {
|
||||
console.log("[qlik-pw] (mois) champ Année introuvable → pas de passe N-1");
|
||||
}
|
||||
} else if (noDateMode) {
|
||||
// Aucun filtre Date : extraction en un seul appel (tous les codes d'un coup).
|
||||
// On sélectionne uniquement Article Code ; Date reste libre.
|
||||
|
||||
Reference in new issue
Block a user