FlowParse
Feature August 2026 15 min read

Cost code allocation

Cost code allocation is the mechanic underneath job costing: reading a supplier invoice line, finding the job number or PO reference behind it, and matching the two — split across multiple jobs on the same invoice when that's what the invoice actually shows.

FlowParse
flowparse.io

Allocation is a matching problem, not a math problem

Once an invoice line is read — description, amount, date — the hard part hasn't started yet. The hard part is figuring out which job it belongs to, and that turns out to be a matching problem: does this line carry a reference, does that reference point to a job you recognize, and if it doesn't point anywhere at all, what then?

This page describes exactly that mechanic — the logic that sits underneath job costing from vendor invoices, spelled out on its own because it's the part worth understanding in detail before trusting it with real cost data.

FlowParse
flowparse.io

Why one invoice line can be ambiguous

In the simplest case, a supplier prints your job number exactly as you gave it to them, on every line, every time. That case needs no cleverness at all. What makes allocation genuinely hard is everything short of that ideal.

A supplier might print only their own PO acknowledgment number, leaving the job reference to be looked up through the PO itself. A job number might be typed with a different hyphen convention, or truncated to fit a narrow invoice column. Two open jobs might have similar-looking numbers — 4471 and 4417 — where a single mistyped digit changes which job a real cost lands against. None of these are exotic edge cases; they're what a supplier base that doesn't share your exact numbering conventions produces routinely.

What gets read

FieldWhere it's checked
Job numberPrinted directly on the invoice line or header
PO numberPrinted on the invoice, resolved against the PO if uploaded
Cost code or GL accountWherever it appears — line description, header, or a dedicated field
Line description textScanned for a readable reference when no structured field carries one
FlowParse
flowparse.io

The matching hierarchy

Rather than trying every possible reference at once and picking whichever seems most likely, allocation follows a fixed order — the same order every time, so the same input always produces the same result.

1

A job number printed directly on the line

The strongest signal available. Matched with high confidence and no flag.

2

A PO number, resolved through the linked purchase order

Used when the invoice cites a PO rather than the job itself, and that PO's own job reference is available.

3

A partial or non-standard reference

Matched where the intent is reasonably clear, but flagged for a quick human confirm rather than accepted outright.

4

No usable reference found

Left unassigned, visible as its own group, never guessed from context.

A line never skips ahead in this order to grab a weaker match just because a stronger one wasn't found — if step one fails, step two is tried on its own merits, not as a consolation prize.

Splitting a single invoice across jobs

A stock supplier who ships materials for three open jobs on one delivery usually bills it as one invoice, with the job breakdown living in separate line items rather than as three distinct bills. Treating that invoice as one number and assigning the whole thing to a single job would overstate one job's cost and understate the other two — a distortion that compounds every time a similar invoice arrives.

Because each line runs through the matching hierarchy independently, an invoice with rows for job 4471, job 4483 and a shared shop consumable splits cleanly into exactly those three destinations. The invoice total is never the unit of allocation — the line is.

FlowParse
flowparse.io

Three confidence levels

Not every match is equally certain, and treating them all the same — either all trusted or all reviewed — wastes effort in one direction or risks silent errors in the other. Three levels keep that distinction visible.

LevelWhen
HighA clean, unambiguous job number or resolvable PO reference
MediumA readable but non-standard reference, or a PO resolved through an extra lookup step
Low / unassignedNo usable reference found anywhere on the line

For a batch of hundreds of lines, that distinction is what turns a full manual review into a review of the handful that actually need one — most of a month's invoices typically land at high confidence and need no attention at all.

FlowParse
flowparse.io

When a code genuinely isn't there

Some invoice lines were never going to have a job reference — a general shop supply purchase, a one-off equipment repair, an invoice from a supplier who simply doesn't include references on anything they send. Forcing a code onto those lines would be worse than leaving them unassigned, because it would misrepresent a shared or overhead cost as belonging to one specific job.

Those lines are read in full and kept in their own visible group rather than being pushed into whichever job happens to be open at the time. What happens to them next — coded to overhead, split by a rule, or assigned by someone who knows the context — is a decision made by a person, not by the matching logic.

Why the same supplier phrasing matters

A supplier who prints the job number the same way every single time is, without knowing it, doing a large part of the allocation work for you. Small, consistent formatting — even if it's not exactly your internal format — is far easier to match reliably than formatting that changes invoice to invoice from the same supplier.

For a supplier whose invoices consistently land at medium confidence or worse, a short note asking them to include the job number in a specific, consistent spot is usually more effective than any adjustment on the reading side — the cleanest fix to an allocation problem is often at the source, not downstream of it.

A supplier that bills in a different currency

A shop sourcing a specialty material or outside process from a supplier abroad receives an invoice in a currency different from its own reporting currency. The job reference on that invoice matches exactly the same way as a domestic one — currency doesn't affect whether a job number or PO reference is found and matched.

The amount itself is read and recorded in the currency and figure printed on the invoice, kept alongside the match rather than silently converted to a different currency during allocation — currency conversion, if a job needs it for reporting, is a decision made downstream with the exchange rate applicable at the time, not baked into the matching step itself.

How it works

1

Upload invoices and any related POs

Whatever the supplier sent, plus purchase orders where an invoice only cites a PO.

2

Each line is read

Description, amount, and every candidate reference found on it.

3

The matching hierarchy runs

Job number, then PO reference, then partial match, then unassigned — in that fixed order.

4

Export

Excel, CSV or JSON, with confidence levels and source documents kept per line.

FlowParse
flowparse.io

A job number written by hand on a packing slip

Not every job reference arrives as clean printed text. A packing slip with a job number scrawled in marker by a receiving clerk, or a supplier invoice with a handwritten annotation added after the fact, is read through the same OCR pipeline as any scanned document — legible handwriting is matched; illegible handwriting is flagged rather than guessed at.

A digit that could be a 4 or a 9 is exactly the kind of ambiguity that gets surfaced rather than resolved by picking whichever job seems more likely — because in a job shop with both job 4471 and job 9471 open at once, that guess has real consequences.

What you get back

One row per invoice line

Job reference, amount and confidence level, each in its own column.

Unassigned lines kept separate

Visible as their own group, not folded into whichever job was open.

Traceable to source

Every row linked back to the invoice — and PO, where used — it came from.

Who this is for

Mostly useful for shops with more than a handful of open jobs at once, where matching invoices to jobs by hand has stopped being a quick task: job shops and contract manufacturers running several concurrent jobs, controllers closing a monthly job-cost report, and bookkeepers coding invoices across multiple manufacturing clients each with their own job numbering.

It's less useful for a shop running one job at a time from start to finish, where every invoice unambiguously belongs to whatever's currently in progress — the matching hierarchy still works, it just doesn't solve a problem that single-job operation doesn't really have.

Somewhere in between sits the shop that mostly runs one job at a time but occasionally overlaps two — a rush order squeezed in alongside a longer-running job. That's exactly the case where allocation earns its keep most, since it's also the case most likely to trip up a habit built around assuming there's only ever one job to worry about.

How many invoices in one pass

A single invoice or two is easy enough to check by eye — the value of a fixed matching hierarchy shows up once the volume grows past what anyone would want to review line by line. A month's worth of invoices across a dozen suppliers, run through the same hierarchy in one batch, produces a consistent result regardless of whether it's ten lines or a thousand.

Up to 100 documents can be processed per export, which in practice covers a full month's invoice volume for most job shops in a single pass — no need to break a batch into smaller uploads to keep the matching manageable.

Why every match traces back to its source

A job's cost total is only as trustworthy as the ability to explain where each dollar of it came from. Every allocated line keeps a link back to the exact invoice — and PO, where one was used to resolve the match — that produced it, so a question about a specific job's cost months later has a concrete answer rather than requiring a fresh search through old paperwork.

That traceability matters most at the moment a job's cost gets questioned — a customer disputing a change order, an owner reviewing margin on a job that ran over, an accountant preparing year-end financials. Being able to point at the exact invoice behind a number is worth more, in that moment, than the time saved by matching in the first place.

Correcting a match after the fact

A line matched with high confidence can still turn out to be wrong — a job number that happened to be valid but belonged to a different job than the one actually intended, discovered only when someone reviewing the job's total notices a cost that doesn't fit what the job actually involved.

Correcting that isn't a special operation — it's the same as coding any other line, just applied after the fact rather than at the moment the invoice first arrived. The corrected line keeps its link back to the original invoice, so the history of the correction — what it was matched to before, what it's matched to now — stays visible rather than silently overwritten.

That visibility matters more than it might seem at first. A job-cost report that changes between two viewings without any record of why is far more worrying than one where a correction is clearly logged, dated and explained. The former erodes trust in every number the report shows; the latter is just normal bookkeeping hygiene.

Where this stops

Cost code allocation matches lines to references that already exist — it doesn't assign a code, decide direct versus overhead, or replace the job-costing logic in your ERP. Those decisions, and the full picture of how matched data becomes a job-cost report, are covered in job costing from vendor invoices.

Kept to that narrow scope, allocation stays predictable — the same input always produces the same match, which is worth more over time than a cleverer system that occasionally guesses right but can't explain why.

That predictability is, in the end, the whole point of a mechanic like this: a shop that trusts its cost data because it can explain every number, not because it hopes the numbers happen to be right.

Frequently asked questions

See how a real invoice batch allocates

Upload an invoice or two — no signup — and see how the matching hierarchy behaves against your own job numbers.

Keep reading