mega-plant/app/(dashboard)/running/page.tsx

133 lines
6.4 KiB
TypeScript
Raw Normal View History

import Link from "next/link";
Running cost = everything linked to a vehicle: repairs, purchases, insurance, finance A machine with no repairs and no purchase order still carries an insurance premium and, while it is financed, a monthly instalment. So a blank row was never "this vehicle costs nothing" — it was "nothing recorded", which is a gap rather than a figure. The Overview now totals all four kinds per machine per month. Everything is read from POCKETBASE, the registers the client maintains in the app. The original spreadsheet only bootstrapped the page (monthly_running_costs, Jan-Aug); it is not a source here. September having no workbook data is expected and correct — the figures there now come from the app. Two finance sources existed and OVERLAPPED. The cost_lines instalment rows are the old workbook's subset (5 machines, R115 576,14/mo); financing_terms is the client's current sheet (18 agreements, R428 585,04/mo). Using both double-counted MG02, RV04, TLB06 and TLB07, so financing_terms wins and the stale rows are ignored. TB01 has no financing_terms row, so its old instalment no longer counts — consistent with it being absent from the current sheet. Insurance has one source and no such problem. Insurance is resolved from the RATE PERIODS rather than the derived cost_lines, so a premium that moves mid-year is charged at the price that applied that month. Also: settled agreements contribute nothing (a paid-off machine is not a running cost), purchase lines are filed under the PO date, and the bottom row keeps showing incl above excl. The page carries one line saying this is a re-cut of costs already inside fixed expenses — adding it to them would count the same premium twice. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-10-09 10:28:29 +00:00
import { getAssets } from "@/lib/server-data";
import { serverAuth } from "@/lib/pb";
import { ZAR } from "@/lib/utils";
import { Wrench, TriangleAlert } from "lucide-react";
import { RunningView } from "@/components/RunningView";
import { buildRunningRows } from "@/lib/rows";
import { MONTH_NAMES } from "@/lib/data";
Running cost = everything linked to a vehicle: repairs, purchases, insurance, finance A machine with no repairs and no purchase order still carries an insurance premium and, while it is financed, a monthly instalment. So a blank row was never "this vehicle costs nothing" — it was "nothing recorded", which is a gap rather than a figure. The Overview now totals all four kinds per machine per month. Everything is read from POCKETBASE, the registers the client maintains in the app. The original spreadsheet only bootstrapped the page (monthly_running_costs, Jan-Aug); it is not a source here. September having no workbook data is expected and correct — the figures there now come from the app. Two finance sources existed and OVERLAPPED. The cost_lines instalment rows are the old workbook's subset (5 machines, R115 576,14/mo); financing_terms is the client's current sheet (18 agreements, R428 585,04/mo). Using both double-counted MG02, RV04, TLB06 and TLB07, so financing_terms wins and the stale rows are ignored. TB01 has no financing_terms row, so its old instalment no longer counts — consistent with it being absent from the current sheet. Insurance has one source and no such problem. Insurance is resolved from the RATE PERIODS rather than the derived cost_lines, so a premium that moves mid-year is charged at the price that applied that month. Also: settled agreements contribute nothing (a paid-off machine is not a running cost), purchase lines are filed under the PO date, and the bottom row keeps showing incl above excl. The page carries one line saying this is a re-cut of costs already inside fixed expenses — adding it to them would count the same premium twice. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-10-09 10:28:29 +00:00
import { machineRunningCosts, RUNNING_VAT_PCT } from "@/lib/running-costs";
import type {
FinancingTerm, InsuranceRate, MonthlyRunningCost, Purchase, PurchaseLine,
} from "@/lib/data";
2026-09-12 10:05:43 +00:00
// Reads PocketBase on every request. Without this Next tries to prerender the
// page at build time, which makes `docker build` depend on the database being
// reachable and then serves a frozen build-time snapshot to users.
export const dynamic = "force-dynamic";
/**
Running cost = everything linked to a vehicle: repairs, purchases, insurance, finance A machine with no repairs and no purchase order still carries an insurance premium and, while it is financed, a monthly instalment. So a blank row was never "this vehicle costs nothing" — it was "nothing recorded", which is a gap rather than a figure. The Overview now totals all four kinds per machine per month. Everything is read from POCKETBASE, the registers the client maintains in the app. The original spreadsheet only bootstrapped the page (monthly_running_costs, Jan-Aug); it is not a source here. September having no workbook data is expected and correct — the figures there now come from the app. Two finance sources existed and OVERLAPPED. The cost_lines instalment rows are the old workbook's subset (5 machines, R115 576,14/mo); financing_terms is the client's current sheet (18 agreements, R428 585,04/mo). Using both double-counted MG02, RV04, TLB06 and TLB07, so financing_terms wins and the stale rows are ignored. TB01 has no financing_terms row, so its old instalment no longer counts — consistent with it being absent from the current sheet. Insurance has one source and no such problem. Insurance is resolved from the RATE PERIODS rather than the derived cost_lines, so a premium that moves mid-year is charged at the price that applied that month. Also: settled agreements contribute nothing (a paid-off machine is not a running cost), purchase lines are filed under the PO date, and the bottom row keeps showing incl above excl. The page carries one line saying this is a re-cut of costs already inside fixed expenses — adding it to them would count the same premium twice. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-10-09 10:28:29 +00:00
* Running Costs Overview — everything a vehicle costs to run, per machine per month.
*
Running cost = everything linked to a vehicle: repairs, purchases, insurance, finance A machine with no repairs and no purchase order still carries an insurance premium and, while it is financed, a monthly instalment. So a blank row was never "this vehicle costs nothing" — it was "nothing recorded", which is a gap rather than a figure. The Overview now totals all four kinds per machine per month. Everything is read from POCKETBASE, the registers the client maintains in the app. The original spreadsheet only bootstrapped the page (monthly_running_costs, Jan-Aug); it is not a source here. September having no workbook data is expected and correct — the figures there now come from the app. Two finance sources existed and OVERLAPPED. The cost_lines instalment rows are the old workbook's subset (5 machines, R115 576,14/mo); financing_terms is the client's current sheet (18 agreements, R428 585,04/mo). Using both double-counted MG02, RV04, TLB06 and TLB07, so financing_terms wins and the stale rows are ignored. TB01 has no financing_terms row, so its old instalment no longer counts — consistent with it being absent from the current sheet. Insurance has one source and no such problem. Insurance is resolved from the RATE PERIODS rather than the derived cost_lines, so a premium that moves mid-year is charged at the price that applied that month. Also: settled agreements contribute nothing (a paid-off machine is not a running cost), purchase lines are filed under the PO date, and the bottom row keeps showing incl above excl. The page carries one line saying this is a re-cut of costs already inside fixed expenses — adding it to them would count the same premium twice. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-10-09 10:28:29 +00:00
* Client ruling, 2026-10-09: insurance, finance, purchases and repairs ALL belong here.
* A machine with no repairs and no purchase order still carries an insurance premium
* and a monthly instalment while it is financed, so it still has a figure.
*
Running cost = everything linked to a vehicle: repairs, purchases, insurance, finance A machine with no repairs and no purchase order still carries an insurance premium and, while it is financed, a monthly instalment. So a blank row was never "this vehicle costs nothing" — it was "nothing recorded", which is a gap rather than a figure. The Overview now totals all four kinds per machine per month. Everything is read from POCKETBASE, the registers the client maintains in the app. The original spreadsheet only bootstrapped the page (monthly_running_costs, Jan-Aug); it is not a source here. September having no workbook data is expected and correct — the figures there now come from the app. Two finance sources existed and OVERLAPPED. The cost_lines instalment rows are the old workbook's subset (5 machines, R115 576,14/mo); financing_terms is the client's current sheet (18 agreements, R428 585,04/mo). Using both double-counted MG02, RV04, TLB06 and TLB07, so financing_terms wins and the stale rows are ignored. TB01 has no financing_terms row, so its old instalment no longer counts — consistent with it being absent from the current sheet. Insurance has one source and no such problem. Insurance is resolved from the RATE PERIODS rather than the derived cost_lines, so a premium that moves mid-year is charged at the price that applied that month. Also: settled agreements contribute nothing (a paid-off machine is not a running cost), purchase lines are filed under the PO date, and the bottom row keeps showing incl above excl. The page carries one line saying this is a re-cut of costs already inside fixed expenses — adding it to them would count the same premium twice. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-10-09 10:28:29 +00:00
* Everything is read from POCKETBASE — the registers the client maintains in the app.
* The original spreadsheet only bootstrapped the page; it is not a source here.
*
* ⚠️ This is a RE-CUT, not new spend: insurance and instalments are already inside
* `monthly_income.fixed_expenses`. Adding this total to fixed expenses would count the
* same premium twice.
*/
export default async function RunningPage() {
const pb = await serverAuth();
Running cost = everything linked to a vehicle: repairs, purchases, insurance, finance A machine with no repairs and no purchase order still carries an insurance premium and, while it is financed, a monthly instalment. So a blank row was never "this vehicle costs nothing" — it was "nothing recorded", which is a gap rather than a figure. The Overview now totals all four kinds per machine per month. Everything is read from POCKETBASE, the registers the client maintains in the app. The original spreadsheet only bootstrapped the page (monthly_running_costs, Jan-Aug); it is not a source here. September having no workbook data is expected and correct — the figures there now come from the app. Two finance sources existed and OVERLAPPED. The cost_lines instalment rows are the old workbook's subset (5 machines, R115 576,14/mo); financing_terms is the client's current sheet (18 agreements, R428 585,04/mo). Using both double-counted MG02, RV04, TLB06 and TLB07, so financing_terms wins and the stale rows are ignored. TB01 has no financing_terms row, so its old instalment no longer counts — consistent with it being absent from the current sheet. Insurance has one source and no such problem. Insurance is resolved from the RATE PERIODS rather than the derived cost_lines, so a premium that moves mid-year is charged at the price that applied that month. Also: settled agreements contribute nothing (a paid-off machine is not a running cost), purchase lines are filed under the PO date, and the bottom row keeps showing incl above excl. The page carries one line saying this is a re-cut of costs already inside fixed expenses — adding it to them would count the same premium twice. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-10-09 10:28:29 +00:00
const [assets, repairs, purchases, lines, insurance, finance] = await Promise.all([
getAssets(),
Running cost = everything linked to a vehicle: repairs, purchases, insurance, finance A machine with no repairs and no purchase order still carries an insurance premium and, while it is financed, a monthly instalment. So a blank row was never "this vehicle costs nothing" — it was "nothing recorded", which is a gap rather than a figure. The Overview now totals all four kinds per machine per month. Everything is read from POCKETBASE, the registers the client maintains in the app. The original spreadsheet only bootstrapped the page (monthly_running_costs, Jan-Aug); it is not a source here. September having no workbook data is expected and correct — the figures there now come from the app. Two finance sources existed and OVERLAPPED. The cost_lines instalment rows are the old workbook's subset (5 machines, R115 576,14/mo); financing_terms is the client's current sheet (18 agreements, R428 585,04/mo). Using both double-counted MG02, RV04, TLB06 and TLB07, so financing_terms wins and the stale rows are ignored. TB01 has no financing_terms row, so its old instalment no longer counts — consistent with it being absent from the current sheet. Insurance has one source and no such problem. Insurance is resolved from the RATE PERIODS rather than the derived cost_lines, so a premium that moves mid-year is charged at the price that applied that month. Also: settled agreements contribute nothing (a paid-off machine is not a running cost), purchase lines are filed under the PO date, and the bottom row keeps showing incl above excl. The page carries one line saying this is a re-cut of costs already inside fixed expenses — adding it to them would count the same premium twice. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-10-09 10:28:29 +00:00
pb.collection("monthly_running_costs").getFullList<MonthlyRunningCost>(),
pb.collection("purchases").getFullList<Purchase>(),
pb.collection("purchase_lines").getFullList<PurchaseLine>(),
Running cost = everything linked to a vehicle: repairs, purchases, insurance, finance A machine with no repairs and no purchase order still carries an insurance premium and, while it is financed, a monthly instalment. So a blank row was never "this vehicle costs nothing" — it was "nothing recorded", which is a gap rather than a figure. The Overview now totals all four kinds per machine per month. Everything is read from POCKETBASE, the registers the client maintains in the app. The original spreadsheet only bootstrapped the page (monthly_running_costs, Jan-Aug); it is not a source here. September having no workbook data is expected and correct — the figures there now come from the app. Two finance sources existed and OVERLAPPED. The cost_lines instalment rows are the old workbook's subset (5 machines, R115 576,14/mo); financing_terms is the client's current sheet (18 agreements, R428 585,04/mo). Using both double-counted MG02, RV04, TLB06 and TLB07, so financing_terms wins and the stale rows are ignored. TB01 has no financing_terms row, so its old instalment no longer counts — consistent with it being absent from the current sheet. Insurance has one source and no such problem. Insurance is resolved from the RATE PERIODS rather than the derived cost_lines, so a premium that moves mid-year is charged at the price that applied that month. Also: settled agreements contribute nothing (a paid-off machine is not a running cost), purchase lines are filed under the PO date, and the bottom row keeps showing incl above excl. The page carries one line saying this is a re-cut of costs already inside fixed expenses — adding it to them would count the same premium twice. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-10-09 10:28:29 +00:00
pb.collection("insurance_rates").getFullList<InsuranceRate>(),
pb.collection("financing_terms").getFullList<FinancingTerm>(),
]);
// Never project past the month we are IN — see lib/running-costs.ts.
const now = new Date();
const lastMonth = now.getFullYear() === 2026 ? now.getMonth() + 1 : 12;
Running cost = everything linked to a vehicle: repairs, purchases, insurance, finance A machine with no repairs and no purchase order still carries an insurance premium and, while it is financed, a monthly instalment. So a blank row was never "this vehicle costs nothing" — it was "nothing recorded", which is a gap rather than a figure. The Overview now totals all four kinds per machine per month. Everything is read from POCKETBASE, the registers the client maintains in the app. The original spreadsheet only bootstrapped the page (monthly_running_costs, Jan-Aug); it is not a source here. September having no workbook data is expected and correct — the figures there now come from the app. Two finance sources existed and OVERLAPPED. The cost_lines instalment rows are the old workbook's subset (5 machines, R115 576,14/mo); financing_terms is the client's current sheet (18 agreements, R428 585,04/mo). Using both double-counted MG02, RV04, TLB06 and TLB07, so financing_terms wins and the stale rows are ignored. TB01 has no financing_terms row, so its old instalment no longer counts — consistent with it being absent from the current sheet. Insurance has one source and no such problem. Insurance is resolved from the RATE PERIODS rather than the derived cost_lines, so a premium that moves mid-year is charged at the price that applied that month. Also: settled agreements contribute nothing (a paid-off machine is not a running cost), purchase lines are filed under the PO date, and the bottom row keeps showing incl above excl. The page carries one line saying this is a re-cut of costs already inside fixed expenses — adding it to them would count the same premium twice. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-10-09 10:28:29 +00:00
const { byAsset, undatedPurchases } = machineRunningCosts({
assets, repairs, purchases, purchaseLines: lines, insurance, finance,
}, lastMonth);
Running cost = everything linked to a vehicle: repairs, purchases, insurance, finance A machine with no repairs and no purchase order still carries an insurance premium and, while it is financed, a monthly instalment. So a blank row was never "this vehicle costs nothing" — it was "nothing recorded", which is a gap rather than a figure. The Overview now totals all four kinds per machine per month. Everything is read from POCKETBASE, the registers the client maintains in the app. The original spreadsheet only bootstrapped the page (monthly_running_costs, Jan-Aug); it is not a source here. September having no workbook data is expected and correct — the figures there now come from the app. Two finance sources existed and OVERLAPPED. The cost_lines instalment rows are the old workbook's subset (5 machines, R115 576,14/mo); financing_terms is the client's current sheet (18 agreements, R428 585,04/mo). Using both double-counted MG02, RV04, TLB06 and TLB07, so financing_terms wins and the stale rows are ignored. TB01 has no financing_terms row, so its old instalment no longer counts — consistent with it being absent from the current sheet. Insurance has one source and no such problem. Insurance is resolved from the RATE PERIODS rather than the derived cost_lines, so a premium that moves mid-year is charged at the price that applied that month. Also: settled agreements contribute nothing (a paid-off machine is not a running cost), purchase lines are filed under the PO date, and the bottom row keeps showing incl above excl. The page carries one line saying this is a re-cut of costs already inside fixed expenses — adding it to them would count the same premium twice. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-10-09 10:28:29 +00:00
const rows = buildRunningRows(assets, byAsset);
const monthTotals = Array(12).fill(0);
const monthTotalsExcl = Array(12).fill(0);
Running cost = everything linked to a vehicle: repairs, purchases, insurance, finance A machine with no repairs and no purchase order still carries an insurance premium and, while it is financed, a monthly instalment. So a blank row was never "this vehicle costs nothing" — it was "nothing recorded", which is a gap rather than a figure. The Overview now totals all four kinds per machine per month. Everything is read from POCKETBASE, the registers the client maintains in the app. The original spreadsheet only bootstrapped the page (monthly_running_costs, Jan-Aug); it is not a source here. September having no workbook data is expected and correct — the figures there now come from the app. Two finance sources existed and OVERLAPPED. The cost_lines instalment rows are the old workbook's subset (5 machines, R115 576,14/mo); financing_terms is the client's current sheet (18 agreements, R428 585,04/mo). Using both double-counted MG02, RV04, TLB06 and TLB07, so financing_terms wins and the stale rows are ignored. TB01 has no financing_terms row, so its old instalment no longer counts — consistent with it being absent from the current sheet. Insurance has one source and no such problem. Insurance is resolved from the RATE PERIODS rather than the derived cost_lines, so a premium that moves mid-year is charged at the price that applied that month. Also: settled agreements contribute nothing (a paid-off machine is not a running cost), purchase lines are filed under the PO date, and the bottom row keeps showing incl above excl. The page carries one line saying this is a re-cut of costs already inside fixed expenses — adding it to them would count the same premium twice. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-10-09 10:28:29 +00:00
const monthByKind = { repairs: Array(12).fill(0), purchases: Array(12).fill(0), insurance: Array(12).fill(0), finance: Array(12).fill(0) };
for (const r of rows) {
Running cost = everything linked to a vehicle: repairs, purchases, insurance, finance A machine with no repairs and no purchase order still carries an insurance premium and, while it is financed, a monthly instalment. So a blank row was never "this vehicle costs nothing" — it was "nothing recorded", which is a gap rather than a figure. The Overview now totals all four kinds per machine per month. Everything is read from POCKETBASE, the registers the client maintains in the app. The original spreadsheet only bootstrapped the page (monthly_running_costs, Jan-Aug); it is not a source here. September having no workbook data is expected and correct — the figures there now come from the app. Two finance sources existed and OVERLAPPED. The cost_lines instalment rows are the old workbook's subset (5 machines, R115 576,14/mo); financing_terms is the client's current sheet (18 agreements, R428 585,04/mo). Using both double-counted MG02, RV04, TLB06 and TLB07, so financing_terms wins and the stale rows are ignored. TB01 has no financing_terms row, so its old instalment no longer counts — consistent with it being absent from the current sheet. Insurance has one source and no such problem. Insurance is resolved from the RATE PERIODS rather than the derived cost_lines, so a premium that moves mid-year is charged at the price that applied that month. Also: settled agreements contribute nothing (a paid-off machine is not a running cost), purchase lines are filed under the PO date, and the bottom row keeps showing incl above excl. The page carries one line saying this is a re-cut of costs already inside fixed expenses — adding it to them would count the same premium twice. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-10-09 10:28:29 +00:00
r.months.forEach((v, i) => (monthTotals[i] += v));
r.monthsExcl.forEach((v, i) => (monthTotalsExcl[i] += v));
Running cost = everything linked to a vehicle: repairs, purchases, insurance, finance A machine with no repairs and no purchase order still carries an insurance premium and, while it is financed, a monthly instalment. So a blank row was never "this vehicle costs nothing" — it was "nothing recorded", which is a gap rather than a figure. The Overview now totals all four kinds per machine per month. Everything is read from POCKETBASE, the registers the client maintains in the app. The original spreadsheet only bootstrapped the page (monthly_running_costs, Jan-Aug); it is not a source here. September having no workbook data is expected and correct — the figures there now come from the app. Two finance sources existed and OVERLAPPED. The cost_lines instalment rows are the old workbook's subset (5 machines, R115 576,14/mo); financing_terms is the client's current sheet (18 agreements, R428 585,04/mo). Using both double-counted MG02, RV04, TLB06 and TLB07, so financing_terms wins and the stale rows are ignored. TB01 has no financing_terms row, so its old instalment no longer counts — consistent with it being absent from the current sheet. Insurance has one source and no such problem. Insurance is resolved from the RATE PERIODS rather than the derived cost_lines, so a premium that moves mid-year is charged at the price that applied that month. Also: settled agreements contribute nothing (a paid-off machine is not a running cost), purchase lines are filed under the PO date, and the bottom row keeps showing incl above excl. The page carries one line saying this is a re-cut of costs already inside fixed expenses — adding it to them would count the same premium twice. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-10-09 10:28:29 +00:00
for (const k of ["repairs", "purchases", "insurance", "finance"] as const)
r.byKind[k].forEach((v, i) => (monthByKind[k][i] += v));
}
const grand = monthTotals.reduce((s, v) => s + v, 0);
const grandExcl = monthTotalsExcl.reduce((s, v) => s + v, 0);
const unallocated = lines.filter((l) => !l.asset).length;
return (
<div className="p-4 sm:p-8 max-w-[1400px]">
<div className="flex flex-col sm:flex-row sm:items-end sm:justify-between gap-4 mb-6">
<div>
<div className="flex items-center gap-3 mb-1">
<div className="w-10 h-10 shrink-0 rounded-xl bg-gradient-to-br from-[#EDAE49]/15 to-[#D1495B]/15 grid place-items-center text-[#EDAE49]">
<Wrench className="w-5 h-5" />
</div>
<h1 className="text-2xl font-semibold text-[#003D5B] dark:text-white">Running Costs</h1>
</div>
<p className="text-gray-500 dark:text-gray-400 text-sm">
Running cost = everything linked to a vehicle: repairs, purchases, insurance, finance A machine with no repairs and no purchase order still carries an insurance premium and, while it is financed, a monthly instalment. So a blank row was never "this vehicle costs nothing" — it was "nothing recorded", which is a gap rather than a figure. The Overview now totals all four kinds per machine per month. Everything is read from POCKETBASE, the registers the client maintains in the app. The original spreadsheet only bootstrapped the page (monthly_running_costs, Jan-Aug); it is not a source here. September having no workbook data is expected and correct — the figures there now come from the app. Two finance sources existed and OVERLAPPED. The cost_lines instalment rows are the old workbook's subset (5 machines, R115 576,14/mo); financing_terms is the client's current sheet (18 agreements, R428 585,04/mo). Using both double-counted MG02, RV04, TLB06 and TLB07, so financing_terms wins and the stale rows are ignored. TB01 has no financing_terms row, so its old instalment no longer counts — consistent with it being absent from the current sheet. Insurance has one source and no such problem. Insurance is resolved from the RATE PERIODS rather than the derived cost_lines, so a premium that moves mid-year is charged at the price that applied that month. Also: settled agreements contribute nothing (a paid-off machine is not a running cost), purchase lines are filed under the PO date, and the bottom row keeps showing incl above excl. The page carries one line saying this is a re-cut of costs already inside fixed expenses — adding it to them would count the same premium twice. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-10-09 10:28:29 +00:00
Everything a vehicle costs to run · repairs, purchases, insurance, finance · 2026
</p>
<p className="text-xs text-gray-400 dark:text-text-soft mt-1">
Shown to {MONTH_NAMES.slice(0, lastMonth).join(", ")}. A month ahead is not shown —
it cannot be calculated, only guessed at, and the last month keeps growing as
things are entered.
</p>
<p className="text-xs text-gray-400 dark:text-text-soft mt-1">
Running cost = everything linked to a vehicle: repairs, purchases, insurance, finance A machine with no repairs and no purchase order still carries an insurance premium and, while it is financed, a monthly instalment. So a blank row was never "this vehicle costs nothing" — it was "nothing recorded", which is a gap rather than a figure. The Overview now totals all four kinds per machine per month. Everything is read from POCKETBASE, the registers the client maintains in the app. The original spreadsheet only bootstrapped the page (monthly_running_costs, Jan-Aug); it is not a source here. September having no workbook data is expected and correct — the figures there now come from the app. Two finance sources existed and OVERLAPPED. The cost_lines instalment rows are the old workbook's subset (5 machines, R115 576,14/mo); financing_terms is the client's current sheet (18 agreements, R428 585,04/mo). Using both double-counted MG02, RV04, TLB06 and TLB07, so financing_terms wins and the stale rows are ignored. TB01 has no financing_terms row, so its old instalment no longer counts — consistent with it being absent from the current sheet. Insurance has one source and no such problem. Insurance is resolved from the RATE PERIODS rather than the derived cost_lines, so a premium that moves mid-year is charged at the price that applied that month. Also: settled agreements contribute nothing (a paid-off machine is not a running cost), purchase lines are filed under the PO date, and the bottom row keeps showing incl above excl. The page carries one line saying this is a re-cut of costs already inside fixed expenses — adding it to them would count the same premium twice. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-10-09 10:28:29 +00:00
A re-cut of costs already counted in fixed expenses — do not add this to them.
Figures are incl VAT, with the excl figure derived at {RUNNING_VAT_PCT}%.
</p>
</div>
<div className="bg-gradient-to-br from-[#EDAE49] to-[#D1495B] rounded-2xl px-5 py-3 text-white shadow-lg shadow-orange-500/20 self-start sm:self-auto">
<div className="text-xs text-white/80">YTD running cost · incl VAT</div>
<div className="text-2xl font-semibold tabular-nums">{ZAR(grand)}</div>
Running cost = everything linked to a vehicle: repairs, purchases, insurance, finance A machine with no repairs and no purchase order still carries an insurance premium and, while it is financed, a monthly instalment. So a blank row was never "this vehicle costs nothing" — it was "nothing recorded", which is a gap rather than a figure. The Overview now totals all four kinds per machine per month. Everything is read from POCKETBASE, the registers the client maintains in the app. The original spreadsheet only bootstrapped the page (monthly_running_costs, Jan-Aug); it is not a source here. September having no workbook data is expected and correct — the figures there now come from the app. Two finance sources existed and OVERLAPPED. The cost_lines instalment rows are the old workbook's subset (5 machines, R115 576,14/mo); financing_terms is the client's current sheet (18 agreements, R428 585,04/mo). Using both double-counted MG02, RV04, TLB06 and TLB07, so financing_terms wins and the stale rows are ignored. TB01 has no financing_terms row, so its old instalment no longer counts — consistent with it being absent from the current sheet. Insurance has one source and no such problem. Insurance is resolved from the RATE PERIODS rather than the derived cost_lines, so a premium that moves mid-year is charged at the price that applied that month. Also: settled agreements contribute nothing (a paid-off machine is not a running cost), purchase lines are filed under the PO date, and the bottom row keeps showing incl above excl. The page carries one line saying this is a re-cut of costs already inside fixed expenses — adding it to them would count the same premium twice. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-10-09 10:28:29 +00:00
<div className="text-xs text-white/75 tabular-nums mt-0.5">excl VAT {ZAR(grandExcl)}</div>
</div>
</div>
Running cost = everything linked to a vehicle: repairs, purchases, insurance, finance A machine with no repairs and no purchase order still carries an insurance premium and, while it is financed, a monthly instalment. So a blank row was never "this vehicle costs nothing" — it was "nothing recorded", which is a gap rather than a figure. The Overview now totals all four kinds per machine per month. Everything is read from POCKETBASE, the registers the client maintains in the app. The original spreadsheet only bootstrapped the page (monthly_running_costs, Jan-Aug); it is not a source here. September having no workbook data is expected and correct — the figures there now come from the app. Two finance sources existed and OVERLAPPED. The cost_lines instalment rows are the old workbook's subset (5 machines, R115 576,14/mo); financing_terms is the client's current sheet (18 agreements, R428 585,04/mo). Using both double-counted MG02, RV04, TLB06 and TLB07, so financing_terms wins and the stale rows are ignored. TB01 has no financing_terms row, so its old instalment no longer counts — consistent with it being absent from the current sheet. Insurance has one source and no such problem. Insurance is resolved from the RATE PERIODS rather than the derived cost_lines, so a premium that moves mid-year is charged at the price that applied that month. Also: settled agreements contribute nothing (a paid-off machine is not a running cost), purchase lines are filed under the PO date, and the bottom row keeps showing incl above excl. The page carries one line saying this is a re-cut of costs already inside fixed expenses — adding it to them would count the same premium twice. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-10-09 10:28:29 +00:00
{undatedPurchases.length > 0 && (
<div className="mb-4 flex items-start gap-2 rounded-2xl border border-[#EDAE49]/30 bg-[#EDAE49]/[0.06] p-4 text-xs text-gray-600 dark:text-gray-400">
<TriangleAlert className="w-4 h-4 mt-0.5 shrink-0 text-[#EDAE49]" />
<span>
<span className="font-semibold text-[#003D5B] dark:text-white">
Running cost = everything linked to a vehicle: repairs, purchases, insurance, finance A machine with no repairs and no purchase order still carries an insurance premium and, while it is financed, a monthly instalment. So a blank row was never "this vehicle costs nothing" — it was "nothing recorded", which is a gap rather than a figure. The Overview now totals all four kinds per machine per month. Everything is read from POCKETBASE, the registers the client maintains in the app. The original spreadsheet only bootstrapped the page (monthly_running_costs, Jan-Aug); it is not a source here. September having no workbook data is expected and correct — the figures there now come from the app. Two finance sources existed and OVERLAPPED. The cost_lines instalment rows are the old workbook's subset (5 machines, R115 576,14/mo); financing_terms is the client's current sheet (18 agreements, R428 585,04/mo). Using both double-counted MG02, RV04, TLB06 and TLB07, so financing_terms wins and the stale rows are ignored. TB01 has no financing_terms row, so its old instalment no longer counts — consistent with it being absent from the current sheet. Insurance has one source and no such problem. Insurance is resolved from the RATE PERIODS rather than the derived cost_lines, so a premium that moves mid-year is charged at the price that applied that month. Also: settled agreements contribute nothing (a paid-off machine is not a running cost), purchase lines are filed under the PO date, and the bottom row keeps showing incl above excl. The page carries one line saying this is a re-cut of costs already inside fixed expenses — adding it to them would count the same premium twice. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-10-09 10:28:29 +00:00
{undatedPurchases.length} purchase line{undatedPurchases.length !== 1 && "s"} could not be filed
</span>{" "}
Running cost = everything linked to a vehicle: repairs, purchases, insurance, finance A machine with no repairs and no purchase order still carries an insurance premium and, while it is financed, a monthly instalment. So a blank row was never "this vehicle costs nothing" — it was "nothing recorded", which is a gap rather than a figure. The Overview now totals all four kinds per machine per month. Everything is read from POCKETBASE, the registers the client maintains in the app. The original spreadsheet only bootstrapped the page (monthly_running_costs, Jan-Aug); it is not a source here. September having no workbook data is expected and correct — the figures there now come from the app. Two finance sources existed and OVERLAPPED. The cost_lines instalment rows are the old workbook's subset (5 machines, R115 576,14/mo); financing_terms is the client's current sheet (18 agreements, R428 585,04/mo). Using both double-counted MG02, RV04, TLB06 and TLB07, so financing_terms wins and the stale rows are ignored. TB01 has no financing_terms row, so its old instalment no longer counts — consistent with it being absent from the current sheet. Insurance has one source and no such problem. Insurance is resolved from the RATE PERIODS rather than the derived cost_lines, so a premium that moves mid-year is charged at the price that applied that month. Also: settled agreements contribute nothing (a paid-off machine is not a running cost), purchase lines are filed under the PO date, and the bottom row keeps showing incl above excl. The page carries one line saying this is a re-cut of costs already inside fixed expenses — adding it to them would count the same premium twice. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-10-09 10:28:29 +00:00
— no readable PO date ({undatedPurchases.slice(0, 3).join(", ")}). Excluded rather than
guessed into January.
</span>
</div>
)}
Running cost = everything linked to a vehicle: repairs, purchases, insurance, finance A machine with no repairs and no purchase order still carries an insurance premium and, while it is financed, a monthly instalment. So a blank row was never "this vehicle costs nothing" — it was "nothing recorded", which is a gap rather than a figure. The Overview now totals all four kinds per machine per month. Everything is read from POCKETBASE, the registers the client maintains in the app. The original spreadsheet only bootstrapped the page (monthly_running_costs, Jan-Aug); it is not a source here. September having no workbook data is expected and correct — the figures there now come from the app. Two finance sources existed and OVERLAPPED. The cost_lines instalment rows are the old workbook's subset (5 machines, R115 576,14/mo); financing_terms is the client's current sheet (18 agreements, R428 585,04/mo). Using both double-counted MG02, RV04, TLB06 and TLB07, so financing_terms wins and the stale rows are ignored. TB01 has no financing_terms row, so its old instalment no longer counts — consistent with it being absent from the current sheet. Insurance has one source and no such problem. Insurance is resolved from the RATE PERIODS rather than the derived cost_lines, so a premium that moves mid-year is charged at the price that applied that month. Also: settled agreements contribute nothing (a paid-off machine is not a running cost), purchase lines are filed under the PO date, and the bottom row keeps showing incl above excl. The page carries one line saying this is a re-cut of costs already inside fixed expenses — adding it to them would count the same premium twice. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-10-09 10:28:29 +00:00
{unallocated > 0 && (
<div className="mb-4 rounded-2xl border border-[#30638E]/25 bg-[#30638E]/[0.05] p-4 text-xs text-gray-600 dark:text-gray-400">
<span className="font-semibold text-[#003D5B] dark:text-white">
{unallocated} purchase line{unallocated !== 1 && "s"} not yet allocated
</span>{" "}
to a machine, so they are{" "}
<span className="font-medium">not</span> in these totals — see{" "}
<Link href="/running/purchases" className="underline inline-block py-4 -my-4">
Purchases
</Link>
.
</div>
)}
<RunningView
rows={rows}
palette={{ income: "#EDAE49", profit: "#EDAE49", loss: "#EDAE49" }}
monthTotals={monthTotals}
monthTotalsExcl={monthTotalsExcl}
Running cost = everything linked to a vehicle: repairs, purchases, insurance, finance A machine with no repairs and no purchase order still carries an insurance premium and, while it is financed, a monthly instalment. So a blank row was never "this vehicle costs nothing" — it was "nothing recorded", which is a gap rather than a figure. The Overview now totals all four kinds per machine per month. Everything is read from POCKETBASE, the registers the client maintains in the app. The original spreadsheet only bootstrapped the page (monthly_running_costs, Jan-Aug); it is not a source here. September having no workbook data is expected and correct — the figures there now come from the app. Two finance sources existed and OVERLAPPED. The cost_lines instalment rows are the old workbook's subset (5 machines, R115 576,14/mo); financing_terms is the client's current sheet (18 agreements, R428 585,04/mo). Using both double-counted MG02, RV04, TLB06 and TLB07, so financing_terms wins and the stale rows are ignored. TB01 has no financing_terms row, so its old instalment no longer counts — consistent with it being absent from the current sheet. Insurance has one source and no such problem. Insurance is resolved from the RATE PERIODS rather than the derived cost_lines, so a premium that moves mid-year is charged at the price that applied that month. Also: settled agreements contribute nothing (a paid-off machine is not a running cost), purchase lines are filed under the PO date, and the bottom row keeps showing incl above excl. The page carries one line saying this is a re-cut of costs already inside fixed expenses — adding it to them would count the same premium twice. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-10-09 10:28:29 +00:00
byKind={monthByKind}
visibleMonths={lastMonth}
/>
</div>
);
}