mega-plant/lib/rows.ts

87 lines
2.5 KiB
TypeScript

import type { Asset, MonthlyIncome, MonthlyRunningCost } from "./data";
import { computeProfit, type ProfitOptions } from "./profit";
export type IncomeRow = {
id: string;
code: string;
name: string;
months: number[];
profit: number[];
income: number;
fixed: number;
running: number;
ytdProfit: number;
};
export function buildIncomeRows(
assets: Asset[],
income: MonthlyIncome[],
running?: MonthlyRunningCost[],
profitOpts: ProfitOptions = {}
): IncomeRow[] {
const byAsset = new Map<string, IncomeRow>();
for (const a of assets) {
if (!a.code) continue;
byAsset.set(a.id, {
id: a.id, code: a.code, name: a.name,
months: Array(12).fill(0),
profit: Array(12).fill(0),
income: 0, fixed: 0, running: 0, ytdProfit: 0,
});
}
for (const r of income) {
const row = byAsset.get(r.asset);
if (!row) continue;
const i = r.month - 1;
row.months[i] = r.income;
row.profit[i] = computeProfit({ income: r.income, fixed: r.fixed_expenses, running: 0 }, profitOpts);
row.income += r.income;
row.fixed += r.fixed_expenses;
}
// Per Part 1.5: running cost is derived from monthly_running_costs, not stored on income.
for (const c of running ?? []) {
const row = byAsset.get(c.asset);
if (!row) continue;
row.running += c.amount;
// Re-compute per-month profit so it includes running cost regardless of includeRunningCost flag.
// When includeRunningCost is false (default), running is shown but not subtracted.
row.profit[c.month - 1] = computeProfit(
{ income: row.months[c.month - 1], fixed: row.fixed / 12, running: c.amount },
profitOpts
);
}
for (const row of byAsset.values()) {
row.ytdProfit = computeProfit({ income: row.income, fixed: row.fixed, running: row.running }, profitOpts);
}
return Array.from(byAsset.values());
}
export type RunningRow = {
id: string;
code: string;
name: string;
months: number[];
ytd: number;
};
export function buildRunningRows(
assets: Asset[],
costs: MonthlyRunningCost[]
): RunningRow[] {
const byAsset = new Map<string, RunningRow>();
for (const a of assets) {
if (!a.code) continue;
byAsset.set(a.id, {
id: a.id, code: a.code, name: a.name,
months: Array(12).fill(0),
ytd: 0,
});
}
for (const c of costs) {
const row = byAsset.get(c.asset);
if (!row) continue;
row.months[c.month - 1] = c.amount;
row.ytd += c.amount;
}
return Array.from(byAsset.values());
}