Per Thai company: Thailand VAT 7%, Thailand VAT 7% (Included) for
VAT-inclusive pricing, Thailand VAT 0% for zero-rated supplies. Sales
schemes post to Output VAT, purchase schemes to Input VAT (category
Total, so recoverable VAT stays out of valuation). The 7% scheme is the
default when the company has none. Created on Company save, after
install, and by a patch for existing companies.
Thai VAT is filed on P.P.30 as output tax (ภาษีขาย, collected on sales)
net of input tax (ภาษีซื้อ, paid on purchases); ERPNext's wizard makes a
single VAT account. Both join the per-company tax accounts created on
Company save and fixture import; a patch adds them to existing companies.
Account names are translated for the chart of accounts tree.
- translations/th.csv: custom field labels, messages, print format and
letter head text, the 22 Tax Withholding Category names; overrides the
upstream Thai for the standard labels the print formats show
- print formats embed Sarabun (public/fonts, OFL) so PDFs render Thai on
servers without a Thai font
- letter head labels go through _()
- withholding row description is translated when stored
- in_words: Thai "...บาทถ้วน" wording via num2words when the language is
Thai (ThaiSalesInvoice.set_total_in_words); print formats re-derive it
in the print language (get_in_words)
- fixture `modified` bumped so migrate re-imports the changed documents
- Split the Customer block into two columns: name / address / tax id on
the left, contact person with phone, mobile and email on the right
(only when the invoice has a contact person; phone read from Contact)
- Thailand Address Template: drop the blank line between the address and
the phone / fax / email lines
- Hide Total Quantity, Update Billed Amount in Delivery Note, Amount
Eligible for Commission and Company Tax ID (already in the letterhead)
- Move Posting Date / Payment Due Date into the print heading, right-aligned
- Add a Customer block (name, address, contact, tax id) under the heading
- Render Total (Without Tax) in the same right-half grid as Taxes / Totals
- Put In Words in the empty left column of Totals, level with Grand Total
- Print Format CSS: one 1.8 line-height rhythm with no row margins, 5px
letterhead margin, 5px margins around the item table
frappe.call filters kwargs to the target signature; the *args/**kwargs
wrapper accepted 'cmd' and forwarded it to ERPNext's function. Mirror
the original signature.
Tick Apply Tax Withholding Amount on unsaved customer receipts whose
references include a Sales Invoice carrying withholding: in the
get_payment_entry override (Create > Payment), in the
allocate_amount_to_references doc method (Get Outstanding Invoices /
Paid Amount changes, so the tax row updates live) and on first save.
Saved entries keep the user's choice; unticking now removes the row.
Client script recomputes the row when the checkbox or category changes.
With a deduction row ERPNext treats Paid Amount as cash received and
credits the party for paid + deduction, so a gross Paid Amount (what Get
Outstanding Invoices fills) over-credited Debtors and posted the gross
to the bank. Use the taxes table with add_deduct_tax=Deduct like
supplier TDS: Paid Amount is the gross settlement, bank receives paid
minus withholding, receivable is debited. Override Payment Entry
build_gl_map to flag the bank entry post_net_value so the merged bank
line shows the net amount.
Move the Sales Invoice withholding fields and both Property Setters from
fixtures to default_thai_company/custom/{sales_invoice,payment_entry}.json
with sync_on_migrate. sync_customizations updates Custom Fields in place
instead of the delete/re-insert that fixtures do on every migrate.
Custom fields Tax Withholding Category (fetched from Customer),
Withholding Tax and Net Payable After Withholding Tax on Sales Invoice;
computed in the Thai set_tax_withholding override from the category
rate and single threshold, informational only (totals/GL unchanged),
printed under Rounded Total by the standard layout. Payment Entry now
prefers each invoice's category over the customer's.
Integration tests on a throwaway Thai company: account creation and
category linking on Company insert, site-configured account surviving
fixture re-import, Sales Invoice left un-grossed, and Payment Entry
deductions (full, prorated, below threshold, unchecked). Run with
CI=1 bench --site <site> run-tests --app default_thai_company.
Thai customers withhold tax at payment; ERPNext's customer-side handling
is Indian TCS which adds tax on top of the Sales Invoice. Override
SalesInvoice.set_tax_withholding to no-op for Thai companies, expose
"Apply Tax Withholding Amount" on Customer/Receive Payment Entries, and
on validate compute rate x pre-VAT amount of each allocated reference
(prorated, single threshold honoured) as a deduction to "Withholding Tax
Receivable". Client script fetches the Customer's category when the box
is ticked.
Add 22 Tax Withholding Category fixtures covering Thailand domestic
withholding (Taw.Paw. 4/2528, Sec. 50(2), Sec. 70) with rates and
thresholds. Fixtures ship without accounts; on import each Thai company
gets "Withholding Tax Payable" (Liability) and "Withholding Tax
Receivable" (Asset) created and the payable account linked. Company
on_update does the same for companies created later. Site-configured
accounts survive fixture re-import on migrate.