feat: Introduce getProductRows API and related types for fetching and processing comprehensive product data, incorporating sales, stock, and classification.

This commit is contained in:
Michael committed 2026-03-18 19:31:16 +01:00
1 parent 8986f7d001
commit d616da8b91
2 files changed
+17 -7

No files matched your search

+14 -6
View File
@@ -65,6 +65,7 @@ export async function getProductRows(input: GetProductRowsInput): Promise<Produc
codeGammeDraft: null,
sales12m: {},
stock12m: {},
receptions12m: {},
totalQuantite: 0,
totalCa: 0,
totalMarge: 0,
@@ -86,7 +87,7 @@ export async function getProductRows(input: GetProductRowsInput): Promise<Produc
if (!product) continue;
// Agréger par période (toutes les entrées site × mois → 1 entrée par mois)
const byPeriod = new Map<string, { qty: number; ca: number; marge: number; stock: number; pa: number }>();
const byPeriod = new Map<string, { qty: number; ca: number; marge: number; stock: number; pa: number; receptions: number }>();
const storeMonths = new Map<string, Set<string>>(); // site → Set<YYYYMM>
for (const entry of entries) {
@@ -96,7 +97,7 @@ export async function getProductRows(input: GetProductRowsInput): Promise<Produc
if (!allowedPeriods.has(periode)) continue;
if (!byPeriod.has(periode)) {
byPeriod.set(periode, { qty: 0, ca: 0, marge: 0, stock: 0, pa: 0 });
byPeriod.set(periode, { qty: 0, ca: 0, marge: 0, stock: 0, pa: 0, receptions: 0 });
}
const p = byPeriod.get(periode)!;
@@ -104,6 +105,11 @@ export async function getProductRows(input: GetProductRowsInput): Promise<Produc
p.stock += Math.abs(parseFloat(entry.stock_fin_mois ?? "0") || 0);
if (!p.pa && entry.prmp_fin_mois) p.pa = parseFloat(entry.prmp_fin_mois) || 0;
// Réceptions
if (entry.receptions) {
p.receptions += Math.abs(parseFloat(entry.receptions.qte_recue ?? "0") || 0);
}
// Ventes
if (entry.ventes) {
p.qty += Math.abs(parseFloat(entry.ventes.qte_vendue ?? "0") || 0);
@@ -124,16 +130,18 @@ export async function getProductRows(input: GetProductRowsInput): Promise<Produc
for (const periode of sortedPeriods) {
const p = byPeriod.get(periode);
if (p) {
product.sales12m[periode] = p.qty;
product.stock12m[periode] = p.stock;
product.sales12m[periode] = p.qty;
product.stock12m[periode] = p.stock;
product.receptions12m[periode] = p.receptions;
product.totalQuantite += p.qty;
product.totalCa += p.ca;
product.totalMarge += p.marge;
lastStock = p.stock;
if (!lastPa && p.pa) lastPa = p.pa;
} else {
product.sales12m[periode] = 0;
product.stock12m[periode] = lastStock; // carry-forward
product.sales12m[periode] = 0;
product.stock12m[periode] = lastStock; // carry-forward
product.receptions12m[periode] = 0;
}
}
+3 -1
View File
@@ -48,8 +48,10 @@ export interface ProductRow {
codeGammeDraft: GammeCode | null;
/** 12-month sales quantities, indexed by YYYYMM key */
sales12m: Record<string, number>;
/** End-of-month stock levels, indexed by YYYYMM key (reconstructed from movements qtestock) */
/** End-of-month stock levels, indexed by YYYYMM key */
stock12m: Record<string, number>;
/** Monthly reception quantities, indexed by YYYYMM key */
receptions12m: Record<string, number>;
totalQuantite: number;
totalCa: number;
totalMarge: number;