The repository contains a read-only ThreeWayMatchService that compares a purchase order line by line. It is covered by integration tests, but the audited first-party metadata and web application expose no standard screen, report or entity action that calls it. There is therefore no product screenshot or end-user procedure to show. Before users can run this review, a deployment must expose the service through a tested API, report or custom action and decide where its result belongs in the payment process.
How the comparison works
For each purchase-order line, the service calculates:
| Result | Calculation |
|---|---|
| Ordered | Purchase-order line Quantity. |
| Received | Sum of ReceivedQuantity on linked goods-receipt lines. |
| Billed | Sum of Quantity on linked bill lines. |
| Receipt variance | Received minus ordered. |
| Bill variance | Billed minus received. |
| Ordered / billed amount | Purchase-order line amount and the sum of linked bill-line amounts. |
Both totals and variances are rounded to four decimal places using midpoint-away-from-zero. A line is Matched only when both quantity variances are zero. Otherwise status is OverReceived or UnderReceived, plus OverBilled or UnderBilled when applicable; two flags are joined with +. The amounts are returned for review, but the service does not calculate a separate amount-variance status.
Link contract
- A receipt contributes only when its line has
PurchaseOrderLineIdset to the order line. - A bill contributes only when its line has
PurchaseOrderLineIdset to the order line. - Soft-deleted purchase-order, receipt and bill lines are excluded.
- A header-level Purchase Order or Goods Receipt link is not enough; the service queries line foreign keys.
Important release-path limitation
The current Goods Receipt → Release Bill service creates each bill line with GoodsReceiptLineId but does not copy PurchaseOrderLineId. Such a bill is therefore absent from the current three-way billed totals even when the receipt itself came from a purchase order.
The Purchase Order → Perform/Selective Release Invoice service behaves differently: when eligible receipt lines exist, it creates bill lines with both PurchaseOrderLineId and GoodsReceiptLineId; without receipts it still creates the purchase-order-line link. If a customization exposes the current match service, use and test this order-side release path when both links are required, or fix the receipt-side mapping before relying on its result.
What an exposed consumer should show
A safe custom consumer should show the purchase-order line, ordered/received/billed quantities, ordered/billed amounts, both variances and status, with links back to every contributing receipt and bill line. It should also disclose bills linked only to a receipt so omission is visible. The service itself performs no save, posting, approval or payment block.
Common problems
- A bill is absent from an integration's result. Inspect
PurchaseOrderLineIdon its lines. Direct bills and current receipt-side released bills can lack it. - Everything is UnderReceived on a fresh order. The service sums actual
ReceivedQuantity, not quantity merely staged on a goods-receipt line. - A line looks correct but is not Matched. Inspect all non-deleted linked receipt and bill lines; the service sums all of them and rounds the totals to four decimals.
Common questions
Does the service block posting or payment?
No. It is a read-only query service. A custom payment control would need to call it explicitly and define tested tolerance and override rules.
Which numbers exactly are compared?
Per order line: ordered quantity and amount from the purchase-order line; received quantity from linked goods-receipt lines; billed quantity and amount from linked bill lines. The two status variances are quantity-based.
