mirror of
https://gitlab.com/hibou-io/hibou-odoo/suite.git
synced 2025-01-20 12:37:31 +02:00
OH Ohio
This commit is contained in:
@@ -7,11 +7,6 @@
|
||||
<field name="country_id" ref="base.us"/>
|
||||
</record>
|
||||
<data noupdate="1">
|
||||
<record id="rule_parameter_us_oh_suta_wage_base_2019" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">9500.00</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_us_oh_suta_wage_base"/>
|
||||
<field name="date_from" eval="datetime(2019, 1, 1).date()"/>
|
||||
</record>
|
||||
<record id="rule_parameter_us_oh_suta_wage_base_2020" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">9000.00</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_us_oh_suta_wage_base"/>
|
||||
@@ -20,17 +15,13 @@
|
||||
</data>
|
||||
|
||||
<!-- Rate -->
|
||||
<!-- https://jfs.ohio.gov/ouio/uctax/rates.stm#:~:text=If%20an%20employer's%20account%20is,and%20the%202021%20rate%20is-->
|
||||
<record id="rule_parameter_us_oh_suta_rate" model="hr.rule.parameter">
|
||||
<field name="name">US OH Ohio SUTA Rate</field>
|
||||
<field name="code">us_oh_suta_rate</field>
|
||||
<field name="country_id" ref="base.us"/>
|
||||
</record>
|
||||
<data noupdate="1">
|
||||
<record id="rule_parameter_us_oh_suta_rate_2019" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">2.7</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_us_oh_suta_rate"/>
|
||||
<field name="date_from" eval="datetime(2019, 1, 1).date()"/>
|
||||
</record>
|
||||
<record id="rule_parameter_us_oh_suta_rate_2020" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">2.7</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_us_oh_suta_rate"/>
|
||||
@@ -38,28 +29,14 @@
|
||||
</record>
|
||||
</data>
|
||||
|
||||
<!-- rates effective From Jan 1, 2020 until december 31, 2021-->
|
||||
<!-- https://tax.ohio.gov/wps/portal/gov/tax/business/ohio-business-taxes/employer-withholding/employer-withholding-tables-010120-->
|
||||
<record id="rule_parameter_us_oh_sit_rate" model="hr.rule.parameter">
|
||||
<field name="name">US OH Ohio SIT Rate Table</field>
|
||||
<field name="code">us_oh_sit_rate</field>
|
||||
<field name="country_id" ref="base.us"/>
|
||||
</record>
|
||||
<data noupdate="1">
|
||||
<record id="rule_parameter_us_oh_sit_rate_2019" model="hr.rule.parameter.value">
|
||||
<!-- https://www.tax.ohio.gov/Portals/0/employer_withholding/2019%20tables/WTH_OptionalComputerFormula_2019.pdf -->
|
||||
<!-- wage_less_than, base_amount, rate_over -->
|
||||
<field name="parameter_value">[
|
||||
( 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),
|
||||
]</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_us_oh_sit_rate"/>
|
||||
<field name="date_from" eval="datetime(2019, 1, 1).date()"/>
|
||||
</record>
|
||||
<record id="rule_parameter_us_oh_sit_rate_2020" model="hr.rule.parameter.value">
|
||||
<!-- https://www.tax.ohio.gov/Portals/0/employer_withholding/2020%20tables/WTH_OptionalComputerFormula_2020.pdf -->
|
||||
<!-- wage_less_than, base_amount, rate_over -->
|
||||
@@ -84,11 +61,6 @@
|
||||
<field name="country_id" ref="base.us"/>
|
||||
</record>
|
||||
<data noupdate="1">
|
||||
<record id="rule_parameter_us_oh_sit_exemption_rate_2019" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">650.0</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_us_oh_sit_exemption_rate"/>
|
||||
<field name="date_from" eval="datetime(2019, 1, 1).date()"/>
|
||||
</record>
|
||||
<record id="rule_parameter_us_oh_sit_exemption_rate_2020" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">650.0</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_us_oh_sit_exemption_rate"/>
|
||||
@@ -102,11 +74,6 @@
|
||||
<field name="country_id" ref="base.us"/>
|
||||
</record>
|
||||
<data noupdate="1">
|
||||
<record id="rule_parameter_us_oh_sit_multiplier_2019" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">1.075</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_us_oh_sit_multiplier"/>
|
||||
<field name="date_from" eval="datetime(2019, 1, 1).date()"/>
|
||||
</record>
|
||||
<record id="rule_parameter_us_oh_sit_multiplier_2020" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">1.032</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_us_oh_sit_multiplier"/>
|
||||
|
||||
@@ -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)
|
||||
108
l10n_us_hr_payroll/tests/test_us_oh_ohio_payslip_2021.py
Executable file
108
l10n_us_hr_payroll/tests/test_us_oh_ohio_payslip_2021.py
Executable file
@@ -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,
|
||||
)
|
||||
Reference in New Issue
Block a user