fix(qlik): batch SelectValues to avoid Engine abort + drop couv stock metric

Large supplier (4816 codes) triggered Qlik Engine "Request aborted"
(code 15): a single SelectValues over all codes forced the hypercube to
calculate too many rows at once. Now select in 1200-code batches and
accumulate, keeping each calc small. 1417 codes worked before, 4816 did
not - chunking scales to any supplier.

Also remove the "Couverture de stock" network column end-to-end (grid,
types, Qlik clients, cache, schema, db-init), shifting the marge measure
index from 6 to 5 and the hypercube width from 7 to 6.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
MichaelandClaude Opus 4.8 committed 2026-06-21 10:55:03 +02:00
1 parent 8cc95cb387
commit de8a435c14
8 files changed
+39 -60

No files matched your search

+4 -10
View File
@@ -49,7 +49,6 @@ export interface QlikConfig {
measQteId: string; // master measure "Quantite N"
measNbMagId: string; // master measure "Magasin Ventes Nb N"
measCaMagId: string; // master measure "CA par Magasin N"
measCouvQteId: string; // master measure "Couverture de stock Quantite N"
measMargePctId: string; // master measure "Marge % N"
tlsInsecure: boolean;
timeoutMs: number;
@@ -73,7 +72,6 @@ export function getQlikConfig(): QlikConfig {
// Master GUIDs de l'app "Magasins Vision Consolidée" (9872ee6e). Si l'engine
// les refuse (qId court attendu), override via env après discovery.
measCaMagId: process.env.QLIK_MEAS_CAMAG_ID ?? "16778c00-a4e0-41c7-ab1c-179810d78172",
measCouvQteId: process.env.QLIK_MEAS_COUVQTE_ID ?? "dbdf957d-a380-495f-bdc4-3f7b6688f3b5",
measMargePctId: process.env.QLIK_MEAS_MARGEPCT_ID ?? "ea1e8feb-49ba-4eb3-8db6-72dcfb4c1222",
tlsInsecure: (process.env.QLIK_TLS_INSECURE ?? "true") === "true",
timeoutMs: Number(process.env.QLIK_TIMEOUT_MS ?? "60000"),
@@ -87,8 +85,6 @@ export interface NetworkMetric {
nbMagasinsReseau: number;
/** CA moyen par magasin (productivité normalisée présence) */
caParMagasinReseau: number;
/** Couverture de stock en quantité (rotation : bas = tourne vite) */
couvertureStockReseau: number;
/** Taux de marge réseau (ratio brut Qlik, ex 0.32 = 32%) */
margePctReseau: number;
periode?: string;
@@ -244,10 +240,9 @@ function hyperCubeDef(cfg: QlikConfig, height: number) {
{ qLibraryId: cfg.measQteId },
{ qLibraryId: cfg.measNbMagId },
{ qLibraryId: cfg.measCaMagId },
{ qLibraryId: cfg.measCouvQteId },
{ qLibraryId: cfg.measMargePctId },
],
qInitialDataFetch: [{ qTop: 0, qLeft: 0, qWidth: 7, qHeight: height }],
qInitialDataFetch: [{ qTop: 0, qLeft: 0, qWidth: 6, qHeight: height }],
qSuppressZero: false,
qSuppressMissing: true,
},
@@ -270,7 +265,7 @@ export async function fetchNetworkMetrics(
const openRes = await conn.rpc("OpenDoc", { qDocName: cfg.appNetwork });
const docHandle = (((openRes.qReturn as Record<string, unknown>) ?? {}).qHandle as number) ?? 1;
const pageHeight = 1400; // 7 colonnes * 1400 = 9800 cellules max
const pageHeight = 1400; // 6 colonnes * 1400 = 8400 cellules max
const createRes = await conn.rpc("CreateSessionObject", { qProp: hyperCubeDef(cfg, pageHeight) }, docHandle);
const objHandle = (((createRes.qReturn as Record<string, unknown>) ?? {}).qHandle as number);
@@ -278,7 +273,7 @@ export async function fetchNetworkMetrics(
for (;;) {
const dataRes = await conn.rpc(
"GetHyperCubeData",
{ qPath: "/qHyperCubeDef", qPages: [{ qTop: top, qLeft: 0, qWidth: 7, qHeight: pageHeight }] },
{ qPath: "/qHyperCubeDef", qPages: [{ qTop: top, qLeft: 0, qWidth: 6, qHeight: pageHeight }] },
objHandle,
);
const pages = (dataRes.qDataPages as Array<{ qMatrix?: Matrix }>) ?? [];
@@ -295,8 +290,7 @@ export async function fetchNetworkMetrics(
qteReseau: Number(row[2]?.qNum ?? 0) || 0,
nbMagasinsReseau: Number(row[3]?.qNum ?? 0) || 0,
caParMagasinReseau: Number(row[4]?.qNum ?? 0) || 0,
couvertureStockReseau: Number(row[5]?.qNum ?? 0) || 0,
margePctReseau: Number(row[6]?.qNum ?? 0) || 0,
margePctReseau: Number(row[5]?.qNum ?? 0) || 0,
});
}
if (matrix.length < pageHeight) break;