Skip to content

Finalisation rules

Finalisation is the act of finalising a booking’s financial consequences. An admin (or the auto-finalisation process) reviews the booking’s usage logs, writes the resulting transactions to the ledger, applies any shortfall, and moves the booking’s status from confirmed to completed.

Before a booking is finalised, its usage is informational: the member has logged flight data but no money has moved on the ledger. After finalisation, the charges are real — they are on the member’s balance and appear on the statement.

Booking finalisation vs payments settlement — this page is about booking finalisation: turning a flight or maintenance booking into ledger entries. The payments domain has transaction settlement — the record that a charge has been paid (by card, Direct Debit, waiver, fund offset, etc.). The two flows are independent: booking finalisation creates debits; payments settlement clears them.

  • Owner and admin — finalise any booking manually from the booking detail screen or in bulk from the Unfinalised bookings queue.
  • Treasurer (admin) — same; this is typically the treasurer’s workflow.
  • Member — cannot finalise. Sees the finalisation outcome on their balance after it runs.
  • Booking detail: /syndicates/:syndicateId/bookings/:bookingId. The Finalise Booking section appears on confirmed, not-yet-finalised bookings.
  • Unfinalised bookings queue: /syndicates/:syndicateId/unfinalised-bookings. A list of every booking awaiting finalisation, with Finalise All for the zero-shortfall ones.
FieldWhat it sets
Shortfall chargeThe shortfall amount that will be posted. Pre-filled from the calculated shortfall (hours × shortfall rate); can be edited to override, including to £0.
Custom chargeOptional extra line (for example a hangar fee). Requires a description.
NoteOptional note attached to the shortfall transaction description.
FieldWhat it does
Finalise All (count)Finalises every booking the look-ahead continuity check accepted (the included and includedTrailing rows — see How each path handles a junction below). Bookings classified as excludedMismatch or excludedNextUnsubmitted are left in the queue. The count reflects the includable subset; when nothing is includable the button is greyed out at “Finalise All (0)”.

Finalisation atomically writes the following ledger entries:

  • One usage charge transaction per usage log, equal to logged usage × resolved rate. The rate is read from the rate snapshot stored on the log at the time the log was saved.
  • One event charge per active event counter on each log (landings, touch-and-gos, etc.). The rate for each event is read from the same snapshot.
  • One minimum shortfall transaction if the booking came in below the configured minimum and the shortfall was not overridden to zero.
  • One custom charge transaction if the admin entered one.

For maintenance bookings, the flow differs in two respects: no shortfall is applied, and the costs are posted as maintenance expense transactions split across equity members proportional to each member’s equity share.

Once the transactions are written, the booking’s status changes to completed. The booking cannot be finalised a second time.

When a usage log is saved, the rates in effect at that moment — the asset’s resolved usage rate for the logging member, the shortfall rate, the event fee rates, and the currency — are snapshotted onto the log. Finalisation uses the snapshot, not the live rates. This means:

  • Changing an asset base rate or a scheme modifier after a log is saved does not retroactively change what that log charges.
  • Very old logs that pre-date snapshotting fall back to the current asset billing config, with the member’s scheme and any asset-scheme rate override applied on read. This is the only path by which a late rate change can reach an existing log.

The shortfall is computed before finalisation and shown in the shortfall preview on the booking detail screen. The formula is:

shortfall_hours = max(0, configured_minimum − total_logged_hours)
shortfall_charge = shortfall_hours × shortfall_rate

The admin can edit the shortfall on finalisation — waive it (set to zero), reduce it, or increase it. Any change is captured in the transaction description.

Finalisation is one database transaction. Either every charge, every event, any shortfall, any custom charge, and the status change all land together, or none of them do. There is no partial finalisation.

The three finalisation paths — single-booking manual, member-triggered auto, and admin bulk — handle a meter-junction disagreement between consecutive bookings differently. The asymmetry is deliberate: it matches the cadence each path serves.

PathContinuity checkJunction matchJunction mismatchNo previous / next log yet
Manual single (finalise a booking)None — admin trustFinalisesFinalises (admin has decided)Finalises
Auto on submit (auto-finalisation)Look back — compare my start to previous booking’s last log endFinalisesSkips, fires tacho_continuity_detectedPrevious absent → finalises. Previous unsubmitted → waits silently for retry
Admin bulk (finalise multiple at once)Look ahead — compare my end to next booking’s first log startIncludes (included)Excludes (excludedMismatch)No next booking → includes on admin trust (includedTrailing, badge shown). Next unsubmitted → excludes (excludedNextUnsubmitted)

The “trailing flight” case in the bulk path deserves a note: every asset always has a most-recent flight, so excluding trailing flights would turn “Finalise All” into “Finalise Most” almost every cycle. They are included on admin trust with an informational badge, on the assumption that the admin glances at the values during reconciliation. If a trailing reading later turns out to have been wrong, the recovery path is correct a finalised booking.

A look-ahead lookup that fails (network error, transient repository failure) is not the same as a confirmed-no-successor: it falls into excludedNextUnsubmitted so the admin re-runs once the lookup recovers.

A completed booking cannot be “unfinalised”. If the finalisation was wrong, the admin posts a reversal to cancel the bad charges and, if needed, writes a new transaction in the right shape. The booking’s completed status stays — the money is corrected through the ledger, not by undoing the finalisation.

Reversals carry a cause (admin correction, full refund, partial refund) and a transaction-handling mode (rebill puts the original charges back on the member; forgive writes them off). Note that reversals on a payments settlement (e.g. a chargeback against a card payment) are a separate flow and do not undo the booking-level finalisation either — they re-open the underlying transactions for re-collection.

For the reasoning behind finalisation being a separate, explicit step rather than happening on log save, see the explanation on why finalisation is a separate step.