What does MRO mean in mining procurement?
MRO stands for maintenance, repair and operations. It covers everything a site buys to keep plant and people running that is not a raw input to the product or a capital project.
On a mine that means spare parts for fixed and mobile plant, wear parts, filters, hoses, bearings, lubricants, PPE, tools, and the service contracts that go with them. MRO is usually a huge number of low value lines, a smaller number of expensive critical spares, and a long tail of one-off buys.
| Term | What it means |
|---|---|
| Stocked item | Held in the warehouse with a min and max. Replenished automatically when stock drops to the min. |
| Direct charge (non stock) | Bought for a specific work order and charged straight to it. Never sits on the shelf as inventory. |
| Purchase requisition (PR) | The internal request to buy. Not a commitment to the supplier. |
| Purchase order (PO) | The commitment to the supplier. Price, quantity, part, delivery and terms. |
| Contract rate | The price agreed in a supply agreement or panel for a given part and supplier. |
| Three way match | Checking the invoice against the PO and the goods receipt before paying. |
The reason MRO gets its own process is volume. A site can raise thousands of PO lines a month, so the process has to work without a person reading every one.
What are the steps in the MRO procurement process?
There are ten steps. The first five decide whether you buy the right thing at the right price. The last five decide whether you pay for what you actually got.
- Identify the need. Either a maintenance work order calls for a part, or a stocked item drops to its min (reorder point) and the ERP raises a requirement.
- Raise the requisition. Use the catalogue part number, not a free text description. Free text is where duplicates and off contract buying start.
- Check stock first. Is it on the shelf here, at another site, or in a rotable pool? A transfer is cheaper than a new buy.
- Source it. If a contract or panel covers the item, the PO goes to that supplier at that rate. If not, request quotes (usually one to three, depending on value).
- Approve. Approval follows the delegation of authority by dollar value. Splitting a buy into smaller POs to dodge an approval level is a red flag.
- Raise the PO. The price on the PO should be the contract rate or the accepted quote. This is the step most sites never check.
- Expedite. Chase overdue lines, especially anything holding up a work order or a critical spare.
- Receive and inspect. Receipt the quantity that actually arrived, not the quantity ordered. Inspect against the part number.
- Match and pay. Three way match the invoice to the PO and the receipt. Hold anything outside tolerance.
- Review. Monthly, look at price variance against contract, off contract spend, stock levels against real usage, and lead times by supplier.
Where does money leak in MRO procurement?
Money leaks where nobody checks. The three way match at step 9 catches an invoice that does not match the PO. It does not catch a PO that was raised above the contract rate in the first place.
The common leak points are:
- PO price above contract rate. The rate in the ERP is out of date, the buyer used the last price paid, or the supplier quoted list price and nobody compared it.
- Off contract buying. A contract exists for the item but the PO went to another supplier, often because the part was described in free text and nobody matched it. See our guide on maverick spend and three way matching.
- Emergency orders as the default. When stock levels are wrong, everything becomes urgent, and urgent buys skip sourcing.
- Rebuying stock another site already holds. The same part under a different number at the next site over.
- Stock levels that never move. A min and max set years ago keeps reordering parts nobody uses. That cash sits on the shelf.
How do you check PO prices against contract rates? A worked example
You join every PO line to the contract rate for the same part and supplier, then multiply the price difference by the quantity. Here is a worked example with made up numbers for one week of PO lines at one site.
| Item | Qty | PO price | Contract rate | Difference | Overpaid |
|---|---|---|---|---|---|
| Filter element | 40 | $86.50 | $78.20 | $8.30 | $332.00 |
| Wear liner | 6 | $1,240.00 | $1,240.00 | $0.00 | $0.00 |
| Hydraulic hose assembly | 15 | $212.00 | $198.50 | $13.50 | $202.50 |
| Bearing | 8 | $455.00 | $461.00 | minus $6.00 | $0.00 (below rate) |
| Gloves, box of 12 | 30 | $62.00 | No contract | n/a | Review |
Overpaid on these five lines: $332.00 + $202.50 = $534.50. The bearing came in $48.00 under the contract rate (8 x $6.00), which is worth knowing too, because it can mean the contract rate is stale. The gloves have no contract, so they go on the list of items to put on a panel.
The formula for each line is simple:
Overpaid = MAX(0, PO price − contract rate) x quantity
The hard part is not the maths. It is matching each PO line to the right contract rate when part numbers, supplier names and units of measure do not line up.
How do you do this check in Excel or your ERP?
You can run a first pass in Excel in an afternoon if you can get two exports: PO lines and contract rates.
- Export PO lines for the last 12 months: PO number, line, date, supplier, part number, description, quantity, unit of measure, unit price, status.
- Drop anything that is not real spend. Quotes, cancelled lines and unapproved orders should not be counted. An international tier 1 mining operator we worked with had exactly this problem: quotes and unapproved orders were being counted as spend, and one rule fixed a whole class of wrong numbers.
- Export contract rates: supplier, part number, rate, unit of measure, valid from, valid to.
- Build a key in both tables: supplier plus part number, for example
=[@Supplier]&"|"&[@PartNo]. - Look up the rate with
=XLOOKUP([@Key], Rates[Key], Rates[Rate], "No contract"). Check the PO date falls inside the rate's valid dates. - Calculate overpaid per line with
=IF(ISNUMBER([@Rate]), MAX(0, [@Price]-[@Rate])*[@Qty], 0). - Pivot by supplier and category and sort by overpaid, largest first.
Expect this to work for maybe the cleanest part of your data. Units of measure (each versus box of 10), superseded part numbers and supplier name variations will break a lot of the lookups. That is normal, and it is the reason most sites run this check once and never again.
What are the most common MRO procurement mistakes?
The biggest mistake is treating the three way match as proof you paid the right price. It only proves you paid what the PO said.
- Free text requisitions. They bypass the catalogue, the contract and the stock check in one go.
- Contract rates not loaded or expired in the ERP. The contract exists on paper but the system never sees it.
- Escalation clauses applied by the supplier, not checked by you. Rises should match the contract formula and timing.
- Receipting the ordered quantity by default. If 48 arrive and 50 are receipted, the match passes and you pay for two parts you never got.
- Counting quotes or unapproved orders as spend. It inflates every spend report and hides the real picture.
- Measuring compliance by supplier, not by item. Buying from a contracted supplier at list price still counts as on contract in most reports.
- Never revisiting stock levels. Old min and max settings drive a lot of unnecessary orders. Our guide on how to set min max levels covers the fix.
How does Source Digital automate MRO procurement checks?
We build the checks inside your own environment (your Azure, Databricks or Snowflake), with read only access to your ERP data. Every number links back to the PO line, receipt or contract it came from. A person approves every action. The AI never decides.
- PO vs contract checker. Every PO line is compared to the contract rate before it is paid, including units of measure, validity dates and superseded parts. See PO and contract rate checking.
- Contract price book. Built from your own contract history, so each price is judged against what was agreed and what was last paid. See the contract price book case study.
- Stock level engine. Sets min and max from real usage. At an international tier 1 mining operator it matched the site inventory expert's own spreadsheet 99.8% of the time.
- An assistant in Microsoft Teams. Ask "what did we pay for this part last quarter and what is the contract rate?" and get an answer from millions of rows in about a minute. See the Teams commercial agent.
The maths is deterministic. The AI explains the results; it does not make up the numbers.
The first step is a free 15 minute call with Tristan, or send a quick enquiry if you would rather write. No obligation and no pitch. He asks what you run and what is costing you, then tells you straight whether there is something worth fixing. Work is charged at a consulting day rate. The price depends on your sites, systems and data, so you talk first, then Tristan sets out what he would build, how many days it takes and what it costs. An engagement runs like this:
- A free 15 minute call. What you run, and what is costing you.
- A look at a sample export of your data, only if it is useful. Read only.
- A clear scope and price, based on the days the work needs.
- The build inside your systems.
- Run, check and support.
See AI for mining supply chains for more.

