diff --git a/l10n_us_hr_payroll/data/state/oh_ohio.xml b/l10n_us_hr_payroll/data/state/oh_ohio.xml
index e6db8eb8..1d3344a0 100644
--- a/l10n_us_hr_payroll/data/state/oh_ohio.xml
+++ b/l10n_us_hr_payroll/data/state/oh_ohio.xml
@@ -7,11 +7,6 @@
-
- 9500.00
-
-
-
9000.00
@@ -20,17 +15,13 @@
+
US OH Ohio SUTA Rate
us_oh_suta_rate
-
- 2.7
-
-
-
2.7
@@ -38,28 +29,14 @@
+
+
US OH Ohio SIT Rate Table
us_oh_sit_rate
-
-
-
- [
- ( 5000.00, 0.0, 0.005),
- ( 10000.00, 25.0, 0.010),
- ( 15000.00, 75.0, 0.020),
- ( 20000.00, 175.0, 0.025),
- ( 40000.00, 300.0, 0.030),
- ( 80000.00, 900.0, 0.035),
- ( 100000.00, 2300.0, 0.040),
- ( 'inf', 3100.0, 0.050),
- ]
-
-
-
@@ -84,11 +61,6 @@
-
- 650.0
-
-
-
650.0
@@ -102,11 +74,6 @@
-
- 1.075
-
-
-
1.032
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
deleted file mode 100755
index d1f65f05..00000000
--- a/l10n_us_hr_payroll/tests/test_us_oh_ohio_payslip_2019.py
+++ /dev/null
@@ -1,96 +0,0 @@
-# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
-
-from .common import TestUsPayslip, process_payslip
-from odoo.addons.l10n_us_hr_payroll.models.hr_contract import USHRContract
-
-
-class TestUsOhPayslip(TestUsPayslip):
- ###
- # Taxes and Rates
- ###
- OH_UNEMP_MAX_WAGE = 9500.0
- OH_UNEMP = -2.7 / 100.0
-
- def test_2019_taxes(self):
- salary = 5000.0
-
- # For formula here
- # http://www.tax.ohio.gov/Portals/0/employer_withholding/August2015Rates/WTH_OptionalComputerFormula_073015.pdf
- tw = salary * 12 # = 60000
- wd = ((tw - 40000) * 0.035 + 900) / 12 * 1.075
-
- employee = self._createEmployee()
-
- contract = self._createContract(employee,
- wage=salary,
- state_id=self.get_us_state('OH'),
- )
-
- self._log('2019 Ohio tax first payslip:')
- payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
-
- payslip.compute_sheet()
-
- cats = self._getCategories(payslip)
-
- self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.OH_UNEMP)
- 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)
-
- # Make a new payslip, this one will have maximums
-
- remaining_oh_unemp_wages = self.OH_UNEMP_MAX_WAGE - salary if (self.OH_UNEMP_MAX_WAGE - 2*salary < salary) \
- else salary
-
- self._log('2019 Ohio 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_oh_unemp_wages * self.OH_UNEMP)
-
- def test_2019_taxes_with_external(self):
- salary = 5000.0
- external_wages = 6000.0
-
- employee = self._createEmployee()
-
- contract = self._createContract(employee,
- wage=salary,
- state_id=self.get_us_state('OH'),
- external_wages=external_wages,
- )
-
- self._log('2019 Ohio_external tax first payslip:')
- payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
-
- payslip.compute_sheet()
-
- cats = self._getCategories(payslip)
-
- self.assertPayrollEqual(cats['ER_US_SUTA'], (self.OH_UNEMP_MAX_WAGE - external_wages) * self.OH_UNEMP)
-
- def test_2019_taxes_with_state_exempt(self):
- salary = 5000.0
- external_wages = 6000.0
-
- employee = self._createEmployee()
- contract = self._createContract(employee,
- wage=salary,
- state_id=self.get_us_state('OH'),
- external_wages=external_wages,
- futa_type=USHRContract.FUTA_TYPE_BASIC)
-
- self._log('2019 Ohio exempt tax first payslip:')
- payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
-
- payslip.compute_sheet()
-
- cats = self._getCategories(payslip)
-
- # FUTA_TYPE_BASIC
- self.assertPayrollEqual(cats.get('ER_US_SUTA', 0.0), salary * 0.0)
diff --git a/l10n_us_hr_payroll/tests/test_us_oh_ohio_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_oh_ohio_payslip_2021.py
new file mode 100755
index 00000000..a05ff6ca
--- /dev/null
+++ b/l10n_us_hr_payroll/tests/test_us_oh_ohio_payslip_2021.py
@@ -0,0 +1,108 @@
+# 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 TestUsOhPayslip(TestUsPayslip):
+ ###
+ # Taxes and Rates
+ ###
+ OH_UNEMP_MAX_WAGE = 9000.0
+ OH_UNEMP = 2.7
+
+ def test_2021_taxes(self):
+ self._test_er_suta('OH', self.OH_UNEMP, date(2021, 1, 1), wage_base=self.OH_UNEMP_MAX_WAGE)
+
+ def _run_test_sit(self,
+ wage=0.0,
+ schedule_pay='monthly',
+ filing_status='single',
+ dependent_credit=0.0,
+ other_income=0.0,
+ deductions=0.0,
+ additional_withholding=0.0,
+ is_nonresident_alien=False,
+ state_income_tax_exempt=False,
+ state_income_tax_additional_withholding=0.0,
+ oh_it4_sit_exemptions=0,
+ expected=0.0,
+ ):
+ employee = self._createEmployee()
+ contract = self._createContract(employee,
+ wage=wage,
+ schedule_pay=schedule_pay,
+ fed_941_fit_w4_is_nonresident_alien=is_nonresident_alien,
+ fed_941_fit_w4_filing_status=filing_status,
+ fed_941_fit_w4_multiple_jobs_higher=False,
+ fed_941_fit_w4_dependent_credit=dependent_credit,
+ fed_941_fit_w4_other_income=other_income,
+ fed_941_fit_w4_deductions=deductions,
+ fed_941_fit_w4_additional_withholding=additional_withholding,
+ state_income_tax_exempt=state_income_tax_exempt,
+ state_income_tax_additional_withholding=state_income_tax_additional_withholding,
+ oh_it4_sit_exemptions=oh_it4_sit_exemptions,
+ state_id=self.get_us_state('OH'),
+ )
+ payslip = self._createPayslip(employee, '2021-01-01', '2021-01-31')
+ payslip.compute_sheet()
+ cats = self._getCategories(payslip)
+ # Instead of PayrollEqual after initial first round of testing.
+ self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected)
+ return payslip
+
+ def test_2021_sit_1(self):
+ wage = 400.0
+ exemptions = 1
+ additional = 10.0
+ pay_periods = 12.0
+ annual_adjusted_wage = (wage * pay_periods) - (650.0 * exemptions)
+ self.assertPayrollEqual(4150.0, annual_adjusted_wage)
+ WD = ((annual_adjusted_wage * 0.005) / pay_periods) * 1.032
+ self.assertPayrollEqual(WD, 1.7845)
+ expected = WD + additional
+ self._run_test_sit(wage=wage,
+ schedule_pay='monthly',
+ state_income_tax_exempt=False,
+ state_income_tax_additional_withholding=additional,
+ oh_it4_sit_exemptions=exemptions,
+ expected=expected,
+ )
+
+ # the above agrees with online calculator to the penny 0.01
+ # below expected coming from calculator to 0.10
+ #
+ # semi-monthly
+ self._run_test_sit(wage=1200,
+ schedule_pay='semi-monthly',
+ state_income_tax_exempt=False,
+ state_income_tax_additional_withholding=20.0,
+ oh_it4_sit_exemptions=2,
+ expected=42.58,
+ )
+
+ # bi-weekly
+ self._run_test_sit(wage=3000,
+ schedule_pay='bi-weekly',
+ state_income_tax_exempt=False,
+ #state_income_tax_additional_withholding=0.0,
+ oh_it4_sit_exemptions=0,
+ expected=88.51,
+ )
+ # weekly
+ self._run_test_sit(wage=355,
+ schedule_pay='weekly',
+ state_income_tax_exempt=False,
+ # state_income_tax_additional_withholding=0.0,
+ oh_it4_sit_exemptions=1,
+ expected=4.87,
+ )
+
+ # Exempt!
+ self._run_test_sit(wage=355,
+ schedule_pay='weekly',
+ state_income_tax_exempt=True,
+ # state_income_tax_additional_withholding=0.0,
+ oh_it4_sit_exemptions=1,
+ expected=0.0,
+ )