OdooWiki OCA HUB

Thai Localization - VAT and Withholding Tax

l10n_th_account_tax folder_open OCA/l10n-thailand open_in_new
Localization / Accounting License: AGPL-3

This module address 2 main tax requirement in Thailand

  • Tax Invoice (VAT)

Point of tax invoice can occur either on Invoice (VAT) or on Payment (Undue VAT on invoice become VAT on payment)

  • Withholding Tax

This is the tax that is deducted during payment. There are 2 kinds of withholding tax calculataion.

  • Fixed rate of based amount, i.e., service 3%
  • Progressive rate of accumulated amount, i.e., personal income tax

auto_awesome What this module does

AI-generated from the code · Odoo 19.0

Adds Thai VAT tax invoice tracking and withholding tax handling to Odoo invoices and payments, including automatic withholding calculation, withholding tax certificates, and personal income tax (PIT) progressive rates.

This module extends Odoo accounting for Thai tax requirements. On customer invoices and vendor bills, each tax line can carry a tax invoice number and date, and users can also flag individual journal items to create a tax invoice manually. When a document is posted, the system fills in tax invoice numbers and dates automatically, using a dedicated sequence configured on the tax when available.

For withholding tax, products and vendors can carry default withholding tax settings. When a payment is registered, the withholding amount is computed automatically, either as a fixed percentage of the base or, for personal income tax, using progressive PIT rate tables by calendar year. The withholding is deducted from the payment and recorded as withholding moves.

Users can create withholding tax certificates from a payment or journal entry, grouped by vendor and type of income, and follow their status (draft, done, cancelled). Certificates can be printed and managed from dedicated menus. The module also adds a Clear Tax wizard for payments where tax is due on payment, and a yearly PIT summary action on partners. Configuration includes marking accounts as withholding accounts, setting tax invoice numbering options, and keeping zero tax lines.

Depends on

account

Menus it adds

Thai Accounting ReportsPersonal Income Taxmenu_action_tax_invoicemenu_action_withholding_tax_movemenu_account_withholding_taxPIT Ratemenu_withholding_tax_certmenu_withholding_tax_income_code
Models and fields (21)
  • clear.tax · new modeldate (Accounting Date (Tax Cash Basis)), payment_id (Payment)
  • account.tax · extends an existing modeltaxinv_sequence_id (Tax Invoice Sequence), sequence_number_next (Next Number)
  • res.company · extends an existing modeltax_zero_line (Keep Zero Line Taxes), customer_tax_invoice_number (Customer Tax Invoice Number (Undue VAT))
  • res.partner · extends an existing modelpit_move_ids (Personal Income Tax)
  • account.move · extends an existing modelhas_wht, wht_cert_ids (Withholding Tax Cert.), wht_move_ids (Withholding), tax_invoice_ids, wht_cert_status
  • account.account · extends an existing modelwht_account (WHT Account)
  • account.payment · extends an existing modelhas_wht, pit_move_ids (Personal Income Tax), to_clear_tax, wht_cert_ids (Withholding Tax Cert.), wht_move_ids (Withholding), tax_invoice_ids, wht_cert_status, wht_certs_count (# Withholding Tax Certs), tax_invoice_move_ids (Tax Invoice's Journal Entry)
  • product.template · extends an existing modelwht_tax_id (Withholding Tax), supplier_wht_tax_id (Individual Vendor Withholding Tax), supplier_company_wht_tax_id (Company Vendor Withholding Tax)
  • account.move.line · extends an existing modelwht_tax_id (WHT), tax_invoice_ids, manual_tax_invoice
  • personal.income.tax · new modelactive, rate_ids (Withholding Tax Rates), calendar_year, effective_date
  • res.config.settings · extends an existing modeltax_zero_line, customer_tax_invoice_number
  • withholding.tax.cert · new modeldate, name (Number), state (Status), number (WHT Number), move_id, wht_line (Withholding Line), tax_payer, verify_by, company_id (Main Company), partner_id (Vendor), payment_id (Payment), company_vat (Company Tax ID), currency_id (Currency), partner_vat (Vendor Tax ID), income_tax_form, ref_wht_cert_id (Ref WHT Cert.), company_partner_id (Company)
  • account.move.reversal · extends an existing modeltax_invoice_date, tax_invoice_number
  • account.withholding.tax · new modelname, amount (Percent), is_pit (Personal Income Tax), pit_id (PIT Rate), account_id (Withholding Tax Account), company_id, income_tax_form (Default Income Tax Form), wht_cert_income_type (Default Type of Income)
  • account.move.tax.invoice · new modelbalance (Tax Amount), move_id, account_id, company_id, move_state, partner_id (Partner), payment_id, report_date, reversed_id, tax_line_id, move_line_id, reversing_id, to_clear_tax, report_late_mo (Report Late), tax_base_amount (Tax Base), tax_invoice_date, tax_invoice_number, company_currency_id
  • account.payment.register · extends an existing modelwht_tax_id (Withholding Tax), wht_amount_base (Withholding Base)
  • account.withholding.move · new modeldate, is_pit, cert_id (Withholding Cert.), move_id (Journal Entry), cancelled, amount_wht (Withholding Amount), company_id (Company), partner_id (Vendor), payment_id (Payment), wht_tax_id, currency_id, amount_income (Income), calendar_year, payment_state, wht_cert_income_desc (Income Description), wht_cert_income_type (Type of Income)
  • personal.income.tax.rate · new modelpit_id (PIT Table), sequence (sequence), tax_rate (Tax Rate (%)), income_to (Income To (<=)), income_from (Income From (>)), amount_tax_max (Maximum Tax in Range), amount_tax_accum (Tax Accumulate)
  • account.partial.reconcile · extends an existing model
  • withholding.tax.cert.line · new modelbase (Base Amount), amount (Tax Amount), cert_id (WHT Cert), company_id, wht_tax_id (Tax), wht_percent (% Tax), wht_income_tax_form, wht_cert_income_code (Income Code), wht_cert_income_desc (Income Description), wht_cert_income_type (Type of Income), wht_cert_bank_account (Bank Account)
  • withholding.tax.code.income · new modelcode, name, is_default (Default), income_tax_form, wht_cert_income_type (Type of Income)

Text generated by AI (DeepSeek) from reading the Odoo 19.0 code on GitHub; it may contain mistakes, so check the code before deciding. The module is very large and only part of the code was read. View the code on GitHub

Availability by version

Reviewed: 2026-11-03
Confirmed (verified in repository and branch) Estimated (unverified) No information

Confirmation status: 4 confirmed, 5 with no information of 9 versions.

Sources · Odoo 19.0

Confirmed on 2026-11-03 in branch 19.0 of OCA/l10n-thailand.

terminal Installation and usage

OCA documentation · Odoo 19.0

Tax Invoices

Preparing Undue Tax

  • Use Developer Mode
  • In Chart of Account, add new account for Undue Tax, if not already exists.
  • As admin, add access rights Show Full Accounting Features
  • Go to Invoicing \> Configuration \> Settings and select Cash Basis, this will open cash basis options in Tax master data
  • Go to Invoicing \> Configuration \> Accounting \> Taxes, create new undue tax for both sales and purchase

For Sales Taxes (tax scope = Sales), there is option to run Tax Invoice number by sequence model. If set properly, Tax Invoice Number will be using this sequence instead of customer invoice number / payment number

  • Goto Invoicing \> Configuration \> Accounting \> Taxes
  • For sales tax, choose 'Tax Invoice Sequence' (or create new one)
  • Make sure you also set the same sequence for the same tax on payment too. I.e., Output VAT7% and Undue Output VAT7% must select the same sequence, both of them will result in same Tax Report

Note: this option is not avaiable for purchase tax, because the Tax Invoice Number is from vendor, and are filled manually.

Preparing Zero Tax Line

If you want tax lines with zero amount (such as 0% tax) to be shown in journal entries, follow these steps:

  • Go to Invoicing \> Configuration \> Settings and select Keep Zero Line Taxes,
  • Create an invoice or bill and select a tax with 0% rate
  • Go to Journal Items, and you will see a tax line created with zero value

Withholding Tax and Personal Income Tax (PIT)

Setup account related to withholding tax will help set default tax amount when create certificate from payment.

  • Go to Invoicing \> Configuration \> Accounting \> Chart of Accounts
  • Search for withholding tax related account \> Setup
  • Check "WHT Account"
  • Go to Invoicing \> Configuration \> Accounting \> Withholding Tax
  • Create withholding Tax (normal and personal income tax)

Configured Withholding Tax by Product (optional)

  • Go to Invoicing \> Customers or Vendors \> Products
  • Select product that you need withholding tax
  • Add Withholding Tax on General Information Tab (Invoices) / Purchase Tab (Bills)

Configure Personal Income Tax Rate

  • Go to Invoicing \> Configuration \> Accounting \> PIT Rate
  • Change range or tax rate (if any)

Configure PIT Withholding Tax as following,

  • Go to Invoicing \> Configuration \> Accounting \> Withholing Tax
  • Create new Withholding Tax for PIT and check Personal Income Tax checkbox
  • PIT Rate that will be used to calculate the withholding amount will be shown
  • You can set default Withholding Tax on the Product's Purchase Tab

Tax Invoice

With this, 2 new tax related fields will be introduced in account.move.tax.invoice

  • tax_invoice_number : Tax Invoice Number
  • tax_invoice_date : Tax Invoice Date

In customer invoice, both field will be defaulted by Odoo's document number and date. But in supplier invoice, both field must be filled by user with tax invoice number and date from vendor.

Note: The new table account.move.tax.invoice is the main source of Thai VAT Report

Case Customer Invoice and Payment

  • Create new customer invoice and choose to use sales' VAT or Undue VAT
  • Process invoice and payment as per normal, Odoo document number and date should be used as Tax Invoice Number/Date

Case Supplier Invoice/Payment

1) Case Input VAT

  • Create new vendor bill and choose Input VAT
  • At vendor bill's tax invoice tab, fill in 2 new fields, Tax Invoice and Tax Date given by your vendor
  • Validate this vendor bill, the given Tax Invoice Number and Tax Date are set in account.move.tax.invoice

2) Case Undue Input VAT

  • Create new vendor bill and choose Undue Input VAT
  • Validate vendor bill, journal entry will be created with Undue VAT
  • Register payment as per normal, this will create new payment document as per normal
  • From this process, the journal entry (cash basis) for clear undue is created, but it will be in state Draft
  • Go to payment document, in tax invoice tab, fill in Tax Invoice Number and Tax Date
  • Click on Clear VAT button, the journal entry (cash basis) for clear undue will now be Posted

Withholding Tax

From bills / invoices that require withheld tax,

  • Create invoice and Fill withholding tax in Field WT at Invoice Lines tab.
  • Post \> Register Payment.
  • System will auto computed amount include withholding tax.

Note

  • if you configured withholding tax on product, it fill withholding tax in field WT automatic.
  • for invoices with withholding tax, > - you can't make payment to multiple invoices belongs to multiple > partners. > - you can only make payment to multiple invoices belongs to the same > partner (using Group Payments).

No verified information in OCA: Installation.

info

Data imported from GitHub: this sheet reflects the latest catalog review, not a live lookup. Always check the module documentation and staging before installing in production.