feat: Social Security deduction component
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), 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. The contribution is deductible from taxable income in full, so the component is exempted_from_income_tax. Withheld amounts are held in "Social Security Payable" (ประกันสังคมค้างจ่าย) until remitted. Created once a Thai company exists (Company.on_update, install hooks, scheduler, the setup_salary_components patch); the Salary Component validate hook links every Thai company.
This commit is contained in:
1 parent
035ab2fc7f
commit
6dd557ee97
2 files changed
+48
-5
No files matched your search
@@ -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)
|
||||
|
||||
|
||||
@@ -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,ภาษีซื้อ
|
||||
|
||||
|
Reference in new issue
Block a user