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
- Odoo Collect and manage
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
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
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
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
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
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
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
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.
-
Odoo 17 or later with external API and Accounting
Odoo Online requires the Custom plan. One App Free and Standard do not include the external API. Odoo 19 and later use JSON-2, while Odoo 17 and 18 use JSON-RPC. The database must have Accounting and the required masters configured.
-
A technical user with minimum permissions
Connect an HTTPS URL, database, dedicated user, and API key. Grant read access to companies, parties, products, taxes, journals, and invoices, plus permission to create draft invoices. This recipe does not need permission to post, send fiscal documents, or register payments.
-
Existing customer, products, and accounting configuration
The customer and variants must exist in the right company. Configure the sales journal, income accounts, taxes, fiscal position, and currency in Odoo before running. The Met does not create these masters or repair an incomplete localization.
-
A policy for manual price and tax values
Define who can override Odoo defaults and how approved precio_unitario and impuesto_ids are documented. Without that authorization, the recipe omits both fields and lets Odoo use its current configuration.
The limits
What this automation does NOT solve
Better said here than discovered halfway through the rollout.
-
It does not quote or negotiate the sale. It does not check stock, availability, or a customer-specific price list and uses no quotation or sales-order tools. It starts after the item is approved for billing.
-
It does not calculate a total before creation. odoo_consultar_precio returns a base price with a warning. Subtotal, taxes, and total are reported only after the draft is created and read from Odoo.
-
It does not post the invoice, create a credit note, or register or reconcile a payment. Those actions are outside this recipe, and the highest-impact actions are blocked for channel Mets.
-
It does not run EDI, report acceptance by DIAN, SAT, SRI, or another authority, or generate, attach, or send a PDF. A draft account.move has no accounting effect and proves no fiscal issuance.
-
It does not move stock or confirm a delivery. A direct invoice does not replace a sales order, delivered-quantity invoicing policy, or operational control of a sale or service.
-
It does not allow an account to be selected per line because the tool has no account_id input. Odoo derives the account from its configuration. If it cannot, creation fails so a person can fix the ERP.
-
It does not guarantee idempotency or uniqueness. The opaque reference, preflight, and reconciliation reduce risk, but a concurrent race can still create two drafts and there is no rollback across tools.
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
Sales and quoting
Quote over WhatsApp with Odoo
How do I quote over WhatsApp with Odoo without opening the ERP?
Finance and operations
- Starts:
- when the customer writes
- Steps:
- 6, with 11 real tools
- Needs:
- Odoo
Collections and receivables
Charge inside the conversation with a Mercado Pago link
How do I charge over WhatsApp without sending people to another app or asking for card details?
Sales
- Starts:
- when the customer writes
- Steps:
- 6, with 11 real tools
- Needs:
- Mercado Pago · Meteor CRM
Collections and receivables
Collect overdue invoices over WhatsApp without chasing anyone by hand
How do I collect overdue invoices over WhatsApp without reviewing the ledger by hand?
Finance and operations
- Starts:
- at a set time
- Steps:
- 5, with 8 real tools
- Needs:
- Alegra · Meteor CRM
Collections and receivables
Charge by PSE and Nequi inside the conversation, with Wompi
How do I charge by PSE or Nequi from WhatsApp without pulling the customer out of the chat?
Sales
- Starts:
- when the customer writes
- Steps:
- 5, with 10 real tools
- Needs:
- Wompi · Meteor CRM
Want this automation running on your own data?
We will show it to you with your accounts connected, not with a canned demo.