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"/>
|
<field name="country_id" ref="base.us"/>
|
||||||
</record>
|
</record>
|
||||||
<data noupdate="1">
|
<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">
|
<record id="rule_parameter_us_oh_suta_wage_base_2020" model="hr.rule.parameter.value">
|
||||||
<field name="parameter_value">9000.00</field>
|
<field name="parameter_value">9000.00</field>
|
||||||
<field name="rule_parameter_id" ref="rule_parameter_us_oh_suta_wage_base"/>
|
<field name="rule_parameter_id" ref="rule_parameter_us_oh_suta_wage_base"/>
|
||||||
@@ -20,17 +15,13 @@
|
|||||||
</data>
|
</data>
|
||||||
|
|
||||||
<!-- Rate -->
|
<!-- 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">
|
<record id="rule_parameter_us_oh_suta_rate" model="hr.rule.parameter">
|
||||||
<field name="name">US OH Ohio SUTA Rate</field>
|
<field name="name">US OH Ohio SUTA Rate</field>
|
||||||
<field name="code">us_oh_suta_rate</field>
|
<field name="code">us_oh_suta_rate</field>
|
||||||
<field name="country_id" ref="base.us"/>
|
<field name="country_id" ref="base.us"/>
|
||||||
</record>
|
</record>
|
||||||
<data noupdate="1">
|
<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">
|
<record id="rule_parameter_us_oh_suta_rate_2020" model="hr.rule.parameter.value">
|
||||||
<field name="parameter_value">2.7</field>
|
<field name="parameter_value">2.7</field>
|
||||||
<field name="rule_parameter_id" ref="rule_parameter_us_oh_suta_rate"/>
|
<field name="rule_parameter_id" ref="rule_parameter_us_oh_suta_rate"/>
|
||||||
@@ -38,28 +29,14 @@
|
|||||||
</record>
|
</record>
|
||||||
</data>
|
</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">
|
<record id="rule_parameter_us_oh_sit_rate" model="hr.rule.parameter">
|
||||||
<field name="name">US OH Ohio SIT Rate Table</field>
|
<field name="name">US OH Ohio SIT Rate Table</field>
|
||||||
<field name="code">us_oh_sit_rate</field>
|
<field name="code">us_oh_sit_rate</field>
|
||||||
<field name="country_id" ref="base.us"/>
|
<field name="country_id" ref="base.us"/>
|
||||||
</record>
|
</record>
|
||||||
<data noupdate="1">
|
<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">
|
<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 -->
|
<!-- https://www.tax.ohio.gov/Portals/0/employer_withholding/2020%20tables/WTH_OptionalComputerFormula_2020.pdf -->
|
||||||
<!-- wage_less_than, base_amount, rate_over -->
|
<!-- wage_less_than, base_amount, rate_over -->
|
||||||
@@ -84,11 +61,6 @@
|
|||||||
<field name="country_id" ref="base.us"/>
|
<field name="country_id" ref="base.us"/>
|
||||||
</record>
|
</record>
|
||||||
<data noupdate="1">
|
<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">
|
<record id="rule_parameter_us_oh_sit_exemption_rate_2020" model="hr.rule.parameter.value">
|
||||||
<field name="parameter_value">650.0</field>
|
<field name="parameter_value">650.0</field>
|
||||||
<field name="rule_parameter_id" ref="rule_parameter_us_oh_sit_exemption_rate"/>
|
<field name="rule_parameter_id" ref="rule_parameter_us_oh_sit_exemption_rate"/>
|
||||||
@@ -102,11 +74,6 @@
|
|||||||
<field name="country_id" ref="base.us"/>
|
<field name="country_id" ref="base.us"/>
|
||||||
</record>
|
</record>
|
||||||
<data noupdate="1">
|
<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">
|
<record id="rule_parameter_us_oh_sit_multiplier_2020" model="hr.rule.parameter.value">
|
||||||
<field name="parameter_value">1.032</field>
|
<field name="parameter_value">1.032</field>
|
||||||
<field name="rule_parameter_id" ref="rule_parameter_us_oh_sit_multiplier"/>
|
<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