The margin report and the profit and loss don't agree
“The margin report and the profit and loss don’t agree” — that is ordinary: the cost stored on a finalised sales line is rewritten whenever a back-dated purchase lands, while no sales document posts a cost-of-sales journal at all, so the ledger follows on a different timetable and only when month-end is re-run for the affected months.
Your gross profit report says something different from the profit and loss. Or worse: it says something different from what it said last week, for a quarter that closed months ago.
Both are the same cause seen from two angles. This is the subtlest of the platform’s stored figures and the one with the longest reach.
The 30-second check
1. Did anything back-dated land for those items? A purchase invoice or goods receipt dated into a period that had already been reported is the trigger in nearly every case. If one did, your margin report is right and it has just been corrected.
2. Has month-end been re-run for the affected months? If not, the ledger cannot have followed — see below. That is the gap you are looking at.
3. Compare like with like. The cost on a sales line is what that sale cost you. The item’s current cost is a different number and moves with every receipt you take in. A report showing one against the other will never tally, and neither is wrong.
What actually happened
When you finalise a document that moves stock, the chain posts the stock movement first, then works out what that stock cost, then writes the cost back onto the document line. Moving average and FIFO both land there, side by side, so a report can read a column instead of replaying a history.
Here is the part nobody expects: the cost stored on a finalised document line is not final.
Post a purchase invoice dated back into a month you have closed, and a replay walks forward through every later movement of that item and rewrites the stored cost on each one’s document line — with no filter for posting status and none for a locked period. Two queues keep that affordable. One replays the moving-average chain forward from the back-dated line. It is a queue, not part of your save, so the rewrite is not instant — expect a margin report to keep moving for a while after you post the back-dated document, and do not read the two minutes after the post as the final answer. The other is a FIFO dirty list keyed on company and item, keeping only the earliest dirty point, so an item edited fifty times is replayed once rather than fifty times. That FIFO replay does not run by itself, though: it is a repair somebody starts, and no schedule starts it for you. If your company reports on FIFO, the moving-average cost on the line catches up on its own and the FIFO cost waits until the rebuild is run. Your system administrator asks BigLedger support to run it.
So last quarter’s gross margin genuinely can move after the fact, and correctly so — you have just learned what that stock really cost.
Why the ledger does not follow
What does not move is the general ledger. No journal is reposted by either replay path. In fact no sales document posts a cost-of-sales journal at all.
Cost of sales is a month-end computation: opening stock, plus purchases, plus purchase returns, minus closing stock. The closing stock is valued from whichever cost column your company’s Inventory Closing Base On setting names, defaulting to moving average.
Follow that through and you have the sequence that produces the question:
- A back-dated purchase lands.
- The stored cost on last quarter’s sales lines is rewritten by the replay. Your sales and margin reports, which read those columns, change.
- The general ledger does not move, because no journal was posted.
- The two come back together only when somebody re-runs month-end for the affected months — which deletes the old cost-of-sales journal and posts a new one.
“The margin report and the P&L don’t agree” is, nine times in ten, exactly this, with step 4 not yet done.
What to do about it
- Find the back-dated document. List purchases for the affected items by the date they were created rather than the date they are dated.
- Re-run Month End Processing for the earliest affected month, then every month after it, in order. That is what reposts cost of sales. If your Inventory Closing Base On is FIFO, have the FIFO rebuild run first, or month-end values closing stock from FIFO costs that have not caught up.
- Then regenerate any Financial Report snapshot covering those months, or the statements will keep showing the old figures.
- Read both reports again. If they now agree, the rebuild was the missing step — and it is part of the correction, not an optional extra.
The other cause: purchases on their own GL code
Month-end counts purchases only on the company’s default Purchase and Purchase Return codes. That is a setup rule — one purchases account per company — so a purchase posted to an item’s or a line’s own GL code is not counted in cost of sales, and re-running month-end does not change that. What the P&L then shows depends on how that account is classified. If its GL category is Purchases (or Purchases Returns), the P&L leaves it out as it leaves out the default, and cost of sales comes out short. Under any other category in a cost-of-goods-sold section, the P&L shows it as a raw purchase. Either way the P&L can disagree with the margin report. Post all purchases to the default Purchase code.
When it is a support matter
The margin report and the ledger still disagree after month-end has been re-run for every affected month, in order. At that point it is no longer a timing difference. Report it with the item, the months, and the two figures.
A negative unit cost on an inventory or costing report is something else, and it is not a data error. Moving-average unit cost is the balance’s total value divided by its quantity. Let a negative adjustment take an item’s quantity below zero and that division can come out negative — an arithmetical artefact of costing stock you did not have, not a loss and not corruption. The transaction chain underneath is intact. Treat a negative unit cost as a flag that the item went short, and fix the quantity.
What this page cannot tell you
- When the cost on a given line was last rewritten. The line carries the cost, not the history of the cost.
- How long a replay takes. It is queued and finishes when it finishes.
- Which cost column your reports read. That depends on your company’s Inventory Closing Base On setting and on the report.
Related documentation
- Costing internals — the moving-average formula as coded, the FIFO register, why FIFO is a rebuilt figure rather than a live one, and that no document posts cost of goods sold.
- Financial Report applet — Month End Processing, which is the only thing that posts the cost-of-sales journal.
- Which figures BigLedger stores, and which it works out fresh — the same trade-off in the other four places it appears.