---
title: "The supplier price-drift watcher: the increase that arrived without a letter"
subtitle: "Every invoice line compared with what you paid last time, per kilo, litre or piece, so a quiet 6% shows up the week it happens instead of at year-end"
url: "https://rxed.ai/blueprints/supplier-price-drift-watcher.html"
id: "supplier-price-drift-watcher"
version: "1.0"
published: "2026-08-13"
kind: "workflow"
setup_effort: "A weekend"
setup_hours: "6-12"
running_cost_usd_per_month: "0-12"
paid_software_usd_per_month: "0"
time_saved: "not a time saving - it finds the rises nobody sent a letter about, worth ~EUR 2,400/year at EUR 10,000/month of purchases and 2 points of drift"
time_saved_basis: "it finds money rather than hours: at EUR 10,000 a month of purchases, two percentage points of drift nobody noticed is EUR 2,400 a year, against euro-area producer prices 3.0% above a year earlier excluding energy (Eurostat, June 2026) and US final-demand producer prices 5.5% higher (BLS, June 2026)"
runs_by: "unattended"
data_location: "your-server"
data_location_note: "Your purchase prices are the most commercially sensitive numbers you hold. They stay on your box - no vendor learns what you pay, and no supplier's portal is the only place your own price history exists."
first_to_break: "item matching: a renamed product or a new supplier code arrives with no history, so it cannot be compared and never gets flagged"
failure_signal: "silent"
problem: "Suppliers raise their prices one item at a time, and nobody sends a letter about it. You check the invoice total, pay it, and only notice months later that the same order costs more than it used to."
fix: "Every line on every supplier invoice is compared with what you paid for that same item last time, worked out per kilo, litre or piece, so a smaller pack at the same price counts as a rise. Once a week you get one list: what went up, by how much, and what it costs over a year at the amount you buy."
tools: ["Paperless-ngx", "Docling", "Grist", "n8n", "Docker"]
tech: ["Paperless-ngx", "Docling", "Grist", "n8n"]
repos:
  - name: "Paperless-ngx"
    url: "https://github.com/paperless-ngx/paperless-ngx"
  - name: "Docling"
    url: "https://github.com/docling-project/docling"
  - name: "pdfplumber"
    url: "https://github.com/jsvine/pdfplumber"
  - name: "Grist"
    url: "https://github.com/gristlabs/grist-core"
  - name: "Baserow"
    url: "https://github.com/baserow/baserow"
  - name: "n8n"
    url: "https://github.com/n8n-io/n8n"
  - name: "Ollama"
    url: "https://github.com/ollama/ollama"
  - name: "OCA account-invoicing (account_invoice_supplierinfo_update)"
    url: "https://github.com/OCA/account-invoicing"
  - name: "ERPNext"
    url: "https://github.com/frappe/erpnext"
  - name: "Material Price Control (ERPNext app)"
    url: "https://github.com/sagarrgarg/material_price_control"
categories: ["Bookkeeping", "Reporting", "Document reading (OCR)", "Self-hosted", "n8n"]
source: "RXed AI News — https://rxed.ai"
---
# The supplier price-drift watcher: the increase that arrived without a letter

> Every invoice line compared with what you paid last time, per kilo, litre or piece, so a quiet 6% shows up the week it happens instead of at year-end

## Before you start

- One unit per item decided up front - per kilo, per litre or per piece - because comparing a case against a bottle produces a month of false alarms
- Twelve months of paid invoices, or an accounting export of purchase lines, to seed the history: a supplier price list is what was quoted, the invoice is what you were charged
- The supplier's own item code on the invoice, or a stable description you are willing to map by hand once
- Your yearly volume per item, at least roughly, or the weekly list has no euro figure and nobody acts on it
- A machine that stays on, with about 8 GB of RAM free if you want the local model as a fallback parser
- One named person who makes the phone call when a line is flagged, and the mandate to renegotiate

## What breaks first

item matching: a renamed product or a new supplier code arrives with no history, so it cannot be compared and never gets flagged. Broken matching looks exactly like a quiet month. Watch the count of new items every month - if it climbs, the matching is rotting rather than your suppliers behaving.

Every line on every supplier invoice compared with what you paid for the same item last time, in price per kilo, litre or piece — so the quiet 6% shows up the week it happens, not at year-end when the margin is already gone.

 

### The problem

 Your input prices are moving right now, and the official numbers say by how much. Eurostat's release of 5 August 2026 puts euro-area industrial producer prices 4.6% above June 2025 , and 3.0% higher excluding energy . In the US, the Bureau of Labor Statistics put final-demand producer prices 5.5% higher over the twelve months to June 2026 , with goods at 7.9% . Those are averages across whole economies. Your basket is not the average: half your lines did not move at all, one moved 15%, and the average tells you nothing about which is which.

 The reason it goes unnoticed is boring. A price rise does not arrive as a letter. It arrives as a different number on line 7 of an invoice you check for two things: does the total look normal, and did the delivery match. Both pass, so you pay it. Three months later the same order costs more, the margin is thinner, and nobody can name the item that did it.

 The arithmetic is worth doing once. Buy €10,000 a month of goods and that is €120,000 a year. Two percentage points of drift you never spotted is €2,400 a year . For a business netting €30,000, that is 8% of the profit, and it is invisible on every single invoice that caused it.

 Then there is the version with no price change at all. Same price on the line, 900 g in the box instead of 1 kg: an 11% rise that your accounting system will never see, because your accounting system counts lines, not contents. Consumer law now treats this as the price increase it is — France's arrêté du 16 avril 2024 has forced food retailers over 400 m² to label reduced-quantity products since 1 July 2024 . That protection stops at the shop shelf. Nobody labels the pack change on your wholesale invoice.

 The shelf you can buy this from is split in two, with nothing in the middle. Procurement and spend-analysis suites do it well and are priced for a company with a purchasing department. At the other end, if you already run an ERP, a module exists (see below). If you run neither — which is most small businesses — you build it out of four parts you can verify, and two of them you are probably running already.

 

### The architecture

 
 [ Supplier invoice ] → one mailbox, or the scanner 
         ▼ 
 [ Paperless-ngx — one archive, OCR ] 
         │  supplier, date, document number 
         ▼ 
 [ Docling or pdfplumber — the line items ] 
         │  description · code · quantity · pack size · price 
         ▼ 
 [ n8n — the comparison ]  price per unit, now against last time 
         ├─ unchanged                 → nothing happens 
         ├─ up beyond your threshold   → FLAGGED 
         ├─ same price, smaller pack   → FLAGGED 
         └─ item never seen before     → NEW , for you to name 
         ▼ 
 [ Grist — price history, one row per purchase ] 
         item · supplier · date · pack · price per unit · your yearly volume 
 
 One list, once a week: what moved, and what it costs over a year at what you buy.
 

 Four parts, and the important one is the smallest. The archive stores documents, the parser turns a page into rows, the table remembers what you paid, and n8n does a subtraction and a percentage. The parser reads. The arithmetic decides. Nothing in this chain is asked whether a price looks fair.

 

### Tool choices — and why

 Paperless-ngx (GPL-3.0, 44k stars, commit today) is the intake. If you built the receipt and invoice intake blueprint, this is already running and this blueprint hangs off it. If not, it is worth having on its own merits — one searchable archive, OCR on scans, and the supplier and date pulled off the document.

 Docling (MIT, 65k stars, commit yesterday) is the part that earns its place. Invoice line items live inside a table, and table structure is exactly where a regex gives up the first time a supplier changes their template. Docling reads the table as a table and hands back rows. pdfplumber (MIT, 11k stars, commit June 2026) is the simpler answer when your five biggest suppliers send text-layer PDFs with a stable layout: fewer dependencies, less RAM, and easier to debug. Start with pdfplumber on the suppliers you actually buy from, move to Docling for the ones it cannot hold.

 Ollama (MIT, 178k stars, commit today) runs a small local model on the layouts that beat both parsers — the ones where the pack size sits in a footnote or the unit price is in a merged cell. Keep it in that role. A model reading a field is useful; a model deciding whether a 9% rise is acceptable is a machine that agrees with whatever you already think.

 Grist (Apache-2.0, 11k stars, commit yesterday) holds the price history. Formulas convert every line to a common unit and compute the change; per-cell access rules keep supplier pricing out of everyone's hands. Baserow (5.6k stars, commit today, core MIT with paid directories under Baserow's own licence) does the same job if you prefer its interface.

 n8n (Sustainable Use License, free for internal business use, 199k stars, commit today) is the comparison. Same box as your other automations.

 If you already run an ERP, do not build this. On Odoo, account_invoice_supplierinfo_update in the OCA account-invoicing repository (AGPL-3.0, 304 stars, commit yesterday) puts a "Check Supplier Info" button on the vendor bill and shows the price variation against the price recorded on the product, per line, before you accept it. That is most of this blueprint, maintained by people who maintain Odoo modules for a living. On ERPNext (GPL-3.0, 38k stars, commit today) the nearest thing is Material Price Control , a third-party app that blocks incoming rates outside a variance band — but it carries 2 stars and its last commit was February 2026, so read the code before you let it block a purchase receipt. Building a parallel price history next to an ERP that already holds your purchase lines is duplicate work with two versions of the truth.

 Monthly cost. Software €0 across the stack. Hosting is €0 extra if this shares the box already running your archive and your automations, otherwise one VPS at roughly €5–12/month. The local model wants about 8 GB of RAM and only runs on the invoices the parsers miss.

 

### Setup outline

 1. Fix the unit before anything else. Every line converts to price per kilo, per litre or per piece. Compare a case against a bottle once and you will spend a month untangling false alarms. 
 2. Seed twelve months of history from invoices you have already paid, or from your accounting export. A supplier price list is what they quoted; the invoice is what you were charged, and only one of those is evidence. 
 3. Give every item two keys: the supplier's code and your own name for it. Match on the code, report under your name. A description-only key breaks the first time "Flour T55 25kg" becomes "FLOUR T55 SACK 25 KG". 
 4. Build extraction for your five biggest suppliers first. They are most of the money and their templates rarely change. The long tail can wait, and some of it never needs doing. 
 5. Set the threshold at 3%, and never below the rounding error of your own unit conversion. Flag drops over 5% as well — sometimes it is a credit in your favour, and sometimes it is a cheaper product substituted into the same line. 
 6. Make the pack-size column mandatory and flag it on its own. Same price, less product is the rise nobody reports. 
 7. Track the invoice-level charges as if they were items: delivery, fuel surcharge, small-order fee, pallet deposit. Otherwise you will announce that prices are stable while the totals climb. 
 8. The weekly list has five columns and one that matters: item, supplier, old and new price per unit, percentage, and what it costs over a year at your volume . Nobody rings a supplier about 4%. People ring about €1,900. 
 9. Run it silent for a month. Check ten flags against the paper invoice, fix the extraction, then start sending the list.

 

### Pitfalls — the real ones

 Item matching is the whole game, and it fails quietly. A renamed product or a new supplier code arrives as a NEW item with no history, so it can never be flagged as a rise. The system then reports a calm week. Watch the count of new items every month: if it climbs, your matching is rotting, not your suppliers behaving. 
 Never compare supplier totals. A total that moved 1% can hide one line up 20% and three down. The comparison is line by line or it is decoration. 
 A promotional price is not a baseline. Store the promo flag, or every promotion will produce a phantom rise the month it ends and you will stop trusting the list. 
 Compare ex-VAT, in one currency. A VAT rate change or an exchange-rate move is real money but it is not your supplier's decision, and mixing them in makes the list unarguable in the wrong direction. 
 Suppliers are allowed to raise prices. Most rises are real cost passed on, and the majority of your flags will end with "fair enough". The point is not to fight all of them, it is to know before the third invoice instead of after the twentieth, and to have the number in front of you when you renegotiate. 
 A flag nobody acts on is a report. Name the person who makes the call and keep it to two or three a month. A list of forty flags gets archived unread. 
 Do not ask a model whether a price is reasonable. It has no idea what you negotiated and it will agree with the framing in your question. Subtraction decides; the model only reads the page.

 

### Verified repos

 
 [Paperless-ngx](https://github.com/paperless-ngx/paperless-ngx) — GPL-3.0, 44k stars, commit today (13/08/2026) 
 [Docling](https://github.com/docling-project/docling) — MIT, 65k stars, commit 12/08/2026 
 [pdfplumber](https://github.com/jsvine/pdfplumber) — MIT, 11k stars, last commit June 2026 
 [Grist](https://github.com/gristlabs/grist-core) — Apache-2.0, 11k stars, commit 12/08/2026 
 [Baserow](https://github.com/baserow/baserow) — core MIT (premium/ and enterprise/ directories under Baserow's own licence), 5.6k stars, commit today 
 [n8n](https://github.com/n8n-io/n8n) — Sustainable Use License (free self-hosted internal use), 199k stars, commit today 
 [Ollama](https://github.com/ollama/ollama) — MIT, 178k stars, commit today 
 [OCA account-invoicing](https://github.com/OCA/account-invoicing) (module account_invoice_supplierinfo_update ) — AGPL-3.0, 304 stars, commit 12/08/2026 
 [ERPNext](https://github.com/frappe/erpnext) — GPL-3.0, 38k stars, commit today 
 [Material Price Control](https://github.com/sagarrgarg/material_price_control) (ERPNext app) — 2 stars, last commit February 2026. Listed because it is the only ERPNext-native option found; read it before you rely on it.
 

 Price sources: [Eurostat, industrial producer prices, June 2026](https://ec.europa.eu/eurostat/en/web/products-euro-indicators/w/4-05082026-ap) (released 05/08/2026) · [US Bureau of Labor Statistics, Producer Price Index, June 2026](https://www.bls.gov/news.release/ppi.nr0.htm) · [Arrêté du 16 avril 2024](https://www.legifrance.gouv.fr/jorf/id/JORFTEXT000049502248) (French reduced-quantity labelling, in force 01/07/2024). Repo figures verified 13/08/2026.

 
 Get the next blueprint as it publishes — free, practical, verified tooling only.

 [Subscribe](https://subscribe.rxed.ai) · Want this audited or extended for your business? DM [@RXed_EU](https://x.com/RXed_EU)
