export const buildInventoryTimeline = ( weeklyDemand: Array<{ MaterialHumanReadableId: string; WeekStart: string; WeeklyDemand: number; }>, opening: Record, ) => { // group weekly demand by material const grouped: Record< string, Array<{ WeekStart: string; Demand: number }> > = {}; for (const d of weeklyDemand) { const mat = d.MaterialHumanReadableId; grouped[mat] ??= []; grouped[mat].push({ WeekStart: d.WeekStart, Demand: Number(d.WeeklyDemand), }); } // sort weeks chronologically per material for (const mat of Object.keys(grouped)) { grouped[mat].sort( (a, b) => new Date(a.WeekStart).getTime() - new Date(b.WeekStart).getTime(), ); } const result: Array<{ MaterialHumanReadableId: string; WeekStart: string; OpeningInventory: number; Consumption: number; ClosingInventory: number; }> = []; for (const [mat, weeks] of Object.entries(grouped)) { // get starting inventory from the ERP result let inv = opening[mat] ?? 0; for (const w of weeks) { const week = w.WeekStart; const demand = Number(w.Demand); const openingInv = inv; const closingInv = openingInv - demand; result.push({ MaterialHumanReadableId: mat, WeekStart: week, OpeningInventory: Number(openingInv.toFixed(2)), Consumption: Number(demand.toFixed(2)), ClosingInventory: Number(closingInv.toFixed(2)), }); inv = closingInv; } } return result; };