Supplier Quote Comparison: Units, Tax, Currency, Payment Terms and Freight on One Basis
The way to compare supplier quotes fairly is to restate each one on the same basis first: the same unit, net of recoverable tax, one exchange rate from one date, one delivery point, and the present value of each payment. Picking the lowest unit price does not do that. I build web apps that do this for purchasing teams: quotes arrive as PDF, Excel or email, prices stay hidden until the deadline, everything is restated in one table after opening, and whoever selects must write a reason that still answers “why this supplier?” months later. In the fictional request below, the supplier with the lowest unit price on every line it quoted ends up level with the winner once prepayment, freight and a missing line are added, and loses on lead time and warranty.
This page is about the buying side: comparing incoming quotes, choosing, and recording the decision. Preparing quotes for your own customers is the job of the cost-protected quoting portal. If you make a handful of purchasing decisions a year, or your ERP’s purchasing module already compares quotes, you may not need this app; I explain why below.
What steps turn quotes into comparable totals?
Comparable totals come out of six steps, and the supplier’s original figure always stays in its own column next to the restated one. Thresholds and details for each step are in the rules table further down.
- Line matching: “PU HOSE 8X5.5 BLUE 100M” is linked to your line “PU air hose 8 mm”; a substitute product stays on its own line.
- Units: roll, pack and box prices are converted to your unit.
- Tax: compare net of tax you can recover. A VAT-registered business normally reclaims input VAT; where you cannot reclaim the tax, it is a cost and stays in. A tax-inclusive quote is reduced using the rate stated on it; if none is stated, ask.
- Exchange rate: one rate from one date for every foreign-currency quote; the supplier’s own rate clause is recorded separately, because it changes step 6.
- Delivery point and gaps: add freight, and for imports insurance, import duty and customs clearance, where the quote excludes them; if the quote names no Incoterms code (EXW, FCA, DAP), ask. Price missing lines at what they would really cost you.
- Payment terms: discount each payment to present value from its due date; prepayment is day 0, and finance sets the rate.
Warranty, lead time and quality stay out of the total, in their own columns, and are named in the reason for the decision.
A sample request: four suppliers, twelve lines, who won?
Short answer: on present value A and B are level (under 0.3%), D is 1.5% higher; the purchasing manager picks A on non-price criteria. The working follows.
Four quotes, four different formats
The request is fictional and the figures are sample data. A 220-person metalworking manufacturer; the maintenance supervisor raises request PR-0418 for three months of pneumatic and hydraulic spares. Purchasing invites five suppliers, one declines, four reply by the deadline. Amounts are in the company’s base currency; B and D quote in a foreign currency (FX), converted at an example rate of 1 foreign-currency unit = 1.25 base-currency units.
- A (domestic distributor): base currency, net of tax, all 12 lines, delivered, 60 days from invoice, 5 working days, 24-month warranty, valid 30 days.
- B (importer): FX, 11 lines (no 4/3 hydraulic directional valve), full prepayment with the order, ex-warehouse, 6 weeks, 12-month warranty. Hose is quoted per 100 m roll.
- C (dealer): base currency including 20% tax, substitute brands on both cylinders, freight 4,500 extra, 30 days, 10 working days. Fittings are quoted per pack of 10.
- D (agent): FX prices, invoiced in base currency at the exchange rate on the delivery date, 90 days from invoice; 10 lines (no hydraulic hose, no filter), delivered, 3 weeks; valid only 7 days.
The maintenance supervisor accepts C’s Ø50 cylinder substitute and rejects the Ø63 one (different mounting flange), so that line counts as missing from C.
Unit prices on one basis
Normalised unit prices (base currency, net of tax, per requested unit; B and D converted at the example rate):
| line | qty | A | B | C | D |
|---|---|---|---|---|---|
| Pneumatic cylinder Ø50×200 | 8 | 2,150 | 2,042.50 | 2,100 (substitute) | 2,193 |
| Pneumatic cylinder Ø63×320 | 6 | 2,980 | 2,831 | rejected | 3,039.60 |
| 5/2 solenoid valve 24 V DC | 20 | 1,640 | 1,558 | 1,658.33 | 1,672.80 |
| FRL unit 1/2” | 6 | 2,450 | 2,327.50 | 2,491.67 | 2,499 |
| PU air hose 8 mm (per m) | 300 | 38.00 | 36.10 | 38.33 | 38.76 |
| PU air hose 10 mm (per m) | 200 | 52.00 | 49.40 | 52.50 | 53.04 |
| Push-in fitting 8 mm, straight | 400 | 46.00 | 43.70 | 46.00 | 46.92 |
| Push-in fitting 10 mm, elbow | 300 | 64.00 | 60.80 | 64.00 | 65.28 |
| Hydraulic hose 1/2”, pressed, 1 m | 40 | 690 | 655.50 | 700 | — |
| Hydraulic filter element | 24 | 1,180 | 1,121 | 1,191.67 | — |
| Hydraulic directional valve 4/3 | 4 | 7,900 | — | 7,900 | 8,058 |
| Pressure switch | 10 | 1,350 | 1,282.50 | 1,366.67 | 1,377 |
B is the lowest on all 11 lines it quoted, 5% below A.
Totals after restating
| A | B | C | D | |
|---|---|---|---|---|
| Quoted lines, net of tax (base) | 243,000 | 200,830 | 226,382 | 190,822 |
| Filling missing lines | — | 33,100 | 19,380 | 57,420 |
| Freight | included | 6,000 | 4,500 | included |
| Nominal total | 243,000 | 239,930 | 250,262 | 248,242 |
| Payment day (order = day 0) | 67 | 0 (freight 42) | 44 | 111 |
| Present value | 238,620 | 239,265 | 247,163 | 242,188 |
| Lead time / warranty | 5 working days / 24 months | 6 weeks / 12 months | 10 working days / 24 months | 3 weeks / 24 months |
Payment day = lead time + credit terms (lead times converted to calendar days: 5 working days = 7, 10 working days = 14, 3 weeks = 21): A 7 + 60 = 67, C 14 + 30 = 44, D 21 + 90 = 111; B pays with the order, freight on delivery (day 42). Lines we fill from A are paid on day 67 in every column. Example, C: (226,382 + 4,500) on day 44 and 19,380 on day 67 give a present value of 247,163.
Missing lines are filled at A’s prices plus 1,500 for a separate delivery (an assumption; A must confirm in writing that it holds those prices on a small order). B’s freight is a sample carrier quote. Even with the rejected Ø63 line removed, C is the most expensive at 271,660 including tax; net of tax it drops below A, then becomes the most expensive again with the missing cylinder and freight. On nominal totals, B is still the cheapest.
How the present value was worked out
Present value is what a future payment is worth today: amount ÷ (1 + annual rate × days ÷ 365). This page uses simple interest; if you treat 10% as a compound (effective annual) rate, A’s present value moves up by under 0.1% and the order of the four quotes doesn’t change. The example assumes a 10% annual cost of money in the base currency and 4% in FX. Your rate is your short-term borrowing cost, or what the cash would earn in the bank; finance sets it. In short: at a 10% cost of money, paying 67 days later is worth about 2% off the price.
- A: 243,000 ÷ (1 + 0.10 × 67 ÷ 365) = 238,620. A’s 67 days (7 delivery + 60 credit) are worth 4,380 at this rate, about 1.8% of the price.
- B: paid with the order, so no discount on 200,830; freight is paid on delivery and the missing valve is bought from A.
- D: the amount floats in FX until the invoice, then is fixed in base currency for 90 days, so it is discounted 21 days at the FX rate and 90 days at the base rate: 185,803, or 242,188 with the filled lines.
Discounting a foreign-currency payment term (D)
D’s row uses two different rates: discount each payment at the rate of the currency it is fixed in, from the day it is fixed to the day it is paid, then convert at today’s rate. Ninety days’ credit in a high-interest currency is worth far more than ninety days in a low-interest one. The rule rests on covered interest parity: the interest-rate gap between two currencies is already priced into the forward rate; in practice the parity holds approximately. The method needs no exchange-rate forecast, but it does not remove currency risk: D’s amount moves with the rate for the 21 days between order and invoice.
How sensitive is the ranking to the rate?
In the sample data A beats B only if your annual cost of money is above about 8.2%. At 10% the gap is 645, under 0.3%.
The decision and its reason
The purchasing manager chooses A and records this reason:
On present value A and B are level (under 0.3%, inside the uncertainty of the rate assumption). Under the tie rule I looked at non-price criteria: A supplies all 12 lines in one delivery in 5 working days with 24 months’ warranty and no prepayment; B needs a second order for the missing valve, takes 6 weeks, gives 12 months and wants full payment up front. D is 1.5% higher, two lines short, and its quote, received on day 12, expires 3 days after the decision.
Finance approves the same day, below the threshold that needs the managing director. The amount is committed against the department budget at approval; tracking budget against actual is the job of the budget vs actual expense dashboard. Unsuccessful suppliers are told the outcome, not each other’s prices. A table ranking on unit price or nominal total would have picked B.
Comparison rules: my suggestion, your decision
The thresholds below are my starting suggestions, not measured values; you decide after testing them on a few of your own purchases.
| rule | my suggestion |
|---|---|
| Unit normalisation | Every price in the requested unit, factor shown. Pack surplus is a cost (400 fittings in packs of 30 = 14 packs, 420 pieces) |
| Exchange-rate date | All FX quotes converted at the same rate from the quote deadline; finance picks the source. The supplier’s rate clause is a separate field, so rankings don’t change silently when rates move |
| Delivery point and freight | Restated to delivered-to-plant; excluded freight added from a carrier quote or the last three shipments, source noted |
| Cross-border quotes | Incoterms code is a required field; if a quote names none, ask. Every quote is restated to landed cost, delivered to your plant and cleared through customs: carriage and insurance the code doesn’t cover are added. Import duty and customs clearance sit with the seller only under DDP; under every other code they are the buyer’s and are added, sourced from a broker’s quote or recent imports. Recoverable import VAT stays out of the comparison. Based on ICC Incoterms 2020; confirm your own case with your customs broker |
| Missing lines | Filled at what you would really pay elsewhere plus the extra delivery; to penalise gaps, use the highest other quote |
| Substitute products | Separate line; technical approval by the requester, who doesn’t see prices, so price doesn’t sway the technical call. Rejected substitutes count as missing |
| Validity | Quotes expiring before the decision date flagged red; extensions asked in writing; expired quotes can’t be selected, because the price may change at order |
| Minimum number of quotes | At least three valid quotes above a value threshold you set; a supplier quoting under half the lines doesn’t count |
| Sole-source justification | Fewer than three quotes: a reason from a list (single manufacturer or authorised seller, compatibility with installed equipment, breakdown urgency, framework agreement), one sentence, one level of senior approval. Earlier sole-source buys of the same line are shown, so it doesn’t become habit |
| Tie rule | Under 1% present-value difference: decide on non-price criteria and name them in the reason; a gap inside the rate assumption’s uncertainty shouldn’t pick the winner |
| Revised quotes | Negotiation goes to every valid bidder at once with the same question; revisions are sealed again as a new version, so nobody undercuts after learning a rival’s price |
| Split orders | Only if the supplier confirms partial-order prices in writing and the split still wins after the second delivery; otherwise cherry-picking costs a second freight bill |
Before changing a rule, such as widening the tie band to 3%, I suggest replaying past requests to see who would have won; the change needs finance approval and goes into the audit trail.
Who requests, who opens, who selects, who approves?
In the setup I suggest, inviting, opening, selecting and approving are done by different people, nobody sees prices before the deadline, and no selection is saved without a reason.
| role | sees | does | cannot |
|---|---|---|---|
| Requester (e.g. maintenance supervisor) | Own request, specification, substitutes’ technical data | Raises the request, judges substitutes technically | See prices |
| Buyer | Supplier list, questions; all quotes after opening | Invites quotes, answers questions to all bidders at once, checks extraction, restates figures | See prices before the deadline, select |
| Purchasing manager | All quotes after opening | Starts the opening, selects and writes the reason, opens a revision round | Complete the opening alone |
| Finance manager | All quotes after opening, rate and FX settings | Confirms the opening, sets discount rate and FX source, approves within limit | Make the selection |
| Managing director | Requests above the threshold | Approves those selections and sole-source reasons | Make the selection alone |
| Internal audit | Everything, read-only | Exports the audit trail | Change records |
Value thresholds, delegation and timeouts follow the same logic as the employee expense approval workflow.
How does a sealed quote work? This is a design proposal. Suppliers send quotes to the app’s dedicated email address or upload link, not to anyone’s inbox. The app records the arrival time and shows no prices until the deadline. Then the purchasing manager starts the opening and the finance manager confirms it, both timed in the audit trail. A quote arriving after opening is stamped “late” and stays out of the comparison.
Two honest limits: if a supplier sends the quote to the buyer’s own address, the seal is broken; the buyer forwards it and the app marks it “arrived unsealed” at opening. And whoever runs the server can technically reach the database; I limit that with permissions and the audit trail, and encrypting prices until the deadline is a separate piece of work we discuss at the first step.
The audit trail for the sample request (sample data; day 1 is a Monday):
- Day 4, 14:40 — C asked whether substitutes are acceptable; the answer went to all five suppliers at once.
- Day 9, 16:12 — B’s quote arrived, sealed. Flag: no delivery point; B was asked without anyone seeing the price.
- Day 12, 11:20 — D’s quote arrived, sealed; valid 7 days.
- Day 15, 09:30 — Purchasing manager started the opening; finance confirmed at 09:34.
- Day 16, 10:05 — Purchasing manager selected A with the reason above; finance approved at 15:30.
Nothing is deleted; a correction is a new entry. Quotes are kept with the decision for as long as you must keep your accounting records; your accountant tells you whether unsuccessful quotes fall under that rule.
What does AI do, and where does it stop?
AI here does not choose a supplier, score bidders or calculate totals; it shortens three manual jobs, and a person approves every suggestion.
- Extracting lines and terms from PDF, Excel or email as suggestions. The app calculates totals and flags any mismatch with the quote’s own subtotal. In the example, 3 of 45 lines were corrected: C’s pack of 10 read as one piece, B’s “100M” not converted to metres, D’s “option 7 days” (validity) read as lead time.
- Matching to your lines: “PU HOSE 8X5.5 BLUE 100M” gets the suggestion “Line 5, PU air hose 8 mm, 1 roll = 100 m”. The buyer confirms or relinks; a confirmed match is the first suggestion on that supplier’s next quote.
- Missing-term flags: quotes without payment terms, tax status, delivery point or validity are flagged during the sealed period without showing prices, so the buyer can ask before the deadline.
Extracted prices stay sealed until opening, and no quote goes to the model for a user who may not see that request. A contact’s name and email in a quote are personal data; if the AI service runs in another jurisdiction, cross-border transfer rules apply (GDPR Chapter V in the EU and UK). Which data goes where is set in writing at the first step; I don’t give legal advice.
In Turkey, the method is the same: input VAT is deductible under Article 29 of VAT Law No. 3065, the Central Bank (TCMB) indicative rates can serve as the conversion source, data transfers abroad fall under KVKK Article 9 (amended 2024), and records are kept five years under the Tax Procedure Law and ten under the Commercial Code; the Turkish version cites each.
Where does a spreadsheet break, and how do you build one if you stay?
Staying in Excel or Google Sheets is often the right call. If you do, I suggest two sheets: raw quotes, with every line exactly as the supplier wrote it, and a comparison sheet with your line code, supplier, quantity, quoted unit price, conversion factor, tax status, tax rate, exchange rate and payment day, plus formula columns for net price per requested unit, base-currency unit price, line amount and present value. Finance writes the annual base-currency rate in cell R1 (0.10 for 10%) and the foreign-currency rate in R2; the exchange rate carries its date and source. Write the selection reason on a third sheet with name and date, and move the final file to a read-only folder.
Formulas for row 2 of the comparison sheet (English Excel). Columns: A2 line code, B2 supplier, C2 quantity in your unit, D2 quoted unit price (in the quote’s own unit), E2 conversion factor (how many of your units one quoted unit holds: 100 for a 100 m roll, 1 if the units match), F2 tax status (“incl” or “excl”), G2 tax rate stated on the quote (such as 0.20), H2 exchange rate (1 for base currency), I2 payment day:
- Net price per requested unit (J2):
=IF(F2="incl",D2/(1+G2),D2)/E2 - Base-currency unit price (K2):
=J2*H2 - Line amount (L2):
=K2*C2 - Present value, quote fixed in one currency (M2):
=L2/(1+$R$1*I2/365) - Quote floating in the foreign currency until invoice, fixed in base currency afterwards (like D):
=L2/(1+$R$2*N2/365)/(1+$R$1*O2/365); N2 days until invoice (21 for D), O2 credit days after invoice (90 for D). For D this gives 185,803.
The simplest seal: quotes go only to a shared mailbox, never to a personal address; nobody opens it before the deadline, and two people do the opening.
As requests, suppliers and people multiply, this breaks in specific places:
- Whoever sees the first price can tip off a rival. The first emailed quote opens in one inbox; telling another supplier “you’ll need to come down a bit” leaves no trace.
- Descriptions don’t match. A lookup won’t link “PU HOSE 8X5.5 BLUE 100M” to “PU air hose 8 mm”; matching is manual every time.
- Nobody tracks who changed the rate cell, or why.
- “Why this supplier?” has no answer months later. The reason is in an email, the comparison in version three of a file, the substitute’s rejection in a phone call.
The difference in the app I propose (a design proposal): a defined business rule is applied when the quote enters the table, not when someone checks the file later.
When your ERP’s purchasing module is enough
I wouldn’t suggest a custom app if:
- You make a few purchasing decisions a year with two or three quotes each: the spreadsheet setup above is enough.
- Your ERP’s purchasing module handles requests for quotation and your team uses it. In Microsoft Dynamics 365 Supply Chain Management, for example, RFQ replies can be scored and compared side by side, accept and reject reasons are stored, and lines can be awarded to different vendors (Microsoft Learn, read 14 October 2026); sealed bidding became generally available on 1 October 2021 (archived Microsoft release plan, read 14 October 2026); according to the current documentation, bid data and attachments stay encrypted until expiry, but the vendor has to enter the bid through the vendor portal with its own user, sealed attachments must be PDF, and questionnaire answers aren’t encrypted (Microsoft Learn, read 14 October 2026). For other ERPs we check the product documentation together; I haven’t verified every product.
Test your own ERP with three questions: (1) does it discount foreign-currency, deferred-payment quotes to present value, (2) does it hide prices until the deadline even from the buyer, (3) does it turn emailed PDFs into lines? If all three are yes, you don’t need a custom app.
A custom app makes sense when your suppliers won’t use an ERP portal and keep sending PDFs and emails, when comparing currency and payment terms on present value goes beyond the module, when requesters, buyers and finance aren’t ERP users, or when you want each decision’s reason in one place.
How do we start, who owns the data and code, and how do users sign in?
The first step is mapping how you buy today from three to five recent purchasing files (quotes, comparison sheet, selection email) and your authority matrix if you have one. The written output: your comparison rules and thresholds, the discount rate and FX source as finance decides them, roles and approval limits, past files recalculated under the new rules, and the scope of version one.
Start with a frequent, mid-sized purchase such as spares, not your largest negotiated contract. My order:
- Requests, invitations, sealed collection, two-person opening, restated table, selection reason and audit trail.
- Present value, exchange rates, gap filling and approval thresholds.
- AI extraction and matching suggestions.
- Price-history reports and order export to your ERP.
Data: The app runs on a hosted server (VPS), with server, keys and accounts in your company’s name if you wish. The data is yours, exportable in full as Excel or CSV. There is no per-user licence; the cost is the server’s monthly fee plus upkeep, unchanged by adding users in a small or mid-sized team.
Sign-in: Everyone in your company signs in with their own account; I give the sign-in method and user management in writing in the first step’s output. Suppliers don’t need accounts.
Code: The complete source sits in a repository you can access, with run instructions, a dependency list and known limits. Because the app handles suppliers’ commercial information and contacts’ personal data, I review access, security, hosting and maintenance separately at the start. If you change ERP, your data stays in your database and the order export has to be rebuilt for the new format; scope and schedule for that, as for version one, are shared in writing once I’ve seen how you work.
Send one comparison table from a recent purchase (names and prices changed), or just a note describing its structure, through the contact page; in the first meeting we check whether payment terms and exchange rates would have changed the ranking.
Frequently Asked Questions
Do suppliers need an account to submit quotes?
No. Suppliers can keep sending PDF or Excel quotes to the app’s dedicated address or an upload link. Accounts for regular suppliers are optional and agreed at the first step.
Should we evaluate quotes with a weighted score?
Turn everything that can be priced into money first. Criteria that can’t be priced (technical fit, delivery record, warranty) work better in separate columns or as pass/fail thresholds than blended with price in one score. A weighting such as “price 60%, quality 40%” hides how many quality points would justify a price gap such as the 645 between A and B in the example; in separate columns, that trade-off is written into the reason.
Does this work for services (maintenance contracts, freight, calibration)?
Yes, but the hard part changes from unit conversion to scope matching: one quote includes spare parts and another doesn’t, one offers four visits a year and another two. Scope items are written line by line, and a missing item is priced with the same gap rule.
Can we load old quotes and see price history?
Yes. Past files are matched to today’s lines, so each line shows its last price, supplier and exchange rate; AI suggests the extraction and the buyer confirms. If old files are scattered, start with the 20 to 30 most frequently bought lines.
How do I work?
Work-hour packages
Tell me about your business and what you need on WhatsApp or by phone; we agree on a work block of somewhere between 5 and 40 hours and I start doing what is needed. What you get is not a calendar window — it is net working hours spent directly on your business. I can use 40 hours working three days straight, or deliberately spread it out and finish it over a year — whatever the work calls for. I do not spend my time estimating how long something will take, I spend it doing the work; every hour I spend leaves a lasting result in your business. We keep going for as long as you find it useful.
Why not monthly?
Is 40 hours a week?
On a fixed monthly fee both sides are watching the wrong thing: you watch a fixed cost, the other side watches how many more contracts like this they can line up. Working by the hour puts us both in front of the same thing — the real value of the work that got done. I know not having an upfront answer to "how much will this cost in total?" is the natural cost of this model. But instead of paying a fixed fee for months to a setup that is not producing results, you only pay for the qualified time spent on your work — and you see exactly where that time went, start to finish. That is why my clients keep coming back.
