diff --git a/l10n_us_hr_payroll/__manifest__.py b/l10n_us_hr_payroll/__manifest__.py index c10cc4e7..f2d7f78d 100755 --- a/l10n_us_hr_payroll/__manifest__.py +++ b/l10n_us_hr_payroll/__manifest__.py @@ -32,6 +32,7 @@ USA Payroll Rules. 'data/state/mt_montana.xml', 'data/state/oh_ohio.xml', 'data/state/pa_pennsylvania.xml', + 'data/state/wa_washington.xml', 'data/final.xml', 'views/hr_contract_views.xml', 'views/us_payroll_config_views.xml', diff --git a/l10n_us_hr_payroll/data/final.xml b/l10n_us_hr_payroll/data/final.xml index 7eb30e83..6e855bd4 100644 --- a/l10n_us_hr_payroll/data/final.xml +++ b/l10n_us_hr_payroll/data/final.xml @@ -29,6 +29,12 @@ ref('hr_payroll_rule_ee_us_pa_suta'), ref('hr_payroll_rule_ee_us_pa_sit'), + ref('hr_payroll_rule_er_us_wa_suta'), + ref('hr_payroll_rule_er_us_wa_fml'), + ref('hr_payroll_rule_ee_us_wa_fml'), + ref('hr_payroll_rule_er_us_wa_lni'), + ref('hr_payroll_rule_ee_us_wa_lni'), + ref('hr_salary_rule_commission'), ref('hr_salary_rule_gamification'), ])]" name="rule_ids"/> diff --git a/l10n_us_hr_payroll/data/state/wa_washington.xml b/l10n_us_hr_payroll/data/state/wa_washington.xml new file mode 100644 index 00000000..52e0b736 --- /dev/null +++ b/l10n_us_hr_payroll/data/state/wa_washington.xml @@ -0,0 +1,203 @@ + + + + + + US WA Washington SUTA Wage Base + us_wa_suta_wage_base + 49800.0 + + + + US WA Washington SUTA Wage Base + us_wa_suta_wage_base + 52700.00 + + + + + + + US WA Washington FML Wage Base + us_wa_fml_wage_base + 132900.00 + + + + US WA Washington FML Wage Base + us_wa_fml_wage_base + 137700.00 + + + + + + + + US WA Washington SUTA Rate + us_wa_suta_rate + 1.18 + + + + US WA Washington SUTA Rate + us_wa_suta_rate + 1.0 + + + + + + + US WA Washington FML Rate (Total) + us_wa_fml_rate + 0.4 + + + + US WA Washington FML Rate (Total) + us_wa_fml_rate + 0.4 + + + + + + + US WA Washington FML Rate (Employee) + us_wa_fml_rate_ee + 66.33 + + + + US WA Washington FML Rate (Employee) + us_wa_fml_rate_ee + 66.33 + + + + + + + US WA Washington FML Rate (Employer) + us_wa_fml_rate_er + 33.67 + + + + US WA Washington FML Rate (Employer) + us_wa_fml_rate_er + 33.67 + + + + + + + US Washington - Employment Security Department (Unemployment) + + + + US Washington - Employment Security Department (Unemployment) + + + + + US Washington - Department of Labor & Industries + + + + US Washington - Department of Labor & Industries + + + + + US Washington - Employment Security Department (PFML) + + + + US Washington - Employment Security Department (PFML) + + + + + + + + + + ER: US WA Washington State Unemployment (5208A/B) + ER_US_WA_SUTA + 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') + code + 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') + + + + + + + + ER: US WA Washington State Family Medical Leave + ER_US_WA_FML + python + result, _ = wa_washington_fml_er(payslip, categories, worked_days, inputs) + code + result, result_rate = wa_washington_fml_er(payslip, categories, worked_days, inputs) + + + + + + + + EE: US WA Washington State Family Medical Leave + EE_US_WA_FML + python + result, _ = wa_washington_fml_ee(payslip, categories, worked_days, inputs) + code + result, result_rate = wa_washington_fml_ee(payslip, categories, worked_days, inputs) + + + + + + + + + ER: US WA Washington State LNI + ER_US_WA_LNI + 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.dict.rule_parameter(payslip.contract_id.us_payroll_config_value('workers_comp_er_code')) + code + +hours = worked_days.WORK100.number_of_hours +rate = payslip.dict.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.dict.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 + + + + + + + + + EE: US WA Washington State LNI + EE_US_WA_LNI + 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.dict.rule_parameter(payslip.contract_id.us_payroll_config_value('workers_comp_ee_code')) + code + result, result_rate = worked_days.WORK100.number_of_hours, -payslip.dict.rule_parameter(payslip.contract_id.us_payroll_config_value('workers_comp_ee_code')) + + + + + \ No newline at end of file diff --git a/l10n_us_hr_payroll/migrations/data.py b/l10n_us_hr_payroll/migrations/data.py index b5d7d15e..c15c3749 100644 --- a/l10n_us_hr_payroll/migrations/data.py +++ b/l10n_us_hr_payroll/migrations/data.py @@ -58,6 +58,13 @@ XMLIDS_TO_REMOVE_2020 = [ 'l10n_us_pa_hr_payroll.hr_payroll_pa_withhold', 'l10n_us_pa_hr_payroll.hr_payroll_rules_pa_unemp_wages_2018', 'l10n_us_pa_hr_payroll.hr_payroll_rules_pa_inc_withhold_add', + + 'l10n_us_wa_hr_payroll.hr_payroll_wa_unemp_wages', + 'l10n_us_wa_hr_payroll.hr_payroll_wa_unemp', + 'l10n_us_wa_hr_payroll.hr_payroll_wa_lni', + 'l10n_us_wa_hr_payroll.hr_payroll_wa_lni_withhold', + 'l10n_us_wa_hr_payroll.hr_payroll_rules_wa_unemp_wages_2018', + ] XMLIDS_TO_RENAME_2020 = { @@ -100,10 +107,24 @@ XMLIDS_TO_RENAME_2020 = { 'l10n_us_pa_hr_payroll.hr_payroll_rules_pa_unemp_company_2018': 'l10n_us_hr_payroll.hr_payroll_rule_er_us_pa_suta', 'l10n_us_pa_hr_payroll.hr_payroll_rules_pa_inc_withhold_2018': 'l10n_us_hr_payroll.hr_payroll_rule_ee_us_pa_sit', + 'l10n_us_wa_hr_payroll.res_partner_wador_unemp': 'l10n_us_hr_payroll.res_partner_us_wa_dor', + 'l10n_us_wa_hr_payroll.res_partner_wador_lni': 'l10n_us_hr_payroll.res_partner_us_wa_dor_lni', + 'l10n_us_wa_hr_payroll.contrib_register_wador_unemp': 'l10n_us_hr_payroll.contrib_register_us_wa_dor', + 'l10n_us_wa_hr_payroll.contrib_register_wador_lni': 'l10n_us_hr_payroll.contrib_register_us_wa_dor_lni', + 'l10n_us_wa_hr_payroll.hr_payroll_rules_wa_unemp_2018': 'l10n_us_hr_payroll.hr_payroll_rule_er_us_wa_suta', + 'l10n_us_wa_hr_payroll.hr_payroll_rules_wa_lni_withhold': 'l10n_us_hr_payroll.hr_payroll_rule_ee_us_wa_lni', + 'l10n_us_wa_hr_payroll.hr_payroll_rules_wa_lni': 'l10n_us_hr_payroll.hr_payroll_rule_er_us_wa_lni', + } XMLIDS_COPY_ACCOUNTING_2020 = { 'l10n_us_hr_payroll.hr_payroll_rule_er_us_mt_suta': [ 'l10n_us_hr_payroll.hr_payroll_rule_er_us_mt_suta_aft', ], + 'l10n_us_hr_payroll.hr_payroll_rule_er_us_wa_lni': [ + 'l10n_us_hr_payroll.hr_payroll_rule_er_us_wa_fml', + ], + 'l10n_us_hr_payroll.hr_payroll_rule_ee_us_wa_lni': [ + 'l10n_us_hr_payroll.hr_payroll_rule_ee_us_wa_fml', + ], } diff --git a/l10n_us_hr_payroll/models/hr_payslip.py b/l10n_us_hr_payroll/models/hr_payslip.py index e2a885f7..5521b078 100644 --- a/l10n_us_hr_payroll/models/hr_payslip.py +++ b/l10n_us_hr_payroll/models/hr_payslip.py @@ -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): @@ -44,8 +47,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, } def get_year(self): diff --git a/l10n_us_hr_payroll/models/state/general.py b/l10n_us_hr_payroll/models/state/general.py index 0d11b054..af2e3931 100644 --- a/l10n_us_hr_payroll/models/state/general.py +++ b/l10n_us_hr_payroll/models/state/general.py @@ -9,6 +9,10 @@ def _state_applies(payslip, state_code): return state_code == payslip.dict.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: diff --git a/l10n_us_hr_payroll/models/state/mt_montana.py b/l10n_us_hr_payroll/models/state/mt_montana.py index 3816b318..b9fa0986 100644 --- a/l10n_us_hr_payroll/models/state/mt_montana.py +++ b/l10n_us_hr_payroll/models/state/mt_montana.py @@ -1,3 +1,5 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + from .general import _state_applies diff --git a/l10n_us_hr_payroll/models/state/oh_ohio.py b/l10n_us_hr_payroll/models/state/oh_ohio.py index 793d4900..8ec52538 100644 --- a/l10n_us_hr_payroll/models/state/oh_ohio.py +++ b/l10n_us_hr_payroll/models/state/oh_ohio.py @@ -1,3 +1,5 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + from .general import _state_applies diff --git a/l10n_us_hr_payroll/models/state/wa_washington.py b/l10n_us_hr_payroll/models/state/wa_washington.py new file mode 100644 index 00000000..c608d2da --- /dev/null +++ b/l10n_us_hr_payroll/models/state/wa_washington.py @@ -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.dict.rule_parameter('us_wa_fml_rate') + rate *= payslip.dict.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') diff --git a/l10n_us_hr_payroll/models/us_payroll_config.py b/l10n_us_hr_payroll/models/us_payroll_config.py index e0d56a6c..be1fa946 100644 --- a/l10n_us_hr_payroll/models/us_payroll_config.py +++ b/l10n_us_hr_payroll/models/us_payroll_config.py @@ -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 Payroll Rate, used by some states or your own rules.') + workers_comp_er_code = fields.Char(string='Workers\' Comp Code (Employer Withholding)', + help='Code for a Payroll Rate, used by some states or your own rules.') fed_940_type = fields.Selection([ (FUTA_TYPE_EXEMPT, 'Exempt (0%)'), diff --git a/l10n_us_hr_payroll/tests/__init__.py b/l10n_us_hr_payroll/tests/__init__.py index a2953520..7ffc630a 100755 --- a/l10n_us_hr_payroll/tests/__init__.py +++ b/l10n_us_hr_payroll/tests/__init__.py @@ -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 diff --git a/l10n_us_hr_payroll/tests/common.py b/l10n_us_hr_payroll/tests/common.py index 042302bb..338e1d44 100755 --- a/l10n_us_hr_payroll/tests/common.py +++ b/l10n_us_hr_payroll/tests/common.py @@ -151,6 +151,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() diff --git a/l10n_us_hr_payroll/tests/test_us_oh_ohio_payslip_2019.py b/l10n_us_hr_payroll/tests/test_us_oh_ohio_payslip_2019.py index bf38f4d5..d1f65f05 100755 --- a/l10n_us_hr_payroll/tests/test_us_oh_ohio_payslip_2019.py +++ b/l10n_us_hr_payroll/tests/test_us_oh_ohio_payslip_2019.py @@ -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) diff --git a/l10n_us_hr_payroll/tests/test_us_oh_ohio_payslip_2020.py b/l10n_us_hr_payroll/tests/test_us_oh_ohio_payslip_2020.py index 04256afa..9026da92 100755 --- a/l10n_us_hr_payroll/tests/test_us_oh_ohio_payslip_2020.py +++ b/l10n_us_hr_payroll/tests/test_us_oh_ohio_payslip_2020.py @@ -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): diff --git a/l10n_us_hr_payroll/tests/test_us_wa_washington_payslip_2019.py b/l10n_us_hr_payroll/tests/test_us_wa_washington_payslip_2019.py new file mode 100755 index 00000000..11cf6138 --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_wa_washington_payslip_2019.py @@ -0,0 +1,88 @@ +# 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.payroll.rate'].create({ + 'name': 'Test LNI EE', + 'code': 'test_lni_ee', + 'date_from': date(2019, 1, 1), + 'parameter_value': str(self.test_ee_lni * 100), + }) + self.parameter_lni_er = self.env['hr.payroll.rate'].create({ + 'name': 'Test LNI ER', + 'code': 'test_lni_er', + '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) diff --git a/l10n_us_hr_payroll/tests/test_us_wa_washington_payslip_2020.py b/l10n_us_hr_payroll/tests/test_us_wa_washington_payslip_2020.py new file mode 100755 index 00000000..9272eba0 --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_wa_washington_payslip_2020.py @@ -0,0 +1,86 @@ +# 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.payroll.rate'].create({ + 'name': 'Test LNI EE', + 'code': 'test_lni_ee', + 'date_from': date(2019, 1, 1), + 'parameter_value': str(self.test_ee_lni * 100), + }) + self.parameter_lni_er = self.env['hr.payroll.rate'].create({ + 'name': 'Test LNI ER', + 'code': 'test_lni_er', + 'date_from': date(2019, 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) diff --git a/l10n_us_hr_payroll/views/us_payroll_config_views.xml b/l10n_us_hr_payroll/views/us_payroll_config_views.xml index ee993be7..f47e18fe 100644 --- a/l10n_us_hr_payroll/views/us_payroll_config_views.xml +++ b/l10n_us_hr_payroll/views/us_payroll_config_views.xml @@ -26,7 +26,6 @@ -

Form 940 - Federal Unemployment

Form 941 / W4 - Federal Income Tax

@@ -39,6 +38,10 @@ +

State Information and Extra

+ + +
@@ -60,6 +63,10 @@ + +

No additional fields.

+

Ensure that your Employee and Employer workers' comp code fields are filled in for WA LNI withholding.

+