TIP: You can type at any time to perform a new search.
Thai Localization - VAT and Withholding Tax
l10n_th_account_tax · OCA/l10n-thailand
- Repository
- OCA/l10n-thailand · module folder · Try on Runboat
- Module version
- 1.0.0
- Category
- Localization / Accounting
- Folder size
- 0.33 MB
- License
- AGPL-3
- Application
- No
- Auto-installable
- No
- Website
- https://github.com/OCA/l10n-thailand
- Last tracking update
- 2026-08-17 05:29:05
- Authors
- Odoo Community Association (OCA), Ecosoft
- Maintainers
- Odoo Community Association (OCA), Ecosoft
- Committers
- OCA-git-bot, oca-ci, monthop-gmail
- Odoo dependencies
- Python dependencies
- None
- System dependencies
- None
- Required by
- None
- Description
This module address 2 main tax requirement in Thailand ## 1. Tax Invoice (VAT) Point of tax invoice can occur either on Invoice (VAT) or on Payment (Undue VAT on invoice become VAT on payment) ## 2. Withholding Tax This is the tax that is deducted during payment. There are 2 kinds of withholding tax calculataion. 1. Fixed rate of based amount, i.e., service 3% 2. Progressive rate of accumulated amount, i.e., personal income tax
Code Analysis ⓘ
Views touched (30)
| XML ID | Name | Model | Type | Status |
|---|---|---|---|---|
product_template_form_view |
product.template.form.inherit | product.template | form | Inherits product.product_template_form_view |
res_config_settings_view_form |
res.config.settings.view.form.thai.account | res.config.settings | form | Inherits account.res_config_settings_view_form |
view_account_form |
view.account.form | account.account | form | Inherits account.view_account_form |
view_account_move_reversal |
account.move.reversal.form | account.move.reversal | form | Inherits account.view_account_move_reversal |
view_account_payment_form |
account.view.account.payment.form | account.payment | form | Inherits account.view_account_payment_form |
view_account_payment_register_form |
account.payment.register.form | account.payment.register | form | Inherits account.view_account_payment_register_form |
view_account_payment_search |
account.payment.search | account.payment | search | Inherits account.view_account_payment_search |
view_account_withholding_tax_form |
view.account.withholding.tax.form | account.withholding.tax | form | New |
view_account_withholding_tax_income_code_form |
view.withholding.tax.income.code.form | withholding.tax.code.income | form | New |
view_account_withholding_tax_income_code_list |
view.withholding.tax.income.code.list | withholding.tax.code.income | list | New |
view_account_withholding_tax_income_code_search |
view.withholding.tax.income.code.search | withholding.tax.code.income | search | New |
view_account_withholding_tax_list |
view.account.withholding.tax.list | account.withholding.tax | list | New |
view_account_withholding_tax_search |
view.account.withholding.tax.search | account.withholding.tax | search | New |
view_clear_tax_form |
clear.tax.form | clear.tax | form | New |
view_move_form |
account.move.form | account.move | form | Inherits account.view_move_form |
view_partner_property_form |
res.partner.property.form.inherit | res.partner | form | Inherits account.view_partner_property_form |
view_personal_income_tax_form |
view.personal.income.tax.form | personal.income.tax | form | New |
view_personal_income_tax_list |
view.personal.income.tax.list | personal.income.tax | list | New |
view_pit_move_graph |
view.account.withholding.move.graph | account.withholding.move | graph | New |
view_pit_move_pivot |
view.account.withholding.move.pivot | account.withholding.move | pivot | New |
view_tax_form |
account.tax.form | account.tax | form | Inherits account.view_tax_form |
view_tax_invoice_form |
account.move.tax.invoice | form | New | |
view_tax_invoice_list |
account.move.tax.invoice | list | New | |
view_tax_invoice_search |
account.move.tax.invoice | search | New | |
view_wht_move_form |
view.account.withholding.move.form | account.withholding.move | form | New |
view_wht_move_list |
view.account.withholding.move.list | account.withholding.move | list | New |
view_wht_move_search |
view.account.withholding.move.search | account.withholding.move | search | New |
view_withholding_tax_cert_form |
view.withholding.tax.cert.form | withholding.tax.cert | form | New |
view_withholding_tax_cert_list |
view.withholding.tax.cert.list | withholding.tax.cert | list | New |
view_withholding_tax_cert_search |
view.withholding.tax.cert.search | withholding.tax.cert | search | New |
HTTP endpoints (0)
No HTTP endpoints found for this module.
Models touched (21)
New fields (1)
-
wht_accountBooleandefault=Falsehelp='If check, this account is for withholding tax'string='WHT Account'
No public methods.
New fields (5)
-
has_whtBooleancompute='_compute_has_wht' -
tax_invoice_idsOne2many → account.move.tax.invoicecomodel_name='account.move.tax.invoice'copy=Falseinverse_name='move_id' -
wht_cert_idsOne2many → withholding.tax.certcomodel_name='withholding.tax.cert'inverse_name='move_id'readonly=Truestring='Withholding Tax Cert.' -
wht_cert_statusSelectioncompute='_compute_wht_cert_status'selection=[('none', 'Not yet created'), ('draft', 'Draft'), ('done', 'Done'), ('cancel', 'Cancelled')] -
wht_move_idsOne2many → account.withholding.movecomodel_name='account.withholding.move'copy=Falsehelp='All withholding moves, including non-PIT'inverse_name='move_id'string='Withholding'
-
button_cancel(self) -
button_draft(self) -
button_wht_certs(self) -
copy(self, default=None)For case reverse move, Tax number and date must have value from wizard reversal. -
create_wht_cert(self)Create/replace one withholding tax cert from withholding move Group by partner and income type, regardless of wht_tax_id -
js_assign_outstanding_line(self, line_id) -
js_remove_outstanding_partial(self, partial_id)
New fields (3)
-
manual_tax_invoiceBooleancopy=Falsehelp='Create Tax Invoice for this debit/credit line' -
tax_invoice_idsOne2many → account.move.tax.invoicecomodel_name='account.move.tax.invoice'inverse_name='move_line_id' -
wht_tax_idMany2one → account.withholding.taxcheck_company=Truecomodel_name='account.withholding.tax'compute='_compute_wht_tax_id'readonly=Falsestore=Truestring='WHT'
-
create(self, vals_list)@api.model_create_multi -
write(self, vals)
New fields (2)
-
tax_invoice_dateDatecopy=False -
tax_invoice_numberCharcopy=False
-
reverse_moves(self, is_modify=False)
New fields (18)
-
account_idMany2one → account.accountcomodel_name='account.account'related='move_line_id.account_id'store=True -
balanceMonetarycompute='_compute_tax_amount'copy=Falsecurrency_field='company_currency_id'readonly=Falsestore=Truestring='Tax Amount' -
company_currency_idMany2one → res.currencycomodel_name='res.currency'related='company_id.currency_id' -
company_idMany2one → res.companycomodel_name='res.company'related='move_id.company_id'store=True -
move_idMany2one → account.movecomodel_name='account.move'copy=Trueindex=True -
move_line_idMany2one → account.move.linecomodel_name='account.move.line'copy=Trueindex=Trueondelete='cascade' -
move_stateSelectionrelated='move_id.state'store=True -
partner_idMany2one → res.partnercomodel_name='res.partner'ondelete='restrict'string='Partner' -
payment_idMany2one → account.paymentcomodel_name='account.payment'compute='_compute_payment_id'copy=Truestore=True -
report_dateDatecompute='_compute_report_date'store=True -
report_late_moSelectiondefault='0'required=Truestring='Report Late' args: [('0', '0 month'), ('1', '1 month'), ('2', '2 months'), ('3', '3 months'), ('4', '4 months'), ('5', '5 months'), ('6', '6 months')] -
reversed_idMany2one → account.movecomodel_name='account.move'help='This move that this move reverse' -
reversing_idMany2one → account.movecomodel_name='account.move'help='The move that reverse this move' -
tax_base_amountMonetarycompute='_compute_tax_amount'copy=Falsecurrency_field='company_currency_id'readonly=Falsestore=Truestring='Tax Base' -
tax_invoice_dateDatecopy=False -
tax_invoice_numberCharcopy=False -
tax_line_idMany2one → account.taxcomodel_name='account.tax'related='move_line_id.tax_line_id'store=True -
to_clear_taxBooleanrelated='payment_id.to_clear_tax'
No public methods.
New fields (0)
No new fields.
Public methods (0)No public methods.
New fields (9)
-
has_whtBooleancompute='_compute_has_wht' -
pit_move_idsOne2many → account.withholding.movecomodel_name='account.withholding.move'copy=Falsedomain=[('is_pit', '=', True)]inverse_name='payment_id'string='Personal Income Tax' -
tax_invoice_idsOne2many → account.move.tax.invoicecomodel_name='account.move.tax.invoice'copy=Falsedomain=[('reversing_id', '=', False), ('reversed_id', '=', False)]inverse_name='payment_id' -
tax_invoice_move_idsMany2many → account.movecolumn1='payment_id'column2='tax_invoice_id'comodel_name='account.move'compute='_compute_tax_invoice_move_ids'relation='payment_tax_invoice_rel'string="Tax Invoice's Journal Entry" -
to_clear_taxBooleancopy=Falsedefault=Falsehelp='When defer journal entry posting, this will show button' -
wht_cert_idsOne2many → withholding.tax.certcomodel_name='withholding.tax.cert'inverse_name='payment_id'readonly=Truestring='Withholding Tax Cert.' -
wht_cert_statusSelectioncompute='_compute_wht_cert_status'selection=[('none', 'Not yet created'), ('draft', 'Draft'), ('done', 'Done'), ('cancel', 'Cancelled')] -
wht_certs_countIntegercompute='_compute_wht_certs_count'string='# Withholding Tax Certs' -
wht_move_idsOne2many → account.withholding.movecomodel_name='account.withholding.move'copy=Falsehelp='All withholding moves, including non-PIT'inverse_name='payment_id'string='Withholding'
-
button_open_journal_entry(self)Add tax cash basis when open journal entry -
button_wht_certs(self) -
clear_tax_cash_basis(self) -
create_wht_cert(self) -
open_clear_tax(self)Open Wizard for clear tax with accounting date
New fields (2)
-
wht_amount_baseMonetarycompute='_compute_wht_amount'help='Based amount for the tax amount'readonly=Falsestore=Truestring='Withholding Base' -
wht_tax_idMany2one → account.withholding.taxcheck_company=Truecomodel_name='account.withholding.tax'help='Optional hidden field to keep wht_tax. Useful for case 1 tax only'string='Withholding Tax'
-
action_create_payments(self) -
default_get(self, fields_list)@api.model
New fields (2)
-
sequence_number_nextIntegercompute='_compute_seq_number_next'help='The next sequence number will be used for the next tax invoice.'inverse='_inverse_seq_number_next'string='Next Number' -
taxinv_sequence_idMany2one → ir.sequencecomodel_name='ir.sequence'copy=Falsehelp='Optional sequence as Tax Invoice number'string='Tax Invoice Sequence'
No public methods.
New fields (16)
-
amount_incomeMonetaryrequired=Truestring='Income' -
amount_whtMonetarystring='Withholding Amount' -
calendar_yearCharcompute='_compute_move_data'index=Truestore=True -
cancelledBooleanhelp='For filtering cancelled payment'readonly=True -
cert_idMany2one → withholding.tax.certcheck_company=Truecomodel_name='withholding.tax.cert'copy=Falsereadonly=Truestring='Withholding Cert.' -
company_idMany2one → res.companycomodel_name='res.company'default=<expr>index=Truerequired=Truestring='Company' -
currency_idMany2one → res.currencycomodel_name='res.currency'default=<expr> -
dateDatecompute='_compute_move_data'readonly=Falsestore=True -
is_pitBooleanrelated='wht_tax_id.is_pit'store=True -
move_idMany2one → account.movecomodel_name='account.move'domain=[('state', 'not in', ['draft', 'cancel'])]index=Trueondelete='cascade'required=Truestring='Journal Entry' -
partner_idMany2one → res.partnercomodel_name='res.partner'index=Trueondelete='cascade'required=Truestring='Vendor' -
payment_idMany2one → account.paymentcomodel_name='account.payment'compute='_compute_move_data'domain=[('state', 'not in', ['draft', 'cancel'])]index=Trueondelete='cascade'readonly=Falsestore=Truestring='Payment' -
payment_stateSelectionrelated='payment_id.state' -
wht_cert_income_descCharcompute='_compute_wht_cert_income_desc'readonly=Falsesize=500store=Truestring='Income Description' -
wht_cert_income_typeSelectioncompute='_compute_wht_cert_income_type'readonly=Falsestore=Truestring='Type of Income' args: WHT_CERT_INCOME_TYPE -
wht_tax_idMany2one → account.withholding.taxcheck_company=Truecomodel_name='account.withholding.tax'index=True
No public methods.
New fields (8)
-
account_idMany2one → account.accountcomodel_name='account.account'domain="[('wht_account', '=', True)]"ondelete='restrict'required=Truestring='Withholding Tax Account' -
amountFloatstring='Percent' -
company_idMany2one → res.companycomodel_name='res.company'default=<expr>required=True -
income_tax_formSelectionselection=INCOME_TAX_FORMstring='Default Income Tax Form' -
is_pitBooleanhelp='As PIT, the calculation of withholding amount is based on pit.rate'string='Personal Income Tax' -
nameCharrequired=True -
pit_idMany2one → personal.income.taxcomodel_name='personal.income.tax'compute='_compute_pit_id'help='Latest PIT Rates used to calcuate withholiding amount'string='PIT Rate' -
wht_cert_income_typeSelectionselection=WHT_CERT_INCOME_TYPEstring='Default Type of Income'
No public methods.
New fields (2)
-
dateDatedefault=fields.Date.context_todayrequired=Truestring='Accounting Date (Tax Cash Basis)' -
payment_idMany2one → account.paymentrequired=Truestring='Payment' args: 'account.payment'
-
action_clear_tax(self)
New fields (4)
-
activeBooleandefault=True -
calendar_yearCharcopy=Falsedefault=<expr>required=True -
effective_dateDatecompute='_compute_effective_date'store=True -
rate_idsOne2many → personal.income.tax.ratecomodel_name='personal.income.tax.rate'copy=Trueinverse_name='pit_id'string='Withholding Tax Rates'
-
calculate_rate_wht(self, total_income, income, pit_date) -
copy(self, default=None)
New fields (7)
-
amount_tax_accumFloatcompute='_compute_amount_accum'string='Tax Accumulate' -
amount_tax_maxFloatcompute='_compute_amount_tax_max'store=Truestring='Maximum Tax in Range' -
income_fromFloatstring='Income From (>)' -
income_toFloatstring='Income To (<=)' -
pit_idMany2one → personal.income.taxcomodel_name='personal.income.tax'index=Trueondelete='cascade'string='PIT Table' -
sequenceIntegerstring='sequence' -
tax_rateFloatstring='Tax Rate (%)'
No public methods.
New fields (3)
-
supplier_company_wht_tax_idMany2one → account.withholding.taxcomodel_name='account.withholding.tax'company_dependent=Truedomain="[('company_id', '=', current_company_id)]"help='Default withholding tax for the vendor that is company'string='Company Vendor Withholding Tax' -
supplier_wht_tax_idMany2one → account.withholding.taxcomodel_name='account.withholding.tax'company_dependent=Truedomain="[('company_id', '=', current_company_id)]"help='Default withholding tax for the vendor that is individual'string='Individual Vendor Withholding Tax' -
wht_tax_idMany2one → account.withholding.taxcomodel_name='account.withholding.tax'company_dependent=Truedomain="[('company_id', '=', current_company_id)]"help='Default withholding tax for the customer'string='Withholding Tax'
No public methods.
New fields (2)
-
customer_tax_invoice_numberSelectiondefault='payment'help="It default running tax number by payment\n when user not select 'Tax Invoice Sequence' in taxes"selection=[('payment', 'Customer Payment Number'), ('invoice', 'Customer Invoice Number')]string='Customer Tax Invoice Number (Undue VAT)' -
tax_zero_lineBooleandefault=Truestring='Keep Zero Line Taxes'
No public methods.
New fields (2)
-
customer_tax_invoice_numberSelectionreadonly=Falserelated='company_id.customer_tax_invoice_number' -
tax_zero_lineBooleanreadonly=Falserelated='company_id.tax_zero_line'
No public methods.
New fields (1)
-
pit_move_idsOne2many → account.withholding.movecomodel_name='account.withholding.move'domain=<expr>inverse_name='partner_id'string='Personal Income Tax'
-
action_view_pit_move_yearly_summary(self) -
button_wht_certs(self)
New fields (17)
-
company_idMany2one → res.companycomodel_name='res.company'default=<expr>required=Truestring='Main Company' -
company_partner_idMany2one → res.partnercomodel_name='res.partner'copy=Falsedefault=<expr>ondelete='restrict'string='Company' -
company_vatCharrelated='company_partner_id.vat'string='Company Tax ID' -
currency_idMany2one → res.currencycomodel_name='res.currency'related='company_id.currency_id'store=Truestring='Currency' -
dateDatecompute='_compute_wht_cert_data'required=Truestore=Truetracking=True -
income_tax_formSelectioncopy=Falseselection=INCOME_TAX_FORMtracking=True -
move_idMany2one → account.movecomodel_name='account.move'copy=Falsedomain="[('journal_id.type', '=', 'general'), ('state', '=', 'posted')]"ondelete='restrict'tracking=True -
nameCharcompute='_compute_wht_cert_data'store=Truestring='Number'tracking=True -
numberCharcopy=Falsedefault='/'readonly=Truerequired=Truestring='WHT Number' -
partner_idMany2one → res.partnercomodel_name='res.partner'ondelete='restrict'required=Truestring='Vendor'tracking=True -
partner_vatCharrelated='partner_id.vat'string='Vendor Tax ID' -
payment_idMany2one → account.paymentcomodel_name='account.payment'copy=Falsedomain="[('partner_id', '=', partner_id)]"ondelete='restrict'string='Payment'tracking=True -
ref_wht_cert_idMany2one → withholding.tax.certcheck_company=Truecomodel_name='withholding.tax.cert'help='This field related from Old WHT Cert.'string='Ref WHT Cert.'tracking=True -
stateSelectioncopy=Falsedefault='draft'selection=[('draft', 'Draft'), ('done', 'Done'), ('cancel', 'Cancelled')]string='Status'tracking=True -
tax_payerSelectioncopy=Falsedefault='withholding'required=Trueselection=TAX_PAYERtracking=True -
verify_byMany2one → res.userscomodel_name='res.users'copy=Falsetracking=True -
wht_lineOne2many → withholding.tax.cert.linecomodel_name='withholding.tax.cert.line'copy=Falseinverse_name='cert_id'string='Withholding Line'
-
action_cancel(self) -
action_done(self) -
action_draft(self)
New fields (11)
-
amountFloatreadonly=Falsestring='Tax Amount' -
baseFloatreadonly=Falsestring='Base Amount' -
cert_idMany2one → withholding.tax.certcomodel_name='withholding.tax.cert'index=Truestring='WHT Cert' -
company_idMany2one → res.companycomodel_name='res.company'related='cert_id.company_id' -
wht_cert_bank_accountMany2one → res.partner.bankcheck_company=Truecomodel_name='res.partner.bank'compute='_compute_wht_bank_account'help='PND2 type 4A need bank account'readonly=Falsestore=Truestring='Bank Account' -
wht_cert_income_codeMany2one → withholding.tax.code.incomecomodel_name='withholding.tax.code.income'help='For Text File income code'index=Truestring='Income Code' -
wht_cert_income_descCharrequired=Falsesize=500string='Income Description' -
wht_cert_income_typeSelectionrequired=Trueselection=WHT_CERT_INCOME_TYPEstring='Type of Income' -
wht_income_tax_formSelectionindex=Truerelated='cert_id.income_tax_form' -
wht_percentFloatcompute='_compute_wht_percent'string='% Tax' -
wht_tax_idMany2one → account.withholding.taxcheck_company=Truecomodel_name='account.withholding.tax'readonly=Falsestring='Tax'
No public methods.
New fields (5)
-
codeChar -
income_tax_formSelectionindex=Truerequired=Trueselection=INCOME_TAX_FORM -
is_defaultBooleanstring='Default' -
nameCharrequired=True -
wht_cert_income_typeSelectionrequired=Trueselection=WHT_CERT_INCOME_TYPEstring='Type of Income'
-
check_is_default(self)@api.constrains('is_default')
Loading…
Loading…
Loading…