mirror of
https://github.com/R0m1k3/CollectFlow.git
synced 2026-10-15 11:18:42 +02:00
feat(grid): implement hierarchical nomenclature filter (Secteur > Rayon > Famille)
This commit is contained in:
1 parent
de7aa1560e
commit
33615bb1bd
10 files changed
+310
-57
No files matched your search
@@ -2,37 +2,48 @@
|
||||
|
||||
import { db } from "@/db";
|
||||
import { ventesProduits } from "@/db/schema";
|
||||
import { eq, and, ne } from "drizzle-orm";
|
||||
import type { ProductRow, GammeCode } from "@/types/grid";
|
||||
import { eq, and, ne, like } from "drizzle-orm";
|
||||
import type { ProductRow, GammeCode, GridFilters } from "@/types/grid";
|
||||
import { computeProductScores } from "@/lib/score-engine";
|
||||
|
||||
interface GetProductRowsInput {
|
||||
codeFournisseur: string;
|
||||
magasin?: string;
|
||||
filters?: Partial<GridFilters>;
|
||||
}
|
||||
|
||||
export async function getProductRows(input: GetProductRowsInput): Promise<ProductRow[]> {
|
||||
const { codeFournisseur, magasin = "TOTAL" } = input;
|
||||
const { codeFournisseur, magasin = "TOTAL", filters } = input;
|
||||
|
||||
// Calculer les 12 derniers mois COMPLETS (excluant le mois en cours)
|
||||
const allowedPeriods = new Set<string>();
|
||||
// ... (allowedPeriods calculation remains the same)
|
||||
const now = new Date();
|
||||
const allowedPeriods = new Set<string>();
|
||||
for (let i = 12; i >= 1; i--) {
|
||||
const d = new Date(now.getFullYear(), now.getMonth() - i, 1);
|
||||
allowedPeriods.add(`${d.getFullYear()}${String(d.getMonth() + 1).padStart(2, "0")}`);
|
||||
}
|
||||
|
||||
// Get all rows for this supplier (excluding the synthetic TOTAL period)
|
||||
// Build conditions
|
||||
const conditions = [
|
||||
eq(ventesProduits.codeFournisseur, codeFournisseur),
|
||||
ne(ventesProduits.periode, "TOTAL"),
|
||||
magasin !== "TOTAL" ? eq(ventesProduits.magasin, magasin) : ne(ventesProduits.magasin, "TOTAL"),
|
||||
];
|
||||
|
||||
// Hierarchical filtering
|
||||
if (filters?.code3) {
|
||||
conditions.push(eq(ventesProduits.code3, filters.code3));
|
||||
} else if (filters?.code2) {
|
||||
conditions.push(like(ventesProduits.code3, `${filters.code2}%`));
|
||||
} else if (filters?.code1) {
|
||||
conditions.push(like(ventesProduits.code3, `${filters.code1}%`));
|
||||
}
|
||||
|
||||
// Get all rows for this supplier
|
||||
const rows = await db
|
||||
.select()
|
||||
.from(ventesProduits)
|
||||
.where(
|
||||
and(
|
||||
eq(ventesProduits.codeFournisseur, codeFournisseur),
|
||||
ne(ventesProduits.periode, "TOTAL"),
|
||||
magasin !== "TOTAL" ? eq(ventesProduits.magasin, magasin) : ne(ventesProduits.magasin, "TOTAL"),
|
||||
)
|
||||
);
|
||||
.where(and(...conditions));
|
||||
|
||||
// Group by codein and aggregate monthly sales + track store participation
|
||||
const productMap = new Map<string, ProductRow>();
|
||||
@@ -69,6 +80,10 @@ export async function getProductRows(input: GetProductRowsInput): Promise<Produc
|
||||
libelle1: row.libelle1 ?? "",
|
||||
gtin: row.gtin ?? "",
|
||||
reference: row.reference ?? "",
|
||||
code1: (row.code3 ?? "").slice(0, 2),
|
||||
libelleNiveau1: "Niv. 1", // À mapper plus tard
|
||||
code2: (row.code3 ?? "").slice(0, 4),
|
||||
libelleNiveau2: "Niv. 2", // À mapper plus tard
|
||||
code3: row.code3 ?? "",
|
||||
libelle3: row.libelle3 ?? "",
|
||||
codeGamme: (row.codeGamme as GammeCode | null),
|
||||
|
||||
Reference in new issue
Block a user