| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Invoicing (account)
• Discuss (mail) |
| Lines of code | 1043 |
| Technical Name |
l10n_lk_vat |
| License | LGPL-3 |
| Website | https://www.beaver-hub.com |
| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Invoicing (account)
• Discuss (mail) |
| Lines of code | 1043 |
| Technical Name |
l10n_lk_vat |
| License | LGPL-3 |
| Website | https://www.beaver-hub.com |
l10n_lk_vat
Description
l10n_lk_vat adds gazette-compliant invoicing to Odoo 19 for businesses registered under the Value Added Tax Act, No. 14 of 2002, Sri Lanka. It implements the complete "Tax Invoice Specification" (Annexure I) published in the Extraordinary Gazette notification No. 2481/22, Friday, March 27, 2026 (effective 1 January 2026), covering all supplier obligations.
Every customer invoice, credit note and debit note gets an auto-generated gazette serial number in
YYMMM_QQQQ_XXXXX format,
and the printed A4 PDF switches its title and layout to TAX INVOICE, TAX CREDIT NOTE
or TAX DEBIT NOTE automatically based on document type.
The module is per-company: a single Odoo database can have Sri Lanka VAT–enabled companies alongside companies that use standard Odoo invoicing, with zero cross-contamination.
ird.gov.lk/en/publications/sitepages/Gazette.aspxProduct Screenshots
Prints YYMMM_QQQQ_XXXXX serial at the top, all required IRD fields in independently boxed sections, dates in MM/DD/YYYY format, total in words, and a true repeating page footer with page numbers.
Same gazette layout with title auto-switched to TAX CREDIT NOTE. Additionally prints Original Invoice No. and Original Invoice Date for full traceability. Independent serial counter from Tax Invoices.
Same gazette layout with title auto-switched to TAX DEBIT NOTE. Prints Original Invoice No. and Date from the originating invoice. Independent serial counter from Tax Invoices and Credit Notes.
Reprint of any posted Tax Invoice, Credit Note or Debit Note. Identical to the original but overlaid with a red circular "COPY ONLY" stamp. Original serial number is preserved - no new number consumed. Requires a mandatory reason before printing.
Per-company kill switch in Accounting settings. The "Configure VAT Invoice Layout" button opens the three-tab wizard directly - no code changes, no restarts.
Layout: template selector, logo on/off, VAT rate. Signature: signatory name, designation, wet-signature box toggle. Footer: free text - bank details, payment terms.
IRD Gazette Requirements Implemented
Maps every IRD obligation to the concrete module implementation.
| IRD Requirement | Module Implementation |
|---|---|
| Document prominently titled "Tax Invoice" (or Credit/Debit Note) | Bold bordered title box - auto-switches to TAX CREDIT NOTE / TAX DEBIT NOTE by document type |
| Supplier TIN, name, address, telephone - top-left | Rendered from res.company: VAT/TIN, name, address, phone |
| Purchaser TIN, name, address, telephone - top-right | Rendered from invoice's partner_id: name, address, VAT, phone |
Invoice serial number - YYMMM_QQQQ_XXXXX, ≤40 chars, no spaces |
Custom sequence.mixin override - monthly reset, isolated per document type and journal unit code |
| Date of Invoice - MM/DD/YYYY | Formatted via strftime('%m/%d/%Y') in QWeb report |
| Place of Supply | New field l10n_lk_place_of_supply on account.move - defaults to company city, editable per invoice in draft |
| Date of Delivery - MM/DD/YYYY | Odoo's native taxable_supply_date field surfaced, formatted MM/DD/YYYY |
| Description of supply, quantity, unit of measure | Standard Odoo invoice lines: name, quantity, product_uom_id |
| Value of Supply - net, VAT amount, total, total in words - stated in LKR with cents (2 decimal places), per the gazette amendment | Total Value of Supply, "VAT Amount @ 18%", Total incl. VAT, amount in words (optional, on by default) - shown at full precision, matching the line items, no rounding applied |
| Mode of Payment | New selection field l10n_lk_mode_of_payment - 7 gazette-defined options |
| Additional information of the supply | Free-text box using the invoice's narration / notes field |
| Supplier must retain a duplicate; reprints must be clearly marked and auditable | "Print Copy" wizard: mandatory reason, red "COPY ONLY" stamp on PDF, l10n_lk_copy_count counter, permanent chatter log |
Core Features
- Format
YYMMM_QQQQ_XXXXX- ≤40 chars, no spaces - Monthly counter reset (prefix changes with
YYMMM) - Counter isolated per document type - invoices, credit notes and debit notes each have their own independent sequence
- Journal-level
QQQQunit code configurable per branch/department - Sequence prefix derived from invoice date, not posting date
- Completely separate QWeb template - does not use
web.external_layout - Independently boxed supplier (left) and purchaser (right) sections
- True repeating page footer with page numbers (Page X of Y)
- Auto-switches title: TAX INVOICE / TAX CREDIT NOTE / TAX DEBIT NOTE
- Optional authorised signatory box at bottom for wet signature
- Red circular "COPY ONLY" stamp for reprints
- Patches
ir.actions.report._build_wkhtmltopdf_args()to force--encoding utf-8 - Eliminates the known Qt mojibake bug:
ft³ → ft³ - Requires the patched-Qt build of wkhtmltopdf (0.12.5 recommended by Odoo)
- For purchasers who are not VAT-registered, a Tax Invoice is not the correct document - this toggle switches that specific invoice to Odoo's standard layout instead
- Boolean toggle
l10n_lk_print_as_tax_invoiceon every invoice, default On - Off falls back to Odoo's standard invoice layout for that document only
- Single source of truth for the Print button, the cog-wheel Print menu, and the Send & Print wizard
- Never touches Odoo's global "Invoice PDF" action - other companies in the same database are unaffected
- Does not affect the gazette serial number - numbering stays governed solely by the kill switch
- "Print Copy" button visible only on posted documents
- Opens wizard - reason is mandatory before printing
- Increments
l10n_lk_copy_count(read-only on invoice form) - Posts permanent chatter message: user, timestamp, reason, copy number
- PDF retains original sequence number - no new number consumed
- Does not re-trigger accounting entries or touch related documents
- Accessed via Settings → Sri Lanka VAT Compliance → "Configure VAT Invoice Layout"
- Layout tab: show/hide company logo (gazette format does not require it), VAT rate, show/hide total amount in words
- Signature tab: signatory name, designation, blank signature box toggle
- Footer tab: free text - bank details, payment terms, etc.
- All settings stored on
res.company- apply immediately to next print
l10n_lk_vat_enabledboolean onres.company- When
False: gazette numbering and layout fully bypassed - standard Odoo invoicing unchanged - Safe to install on multi-company databases where only some entities are LK VAT registered
- Per-company configuration - no global settings
- 76 unit tests using
AccountTestInvoicingCommon, taggedpost_install - Covers: sequence generation, monthly reset, counter isolation, copy guards, field defaults, print-toggle redirects, wizard write-through
- pylint-odoo compliant, ruff-formatted
- No external Python dependencies beyond Odoo core
Invoice Numbering Format
| Segment | Meaning | Example | Notes |
|---|---|---|---|
YY |
Last 2 digits of the invoice year | 26 |
Derived from the invoice date - not the posting date |
MMM |
First 3 letters of the invoice month, uppercase | JAN, JUN |
Counter resets to 00001 each time this changes |
QQQQ |
Alphanumeric branch/unit code - configured per journal | HEAD, BR03 |
Set on the Sales Journal (l10n_lk_vat_unit_code) - mandatory once LK VAT is enabled |
XXXXX |
Zero-padded numeric running counter | 00001, 00042 |
Always ≥5 digits; resets every calendar month |
YYMMM changes, the counter starts from 00001 again.Configuration
Enable VAT Compliance for a Company
Toggle "Enable Sri Lanka VAT Compliance" on. This is a per-company field - other companies in the database are unaffected until you enable it for them too.
YYMMM_QQQQ_XXXXX numbering.
Every other company keeps printing Odoo's standard invoice, completely unaffected.
Open each Sales journal and set the VAT Unit Code (e.g. HEAD, BR03). This field is mandatory - Odoo will block saving the journal without it.
Opens the three-tab wizard. Layout: show/hide logo. Signature: signatory name, designation, blank signature box toggle. Footer: free text printed in the repeating page footer - use for bank details or payment terms.
Per-Invoice Fields
Place of Supply: defaults to company city; edit if the delivery origin differs. Mode of Payment: select from Cash, Bank Transfer, Cheque, Credit Card, Debit Card, Mobile Payment, or Online Payment. Both are locked once the invoice is confirmed. Print as Tax Invoice: on by default - turn off when the purchaser is not VAT-registered and a Tax Invoice is not the correct document, to print Odoo's standard layout instead. Editable at any time.
Issuing a COPY ONLY Reprint
A wizard opens - enter a mandatory reason. Click Print Copy. The PDF is generated with the original sequence number unchanged but with a red "COPY ONLY" stamp. The copy counter increments and a permanent chatter message records the event. No new accounting entries, no new sequence number consumed.
Requirements & Installation
Odoo & Python
- Odoo version: 19.0 (Community or Enterprise)
- Python: no additional pip packages - Odoo core only
Module Dependencies
account- invoicing baseaccount_debit_note- provides "Add Debit Note" actionl10n_lk- Sri Lanka chart of accounts localization
System Dependency
wkhtmltopdf- already required by Odoo for any PDF report- Recommended: wkhtmltopdf 0.12.5 with patched Qt (Odoo's recommended build)
- The module's UTF-8 fix patches the args - if you still see garbled characters, confirm the binary version
Installation
- Copy
l10n_lk_vat/into youraddons_path - Restart Odoo or update the apps list
- Search for "Sri Lanka VAT Invoice Compliance" in Apps → Install
- Configure as described above - no demo data or default sequences are created on install
Running the Test Suite
All tests are tagged post_install. Use -u (update) to trigger them - -i (install) is a no-op when the module is already installed.
| Test file | What it covers |
|---|---|
tests/test_sequence.py |
Gazette sequence format, monthly reset, counter isolation per document type |
tests/test_copy.py |
COPY ONLY counter, wizard guards, copy-mode context bypass security fix |
tests/test_fields.py |
Field defaults, VAT rate constraints, journal unit-code constraint, wizard write-through |
tests/test_printing.py |
Print-as-Tax-Invoice toggle redirect at the Print button, report_action(), and the cog-wheel/Send wizard chokepoint |
-d test_mydb) so test data does not pollute your production instance.
l10n_lk_place_of_supply, l10n_lk_mode_of_payment, l10n_lk_copy_count, etc.) and their historical data. To revert a single company to standard invoicing without uninstalling, simply disable the kill switch.Known Issues & Troubleshooting
ft³ instead of ft³)
Known wkhtmltopdf/Qt bug where locally-loaded HTML is mis-detected as Latin-1. This module patches ir.actions.report._build_wkhtmltopdf_args() to force --encoding utf-8. If you still see corrupted characters, confirm your wkhtmltopdf binary is the patched-Qt build (version 0.12.5).
invoice_date is correct before posting - the prefix is locked in at the moment of sequence assignment.
Release Notes
- Gazette
YYMMM_QQQQ_XXXXXserial number - auto-assigned on post, monthly reset, scoped per journal unit code - Full A4 QWeb PDF report - Tax Invoice, Tax Credit Note, Tax Debit Note with all IRD-required fields
- LKR totals shown with cents (2 decimal places), per the amended Clause 4.1.g
- Total amount in words - optional, toggleable per company (on by default)
- Repeating page footer with page numbers on every printed page
- Red COPY ONLY circular stamp on reprints (Clause 6.2)
- Original invoice reference block on Credit Notes and Debit Notes
- Three-tab VAT Layout Designer wizard - logo, VAT rate, signatory, footer text, total-in-words visibility
- Place of Supply field - defaults to company city, editable per invoice (Clause 4.1.c)
- Mode of Payment - seven gazette-specified options (Clause 4.1.h)
- Per-invoice Print as Tax Invoice toggle - one source of truth for the Print button, Print menu, and Send & Print wizard
- COPY ONLY reprint audit trail - requires reason, logs to chatter, increments copy counter
- Per-company kill switch - safe in multi-company databases
- Global UTF-8 fix for wkhtmltopdf; 76 automated tests
About Beaver Hub
Beaver Hub is a Sri Lanka–based Odoo implementation and development company. We build production-ready modules focused on accuracy, maintainability, and long-term support.
l10n_lk_vat was developed directly from the IRD gazette - every field label, date convention, sequence format, and label wording is gazette-traced, not approximated. We maintain this as a free, open-source contribution to the Sri Lanka Odoo community.
Got a Challenging Odoo Project?
We take on the hard ones. Beaver Hub delivers end-to-end Odoo services for businesses that need it done right.
No 24, Angampitiya Road
Ethulkotte, Colombo
Beaver Hub (Pvt) Ltd - Sri Lanka | beaver-hub.com
© 2026 Beaver Hub (Pvt) Ltd · Released under LGPL-3 · Module version 19.0.1.0.0 · Odoo 19.0 · Legal basis: IRD Gazette Extraordinary No. 2481/22, Friday, March 27, 2026, effective 01 January 2026
Please log in to comment on this module