diff --git a/l10n_us_hr_payroll/data/federal/fed_940_futa_parameters.xml b/l10n_us_hr_payroll/data/federal/fed_940_futa_parameters.xml
index 9c34afb6..325f53b6 100644
--- a/l10n_us_hr_payroll/data/federal/fed_940_futa_parameters.xml
+++ b/l10n_us_hr_payroll/data/federal/fed_940_futa_parameters.xml
@@ -6,6 +6,7 @@
fed_940_futa_wage_base
+
7000.00
@@ -18,6 +19,7 @@
fed_940_futa_rate_basic
+
6.0
@@ -29,6 +31,7 @@
fed_940_futa_rate_normal
+
0.6
diff --git a/l10n_us_hr_payroll/data/federal/fed_941_fica_parameters.xml b/l10n_us_hr_payroll/data/federal/fed_941_fica_parameters.xml
index 1be404bb..6a4b2804 100644
--- a/l10n_us_hr_payroll/data/federal/fed_941_fica_parameters.xml
+++ b/l10n_us_hr_payroll/data/federal/fed_941_fica_parameters.xml
@@ -22,6 +22,12 @@
+
+
+ 142800.0
+
+
+
@@ -29,6 +35,7 @@
fed_941_fica_ss_rate
+
6.2
@@ -42,6 +49,7 @@
fed_941_fica_m_wage_base
+
"inf"
@@ -54,6 +62,7 @@
fed_941_fica_m_rate
+
1.45
@@ -67,6 +76,7 @@
fed_941_fica_m_add_wage_start
+
200000.0
@@ -79,6 +89,7 @@
fed_941_fica_m_add_rate
+
0.9
diff --git a/l10n_us_hr_payroll/data/federal/fed_941_fit_parameters.xml b/l10n_us_hr_payroll/data/federal/fed_941_fit_parameters.xml
index 97753e5a..f83f9ebd 100644
--- a/l10n_us_hr_payroll/data/federal/fed_941_fit_parameters.xml
+++ b/l10n_us_hr_payroll/data/federal/fed_941_fit_parameters.xml
@@ -7,20 +7,6 @@
fed_941_fit_allowance
-
-
- {
- 'weekly': 80.80,
- 'bi-weekly': 161.50,
- 'semi-monthly': 175.00,
- 'monthly': 350.00,
- 'quarterly': 1050.00,
- 'semi-annually': 2100.00,
- 'annually': 4200.00,
- }
-
-
-
{
'weekly': 80.80,
@@ -36,6 +22,7 @@
+
4300.0
@@ -46,33 +33,6 @@
fed_941_fit_nra_additional
-
-
- {
- 'weekly': 153.80,
- 'bi-weekly': 307.70,
- 'semi-monthly': 333.30,
- 'monthly': 666.70,
- 'quarterly': 2000.00,
- 'semi-annually': 4000.00,
- 'annually': 8000.00,
- }
-
-
-
-
- {
- 'weekly': 153.80,
- 'bi-weekly': 307.70,
- 'semi-monthly': 333.30,
- 'monthly': 666.70,
- 'quarterly': 2000.00,
- 'semi-annually': 4000.00,
- 'annually': 8000.00,
- }
-
-
-
{
'weekly': 238.50,
@@ -86,6 +46,19 @@
+
+ {
+ 'weekly': 241.30,
+ 'bi-weekly': 482.70,
+ 'semi-monthly': 522.90,
+ 'monthly': 1045.80,
+ 'quarterly': 3137.50,
+ 'semi-annually': 6275.00,
+ 'annually': 12550.00,
+ }
+
+
+
@@ -93,161 +66,7 @@
fed_941_fit_table_single
-
-
-
- {
- '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),
- ],
- }
-
-
-
-
-
- {
- '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),
- ],
- }
-
-
-
+
@@ -276,6 +95,33 @@
+
+
+ {
+ '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),
+ ],
+ }
+
+
+
@@ -283,161 +129,6 @@
fed_941_fit_table_married
-
-
-
- {
- '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),
- ],
- }
-
-
-
-
-
- {
- '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),
- ],
- }
-
-
-
@@ -466,6 +157,33 @@
+
+
+ {
+ '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),
+ ],
+ }
+
+
+
Federal 941 FIT Table Head of Household
@@ -500,5 +218,33 @@
+
+
+
+ {
+ '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),
+ ],
+ }
+
+
+
\ No newline at end of file
diff --git a/l10n_us_hr_payroll/tests/__init__.py b/l10n_us_hr_payroll/tests/__init__.py
index a1944823..6100a5d7 100755
--- a/l10n_us_hr_payroll/tests/__init__.py
+++ b/l10n_us_hr_payroll/tests/__init__.py
@@ -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
diff --git a/l10n_us_hr_payroll/tests/test_us_payslip_2019.py b/l10n_us_hr_payroll/tests/test_us_payslip_2019.py
deleted file mode 100644
index db6004e9..00000000
--- a/l10n_us_hr_payroll/tests/test_us_payslip_2019.py
+++ /dev/null
@@ -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)
diff --git a/l10n_us_hr_payroll/tests/test_us_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_payslip_2021.py
new file mode 100644
index 00000000..60822b05
--- /dev/null
+++ b/l10n_us_hr_payroll/tests/test_us_payslip_2021.py
@@ -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,
+ )