diff --git a/default_thai_company/payroll.py b/default_thai_company/payroll.py index e082713..9d53956 100644 --- a/default_thai_company/payroll.py +++ b/default_thai_company/payroll.py @@ -24,6 +24,30 @@ INCOME_TAX_ACCOUNT = "Withholding Tax Payable (P.N.D.1)" DEDUCTION_ACCOUNT = "Salary Deductions" DEDUCTION_ACCOUNT_GROUPS = ("Current Liabilities",) +# Employee's Social Security Fund contribution (Sec. 33): 5% of wages, wages +# taken as at least 1,650 and at most 17,500 a month (2026-2028 ceiling; 20,000 +# from 2029), fractions of a baht rounded half up. Computed from the Basic +# earning rather than `base` so a partial month is 5% of the wages actually paid +# and the ceiling applies after proration, as the Social Security Office +# assesses it. The contribution is deductible from taxable income in full, so +# the component is exempted_from_income_tax; the "Social Security Fund" +# exemption sub-category is for contributions not run through payroll here. +# The employer's equal share is not an employee deduction and is left to the +# accounts. Thai books carry the withheld amount as ประกันสังคมค้างจ่าย until +# it is remitted by the 15th, so it gets its own liability. +SOCIAL_SECURITY_COMPONENT = { + "doctype": "Salary Component", + "salary_component": "Social Security", + "salary_component_abbr": "SSO", + "type": "Deduction", + "description": "Social Security Fund contribution (Sec. 33 employee)", + "depends_on_payment_days": 0, + "exempted_from_income_tax": 1, + "condition": "B > 0", + "amount_based_on_formula": 1, + "formula": "int((1650 if B < 1650 else 17500 if B > 17500 else B) * 5 / 100 + 0.5)", +} +SOCIAL_SECURITY_ACCOUNT = "Social Security Payable" def hrms_installed(): @@ -35,6 +59,10 @@ def salary_component_account(company, component): return get_or_create_account(company, EARNING_ACCOUNT, "Expense", "", EARNING_ACCOUNT_GROUPS) if component.is_income_tax_component: return get_or_create_account(company, INCOME_TAX_ACCOUNT, "Liability") + if component.salary_component == SOCIAL_SECURITY_COMPONENT["salary_component"]: + return get_or_create_account( + company, SOCIAL_SECURITY_ACCOUNT, "Liability", "", DEDUCTION_ACCOUNT_GROUPS + ) return get_or_create_account(company, DEDUCTION_ACCOUNT, "Liability", "", DEDUCTION_ACCOUNT_GROUPS) @@ -62,6 +90,13 @@ def ensure_component_accounts(company): component.save(ignore_permissions=True) +def ensure_social_security_component(): + """Social Security deduction; the validate hook links every Thai company.""" + if frappe.db.exists("Salary Component", SOCIAL_SECURITY_COMPONENT["salary_component"]): + return + frappe.get_doc(SOCIAL_SECURITY_COMPONENT).insert(ignore_permissions=True) + + def payroll_period_name(company, year): abbr = frappe.get_cached_value("Company", company, "abbr") return f"{year} - {abbr}" @@ -88,21 +123,26 @@ def ensure_payroll_period(company, year): def setup_company(doc, method=None): - """Company.on_update: this year's Payroll Period and the Salary Component - accounts for a Thai company.""" + """Company.on_update: this year's Payroll Period, the Social Security + component and the Salary Component accounts for a Thai company.""" if doc.country == "Thailand" and hrms_installed(): ensure_payroll_period(doc.name, getdate().year) + ensure_social_security_component() ensure_component_accounts(doc.name) def setup_companies(): """after_install, the daily scheduler, and the setup_salary_components - patch: this year's Payroll Period and the Salary Component accounts for - every Thai company. The scheduler rolls the Payroll Period over on 1 January.""" + patch: this year's Payroll Period, the Social Security component and the + Salary Component accounts for every Thai company. The scheduler rolls the + Payroll Period over on 1 January.""" if not hrms_installed(): return year = getdate().year - for company in thai_companies(): + companies = thai_companies() + if companies: + ensure_social_security_component() + for company in companies: ensure_payroll_period(company, year) ensure_component_accounts(company) diff --git a/default_thai_company/translations/th.csv b/default_thai_company/translations/th.csv index 761f3cd..8c341a2 100644 --- a/default_thai_company/translations/th.csv +++ b/default_thai_company/translations/th.csv @@ -76,6 +76,9 @@ Page {0} of {1},หน้า {0} จาก {1} Withholding Tax Payable,ภาษีหัก ณ ที่จ่ายค้างจ่าย Withholding Tax Payable (P.N.D.1),ภาษีหัก ณ ที่จ่ายค้างจ่าย (ภ.ง.ด.1) Salary Deductions,รายการหักจากเงินเดือน +Social Security,ประกันสังคม +Social Security Payable,ประกันสังคมค้างจ่าย +Social Security Fund contribution (Sec. 33 employee),เงินสมทบกองทุนประกันสังคม (ผู้ประกันตนมาตรา 33) Withholding Tax Receivable,ภาษีถูกหัก ณ ที่จ่าย Output VAT,ภาษีขาย Input VAT,ภาษีซื้อ