A build-to-order Odoo module that turns your posted customer invoices into GRA E-VAT compliant submissions, with rejection handling, correction workflow and a compliant archive. ECOSIRE builds, installs and supports it for your exact Odoo version and chart of accounts. Built to order by ECOSIRE for Odoo 17, 18, 19 — indicative price from $499.00 USD; request a quote for a scoped proposal.
Illustrative previewA build-to-order Odoo module that turns your posted customer invoices into GRA E-VAT compliant submissions,
with rejection handling, correction workflow and a compliant archive.
ECOSIRE builds, installs and supports it for your exact Odoo version and chart of accounts.
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 Ghana face a problem Odoo core was never designed for: the Ghana Revenue Authority does not accept a PDF you printed and emailed. An E-VAT invoice has to be transmitted in the Authority's expected structure, carry the identifiers the Authority returns, and be reproducible on demand for audit years later. Odoo's native account.move gives you the accounting truth and a QWeb PDF, but nothing downstream of action_post — no submission state, no response identifier stored against the invoice, no way to tell an accountant that the invoice they posted this morning was rejected this afternoon and why. Teams fill that hole with a second system: a portal someone re-keys into, a spreadsheet of reference numbers, and a monthly reconciliation that nobody enjoys. Every re-keyed field is a mismatch waiting to be found by an auditor.
What ECOSIRE builds is a compliance layer that lives inside the invoice record, not beside it. We extend account.move with the E-VAT fields the flow actually needs — submission state, Authority response identifiers, response timestamps, the raw response payload, and a rejection reason — and drive them from a state machine hung off invoice posting rather than a manual button someone forgets. Tax mapping comes from your existing master data, not a parallel table: account.tax and account.fiscal.position already encode which rate applies to which customer and product, so the module reads that mapping and translates it into the codes the Authority expects, with a validation pass that refuses to submit an invoice whose tax lines cannot be mapped cleanly. One posting produces both outputs: the machine format for transmission and the human-readable QWeb report your customer receives, rendered from the same record so the two can never diverge in figures.
Technically, the module ships as a standard Odoo addon with its own __manifest__.py, models under models/, XML and OWL view extensions, QWeb report templates, and an ir.model.access.csv plus record rules so that E-VAT operations are scoped — an invoicing clerk can submit, only a finance manager can force a correction or re-submit. Transmission runs through a queued job rather than the request thread, so a slow or unavailable Authority endpoint never blocks a user posting an invoice; failures are retried on a schedule via ir.cron and surfaced on the invoice in a way that is visible from the list view, not buried in the log. Rejections open a correction workflow: the original stays immutable, the reason is recorded in the chatter with the mail thread intact, and the corrected document carries an explicit link back to what it replaces. Every request and response is archived as an ir.attachment against the move, giving you a byte-exact audit trail rather than a reconstruction. Everything is reachable over XML-RPC and JSON-RPC, so a fulfilment system or an external portal can trigger and read submission state without a human in the loop. We build against Odoo 17.0, 18.0 or 19.0 and we work on Community as well as Enterprise — where a capability genuinely depends on Enterprise (for example if your process leans on Odoo Studio or the Enterprise document tooling), we say so during scoping instead of after delivery.
This is build-to-order, and we are explicit about what that means. There is no instant download; when you request a quotation we start with a short scoping call to confirm your Odoo version and edition, your chart of accounts and tax configuration, whether you invoice from Sales, Subscriptions, POS or an external system, and how your finance team wants rejections to reach them. From confirmed scope, typical delivery is two to four weeks. You receive installable source for your exact version, we install and configure it, we run UAT on a staging database with your own data before anything touches production, and we hand over the git repository so the code is yours. After go-live you have a support window in which we fix defects in what we built.
One honest caveat worth stating up front: regulatory requirements in Ghana continue to evolve, and any integration is bound to the Authority's current interface and rules. We build to what is documented and in force at the time of your scope, we design the mapping layer so codes and formats are configuration rather than hard-coded constants, and we handle changes after the support window as a scoped update rather than pretending a module can be permanently future-proof.
Owns the VAT return and signs off the numbers. Needs to know that every posted invoice was accepted, that rejections surface the same day rather than at month-end, and that the archive will stand up in an audit without reconstructing anything from a portal.
Posts invoices all day and is the person currently re-keying them into a portal. Needs submission to happen from the invoice they are already looking at, with a clear status and a plain-language reason when something is rejected.
Owns the Odoo instance and its upgrade path. Wants a clean addon with proper access rules and no core patching, source in a git repository they control, and an RPC surface so other systems can read submission state instead of scraping the UI.
Reviews the trail after the fact. Needs each invoice to carry its own submitted payload and Authority response, and needs corrections to be traceable back to the document they replace rather than appearing as silent edits.
| Criterion | ECOSIRE | Custom Build | Competitor | Odoo Native |
|---|---|---|---|---|
| Fit to your Odoo version and tax setup | Built against your exact 17.0/18.0/19.0 branch, edition and chart of accounts, verified on your data in UAT | Fits perfectly if the team knows both Odoo and the E-VAT rules — the risk sits in the second half of that sentence | Built for a generic configuration; your fiscal positions and custom taxes are yours to reconcile | No E-VAT concept at all — Odoo posts the invoice and stops there |
| Tax mapping source | Reads `account.tax` and `account.fiscal.position` directly, with validation that blocks unmappable lines before transmission | Whatever the team chooses; a parallel mapping table is the common shortcut and the common source of drift | Usually a separate mapping screen maintained alongside your real tax configuration | Tax configuration exists and is correct — it simply has no Authority-facing translation |
| Rejection handling | Reason and raw response stored on the record, filterable from the list view, with a correction workflow linking the replacement to the original | Depends entirely on how much of the unhappy path made it into scope — usually the first thing cut | Typically a status flag; the reason often lands in the server log rather than on the invoice | Nothing to reject — there is no submission |
| Audit trail | Every request and response archived as an `ir.attachment` on the move, byte-exact and reproducible years later | Achievable, but only if someone specified it up front | Varies widely; often a reference number with nothing behind it | Standard accounting audit trail and chatter only — no Authority correspondence |
| Effect on daily invoicing | Transmission runs as a queued background job, so a slow Authority endpoint never blocks posting | Often built synchronously first, which is fine until the endpoint has a bad afternoon | Frequently synchronous; users learn to fear the Post button | Fast, because it does nothing — the work moves to a portal and a spreadsheet |
| Security and access control | `ir.model.access.csv` plus record rules, with submit, force re-submit and correction separately grantable and multi-company scoped | As good as the developer's discipline; access rules are a common omission on internal builds | Usually a single group that can do everything | Standard invoicing groups, with no E-VAT-specific rights to grant |
| Integration with other systems | Full XML-RPC and JSON-RPC surface, documented method by method in the handover | Possible, but internal builds tend to expose only what the first caller needed | Often UI-first, with RPC access undocumented or absent | Odoo's generic RPC exists, but there is no submission state to call |
| Ownership and ongoing change | Git repository handed over, support window for defects, later regulatory changes quoted as scoped updates | You own it outright — and you own every future rule change and Odoo upgrade with it | Vendor-controlled release cycle; a change you need may not be one they prioritise | Nothing to own; you carry the manual process indefinitely |
No — this is build-to-order, not an existing apps.odoo.com download. We start with a scoping call to confirm your Odoo version and edition, tax configuration, invoicing sources and rejection-handling process. From confirmed scope, typical delivery is two to four weeks, including UAT on staging before anything reaches production. If your scope includes non-standard invoicing sources or a heavily customised chart of accounts, we will tell you during scoping whether that pushes past four weeks rather than discovering it later.
You get a post-go-live support window in which we fix defects in what we built, at no extra cost. Beyond that window, and for changes driven by new Authority requirements or an Odoo major-version upgrade, we quote the work as a scoped update. You also receive the git repository, so if you prefer to maintain it in-house or hand it to another team, nothing is locked to us.
The module itself is built to run on Community and Enterprise for Odoo 17.0, 18.0 and 19.0. Where your specific process depends on an Enterprise-only capability — for example if your finance team's workflow leans on Odoo Studio or the Enterprise document tooling — we identify that during scoping and tell you before you commit, not after delivery.
A rejection is never silently retried. The original invoice stays immutable, the rejection reason and the raw Authority response are recorded on the record and in the chatter, and the invoice moves into a state your team can filter for from the list view. The correction workflow then produces a replacement document that carries an explicit reference back to the one it supersedes, so the audit trail shows what happened rather than hiding it as an edit. Transport-level failures — a timeout or an unreachable endpoint — are treated differently and retried on a bounded schedule.
It reads your existing `account.tax` and `account.fiscal.position` configuration. That is deliberate: a parallel mapping table is a second thing to maintain and the first thing to go stale. Where the Authority requires a code your master data does not yet carry, we add it as a field on the relevant record during implementation so it stays in one place. Pre-submission validation blocks any invoice whose tax lines cannot be mapped cleanly and names the offending line.
Yes. Everything is exposed over Odoo's standard XML-RPC and JSON-RPC API — an external order system, a portal or a middleware layer can trigger submission, poll state and retrieve the archived response payload without a human in the Odoo UI. We document the exact method signatures in the technical handover.
We build to what is documented and in force at the time of your scope, and we deliberately keep codes, formats and endpoints as configuration rather than hard-coded constants so a rule change is a configuration change or a small patch rather than a rewrite. We do not claim the module is permanently future-proof — no integration bound to a live regulatory interface can be. Changes after your support window are handled as a scoped update, and the handover note records exactly which interface version your build targets so there is a documented baseline to change from.

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.
A build-to-order Odoo module that turns your posted customer invoices into GRA E-VAT compliant submissions, with rejection handling, correction workflow and a compliant archive. ECOSIRE builds, installs and supports it for your exact Odoo version and chart of accounts.