Background Schedulers
Five jobs run on their own every day, on a fixed timetable. You don't open a screen and press "start" — you mostly see and act on the records they leave behind.
Nothing on this page corresponds to a page under /staff that you click into. Each job is a scheduled command that runs unattended on the server. Your involvement is upstream (setting the kill-switches in System Configuration) and downstream (working the sale orders, picking waves and bank statements the jobs produce or touch).
The daily timetable
The five jobs run in this order every day. Reservation runs first because everything else in despatch depends on stock having been set aside; wave creation follows an hour later so it only ever groups moves that are already reserved. The despatch safety net runs two hours after that, checking for anything reservation should have picked up but didn't.
Reservation itself has nothing to do if no one has created stock moves to reserve — that's the job of Release for despatch, a console action rather than a scheduled job. See the callout below the timetable for how the two connect.
The chain that starts with an approved order and ends with a despatched package now runs all the way through: Release for despatch (a Products row action, stock_move.create — see Products) creates Confirmed delivery stock moves → air:auto-reserve reserves them → air:auto-wave groups them into picking waves → waves become packages and go out for despatch. Release is a manual console action, not a scheduled job; the five jobs on this page are what carries a released move the rest of the way automatically.
Auto-reservation Built
Command air:auto-reserve, runs daily at approximately 02:00.
It scans confirmed delivery stock-moves in order: products with a higher delivery priority first, then a lower despatch sort order, then the move's own priority (critical, urgent, normal) and its scheduled date. For each move it does one of two things: reserve the available stock (moving quantity from available to reserved), or — if the move fails one of the credit-control checks below — hold it under a suspend reason instead of reserving it. A warehouse or carrier can opt out of this entirely; any move at a location or carrier whose allow_autoreservation flag is off is skipped and left for manual handling.
The checks run strictest first, and only the first one that fails is recorded — so the hold reason you see on a move is the thing you actually have to fix. See Stock Moves → Why a move is held for what each reason means and what to do about it.
- Carrier can't deliver there
The order's delivery pincode is marked as not serviceable by the carrier on the move → held as Delivery pincode not serviceable by the assigned carrier. If there is no serviceability record for that pincode and carrier at all, the move passes — a missing record is never treated as "unserviceable".
- A return is holding this customer's further parts
An open (not yet reconciled or cancelled) return for this customer has an item an inspector marked suspend further parts → held as A pending return for this customer holds further parts.
- Too much uncollected COD cash is already out
The customer has too many despatched or delivered COD packages whose money has not come back yet → held as Too many unremitted COD packages already out for this customer. This check is switched off until an administrator sets a limit — see reservation.cod_in_transit_limit in System Configuration.
- The full set isn't paid
The product is flagged withhold until paid in full and the payments recorded against that order line don't yet cover the whole line → held as Full set not yet paid. No part of the set goes out until it is paid.
- The minimum payment isn't in
The product has a minimum payment allocation % and the payments against the order line, or against the whole order, are below it → held as Minimum payment allocation not reached. Clears itself once the payment reaches the percentage.
- This part isn't paid for
The product is flagged send strictly against payment and the payments against the order line don't yet cover this part's share of the line → held as Payment not received/allocated. Parts go out only as far as the money reaches.
- Too many unpaid parts of the set are out
The part belongs to a set with a parts-on-credit limit, it isn't paid for, and the customer already has that many unpaid parts of the set reserved or sent → held as Parts-on-credit limit reached for this set.
- The customer is over their credit limit
Credit-limit checking is on for the customer and what they owe exceeds the ceiling → held as Credit limit exceeded.
- The order's payment hasn't settled
The last catch-all: the order is not settled for head office → held as Payment not received/allocated.
A part's share, for the two payment checks, is the order line's net amount divided by the number of parts on that line — for a twelve-part Full Set, one twelfth of the line per part.
A move flagged ignore_rule_and_despatch skips every check above and reserves regardless.
Running out of stock is not a hold: a move with insufficient stock simply stays Confirmed and is tried again on the next night's run.
Controlled by the reservation.enabled switch in System Configuration. Turn it off and the job still runs but does nothing.
Open Stock Moves the morning after a run: reserved moves show as Reserved, and anything the credit-control checks stopped shows as Suspended with its Hold reason filled in. You can also watch it indirectly — the qty_reserved column on Stock on hand rises for the products it touched, and an hour later the reserved moves start appearing grouped into new picking waves (below).
Auto-wave creation Built
Command air:auto-wave, runs daily at approximately 03:00, after reservation.
It groups reserved delivery moves that aren't yet part of a wave by location, carrier, product category, product timeline and the product's wave group # (plus delivery route for hand delivery), and turns each group into a picking wave — batches of up to 500 moves per wave, with a solo wave carved out for any single large-quantity move (more than 50 units). A move with no carrier assigned is skipped rather than forced into a wave.
Controlled by the wave.enabled switch in System Configuration.
The waves it creates land in Picking Waves at Draft / Items Identified, ready for despatch staff to print labels, pack and send them on.
Despatch safety net Built
Command air:despatch-safety-net, runs daily at approximately 05:00, after auto-wave and before the health check.
This job is a safety net, not a producer — it never creates a stock move itself. It looks for order lines that should have a move by now and don't: any line on an order that is ApprovedForDespatch, whose product is flagged to be considered for despatch, that still has no stock move at all. Each one it finds is logged as a dropped record (so it's possible to review the specific line later), and the scheduler run is marked Warning if it found anything, Success if it found nothing.
In the normal flow, Release for despatch creates the move for every eligible line the moment a product is released. This job exists to catch the exceptions — a release that was never triggered for a product, or one whose queued job failed partway through — before they sit unnoticed for days.
Finding an orphan line here does not create the missing move. If you spot a Warning run, the fix is to release the affected product again from Products — re-releasing is safe and only ever picks up lines that still don't have a move.
Gateway settlement bifurcation Built
Command air:bifurcate-settlements, runs daily at approximately 07:00.
Online-gateway settlements (Razorpay, CCAvenue) arrive as one lump sum covering many customer payments. This job splits a bank statement's gateway settlement lines back into the individual payment vouchers they represent, so each customer's payment can be reconciled on its own. See Bank Reconciliation for the statement screen this feeds.
Health check Built
Command air:health-check, runs daily at approximately 06:00.
Records a snapshot of overall system health. Review it in Administration › Diagnostics › Health Check Results — see Diagnostics below.
Reviewing what the schedulers did
Every run above is recorded and can be reviewed in the console. The Administration → Diagnostics screens (gated diagnostics.view) show Scheduler Runs (each run's status + processed/skipped/failed counts), Dropped Records (exactly what each run skipped and why — e.g. the despatch safety net's orphan-line log or a credit-held reservation), and Health Check Results (the latest health-check output). See the Diagnostics page.