Skip to content

Delivered but not invoiced in Odoo: recover sleeping revenue

Maxime VanderhaeghePublished 9 min read

In short, "Delivered but not invoiced" revenue is goods that have reached the customer with no posted invoice to match. In Odoo it hides in three places: orders still marked "To Invoice" whose delivery is done, orders only partly invoiced after a partial delivery, and invoices left in draft. The Sales, To Invoice, Orders to Invoice menu shows most of it in a few clicks. The hard part isn't finding it once, it's looking at it every week.

Delivering without invoicing means giving your customer free credit with no end date. They have the goods, your stock has gone down, your carrier has been paid, and yet no receivable exists. Nobody chases this customer, because on paper they owe you nothing. The payment term hasn't even started running.

The gap stays invisible for a simple reason: every team is doing its job properly. The warehouse validates its delivery orders, sales moves on to the next deal, accounting invoices whatever it's told about. Unbilled revenue falls through the crack between the three, and no standard report puts it on the front page. It usually surfaces at month-end close, when the gap between stock shipped and sales booked won't reconcile, or when the customer asks why they never received an invoice.

Why delivered revenue stays unbilled in Odoo#

In Odoo, a sales order carries an invoice status, mainly "Nothing to Invoice", "To Invoice" or "Fully Invoiced". It's computed line by line from the ordered quantity, the delivered quantity and the quantity already invoiced. Several very concrete causes throw that calculation off.

The invoicing policy. Every product has an invoicing policy: "Ordered quantities" or "Delivered quantities". With delivered quantities, the order only becomes "To Invoice" as delivery orders get validated. That's the healthiest policy for physical goods, but it assumes someone comes back to the order after shipping. If nobody does, the order sits at "To Invoice" for months. With ordered quantities, the order is invoiceable as soon as it's confirmed, shipped or not: the list of orders to invoice then mixes delivered and undelivered orders, which makes it harder to read and easier to ignore.

Partial deliveries and backorders. An order for a hundred units, sixty shipped, a backorder of forty created automatically. You invoice the sixty, the backorder ships three weeks later, and nobody invoices it. The order says "To Invoice", but it already has an invoice attached: in a list, it looks handled.

Plain forgetting. In standard Odoo, the invoice for a goods order isn't created automatically when the delivery is validated. Someone has to click "Create Invoice", on the order or in bulk from the list. If that click depends on one person who is away or swamped, nothing happens.

Invoices created but never posted. The invoice was generated, then left in draft: an address to check, a price to confirm, a question to the salesperson that never got an answer. Here's the trap: for Odoo, a draft invoice already counts as invoiced in the order's calculation. The draft's quantities are no longer "to invoice": the order drops out of the orders to invoice list (it switches to "Fully Invoiced" if the draft covers the whole order), even though no invoice was ever sent.

Edge cases. A customer return that doesn't reduce the delivered quantity, a cancelled backorder on a product invoiced on ordered quantities: these leave an order at "To Invoice" with no real revenue to recover. They clutter the list and make people stop working it.

What it costs#

The first cost is cash. Every day between delivery and invoice adds to your real payment term: a customer on thirty-day terms who gets the invoice six weeks after delivery is actually paying you after more than two months.

The second cost is the risk of never getting paid. The later an invoice arrives, the more likely it is to be disputed: the customer can't find the goods receipt, the contact has moved on, the year's budget is closed. A delivery invoiced six months late gets negotiated. A delivery invoiced the next day gets paid.

The third cost is the reliability of your numbers. Monthly revenue is understated, margin is distorted (the goods have left your stock, the sale hasn't been booked), and steering decisions rest on a result that doesn't exist. That's one reason cash and receivables sit among the KPIs an SMB leader should read every Monday.

How much is at stake depends on your volume and your invoicing discipline. Rather than a theoretical figure, measure your own.

Finding it by hand in Odoo, step by step#

Everything below works in standard Odoo (Sales, Inventory and Invoicing or Accounting apps). The paths below may vary slightly depending on your Odoo version.

1. List the orders to invoice. Go to Sales, To Invoice, Orders to Invoice. This view filters confirmed orders whose invoice status is "To Invoice". Group by customer or salesperson to see where the problem concentrates, and sort by order date to bring the oldest to the top.

2. Separate delivered from undelivered. This is the step Odoo doesn't do for you. If your products use "Delivered quantities", an order at "To Invoice" necessarily contains something delivered: you can work it with confidence. If some products use "Ordered quantities", open the orders concerned and check the "Delivery" smart button at the top of the form, or the "Delivered" column on the lines. You can check the policy on the product form (the "Invoicing Policy" field, on the General Information tab), and the default is set in Sales, Configuration, Settings, Invoicing section.

3. Start from completed deliveries. For a warehouse-side check, go to Inventory, Operations, Deliveries (under the Transfers heading of the menu). Filter on the "Done" state and an effective date older than thirty days. The delivery order doesn't carry an invoice status of its own: you have to open the source order (the "Source Document" field or the link to the order) to check. At volume, export the deliveries with their order reference, export the orders to invoice, and match the two in a spreadsheet.

4. Put a number on what's left to invoice. The "Already invoiced" and "Amount to invoice" amounts (called "Un-invoiced Balance" depending on your Odoo version) are available through export. Watch out: in recent versions, you can't filter or sort the orders list on that amount directly in Odoo, which is why exporting is the way to rank orders by amount.

5. Hunt down drafts. Go to Invoicing (or Accounting), Customers, Invoices, and apply the "Draft" filter. Sort by creation date. Any invoice sitting in draft for more than a few days needs an explanation, because, as we saw, its order has already dropped off the orders to invoice list.

Let's be honest about the effort: steps 1 and 5 take a few minutes. Steps 2 to 4, across several hundred orders, take one to two hours of exports and spreadsheet work the first time. And standard Odoo has no "delivered thirty days ago, still no invoice" alert: if nobody asks the question, nobody gets the answer.

Fixing it, in order#

  1. Post the legitimate drafts. This is the quickest win: the invoice already exists. Review it, fix whatever was blocking, post it and send it. If the draft no longer has a reason to exist (duplicate, cancelled order), cancel or delete it so the order gets back to an accurate status.
  2. Invoice the oldest and largest delivered orders. From the orders to invoice list, select several orders and use the "Create Invoices" action to generate them in bulk (regular invoice option, to bill what's delivered and not yet invoiced). Review the resulting drafts before posting: it's your chance to catch a wrong price or address.
  3. Give the customer a heads-up when the delay is long. An invoice arriving three months after delivery deserves a short note.
  4. Clean up the false positives. Cancelled backorder on a product invoiced on ordered quantities, return not taken into account: correct the quantity on the order or issue the right credit note, and check the treatment with your accountant.
  5. Fix the root cause. Review the invoicing policy on your physical products. If you invoice goods on "Ordered quantities" out of habit rather than by choice, that's often where the mess starts.

One point that matters if you hand this search to a tool: at UpBoard, creating or posting an invoice in Odoo always goes through explicit human approval. A tool that finds forgotten revenue saves you time. A tool that invoices on your behalf with no control costs you time.

Keeping it from coming back#

Prevention comes down to three commitments.

A weekly routine. Every week, on a fixed day, one person opens the orders to invoice list and the draft invoices filter. Irregularity is what turns a short task into a multi-hour catch-up.

A named owner. Not "accounting" or "sales": one person. Whoever signs off the monthly close is often best placed, because they're the one who absorbs the gap at month-end. If your invoicing also has format or timing obligations, as in Belgium with e-invoicing, our Odoo invoicing compliance checklist for Belgium is worth going through at the same time.

An alert threshold decided in advance. For example: no delivery without a posted invoice beyond seven days, no draft invoice beyond three days. What matters is that it's written down and that any breach triggers an action, not a debate.

Conclusion#

Delivered but unbilled revenue doesn't show up in day-to-day work, because every team did its part. You find it by looking in three places: orders to invoice, completed deliveries with no invoice, draft invoices. You fix it by starting with what already exists (the drafts), then the oldest and largest amounts, and you prevent it with a weekly routine and a named owner.

If gathering the data is what has held you back so far, the UpBoard scan does this sweep for you: free, read-only on your Odoo, 92 checks, with a score you see before leaving any contact details. Three of those checks cover exactly this topic. The first flags outbound deliveries completed more than thirty days ago whose order is still "To Invoice" (an order shipped in several deliveries counts once, and the amount shown is the order total). The second lists confirmed orders dated more than sixty days ago that still have an amount to invoice, ranked by what's left to bill. The third surfaces customer invoices left in draft for more than thirty days. The scan detects and quantifies; you decide what gets invoiced.

See what your Odoo data has to tell you

A few minutes, read-only, no card. Then a trial on your real data: 14 days, or until the trial credit is used up.