mirror of
https://gitlab.com/hibou-io/hibou-odoo/suite.git
synced 2025-01-20 12:37:31 +02:00
FED
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
<field name="code">fed_940_futa_wage_base</field>
|
||||
<field name="country_id" ref="base.us"/>
|
||||
</record>
|
||||
<!-- Unchanged in 2021 https://www.irs.gov/taxtopics/tc759 -->
|
||||
<record id="rule_parameter_940_futa_wage_base_2016" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">7000.00</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_940_futa_wage_base"/>
|
||||
@@ -18,6 +19,7 @@
|
||||
<field name="code">fed_940_futa_rate_basic</field>
|
||||
<field name="country_id" ref="base.us"/>
|
||||
</record>
|
||||
<!-- Unchanged in 2021 https://www.irs.gov/taxtopics/tc759 -->
|
||||
<record id="rule_parameter_940_futa_rate_basic_2016" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">6.0</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_940_futa_rate_basic"/>
|
||||
@@ -29,6 +31,7 @@
|
||||
<field name="code">fed_940_futa_rate_normal</field>
|
||||
<field name="country_id" ref="base.us"/>
|
||||
</record>
|
||||
<!-- Unchanged in 2021 https://www.irs.gov/taxtopics/tc759 -->
|
||||
<record id="rule_parameter_940_futa_rate_normal_2016" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">0.6</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_940_futa_rate_normal"/>
|
||||
|
||||
@@ -22,6 +22,12 @@
|
||||
<field name="rule_parameter_id" ref="rule_parameter_941_fica_ss_wage_base"/>
|
||||
<field name="date_from" eval="datetime(2020, 1, 1).date()"/>
|
||||
</record>
|
||||
<!-- https://www.ssa.gov/oact/cola/cbb.html -->
|
||||
<record id="rule_parameter_941_fica_ss_wage_base_2021" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">142800.0</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_941_fica_ss_wage_base"/>
|
||||
<field name="date_from" eval="datetime(2021, 1, 1).date()"/>
|
||||
</record>
|
||||
|
||||
<!-- Rate -->
|
||||
<record id="rule_parameter_941_fica_ss_rate" model="hr.rule.parameter">
|
||||
@@ -29,6 +35,7 @@
|
||||
<field name="code">fed_941_fica_ss_rate</field>
|
||||
<field name="country_id" ref="base.us"/>
|
||||
</record>
|
||||
<!-- Unchanged in 2021 https://www.ssa.gov/oact/cola/cbb.html -->
|
||||
<record id="rule_parameter_941_fica_ss_rate_2016" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">6.2</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_941_fica_ss_rate"/>
|
||||
@@ -42,6 +49,7 @@
|
||||
<field name="code">fed_941_fica_m_wage_base</field>
|
||||
<field name="country_id" ref="base.us"/>
|
||||
</record>
|
||||
<!-- Unchanged in 2021 https://www.irs.gov/taxtopics/tc751 -->
|
||||
<record id="rule_parameter_941_fica_m_wage_base_2016" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">"inf"</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_941_fica_m_wage_base"/>
|
||||
@@ -54,6 +62,7 @@
|
||||
<field name="code">fed_941_fica_m_rate</field>
|
||||
<field name="country_id" ref="base.us"/>
|
||||
</record>
|
||||
<!-- Unchanged in 2021 https://www.irs.gov/taxtopics/tc751 -->
|
||||
<record id="rule_parameter_941_fica_m_rate_2016" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">1.45</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_941_fica_m_rate"/>
|
||||
@@ -67,6 +76,7 @@
|
||||
<field name="code">fed_941_fica_m_add_wage_start</field>
|
||||
<field name="country_id" ref="base.us"/>
|
||||
</record>
|
||||
<!-- Unchanged in 2021 https://www.irs.gov/taxtopics/tc751 -->
|
||||
<record id="rule_parameter_941_fica_m_add_wage_start_2016" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">200000.0</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_941_fica_m_add_wage_start"/>
|
||||
@@ -79,6 +89,7 @@
|
||||
<field name="code">fed_941_fica_m_add_rate</field>
|
||||
<field name="country_id" ref="base.us"/>
|
||||
</record>
|
||||
<!-- Unchanged in 2021 https://www.irs.gov/taxtopics/tc751 -->
|
||||
<record id="rule_parameter_941_fica_m_add_rate_2016" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">0.9</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_941_fica_m_add_rate"/>
|
||||
|
||||
@@ -7,20 +7,6 @@
|
||||
<field name="code">fed_941_fit_allowance</field>
|
||||
<field name="country_id" ref="base.us"/>
|
||||
</record>
|
||||
<record id="rule_parameter_941_fit_allowance_2018" model="hr.rule.parameter.value">
|
||||
<!-- Bogus 2018 -->
|
||||
<field name="parameter_value">{
|
||||
'weekly': 80.80,
|
||||
'bi-weekly': 161.50,
|
||||
'semi-monthly': 175.00,
|
||||
'monthly': 350.00,
|
||||
'quarterly': 1050.00,
|
||||
'semi-annually': 2100.00,
|
||||
'annually': 4200.00,
|
||||
}</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_941_fit_allowance"/>
|
||||
<field name="date_from" eval="datetime(2018, 1, 1).date()"/>
|
||||
</record>
|
||||
<record id="rule_parameter_941_fit_allowance_2019" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">{
|
||||
'weekly': 80.80,
|
||||
@@ -36,6 +22,7 @@
|
||||
</record>
|
||||
<record id="rule_parameter_941_fit_allowance_2020" model="hr.rule.parameter.value">
|
||||
<!-- Warning, major change to allowance in 2020 -->
|
||||
<!-- unchanged in 2021 https://www.irs.gov/pub/irs-pdf/p15t.pdf -->
|
||||
<field name="parameter_value">4300.0</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_941_fit_allowance"/>
|
||||
<field name="date_from" eval="datetime(2020, 1, 1).date()"/>
|
||||
@@ -46,33 +33,6 @@
|
||||
<field name="code">fed_941_fit_nra_additional</field>
|
||||
<field name="country_id" ref="base.us"/>
|
||||
</record>
|
||||
<record id="rule_parameter_941_fit_nra_additional_2018" model="hr.rule.parameter.value">
|
||||
<!-- Bogus from 2018 -->
|
||||
<field name="parameter_value">{
|
||||
'weekly': 153.80,
|
||||
'bi-weekly': 307.70,
|
||||
'semi-monthly': 333.30,
|
||||
'monthly': 666.70,
|
||||
'quarterly': 2000.00,
|
||||
'semi-annually': 4000.00,
|
||||
'annually': 8000.00,
|
||||
}</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_941_fit_nra_additional"/>
|
||||
<field name="date_from" eval="datetime(2018, 1, 1).date()"/>
|
||||
</record>
|
||||
<record id="rule_parameter_941_fit_nra_additional_2019" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">{
|
||||
'weekly': 153.80,
|
||||
'bi-weekly': 307.70,
|
||||
'semi-monthly': 333.30,
|
||||
'monthly': 666.70,
|
||||
'quarterly': 2000.00,
|
||||
'semi-annually': 4000.00,
|
||||
'annually': 8000.00,
|
||||
}</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_941_fit_nra_additional"/>
|
||||
<field name="date_from" eval="datetime(2019, 1, 1).date()"/>
|
||||
</record>
|
||||
<record id="rule_parameter_941_fit_nra_additional_2020" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">{
|
||||
'weekly': 238.50,
|
||||
@@ -86,6 +46,19 @@
|
||||
<field name="rule_parameter_id" ref="rule_parameter_941_fit_nra_additional"/>
|
||||
<field name="date_from" eval="datetime(2020, 1, 1).date()"/>
|
||||
</record>
|
||||
<record id="rule_parameter_941_fit_nra_additional_2021" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">{
|
||||
'weekly': 241.30,
|
||||
'bi-weekly': 482.70,
|
||||
'semi-monthly': 522.90,
|
||||
'monthly': 1045.80,
|
||||
'quarterly': 3137.50,
|
||||
'semi-annually': 6275.00,
|
||||
'annually': 12550.00,
|
||||
}</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_941_fit_nra_additional"/>
|
||||
<field name="date_from" eval="datetime(2021, 1, 1).date()"/>
|
||||
</record>
|
||||
|
||||
<!-- Single and Married Single Rate -->
|
||||
<record id="rule_parameter_941_fit_table_single" model="hr.rule.parameter">
|
||||
@@ -93,161 +66,7 @@
|
||||
<field name="code">fed_941_fit_table_single</field>
|
||||
<field name="country_id" ref="base.us"/>
|
||||
</record>
|
||||
<record id="rule_parameter_941_fit_table_single_2018" model="hr.rule.parameter.value">
|
||||
<!-- Bogus 2018 -->
|
||||
<!-- But-not-over, $, % -->
|
||||
<field name="parameter_value">{
|
||||
'weekly': [
|
||||
( 73.00, 0.00, 0),
|
||||
( 260.00, 0.00, 10),
|
||||
( 832.00, 18.70, 12),
|
||||
( 1692.00, 87.34, 22),
|
||||
( 3164.00, 276.54, 24),
|
||||
( 3998.00, 629.82, 32),
|
||||
( 9887.00, 896.70, 35),
|
||||
( 'inf', 2957.85, 37),
|
||||
],
|
||||
'bi-weekly': [
|
||||
( 146.00, 0.00, 0),
|
||||
( 519.00, 0.00, 10),
|
||||
( 1664.00, 37.30, 12),
|
||||
( 3385.00, 174.70, 22),
|
||||
( 6328.00, 553.32, 24),
|
||||
( 7996.00, 1259.64, 32),
|
||||
( 19773.00, 1793.40, 35),
|
||||
( 'inf', 5915.35, 37),
|
||||
],
|
||||
'semi-monthly': [
|
||||
( 158.00, 0.00, 0),
|
||||
( 563.00, 0.00, 10),
|
||||
( 1803.00, 40.50, 12),
|
||||
( 3667.00, 189.30, 22),
|
||||
( 6855.00, 599.38, 24),
|
||||
( 8663.00, 1364.50, 32),
|
||||
( 21421.00, 1943.06, 35),
|
||||
( 'inf', 6408.36, 37),
|
||||
],
|
||||
'monthly': [
|
||||
( 317.00, 0.00, 0),
|
||||
( 1125.00, 0.00, 10),
|
||||
( 3606.00, 80.80, 12),
|
||||
( 7333.00, 378.52, 22),
|
||||
( 13710.00, 1198.46, 24),
|
||||
( 17325.00, 2728.94, 32),
|
||||
( 42842.00, 3885.74, 35),
|
||||
( 'inf', 12816.69, 37),
|
||||
],
|
||||
'quarterly': [
|
||||
( 950.00, 0.00, 0),
|
||||
( 3375.00, 0.00, 10),
|
||||
( 10819.00, 242.50, 12),
|
||||
( 22000.00, 1135.78, 22),
|
||||
( 41131.00, 3595.60, 24),
|
||||
( 51975.00, 8187.04, 32),
|
||||
( 128525.00, 11657.12, 35),
|
||||
( 'inf', 38449.62, 37),
|
||||
],
|
||||
'semi-annually': [
|
||||
( 1900.00, 0.00, 0),
|
||||
( 6750.00, 0.00, 10),
|
||||
( 21638.00, 485.00, 12),
|
||||
( 44000.00, 2271.56, 22),
|
||||
( 82263.00, 7191.20, 24),
|
||||
( 103950.00, 16374.32, 32),
|
||||
( 257050.00, 23314.16, 35),
|
||||
( 'inf', 76899.16, 37),
|
||||
],
|
||||
'annually': [
|
||||
( 3800.00, 0.00, 0),
|
||||
( 13500.00, 0.00, 10),
|
||||
( 43275.00, 970.00, 12),
|
||||
( 88000.00, 4543.00, 22),
|
||||
( 164525.00, 14382.50, 24),
|
||||
( 207900.00, 32748.50, 32),
|
||||
( 514100.00, 46628.50, 35),
|
||||
( 'inf', 153798.50, 37),
|
||||
],
|
||||
}</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_941_fit_table_single"/>
|
||||
<field name="date_from" eval="datetime(2018, 1, 1).date()"/>
|
||||
</record>
|
||||
<record id="rule_parameter_941_fit_table_single_2019" model="hr.rule.parameter.value">
|
||||
<!-- But-not-over, $, % -->
|
||||
<field name="parameter_value">{
|
||||
'weekly': [
|
||||
( 73.00, 0.00, 0),
|
||||
( 260.00, 0.00, 10),
|
||||
( 832.00, 18.70, 12),
|
||||
( 1692.00, 87.34, 22),
|
||||
( 3164.00, 276.54, 24),
|
||||
( 3998.00, 629.82, 32),
|
||||
( 9887.00, 896.70, 35),
|
||||
( 'inf', 2957.85, 37),
|
||||
],
|
||||
'bi-weekly': [
|
||||
( 146.00, 0.00, 0),
|
||||
( 519.00, 0.00, 10),
|
||||
( 1664.00, 37.30, 12),
|
||||
( 3385.00, 174.70, 22),
|
||||
( 6328.00, 553.32, 24),
|
||||
( 7996.00, 1259.64, 32),
|
||||
( 19773.00, 1793.40, 35),
|
||||
( 'inf', 5915.35, 37),
|
||||
],
|
||||
'semi-monthly': [
|
||||
( 158.00, 0.00, 0),
|
||||
( 563.00, 0.00, 10),
|
||||
( 1803.00, 40.50, 12),
|
||||
( 3667.00, 189.30, 22),
|
||||
( 6855.00, 599.38, 24),
|
||||
( 8663.00, 1364.50, 32),
|
||||
( 21421.00, 1943.06, 35),
|
||||
( 'inf', 6408.36, 37),
|
||||
],
|
||||
'monthly': [
|
||||
( 317.00, 0.00, 0),
|
||||
( 1125.00, 0.00, 10),
|
||||
( 3606.00, 80.80, 12),
|
||||
( 7333.00, 378.52, 22),
|
||||
( 13710.00, 1198.46, 24),
|
||||
( 17325.00, 2728.94, 32),
|
||||
( 42842.00, 3885.74, 35),
|
||||
( 'inf', 12816.69, 37),
|
||||
],
|
||||
'quarterly': [
|
||||
( 950.00, 0.00, 0),
|
||||
( 3375.00, 0.00, 10),
|
||||
( 10819.00, 242.50, 12),
|
||||
( 22000.00, 1135.78, 22),
|
||||
( 41131.00, 3595.60, 24),
|
||||
( 51975.00, 8187.04, 32),
|
||||
( 128525.00, 11657.12, 35),
|
||||
( 'inf', 38449.62, 37),
|
||||
],
|
||||
'semi-annually': [
|
||||
( 1900.00, 0.00, 0),
|
||||
( 6750.00, 0.00, 10),
|
||||
( 21638.00, 485.00, 12),
|
||||
( 44000.00, 2271.56, 22),
|
||||
( 82263.00, 7191.20, 24),
|
||||
( 103950.00, 16374.32, 32),
|
||||
( 257050.00, 23314.16, 35),
|
||||
( 'inf', 76899.16, 37),
|
||||
],
|
||||
'annually': [
|
||||
( 3800.00, 0.00, 0),
|
||||
( 13500.00, 0.00, 10),
|
||||
( 43275.00, 970.00, 12),
|
||||
( 88000.00, 4543.00, 22),
|
||||
( 164525.00, 14382.50, 24),
|
||||
( 207900.00, 32748.50, 32),
|
||||
( 514100.00, 46628.50, 35),
|
||||
( 'inf', 153798.50, 37),
|
||||
],
|
||||
}</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_941_fit_table_single"/>
|
||||
<field name="date_from" eval="datetime(2019, 1, 1).date()"/>
|
||||
</record>
|
||||
<!-- page 6 of 15T Standard is left column and higher is right column-->
|
||||
<record id="rule_parameter_941_fit_table_single_2020" model="hr.rule.parameter.value">
|
||||
<!-- Major changes in 2020 -->
|
||||
<!-- Wage Threshold, Base Withholding Amount, Marginal Rate Over Threshold -->
|
||||
@@ -276,6 +95,33 @@
|
||||
<field name="rule_parameter_id" ref="rule_parameter_941_fit_table_single"/>
|
||||
<field name="date_from" eval="datetime(2020, 1, 1).date()"/>
|
||||
</record>
|
||||
<record id="rule_parameter_941_fit_table_single_2021" model="hr.rule.parameter.value">
|
||||
<!-- Wage Threshold, Base Withholding Amount, Marginal Rate Over Threshold -->
|
||||
<field name="parameter_value">{
|
||||
'standard': [
|
||||
( 0.00, 0.00, 0.00),
|
||||
( 3950.00, 0.00, 0.10),
|
||||
( 13900.00, 995.00, 0.12),
|
||||
( 44475.00, 4664.00, 0.22),
|
||||
( 90325.00, 14751.00, 0.24),
|
||||
( 168875.00, 33603.00, 0.32),
|
||||
( 213375.00, 47843.00, 0.35),
|
||||
( 527550.00, 157804.25, 0.37),
|
||||
],
|
||||
'higher': [
|
||||
( 0.00, 0.00, 0.00),
|
||||
( 6275.00, 0.00, 0.10),
|
||||
( 11250.00, 497.50, 0.12),
|
||||
( 26538.00, 2332.00, 0.22),
|
||||
( 49463.00, 7375.50, 0.24),
|
||||
( 88738.00, 16801.50, 0.32),
|
||||
( 110988.00, 23921.50, 0.35),
|
||||
( 268075.00, 78902.13, 0.37),
|
||||
],
|
||||
}</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_941_fit_table_single"/>
|
||||
<field name="date_from" eval="datetime(2021, 1, 1).date()"/>
|
||||
</record>
|
||||
|
||||
<!-- Married -->
|
||||
<record id="rule_parameter_941_fit_table_married" model="hr.rule.parameter">
|
||||
@@ -283,161 +129,6 @@
|
||||
<field name="code">fed_941_fit_table_married</field>
|
||||
<field name="country_id" ref="base.us"/>
|
||||
</record>
|
||||
<record id="rule_parameter_941_fit_table_married_2018" model="hr.rule.parameter.value">
|
||||
<!-- Bogus 2018 -->
|
||||
<!-- But-not-over, $, % -->
|
||||
<field name="parameter_value">{
|
||||
'weekly': [
|
||||
( 227.00, 0.00, 0),
|
||||
( 600.00, 0.00, 10),
|
||||
( 1745.00, 37.30, 12),
|
||||
( 3465.00, 174.70, 22),
|
||||
( 6409.00, 553.10, 24),
|
||||
( 8077.00, 1259.66, 32),
|
||||
( 12003.00, 1793.42, 35),
|
||||
( 'inf', 3167.52, 37),
|
||||
],
|
||||
'bi-weekly': [
|
||||
( 454.00, 0.00, 0),
|
||||
( 1200.00, 0.00, 10),
|
||||
( 3490.00, 74.60, 12),
|
||||
( 6931.00, 349.40, 22),
|
||||
( 12817.00, 1106.42, 24),
|
||||
( 16154.00, 2519.06, 32),
|
||||
( 24006.00, 3586.90, 35),
|
||||
( 'inf', 6335.10, 37),
|
||||
],
|
||||
'semi-monthly': [
|
||||
( 492.00, 0.00, 0),
|
||||
( 1300.00, 0.00, 10),
|
||||
( 3781.00, 80.80, 12),
|
||||
( 7508.00, 378.52, 22),
|
||||
( 13885.00, 1198.46, 24),
|
||||
( 17500.00, 2728.94, 32),
|
||||
( 26006.00, 3885.74, 35),
|
||||
( 'inf', 6862.84, 37),
|
||||
],
|
||||
'monthly': [
|
||||
( 983.00, 0.00, 0),
|
||||
( 2600.00, 0.00, 10),
|
||||
( 7563.00, 161.70, 12),
|
||||
( 15017.00, 757.26, 22),
|
||||
( 27771.00, 2397.14, 24),
|
||||
( 35000.00, 5458.10, 32),
|
||||
( 52013.00, 7771.38, 35),
|
||||
( 'inf', 13725.93, 37),
|
||||
],
|
||||
'quarterly': [
|
||||
( 2950.00, 0.00, 0),
|
||||
( 7800.00, 0.00, 10),
|
||||
( 22688.00, 485.00, 12),
|
||||
( 45050.00, 2271.56, 22),
|
||||
( 83313.00, 7191.20, 24),
|
||||
( 105000.00, 16374.32, 32),
|
||||
( 156038.00, 23314.16, 35),
|
||||
( 'inf', 41177.46, 37),
|
||||
],
|
||||
'semi-annually': [
|
||||
( 5900.00, 0.00, 0),
|
||||
( 15600.00, 0.00, 10),
|
||||
( 45375.00, 970.00, 12),
|
||||
( 90100.00, 4543.00, 22),
|
||||
( 166625.00, 14382.50, 24),
|
||||
( 210000.00, 32748.50, 32),
|
||||
( 312075.00, 46628.50, 35),
|
||||
( 'inf', 82354.75, 37),
|
||||
],
|
||||
'annually': [
|
||||
( 11800.00, 0.00, 0),
|
||||
( 31200.00, 0.00, 10),
|
||||
( 90750.00, 1940.00, 12),
|
||||
( 180200.00, 9086.00, 22),
|
||||
( 333250.00, 28765.00, 24),
|
||||
( 420000.00, 65497.00, 32),
|
||||
( 624150.00, 93257.00, 35),
|
||||
( 'inf', 164709.50, 37),
|
||||
],
|
||||
}</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_941_fit_table_married"/>
|
||||
<field name="date_from" eval="datetime(2018, 1, 1).date()"/>
|
||||
</record>
|
||||
<record id="rule_parameter_941_fit_table_married_2019" model="hr.rule.parameter.value">
|
||||
<!-- But-not-over, $, % -->
|
||||
<field name="parameter_value">{
|
||||
'weekly': [
|
||||
( 227.00, 0.00, 0),
|
||||
( 600.00, 0.00, 10),
|
||||
( 1745.00, 37.30, 12),
|
||||
( 3465.00, 174.70, 22),
|
||||
( 6409.00, 553.10, 24),
|
||||
( 8077.00, 1259.66, 32),
|
||||
( 12003.00, 1793.42, 35),
|
||||
( 'inf', 3167.52, 37),
|
||||
],
|
||||
'bi-weekly': [
|
||||
( 454.00, 0.00, 0),
|
||||
( 1200.00, 0.00, 10),
|
||||
( 3490.00, 74.60, 12),
|
||||
( 6931.00, 349.40, 22),
|
||||
( 12817.00, 1106.42, 24),
|
||||
( 16154.00, 2519.06, 32),
|
||||
( 24006.00, 3586.90, 35),
|
||||
( 'inf', 6335.10, 37),
|
||||
],
|
||||
'semi-monthly': [
|
||||
( 492.00, 0.00, 0),
|
||||
( 1300.00, 0.00, 10),
|
||||
( 3781.00, 80.80, 12),
|
||||
( 7508.00, 378.52, 22),
|
||||
( 13885.00, 1198.46, 24),
|
||||
( 17500.00, 2728.94, 32),
|
||||
( 26006.00, 3885.74, 35),
|
||||
( 'inf', 6862.84, 37),
|
||||
],
|
||||
'monthly': [
|
||||
( 983.00, 0.00, 0),
|
||||
( 2600.00, 0.00, 10),
|
||||
( 7563.00, 161.70, 12),
|
||||
( 15017.00, 757.26, 22),
|
||||
( 27771.00, 2397.14, 24),
|
||||
( 35000.00, 5458.10, 32),
|
||||
( 52013.00, 7771.38, 35),
|
||||
( 'inf', 13725.93, 37),
|
||||
],
|
||||
'quarterly': [
|
||||
( 2950.00, 0.00, 0),
|
||||
( 7800.00, 0.00, 10),
|
||||
( 22688.00, 485.00, 12),
|
||||
( 45050.00, 2271.56, 22),
|
||||
( 83313.00, 7191.20, 24),
|
||||
( 105000.00, 16374.32, 32),
|
||||
( 156038.00, 23314.16, 35),
|
||||
( 'inf', 41177.46, 37),
|
||||
],
|
||||
'semi-annually': [
|
||||
( 5900.00, 0.00, 0),
|
||||
( 15600.00, 0.00, 10),
|
||||
( 45375.00, 970.00, 12),
|
||||
( 90100.00, 4543.00, 22),
|
||||
( 166625.00, 14382.50, 24),
|
||||
( 210000.00, 32748.50, 32),
|
||||
( 312075.00, 46628.50, 35),
|
||||
( 'inf', 82354.75, 37),
|
||||
],
|
||||
'annually': [
|
||||
( 11800.00, 0.00, 0),
|
||||
( 31200.00, 0.00, 10),
|
||||
( 90750.00, 1940.00, 12),
|
||||
( 180200.00, 9086.00, 22),
|
||||
( 333250.00, 28765.00, 24),
|
||||
( 420000.00, 65497.00, 32),
|
||||
( 624150.00, 93257.00, 35),
|
||||
( 'inf', 164709.50, 37),
|
||||
],
|
||||
}</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_941_fit_table_married"/>
|
||||
<field name="date_from" eval="datetime(2019, 1, 1).date()"/>
|
||||
</record>
|
||||
<record id="rule_parameter_941_fit_table_married_2020" model="hr.rule.parameter.value">
|
||||
<!-- Major changes in 2020 -->
|
||||
<!-- Wage Threshold, Base Withholding Amount, Marginal Rate Over Threshold -->
|
||||
@@ -466,6 +157,33 @@
|
||||
<field name="rule_parameter_id" ref="rule_parameter_941_fit_table_married"/>
|
||||
<field name="date_from" eval="datetime(2020, 1, 1).date()"/>
|
||||
</record>
|
||||
<record id="rule_parameter_941_fit_table_married_2021" model="hr.rule.parameter.value">
|
||||
<!-- Wage Threshold, Base Withholding Amount, Marginal Rate Over Threshold -->
|
||||
<field name="parameter_value">{
|
||||
'standard': [
|
||||
( 0.00, 0.00, 0.00),
|
||||
( 12200.00, 0.00, 0.10),
|
||||
( 32100.00, 1990.00, 0.12),
|
||||
( 93250.00, 9328.00, 0.22),
|
||||
( 184950.00, 29502.00, 0.24),
|
||||
( 342050.00, 67206.00, 0.32),
|
||||
( 431050.00, 95686.00, 0.35),
|
||||
( 640500.00, 168993.50, 0.37),
|
||||
],
|
||||
'higher': [
|
||||
( 0.00, 0.00, 0.00),
|
||||
( 12550.00, 0.00, 0.10),
|
||||
( 22500.00, 995.00, 0.12),
|
||||
( 53075.00, 4664.00, 0.22),
|
||||
( 98925.00, 14751.00, 0.24),
|
||||
( 177475.00, 33603.00, 0.32),
|
||||
( 221975.00, 47843.00, 0.35),
|
||||
( 326700.00, 84496.75, 0.37),
|
||||
],
|
||||
}</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_941_fit_table_married"/>
|
||||
<field name="date_from" eval="datetime(2021, 1, 1).date()"/>
|
||||
</record>
|
||||
|
||||
<record id="rule_parameter_941_fit_table_hh" model="hr.rule.parameter">
|
||||
<field name="name">Federal 941 FIT Table Head of Household</field>
|
||||
@@ -500,5 +218,33 @@
|
||||
<field name="rule_parameter_id" ref="rule_parameter_941_fit_table_hh"/>
|
||||
<field name="date_from" eval="datetime(2020, 1, 1).date()"/>
|
||||
</record>
|
||||
<record id="rule_parameter_941_fit_table_hh_2021" model="hr.rule.parameter.value">
|
||||
<!-- Major changes in 2020 -->
|
||||
<!-- Wage Threshold, Base Withholding Amount, Marginal Rate Over Threshold -->
|
||||
<field name="parameter_value">{
|
||||
'standard': [
|
||||
( 0.00, 0.00, 0.00),
|
||||
( 10200.00, 0.00, 0.10),
|
||||
( 24400.00, 1420.00, 0.12),
|
||||
( 64400.00, 6220.00, 0.22),
|
||||
( 96550.00, 13293.00, 0.24),
|
||||
( 175100.00, 32145.00, 0.32),
|
||||
( 219600.00, 46385.00, 0.35),
|
||||
( 533800.00, 156355.50, 0.37),
|
||||
],
|
||||
'higher': [
|
||||
( 0.00, 0.00, 0.00),
|
||||
( 9400.00, 0.00, 0.10),
|
||||
( 16500.00, 710.00, 0.12),
|
||||
( 36500.00, 3110.00, 0.22),
|
||||
( 52575.00, 6646.50, 0.24),
|
||||
( 91950.00, 16072.50, 0.32),
|
||||
( 114100.00, 23192.50, 0.35),
|
||||
( 271200.00, 78177.50, 0.37),
|
||||
],
|
||||
}</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_941_fit_table_hh"/>
|
||||
<field name="date_from" eval="datetime(2021, 1, 1).date()"/>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
@@ -4,41 +4,42 @@ from . import common
|
||||
|
||||
from . import test_special
|
||||
|
||||
from . import test_us_payslip_2019
|
||||
from . import test_us_payslip_2020
|
||||
from . import test_us_payslip_2021
|
||||
|
||||
|
||||
from . import test_us_ak_alaska_payslip_2019
|
||||
from . import test_us_ak_alaska_payslip_2020
|
||||
from . import test_us_ak_alaska_payslip_2021
|
||||
|
||||
from . import test_us_al_alabama_payslip_2019
|
||||
from . import test_us_al_alabama_payslip_2020
|
||||
from . import test_us_al_alabama_payslip_2021
|
||||
|
||||
from . import test_us_ar_arkansas_payslip_2019
|
||||
from . import test_us_ar_arkansas_payslip_2020
|
||||
from . import test_us_ar_arkansas_payslip_2021
|
||||
|
||||
from . import test_us_az_arizona_payslip_2019
|
||||
from . import test_us_az_arizona_payslip_2020
|
||||
from . import test_us_az_arizona_payslip_2021
|
||||
|
||||
from . import test_us_ca_california_payslip_2019
|
||||
from . import test_us_ca_california_payslip_2020
|
||||
from . import test_us_ca_california_payslip_2021
|
||||
|
||||
from . import test_us_co_colorado_payslip_2020
|
||||
from . import test_us_co_colorado_payslip_2021
|
||||
|
||||
from . import test_us_ct_connecticut_payslip_2019
|
||||
from . import test_us_ct_connecticut_payslip_2020
|
||||
from . import test_us_ct_connecticut_payslip_2021
|
||||
|
||||
from . import test_us_de_delaware_payslip_2020
|
||||
from . import test_us_de_delaware_payslip_2021
|
||||
|
||||
from . import test_us_fl_florida_payslip_2019
|
||||
from . import test_us_fl_florida_payslip_2020
|
||||
from . import test_us_fl_florida_payslip_2021
|
||||
|
||||
from . import test_us_ga_georgia_payslip_2019
|
||||
from . import test_us_ga_georgia_payslip_2020
|
||||
from . import test_us_ga_georgia_payslip_2021
|
||||
|
||||
from . import test_us_hi_hawaii_payslip_2019
|
||||
from . import test_us_hi_hawaii_payslip_2020
|
||||
from . import test_us_hi_hawaii_payslip_2021
|
||||
|
||||
from . import test_us_ia_iowa_payslip_2020
|
||||
from . import test_us_ia_iowa_payslip_2021
|
||||
@@ -46,87 +47,103 @@ from . import test_us_ia_iowa_payslip_2021
|
||||
from . import test_us_id_idaho_payslip_2019
|
||||
from . import test_us_id_idaho_payslip_2020
|
||||
|
||||
from . import test_us_il_illinois_payslip_2019
|
||||
from . import test_us_il_illinois_payslip_2020
|
||||
from . import test_us_il_illinois_payslip_2021
|
||||
|
||||
from . import test_us_in_indiana_payslip_2020
|
||||
from . import test_us_in_indiana_payslip_2021
|
||||
|
||||
from . import test_us_ky_kentucky_payslip_2020
|
||||
from . import test_us_ky_kentucky_payslip_2021
|
||||
|
||||
from . import test_us_ks_kansas_payslip_2020
|
||||
from . import test_us_ks_kansas_payslip_2021
|
||||
|
||||
from . import test_us_la_louisiana_payslip_2019
|
||||
from . import test_us_la_louisiana_payslip_2020
|
||||
from . import test_us_la_louisiana_payslip_2021
|
||||
|
||||
from . import test_us_me_maine_payslip_2020
|
||||
from . import test_us_me_maine_payslip_2021
|
||||
|
||||
from . import test_us_mi_michigan_payslip_2019
|
||||
from . import test_us_mi_michigan_payslip_2020
|
||||
from . import test_us_mi_michigan_payslip_2021
|
||||
|
||||
from . import test_us_mn_minnesota_payslip_2019
|
||||
from . import test_us_mn_minnesota_payslip_2020
|
||||
from . import test_us_mn_minnesota_payslip_2021
|
||||
|
||||
from . import test_us_mo_missouri_payslip_2019
|
||||
from . import test_us_mo_missouri_payslip_2020
|
||||
from . import test_us_mo_missouri_payslip_2021
|
||||
|
||||
from . import test_us_ms_mississippi_payslip_2019
|
||||
from . import test_us_ms_mississippi_payslip_2020
|
||||
from . import test_us_ms_mississippi_payslip_2021
|
||||
|
||||
from . import test_us_mt_montana_payslip_2019
|
||||
from . import test_us_mt_montana_payslip_2020
|
||||
from . import test_us_mt_montana_payslip_2021
|
||||
|
||||
from . import test_us_nc_northcarolina_payslip_2019
|
||||
from . import test_us_nc_northcarolina_payslip_2020
|
||||
from . import test_us_nc_northcarolina_payslip_2021
|
||||
|
||||
from . import test_us_nd_north_dakota_payslip_2020
|
||||
from . import test_us_nd_north_dakota_payslip_2021
|
||||
|
||||
from . import test_us_ne_nebraska_payslip_2020
|
||||
from . import test_us_ne_nebraska_payslip_2021
|
||||
|
||||
from . import test_us_nh_new_hampshire_payslip_2020
|
||||
from . import test_us_nh_new_hampshire_payslip_2021
|
||||
|
||||
from . import test_us_nj_newjersey_payslip_2019
|
||||
from . import test_us_nj_newjersey_payslip_2020
|
||||
from . import test_us_nj_newjersey_payslip_2021
|
||||
|
||||
from . import test_us_nm_new_mexico_payslip_2020
|
||||
from . import test_us_nm_new_mexico_payslip_2021
|
||||
|
||||
from . import test_us_nv_nevada_payslip_2020
|
||||
from . import test_us_nv_nevada_payslip_2021
|
||||
|
||||
from . import test_us_ny_new_york_payslip_2019
|
||||
from . import test_us_ny_new_york_payslip_2020
|
||||
from . import test_us_ny_new_york_payslip_2021
|
||||
|
||||
from . import test_us_oh_ohio_payslip_2019
|
||||
from . import test_us_oh_ohio_payslip_2020
|
||||
from . import test_us_oh_ohio_payslip_2021
|
||||
|
||||
from . import test_us_ok_oklahoma_payslip_2020
|
||||
from . import test_us_ok_oklahoma_payslip_2021
|
||||
|
||||
from . import test_us_pa_pennsylvania_payslip_2019
|
||||
from . import test_us_pa_pennsylvania_payslip_2020
|
||||
from . import test_us_pa_pennsylvania_payslip_2021
|
||||
|
||||
from . import test_us_ri_rhode_island_payslip_2020
|
||||
from . import test_us_ri_rhode_island_payslip_2021
|
||||
|
||||
from . import test_us_sc_south_carolina_payslip_2019
|
||||
from . import test_us_sc_south_carolina_payslip_2020
|
||||
from . import test_us_sc_south_carolina_payslip_2021
|
||||
|
||||
from . import test_us_sd_south_dakota_payslip_2020
|
||||
from . import test_us_sd_south_dakota_payslip_2021
|
||||
|
||||
from . import test_us_tn_tennessee_payslip_2020
|
||||
from . import test_us_tn_tennessee_payslip_2021
|
||||
|
||||
from . import test_us_tx_texas_payslip_2019
|
||||
from . import test_us_tx_texas_payslip_2020
|
||||
|
||||
from . import test_us_us_utah_payslip_2020
|
||||
from . import test_us_us_utah_payslip_2021
|
||||
|
||||
from . import test_us_vt_vermont_payslip_2020
|
||||
from . import test_us_vt_vermont_payslip_2021
|
||||
|
||||
from . import test_us_va_virginia_payslip_2019
|
||||
from . import test_us_va_virginia_payslip_2020
|
||||
from . import test_us_va_virginia_payslip_2021
|
||||
|
||||
from . import test_us_wa_washington_payslip_2019
|
||||
from . import test_us_wa_washington_payslip_2020
|
||||
from . import test_us_wa_washington_payslip_2021
|
||||
|
||||
from . import test_us_wv_west_virginia_payslip_2020
|
||||
|
||||
from . import test_us_wi_wisconsin_payslip_2020
|
||||
from . import test_us_wi_wisconsin_payslip_2021
|
||||
|
||||
from . import test_us_wy_wyoming_payslip_2019
|
||||
from . import test_us_wy_wyoming_payslip_2020
|
||||
from . import test_us_wy_wyoming_payslip_2021
|
||||
|
||||
@@ -1,338 +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
|
||||
|
||||
from sys import float_info
|
||||
|
||||
|
||||
class TestUsPayslip2019(TestUsPayslip):
|
||||
# FUTA Constants
|
||||
FUTA_RATE_NORMAL = 0.6
|
||||
FUTA_RATE_BASIC = 6.0
|
||||
FUTA_RATE_EXEMPT = 0.0
|
||||
|
||||
# Wage caps
|
||||
FICA_SS_MAX_WAGE = 132900.0
|
||||
FICA_M_MAX_WAGE = float_info.max
|
||||
FICA_M_ADD_START_WAGE = 200000.0
|
||||
FUTA_MAX_WAGE = 7000.0
|
||||
|
||||
# Rates
|
||||
FICA_SS = 6.2 / -100.0
|
||||
FICA_M = 1.45 / -100.0
|
||||
FUTA = FUTA_RATE_NORMAL / -100.0
|
||||
FICA_M_ADD = 0.9 / -100.0
|
||||
|
||||
###
|
||||
# 2019 Taxes and Rates
|
||||
###
|
||||
|
||||
def test_2019_taxes(self):
|
||||
self.debug = False
|
||||
# salary is high so that second payslip runs over max
|
||||
# social security salary
|
||||
salary = 80000.0
|
||||
|
||||
employee = self._createEmployee()
|
||||
|
||||
contract = self._createContract(employee, wage=salary)
|
||||
self._log(contract.read())
|
||||
|
||||
self._log('2018 tax last slip')
|
||||
payslip = self._createPayslip(employee, '2018-12-01', '2018-12-31')
|
||||
payslip.compute_sheet()
|
||||
self._log(payslip.read())
|
||||
process_payslip(payslip)
|
||||
|
||||
# Ensure amounts are there, they shouldn't be added in the next year...
|
||||
cats = self._getCategories(payslip)
|
||||
self.assertTrue(cats['ER_US_940_FUTA'], self.FUTA_MAX_WAGE * self.FUTA)
|
||||
|
||||
self._log('2019 tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
rules = self._getRules(payslip)
|
||||
# Employee
|
||||
self.assertPayrollEqual(rules['EE_US_941_FICA_SS'], cats['BASIC'] * self.FICA_SS)
|
||||
self.assertPayrollEqual(rules['EE_US_941_FICA_M'], cats['BASIC'] * self.FICA_M)
|
||||
self.assertPayrollEqual(rules['EE_US_941_FICA_M_ADD'], 0.0)
|
||||
# Employer
|
||||
self.assertPayrollEqual(rules['ER_US_941_FICA_SS'], rules['EE_US_941_FICA_SS'])
|
||||
self.assertPayrollEqual(rules['ER_US_941_FICA_M'], rules['EE_US_941_FICA_M'])
|
||||
self.assertTrue(cats['ER_US_940_FUTA'], self.FUTA_MAX_WAGE * self.FUTA)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
# Make a new payslip, this one will have reached Medicare Additional (employee only)
|
||||
remaining_ss_wages = self.FICA_SS_MAX_WAGE - salary if (self.FICA_SS_MAX_WAGE - 2 * salary < salary) else salary
|
||||
remaining_m_wages = self.FICA_M_MAX_WAGE - salary if (self.FICA_M_MAX_WAGE - 2 * salary < salary) else salary
|
||||
|
||||
self._log('2019 tax second payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
rules = self._getRules(payslip)
|
||||
|
||||
self.assertPayrollEqual(rules['EE_US_941_FICA_SS'], remaining_ss_wages * self.FICA_SS)
|
||||
self.assertPayrollEqual(rules['EE_US_941_FICA_M'], remaining_m_wages * self.FICA_M)
|
||||
self.assertPayrollEqual(rules['EE_US_941_FICA_M_ADD'], 0.0)
|
||||
self.assertPayrollEqual(cats['ER_US_940_FUTA'], 0.0)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
# Make a new payslip, this one will have reached Medicare Additional (employee only)
|
||||
self._log('2019 tax third payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-03-01', '2019-03-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
rules = self._getRules(payslip)
|
||||
|
||||
self.assertPayrollEqual(rules['EE_US_941_FICA_M_ADD'], (self.FICA_M_ADD_START_WAGE - (salary * 2)) * self.FICA_M_ADD) # aka 40k
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
# Make a new payslip, this one will have all salary as Medicare Additional
|
||||
|
||||
self._log('2019 tax fourth payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-04-01', '2019-04-30')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
rules = self._getRules(payslip)
|
||||
|
||||
self.assertPayrollEqual(rules['EE_US_941_FICA_M_ADD'], salary * self.FICA_M_ADD)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
def test_2019_fed_income_withholding_single(self):
|
||||
self.debug = False
|
||||
|
||||
salary = 6000.00
|
||||
schedule_pay = 'monthly'
|
||||
w4_allowances = 3
|
||||
w4_allowance_amt = 350.00 * w4_allowances
|
||||
adjusted_salary = salary - w4_allowance_amt # should be 4962.60, but would work over a wide value for the rate
|
||||
###
|
||||
# Single MONTHLY form Publication 15
|
||||
expected_withholding = self.float_round(-(378.52 + ((adjusted_salary - 3606) * 0.22)), self.payroll_digits)
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
schedule_pay=schedule_pay,
|
||||
fed_941_fit_w4_filing_status='single',
|
||||
fed_941_fit_w4_allowances=w4_allowances
|
||||
)
|
||||
|
||||
self._log('2019 fed income single payslip: adjusted_salary: ' + str(adjusted_salary))
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
self.assertPayrollEqual(cats['EE_US_941_FIT'], expected_withholding)
|
||||
|
||||
def test_2019_fed_income_withholding_married_as_single(self):
|
||||
salary = 500.00
|
||||
schedule_pay = 'weekly'
|
||||
w4_allowances = 1
|
||||
w4_allowance_amt = 80.80 * w4_allowances
|
||||
adjusted_salary = salary - w4_allowance_amt # should be 420.50, but would work over a wide value for the rate
|
||||
###
|
||||
expected_withholding = self.float_round(-(18.70 + ((adjusted_salary - 260) * 0.12)), self.payroll_digits)
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
schedule_pay=schedule_pay,
|
||||
fed_941_fit_w4_filing_status='married_as_single',
|
||||
fed_941_fit_w4_allowances=w4_allowances,
|
||||
)
|
||||
|
||||
self._log('2019 fed income married_as_single payslip: adjusted_salary: ' + str(adjusted_salary))
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
self.assertPayrollEqual(cats['EE_US_941_FIT'], expected_withholding)
|
||||
|
||||
def test_2019_fed_income_withholding_married(self):
|
||||
salary = 14000.00
|
||||
schedule_pay = 'bi-weekly'
|
||||
w4_allowances = 2
|
||||
w4_allowance_amt = 161.50 * w4_allowances
|
||||
adjusted_salary = salary - w4_allowance_amt # should be 13680.80, but would work over a wide value for the rate
|
||||
###
|
||||
# Single MONTHLY form Publication 15
|
||||
expected_withholding = self.float_round(-(2519.06 + ((adjusted_salary - 12817) * 0.32)), self.payroll_digits)
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
schedule_pay=schedule_pay,
|
||||
fed_941_fit_w4_filing_status='married',
|
||||
fed_941_fit_w4_allowances=w4_allowances
|
||||
)
|
||||
|
||||
self._log('2019 fed income married payslip: adjusted_salary: ' + str(adjusted_salary))
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
# This is off by 1 penny given our new reporting of adjusted wage * computed percentage
|
||||
#self.assertPayrollEqual(cats['EE_US_941_FIT'], expected_withholding)
|
||||
self.assertTrue(abs(cats['EE_US_941_FIT'] - expected_withholding) < 0.011)
|
||||
|
||||
def test_2019_taxes_with_external(self):
|
||||
# social security salary
|
||||
salary = self.FICA_M_ADD_START_WAGE
|
||||
external_wages = 6000.0
|
||||
|
||||
employee = self._createEmployee()
|
||||
|
||||
self._createContract(employee, wage=salary, external_wages=external_wages)
|
||||
|
||||
self._log('2019 tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
rules = self._getRules(payslip)
|
||||
self.assertPayrollEqual(rules['EE_US_941_FICA_SS'], (self.FICA_SS_MAX_WAGE - external_wages) * self.FICA_SS)
|
||||
self.assertPayrollEqual(rules['EE_US_941_FICA_M'], salary * self.FICA_M)
|
||||
self.assertPayrollEqual(rules['EE_US_941_FICA_M_ADD'], external_wages * self.FICA_M_ADD)
|
||||
self.assertPayrollEqual(rules['ER_US_941_FICA_SS'], rules['EE_US_941_FICA_SS'])
|
||||
self.assertPayrollEqual(rules['ER_US_941_FICA_M'], rules['EE_US_941_FICA_M'])
|
||||
self.assertPayrollEqual(cats['ER_US_940_FUTA'], (self.FUTA_MAX_WAGE - external_wages) * self.FUTA)
|
||||
|
||||
def test_2019_taxes_with_full_futa(self):
|
||||
futa_rate = self.FUTA_RATE_BASIC / -100.0
|
||||
# social security salary
|
||||
salary = self.FICA_M_ADD_START_WAGE
|
||||
|
||||
employee = self._createEmployee()
|
||||
|
||||
self._createContract(employee, wage=salary, fed_940_type=USHRContract.FUTA_TYPE_BASIC)
|
||||
|
||||
self._log('2019 tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
rules = self._getRules(payslip)
|
||||
self.assertPayrollEqual(rules['EE_US_941_FICA_SS'], self.FICA_SS_MAX_WAGE * self.FICA_SS)
|
||||
self.assertPayrollEqual(rules['EE_US_941_FICA_M'], salary * self.FICA_M)
|
||||
self.assertPayrollEqual(rules['EE_US_941_FICA_M_ADD'], 0.0 * self.FICA_M_ADD)
|
||||
self.assertPayrollEqual(rules['ER_US_941_FICA_SS'], rules['EE_US_941_FICA_SS'])
|
||||
self.assertPayrollEqual(rules['ER_US_941_FICA_M'], rules['EE_US_941_FICA_M'])
|
||||
self.assertPayrollEqual(cats['ER_US_940_FUTA'], self.FUTA_MAX_WAGE * futa_rate)
|
||||
|
||||
def test_2019_taxes_with_futa_exempt(self):
|
||||
futa_rate = self.FUTA_RATE_EXEMPT / -100.0 # because of exemption
|
||||
|
||||
# social security salary
|
||||
salary = self.FICA_M_ADD_START_WAGE
|
||||
employee = self._createEmployee()
|
||||
self._createContract(employee, wage=salary, fed_940_type=USHRContract.FUTA_TYPE_EXEMPT)
|
||||
self._log('2019 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_940_FUTA'], 0.0)
|
||||
|
||||
def test_2019_fed_income_withholding_nonresident_alien(self):
|
||||
salary = 3500.00
|
||||
schedule_pay = 'quarterly'
|
||||
w4_allowances = 1
|
||||
w4_allowance_amt = 1050.0 * w4_allowances
|
||||
nra_adjustment = 2000.0 # for quarterly
|
||||
adjusted_salary = salary - w4_allowance_amt + nra_adjustment # 4450
|
||||
|
||||
###
|
||||
# Single QUARTERLY form Publication 15
|
||||
expected_withholding = self.float_round(-(242.50 + ((adjusted_salary - 3375) * 0.12)), self.payroll_digits)
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
schedule_pay=schedule_pay,
|
||||
fed_941_fit_w4_allowances=w4_allowances,
|
||||
fed_941_fit_w4_is_nonresident_alien=True,
|
||||
)
|
||||
|
||||
self._log('2019 fed income single payslip nonresident alien: adjusted_salary: ' + str(adjusted_salary))
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
rules = self._getRules(payslip)
|
||||
self.assertPayrollEqual(rules['EE_US_941_FIT'], expected_withholding)
|
||||
|
||||
def test_2019_fed_income_additional_withholding(self):
|
||||
salary = 50000.00
|
||||
schedule_pay = 'annually'
|
||||
w4_additional_withholding = 5000.0
|
||||
w4_allowances = 2
|
||||
w4_allowance_amt = 4200.0 * w4_allowances
|
||||
adjusted_salary = salary - w4_allowance_amt # 41700
|
||||
|
||||
###
|
||||
# Single ANNUAL form Publication 15
|
||||
expected_withholding = \
|
||||
self.float_round(-((1940.00 + ((adjusted_salary - 31200) * 0.12)) + w4_additional_withholding),
|
||||
self.payroll_digits)
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
schedule_pay=schedule_pay,
|
||||
fed_941_fit_w4_filing_status='married',
|
||||
fed_941_fit_w4_allowances=w4_allowances,
|
||||
fed_941_fit_w4_additional_withholding=w4_additional_withholding,
|
||||
)
|
||||
|
||||
self._log('2019 fed income married payslip additional withholding: adjusted_salary: ' + str(adjusted_salary))
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
|
||||
rules = self._getRules(payslip)
|
||||
self.assertPayrollEqual(rules['EE_US_941_FIT'], expected_withholding)
|
||||
|
||||
def test_2019_taxes_with_w4_exempt(self):
|
||||
salary = 6000.0
|
||||
schedule_pay = 'bi-weekly'
|
||||
w4_allowances = 0
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
schedule_pay=schedule_pay,
|
||||
fed_941_fit_w4_allowances=w4_allowances,
|
||||
fed_941_fit_w4_filing_status='',
|
||||
)
|
||||
|
||||
self._log('2019 tax w4 exempt payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
rules = self._getRules(payslip)
|
||||
self.assertPayrollEqual(rules['EE_US_941_FIT'], 0.0)
|
||||
|
||||
def test_2019_taxes_with_fica_exempt(self):
|
||||
salary = 6000.0
|
||||
schedule_pay = 'bi-weekly'
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee, wage=salary, schedule_pay=schedule_pay)
|
||||
contract.us_payroll_config_id.fed_941_fica_exempt = True
|
||||
|
||||
self._log('2019 tax w4 exempt payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
self.assertPayrollEqual(cats['EE_US_941_FICA'], 0.0)
|
||||
self.assertPayrollEqual(cats['ER_US_941_FICA'], 0.0)
|
||||
294
l10n_us_hr_payroll/tests/test_us_payslip_2021.py
Normal file
294
l10n_us_hr_payroll/tests/test_us_payslip_2021.py
Normal file
@@ -0,0 +1,294 @@
|
||||
# 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
|
||||
|
||||
from sys import float_info
|
||||
|
||||
|
||||
class TestUsPayslip2021(TestUsPayslip):
|
||||
# FUTA Constants
|
||||
FUTA_RATE_NORMAL = 0.6
|
||||
FUTA_RATE_BASIC = 6.0
|
||||
FUTA_RATE_EXEMPT = 0.0
|
||||
|
||||
# Wage caps
|
||||
FICA_SS_MAX_WAGE = 142800.0
|
||||
FICA_M_MAX_WAGE = float_info.max
|
||||
FICA_M_ADD_START_WAGE = 200000.0
|
||||
FUTA_MAX_WAGE = 7000.0
|
||||
|
||||
# Rates
|
||||
FICA_SS = 6.2 / -100.0
|
||||
FICA_M = 1.45 / -100.0
|
||||
FUTA = FUTA_RATE_NORMAL / -100.0
|
||||
FICA_M_ADD = 0.9 / -100.0
|
||||
|
||||
###
|
||||
# 2021 Taxes and Rates
|
||||
###
|
||||
|
||||
def test_2021_taxes(self):
|
||||
# salary is high so that second payslip runs over max
|
||||
# social security salary
|
||||
salary = 80000.0
|
||||
|
||||
employee = self._createEmployee()
|
||||
|
||||
contract = self._createContract(employee, wage=salary)
|
||||
self._log(contract.read())
|
||||
|
||||
self._log('2020 tax last slip')
|
||||
payslip = self._createPayslip(employee, '2020-12-01', '2020-12-31')
|
||||
self.assertEqual(payslip.contract_id, contract)
|
||||
self._log(payslip.read())
|
||||
process_payslip(payslip)
|
||||
|
||||
# Ensure amounts are there, they shouldn't be added in the next year...
|
||||
cats = self._getCategories(payslip)
|
||||
self.assertTrue(cats['ER_US_940_FUTA'], ' Value should be well above whatever was available that year!')
|
||||
|
||||
self._log('2021 tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2021-01-01', '2021-01-31')
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
rules = self._getRules(payslip)
|
||||
# Employee
|
||||
self.assertPayrollEqual(rules['EE_US_941_FICA_SS'], cats['BASIC'] * self.FICA_SS)
|
||||
self.assertPayrollEqual(rules['EE_US_941_FICA_M'], cats['BASIC'] * self.FICA_M)
|
||||
self.assertPayrollEqual(rules['EE_US_941_FICA_M_ADD'], 0.0)
|
||||
# Employer
|
||||
self.assertPayrollEqual(rules['ER_US_941_FICA_SS'], rules['EE_US_941_FICA_SS'])
|
||||
self.assertPayrollEqual(rules['ER_US_941_FICA_M'], rules['EE_US_941_FICA_M'])
|
||||
self.assertTrue(cats['ER_US_940_FUTA'], self.FUTA_MAX_WAGE * self.FUTA)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
# Make a new payslip, this one will have reached Medicare Additional (employee only)
|
||||
remaining_ss_wages = self.FICA_SS_MAX_WAGE - salary if (self.FICA_SS_MAX_WAGE - 2 * salary < salary) else salary
|
||||
remaining_m_wages = self.FICA_M_MAX_WAGE - salary if (self.FICA_M_MAX_WAGE - 2 * salary < salary) else salary
|
||||
|
||||
self._log('2021 tax second payslip:')
|
||||
payslip = self._createPayslip(employee, '2021-02-01', '2021-02-28')
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
rules = self._getRules(payslip)
|
||||
|
||||
self.assertPayrollEqual(rules['EE_US_941_FICA_SS'], remaining_ss_wages * self.FICA_SS)
|
||||
self.assertPayrollEqual(rules['EE_US_941_FICA_M'], remaining_m_wages * self.FICA_M)
|
||||
self.assertPayrollEqual(rules['EE_US_941_FICA_M_ADD'], 0.0)
|
||||
self.assertPayrollEqual(cats['ER_US_940_FUTA'], 0.0)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
# Make a new payslip, this one will have reached Medicare Additional (employee only)
|
||||
self._log('2021 tax third payslip:')
|
||||
payslip = self._createPayslip(employee, '2021-03-01', '2021-03-31')
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
rules = self._getRules(payslip)
|
||||
|
||||
self.assertPayrollEqual(rules['EE_US_941_FICA_M_ADD'], (self.FICA_M_ADD_START_WAGE - (salary * 2)) * self.FICA_M_ADD) # aka 40k
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
# Make a new payslip, this one will have all salary as Medicare Additional
|
||||
|
||||
self._log('2021 tax fourth payslip:')
|
||||
payslip = self._createPayslip(employee, '2021-04-01', '2021-04-30')
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
rules = self._getRules(payslip)
|
||||
|
||||
self.assertPayrollEqual(rules['EE_US_941_FICA_M_ADD'], salary * self.FICA_M_ADD)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
def test_2021_taxes_with_external(self):
|
||||
# social security salary
|
||||
salary = self.FICA_M_ADD_START_WAGE
|
||||
external_wages = 6000.0
|
||||
|
||||
employee = self._createEmployee()
|
||||
|
||||
self._createContract(employee, wage=salary, external_wages=external_wages)
|
||||
|
||||
self._log('2021 tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2021-01-01', '2021-01-31')
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
rules = self._getRules(payslip)
|
||||
self.assertPayrollEqual(rules['EE_US_941_FICA_SS'], (self.FICA_SS_MAX_WAGE - external_wages) * self.FICA_SS)
|
||||
self.assertPayrollEqual(rules['EE_US_941_FICA_M'], salary * self.FICA_M)
|
||||
self.assertPayrollEqual(rules['EE_US_941_FICA_M_ADD'], external_wages * self.FICA_M_ADD)
|
||||
self.assertPayrollEqual(rules['ER_US_941_FICA_SS'], rules['EE_US_941_FICA_SS'])
|
||||
self.assertPayrollEqual(rules['ER_US_941_FICA_M'], rules['EE_US_941_FICA_M'])
|
||||
self.assertPayrollEqual(cats['ER_US_940_FUTA'], (self.FUTA_MAX_WAGE - external_wages) * self.FUTA)
|
||||
|
||||
def test_2021_taxes_with_full_futa(self):
|
||||
futa_rate = self.FUTA_RATE_BASIC / -100.0
|
||||
# social security salary
|
||||
salary = self.FICA_M_ADD_START_WAGE
|
||||
|
||||
employee = self._createEmployee()
|
||||
|
||||
self._createContract(employee, wage=salary, fed_940_type=USHRContract.FUTA_TYPE_BASIC)
|
||||
|
||||
self._log('2021 tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2021-01-01', '2021-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
rules = self._getRules(payslip)
|
||||
self.assertPayrollEqual(rules['EE_US_941_FICA_SS'], self.FICA_SS_MAX_WAGE * self.FICA_SS)
|
||||
self.assertPayrollEqual(rules['EE_US_941_FICA_M'], salary * self.FICA_M)
|
||||
self.assertPayrollEqual(rules['EE_US_941_FICA_M_ADD'], 0.0 * self.FICA_M_ADD)
|
||||
self.assertPayrollEqual(rules['ER_US_941_FICA_SS'], rules['EE_US_941_FICA_SS'])
|
||||
self.assertPayrollEqual(rules['ER_US_941_FICA_M'], rules['EE_US_941_FICA_M'])
|
||||
self.assertPayrollEqual(cats['ER_US_940_FUTA'], self.FUTA_MAX_WAGE * futa_rate)
|
||||
|
||||
def test_2021_taxes_with_futa_exempt(self):
|
||||
futa_rate = self.FUTA_RATE_EXEMPT / -100.0 # because of exemption
|
||||
|
||||
# social security salary
|
||||
salary = self.FICA_M_ADD_START_WAGE
|
||||
employee = self._createEmployee()
|
||||
self._createContract(employee, wage=salary, fed_940_type=USHRContract.FUTA_TYPE_EXEMPT)
|
||||
self._log('2021 tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2021-01-01', '2021-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
self.assertPayrollEqual(cats['ER_US_940_FUTA'], 0.0)
|
||||
|
||||
def test_2021_taxes_with_fica_exempt(self):
|
||||
salary = 6000.0
|
||||
schedule_pay = 'bi-weekly'
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee, wage=salary, schedule_pay=schedule_pay)
|
||||
contract.us_payroll_config_id.fed_941_fica_exempt = True
|
||||
|
||||
self._log('2021 tax w4 exempt payslip:')
|
||||
payslip = self._createPayslip(employee, '2021-01-01', '2021-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
self.assertPayrollEqual(cats['EE_US_941_FICA'], 0.0)
|
||||
self.assertPayrollEqual(cats['ER_US_941_FICA'], 0.0)
|
||||
|
||||
"""
|
||||
For Federal Income Tax Withholding, we are utilizing the calculations from the new IRS Excel calculator.
|
||||
Given that you CAN round, we will round to compare even though we will calculate as close to the penny as possible
|
||||
with the wage * computed_percent method.
|
||||
"""
|
||||
|
||||
def _run_test_fit(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,
|
||||
expected_standard=0.0,
|
||||
expected_higher=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,
|
||||
)
|
||||
payslip = self._createPayslip(employee, '2021-01-01', '2021-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
self.assertPayrollEqual(round(cats.get('EE_US_941_FIT', 0.0)), -expected_standard)
|
||||
|
||||
contract.us_payroll_config_id.fed_941_fit_w4_multiple_jobs_higher = True
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
self.assertPayrollEqual(round(cats.get('EE_US_941_FIT', 0.0)), -expected_higher)
|
||||
return payslip
|
||||
|
||||
def test_2021_fed_income_withholding_single(self):
|
||||
_ = self._run_test_fit(
|
||||
wage=6000.0,
|
||||
schedule_pay='monthly',
|
||||
filing_status='single',
|
||||
dependent_credit=100.0,
|
||||
other_income=200.0,
|
||||
deductions=300.0,
|
||||
additional_withholding=400.0,
|
||||
is_nonresident_alien=False,
|
||||
expected_standard=1125.0,
|
||||
expected_higher=1455.0,
|
||||
)
|
||||
|
||||
def test_2021_fed_income_withholding_married_as_single(self):
|
||||
# This is "Head of Household" though the field name is the same for historical reasons.
|
||||
_ = self._run_test_fit(
|
||||
wage=500.0,
|
||||
schedule_pay='weekly',
|
||||
filing_status='married_as_single',
|
||||
dependent_credit=20.0,
|
||||
other_income=30.0,
|
||||
deductions=40.0,
|
||||
additional_withholding=10.0,
|
||||
is_nonresident_alien=False,
|
||||
expected_standard=23.0,
|
||||
expected_higher=45.0,
|
||||
)
|
||||
|
||||
def test_2021_fed_income_withholding_married(self):
|
||||
_ = self._run_test_fit(
|
||||
wage=14000.00,
|
||||
schedule_pay='bi-weekly',
|
||||
filing_status='married',
|
||||
dependent_credit=2500.0,
|
||||
other_income=1200.0,
|
||||
deductions=1000.0,
|
||||
additional_withholding=0.0,
|
||||
is_nonresident_alien=False,
|
||||
expected_standard=2603.0,
|
||||
expected_higher=3687.0,
|
||||
)
|
||||
|
||||
def test_2021_fed_income_withholding_nonresident_alien(self):
|
||||
# Monthly NRA additional wage is 1033.30
|
||||
# Wage input on IRS Form entered as (3500+1033.30)=4533.30, not 3500.0
|
||||
_ = self._run_test_fit(
|
||||
wage=3500.00,
|
||||
schedule_pay='monthly',
|
||||
filing_status='married',
|
||||
dependent_credit=340.0,
|
||||
other_income=0.0,
|
||||
deductions=0.0,
|
||||
additional_withholding=0.0,
|
||||
is_nonresident_alien=True,
|
||||
expected_standard=233.0,
|
||||
expected_higher=387.0,
|
||||
)
|
||||
|
||||
def test_2021_taxes_with_w4_exempt(self):
|
||||
_ = self._run_test_fit(
|
||||
wage=3500.00,
|
||||
schedule_pay='monthly',
|
||||
filing_status='', # Exempt
|
||||
dependent_credit=340.0,
|
||||
other_income=0.0,
|
||||
deductions=0.0,
|
||||
additional_withholding=0.0,
|
||||
is_nonresident_alien=True,
|
||||
expected_standard=0.0,
|
||||
expected_higher=0.0,
|
||||
)
|
||||
Reference in New Issue
Block a user