<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
  <title>VioPO Blog</title>
  <subtitle>Articles from VioPO on purchase order processing, order entry and document AI.</subtitle>
  <id>https://viopo.co.uk/</id>
  <link rel="alternate" type="text/html" href="https://viopo.co.uk/blog/"/>
  <link rel="self" type="application/atom+xml" href="https://viopo.co.uk/feed.xml"/>
  <updated>2026-10-04T07:20:00Z</updated>
  <author>
    <name>VioPO</name>
    <uri>https://viopo.co.uk/</uri>
  </author>
  <entry>
    <title>Automating sales order entry from customer POs</title>
    <id>https://viopo.co.uk/blog/automate-sales-order-entry/</id>
    <link rel="alternate" type="text/html" href="https://viopo.co.uk/blog/automate-sales-order-entry/"/>
    <published>2026-10-04T07:20:00Z</published>
    <updated>2026-10-04T07:20:00Z</updated>
    <category term="order-entry" label="Order entry"/>
    <category term="how-to" label="How to"/>
    <summary>A practical workflow for suppliers to turn emailed customer purchase orders into sales orders automatically, and keep a person on the orders that need one.</summary>
    <content type="html" xml:base="https://viopo.co.uk/blog/automate-sales-order-entry/">&lt;p&gt;Most B2B suppliers receive the bulk of their orders the same way: a PDF attached to an email, sent to a shared mailbox. This article describes a workflow for getting those orders into your system without retyping them, and without losing the checks a good order desk applies.&lt;/p&gt;
&lt;h2 id=&quot;the-shape-of-the-workflow&quot;&gt;The shape of the workflow&lt;a class=&quot;anchor&quot; href=&quot;#the-shape-of-the-workflow&quot; aria-label=&quot;Link to this section&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Collect the attachments from the order mailbox.&lt;/li&gt;
&lt;li&gt;Read each one into structured data.&lt;/li&gt;
&lt;li&gt;Match the customer and the products to your own records.&lt;/li&gt;
&lt;li&gt;Decide: post automatically, or send to a person.&lt;/li&gt;
&lt;li&gt;Create the sales order.&lt;/li&gt;
&lt;li&gt;Keep a record of what happened to each order.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Steps 1, 3, 5 and 6 are ordinary integration work. Step 2 is the hard one, and step 4 is the one that decides whether you can trust the rest.&lt;/p&gt;
&lt;h2 id=&quot;1-collecting-attachments&quot;&gt;1. Collecting attachments&lt;a class=&quot;anchor&quot; href=&quot;#1-collecting-attachments&quot; aria-label=&quot;Link to this section&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Most mail platforms can forward or expose attachments to a script. Common options are a rule that forwards to an automation tool, a scheduled job that reads the mailbox over IMAP or the Microsoft Graph API, or the attachment trigger in an integration platform you already use. Keep the original email with each order so a person can see the context if needed.&lt;/p&gt;
&lt;p&gt;Skip what is clearly not an order: email signatures, logos, terms and conditions. File type and size filter most of these. A model will also tell you when a document does not look like an order; VioPO returns &lt;code&gt;is_purchase_order: false&lt;/code&gt; in that case.&lt;/p&gt;
&lt;h2 id=&quot;2-reading-the-order&quot;&gt;2. Reading the order&lt;a class=&quot;anchor&quot; href=&quot;#2-reading-the-order&quot; aria-label=&quot;Link to this section&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Send each PDF or image to the extraction API. With VioPO that is one request to &lt;code&gt;POST /v1/extract&lt;/code&gt;, and the response holds the header, parties, addresses, lines and totals in a &lt;a href=&quot;https://viopo.co.uk/docs/#the-output-format&quot;&gt;fixed format&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;3-matching-to-your-records&quot;&gt;3. Matching to your records&lt;a class=&quot;anchor&quot; href=&quot;#3-matching-to-your-records&quot; aria-label=&quot;Link to this section&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The order tells you what the customer printed. Your system needs its own ids.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Customer.&lt;/strong&gt; Match on VAT number or company number first, then on the account reference the customer uses for you, then on name. Names alone are unreliable: &amp;quot;Northgate Joinery Ltd&amp;quot; and &amp;quot;NORTHGATE JOINERY LIMITED&amp;quot; are the same customer.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Delivery address.&lt;/strong&gt; Match against the customer&amp;#39;s known delivery addresses by postcode, then by street. A new delivery address is worth a person&amp;#39;s look.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Products.&lt;/strong&gt; If the customer prints your part numbers, match on those. If they print only their own, keep a cross-reference table per customer. Build it as you go: each time a person resolves an unknown part number, save the pair.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Units.&lt;/strong&gt; Convert the customer&amp;#39;s unit to yours. Watch for pack sizes: &amp;quot;box of 200&amp;quot; against a product you sell each.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;4-deciding-what-to-post&quot;&gt;4. Deciding what to post&lt;a class=&quot;anchor&quot; href=&quot;#4-deciding-what-to-post&quot; aria-label=&quot;Link to this section&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This is the step that makes automation safe. Post an order automatically only when all of these hold:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;every arithmetic check passed (line amounts, lines to subtotal, total);&lt;/li&gt;
&lt;li&gt;there are no warnings;&lt;/li&gt;
&lt;li&gt;the customer, the delivery address and every product matched;&lt;/li&gt;
&lt;li&gt;prices agree with your price list or the quoted prices, within a tolerance you choose.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Everything else goes to a review queue, with the PDF and the extracted data side by side, and the reason it was held. In most order books a minority of orders need a look, and the order desk spends its time on those instead of on typing.&lt;/p&gt;
&lt;h2 id=&quot;5-creating-the-sales-order&quot;&gt;5. Creating the sales order&lt;a class=&quot;anchor&quot; href=&quot;#5-creating-the-sales-order&quot; aria-label=&quot;Link to this section&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Use your ERP&amp;#39;s import or API. Put the customer&amp;#39;s PO number in the field your system prints on delivery notes and invoices, so it flows through to the documents the customer expects.&lt;/p&gt;
&lt;h2 id=&quot;6-keeping-a-record&quot;&gt;6. Keeping a record&lt;a class=&quot;anchor&quot; href=&quot;#6-keeping-a-record&quot; aria-label=&quot;Link to this section&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Store the request id, the decision and who approved it. When a customer queries an order months later, you want to see what was read, what was posted, and why.&lt;/p&gt;
&lt;h2 id=&quot;start-small&quot;&gt;Start small&lt;a class=&quot;anchor&quot; href=&quot;#start-small&quot; aria-label=&quot;Link to this section&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Run the reading step alongside your current process for a week or two. Compare what was read with what your team keyed. You will see quickly which customers&amp;#39; orders read cleanly and where your matching tables need work.&lt;/p&gt;
&lt;p&gt;VioPO is not open yet. You can see &lt;a href=&quot;https://viopo.co.uk/try/&quot;&gt;its output on three sample orders&lt;/a&gt; now, and &lt;a href=&quot;https://viopo.co.uk/waitlist/&quot;&gt;join the waitlist&lt;/a&gt; to hear when you can send your own. The Free plan at launch reads 50 pages a month.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>How to extract data from purchase order PDFs</title>
    <id>https://viopo.co.uk/blog/extract-data-from-purchase-order-pdfs/</id>
    <link rel="alternate" type="text/html" href="https://viopo.co.uk/blog/extract-data-from-purchase-order-pdfs/"/>
    <published>2026-10-04T07:10:00Z</published>
    <updated>2026-10-04T07:10:00Z</updated>
    <category term="document-ai" label="Document AI"/>
    <category term="po-processing" label="PO processing"/>
    <summary>Four ways to get order data out of PDF purchase orders, from typing to templates, OCR and vision language models, with what each costs and where each breaks.</summary>
    <content type="html" xml:base="https://viopo.co.uk/blog/extract-data-from-purchase-order-pdfs/">&lt;p&gt;If your customers send purchase orders as PDFs, someone or something has to turn each one into data your order system can use. There are four ways to do it. Each has a place, and each fails in its own way.&lt;/p&gt;
&lt;h2 id=&quot;1-typing-them-in&quot;&gt;1. Typing them in&lt;a class=&quot;anchor&quot; href=&quot;#1-typing-them-in&quot; aria-label=&quot;Link to this section&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The default. A person opens the PDF and keys the order.&lt;/p&gt;
&lt;p&gt;It works on any layout, needs no software, and a good order desk catches odd things a machine would not, such as a price that does not match the quote.&lt;/p&gt;
&lt;p&gt;It is slow, and it does not scale with volume. Errors are rare per field but there are a lot of fields: an order with 20 lines has well over 100 values to key. The mistakes that get through tend to be the costly kind, such as a transposed digit in a quantity or a delivery sent to the invoice address.&lt;/p&gt;
&lt;h2 id=&quot;2-templates&quot;&gt;2. Templates&lt;a class=&quot;anchor&quot; href=&quot;#2-templates&quot; aria-label=&quot;Link to this section&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A template tells the software where each field sits on one customer&amp;#39;s layout: the order number is in this box, the lines are in this table between these columns.&lt;/p&gt;
&lt;p&gt;For a handful of large customers who send the same layout every time, templates are accurate and cheap to run.&lt;/p&gt;
&lt;p&gt;They break when the layout changes, and layouts change whenever a customer updates their ERP, edits their form or exports from a different system. Every new customer needs a new template. With a long tail of customers, maintaining templates becomes a job of its own.&lt;/p&gt;
&lt;h2 id=&quot;3-ocr-plus-rules&quot;&gt;3. OCR plus rules&lt;a class=&quot;anchor&quot; href=&quot;#3-ocr-plus-rules&quot; aria-label=&quot;Link to this section&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;OCR (optical character recognition) turns the page image into text. Rules or regular expressions then look for fields: a number after &amp;quot;PO No.&amp;quot;, a date near &amp;quot;Order date&amp;quot;.&lt;/p&gt;
&lt;p&gt;OCR is mature and reads clean print very accurately. The trouble is structure. Tables come out as lines of words with the columns lost, and two address boxes side by side are often read across, so their lines interleave. The rules that find fields are, in effect, templates written in a different way, and they fail in the same places.&lt;/p&gt;
&lt;p&gt;If your PDFs come from software they usually have a text layer already, and you can skip OCR and read the text directly. The structure problem stays.&lt;/p&gt;
&lt;h2 id=&quot;4-vision-language-models&quot;&gt;4. Vision language models&lt;a class=&quot;anchor&quot; href=&quot;#4-vision-language-models&quot; aria-label=&quot;Link to this section&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A vision language model takes the page image and an instruction, and answers in text. Asked to fill a fixed JSON structure, it reads the page much as a person does: it sees that a table has columns, that one box is labelled &amp;quot;Deliver to&amp;quot; and another &amp;quot;Invoice to&amp;quot;, and that &amp;quot;Q-55120&amp;quot; next to &amp;quot;Your quote&amp;quot; is a quote reference.&lt;/p&gt;
&lt;p&gt;The advantage is that there is no template. A layout the model has never seen is handled the same way as a familiar one.&lt;/p&gt;
&lt;p&gt;The risks are different from OCR&amp;#39;s:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;It can be wrong with confidence.&lt;/strong&gt; A model may put a value in the wrong field, or occasionally produce a value that is not on the page. Instructions help (&amp;quot;use null when a value is not present&amp;quot;) but do not remove the risk.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Formats drift.&lt;/strong&gt; Left to itself, a model writes dates and amounts however they appeared. You need a fixed schema and a step afterwards that normalises dates, numbers and codes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cost and privacy.&lt;/strong&gt; Hosted model APIs charge per token, and send your customers&amp;#39; orders to a third party.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The fix for the first two is to treat the model&amp;#39;s output as a reading to be checked, not as the answer. Purchase orders are good for this because they check themselves: quantity times unit price should equal each line amount, the lines should sum to the subtotal, and the subtotal plus tax and carriage should equal the total. A misread digit almost always breaks one of those sums.&lt;/p&gt;
&lt;h2 id=&quot;which-to-use&quot;&gt;Which to use&lt;a class=&quot;anchor&quot; href=&quot;#which-to-use&quot; aria-label=&quot;Link to this section&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;A few customers, steady layouts, low volume: typing, or templates.&lt;/li&gt;
&lt;li&gt;Many customers, changing layouts: a vision model with a fixed schema, normalisation and arithmetic checks, and a person reviewing only the orders that fail a check.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That second approach is what &lt;a href=&quot;https://viopo.co.uk/&quot;&gt;VioPO&lt;/a&gt; does, with the model running on hardware we operate rather than a third party&amp;#39;s API. It is not open yet, but you can see &lt;a href=&quot;https://viopo.co.uk/try/&quot;&gt;its output on three sample orders&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>What is on a purchase order? The fields that matter</title>
    <id>https://viopo.co.uk/blog/what-is-on-a-purchase-order/</id>
    <link rel="alternate" type="text/html" href="https://viopo.co.uk/blog/what-is-on-a-purchase-order/"/>
    <published>2026-10-04T07:00:00Z</published>
    <updated>2026-10-04T07:00:00Z</updated>
    <category term="po-processing" label="PO processing"/>
    <category term="order-entry" label="Order entry"/>
    <summary>The parts of a purchase order, what each one is for, and which fields a supplier needs to read correctly before an order can be shipped and invoiced.</summary>
    <content type="html" xml:base="https://viopo.co.uk/blog/what-is-on-a-purchase-order/">&lt;p&gt;A purchase order is a buyer&amp;#39;s written offer to buy goods or services on stated terms. Once the supplier accepts it, it is the contract for that sale. Every later step leans on it: the warehouse picks against it, the delivery note quotes it, and the buyer&amp;#39;s accounts team will not pay an invoice that does not match it.&lt;/p&gt;
&lt;p&gt;No two companies lay one out the same way, but almost every purchase order carries the same few groups of information.&lt;/p&gt;
&lt;h2 id=&quot;the-header&quot;&gt;The header&lt;a class=&quot;anchor&quot; href=&quot;#the-header&quot; aria-label=&quot;Link to this section&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The header identifies the order.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Order number.&lt;/strong&gt; The buyer&amp;#39;s reference. It is the single most important field, because the buyer will expect it on the delivery note and the invoice. Many accounts teams return invoices without a valid PO number unpaid.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Order date.&lt;/strong&gt; When the order was raised. It matters for price validity and for matching later.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Revision.&lt;/strong&gt; Some systems issue amended orders with the same number and a revision or change number. Treat a revised order as replacing the old one, not adding to it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Quote reference.&lt;/strong&gt; If the order accepts a quote you sent, it should say which. That is how you know the prices on the order should be the ones you offered.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Currency.&lt;/strong&gt; Often only shown as a symbol on the amounts.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Requested delivery date.&lt;/strong&gt; For the whole order, or per line.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;the-parties&quot;&gt;The parties&lt;a class=&quot;anchor&quot; href=&quot;#the-parties&quot; aria-label=&quot;Link to this section&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;strong&gt;buyer&lt;/strong&gt; is the organisation placing the order. Its name usually sits in the letterhead, often with a VAT number and company number. A person named beside &amp;quot;Buyer&amp;quot; or &amp;quot;Ordered by&amp;quot; is the contact, not the customer.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;supplier&lt;/strong&gt; (or vendor) is you. The order may include your account number in the buyer&amp;#39;s system, which you will need to quote back on the invoice.&lt;/p&gt;
&lt;h2 id=&quot;the-addresses&quot;&gt;The addresses&lt;a class=&quot;anchor&quot; href=&quot;#the-addresses&quot; aria-label=&quot;Link to this section&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There are usually two that matter, and mixing them up is a common and expensive mistake.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Delivery address&lt;/strong&gt; (&amp;quot;Ship to&amp;quot;, &amp;quot;Deliver to&amp;quot;). Where the goods go. Often a warehouse, a site or a specific goods-in door, sometimes with delivery hours.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Invoice address&lt;/strong&gt; (&amp;quot;Bill to&amp;quot;, &amp;quot;Invoice to&amp;quot;). Where the invoice goes. Increasingly this is an email address for an accounts payable mailbox rather than a postal address.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When an order says &amp;quot;deliver to the address above&amp;quot;, the delivery address is the buyer&amp;#39;s own.&lt;/p&gt;
&lt;h2 id=&quot;the-lines&quot;&gt;The lines&lt;a class=&quot;anchor&quot; href=&quot;#the-lines&quot; aria-label=&quot;Link to this section&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Each line is one item:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a part number, either the buyer&amp;#39;s own code, yours, or both;&lt;/li&gt;
&lt;li&gt;a description;&lt;/li&gt;
&lt;li&gt;a quantity and a unit of measure: each, box, pair, case, metre;&lt;/li&gt;
&lt;li&gt;a unit price, sometimes with a discount;&lt;/li&gt;
&lt;li&gt;a line amount;&lt;/li&gt;
&lt;li&gt;sometimes a tax rate and a delivery date for that line only.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Units cause more trouble than they should. &amp;quot;Box of 200&amp;quot; priced per box is very different from 200 screws priced each.&lt;/p&gt;
&lt;h2 id=&quot;the-totals&quot;&gt;The totals&lt;a class=&quot;anchor&quot; href=&quot;#the-totals&quot; aria-label=&quot;Link to this section&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Subtotal, any discount, carriage, tax and the total. These are the figures the buyer expects to see on your invoice. They are also the easiest way to catch a mistake: if the lines do not add up to the subtotal, either the order is wrong or it was read wrongly.&lt;/p&gt;
&lt;h2 id=&quot;terms-and-instructions&quot;&gt;Terms and instructions&lt;a class=&quot;anchor&quot; href=&quot;#terms-and-instructions&quot; aria-label=&quot;Link to this section&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Payment terms (&amp;quot;30 days end of month&amp;quot;, &amp;quot;Net 45&amp;quot;), shipping method, Incoterms for international orders, and free-text instructions such as delivery windows or &amp;quot;quote our PO number on all invoices&amp;quot;. These are easy to skip and often the reason an invoice is rejected.&lt;/p&gt;
&lt;h2 id=&quot;why-the-fields-matter-more-than-the-layout&quot;&gt;Why the fields matter more than the layout&lt;a class=&quot;anchor&quot; href=&quot;#why-the-fields-matter-more-than-the-layout&quot; aria-label=&quot;Link to this section&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;From the supplier&amp;#39;s side, the job is to get these fields out of the document and into your own system without changing any of them. The layout around them changes with every customer; the fields do not. That is the idea behind &lt;a href=&quot;https://viopo.co.uk/&quot;&gt;VioPO&lt;/a&gt;: whatever the document looks like, the output has the same &lt;a href=&quot;https://viopo.co.uk/docs/#the-output-format&quot;&gt;fields&lt;/a&gt;, in the same format, with checks that the figures add up.&lt;/p&gt;
</content>
  </entry>
</feed>
