A build-to-order Odoo module that fiscalises your customer invoices and credit notes through the ZRA Smart Invoice device/API flow, directly from `account.move`. ECOSIRE scopes, builds, installs and supports it for your Odoo 17.0, 18.0 or 19.0 database. 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 fiscalises your customer invoices and credit notes through the ZRA Smart
Invoice device/API flow, directly from `account.move`. ECOSIRE scopes, builds, installs and supports it for your Odoo 17.0, 18.0 or 19.0 database.
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 Zambia face a problem Odoo core does not solve: an invoice is not legally complete when it is posted in the ERP. It becomes valid only once it has been transmitted to the Zambia Revenue Authority's Smart Invoice service, accepted, and returned with its fiscal identifiers so the printed document can carry them. Out of the box, account.move knows nothing about that round trip. Teams bridge the gap by hand — re-keying every invoice into a separate Smart Invoice client, exporting spreadsheets at month end, or building fragile scripts on top of the JSON-RPC API. The results are predictable: mismatched totals between the ERP and the fiscal record, invoices that were posted but never fiscalised, credit notes with no traceable link to the original document, and an audit trail that lives in two systems that were never reconciled.
We build a dedicated Odoo module that makes fiscalisation a first-class part of the invoicing workflow. The module extends account.move and account.move.line with the fields the regime actually needs — fiscal status, submission and response timestamps, the returned invoice number and verification data, the reference to the original document on a credit note — and models the ZRA transport as its own object so device/API credentials, endpoints and the branch or taxpayer identifiers are configured per company rather than hard-coded. Posting an invoice raises a submission record; a queued job (or an ir.cron on smaller installations, your choice at scoping) handles transmission, retries and the response, so a slow or unavailable endpoint never blocks a user's action_post(). Tax treatment is derived from your existing master data — account.tax, fiscal positions, product categories and UoM — through an explicit mapping model rather than guesswork, so the classification a document carries is auditable and changeable by an accountant instead of a developer.
One posting produces both required outputs. The machine payload is assembled from the same lines that produce the human-readable document, so the two can never diverge: a QWeb report inheriting your existing invoice template renders the fiscal number, verification QR code and any statutory wording, while the transmitted payload is stored verbatim alongside the response. Rejections are treated as a workflow, not an error log — a rejected document lands in a dedicated state with the authority's reason code surfaced on the form, an activity raised for the responsible user, and a guarded correction path that either amends and resubmits or issues a properly linked credit note, with every attempt retained. Access is governed through ir.model.access.csv plus record rules so only the finance roles you nominate can resubmit or override, and every state change is written to the chatter and to an immutable submission log for archiving.
The module targets Odoo 17.0, 18.0 and 19.0 and is built against your edition. It depends only on account and standard framework services, so it works on Community; where you run Enterprise we use the accounting features you already have (bank reconciliation, follow-up, consolidated reporting) rather than duplicating them. Multi-company and multi-branch setups are handled through company-scoped configuration, and integration points are exposed over XML-RPC/JSON-RPC where a POS, e-commerce front end or third-party billing system needs to trigger fiscalisation from outside Odoo.
This is build-to-order, not a marketplace download. We start with a short scoping call to confirm your ZRA registration model, the document types in scope, your tax mapping and your Odoo version and edition. From there we write the manifest and models, build against a copy of your database, and deliver typically 2–4 weeks from confirmed scope. You get the installable source for your version, a staging deployment for UAT, a documented rollback, training for the finance team, and a post-go-live support window — plus the git repository, so the code is yours to keep and extend.
Owns the accuracy of the ledger and the relationship with ZRA. Needs certainty that every posted customer invoice has been fiscalised, that rejections are visible the day they happen rather than at month end, and that the ERP totals and the fiscal record reconcile without a spreadsheet.
Runs day-to-day invoicing and credit notes. Wants fiscalisation to happen inside the invoice they already work in — no second system to re-key into — with a clear correction path when a document is rejected and no risk of accidentally sending the same invoice twice.
Maintains the Odoo instance and is accountable for upgrades. Needs a module that depends only on standard `account` behaviour, keeps credentials out of the repository, logs enough to diagnose a failed transmission, and comes with source they can read and maintain.
Oversees several Zambian entities or branches on one database. Needs per-company configuration and record rules, consistent tax mapping across entities, and a retained, exportable audit trail of every submission and response for internal and external audit.
| Criterion | ECOSIRE | Custom Build | Competitor | Odoo Native |
|---|---|---|---|---|
| ZRA Smart Invoice transmission | Built into the posting workflow, queued and retried, with idempotency so no invoice is sent twice | Achievable, but the retry/idempotency design is where in-house builds usually get it wrong | Generic e-invoicing connectors rarely cover the Zambian device/API flow specifically | Not present — Odoo core has no concept of fiscalisation |
| Tax classification mapping | Explicit mapping model over your `account.tax`, fiscal positions, product categories and UoM, editable by accountants | Often hard-coded in Python, so every rate change becomes a developer ticket | Fixed assumptions about your chart of accounts that may not match yours | Odoo taxes exist but carry no fiscal classification codes |
| Rejection handling | Dedicated state, authority reason code on the form, activity raised, guarded correct-and-resubmit or linked credit note | Typically a log line and an email; correction handled manually | Usually surfaces an error; the workflow around it is left to you | No concept of an externally rejected document |
| Audit trail and archiving | Immutable submission log storing every payload and response verbatim, plus chatter, retained for the statutory period | Depends entirely on what the developer chose to store — often the response only | Varies widely; frequently keeps status but not the payload | Chatter tracks accounting changes, nothing about fiscalisation |
| Printed document | QWeb report inherited from your existing invoice template, adding fiscal number, QR and statutory wording | Common approach is to replace the template, which breaks your branding and other customisations | Ships its own layout that you then have to re-brand | Standard invoice PDF with no fiscal identifiers |
| Fit to your Odoo version and edition | Built and tested against your exact 17.0/18.0/19.0 database and edition, Community or Enterprise | Fits by definition, but the version-upgrade path is your problem alone | Listed for a version range; behaviour on your customised database is unverified until install | n/a |
| Time and cost to get live | Typically 2–4 weeks from confirmed scope, fixed quotation, UAT on staging with a rollback plan | Longer — specification, build, and the regime research your team has not done yet | Fast to install, slow to reconcile once the assumptions do not match your data | Immediate, but the compliance work stays manual |
| Ownership and maintenance | Full source plus git repository handed over; support window included, ongoing support optional | You own it and you maintain it, including the key-person risk | Vendor-controlled; you depend on their release cadence for regime changes | Maintained by Odoo, but never covers this requirement |
This is a build-to-order module, not an instant download. Typical delivery is 2–4 weeks from confirmed scope. The clock starts once we have agreed the document types in scope, your tax mapping, your ZRA registration and device/API details, and your Odoo version and edition on a scoping call. Larger multi-entity or POS-integrated builds can run longer, and we tell you that before you commit, not afterwards.
Delivery includes a post-go-live support window for defect fixes and configuration adjustments — the exact length is agreed in your quotation. After that, ongoing support and version-to-version upgrades (for example moving the module from 18.0 to 19.0, or adapting to a change in the ZRA specification) are handled under a support agreement or as a scoped change. Because you receive the git repository, you also retain the option to maintain it in-house.
We build for Odoo 17.0, 18.0 and 19.0, on Community or Enterprise. The module depends on the standard `account` module and framework services only, so it does not require Enterprise. Where you already run Enterprise accounting features, we integrate with them rather than duplicating them. We build against your specific version — we do not ship one branch and hope it loads on another.
Yes — that is part of scoping. The printed fiscal data is added by inheriting your existing `account.move` QWeb report rather than replacing it, and the model extensions are additive fields and methods on `account.move`/`account.move.line`. If you already have customisations touching invoice posting, we review them on the copy of your database we build against, so conflicts surface during development instead of on go-live day.
Neither blocks your finance team. Transmission runs outside the posting transaction, so an unreachable endpoint means the invoice is posted and queued, with automatic retries. A rejection puts the document into a dedicated state with the authority's reason code shown on the form and an activity assigned to the responsible user; from there you either correct and resubmit or issue a linked credit note. Every attempt, payload and response is retained.
Yes, subject to scoping. We expose the submission and status calls over Odoo's XML-RPC/JSON-RPC API so an external system can trigger fiscalisation and read back the result. If the volume or shape of that traffic is significant, tell us on the scoping call — it changes how we design the queue and the idempotency keys, and we would rather design for it than bolt it on.
Yes. You receive the full source and the git repository with commit history at handover. There is no runtime licence check that can disable the module, and no dependency on us to keep it running. We would like to be your support partner; you are not obliged to make us one.

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 fiscalises your customer invoices and credit notes through the ZRA Smart Invoice device/API flow, directly from `account.move`. ECOSIRE scopes, builds, installs and supports it for your Odoo 17.0, 18.0 or 19.0 database.