Finalise is a different button, and a different endpoint — transcript
Play this as a presentation — one slide per step, with the same narration. Every word of every step is on this page.
This lesson is for whoever at GadgetSphere presses Finalise, or writes the integration that presses it. In about thirteen minutes you will know that Finalise is a separate call rather than a save with a flag, which nine checks can turn it down, what it writes onto your document before anything else happens, and why the copy you get back already differs from the one you sent.
Step 1 — Stop thinking of Finalise as a save
After this step you will read the rest of this series correctly. Saving a document and finalising one are two different endpoints on the server. The save takes the whole document and stores it. The finalise takes only the document’s identifier and a posting status, runs a set of checks the save never runs, stamps a few fields, and then puts one row on a work queue. Almost everything a reader thinks of as “posting” happens after that call has already returned. If you go looking in the save path for the journal entry, you will never find it, because it is not there.
Reference: How Work Actually Runs — Trace it once: what one Finalise actually starts
Step 2 — Know the nine ways it can be refused
After this step you will recognise a refusal instead of guessing at it. Before anything is stamped, the server checks the exchange rate on a foreign-currency document, whether the customer is blacklisted for credit, whether the serial numbers, bin quantities and batch quantities on each line add up to the line quantity, whether there is stock at the line’s location, optionally whether you are selling below cost, optionally whether the member has the points being redeemed, and whether the transaction date falls in a locked fiscal period. Every failure is collected and returned together, so one rejection can carry several reasons.
Reference: Sales Invoice (Internal) — Lifecycle and effects
Step 3 — Know that three of those checks are decided by the screen, not by a setting
After this step you will stop hunting for a company-level switch that does not exist. Three of those checks are switched on and off by the request itself. The stock check is on by default and goes off if the applet was configured to hide stock balances. The sell-below-cost check is off unless the caller asks for it, and the sales invoice applet never asks. The points check is sent when you finalise several documents from the listing and not when you finalise one from the form. So the same document can pass from one screen and fail from another, which is a real answer to a question that otherwise looks like a bug.
Reference: Sales Invoice (Internal) — Lifecycle and effects
Step 4 — Know what it stamps before it queues anything
After this step you will know why a finalised document differs from the draft you were looking at. Once the checks pass, the server sets the finalised date, and unless the document is holding its own transaction date it may rewrite that date to the finalised date, the created date or the updated date, according to the rule the request carries. It copies the customer’s e-invoice skip flag onto the header. It then assigns the running numbers — tenant, company and branch — which is why a draft has no document number and a final one does. Only then is any work queued.
Reference: Sales Invoice (Internal) — Lifecycle and effects
Step 5 — Know what the shared save path rewrites on the way through
After this step you will stop being surprised by fields that change without an editor. The finalise call runs the same update path as an ordinary save, so three rewrites happen on both, and the finalise is usually the last save. Every line’s transaction date is overwritten from the header, so a line can never carry a date of its own. A unit price you did not send is back-computed from the line total and the quantity, to two decimals, rounding up. And a line that names a pricing scheme link has that link’s whole price set recopied onto it. Those are the next lesson but one.
Reference: Sales Invoice (Internal) — Lifecycle and effects
Step 6 — Accept that the call returns before the work is done
After this step you will have the right mental model for everything that follows. Finalise does not wait for the journal, the stock movement, the costing, the e-invoice row or the loyalty points. It enqueues them and returns, which is why a busy counter is not slowed by a slow posting. The cost of that design is the whole subject of this series: for a few seconds, and occasionally much longer, a document is FINAL and has posted nothing. Pressing Finalise a second time is refused outright with Generic Document has already been posted to FINAL, so you cannot make it try again that way.
Reference: Which figures BigLedger stores, and which it works out fresh
Check yourself
Three to five questions on what you just heard. Every correct answer links to the page that makes it correct, so you can check the source, not just the mark.
Answer key
- Behind a separate finalise endpoint, which queues the work and returns — How Work Actually Runs — Trace it once: what one Finalise actually starts
- That check runs only when the request asks for it, and the two screens ask differently — Sales Invoice (Internal) — Lifecycle and effects
- The finalised date, possibly a rewritten transaction date, the e-invoice skip flag and the running numbers — Sales Invoice (Internal) — Lifecycle and effects
- The request is refused, because the document is already FINAL — Sales Invoice (Internal) — Lifecycle and effects
Next: One press, and a fan-out you did not configure · Back to the series · Play this as a presentation