diff --git a/App/CLAUDE.md b/App/CLAUDE.md
index 38e9495..7a40344 100644
--- a/App/CLAUDE.md
+++ b/App/CLAUDE.md
@@ -162,7 +162,7 @@ Spend analytics under a **Reports** sidebar section (with a **"Purchasing"** sub
**Spend definition** (`lib/reports.ts`, the pure/unit-tested core): a PO counts once it reaches `POST_APPROVAL_STATUSES`, dated by `approvedAt`, valued at the full `totalAmount` — the same basis as the dashboard tiles. FY is the Indian **Apr–Mar** year. `getReportDataset()` does one query pass; everything else is pure functions over it. **`allocatePoSpend()`** splits each PO across the accounting codes its **line items** carry (line `accountId`, falling back to the PO-level account), **proportionally** so the per-PO rows always sum back to `totalAmount` — so multi-account POs are attributed correctly in the accounting-code report. `poCount` is **distinct POs** (a multi-account PO yields several rows). Account spend rolls leaf descendants up via `buildAccountIndex().leavesUnder`.
-**Filters** live in the **URL query** so the server component re-renders — no client fetching: `gran` (**weekly** / monthly / yearly), `fy`, `month` (weekly), `scope` (Top/Bottom-N), `parent` (accounting drill), `tier` / `break` / `topn` (detail breakdowns), and `sel` + `cmp` (the **custom "Add to graph"** multi-select — tick rows via the `` links, then `cmp=1` compares just the selected set). Weekly focuses one FY month and buckets by week-of-month (W1–W5). The shared `` (client) writes the params; charts are **recharts** (`components/reports/charts.tsx`); KPIs/tables/breadcrumbs are server-rendered. Export → `/api/reports/spend?dim=…` (CSV mirroring the on-screen view, incl. the custom selection).
+**Filters** live in the **URL query** so the server component re-renders — no client fetching: `gran` (**weekly** / monthly / yearly), `fy`, `month` (weekly), `scope` (Top/Bottom-N), `parent` (accounting drill), `tier` / `break` / `topn` (detail breakdowns), and `sel` + `cmp` (the **custom "Add to graph"** multi-select — tick rows via the `` links, then `cmp=1` compares just the selected set). Weekly focuses one FY month and buckets by week-of-month (W1–W5). The shared `` (client) writes the params; charts are **recharts** (`components/reports/charts.tsx`) — the comparison chart plots **one colour-coded series per item** (cost centre / accounting code) in every granularity, including the yearly grouped-bars view (x-axis = FYs, a coloured bar per item — not one colour per year); KPIs/tables/breadcrumbs are server-rendered. Export → `/api/reports/spend?dim=…` (CSV mirroring the on-screen view, incl. the custom selection).
Sites are **not** cost centres (only vessels are).
diff --git a/App/app/(portal)/reports/accounting-codes/page.tsx b/App/app/(portal)/reports/accounting-codes/page.tsx
index cf5a9c8..c48f9ec 100644
--- a/App/app/(portal)/reports/accounting-codes/page.tsx
+++ b/App/app/(portal)/reports/accounting-codes/page.tsx
@@ -79,25 +79,16 @@ export default async function AccountingCodesReport({
const prevT = nf >= 2 ? shown.reduce((s, r) => s + r.fyTotals[nf - 2], 0) : 0;
const yoy = prevT ? ((curT - prevT) / prevT) * 100 : 0;
+ // One distinct colour per accounting code (series) in every granularity; the
+ // x-axis is months / weeks / financial years.
const colored = (i: number) => SERIES_COLORS[i % SERIES_COLORS.length];
- let chartData: Record[];
- let series: Series[];
- if (yearly) {
- chartData = shown.map((r) => {
- const row: Record = { name: r.node.code };
- ds.fys.forEach((y, i) => (row[fyLabel(y)] = r.fyTotals[i]));
- return row;
- });
- series = ds.fys.map((y, i) => ({ key: fyLabel(y), color: colored(i) }));
- } else {
- const labels = weekly ? [...WEEK_LABELS] : [...FY_MONTHS];
- chartData = labels.map((lab, i) => {
- const row: Record = { x: lab };
- shown.forEach((r) => (row[r.node.code] = sparkOf(r)[i]));
- return row;
- });
- series = shown.map((r, i) => ({ key: r.node.code, color: colored(i) }));
- }
+ const chartLabels = yearly ? ds.fys.map(fyLabel) : weekly ? [...WEEK_LABELS] : [...FY_MONTHS];
+ const chartData: Record[] = chartLabels.map((lab, i) => {
+ const row: Record = { x: lab };
+ shown.forEach((r) => (row[r.node.code] = sparkOf(r)[i]));
+ return row;
+ });
+ const series: Series[] = shown.map((r, i) => ({ key: r.node.code, color: colored(i) }));
const monthLabel = (i: number) => `${FY_MONTHS[i]} '${String((fy + (i >= 9 ? 1 : 0)) % 100).padStart(2, "0")}`;
const periodLabel = yearly ? ds.fys.map(fyLabel).join(" · ") : weekly ? `${monthLabel(month)} · ${fyLabel(fy)}` : fyLabel(fy);
@@ -190,7 +181,7 @@ export default async function AccountingCodesReport({
{periodLabel}
-
+
diff --git a/App/app/(portal)/reports/cost-centres/page.tsx b/App/app/(portal)/reports/cost-centres/page.tsx
index acccab0..98ea42f 100644
--- a/App/app/(portal)/reports/cost-centres/page.tsx
+++ b/App/app/(portal)/reports/cost-centres/page.tsx
@@ -64,26 +64,17 @@ export default async function CostCentresReport({
const prevT = nf >= 2 ? shown.reduce((s, r) => s + r.fyTotals[nf - 2], 0) : 0;
const yoy = prevT ? ((curT - prevT) / prevT) * 100 : 0;
- // Chart data.
+ // Chart data — one distinct colour per item (series) in every granularity; the
+ // x-axis is months / weeks / financial years. (Yearly is grouped bars per item,
+ // not per FY, so each cost centre keeps its own colour.)
const colored = (i: number) => SERIES_COLORS[i % SERIES_COLORS.length];
- let chartData: Record[];
- let series: Series[];
- if (yearly) {
- chartData = shown.map((r) => {
- const row: Record = { name: r.name };
- ds.fys.forEach((y, i) => (row[fyLabel(y)] = r.fyTotals[i]));
- return row;
- });
- series = ds.fys.map((y, i) => ({ key: fyLabel(y), color: colored(i) }));
- } else {
- const labels = weekly ? [...WEEK_LABELS] : [...FY_MONTHS];
- chartData = labels.map((lab, i) => {
- const row: Record = { x: lab };
- shown.forEach((r) => (row[r.name] = sparkOf(r)[i]));
- return row;
- });
- series = shown.map((r, i) => ({ key: r.name, color: colored(i) }));
- }
+ const chartLabels = yearly ? ds.fys.map(fyLabel) : weekly ? [...WEEK_LABELS] : [...FY_MONTHS];
+ const chartData: Record[] = chartLabels.map((lab, i) => {
+ const row: Record = { x: lab };
+ shown.forEach((r) => (row[r.name] = sparkOf(r)[i]));
+ return row;
+ });
+ const series: Series[] = shown.map((r, i) => ({ key: r.name, color: colored(i) }));
const monthLabel = (i: number) => `${FY_MONTHS[i]} '${String((fy + (i >= 9 ? 1 : 0)) % 100).padStart(2, "0")}`;
const periodLabel = yearly ? ds.fys.map(fyLabel).join(" · ") : weekly ? `${monthLabel(month)} · ${fyLabel(fy)}` : fyLabel(fy);
@@ -158,7 +149,7 @@ export default async function CostCentresReport({
{periodLabel}
-
+