mirror of
https://gitlab.com/hibou-io/hibou-odoo/suite.git
synced 2025-01-20 12:37:31 +02:00
Merge branch 'new/13.0/l10n_us_hr_payroll' into '13.0-test'
new/13.0/l10n_us_hr_payroll into 13.0-test See merge request hibou-io/hibou-odoo/suite!224
This commit is contained in:
@@ -29,6 +29,7 @@ United States of America - Payroll Rules.
|
||||
'data/state/mt_montana.xml',
|
||||
'data/state/oh_ohio.xml',
|
||||
'data/state/pa_pennsylvania.xml',
|
||||
'data/state/wa_washington.xml',
|
||||
'views/hr_contract_views.xml',
|
||||
'views/us_payroll_config_views.xml',
|
||||
],
|
||||
|
||||
211
l10n_us_hr_payroll/data/state/wa_washington.xml
Normal file
211
l10n_us_hr_payroll/data/state/wa_washington.xml
Normal file
@@ -0,0 +1,211 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<!-- Wage Base -->
|
||||
<record id="rule_parameter_us_wa_suta_wage_base" model="hr.rule.parameter">
|
||||
<field name="name">US WA Washington SUTA Wage Base</field>
|
||||
<field name="code">us_wa_suta_wage_base</field>
|
||||
<field name="country_id" ref="base.us"/>
|
||||
</record>
|
||||
<data noupdate="1">
|
||||
<record id="rule_parameter_us_wa_suta_wage_base_2019" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">49800.0</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_us_wa_suta_wage_base"/>
|
||||
<field name="date_from" eval="datetime(2019, 1, 1).date()"/>
|
||||
</record>
|
||||
<record id="rule_parameter_us_wa_suta_wage_base_2020" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">52700.00</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_us_wa_suta_wage_base"/>
|
||||
<field name="date_from" eval="datetime(2020, 1, 1).date()"/>
|
||||
</record>
|
||||
</data>
|
||||
|
||||
<record id="rule_parameter_us_wa_fml_wage_base" model="hr.rule.parameter">
|
||||
<field name="name">US WA Washington FML Wage Base</field>
|
||||
<field name="code">us_wa_fml_wage_base</field>
|
||||
<field name="country_id" ref="base.us"/>
|
||||
</record>
|
||||
<data noupdate="1">
|
||||
<record id="rule_parameter_us_wa_fml_wage_base_2019" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">132900.00</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_us_wa_fml_wage_base"/>
|
||||
<field name="date_from" eval="datetime(2019, 1, 1).date()"/>
|
||||
</record>
|
||||
<record id="rule_parameter_us_wa_fml_wage_base_2020" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">137700.00</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_us_wa_fml_wage_base"/>
|
||||
<field name="date_from" eval="datetime(2020, 1, 1).date()"/>
|
||||
</record>
|
||||
</data>
|
||||
|
||||
<!-- Rate -->
|
||||
<record id="rule_parameter_us_wa_suta_rate" model="hr.rule.parameter">
|
||||
<field name="name">US WA Washington SUTA Rate</field>
|
||||
<field name="code">us_wa_suta_rate</field>
|
||||
<field name="country_id" ref="base.us"/>
|
||||
</record>
|
||||
<data noupdate="1">
|
||||
<record id="rule_parameter_us_wa_suta_rate_2019" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">1.18</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_us_wa_suta_rate"/>
|
||||
<field name="date_from" eval="datetime(2019, 1, 1).date()"/>
|
||||
</record>
|
||||
<record id="rule_parameter_us_wa_suta_rate_2020" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">1.0</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_us_wa_suta_rate"/>
|
||||
<field name="date_from" eval="datetime(2020, 1, 1).date()"/>
|
||||
</record>
|
||||
</data>
|
||||
|
||||
<record id="rule_parameter_us_wa_fml_rate" model="hr.rule.parameter">
|
||||
<field name="name">US WA Washington FML Rate (Total)</field>
|
||||
<field name="code">us_wa_fml_rate</field>
|
||||
<field name="country_id" ref="base.us"/>
|
||||
</record>
|
||||
<data noupdate="1">
|
||||
<record id="rule_parameter_us_wa_fml_rate_2019" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">0.4</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_us_wa_fml_rate"/>
|
||||
<field name="date_from" eval="datetime(2019, 1, 1).date()"/>
|
||||
</record>
|
||||
<record id="rule_parameter_us_wa_fml_rate_2020" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">0.4</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_us_wa_fml_rate"/>
|
||||
<field name="date_from" eval="datetime(2020, 1, 1).date()"/>
|
||||
</record>
|
||||
</data>
|
||||
|
||||
<record id="rule_parameter_us_wa_fml_rate_ee" model="hr.rule.parameter">
|
||||
<field name="name">US WA Washington FML Rate (Employee)</field>
|
||||
<field name="code">us_wa_fml_rate_ee</field>
|
||||
<field name="country_id" ref="base.us"/>
|
||||
</record>
|
||||
<data noupdate="1">
|
||||
<record id="rule_parameter_us_wa_fml_rate_ee_2019" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">66.33</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_us_wa_fml_rate_ee"/>
|
||||
<field name="date_from" eval="datetime(2019, 1, 1).date()"/>
|
||||
</record>
|
||||
<record id="rule_parameter_us_wa_fml_rate_ee_2020" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">66.33</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_us_wa_fml_rate_ee"/>
|
||||
<field name="date_from" eval="datetime(2020, 1, 1).date()"/>
|
||||
</record>
|
||||
</data>
|
||||
|
||||
<record id="rule_parameter_us_wa_fml_rate_er" model="hr.rule.parameter">
|
||||
<field name="name">US WA Washington FML Rate (Employer)</field>
|
||||
<field name="code">us_wa_fml_rate_er</field>
|
||||
<field name="country_id" ref="base.us"/>
|
||||
</record>
|
||||
<data noupdate="1">
|
||||
<record id="rule_parameter_us_wa_fml_rate_er_2019" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">33.67</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_us_wa_fml_rate_er"/>
|
||||
<field name="date_from" eval="datetime(2019, 1, 1).date()"/>
|
||||
</record>
|
||||
<record id="rule_parameter_us_wa_fml_rate_er_2020" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">33.67</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_us_wa_fml_rate_er"/>
|
||||
<field name="date_from" eval="datetime(2020, 1, 1).date()"/>
|
||||
</record>
|
||||
</data>
|
||||
|
||||
<!-- Partners and Contribution Registers -->
|
||||
<record id="res_partner_us_wa_dor" model="res.partner">
|
||||
<field name="name">US Washington - Employment Security Department (Unemployment)</field>
|
||||
</record>
|
||||
|
||||
<record id="res_partner_us_wa_dor_lni" model="res.partner">
|
||||
<field name="name">US Washington - Department of Labor & Industries</field>
|
||||
</record>
|
||||
|
||||
<record id="res_partner_us_wa_dor_fml" model="res.partner">
|
||||
<field name="name">US Washington - Employment Security Department (PFML)</field>
|
||||
</record>
|
||||
|
||||
<!-- Categories -->
|
||||
|
||||
<!-- Rules -->
|
||||
<record id="hr_payroll_rule_er_us_wa_suta" model="hr.salary.rule">
|
||||
<field name="sequence" eval="450"/>
|
||||
<field name="struct_id" ref="hr_payroll_structure"/>
|
||||
<field name="category_id" ref="hr_payroll_category_er_us_suta"/>
|
||||
<field name="name">ER: US WA Washington State Unemployment (5208A/B)</field>
|
||||
<field name="code">ER_US_WA_SUTA</field>
|
||||
<field name="condition_select">python</field>
|
||||
<field name="condition_python">result, _ = general_state_unemployment(payslip, categories, worked_days, inputs, wage_base='us_wa_suta_wage_base', rate='us_wa_suta_rate', state_code='WA')</field>
|
||||
<field name="amount_select">code</field>
|
||||
<field name="amount_python_compute">result, result_rate = general_state_unemployment(payslip, categories, worked_days, inputs, wage_base='us_wa_suta_wage_base', rate='us_wa_suta_rate', state_code='WA')</field>
|
||||
<field name="partner_id" ref="res_partner_us_wa_dor"/>
|
||||
<field name="appears_on_payslip" eval="False"/>
|
||||
</record>
|
||||
|
||||
<record id="hr_payroll_rule_er_us_wa_fml" model="hr.salary.rule">
|
||||
<field name="sequence" eval="451"/>
|
||||
<field name="struct_id" ref="hr_payroll_structure"/>
|
||||
<field name="category_id" ref="hr_payroll.COMP"/>
|
||||
<field name="name">ER: US WA Washington State Family Medical Leave</field>
|
||||
<field name="code">ER_US_WA_FML</field>
|
||||
<field name="condition_select">python</field>
|
||||
<field name="condition_python">result, _ = wa_washington_fml_er(payslip, categories, worked_days, inputs)</field>
|
||||
<field name="amount_select">code</field>
|
||||
<field name="amount_python_compute">result, result_rate = wa_washington_fml_er(payslip, categories, worked_days, inputs)</field>
|
||||
<field name="partner_id" ref="res_partner_us_wa_dor_fml"/>
|
||||
<field name="appears_on_payslip" eval="False"/>
|
||||
</record>
|
||||
|
||||
<record id="hr_payroll_rule_ee_us_wa_fml" model="hr.salary.rule">
|
||||
<field name="sequence" eval="196"/>
|
||||
<field name="struct_id" ref="hr_payroll_structure"/>
|
||||
<field name="category_id" ref="hr_payroll.DED"/>
|
||||
<field name="name">EE: US WA Washington State Family Medical Leave</field>
|
||||
<field name="code">EE_US_WA_FML</field>
|
||||
<field name="condition_select">python</field>
|
||||
<field name="condition_python">result, _ = wa_washington_fml_ee(payslip, categories, worked_days, inputs)</field>
|
||||
<field name="amount_select">code</field>
|
||||
<field name="amount_python_compute">result, result_rate = wa_washington_fml_ee(payslip, categories, worked_days, inputs)</field>
|
||||
<field name="partner_id" ref="res_partner_us_wa_dor_fml"/>
|
||||
<field name="appears_on_payslip" eval="True"/>
|
||||
</record>
|
||||
|
||||
<!-- LNI May need to be updated depending on hours worked (or drywall laid) -->
|
||||
<record id="hr_payroll_rule_er_us_wa_lni" model="hr.salary.rule">
|
||||
<field name="sequence" eval="451"/>
|
||||
<field name="struct_id" ref="hr_payroll_structure"/>
|
||||
<field name="category_id" ref="hr_payroll.COMP"/>
|
||||
<field name="name">ER: US WA Washington State LNI</field>
|
||||
<field name="code">ER_US_WA_LNI</field>
|
||||
<field name="condition_select">python</field>
|
||||
<field name="condition_python">result = is_us_state(payslip, 'WA') and payslip.contract_id.us_payroll_config_value('workers_comp_er_code') and worked_days.WORK100 and worked_days.WORK100.number_of_hours and payslip.rule_parameter(payslip.contract_id.us_payroll_config_value('workers_comp_er_code'))</field>
|
||||
<field name="amount_select">code</field>
|
||||
<field name="amount_python_compute">
|
||||
hours = worked_days.WORK100.number_of_hours
|
||||
rate = payslip.rule_parameter(payslip.contract_id.us_payroll_config_value('workers_comp_er_code'))
|
||||
try:
|
||||
# Redo employee withholding calculation
|
||||
ee_withholding = worked_days.WORK100.number_of_hours * -payslip.rule_parameter(payslip.contract_id.us_payroll_config_value('workers_comp_ee_code')) / 100.0
|
||||
except:
|
||||
ee_withholding = 0.0
|
||||
er_withholding = -(hours * (rate / 100.0)) - ee_withholding
|
||||
result = hours
|
||||
result_rate = (er_withholding / hours) * 100.0
|
||||
</field>
|
||||
<field name="partner_id" ref="res_partner_us_wa_dor_lni"/>
|
||||
<field name="appears_on_payslip" eval="False"/>
|
||||
</record>
|
||||
|
||||
<record id="hr_payroll_rule_ee_us_wa_lni" model="hr.salary.rule">
|
||||
<field name="sequence" eval="196"/>
|
||||
<field name="struct_id" ref="hr_payroll_structure"/>
|
||||
<field name="category_id" ref="hr_payroll.DED"/>
|
||||
<field name="name">EE: US WA Washington State LNI</field>
|
||||
<field name="code">EE_US_WA_LNI</field>
|
||||
<field name="condition_select">python</field>
|
||||
<field name="condition_python">result = is_us_state(payslip, 'WA') and payslip.contract_id.us_payroll_config_value('workers_comp_ee_code') and worked_days.WORK100 and worked_days.WORK100.number_of_hours and payslip.rule_parameter(payslip.contract_id.us_payroll_config_value('workers_comp_ee_code'))</field>
|
||||
<field name="amount_select">code</field>
|
||||
<field name="amount_python_compute">result, result_rate = worked_days.WORK100.number_of_hours, -payslip.rule_parameter(payslip.contract_id.us_payroll_config_value('workers_comp_ee_code'))</field>
|
||||
<field name="partner_id" ref="res_partner_us_wa_dor_lni"/>
|
||||
<field name="appears_on_payslip" eval="True"/>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
@@ -10,9 +10,12 @@ from .federal.fed_941 import ee_us_941_fica_ss, \
|
||||
er_us_941_fica_m, \
|
||||
ee_us_941_fit
|
||||
from .state.general import general_state_unemployment, \
|
||||
general_state_income_withholding
|
||||
general_state_income_withholding, \
|
||||
is_us_state
|
||||
from .state.mt_montana import mt_montana_state_income_withholding
|
||||
from .state.oh_ohio import oh_ohio_state_income_withholding
|
||||
from .state.wa_washington import wa_washington_fml_er, \
|
||||
wa_washington_fml_ee
|
||||
|
||||
|
||||
class HRPayslip(models.Model):
|
||||
@@ -43,8 +46,11 @@ class HRPayslip(models.Model):
|
||||
'ee_us_941_fit': ee_us_941_fit,
|
||||
'general_state_unemployment': general_state_unemployment,
|
||||
'general_state_income_withholding': general_state_income_withholding,
|
||||
'is_us_state': is_us_state,
|
||||
'mt_montana_state_income_withholding': mt_montana_state_income_withholding,
|
||||
'oh_ohio_state_income_withholding': oh_ohio_state_income_withholding,
|
||||
'wa_washington_fml_er': wa_washington_fml_er,
|
||||
'wa_washington_fml_ee': wa_washington_fml_ee,
|
||||
})
|
||||
return res
|
||||
|
||||
|
||||
@@ -9,6 +9,10 @@ def _state_applies(payslip, state_code):
|
||||
return state_code == payslip.contract_id.us_payroll_config_value('state_code')
|
||||
|
||||
|
||||
# Export for eval context
|
||||
is_us_state = _state_applies
|
||||
|
||||
|
||||
def _general_rate(payslip, wage, ytd_wage, wage_base=None, wage_start=None, rate=None):
|
||||
"""
|
||||
Function parameters:
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from .general import _state_applies
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from .general import _state_applies
|
||||
|
||||
|
||||
|
||||
27
l10n_us_hr_payroll/models/state/wa_washington.py
Normal file
27
l10n_us_hr_payroll/models/state/wa_washington.py
Normal file
@@ -0,0 +1,27 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from .general import _state_applies, _general_rate
|
||||
|
||||
|
||||
def _wa_washington_fml(payslip, categories, worked_days, inputs, inner_rate=None):
|
||||
if not inner_rate:
|
||||
return 0.0, 0.0
|
||||
|
||||
if not _state_applies(payslip, 'WA'):
|
||||
return 0.0, 0.0
|
||||
|
||||
wage = categories.GROSS
|
||||
year = payslip.dict.get_year()
|
||||
ytd_wage = payslip.sum_category('GROSS', str(year) + '-01-01', str(year + 1) + '-01-01')
|
||||
ytd_wage += payslip.contract_id.external_wages
|
||||
rate = payslip.rule_parameter('us_wa_fml_rate')
|
||||
rate *= payslip.rule_parameter(inner_rate) / 100.0
|
||||
return _general_rate(payslip, wage, ytd_wage, wage_base='us_wa_fml_wage_base', rate=rate)
|
||||
|
||||
|
||||
def wa_washington_fml_er(payslip, categories, worked_days, inputs):
|
||||
return _wa_washington_fml(payslip, categories, worked_days, inputs, inner_rate='us_wa_fml_rate_er')
|
||||
|
||||
|
||||
def wa_washington_fml_ee(payslip, categories, worked_days, inputs):
|
||||
return _wa_washington_fml(payslip, categories, worked_days, inputs, inner_rate='us_wa_fml_rate_ee')
|
||||
@@ -17,6 +17,10 @@ class HRContractUSPayrollConfig(models.Model):
|
||||
state_code = fields.Char(related='state_id.code')
|
||||
state_income_tax_exempt = fields.Boolean(string='State Income Tax Exempt')
|
||||
state_income_tax_additional_withholding = fields.Float(string='State Income Tax Additional Withholding')
|
||||
workers_comp_ee_code = fields.Char(string='Workers\' Comp Code (Employee Withholding)',
|
||||
help='Code for a Rule Parameter, used by some states or your own rules.')
|
||||
workers_comp_er_code = fields.Char(string='Workers\' Comp Code (Employer Withholding)',
|
||||
help='Code for a Rule Parameter, used by some states or your own rules.')
|
||||
|
||||
fed_940_type = fields.Selection([
|
||||
(FUTA_TYPE_EXEMPT, 'Exempt (0%)'),
|
||||
|
||||
@@ -15,3 +15,6 @@ from . import test_us_oh_ohio_payslip_2020
|
||||
|
||||
from . import test_us_pa_pennsylvania_payslip_2019
|
||||
from . import test_us_pa_pennsylvania_payslip_2020
|
||||
|
||||
from . import test_us_wa_washington_payslip_2019
|
||||
from . import test_us_wa_washington_payslip_2020
|
||||
|
||||
@@ -146,6 +146,9 @@ class TestUsPayslip(common.TransactionCase):
|
||||
def assertPayrollEqual(self, first, second):
|
||||
self.assertAlmostEqual(first, second, self.payroll_digits)
|
||||
|
||||
def assertPayrollAlmostEqual(self, first, second):
|
||||
self.assertAlmostEqual(first, second, self.payroll_digits-1)
|
||||
|
||||
def test_semi_monthly(self):
|
||||
salary = 80000.0
|
||||
employee = self._createEmployee()
|
||||
|
||||
@@ -34,7 +34,7 @@ class TestUsOhPayslip(TestUsPayslip):
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.OH_UNEMP)
|
||||
self.assertAlmostEqual(cats['EE_US_SIT'], -wd, 1) # Off by 0.6 cents so it rounds off by a penny
|
||||
self.assertPayrollAlmostEqual(cats['EE_US_SIT'], -wd) # Off by 0.6 cents so it rounds off by a penny
|
||||
#self.assertPayrollEqual(cats['EE_US_SIT'], -wd)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
@@ -48,7 +48,7 @@ class TestUsOhPayslip(TestUsPayslip):
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
# Instead of PayrollEqual after initial first round of testing.
|
||||
self.assertAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected, 1)
|
||||
self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected)
|
||||
return payslip
|
||||
|
||||
def test_2020_sit_1(self):
|
||||
|
||||
92
l10n_us_hr_payroll/tests/test_us_wa_washington_payslip_2019.py
Executable file
92
l10n_us_hr_payroll/tests/test_us_wa_washington_payslip_2019.py
Executable file
@@ -0,0 +1,92 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date
|
||||
from .common import TestUsPayslip, process_payslip
|
||||
|
||||
|
||||
class TestUsWAPayslip(TestUsPayslip):
|
||||
###
|
||||
# Taxes and Rates
|
||||
###
|
||||
WA_UNEMP_MAX_WAGE = 49800.0
|
||||
WA_UNEMP_RATE = 1.18
|
||||
WA_FML_RATE = 0.4
|
||||
WA_FML_RATE_EE = 66.33
|
||||
WA_FML_RATE_ER = 33.67
|
||||
|
||||
def setUp(self):
|
||||
super(TestUsWAPayslip, self).setUp()
|
||||
# self.lni = self.env['hr.contract.lni.wa'].create({
|
||||
# 'name': '5302 Computer Consulting',
|
||||
# 'rate': 0.1261,
|
||||
# 'rate_emp_withhold': 0.05575,
|
||||
# })
|
||||
self.test_ee_lni = 0.05575 # per 100 hours
|
||||
self.test_er_lni = 0.1261 # per 100 hours
|
||||
self.parameter_lni_ee = self.env['hr.rule.parameter'].create({
|
||||
'name': 'Test LNI EE',
|
||||
'code': 'test_lni_ee',
|
||||
'parameter_version_ids': [(0, 0, {
|
||||
'date_from': date(2019, 1, 1),
|
||||
'parameter_value': str(self.test_ee_lni * 100),
|
||||
})],
|
||||
})
|
||||
self.parameter_lni_er = self.env['hr.rule.parameter'].create({
|
||||
'name': 'Test LNI ER',
|
||||
'code': 'test_lni_er',
|
||||
'parameter_version_ids': [(0, 0, {
|
||||
'date_from': date(2019, 1, 1),
|
||||
'parameter_value': str(self.test_er_lni * 100),
|
||||
})],
|
||||
})
|
||||
|
||||
def test_2019_taxes(self):
|
||||
salary = 25000.0
|
||||
|
||||
employee = self._createEmployee()
|
||||
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('WA'),
|
||||
workers_comp_ee_code=self.parameter_lni_ee.code,
|
||||
workers_comp_er_code=self.parameter_lni_er.code,
|
||||
)
|
||||
self._log(str(contract.resource_calendar_id) + ' ' + contract.resource_calendar_id.name)
|
||||
|
||||
|
||||
# tax rates
|
||||
wa_unemp = self.WA_UNEMP_RATE / -100.0
|
||||
|
||||
self._log('2019 Washington tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
hours_in_period = payslip.worked_days_line_ids.filtered(lambda l: l.code == 'WORK100').number_of_hours
|
||||
self.assertEqual(hours_in_period, 184) # only asserted to test algorithm
|
||||
payslip.compute_sheet()
|
||||
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
rules = self._getRules(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * wa_unemp)
|
||||
self.assertPayrollEqual(rules['EE_US_WA_LNI'], -(self.test_ee_lni * hours_in_period))
|
||||
self.assertPayrollEqual(rules['ER_US_WA_LNI'], -(self.test_er_lni * hours_in_period) - rules['EE_US_WA_LNI'])
|
||||
# Both of these are known to be within 1 penny
|
||||
self.assertPayrollAlmostEqual(rules['EE_US_WA_FML'], -(salary * (self.WA_FML_RATE / 100.0) * (self.WA_FML_RATE_EE / 100.0)))
|
||||
self.assertPayrollAlmostEqual(rules['ER_US_WA_FML'], -(salary * (self.WA_FML_RATE / 100.0) * (self.WA_FML_RATE_ER / 100.0)))
|
||||
|
||||
# FML
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
# Make a new payslip, this one will have maximums
|
||||
|
||||
remaining_wa_unemp_wages = self.WA_UNEMP_MAX_WAGE - salary if (self.WA_UNEMP_MAX_WAGE - 2*salary < salary) \
|
||||
else salary
|
||||
|
||||
self._log('2019 Washington tax second payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_wa_unemp_wages * wa_unemp)
|
||||
90
l10n_us_hr_payroll/tests/test_us_wa_washington_payslip_2020.py
Executable file
90
l10n_us_hr_payroll/tests/test_us_wa_washington_payslip_2020.py
Executable file
@@ -0,0 +1,90 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date
|
||||
from .common import TestUsPayslip, process_payslip
|
||||
|
||||
|
||||
class TestUsWAPayslip(TestUsPayslip):
|
||||
###
|
||||
# Taxes and Rates
|
||||
###
|
||||
WA_UNEMP_MAX_WAGE = 52700.00
|
||||
WA_UNEMP_RATE = 1.0
|
||||
WA_FML_MAX_WAGE = 137700.00
|
||||
WA_FML_RATE = 0.4
|
||||
WA_FML_RATE_EE = 66.33
|
||||
WA_FML_RATE_ER = 33.67
|
||||
|
||||
def setUp(self):
|
||||
super(TestUsWAPayslip, self).setUp()
|
||||
# self.lni = self.env['hr.contract.lni.wa'].create({
|
||||
# 'name': '5302 Computer Consulting',
|
||||
# 'rate': 0.1261,
|
||||
# 'rate_emp_withhold': 0.05575,
|
||||
# })
|
||||
self.test_ee_lni = 0.05575 # per 100 hours
|
||||
self.test_er_lni = 0.1261 # per 100 hours
|
||||
self.parameter_lni_ee = self.env['hr.rule.parameter'].create({
|
||||
'name': 'Test LNI EE',
|
||||
'code': 'test_lni_ee',
|
||||
'parameter_version_ids': [(0, 0, {
|
||||
'date_from': date(2020, 1, 1),
|
||||
'parameter_value': str(self.test_ee_lni * 100),
|
||||
})],
|
||||
})
|
||||
self.parameter_lni_er = self.env['hr.rule.parameter'].create({
|
||||
'name': 'Test LNI ER',
|
||||
'code': 'test_lni_er',
|
||||
'parameter_version_ids': [(0, 0, {
|
||||
'date_from': date(2020, 1, 1),
|
||||
'parameter_value': str(self.test_er_lni * 100),
|
||||
})],
|
||||
})
|
||||
|
||||
def test_2020_taxes(self):
|
||||
self._test_er_suta('WA', self.WA_UNEMP_RATE, date(2020, 1, 1), wage_base=self.WA_UNEMP_MAX_WAGE)
|
||||
|
||||
salary = (self.WA_FML_MAX_WAGE / 2.0) + 1000.0
|
||||
|
||||
employee = self._createEmployee()
|
||||
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('WA'),
|
||||
workers_comp_ee_code=self.parameter_lni_ee.code,
|
||||
workers_comp_er_code=self.parameter_lni_er.code,
|
||||
)
|
||||
self._log(str(contract.resource_calendar_id) + ' ' + contract.resource_calendar_id.name)
|
||||
|
||||
|
||||
# Non SUTA
|
||||
self._log('2020 Washington tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2020-01-01', '2020-01-31')
|
||||
hours_in_period = payslip.worked_days_line_ids.filtered(lambda l: l.code == 'WORK100').number_of_hours
|
||||
self.assertEqual(hours_in_period, 184) # only asserted to test algorithm
|
||||
payslip.compute_sheet()
|
||||
|
||||
rules = self._getRules(payslip)
|
||||
|
||||
self.assertPayrollEqual(rules['EE_US_WA_LNI'], -(self.test_ee_lni * hours_in_period))
|
||||
self.assertPayrollEqual(rules['ER_US_WA_LNI'], -(self.test_er_lni * hours_in_period) - rules['EE_US_WA_LNI'])
|
||||
# Both of these are known to be within 1 penny
|
||||
self.assertPayrollAlmostEqual(rules['EE_US_WA_FML'], -(salary * (self.WA_FML_RATE / 100.0) * (self.WA_FML_RATE_EE / 100.0)))
|
||||
self.assertPayrollAlmostEqual(rules['ER_US_WA_FML'], -(salary * (self.WA_FML_RATE / 100.0) * (self.WA_FML_RATE_ER / 100.0)))
|
||||
process_payslip(payslip)
|
||||
|
||||
# Second payslip
|
||||
remaining_wage = self.WA_FML_MAX_WAGE - salary
|
||||
payslip = self._createPayslip(employee, '2020-03-01', '2020-03-31')
|
||||
payslip.compute_sheet()
|
||||
rules = self._getRules(payslip)
|
||||
self.assertPayrollAlmostEqual(rules['EE_US_WA_FML'], -(remaining_wage * (self.WA_FML_RATE / 100.0) * (self.WA_FML_RATE_EE / 100.0)))
|
||||
self.assertPayrollAlmostEqual(rules['ER_US_WA_FML'], -(remaining_wage * (self.WA_FML_RATE / 100.0) * (self.WA_FML_RATE_ER / 100.0)))
|
||||
process_payslip(payslip)
|
||||
|
||||
# Third payslip
|
||||
payslip = self._createPayslip(employee, '2020-04-01', '2020-04-30')
|
||||
payslip.compute_sheet()
|
||||
rules = self._getRules(payslip)
|
||||
self.assertPayrollAlmostEqual(rules['EE_US_WA_FML'], 0.0)
|
||||
self.assertPayrollAlmostEqual(rules['ER_US_WA_FML'], 0.0)
|
||||
@@ -26,7 +26,6 @@
|
||||
</group>
|
||||
<group>
|
||||
<group name="federal" string="Federal">
|
||||
<field name="state_id" domain="[('country_id', '=', %(base.us)s)]" options="{'no_create': True}"/>
|
||||
<p colspan="2"><h3>Form 940 - Federal Unemployment</h3></p>
|
||||
<field name="fed_940_type" string="Federal Unemployment Rate"/>
|
||||
<p colspan="2"><h3>Form 941 / W4 - Federal Income Tax</h3></p>
|
||||
@@ -39,6 +38,10 @@
|
||||
<field name="fed_941_fit_w4_other_income" string="Other Income"/>
|
||||
<field name="fed_941_fit_w4_deductions" string="Deductions"/>
|
||||
<field name="fed_941_fit_w4_additional_withholding" string="Additional Withholding"/>
|
||||
<p colspan="2"><h3>State Information and Extra</h3></p>
|
||||
<field name="state_id" domain="[('country_id', '=', %(base.us)s)]" options="{'no_create': True}"/>
|
||||
<field name="workers_comp_ee_code"/>
|
||||
<field name="workers_comp_er_code"/>
|
||||
</group>
|
||||
|
||||
<group name="state_fl_florida" string="FL Florida" attrs="{'invisible':[('state_id', '!=', %(base.state_us_10)s)]}">
|
||||
@@ -60,6 +63,10 @@
|
||||
<field name="state_income_tax_exempt"/>
|
||||
<field name="state_income_tax_additional_withholding"/>
|
||||
</group>
|
||||
<group name="state_wa_washington" string="WA Washington" attrs="{'invisible':[('state_id', '!=', %(base.state_us_48)s)]}">
|
||||
<p colspan="2"><h3>No additional fields.</h3></p>
|
||||
<p colspan="2">Ensure that your Employee and Employer workers' comp code fields are filled in for WA LNI withholding.</p>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
|
||||
Reference in New Issue
Block a user