← Back to Blog
Automation by

How a 2-Week PoC Changed a 6-Month Project Estimate

How a 2-Week PoC Changed a 6-Month Project Estimate

A procurement automation project initially scoped at 6 months was reframed in 2 weeks. Real Odoo data, real accuracy numbers, and a conversation that changed the moment there was something to measure.

Key Takeaways: A 6-month procurement automation project was reframed after a 2-week PoC identified which 20% of the original scope delivered 80% of the value. Three months of real purchase.order and account.move data produced a working prototype with measurable accuracy. Once there was a number on the table, scope debates collapsed — the conversation shifted from abstract requirements to evidence-based decisions. The project that shipped was smaller than originally proposed, launched faster, and cost less.

The Original Brief

The client was a mid-size distributor in Ho Chi Minh City managing procurement across 40+ active suppliers. Their procurement team spent roughly 15 hours a week on manual tasks: matching purchase orders to delivery notes, reconciling discrepancies against vendor invoices in Odoo, and chasing approvals stuck in email threads.

The initial proposal covered six months of work: automated three-way matching across purchase.order, stock.picking, and account.move; a custom approval routing engine based on supplier tier and PO value; a vendor portal with real-time status updates; integration with the client’s legacy document management system; and automated exception reporting by email.

On paper, it addressed everything the procurement team had raised. That was the problem. A proposal that covers everything you’ve heard rarely reflects what’s actually causing the most pain.

Narrowing the Hypothesis

Before committing to six months, we asked a more targeted question: which part of this scope, if it worked, would eliminate the most friction?

The procurement manager’s answer was immediate. Matching. Their team spent 60% of manual time on three-way matching — comparing what was ordered, what was received, and what the vendor billed. The portal, the routing engine, the legacy integration — those were real problems, but they weren’t the daily grind.

The PoC hypothesis: if we could automate three-way matching on high-confidence cases and route exceptions for human review, we could eliminate most of the manual work without touching the rest of the original scope.

That’s a testable claim. Two weeks, real data, and you have an answer.

The narrowing step is easy to skip when you’re under pressure to show a comprehensive plan. We’ve written about why resisting that pressure matters in our PoC sprint methodology post. The short version: comprehensive proposals optimize for approval, not for learning.

Two Weeks, Three Months of Data

We pulled three months of historical records: 847 purchase.order entries, corresponding stock.picking data, and 912 account.move records on the vendor payables side. The gap between order count and invoice count — 65 extra invoices — was itself informative. Most were recurring service charges the team handled ad hoc, outside the standard procurement flow.

The matching logic was straightforward Python. It didn’t need to be clever. The matching problem turned out to be mostly deterministic: the same vendor reference appears on the PO and the invoice, quantities match within a 2% tolerance, and currency conversion uses the exchange rate from the transaction date. That pattern covers a large fraction of cases without any machine learning at all.

def match_po_to_invoice(po: dict, invoice: dict, tolerance: float = 0.02) -> dict:
    """
    Match a purchase.order to an account.move by vendor reference and amount.
    Returns confidence score and exception flag.
    """
    result = {
        "po_id": po["id"],
        "invoice_id": invoice["id"],
        "matched": False,
        "confidence": 0.0,
        "flag": None,
    }

    # Vendor reference match
    if po.get("partner_ref") and po["partner_ref"] == invoice.get("ref"):
        result["confidence"] += 0.5

    # Amount comparison within tolerance
    po_total = po["amount_total"]
    inv_total = invoice["amount_untaxed"]
    delta = abs(po_total - inv_total) / max(po_total, 1)

    if delta <= tolerance:
        result["confidence"] += 0.4
    elif delta <= 0.10:
        result["confidence"] += 0.2
        result["flag"] = "amount_discrepancy"

    result["matched"] = result["confidence"] >= 0.8
    return result

On a held-out test set of 200 invoices, the logic auto-matched 156 — 78%. Of the 44 exceptions, 31 were genuine discrepancies the team would have reviewed manually anyway. Thirteen were matching failures caused by inconsistent vendor reference formatting: some vendors included a prefix, some didn’t. A normalisation step before matching fixed most of those.

After normalisation, the auto-match rate reached 84%.

The Number That Changed the Meeting

At the end of week two, we had a number. Not a diagram. Not a featureAn individual measurable property or characteristic of the data used as input to a model. Feature engineering — selecting, transforming, and creating features — is a critical step in the ML pipeline. list. A number.

84% auto-match rate. Average processing time for matched invoices: under a second. Estimated manual review time for the flagged 16%: around 3 hours per week, down from 15.

The client’s finance team ran the ROI calculation themselves. At roughly 300 invoices per month, the team was spending 60 hours on three-way matching. The prototype reduced that to around 10. At their blended staff cost, the break-even on a production build was under 4 months.

None of that was estimated. It came from their data.

When a project decision is grounded in a number from real data, the conversation changes. The vendor portal debate — which had consumed two meetings during the original scoping — dropped out entirely. Nobody was arguing about features in the abstract. They were looking at an ROI modelA mathematical function trained on data that maps inputs to outputs. In ML, a model is the artifact produced after training — it encapsulates learned patterns and is used to make predictions or… they’d built themselves, with inputs from the PoC output.

This shift is the real deliverable of a well-run PoC. The prototype proved a point; the number closed the debate.

What Got Cut — and Why

The production project that followed was substantially smaller than the original proposal and shipped in 6 weeks.

What made it in: the matching engine, exception routing to a dedicated Odoo inbox (a filtered view on account.move, not a custom portal), and a weekly exception report exported to Excel. The procurement team already lived in Excel — adding another interface wasn’t worth the transition cost.

What didn’t make it:

  • The vendor portal. Fewer than 10 suppliers were responsible for 70% of invoice volume. A portal serving 40+ vendors wasn’t justified by the actual distribution of work.
  • The legacy document management integration. The client agreed that problem needed a standalone solution, not an ERP integration shim.
  • The custom approval routing engine. Once three-way matching removed the volume of manual exceptions, Odoo’s existing approval rules covered 90% of remaining cases.

This is the pattern that AI roadmapping surfaces when you start with the bottleneck: original scope is comprehensive because no one wants to be blamed for missing a requirement. The PoC forces a different question — not “what should we build?” but “what’s actually causing the most pain and can we prove we can fix it?”

Three Things This Project Confirmed

Auto-match rate is not the right primary metric. 84% sounds solid. But the team’s actual frustration was the 23-day average resolution time for disputed invoices, not overall throughput. Once exception routing was in place, median resolution time dropped to 4 days. That’s the outcome that mattered — and it wouldn’t have surfaced if we’d only measured auto-match rate.

The messy 16% is the product. Any matching engine gets the easy cases right. What determines whether the system actually reduces work is how it handles the exceptions it can’t resolve. Bad exception handling — dumping unmatched invoices into a generic queue — would have recreated exactly the manual pile the automation was meant to eliminate.

Scope without an owner becomes shelfware. The vendor portal died when we asked who would own supplier onboarding. Nobody volunteered. That’s the right outcome. A featureAn individual measurable property or characteristic of the data used as input to a model. Feature engineering — selecting, transforming, and creating features — is a critical step in the ML pipeline. with no owner doesn’t ship successfully even when it’s technically built.

The scoping document for the original 6-month project ran to 34 pages. The post-PoC specification was 8. The difference wasn’t less rigour. It was the removal of requirements the PoC showed were either lower priority than assumed or solvable with Odoo out of the box.


At Trobz, we run structured 2-week PoCs before committing to any automation project — because the first number from real data tells you more than a month of requirements workshops. If you’re scoping a procurement or finance automation project and want to know what a PoC would look like for your data, get in touch.

Ready to put AI to work?

Let's explore how Trobz AI can automate your processes, enhance your ERP, and help your team make better decisions — faster.