Skip to content

Automation · Collections and receivables

Create a draft customer invoice in Odoo with approval

Create a draft invoice in Odoo after explicit approval, verify its data, and read it back without posting it or sending it to a tax authority.

How do I create and review a draft invoice in Odoo before posting it?

A Met identifies the company, customer, and each product variant in Odoo before preparing a customer invoice. It reads the base price, taxes, and journals for that company, then separates two paths: using Odoo's configured defaults or sending previously authorized manual precio_unitario and impuesto_ids values. It creates an opaque reference with no personal data, checks existing drafts, and presents every input in one message. Only an explicit yes in a new message enables one call with tipo=out_invoice and confirmar=true. The Met then reads the invoice by id and returns Odoo's literal state, lines, currency, and totals. The result remains a draft. It is not posted, sent to a tax authority, or marked as paid.

What starts it

When someone asks for it

It starts when a person asks to prepare an invoice for a sale or service that is already approved for billing. It does not start from a price request or quotation conversation. The operator opens the task, supplies the agreed date and terms, and keeps posting as a later workflow outside this recipe.

A manual task: someone on the team runs it with a button, or asks the Met for it in chat.

Who runs it

Odoo invoicing Met

Finance and operations team

This is not a named, seeded Met. Its job is to prepare a reviewable accounting document from existing masters and stop before the action that creates accounting or tax effects. It does not negotiate the sale or replace approval from the person accountable for invoicing.

What you need connected

7 steps · 11 tools

The procedure, step by step

Each step shows the tool that runs. They belong to the real connector: if one of them stopped existing, this page would not build.

  1. 1

    Fix the company and open the exact customer

    The Met lists accessible companies and fixes one compania_id for every later call, even when the technical user has a default company. It searches the party by name, tax id, email, or phone and reads the candidate by id. It verifies the customer, active state, and identity instead of trusting a partial match. If results are ambiguous or the customer does not exist, it stops. This recipe does not create or modify parties.

  2. 2

    Resolve products and read their current configuration

    Each item is resolved against product.product by name, internal reference, or barcode. The Met reads the selected variant and requires it to be active and sellable. It then reads precio_venta, currency, unit, and impuestos_venta_ids with odoo_consultar_precio. That value is the product's base price, not a customer-specific quotation, so it does not become a manual precio_unitario by default. If billing needs a missing variant, free-form line, or manually selected account, the flow stops because the tool does not support those inputs.

  3. 3

    Choose Odoo defaults or authorized manual values

    The Met lists sales taxes and sale journals for the company so every id has a name and company. In default mode it sends only producto_id and quantity. Odoo obtains the product price, applies configured taxes and the customer's fiscal position, selects a sales journal, and derives the income account from the product, category, or journal. In manual mode it includes precio_unitario and/or impuesto_ids only when the operator supplies and authorizes exact, finite, non-negative values. No discount, withholding, or free-form account is implied. A manual diario_id is used only when the list confirms type sale and the same company.

  4. 4

    Prepare an opaque reference and the review

    The Met creates a random external reference for this attempt, such as MET-INV followed by meaningless characters. It contains no name, tax id, email, phone, or other personal data. The Met pages through odoo_listar_facturas in the agreed date window with compania_id, tercero_id, tipo=out_invoice, and estado=draft. If the exact reference already exists, it creates nothing. It then presents company, customer, dates, reference, journal, products, quantities, and whether each line uses Odoo defaults or manual precio_unitario/impuesto_ids. It shows no projected subtotal, tax total, or grand total because those values do not yet exist in a document read from Odoo.

  5. 5

    Wait for another message and create once

    The review does not authorize itself. The Met waits for a new message with an explicit yes for those same inputs. A question, change, or silence is not approval. It then repeats the preflight with odoo_listar_facturas and the opaque reference. If there is no match, it calls odoo_crear_factura_borrador exactly once with tipo=out_invoice, compania_id, and confirmar=true. requireConfirmation runs before the write. The tool creates account.move in draft. Posting, EDI, sending, and payment are never chained, and confirmar is not forwarded to later reads.

  6. 6

    Read the created invoice and return literal values

    With the returned id, odoo_consultar_factura reads the header and lines again. The Met checks tipo out_invoice, state draft, customer, company, reference, and quantities against the approved inputs. Only then does it report number, dates, journal, currency, precio_unitario, taxes, subtotal, total, and residual exactly as Odoo returned them. If Odoo rejects an account, tax, or journal configuration, the Met reports the error and does not substitute ids or invent an amount.

  7. 7

    Stop and reconcile an uncertain response

    If creation returns posiblemente_creada after a timeout or network loss, the Met does not repeat the write. It pages the same customer's drafts for the same company, type, and date window, then compares the literal opaque reference. Only when exactly one candidate appears does it read that id and apply the same final checks. With zero or multiple candidates, it stops for manual review. The preflight and reconciliation reduce duplicate risk, but calls are separate transactions and do not guarantee uniqueness or provide rollback.

Before you start

What you need ready

The Met solves none of these for you. If one is missing, the automation stops there.

The limits

What this automation does NOT solve

Better said here than discovered halfway through the rollout.

FAQ

Questions about this automation

No. The yes in a new message authorizes one creation with confirmar=true. The document remains draft, and this recipe does not call posting, EDI, sending, credit notes, or payment.

When precio_unitario and impuesto_ids are omitted, Odoo uses product, company, and fiscal-position configuration. That is not a promise of a negotiated customer price. Manual values must appear exactly in the review and be authorized before the yes.

Odoo tries to derive the account from the product, category, or journal and selects a sale journal for the company when none is sent. If configuration is insufficient, it returns an error. The Met does not invent account_id or switch companies to force creation.

It uses an opaque reference, lists drafts before creation, and searches for that same reference after posiblemente_creada before doing anything else. It accepts only one candidate and stops with zero or several. This reduces risk but is not a unique constraint inside Odoo.

No. The flow fixes tipo=out_invoice and validates a customer. Vendor bills, credit notes, and free-form accounting lines need a separate procedure and a separate review of permissions and inputs.

Keep going

Other automations built on the same tools

Want this automation running on your own data?

We will show it to you with your accounts connected, not with a canned demo.