- Cash Floats: ledger card (opening balance, top-ups, slips), manual entries, slip photos - Office access level; clock app Slips tab (photograph a slip, popup for supplier/cost code/comments/amount); only Office sees it; per-role route table in lib/clock-access - Job cards: Machine Service PDF (with Oil block), JC numbers, manual Close job, Delete - Hide Expenses > Vehicle Costs and Finance (Bastion) from the menu Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
17 lines
896 B
TypeScript
17 lines
896 B
TypeScript
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { cashBalance, hasOpening, parseAmount } from "./cash-float";
|
|
|
|
test("balance is opening + top-ups minus slips, to the cent", () => {
|
|
assert.equal(cashBalance([{ kind: "opening", amount: 1000 }, { kind: "expense", amount: 250.1 }, { kind: "expense", amount: 0.2 }, { kind: "topup", amount: 100 }]), 849.7);
|
|
assert.equal(cashBalance([]), 0);
|
|
});
|
|
test("a card with no opening entry is not started", () => {
|
|
assert.equal(hasOpening([{ kind: "expense", amount: 5 }]), false);
|
|
assert.equal(hasOpening([{ kind: "opening", amount: 0.01 }]), true);
|
|
});
|
|
test("amounts accept South African typing and refuse junk", () => {
|
|
assert.equal(parseAmount("1 250,50"), 1250.5);
|
|
assert.equal(parseAmount("12.345"), 12.35);
|
|
for (const bad of ["", "0", "-5", "abc", "99999999"]) assert.equal(parseAmount(bad), null, bad);
|
|
});
|