A build-to-order Odoo module that turns every posted customer invoice into a Veri*factu-compliant record and keeps your SII ledgers submitted, acknowledged and reconciled from inside Odoo. 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 turns every posted customer invoice into a Veri*factu-compliant record and
keeps your SII ledgers submitted, acknowledged and reconciled from inside Odoo. 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.
Spanish invoicing has moved from "print a PDF and file the VAT return" to "your software must prove what it did". Veri*factu requires that invoicing software produce a tamper-evident record for each invoice — chained to the previous one, hashed, timestamped, carrying the issuer and recipient tax identifiers, the taxable base and quota by rate, and a QR the recipient can verify. Separately, SII requires near-real-time submission of the issued and received invoice ledgers to the AEAT. Two obligations, one posting event, and finance teams end up bridging them with spreadsheets, a third-party portal, and a monthly panic when the ledgers do not agree with the general ledger.
Odoo core does not close this gap. l10n_es gives you a Spanish chart of accounts and tax codes; l10n_es_edi_sii (Enterprise) covers a slice of SII, and neither ships a Veri*factu record chain, the hash/QR generation, or a rejection-and-correction workflow that an auditor can follow. Community editions have no SII path at all. The practical failure mode is not "it does not work" — it is that a rejection from the AEAT lands in a log nobody reads, the invoice stays posted in Odoo, and the ledger silently diverges from what the tax authority believes you issued.
What we build is a l10n_es-dependent module that hangs off account.move and treats the compliance record as a first-class Odoo object rather than a side effect. Posting an invoice fires an override on _post() that snapshots the fiscally relevant fields into a new ecosire.es.verifactu.record model — chained via a previous_record_id and a stored hash computed by a @api.depends-guarded compute so the chain cannot be silently rebuilt, with the QR payload rendered into the QWeb invoice report from that same stored record. Tax mapping is driven from your master data, not hardcoded: account.tax rows carry a mapping field resolving to the correct SII/Veri*factu tax key and régimen clave, and res.partner supplies the NIF/VAT type discrimination (national, intra-community, third country) so the ledger classification is derived from what your accountants already maintain. Submission runs through a queued outbound job driven by an ir.cron and an automated action, so a slow AEAT endpoint never blocks a user posting an invoice; every request and response is persisted on the record with its CSV/acknowledgement, and the whole model is secured with ir.model.access.csv plus record rules so multi-company groups only see their own establishment's records.
Rejections are where most implementations quietly fail, so the correction workflow is explicit. A rejected or partially accepted submission moves the record to a rejected state, raises an activity on the responsible accountant, and exposes the AEAT error code and message in a dedicated notebook page on the invoice form. From there you either resubmit after fixing master data, or issue a factura rectificativa that inherits the original's chain reference — Odoo's credit note flow is extended so the rectification carries the correct rectification type and reason rather than being posted as an unrelated document. Everything remains queryable over XML-RPC/JSON-RPC, so a group consolidation tool or a Power BI model can read submission state without touching the database. We build for whichever of Odoo 17.0, 18.0 or 19.0 you actually run, and we handle the Community versus Enterprise difference explicitly during scoping — on Enterprise we can extend and reuse the existing SII plumbing; on Community we implement the transport layer ourselves.
This is a build-to-order product, not an instant download. You request a quotation, we run a scoping call to confirm your Odoo version and edition, your establishments, invoice volume, whether you are already in SII, your certificate arrangements, and any existing localisation customisations. We then quote a fixed scope, build the module against a copy of your database, and deliver it with UAT on a staging instance before anything touches production. Typical delivery is 2-4 weeks from confirmed scope — the range moves with how much of your master data needs remediation, which is usually the real work. You receive the full source, the git repository, documentation, a training session, and a post-go-live support window.
Owns the VAT filings and answers to the auditor. Needs the Veri*factu record and the SII ledger to be a by-product of posting an invoice in Odoo, not a separate reconciliation exercise, and needs rejections to reach a human before the filing deadline rather than sitting in a log.
Runs Odoo across several countries and cannot accept a bolt-on portal that lives outside the ERP. Wants submission state queryable alongside every other entity's data, with per-company record rules so the Spanish establishment's compliance data stays isolated.
Has already customised the Spanish localisation and knows a generic module will collide with it. Wants source code, a git repository, documented extension points, and a build that respects the existing `l10n_es` configuration instead of overwriting tax mappings.
Files on behalf of multiple companies and needs a repeatable, auditable workflow — same rejection handling, same rectification path, same evidence trail on every database they touch.
| Criterion | ECOSIRE | Custom Build | Competitor | Odoo Native |
|---|---|---|---|---|
| Veri*factu record chain and QR | Dedicated hash-chained record model created on posting; QR rendered from the stored record | Achievable, but the chain design is the hard part and is usually got wrong on the first attempt | Varies widely; some cover SII only and add QR as an afterthought | Not provided in Odoo core or `l10n_es` |
| SII ledger submission | Queued cron-driven submission with full request/response persistence per attempt | Built from scratch including retry and idempotency handling | Usually present; retry and acknowledgement storage often thin | Partial via `l10n_es_edi_sii` on Enterprise only; nothing on Community |
| Rejection and correction workflow | Explicit rejected state, error surfaced on the invoice, activity raised, rectificativa flow extended | Frequently deferred to phase two and never built | Often a log entry with no assignment to a human | No workflow; errors surface as raw traces if at all |
| Tax mapping approach | Driven from your `account.tax` and `res.partner` master data, no hardcoded catalogue | Depends entirely on the developer's discipline | Commonly a fixed internal mapping that drifts from your chart | Tax codes exist in `l10n_es` but carry no Veri*factu classification |
| Fit to your existing localisation | Built against a copy of your database after scoping your actual configuration | Perfect fit possible, at full discovery and build cost | Generic by design; conflicts with customised `l10n_es` setups are common | Is the baseline, so no conflict — and no coverage |
| Source code and ownership | Full source plus private git repository handed over | You own it, and you own maintaining it alone | Often obfuscated or licence-key gated | Open source, but the functionality is absent |
| Version and edition coverage | Built for your exact series — 17.0, 18.0 or 19.0, Community or Enterprise | Whatever you pay to build and then re-pay to upgrade | Usually one or two versions; Community support inconsistent | SII slice is Enterprise-only; Community has no path |
| Time and cost to live | 2-4 weeks from confirmed scope, fixed quoted scope, UAT on staging with rollback plan | Months, open-ended, discovery cost paid entirely by you | Installs in minutes; the fit and rejection gaps surface at the first filing | Immediate but incomplete — the gap moves to spreadsheets |
This is a build-to-order module, so nothing ships the moment you click. Typical delivery is 2-4 weeks from confirmed scope. The clock starts when we have agreed the scope in writing after the scoping call — not when the enquiry arrives. What moves you within that range is usually the state of your master data: if your `account.tax` rows and partner NIF data are clean, we are at the fast end; if tax mapping needs remediation across a long product and tax catalogue, we are at the slow end. We tell you which case you are in during scoping, before you commit.
Both, and we handle the difference explicitly at scoping. On Enterprise, `l10n_es_edi_sii` already provides part of the SII transport, and where it fits your setup we extend and reuse it rather than duplicating it. On Community there is no SII path in core, so we implement the transport layer as part of the build. The functional result is the same; the internals and therefore the effort differ, which is why we confirm your edition before quoting.
Delivery includes a post-go-live support window for defect fixes within the scope we agreed — if the module does not do what the signed scope says it does, we fix it. Because you receive the full source and the git repository, you are never locked in. Regulatory changes and Odoo major-version upgrades are separate engagements: Spanish requirements evolve, and we scope and quote that work when it arrives rather than promising open-ended free maintenance we could not honestly deliver.
That is exactly what the scoping call is for. We build against a copy of your database, so we see your actual tax rows, fiscal positions, journals and any existing localisation customisations before writing code. The module depends on `l10n_es` and extends `account.move` rather than replacing it, and tax mapping reads your existing master data instead of imposing its own. If we find a genuine conflict, you hear about it during scoping, not during UAT.
The record moves to a `rejected` state, the AEAT error code and message are stored and shown in a dedicated tab on the invoice form, and an activity is raised on the responsible accountant so a person is assigned rather than an error going into a log file. From there you either fix the underlying master data and resubmit, or issue a `factura rectificativa` through the extended credit note flow, which carries the correct rectification type, reason and reference to the original record.
We build the configuration and the transport, and we document exactly where the certificate lives and how it is referenced. We do not take custody of your certificate or your AEAT credentials — your team installs them on your own infrastructure. During UAT on staging we validate the connection with whatever test arrangement your setup allows, so the first production submission is not the first time the pipeline runs.
Yes. The compliance records are ordinary Odoo models, so submission state, AEAT acknowledgements and error codes are readable over the standard XML-RPC and JSON-RPC API, subject to the same access rights and record rules as any other model. Group consolidation tools, a Power BI dataset, or an internal reconciliation script can read them without touching the database directly.

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 every posted customer invoice into a Veri*factu-compliant record and keeps your SII ledgers submitted, acknowledged and reconciled from inside Odoo. ECOSIRE scopes, builds, installs and supports it for your Odoo 17.0, 18.0 or 19.0 database.