← All notes

Hotel Management

Folios that split without a spreadsheet

A guest bill is not a total. It is a set of postings with owners, and the moment two people pay for parts of one stay, a single amount column stops working.

  • Invexa Technologies
  • 2 min read

Front desk asks to split a bill. The company pays room and tax, the guest pays the minibar and the spa. If your booking has a total_amount column, this is now a manual exercise with a calculator and a printed folio.

A folio is a ledger

Every chargeable event is a posting, not an adjustment to a total:

folio_postings
  folio_id
  stay_date
  code            -- ROOM | TAX | FNB | SPA | MISC
  description
  amount_minor
  posted_at
  posted_by
  reversed_by     -- null unless corrected

The balance is the sum. It is never stored, because a stored total is a second source of truth that will disagree with the postings the first time someone corrects one.

Corrections are reversing postings, not edits. A charge posted in error stays on the folio with a matching negative beside it. That is not pedantry — a guest disputing a charge that silently vanished has no way to see it was handled, and neither does the night auditor.

Splitting is routing, not arithmetic

Add a second folio to the same reservation and give each posting an owner:

reservations 1 ─── * folios ─── * postings

“Split the bill” becomes moving postings between folios, which is one update to a foreign key and fully reversible. No recalculation, no rounding, no chance of the parts failing to sum to the whole — because the whole was always just the sum of the parts.

Routing rules make it automatic: room and tax to the company folio, everything else to the guest folio, set at check-in from the rate plan.

Why this shape survives the edge cases

Group bookings with one master account and twenty individual folios: same model. A guest extending by two nights mid-stay: two more room postings, no recalculation. Tax that changes rate on the first of the month: the postings already carry their own dates.

Every one of those breaks a total_amount column and none of them break a posting list.

The night audit falls out for free

The end-of-day run is a query over postings by date. With a total column it is a reconstruction, done nightly, that has to guess what happened.

Next step

Have a project in mind?

A 30-minute call is usually enough to know whether we are the right team for it. If we are not, we will say so.

Start a project

Replies within one working day