Finalisation rules
What it is
Section titled “What it is”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, offset, etc.). The two flows are independent: booking finalisation creates debits; payments settlement clears them.
Who can use it
Section titled “Who can use it”- 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.
Where to find it
Section titled “Where to find it”- 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.
Fields / options
Section titled “Fields / options”From the booking detail screen
Section titled “From the booking detail screen”| Field | What it sets |
|---|---|
| Shortfall preview | The shortfall amount that will be posted (read-only). Computed server-side from the booking’s usage logs. |
| Waive shortfall | Checkbox. When ticked, the shortfall is charged and immediately credited back, leaving the waiver on record. Offered only when there is a positive shortfall to waive. |
| Custom charge | Optional extra line (for example a hangar fee). Requires a description. |
From the unfinalised bookings queue
Section titled “From the unfinalised bookings queue”| Field | What it does |
|---|---|
| Finalise All (count) | Finalises every booking the look-back continuity check accepted (those showing a Junction confirmed badge, see How each path handles a junction below). Four badges hold a booking back: Nobody assigned (nobody to charge — assign the booking to a member), Junction conflict, Awaiting previous log (the previous flight on the asset hasn’t been logged yet), and Couldn’t check. Nobody assigned is tested first and independently of the junction, because the server refuses an unassigned booking outright and a bulk run is one transaction — leaving it in would take every other booking down with it. The count reflects the includable subset; when nothing is includable the button is greyed out at “Finalise All (0)”. |
Behaviour rules
Section titled “Behaviour rules”What finalisation does
Section titled “What finalisation does”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, finalisation writes no charge at all. Flying the aircraft to the engineer is a cost of owning it, in the same family as hangarage and insurance, and those are already met through the monthlies — so there is nothing left to bill per flight, and no shortfall either. Finalising a maintenance booking only closes it: its status moves to completed. The flight itself is unaffected by that: its hours had already moved the asset’s meter and joined the technical log the moment the usage log was saved, independently of finalisation. A syndicate that genuinely needs extra money for a big maintenance bill raises a cash call instead — a deliberate, separately-issued charge, not something finalisation does on its own.
That holds however the booking is finalised — opened on its own, picked up in a bulk run from the unfinalised queue, or closed by the auto-finalisation sweep. A maintenance booking closes automatically on the first sweep after its end time, and does so even in a syndicate that has auto-finalisation switched off: that setting decides whether a member’s flying becomes a charge without an admin’s say-so, and closing a maintenance booking never charges anybody, so there is nothing for it to protect. That applies whether or not anyone logged usage against the booking — an annual with the aircraft on a trailer records no hours, costs nobody anything, and closes on the same schedule.
Once the transactions are written, the booking’s status changes to completed. The booking cannot be finalised a second time.
Rate snapshot
Section titled “Rate snapshot”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 asset’s current base rate, and then to the syndicate’s default rate if the asset has none. No scheme modifier or asset-scheme override is applied on the way past: scheme resolution happens only when a snapshot is stamped. This is the only path by which a late rate change can reach an existing log.
Shortfall
Section titled “Shortfall”The shortfall is computed before finalisation and shown in the shortfall preview on the booking detail screen.
A minimum is a day minimum, and only some days count towards it. The booking is broken into the calendar days it touches and each day is judged on its own. A day contributes its minimum only when the booking covers at least eight hours between 08:00 and 20:00 on that day. That twelve-hour stretch is the day’s core window, and hours outside it count towards nothing. A qualifying Saturday or Sunday contributes the weekend minimum; any other qualifying day contributes the weekday minimum. A day that does not qualify contributes nothing.
The booking’s expected usage is the sum of the days that qualified, and the shortfall is the amount the member flew below it:
expected_hours = sum of the minimum for each qualifying dayshortfall_hours = max(0, expected_hours − total_logged_hours)shortfall_charge = shortfall_hours × shortfall_rateWhat the minimum is for. It charges for monopolising the asset, not for flying little. A member who books an aircraft for a half day leaves the rest of that day free for somebody else, so nothing is owed however briefly they flew. The case the minimum exists to catch is the member who books Monday to Friday and flies twenty minutes on the Wednesday, keeping everyone else on the ground all week.
That is why the threshold is eight of the day’s twelve core hours rather than any flying-time test, and reading the rule against that intent is what makes its edges make sense. Monday to Friday with twenty minutes flown qualifies all five days, so the minimum bites five times. A half-day booking qualifies no day and is exempt, which is the right answer. An overnight Friday-into-Saturday qualifies neither day, which is also right: nobody else wanted the aircraft at three in the morning.
What this means in practice. A short weekday flight raises no shortfall, however high the weekday minimum is set: a booking from 09:00 to 13:00 covers four hours of the core window, so that day expects nothing and there is nothing to fall short of. Nor does a long booking at the wrong end of the day — 05:00 to 13:00 is eight hours, but only five of them (08:00 to 13:00) fall inside the window. For a day to count, the booking must hold eight of that day’s twelve core hours, so it cannot start after 12:00 or end before 16:00 on a day it is to count. Hours flown always count in full towards the total, whether or not the day they were flown on qualified.
A multi-day booking adds up the days that qualified. A booking running from Saturday morning to Sunday evening that holds eight core hours on both days expects the weekend minimum twice.
Days are counted in the operating timezone — currently the booking owner’s profile timezone, falling back to Europe/London — and the window is worked out in local wall-clock time, so it stays 08:00 to 20:00 on the two days a year the clocks change.
The admin can waive the shortfall at finalisation using the Waive shortfall checkbox. Waiving charges the shortfall and credits it straight back, leaving the waiver on record. The shortfall amount itself is computed server-side and shown read-only; it cannot be reduced or increased.
Atomicity
Section titled “Atomicity”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.
How each path handles a junction
Section titled “How each path handles a junction”The two automatic paths (member-triggered auto and admin bulk) run the same look-back check against the previous flight on the asset; they differ only in when they run, not in the direction of the check. The manual single-booking path skips the check entirely on admin trust.
| Path | Continuity check | Junction match | Junction mismatch | No previous log yet |
|---|---|---|---|---|
| Manual single (finalise a booking) | None (admin trust) | Finalises | Finalises (admin has decided) | Finalises |
| Auto on submit (auto-finalisation) | Look back: compare my start to previous booking’s last log end | Finalises | Skips, fires the meter-continuity notification | Previous absent → finalises. Previous unsubmitted → waits silently for retry |
| Admin bulk (finalise multiple at once) | Look back: compare my start to previous booking’s last log end | Includes (Junction confirmed) | Excludes (Junction conflict) | No previous flight → includes (first flight on the asset). Previous unsubmitted → excludes (Awaiting previous log) |
The most-recent flight on an asset needs no special handling under the look-back check: it is compared to the flight before it, never to a future flight, so it clears as Junction confirmed (or because it is the first flight on the asset and has nothing before it to disagree with). There is no “trailing flight” exclusion, and “Finalise All” clears the whole clean queue rather than leaving the latest flight behind. If that flight’s end reading later turns out to have been wrong (the next pilot’s start disagrees with it once they fly and log), the recovery path is correct a finalised booking.
A look-back lookup that fails (network error, transient repository failure) is not the same as a confirmed continuity verdict: the booking is excluded with a Couldn’t check badge, so the admin refreshes and re-runs once the lookup recovers.
Reversing a finalisation
Section titled “Reversing a finalisation”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).
Reversals on a payments settlement are a separate flow and do not undo the booking-level finalisation either. Be aware that raising one against a payment collected through the payment provider moves real money: it asks the provider to return it to the member. What happens to the charges then depends on what the refund was recorded as — re-opened, forgiven, or left settled at a corrected figure. See Refund or correct a payment.
See also
Section titled “See also”- Transaction types: every ledger entry finalisation can write
- Member balance: where the charges land
- Auto-finalisation: the eager pay-as-you-go path with look-back continuity
- Tacho-continuity conflict: the meter-junction check both paths use
- Finalise a booking: the manual single-booking recipe
- Finalise multiple bookings at once: the admin bulk recipe with look-back classifications
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.