Who writes the contra, and when the balance moves — transcript
Play this as a presentation — one slide per step, with the same narration. Every word of every step is on this page.
This presentation is for whoever at GadgetSphere keys receipts and payments, and for whoever is asked afterwards why a receipt that was finalised with the invoice ticked has left the invoice open. In about twelve minutes you will learn who writes the settlement pair and at what moment, what it writes, why there is no recalculation queue to wait for, what a failed write leaves behind, and why a contra keyed on a draft is already live.
Step 1 — Know that the contra is not a Finalise job
After this step you will stop looking for the contra in the Posting tab. Finalise starts one primary job that fans out to the subscribers your tenant holds: the cash book line and the journal for a receipt voucher are two of them. The contra is not one of them, and no subscriber of the Finalise primary creates one. What happens instead is this. You tick the invoices on the Contra tab and press FINAL. The applet sends the finalise call, waits for it to come back, and then sends a second request of its own, carrying the rows you ticked. That second request writes the settlement. So the contra is on the invoice before the journal exists, and it is written by the browser you are sitting at, not by the background chain. Everything else in this presentation follows from that one fact, including the one way it goes wrong.
Reference: Receipt Voucher (Internal) — Lifecycle and posting
Step 2 — Know what the second request writes
After this step you will know what a contra row is made of. The applet takes every row on the Contra tab that has no status yet, stamps it active, and posts the list to the bulk contra endpoint, which needs the contra update permission on your login. For each row the backend writes the mirrored pair: one row on the invoice, one on the receipt with the amount negated and the documents swapped. The amount is rounded to two decimals first, and a row that rounds to zero is dropped silently. A contra dated earlier than either document is moved to the later document’s date before it is written. A back-dated contra rebuilds the aging months it touches. A cross-currency pair posts an exchange-difference journal, the only journal a contra ever creates. And nothing on the server checks the amount against the open balance: the cap is the greyed-out Add button in the browser.
Reference: Debtor Report Applet — Lifecycle and effects
Step 3 — Know the exact moment both balances move, and that no queue is involved
After this step you will stop waiting. Inside that second request, after the pairs are inserted, the backend re-sums each affected document’s Contra figure from its rows and rewrites Contra and Balance together, on the invoice and on the receipt, before the response comes back to your screen. There is no queue and no delay, which is why a knock-off normally shows the instant you save. The support corpus has a phrase for the opposite belief, async recalculation stuck, and it is worth knowing why it is wrong. A queue table for exactly this recomputation does exist, with a registered processor and a sweeper that polls it, and nothing has ever written a row to it: every live tenant has the table and every one of them has it empty. So the balance moved inside the request, or the request failed. There is no third state to wait out, and no overnight job that will catch up.
Reference: I knocked it off and the outstanding balance hasn’t changed — When it is a support matter
Step 4 — Know what a failed second request leaves behind
After this step you will recognise the commonest shape. Because the contra travels in its own request, it fails on its own: the login lacks the contra permission, the session expired between the two calls, the network dropped, the tab was closed the moment FINAL came back. The applet shows a red toast, Documents contra unsuccessfully, and does not retry. What is left is a receipt that is FINAL, has its cash book line and its journal, and has no contra. The customer’s total on the Statement of Account is right, the invoice is still open, and the receipt sits on the statement as an unapplied credit. Across the estate, finalised receipts carrying a balance and no contra number in the thousands on about a quarter of tenants; most are deliberate payments on account, and a failed request leaves exactly the same shape. The fix is the receipt’s Contra tab: if it is empty, apply it there.
Step 5 — Know that a contra keyed on a draft is already live
After this step you will not leave a draft with contras on it overnight. The same second request fires after an ordinary save, not only after FINAL. Key two invoices on the Contra tab of a draft receipt at GS-PEN-01, press Save, and the pairs are written and both balances re-summed at once; the validator on the server checks that both documents exist and the amount is filled, and nothing about the receipt’s posting status. So the invoices read as paid, on the Outstanding Document Report and the ageing, by a receipt that has not been finalised. Leave that draft for a week and a collections call goes out on an invoice the report says is settled. This is the design: the contra is a link between documents, independent of either one’s lifecycle. It is also why a receipt pulled back to Draft keeps its contras, which is the third presentation.
Reference: Receipt Voucher (Internal) — Lifecycle and posting
Step 6 — Know the two paths and which one you are on
After this step you will know whether a half-written settlement is even possible from your screen. The backend has two ways of creating a settlement, differing in one way you can feel. The settle-several path treats a failed balance refresh as a failure of the whole operation: it stops, nothing is written, and you get an error. The settle-single path logs the failure and carries on: the rows are committed and the header keeps the balance it had. Which path you are on is decided by the screen, not by how many invoices you ticked. Every Contra tab in the voucher and report applets sends the settle-several path. The settle-single path is behind no button; it is what the receipt file import, the JSON document import, the payment-gateway callback and a background job call. So a settlement a person keyed either lands whole or fails loudly, and the quiet half-write belongs to integrations and imports.
Reference: I knocked it off and the outstanding balance hasn’t changed — When it is a support matter
How the steps fit together
flowchart TD
s1["Step 1 — Know that the contra is not a Finalise job"]
s2["Step 2 — Know what the second request writes"]
s3["Step 3 — Know the exact moment both balances move, and that no queue is involved"]
s4["Step 4 — Know what a failed second request leaves behind"]
s5["Step 5 — Know that a contra keyed on a draft is already live"]
s6["Step 6 — Know the two paths and which one you are on"]
s1 --> s2
s2 --> s3
s3 --> s4
s4 --> s5
s5 --> s6
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
- The receipt's Contra tab; if it is empty, the second request never got through and you apply the contra there — Receipt Voucher (Internal) — Lifecycle and posting
- Inside the applet's second request, before the journal exists — I knocked it off and the outstanding balance hasn't changed — Contra is a mirrored pair, not an entry
- Nothing; no code has ever written a row to it, and the re-sum happens inside the request or not at all — I knocked it off and the outstanding balance hasn't changed — When it is a support matter
- Paid; the contra is live as soon as the draft is saved — Receipt Voucher (Internal) — Lifecycle and posting
Next: What un-does a knock-off, and what each route leaves behind · Back to the series · Play this as a presentation