Why a purchase order and its invoice never meet in your books
A distributor sends us a purchase order and the invoice raised against it. Same
customer, same part, same quantity. The order says 30208, quantity 6. The
invoice says 30208, quantity 6.
The system reports the order as not dispatched.
Nothing is wrong with either document. The failure is in what sits between them, and it is the single most common reason an order book stops agreeing with the books.
Dispatch is a join, and the join has no key
To say an order has been fulfilled, software has to decide that this invoice line corresponds to that order line. Almost every system does this by joining on a catalogue identifier — an internal item code that both documents resolve to.
That works right up until a part has no catalogue entry. Then neither document resolves to anything, the join finds no match, and the order sits open. The part is not missing from the documents. It is missing from the catalogue, which is a different problem with the same symptom.
The distributor above had 2,862 such parts. Every order containing one of them was stuck, and nobody could see why, because the order looked complete on screen.
Four ways the same part gets written
Even when a catalogue entry exists, the text rarely matches. A single bearing might appear as:
6205-2RS1/C3— how the manufacturer prints it6205 2RSLTN9/C3VT162— the full designation, with the grease specification6205-2Z C3 BRG— how a buyer's purchase clerk types it6205 2RS— how it ends up in the accounts package
An exact-match lookup finds none of these from any of the others. A fuzzy match
finds all of them, plus 6205-2RS1/C4, which is a different bearing with a
different internal clearance. That is the trap: the tolerant matcher is the one
that quietly writes the wrong part to your ledger.
What works is a ladder — exact, then normalised, then token-wise, then squashed — stopping at the first rung that produces exactly one candidate. A line that produces two candidates is not a match. It is a question for a person.
The purchase order number is not a key either
Invoices reference the customer's PO number. Your order is filed under yours.
Invoice:
PO 1723Order:PO/1723/PVCC/26-27
String equality fails. So does a naive substring test, because 1723 also
matches PO/17230/.... The reference has to be parsed into parts — a numeric
core, a party token, a financial year — and compared component-wise, with the
year used to disambiguate rather than as decoration.
GSTIN validation that stops at fifteen characters
A GSTIN is fifteen characters, and most systems check exactly that. Consider:
24AACCR8735L1ZO
Fifteen characters. Correct shape: two digits of state code, ten of PAN, an
entity number, a Z, and a check character. It passes every format test and it
cannot exist — the final position is a letter O where the checksum requires a
zero. An OCR pass read a zero as a letter, and the order is now filed against a
company that does not exist.
The check digit is a mod-36 computation over the preceding fourteen characters. Validating it costs nothing and catches precisely this class of error, which is the most common single-character misread in scanned documents.
What to look for
If you are evaluating anything that promises order-to-invoice reconciliation, three questions separate the systems that work from the ones that produce confident nonsense:
- What happens to a line it cannot identify? The right answer is that it goes on a worklist for a person. Any system that picks the nearest neighbour is writing guesses into your ledger.
- Does it validate the GSTIN check digit, or only the length?
- Can it show you the evidence for a match? A reconciliation you cannot audit is a reconciliation you cannot defend when a customer disputes it.
The parts nobody has added to the catalogue yet are usually holding more money than anything else on the list. Sorting that list by value blocked, rather than alphabetically, is often the fastest week of work a distributor can do.