More

Book a free call
Fixed price in writing before we start

Supplier price lists in PDF or Excel: which increases actually raise your product cost

A supplier sends a price list with hundreds of lines, and the real question is how much more a specific product now costs to make. This n8n workflow reads the list in PDF, XLSX or CSV, compares it with the prices you accepted last time and turns the changes into the material cost of every product in your bill of materials.

Author

Published:
Last verified:
n8n version:
2.8.4

In short

What it does

  • Reads a supplier price list in PDF, XLSX or CSV uploaded through a form
  • Checks every code and price the model read against the PDF text
  • Converts prices to a base unit: packs, metres, kilograms
  • Shows a person only the uncertain lines for approval
  • Calculates the material cost change of every product per unit and per year
  • Writes a negotiation brief from already calculated numbers only

What it does not do

  • Does not read scanned PDFs without a text layer
  • Does not convert currencies
  • Does not handle quantity-based tiered prices
  • Does not replace an ERP that already imports price lists

What it needs

  • n8n with Data Tables (tested on 2.8.4)
  • An Anthropic API key
  • A BOM table: product, supplier code, quantity, unit, annual volume

Supplier price lists in PDF or Excel: which increases actually raise your product cost

A supplier sends a new price list. A few hundred lines, some priced per pack, some per metre, a few codes renamed without notice. Purchasing does not need a list of what went up. It needs to know how much more a specific product now costs to make, and what that adds up to over a year.

This n8n workflow reads a price list in PDF, XLSX or CSV, compares it with the prices you accepted last time, turns the changes into the material cost of every product in your bill of materials, and ends with a short brief for the conversation with the supplier. Uncertain lines are approved by a person before they touch anyone's costing.

n8n workflow canvas: price list form, separate PDF and spreadsheet paths, normalization, comparison with stored prices, an approval page and the BOM impact calculation
The whole workflow after import. The model works in three places only: mapping columns, copying PDF rows and writing the brief.

Why "paste the price list into a chatbot" is not enough

The obvious idea is to give a model both lists and ask for a comparison. With a dozen lines it even works. With a real price list, three things break.

Units and packs

In January an M8x20 screw cost 34.00 PLN per pack of 100. In November the same screw is listed at 0.36 PLN per piece. A price-to-price comparison shows a 99% drop. In reality it is a 5.9% increase.

A model sometimes catches this and sometimes does not. And this is the worst direction to get it wrong, because the increase looks like a bargain.

Rows that were never there

A model reading a PDF can skip a row or add one that is not in the document. In a full price list a skipped row looks like a discontinued item. An added row looks like a new product with an invented price.

The model does not know your BOM

Even a perfect list comparison answers the wrong question. A 16.6% rise in powder coating matters more than a 114% rise in a lock if you use two kilograms of coating per product and buy the lock once a quarter.

The rule: the model copies, code calculates

The whole workflow rests on a division of labour. The language model only does what code cannot do well, which is reading messy documents. Everything that can be calculated is calculated by code.

Excel and CSV

The model gets the column names and a few sample rows. It returns only a mapping: which column is the code, which is the price, which is the unit. Code then reads every row.

A 5,000-line list costs one model call, the same as a 20-line one.

PDF

The model copies rows exactly as printed. The price stays text such as "1 234,50". Nothing is converted or rounded.

Code then looks up every copied code and every price in the original PDF text.

That check is the most important part of the workflow:

check-rows-against-pdf.js
const squash = s => String(s || '').toUpperCase().replace(/\s+/g, '');
const haystack = squash(fullText);
const digitsOf = s => String(s || '').replace(/[^0-9]/g, '');
const numberTokens = new Set([
  ...(fullText.match(/\d+(?:[.,]\d+)?/g) || []),
  ...(fullText.match(/\d{1,3}(?:[ \u00a0.]\d{3})+(?:,\d+)?/g) || []),
].map(digitsOf));

if (!haystack.includes(squash(r.supplier_sku))) issues.push(`code "${r.supplier_sku}" not found in the PDF`);
if (!numberTokens.has(digitsOf(r.price))) issues.push(`price "${r.price}" not found in the PDF`);

In testing we added a row to the model's output that was not in the price list. It did not get through: it went to review with a note that neither the code nor the price appears in the document.

One number to compare: price per base unit

Every price is converted to a price per piece, metre, kilogram, litre, m² or m³. Only those numbers are compared.

In the price listBase unitFactor
pack (100 pcs)pcsprice ÷ 100
100 pcspcsprice ÷ 100
mb, lmm1
gkg0.001
tkg1000
mll0.001

Pack size comes from a "quantity per pack" column, or from a description such as "opak. 100 szt." when there is no such column. Prices written like "1 234,50 zł" are parsed by code too, not by the model. Polish and other European number formats are handled.

When a person decides

A second page of the same form shows only the lines an automation should not decide on its own. Each has a reason and a choice: accept or reject.

SituationWhy not automatic
unit changed (e.g. tube from metres to 6 m bars)prices are not comparable
currency changedthe exchange rate is a decision, not arithmetic
price moved 40% or moreusually a pack-size error, sometimes a real increase
a new code resembles one that disappearedthe supplier may have renamed it
a row not confirmed in the PDFthe model may have invented it
an item missing from a full list read from PDFit may have been skipped while reading
The second form page with two lines to decide on: a lock price jump of 113.8% and a row whose code and price are not in the PDF
The approval page shows only the lines an automation should not accept on its own. Each comes with the reason.

A rejected line keeps its old price and is written to the change log with the decision. In testing, a lock jumping from 6.50 to 13.90 PLN was rejected and did not affect any costing.

Impact on the bill of materials

The bom_lines table holds one row per component: product, supplier, supplier code, quantity per unit, unit and annual volume. For each product, code calculates the material cost before and after the change.

ProductPer unit%Per year
REG-200 shelving unit+16.64 PLN+3.51+9,984 PLN
SZF-90 tool cabinet−11.40 PLN−1.49−2,052 PLN
WOZ-50 workshop trolley+4.20 PLN+0.75+1,050 PLN

For the shelving unit the biggest drivers are powder coating (+11.52 PLN) and the 40x40 profile (+11.04 PLN), partly offset by cheaper sheet steel (−7.00 PLN). That is what you take to the supplier.

Code also catches things that quietly break costing: a discontinued component, a BOM counted in metres while the price is per bar, a component with no price on file.

The negotiation brief

At the end the model writes a short brief: what changed, which increases matter for our products, what to ask the supplier, and what to fix internally. It receives only numbers that are already calculated and is told not to compute new ones.

Use only the numbers in DATA. Every figure you mention must appear there; do not calculate new ones.

The brief is an extra, not the source of truth. The numbers in the table above come from code and do not depend on the model.

Configuration

All thresholds live in one Settings node.

ParameterValuePurpose
alertThresholdPct3increases from this percentage go on the alert list
reviewAbovePct40changes from this percentage need approval
fuzzyMatchMin0.6description similarity that suggests a renamed code
maxReviewRows25how many lines fit on the approval page
defaultCurrencyPLNcurrency when the list does not state one
csvEncodingutf8windows1250 for older Central European exports

A separate branch, run once, creates the three n8n Data Tables (supplier_prices, price_change_log, bom_lines). CSV files with ; as the separator, common wherever the comma is the decimal mark, are detected automatically.

Limitations

Scanned PDFs are not supported; you need a text layer or the Excel/CSV version.

No currency conversion. Lines in a currency other than the default are flagged and left out of totals.

Tiered prices (one price from 100 units, another from 1,000) are not modelled. When mapping columns, the model picks the base price and adds a note.

Renamed codes are matched on description similarity. A supplier who changes both the code and the description shows up as one new item plus one discontinued item.

The first list from a supplier compares nothing; it only saves the baseline.

We tested on fictional data on n8n 2.8.4, with the model responses substituted during the test. All logic outside the model ran on the instance, but we have not measured how often Claude maps columns wrongly or skips rows on real price lists from different suppliers.

When it does not make sense

With a handful of suppliers and stable prices, comparing lists by hand once a quarter takes less time than maintaining the BOM table. The workflow starts paying off when price lists arrive more than once a month, run to hundreds of lines, and your own selling prices depend on material cost. When supplier prices, BOMs, orders and stock need to live in one place, that is no longer a workflow but a production management system.

How to cite this

Adrian Hunia (2026). Supplier price lists in PDF or Excel: which increases actually raise your product cost. SEVENEDGE. https://sevenedge.pl/en/workflows/cenniki-dostawcow-koszt-bom (accessed: November 5, 2026)

Sources

  1. n8n docs — Data tablesn8n docs
  2. n8n docs — n8n Formn8n docs
  3. n8n docs — Extract From Filen8n docs
  4. n8n docs — Structured Output Parsern8n docs

Who is behind this

Adrian Hunia

Co-founder of SEVENEDGE

Co-founder of SEVENEDGE. Designs and deploys business systems for small companies, from production management to time tracking. Works with Next.js, FastAPI and PostgreSQL. SEVENEDGE has no subcontractors — both owners write the code.

Related documents

Other workflows we documented the same way.

7SVENAI assistant, not a human

You are chatting with an AI assistant. Replies are generated by artificial intelligence (Cerebras) and may contain mistakes. Please do not share sensitive data in the chat.

Your personal data is controlled by SEVENEDGE ADRIAN HUNIA. We use your chat messages to answer your questions and, if you ask, to book a meeting. Details and your rights: Privacy policy.

Hi! I'm SVEN, the SEVENEDGE AI assistant. We build apps, SaaS and AI automations. How can I help?
SVEN, the SEVENEDGE mascot, looking through a requestSVEN, the SEVENEDGE mascot, thinking over a coffeeSVEN, the SEVENEDGE mascot, working at a laptop
Got an app idea?