changes
This commit is contained in:
@@ -291,7 +291,8 @@ class PayrollEntry(models.TransientModel):
|
||||
|
||||
@api.depends('gross_pay', 'employee_id')
|
||||
def _compute_taxes(self):
|
||||
"""Calculate employee tax deductions."""
|
||||
"""Calculate employee tax deductions (preview estimate for bi-weekly)."""
|
||||
PAY_PERIODS = 26
|
||||
for entry in self:
|
||||
if entry.gross_pay <= 0:
|
||||
entry.income_tax = 0
|
||||
@@ -300,26 +301,81 @@ class PayrollEntry(models.TransientModel):
|
||||
entry.cpp2 = 0
|
||||
entry.total_employee_tax = 0
|
||||
continue
|
||||
|
||||
# Get tax rates from parameters or use defaults
|
||||
# These are simplified calculations - actual payroll uses full tax rules
|
||||
|
||||
gross = entry.gross_pay
|
||||
|
||||
# Simplified tax calculations (bi-weekly)
|
||||
# Income tax: ~15-20% average for Canadian employees
|
||||
entry.income_tax = round(gross * 0.128, 2) # Approximate federal + provincial
|
||||
|
||||
# EI: 1.64% of gross (2025 rate) up to maximum
|
||||
entry.employment_insurance = round(min(gross * 0.0164, 1049.12 / 26), 2)
|
||||
|
||||
# CPP: 5.95% of pensionable earnings above basic exemption (2025)
|
||||
cpp_exempt = 3500 / 26 # Annual exemption / 26 pay periods
|
||||
pensionable = max(0, gross - cpp_exempt)
|
||||
entry.cpp = round(min(pensionable * 0.0595, 4034.10 / 26), 2)
|
||||
|
||||
# CPP2: 4% on earnings above first ceiling (2025)
|
||||
entry.cpp2 = 0 # Only applies if earnings exceed $71,300/year
|
||||
|
||||
annual = gross * PAY_PERIODS
|
||||
emp = entry.employee_id
|
||||
|
||||
is_cpp_exempt = getattr(emp, 'exempt_cpp', False)
|
||||
is_ei_exempt = getattr(emp, 'exempt_ei', False)
|
||||
is_fed_exempt = getattr(emp, 'exempt_federal_tax', False)
|
||||
|
||||
# Federal tax estimate using 2026 brackets + BPA phase-out
|
||||
fed_brackets = [
|
||||
(58523, 0.14), (117045, 0.205), (181440, 0.26),
|
||||
(258482, 0.29), (float('inf'), 0.33),
|
||||
]
|
||||
bpa_max, bpa_min = 16452, 14829
|
||||
if annual <= 181440:
|
||||
fed_bpa = bpa_max
|
||||
elif annual >= 258482:
|
||||
fed_bpa = bpa_min
|
||||
else:
|
||||
fed_bpa = bpa_max - (bpa_max - bpa_min) * (annual - 181440) / (258482 - 181440)
|
||||
|
||||
fed_tax = 0
|
||||
prev = 0
|
||||
for threshold, rate in fed_brackets:
|
||||
taxable_in = min(annual, threshold) - prev
|
||||
if taxable_in > 0:
|
||||
fed_tax += taxable_in * rate
|
||||
prev = threshold
|
||||
if annual <= threshold:
|
||||
break
|
||||
fed_tax = max(fed_tax - fed_bpa * 0.14 - 1433 * 0.14, 0)
|
||||
|
||||
# Ontario provincial estimate (default province)
|
||||
on_brackets = [
|
||||
(53891, 0.0505), (107785, 0.0915), (150000, 0.1116),
|
||||
(220000, 0.1216), (float('inf'), 0.1316),
|
||||
]
|
||||
prov_tax = 0
|
||||
prev = 0
|
||||
for threshold, rate in on_brackets:
|
||||
taxable_in = min(annual, threshold) - prev
|
||||
if taxable_in > 0:
|
||||
prov_tax += taxable_in * rate
|
||||
prev = threshold
|
||||
if annual <= threshold:
|
||||
break
|
||||
prov_tax = max(prov_tax - 12989 * 0.0505, 0)
|
||||
|
||||
entry.income_tax = 0 if is_fed_exempt else round((fed_tax + prov_tax) / PAY_PERIODS, 2)
|
||||
|
||||
if is_ei_exempt:
|
||||
entry.employment_insurance = 0
|
||||
else:
|
||||
period_max_insurable = 68900 / PAY_PERIODS
|
||||
insurable = min(gross, period_max_insurable)
|
||||
entry.employment_insurance = round(min(insurable * 0.0163, 1123.07 / PAY_PERIODS), 2)
|
||||
|
||||
if is_cpp_exempt:
|
||||
entry.cpp = 0
|
||||
entry.cpp2 = 0
|
||||
else:
|
||||
period_ympe = 74600 / PAY_PERIODS
|
||||
cpp_exempt_amt = 3500 / PAY_PERIODS
|
||||
pensionable = min(gross, period_ympe)
|
||||
pensionable = max(0, pensionable - cpp_exempt_amt)
|
||||
entry.cpp = round(min(pensionable * 0.0595, 4230.45 / PAY_PERIODS), 2)
|
||||
|
||||
if not is_cpp_exempt and gross > 74600 / PAY_PERIODS:
|
||||
period_ceiling = 85000 / PAY_PERIODS
|
||||
cpp2_base = min(gross, period_ceiling) - period_ympe
|
||||
entry.cpp2 = round(min(cpp2_base * 0.04, 416.00 / PAY_PERIODS), 2)
|
||||
else:
|
||||
entry.cpp2 = 0
|
||||
|
||||
entry.total_employee_tax = entry.income_tax + entry.employment_insurance + entry.cpp + entry.cpp2
|
||||
|
||||
@api.depends('employment_insurance', 'cpp', 'cpp2')
|
||||
|
||||
Reference in New Issue
Block a user