The purchase order price source determines what an invoice match verifies.
CodeCore Dynamics LLC. 28 August 2026.
Summary
- F&O matching compares an invoice to its own purchase order. The control is therefore not stronger than its source.
- A price from a trade agreement was fixed before the transaction and applies across all of them. Where a buyer typed the price onto the PO, matching checks the vendor against their own quote. Both produce the same match status.
- Two years of US airline filings show fuel pricing within 4 per cent of its own agreed rate, while airframe repair spans 32 per cent. Fuel can be driven from master data. Repair cannot.
- The same charge measured against a different benchmark can flip the verdict. Fuel varies by 16 per cent against the industry and 4 per cent against its own indexed rate, either side of the 15 per cent line for automating.
- The legal entity price tolerance defaults to 0 per cent, and that default record cannot be deleted.
- Charges matching requires both Match charges at legal entity level and Compare purchase order and invoice values on the individual charges code.
- At a 10 per cent tolerance a repair charge sends roughly a third of its invoices for manual review, against one in ten for fuel.
For finance leadership
The current position can be established without opening the system. Ask what the legal entity price tolerance is set to. If it remains at 0 per cent, every price variance is being flagged. Ask which charges codes have Compare purchase order and invoice values selected. The codes without it post unchecked and raise no error. And finally, ask what share of purchase order lines take their price from a trade agreement rather than from manual entry. That share is the exposure this article describes.
The running cost is in Section 4.4. At a 10 per cent tolerance, repair flags 31 per cent of its invoices against 10 per cent for fuel. This reflects three times the review time, and the reviewer has no agreed price to compare against.
Where no rate exists, a price tolerance creates review load and checks nothing. Quantity matching does not depend on a rate and should stay on.
Terms
Dynamics 365 F&O
| Term | Meaning |
|---|---|
| Purchase order (PO) | The order raised before the goods or services arrive, carrying an agreed price, quantity and any charges |
| Product receipt | The record of what was received |
| Net unit price | The net amount of a line divided by its quantity |
| Two-way matching | Compares the net unit price on the invoice line to the net unit price on the PO line |
| Three-way matching | Two-way matching plus invoice quantity against the quantity on the matched product receipt |
| Line matching policy | Which of the above applies. Set for the legal entity and overridable by vendor, item, or item and vendor |
| Price tolerance | The variance allowed before a discrepancy is reported |
| Invoice totals matching | Compares totals on the invoice to the totals expected from the PO |
| Trade agreement | Stored agreed prices per vendor and item, used to populate the PO price |
| Purchase agreement | A commitment to buy an agreed volume or value, carrying agreed pricing |
| Charges code | A named cost added to an order or invoice, such as freight, handling or a landing fee |
| Charges matching | Compares charge amounts on the invoice to charge amounts on the PO |
| Legal entity | The company the configuration belongs to |
| Rung | Used in this article for where a PO price came from, per Table 1. Not a Microsoft term. |
Aviation
| Term | Meaning |
|---|---|
| Flight hour | Time the aircraft is airborne. The driver for maintenance and crew cost |
| Capacity purchase agreement | A mainline carrier pays a regional to operate routes on its behalf, commonly supplying the fuel |
| ACMI | A lease where the operator supplies aircraft, crew, maintenance and insurance, and the customer covers fuel |
| 14 CFR Part 241 | The US regulation requiring carriers to file the financial schedules used here |
1. Introduction
Two-way matching in Dynamics 365 F&O compares the net unit price on the invoice line to the net unit price on the purchase order line. Three-way matching additionally compares the invoice quantity to the quantity on the matched product receipt.
Both comparisons take the purchase order as the reference. That reference came from somewhere, and where it came from determines what a passed match establishes. F&O does not distinguish between those sources anywhere in the interface.
| Rung | Source of the PO price | Passed match means |
|---|---|---|
| 1 | Trade agreement or purchase agreement | The vendor billed a price set outside the transaction |
| 2 | A quote entered onto the PO by a buyer | The vendor billed the amount they quoted |
| 3 | A line added at invoice entry, with no PO line | Line matching does not apply |
Table 1. The same match status is produced at every rung.
Rung 2 confirms the vendor has not deviated from their own quote. It carries no information about whether the quote was reasonable.
Reaching rung 1 requires a rate stable enough to hold in master data. Sections 2 to 4 test which charges have one using public airline financial filings. Section 5 sets out what follows for the F&O configuration.
2. Dataset and cleaning
2.1 Source
BTS Form 41 Schedule P-5.2, quarterly aircraft operating expenses, 2024 and 2025. The dataset contains 4,805 rows across 47 carriers, 95 aircraft types and 8 quarters. Each row conforms to a matched carrier, aircraft type, and quarter.
Airlines are one of the few industries where third-party spend and the quantity driving it are both public. US carriers file both under 14 CFR Part 241. The same analysis is not possible from public data at a manufacturer.
The code, the filings and the raw output are in a public repository, linked below.
2.2 Charges selected
| Charge | Amount field | Account | Driver field |
|---|---|---|---|
| Aircraft fuel | FUEL_FLY_OPS |
51451 | AIR_FUELS_ISSUED |
| Engine repair | ENGINE_REPAIRS |
52432 | TOTAL_AIR_HOURS |
| Airframe repair | AIRFRAME_REPAIR |
52431 | TOTAL_AIR_HOURS |
| Pilot pay | PILOT_FLY_OPS |
51230 | TOTAL_AIR_HOURS |
Table 2. The first three are third-party spend arriving as vendor invoices. Pilot pay is account 51230 (salaries), not meeting invoice matching. It is carried through the figures as a rate that is contracted but not invoiced.
2.3 Units
Amounts are reported in thousands of dollars and quantities in thousands. Therefore, amount divided by driver yields dollars per gallon and dollars per flight hour.
Two independent checks:
The fuel rate resolves to $2.43 per gallon. US Gulf Coast kerosene-type jet fuel spot averaged $2.23 over the same 24 months. The filed figure therefore sits about 9 per cent above the spot benchmark. This is the correct direction and a plausible magnitude where account 51451 is delivered cost, carrying the supplier differential, the into-plane fee and taxes on top of spot. In contrast, a figure below spot, or one several times it, would indicate a units error.
Pilot pay resolves to $1,498 per flight hour, which falls in the published range for narrowbody crew cost per block hour. The two checks are independent of each other.
2.4 Filters applied
Rows below $100,000 of quarterly spend are excluded, since rounding in the filing dominates the implied rate at that scale. A carrier and aircraft type requires at least four quarters on file before it is treated as having an established rate of its own. After filtering, fuel retains 2,175 rows across 143 carrier and aircraft combinations.
2.5 A mixed population in the fuel data
132 fuel rows, 6.1 per cent of the file, imply a rate below $1.00 per gallon. These are regional carriers operating capacity purchase agreements and ACMI cargo operators, which burn fuel a partner pays for, so gallons are reported against little or no cost. The carriers concerned are SkyWest, Republic, Atlas Air and ABX Air. This is a commercial arrangement, not a reporting error. The rows are retained.
The effect on each measure differs, as the table below shows.
| Fuel | n | Median rate | Pooled R² | Within band | Variance |
|---|---|---|---|---|---|
| As published | 2,175 | $2.43 | 0.922 | 0.689 | 0.039 |
| Excluding under $1.00/gal | 2,043 | $2.45 | 0.986 | 0.862 | 0.036 |
Table 3. R² shifts substantially, whereas the median rate and variance remain largely unchanged.
A measure built on medians tolerates a mixed population. One built on squared deviations does not. In accounts payable, applying a single tolerance at vendor group level may fail when one charge code covers multiple pricing structures.
3. Analysis
Two measures are computed for each charge.
Measurement
| Term | Meaning |
|---|---|
| Driver | The quantity determining the amount. Gallons for fuel, flight hours for repair |
| Unit rate | Amount divided by driver. Dollars per gallon, dollars per flight hour |
| Benchmark | The reference a unit rate is compared against. Check 3.2 for defined benchmarks |
| R² | The share of variation in the amount explained by the driver, from 0 to 1 |
| Median | The middle observation of data |
| Interquartile range (IQR) | The span covering the 25th to the 75th per centile |
| Variance | IQR divided by the median. A value of 0.04 means the middle half sit within 4 per cent of the benchmark. In this article, this is a measure of dispersion. |
The measurement terms used from here on.
3.1 Drivers
An ordinary least squares fit of amount = a + b × driver, reported as R².
Pooled R² is inflated in this dataset because carrier size correlates with both variables independently of any pricing discipline. The fit is therefore repeated within driver size quartiles and averaged, which removes most of that effect.
3.2 Unit Rate
The amount divided by the quantity gives the unit rate. A variance value of 0.04 indicates that the middle half of observations price within 4 per cent of their benchmark.
A charge is treated here as worth automating where that variance falls below 0.15. The threshold is a judgement and not a derived value, and is named again in Limits. Variance is reported as a decimal in the tables that follow.
The benchmarks chosen for this model:
- Industry. A single rate across all carriers.
- Indexed. The median rate within the same quarter, removing market movement.
- Own rate. The carrier's own median, without market movement.
In purchase agreement terms, these correspond to no agreement, an index-linked agreement, and a vendor-specific trade agreement.
4. Results
4.1 Driver explanatory power
| Charge | Pooled R² | Within size band |
|---|---|---|
| Aircraft fuel | 0.92 | 0.69 |
| Engine repair | 0.51 | 0.13 |
| Airframe repair | 0.43 | 0.11 |
Table 4. Gallons account for most of the variation in fuel spend. Flight hours account for little of the variation in repair spend.
Figure 1. The fuel relationship is close to linear. The repair relationship is dispersed.
4.2 Rate variance
| Charge | Unit rate | Variance against own rate |
|---|---|---|
| Aircraft fuel | $2.43 / gallon | 0.04 |
| Engine repair | $334 / flight hour | 0.23 |
| Airframe repair | $285 / flight hour | 0.32 |
Table 5. An eightfold difference between fuel and airframe repair, on identical carriers, aircraft and quarters.
Figure 2. Each invoice divided by its own benchmark. The variance in Table 5 is the width of these distributions expressed as one number.
4.3 Effect of benchmark choice
| Charge | vs industry | vs same quarter | vs own rate |
|---|---|---|---|
| Aircraft fuel | 0.16 | 0.08 | 0.04 |
| Engine repair | 1.20 | 1.14 | 0.23 |
| Airframe repair | 1.27 | 1.20 | 0.32 |
Table 6. Read across rows.
Figure 3. Fuel variance falls below the 0.15 threshold only once the benchmark accounts for the quarter.
Indexing reduces fuel variance from 0.16 to 0.08, and vendor-specific pricing reduces it again to 0.04. Indexing therefore accounts for half of the total improvement. For repair, all three benchmarks remain wide.
4.4 Review load
A tolerance flags every line whose deviation from its benchmark exceeds it, so the share flagged is the workload the control creates. That share differs by charge as sharply as the variance.
| Charge | 5% | 10% | 15% | 25% |
|---|---|---|---|---|
| Aircraft fuel | 13% | 10% | 9% | 6% |
| Engine repair | 31% | 26% | 23% | 18% |
| Airframe repair | 38% | 31% | 26% | 17% |
Table 7. Share of invoices sent for manual review at each price tolerance, measured against the benchmark that holds each charge tightest.
Figure 4. At every tolerance, the repair charges flag two to three times as many invoices as fuel.
At a 10 per cent tolerance fuel sends one invoice in ten for review, whereas airframe repair sends close to one in three. Section 4.2 shows there is no stable rate for that review to check against.
5. Discussion
5.1 The path an amount takes
flowchart TD
TA["Trade agreement or<br/>purchase agreement"]
QUOTE["Buyer enters a quote<br/>onto the PO"]
ADDED["Line added at invoice entry,<br/>not on the PO"]
PO["Purchase order line<br/>price, quantity, charges"]
RCPT["Product receipt"]
INV["Vendor invoice"]
LMP{"Line matching policy"}
PRICE["Price check<br/>net unit price, price totals"]
QTY["Quantity check<br/>vs received quantity"]
NOLINE["No line matching"]
MCH{"Match charges<br/>legal entity"}
CTOG{"Charges code:<br/>Compare PO and invoice values"}
CCHK["Charges check<br/>vs Charges tolerances"]
CGAP["Charge not matched"]
TTOG{"Match invoice totals<br/>legal entity"}
TCHK["Invoice totals check"]
TGAP["Line not matched"]
LEDGER["Posted to the ledger"]
TA -->|rung 1| PO
QUOTE -->|rung 2| PO
PO --> LMP
RCPT --> LMP
INV --> LMP
LMP -->|two-way or three-way| PRICE
LMP -->|three-way only| QTY
LMP -->|not required| NOLINE
PO --> MCH
MCH -->|on| CTOG
MCH -->|off| CGAP
CTOG -->|selected| CCHK
CTOG -->|not selected| CGAP
ADDED -->|rung 3| TTOG
TTOG -->|on| TCHK
TTOG -->|off| TGAP
PRICE --> LEDGER
QTY --> LEDGER
NOLINE --> LEDGER
CCHK --> LEDGER
CGAP --> LEDGER
TCHK --> LEDGER
TGAP --> LEDGER
classDef strong fill:#dcecdc,stroke:#3a7d3a,color:#0b0b0b
classDef weak fill:#fbe8cd,stroke:#b8761c,color:#0b0b0b
classDef gap fill:#f6d8d4,stroke:#b0443a,color:#0b0b0b
classDef check fill:#e8eef6,stroke:#2a78d6,color:#0b0b0b
class TA strong
class QUOTE,ADDED weak
class NOLINE,CGAP,TGAP gap
class PRICE,CCHK,TCHK check
class QTY strong
Figure 5. Colour represents the strength of the reference behind each check, blue marking the checks and red the paths where no check happens.
Charges codes appear on the purchase order, and charges matching compares the invoice charge to the PO charge. A line added at invoice entry that was not on the purchase order, falls outside line matching and is covered by invoice totals matching only.
Observations from the diagram:
Price check strength derives from the source. The comparison is identical whether the PO price originates from a trade agreement or from manual buyer entry, producing the same match status in both cases.
Quantity check strength derives from the product receipt.Invoiced quantity and received quantity are both recorded values rather than judgements, so the check needs no rate, no tolerance and no master data. It runs under a three-way policy only.
Three branches reach the ledger without a line-level comparison: a PO line under a Not required matching policy, a charges code with
Compare purchase order and invoice valuesnot selected (orMatch chargesoff at legal entity level), and an invoice-entry line withMatch invoice totalsoff.
5.2 Configuration
Fuel belongs on rung 1. Its rate holds to 0.04 against a vendor-specific indexed benchmark, which is stable enough to sit in a purchase agreement. Since half the available improvement comes from indexing to the period rather than from vendor-specific pricing, the agreement would benefit from a refresh process tied to the index.
Repair remains on rung 2. No benchmark brings its variance near 0.15, so no stable rate exists to place in master data. Each PO price will be a per-event quote, and matching will do no more than confirm it, at the review cost shown in section 4.4. That limitation belongs to the charge instead of the configuration.
Quantity matching does not depend on the rung. Set Line matching policy to Three-way match on Accounts payable > Setup > Accounts payable parameters, on the Invoice validation tab, together with Enable invoice matching validation, wherever a product receipt is taken.
Price tolerances. Set on Accounts payable > Setup > Invoice matching setup > Price tolerances, resolving from item and vendor down to All/All. The legal entity default is 0 per cent and cannot be deleted, so any price variance is reported until a tolerance is entered. Override the matching policy per vendor or item on Accounts payable > Setup > Invoice matching setup > Matching policy, which resolves item and vendor, then item, then vendor, then legal entity.
Charges. Enable Match charges in Accounts payable parameters and set the Charges tolerances page. Charges matching runs only on charges codes where Compare purchase order and invoice values is selected on the Charges code page.
Duplicate invoice numbers. The Check the invoice number used parameter in Accounts payable parameters, set to Reject duplicate or Reject duplicates within fiscal year, applies independently of any rate.
5.3 What the analysis supports
The analysis establishes which charges can be driven from master data and how a fuel agreement should be structured. Everything else in section 5.2 comes from the product documentation, and the rung model in section 1 follows from how matching is defined.
Price protection in F&O grows with the quality of the master data behind the purchase order, whereas quantity protection is independent of it. Where no stable rate can be established such as in section 4 for engine and airframe repair, the constraint is commercial and no configuration will be able to remove it.
Limits
The filings are quarterly aggregates rather than individual invoices. A quarter combines many transactions, so part of the reported variance reflects differences in work mix rather than pricing. The ordering between charges is the result. The absolute values are not tolerance settings.
Three parameters are judgement rather than derived: the $100,000 minimum row, the four-quarter minimum history, and the 0.15 variance threshold marked on Figure 3.
No evidence of overcharging at any carrier is presented, and no carrier is identified as such. The analysis addresses which charges can be checked, not what any operator would recover.
Configuration detail is taken from Microsoft Learn and has not been verified against a specific implementation. Version differences apply.
Reproducing this
The source codes and datasets are at github.com/kingomnivore/airline-invoices-dynamics365-fno. Clone it, pip install -r requirements.txt, then python run.py. The filings are committed, so it should run as cloned.
The recipe below describes the same analysis independently of the code, for anyone who would rather rebuild it. It is a download, 4 filters and 2 ratios, without the modelling.
1. Get the data. From TranStats, Air Carrier Financial, Schedule P-5.2, select all fields, set Quarter to All Quarters, and download 2024 and 2025. Concatenate them. The amount and driver columns for each charge are in Table 2.
2. Filter. Keep rows where the amount exceeds 100 and the driver exceeds 0. Amounts are in thousands. Keep only carrier and aircraft type combinations with at least four quarters on file.
3. Unit rate. Divide amount by driver. Both columns carry the same factor of a thousand, so the result is dollars per gallon and dollars per flight hour directly.
4. Explanatory power. Fit amount = a + b x driver by ordinary least squares and take R2. Then split the rows into quartiles by driver, refit inside each, and average those. The second figure is the one to report, since carrier size inflates the first.
5. The benchmarks. Each is the unit rate divided by a reference.
| Benchmark | Reference |
|---|---|
| Industry | The median rate across all rows |
| Indexed | The median rate within the same year and quarter |
| Own rate | The indexed deviation divided by its own median within each carrier and aircraft type |
6. Variance. For each set of deviations, take the 75th per centile minus the 25th, divided by the median.
7. Check. The fuel median should be $2.43 per gallon and pilot pay roughly $1,498 per flight hour. The two are independent, check if either are off the column for units.
Chosen parameters. The $100,000 floor, the four-quarter minimum, and the 0.15 threshold drawn on Figure 3 were deliberate choices assumed.
On method
The analysis code and the initial draft were produced with Claude Code. The dataset and the configuration claims were verified against the sources listed below before publication. The code is public on the repository.
Sources
- Accounts payable invoice matching overview, Microsoft Learn
- Set up Accounts payable invoice matching validation, Microsoft Learn
- Three-way matching policies, Microsoft Learn
- Vendor invoices overview, Microsoft Learn
- Analysis code and data, GitHub
- BTS TranStats, Air Carrier Financial Reports, Schedule P-5.2
- EIA, US Gulf Coast Kerosene-Type Jet Fuel Spot Price FOB, monthly

















