Freeze three source views before asking for alignment
Export or open the authoritative purchase order, goods-receipt record, and supplier invoice at a stated time. Capture stable document and line identifiers, currency, unit of measure, quantities, unit prices, tax basis, revision, receipt or return state, and document status. Do not paste bank details or unnecessary supplier personal data.
Our fictional case deliberately omits the tolerance policy, tax decision, previous invoice history, credit notes, and later receipts. Those omissions are part of the result, not inconveniences for the model to resolve.
Purchase order PO-4821
| Line | Item | Ordered quantity | PO unit price | Extended amount |
|---|---|---|---|---|
| 1 | Filter cartridge FC-20 | 10 | $12.00 | $120.00 |
| 2 | Sensor bracket SB-4 | 5 | $30.00 | $150.00 |
| 3 | Cable kit CK-9 | 4 | $8.50 | $34.00 |
Receipt GR-778 and invoice INV-9017
| Line | Received on 2026-09-01 | Invoiced quantity | Invoice unit price | Invoice amount |
|---|---|---|---|---|
| 1 | 8 | 10 | $12.00 | $120.00 |
| 2 | 5 | 5 | $32.00 | $160.00 |
| 3 | 4 | 4 | $8.50 | $34.00 |
The invoice subtotal is $314.00 before tax. That total does not show which $34.00 is unsupported. The match must be performed at line level.
Specify the arithmetic explicitly
For this fixture, the supported quantity is limited by the supplied receipt. We compute each result without applying a tolerance:
quantity_variance_units = invoiced_qty - received_qtyprice_variance_each = invoice_unit_price - po_unit_pricesupported_amount_at_po_price = received_qty × po_unit_price- Quantity and price exceptions remain separate; they are never netted.
Line-match output contract
Match only the provided fictional PO, receipt, and invoice.
Return one object per PO line with source_ids.
Compute quantity and unit-price variances independently.
Do not net exceptions or invent a tolerance.
Set tolerance_policy to null.
Set overall_state to HOLD_FOR_REVIEW.
Do not approve, post, pay, contact the supplier, or alter a record.
The complete reconciliation result
| Line | Quantity result | Price result | Supported at PO price | Exception |
|---|---|---|---|---|
| 1 | 10 invoiced minus 8 received = 2 units | $12.00 matches $12.00 | 8 × $12.00 = $96.00 | $24.00 invoiced quantity unsupported by supplied receipt |
| 2 | 5 invoiced and 5 received | $32.00 minus $30.00 = $2.00 each | 5 × $30.00 = $150.00 | $10.00 price exception across five units |
| 3 | 4 invoiced and 4 received | $8.50 matches $8.50 | 4 × $8.50 = $34.00 | None in supplied fields |
| Review state | Raw quantity checks complete | Raw price checks complete | HOLD_FOR_REVIEW | Tolerance policy is null |
Line 1 and line 2 fail for different reasons. A later valid receipt could change the line 1 comparison. An authorized PO amendment could change line 2. Neither possibility appears in this source packet, so neither can be assumed.

Independent checks on the retained output
The Python gate recomputed the $24.00 quantity exception and $10.00 price exception, confirmed that the matching line had no exception, required the tolerance field to remain null, and required the invoice state to stay on hold. It accepted the retained response.
Three single-field corruptions were then tested:
| Mutation | Source conflict | Outcome |
|---|---|---|
State changed to APPROVED_FOR_PAYMENT | No approval authority or completed review exists | Rejected: payment approval invented |
| A quantity and price tolerance object inserted | No tolerance policy was supplied | Rejected: tolerance policy invented |
| Line 1 quantity variance changed from 2 to 0 | Receipt shows only eight units | Rejected: quantity variance wrong |
The exact input, retained JSON, executable checks, mutation record, and hashes are included in the three-way match practice bundle. It runs with Python's standard library and performs no ERP connection. Reconcile the readable tables with the JSON as well as running the automated gate.
Apply tolerance only from the controlling configuration
A tolerance is a policy input, not a number for the model to choose. Oracle's invoice-tolerance documentation shows that configured quantity and amount tolerances can determine holds and payment availability. Another system may use different fields, authority, or behavior. Retrieve the current policy by supplier, item, business unit, and match type where relevant; record its version and source.
Compute the raw variance first. Then apply the verified tolerance as a deterministic second operation. This preserves both the economic difference and the policy decision. Never rewrite an actual variance as zero just because it falls within a permitted threshold.
Branches that the fixture did not test
Do not generalize one three-line example to every payables case. Add separate test records before using the pattern for these conditions:
| Condition | Required additional evidence | Failure to prevent |
|---|---|---|
| Multiple or partial receipts | All receipt IDs, reversals, dates, and open quantity | Comparing against only the latest receipt |
| Returns or rejected goods | Return transaction and inspection state | Counting returned units as accepted |
| Different units of measure | Authorized conversion and precision rule | Comparing cases with eaches directly |
| Foreign currency | PO and invoice currencies, rate source, rate date, rounding | Creating an exchange rate or hiding FX variance |
| Freight, tax, or additional charges | Contract, tax, and charge-line treatment | Folding non-item costs into unit-price variance |
| Duplicate or split invoice | Prior invoice history and credit notes | Calling a unique document number sufficient proof |
| Authorized PO change | Approved revision and effective sequence | Using a draft change to clear an exception |
| Four-way match | Inspection or acceptance record | Treating receipt as acceptance |
Reviewer sequence
- Confirm document identity. Check supplier, business unit, currency, PO revision, receipt status, invoice number, and line keys.
- Align items and units. Resolve unit conversions only from authorized master data.
- Compute raw line variances. Preserve signs, precision, and source values.
- Investigate receipt exceptions. Search for later receipts, reversals, returns, and acceptance evidence.
- Investigate price exceptions. Check the approved PO revision, contract, freight, and charge treatment.
- Check duplicates, tax, and credits. Use the source system and specialized rules.
- Apply the current tolerance policy. Record rule version and authority without erasing the raw variance.
- Leave the payment decision to the designated approver. Preserve the hold until every required control is satisfied.
Related controls
Use the vendor onboarding register before production access and supplier activation. Link commercial due rules to the contract obligation tracker. For small expense records without a PO, the verified receipt-to-expense workflow solves a different reconciliation problem. Time-based services belong in the time-log invoice review.
Decision boundary
The comparison is ready for an authorized reviewer when document identity is confirmed, every line is traceable, arithmetic is independently reproducible, raw exceptions remain visible, and all omitted policies or records are listed. It is not payment approval. The invoice leaves hold only through the organization's configured controls and named authority.
