What data does your ERP hold on maintenance and repair?

ERP data gaps on maintenance and repair spend: work orders, PM schedules, warranty flags, and what a diagnostic reconciles against them. Read the full guide.

Twitter LinkedIn WhatsApp
Ask AI: ChatGPT Claude Gemini Grok
What data does your ERP hold on maintenance and repair?

Margin drift is the gap between what a vendor contract says and what the invoice actually charges. On maintenance and repair spend, that gap survives because the ERP holds one half of the comparison and not the other.

A controller pulling a maintenance report can answer "what did we spend" and "which asset" without difficulty. The harder question, "was this invoice priced the way the contract said it would be," has no answer inside the system at all.

Executive Summary

Every ERP with a maintenance module stores a work order number, an asset ID, labor hours and a parts list. What most installations do not store, in a field anyone can query, is the master service agreement rate that invoice should have been priced against, the warranty window that should have made a repair free, or the scope boundary that separates a preventive visit from a billable emergency call. The invoice arrives with a PO number that matches.

It does not carry the contract clause that would tell an AP clerk whether the number on it is correct.

This is a structural gap, not a training gap. Three-way matching checks the invoice against the purchase order and the goods receipt. It confirms a work order existed and a technician showed up.

It has no field for a labor rate escalation cap, no field for a warranty expiration date tied to a specific serial number, and no field for the four-hour response window a facilities contract promises. Those terms live in a PDF, not a table, so the system that approves the invoice cannot test it.

The fix is not a new module. It is treating the contract as a second dataset that has to be reconciled against ERP transaction data on a schedule, the same way a bank statement gets reconciled against a general ledger. On maintenance spend, the ERP alone cannot see the gap between contract and invoice because it was never asked to hold the contract in the first place.

1. What does an ERP actually capture on a maintenance work order?

A standard ERP maintenance module captures a work order number, an asset or equipment ID, a requested date, a technician or vendor assignment, labor hours logged, parts consumed against inventory, and a total cost that rolls up to a GL account. This is transaction data: what happened and what it cost. It answers volume and spend questions well.

It was not built to hold contract terms, so it has no field asking whether the rate charged, or the response time.

The work order is the system's unit of record. It ties a piece of equipment to a labor entry and a parts list, and it closes when the technician signs off. That structure is good for asset history: when a pump last failed, how many hours a line was down, which vendor did the work.

It is weak for contract enforcement because the work order was designed around the physical event, not the commercial agreement behind it. A field for "hours billed" exists. A field for "contracted labor rate at time of service" usually does not, so nothing in the system flags a rate that has drifted from the agreement.

The result is a system that can tell you a repair happened and what it cost, but not whether that cost was the one you contracted for.

2. Where does the contract data live if not in the ERP?

Master service agreements, warranty terms, and rate schedules for maintenance vendors typically live as signed PDFs in a contract repository, a shared drive, or a vendor management system that does not talk to the ERP. The invoice references a PO and a work order that the ERP can validate. It does not reference the labor rate table, the response time SLA, or the warranty window written into the contract, because none of those terms were entered as structured data anywhere.

This is the core disconnect. A rate card negotiated at contract signing gets filed, not entered. A warranty period tied to a serial number gets mentioned in an email, not linked to the asset record. An escalation clause capping annual rate increases gets referenced once during negotiation and then forgotten until someone reads the contract again, usually after a dispute.

None of this is a system failure in the sense of a bug. The ERP is doing what it was configured to do: track transactions against a purchase order. The contract was never loaded into it as enforceable data, so there is nothing for the invoice to be checked against automatically.

Closing that gap means treating the contract file as a dataset in its own right, and reconciling it against ERP transactions on a set schedule rather than assuming the ERP already covers it.

3. Can three-way matching catch a maintenance and repair overcharge?

Three-way matching checks that an invoice agrees with its purchase order and its goods receipt or work order closure. It confirms quantity and a PO-level price field agree. It does not test whether the labor rate on that PO reflects the current master service agreement, whether a repair should have been free under warranty, or whether the scope performed matches what was actually authorized.

Those are contract questions, and three-way matching was built to answer a procurement question instead.

A maintenance invoice can pass three-way matching cleanly and still be wrong. The PO says $95 an hour, the invoice says $95 an hour, the work order closed, and the match succeeds. If the master service agreement actually caps that rate at $85 after a volume threshold, or the repair falls inside a warranty period the technician never checked, the match has no way to know.

The control was built to stop a vendor from billing for parts that were never received or quantities that were never ordered. It does the job asked of it. Testing a rate escalation clause, a warranty expiration date, or a scope boundary is a different job, one that needs the contract as an input, and none of that logic sits inside standard matching rules.

4. Which maintenance data points cause reconciliation problems?

Five fields recur as blind spots across ERP maintenance modules: the labor rate tier that should apply at time of service, the warranty window tied to a specific asset serial number, the distinction between preventive and emergency scope, the response time commitment in the service agreement, and the price attached to a substituted part. None of these is stored as a testable field in a standard work order, so an invoice can close cleanly while any one of them drifts.

Each of these is a place where the ERP records an outcome without recording the rule that outcome should have followed. None requires a new module to fix. Each requires the contract term to be captured as structured data once, then compared against the transaction on a schedule.

The pattern across all five is the same: the system faithfully records what happened and has no opinion on whether it should have happened that way.

  • Labor rate at time of service: The ERP logs hours and a total, not the rate schedule tier that hour should have been billed against.
  • Warranty window by serial number: A repair on covered equipment can be billed as new work when no field links the asset ID to a warranty expiration date.
  • Preventive versus emergency scope: A scheduled PM visit and an after-hours emergency call carry different rates in many agreements, and the work order rarely distinguishes them.
  • Response time commitment: An SLA promising a same-day response has no corresponding timestamp field to test it against.
  • Parts substitution pricing: A part swapped for an equivalent can carry a different price than the one quoted, with no flag when that substitution occurs.

5. Does the ERP vendor's cost data explain rising maintenance invoices?

External cost indices explain part of an invoice increase but say nothing about contract compliance. Per the US Bureau of Labor Statistics Producer Price Index for commercial machinery repair and maintenance (series PCU8113--8113--, read 2026-09-06), the July 2026 index stood at 237.468, up 9.1% year over year. That figure shows input costs are rising industry-wide.

It does not tell a controller whether a specific vendor's increase was contractually permitted or exceeded an escalation cap.

A rate increase that tracks broad cost inflation looks reasonable on its face. A controller comparing this year's invoice to last year's, without the contract in hand, has no way to separate a justified pass-through from an increase that simply exceeds what the agreement allows.

The PPI series gives a market-level reference point: costs in this repair and maintenance category are moving up industry-wide as of the date read. It says nothing about a single vendor's specific rate card, and it cannot substitute for checking the escalation clause the vendor actually signed.

The two questions are separate. "Are costs rising in this category" is answered by an index. "Did this vendor charge what their contract allows" is answered only by comparing the invoice to the agreement, line by line.

6. How do you close the gap without a new ERP system?

Closing the gap does not require replacing the ERP. It requires pulling the maintenance contracts, rate cards, and warranty terms into a structured form once, then reconciling ERP transaction history against that structured data on a fixed schedule. This is the mechanism behind an indirect spend audit: the contract becomes a dataset the invoice can be tested against, rather than a document nobody opens after signing, while the ERP keeps doing the transaction tracking it already does well.

The practical sequence is straightforward even if the manual version is slow: collect every active maintenance and repair agreement, extract the rate tables, warranty terms, response commitments and scope definitions into a comparable format, then run historical invoices against that extracted data.

What surfaces is specific. A labor rate charged above the contracted tier. A repair billed as new work inside an active warranty window. An emergency rate applied to what the work order itself describes as a scheduled visit. Each of these is a finding the ERP could not have produced on its own, because it never held the reference point to compare against.

This is a one-time reconciliation exercise unless something keeps checking new invoices against the same contract data going forward. Absent that, the same gap reopens with the next contract renewal or rate change.

For the wider pattern this sits inside, start with the margin drift guide. See also the six categories drift hides in and accessorial charge audit: the surcharges nobody validates.

For the wider pattern this sits inside, start with the margin drift guide.

7. Frequently Asked Questions (People Also Ask)

Can we just add custom fields to the ERP for contract rates?

You can add fields to hold a rate value, but the ERP still needs someone to keep them current as contracts renew and rate schedules change. Without a process for updating those fields against the signed agreement, they drift out of date as fast as the invoice review they were meant to support.

Does a CMMS solve this instead of the ERP?

A computerized maintenance management system tracks asset condition and work order history well, often better than an ERP module does. It still does not typically hold the commercial terms: rate tiers, warranty windows, and SLA commitments. The same reconciliation gap exists whether the transaction system is an ERP or a CMMS.

How far back should a maintenance invoice review go?

That depends on how long records are retained and how many contract renewals have happened in that window. A reconciliation is most useful when it covers a period with a single, current contract version, since comparing invoices to a superseded rate card produces false findings.

What counts as a warranty-covered repair versus billable work?

A warranty typically covers a defined defect type on a defined component within a defined time window, all specified in the original purchase or service agreement. Whether a specific repair falls inside that window depends on reading the warranty terms alongside the asset's service history, not on anything the ERP tags automatically.

Who should own checking maintenance invoices against contracts?

In practice this sits between AP, procurement, and whoever manages the vendor relationship, since no single role holds both the invoice and the contract by default. Assigning clear ownership, even informally, is often the difference between a one-time reconciliation and an ongoing control.

Is this worth doing for a small maintenance vendor spend?

The setup cost of extracting and structuring contract terms is largely fixed regardless of vendor size, so it scales better across a larger spend base. For a single small vendor, a simpler manual spot check against the contract may answer the question without the full reconciliation exercise.

Does a rate card review require legal involvement?

Reading a rate schedule or SLA commitment for reconciliation purposes is not a legal exercise; it is a comparison of stated terms to billed amounts. Where a contract term is ambiguous enough to be disputed with a vendor, that is the point to involve legal, and this is general information, not legal advice.

What is the first thing to pull if we want to check our own maintenance spend?

Start with the active service agreements for the vendors that generate the most maintenance invoices, and pull the rate schedule, warranty terms, and SLA sections out of each one. Comparing those against a sample of recent invoices for the same vendors shows quickly whether a fuller reconciliation is worth running.

Margin Drift Resources