65 lines
1.4 KiB
TypeScript
65 lines
1.4 KiB
TypeScript
export const buildInventoryTimeline = (
|
|
weeklyDemand: Array<{
|
|
MaterialHumanReadableId: string;
|
|
WeekStart: string;
|
|
WeeklyDemand: number;
|
|
}>,
|
|
opening: Record<string, number>,
|
|
) => {
|
|
// 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;
|
|
};
|