Issue Vietnamese e-invoices directly from Odoo, with provider API transmission, invoice-code handling, tax mapping from your own master data, and a full correction and archiving trail. Built to order by ECOSIRE for Odoo 17.0, 18.0 or 19.0. Built to order by ECOSIRE for Odoo 17, 18, 19 — indicative price from $499.00 USD; request a quote for a scoped proposal.
Illustrative previewIssue Vietnamese e-invoices directly from Odoo, with provider API transmission,
invoice-code handling, tax mapping from your own master data, and a full correction and archiving trail. Built to order by ECOSIRE for Odoo 17.0, 18.0 or 19.0.
No DIY setup — a working app, built, installed and supported by ECOSIRE.
Start with a one-time build price. We scope it with you at kickoff.
ECOSIRE builds, configures and installs it on your Odoo.
You go live in about 2–4 weeks, with a post-launch support window.
Finance teams invoicing in Vietnam carry a compliance obligation that Odoo's standard accounting does not answer. account.move posts a document, numbers it with an ir.sequence, and renders a QWeb PDF — but Vietnamese e-invoicing requires that the same posting be transmitted to an authorised e-invoice service provider, receive back an official invoice code, be represented in a machine-readable structure alongside the human-readable copy, and be retrievable in that exact issued form for years afterwards. Nothing in Odoo Community or Enterprise does this. The usual fallback is a parallel workflow: post in Odoo, re-key into the provider's web portal, download the returned file, and reconcile two systems by hand at month end. That is where numbering diverges, where a customer receives a document the tax record does not recognise, and where a rejected submission sits unnoticed until someone reads an email.
We build a module that makes transmission part of posting. A new model — typically ecosire.einvoice.document — is created on account.move post and carries its own lifecycle state (draft, queued, sent, accepted, rejected, cancelled, replaced), the provider request and response payloads, the returned invoice code and lookup reference, and relations back to account.move and res.partner so the chain is traceable from either end. Transmission runs asynchronously through a queued job or an ir.cron sweep rather than inline in the write transaction, so a provider timeout never blocks a user's posting. Every call is stored with its request body, HTTP status, provider error code and timestamp, which is what turns "the invoice failed" into a specific, answerable question.
Tax handling is driven by your own master data, not a hard-coded table. We extend account.tax, product.template and product.category with the provider's tax-category and unit-of-measure codes, and a compute (@api.depends on the line taxes and product) resolves each account.move.line to the code set the provider expects. Exempt, zero-rated, non-declarable and reduced-rate cases each get an explicit mapping rather than falling through to a default, and a validation gate on post raises a clear message naming the specific tax or product that is unmapped — before the document is submitted and rejected. Partner-side data (tax code, legal name, address) is validated for format and completeness on res.partner, so the common rejection causes are caught inside Odoo.
Rejections are treated as a workflow, not an error log. A rejected document moves to rejected with the provider's reason surfaced on the form and posted to the chatter via message_post, and an mail.activity is scheduled for the responsible accountant. From there the correction path — adjustment or replacement, depending on what the original document's state allows — creates the linked corrective document and preserves the reference to what it supersedes, so the audit trail shows the full sequence rather than a silently amended record. Archiving stores the issued machine-readable file and the rendered human-readable copy as checksummed ir.attachment records, and a dedicated menu lets finance search and export by period, partner, tax code or document state. Access is governed by ir.model.access.csv plus record rules, so multi-company installs cannot see each other's issued documents, and provider credentials live in ir.config_parameter scoped per company rather than in source.
This is a build-to-order product: ECOSIRE develops it against your Odoo version (17.0, 18.0 or 19.0), your chart of accounts, and your specific e-invoice service provider's API contract — providers differ in authentication, payload schema and error semantics, so the connector is written to yours rather than assumed. It is not an instant download. After a short scoping call we confirm scope in writing, and typical delivery is two to four weeks from that confirmation. You receive installable source, deployment on your staging database for UAT against the provider's test environment, and a git repository handover, so the module remains yours to maintain, extend, or hand to another team.
Owns the tax filing and answers to the authorities when an invoice cannot be produced in its issued form. Needs every posted invoice to carry a provider-acknowledged code, needs rejections visible the same day rather than at month end, and needs a searchable archive that matches the ledger exactly.
Runs one Odoo instance across several countries and refuses to add a country-specific parallel system. Needs Vietnamese compliance to live inside the same `account.move` flow as every other entity, with per-company isolation so the Vietnam records are governed separately without a second database.
Responsible for the Odoo estate and its upgrade path. Needs the integration written as a clean addon rather than core patches, credentials kept out of source, the transmission queue observable, and the git repository in hand so the module is not a black box at the next version upgrade.
Issues invoices daily and fields the customer calls when a document is queried. Needs the invoice code and lookup reference visible on the record and the printed copy, the rejection reason in plain language, and the correction path to be a guided workflow rather than manual re-entry.
| Criterion | ECOSIRE | Custom Build | Competitor | Odoo Native |
|---|---|---|---|---|
| Fit to your provider's API | Connector written against your provider's actual contract, sandbox-tested during UAT | Same fidelity possible, but your team absorbs the full integration learning curve | Supports the providers the vendor chose; yours may be unsupported or partially covered | No e-invoice provider integration of any kind |
| Transmission and invoice-code handling | Async queue with idempotent retry; official code stored on the record and printed on the report | Depends entirely on the developer's care with queueing and idempotency | Usually present, though retry and idempotency behaviour is often undocumented | Posting produces a numbered `account.move` and a PDF only |
| Tax and UoM code mapping | Declared on your own `account.tax` and product records, validated before submission | Built to your spec; mapping is frequently under-scoped and discovered during UAT | Generic mapping table that may not reflect your chart of accounts | Odoo taxes carry no provider tax-category codes |
| Rejection and correction workflow | Reason on the form, chatter entry, scheduled activity, and a linked correction path | Often stops at logging the error; the correction workflow becomes a second project | Varies widely — many surface only a status flag with no guided correction | Nothing to reject against; corrections are manual credit notes |
| Archiving and audit trail | Checksummed attachments for both formats, searchable archive with export | Achievable, but retention and search are usually deferred past go-live | Attachments typically stored; search and export depth is inconsistent | PDF attachment only, no issued machine-readable copy |
| Odoo version support | Built for your target version — 17.0, 18.0 or 19.0 — Community or Enterprise | Whatever you build; upgrade cost lands on your team each cycle | Version support depends on the vendor's release cadence; gaps are common | Version-agnostic because the capability does not exist |
| Ownership and lock-in | Private git repository with full commit history handed over to you | You own it outright, along with all maintenance | Licensed source; continued fixes depend on the vendor staying active | Not applicable |
| Time and effort to production | Typically 2-4 weeks from confirmed scope, including staging UAT and rollback plan | Commonly several months once provider integration and edge cases are real | Fast to install, then weeks of adaptation if your provider or taxes differ | Immediate, but the compliance obligation remains unmet |
No — this is a build-to-order product, not an existing apps.odoo.com download. We start with a short scoping call, confirm scope in writing, then build against your Odoo version and your e-invoice service provider's API. Typical delivery is two to four weeks from confirmed scope, including UAT on your staging database. Complex multi-company setups or heavily customised charts of accounts can extend that, and we tell you before we start rather than after.
We build the connector against the authorised provider you already use. Providers differ meaningfully in authentication, payload schema, invoice-code semantics and error codes, so we write to your provider's published API contract rather than assuming a generic one. During scoping we ask for that integration documentation and sandbox access. If you have not selected a provider yet, we can talk through the integration implications of the common options, but the choice and any commercial relationship remain yours.
Both. The module is built on standard `account` functionality present in Community, so it does not require Enterprise. We build and test against your target version — 17.0, 18.0 or 19.0 — and your edition. If you run Enterprise we take advantage of Enterprise accounting features where they genuinely help; nothing in the compliance path depends on them.
Posting still succeeds. Transmission runs asynchronously via a queued job or an `ir.cron` sweep, never inline in the posting transaction, so a provider outage cannot block your team from invoicing. The document stays in `queued` and retries using its original correlation reference, which makes the retry idempotent — a network failure cannot produce a duplicate submission. If retries keep failing, the document surfaces in the exception view with the provider's last error rather than sitting silently.
Delivery includes a post-go-live support window for defect fixes and configuration adjustments within the agreed scope. Beyond that, ongoing support and change requests — a provider API version change, a regulatory format update, or a port to a newer Odoo version — are quoted separately. Because you receive the git repository with full history, you are never locked in: your own team or another partner can maintain the module. We are happy to keep doing it, but that is your choice, not a dependency.
Once a document carries an official invoice code it cannot simply be edited. The module implements the correction path your provider and the regulations allow — adjustment or replacement — by creating a linked corrective document that preserves the reference to what it supersedes. Both records stay in the archive, so the audit trail shows the full sequence. The available options are constrained by the original document's state, and the interface only offers what is actually permitted.
Yes. Delivery includes UAT on your staging database against the provider's sandbox environment, with an agreed test script covering successful issuance, a deliberate rejection, a correction, and archive retrieval. We also agree a rollback plan before production cutover. We do not ask you to accept the work on the basis of a demo of somebody else's data.

A build-to-order Odoo localization that loads Algeria's full wilaya and commune hierarchy with bilingual French and Arabic names, wired into partner addresses and reporting. ECOSIRE builds, installs, and supports it after your quotation.



A build-to-order Odoo module that lets you render any accounting report — P&L, Balance Sheet, aged reports, journals, trial balance — in a currency of your choice, with automatic conversion at the rate you define. ECOSIRE scopes, builds, installs and supports it for your Odoo 17/18/19 environment.
Issue Vietnamese e-invoices directly from Odoo, with provider API transmission, invoice-code handling, tax mapping from your own master data, and a full correction and archiving trail. Built to order by ECOSIRE for Odoo 17.0, 18.0 or 19.0.