GS Crane Enterprise hires cranes out of Seremban off a claim sheet and a paper book. The tally at month end — whose days were billed, whose weren't, which crane actually made money — was done by hand, which meant it was sometimes done wrong.
The claim sheet GS Crane already used records a crane-day: the date, which crane, which site, the basic charge, and any overtime hours. The problem was never the record — it was what happened to it afterwards. Tallying a customer's unbilled days onto one invoice at month end was a manual pass over a paper book, and a manual pass over a paper book misses things and repeats things.
The harder question sat underneath the billing one. Fuel, maintenance, operator wages and tolls all landed in the same pile, with no route back to which crane earned them. A machine's margin was a feeling the office had, not a number anyone could show.
The system keeps the same atomic unit the claim sheet already used: a crane-day with a date, a crane, a site, a basic charge and overtime hours. What changed is what happens once it's logged. The rate and billing basis prefill from the customer record, and the crane plate autocompletes from the machine register, so entering a day is closer to confirming one than typing one from scratch.
Invoicing pulls every unbilled crane-day for a customer across a date range onto one document and renders it as a PDF built in React, not printed off a spreadsheet template. Quotations run off the same builder, so a quote and the eventual invoice are the same shape.
AMOUNT is Basic Total plus Overtime Hours times Overtime Charges — copied verbatim from GS Crane's own claim sheet rather than a formula we chose. That mattered more than it sounds: the office has run this arithmetic for years, and the fastest way to ship a wrong invoice is to have a developer re-derive a rate calculation they've never actually billed against.
Expenses carry a category and an optional crane. Tag an expense to a machine and it sets against that machine's income for the period; leave it untagged and it's still recorded, but it doesn't count toward any single crane's number. Net earnings — invoiced less spent — is then a figure for whatever period the office picks, per crane or across the fleet.
Sign-in supports an authenticator app with ten single-use recovery codes, and a superadmin can make two-factor mandatory company-wide rather than leaving it optional per user. A lost phone resets through the superadmin's own password, and every reset writes to an append-only security log — the same discipline as the billing ledger itself: nothing happens without a record of it happening.
Take the client's own formula and use it exactly, rather than treat a billing calculation as something to redesign. And deploy under the client's own accounts from day one — GS Crane's GitHub, Supabase and Vercel — so the system they depend on is never something we hold the keys to.