From a87e15e19bd22e86d9de26933fb577d9593f35bd Mon Sep 17 00:00:00 2001 From: Jared Kipe Date: Thu, 31 Dec 2020 09:05:56 -0800 Subject: [PATCH] [IMP] l10n_us_hr_payroll: Migrating States and Federal for 2021 TX Texas Amended (+50 squashed commits) Squashed commits: [7da4d616] ID Idaho [a2970d9b] FED amended [8ebf4c24] FED [080f6f05] TN Tennessee [bf2aa103] MI Michigan [493a6361] SC South Carolina [8e97119d] LA Louisiana [ee97a733] DE Delaware [5d9a7ced] WY Wyoming [8f72bfdd] WI Wisconsin [88073c7e] WV West Virginia [192ea027] VA Virginia [a32b4630] VT Vermont [1874a69f] TX Texas [39db5caa] SD South Dakota [21ebee50] RI Rhode Island [677e6f78] PA Pennsylvania [91cb694d] OK Oklahoma [5d93e5c4] ND North Dakota [f3d535ba] NM New Mexico [308fd185] NJ New Jersey [3c36600c] NH New Hampshire [d422bef6] NV Nevada [dc0551f1] NE Nebraska [eaae1e2b] MO Missouri [1ecd2521] MS Mississippi [bb8734ad] MN Minnesota [da6d84bb] Revert "ME Maine" This reverts commit e866f89b2b08b3a96bd9c8f3c29dcc6cea9ba958. [e866f89b] ME Maine [c0a7d06c] KY Kentucky [84556347] IN Indiana [ed241bf0] IL Illinois [d4c33133] HI Hawaii [982bf274] GA Georgia [5d0ef117] CT Connecticut [e4713512] CA California [24b867f3] WA Washington - formatting changes [e754b3aa] AR Arkansas [33482ad3] UT Utah [25595393] WA Washington [ac222b58] MT Montana [55babb7b] AZ Arizona todo: Income Tax not calculated [8b184e6f] AL Alabama [cc688c9d] AK Alaska [e8b105ad] OH Ohio [bff5ca12] nc north carolina [118e9a76] ny new york [575953a3] fl florida [401a7ce3] IA Iowa --- .../data/federal/fed_940_futa_parameters.xml | 3 + .../data/federal/fed_941_fica_parameters.xml | 11 + .../data/federal/fed_941_fit_parameters.xml | 448 +++------- l10n_us_hr_payroll/data/state/ak_alaska.xml | 31 +- l10n_us_hr_payroll/data/state/al_alabama.xml | 72 +- l10n_us_hr_payroll/data/state/ar_arkansas.xml | 67 +- l10n_us_hr_payroll/data/state/az_arizona.xml | 16 +- .../data/state/ca_california.xml | 660 ++++++++------- .../data/state/ct_connecticut.xml | 571 +------------ l10n_us_hr_payroll/data/state/de_delaware.xml | 5 + l10n_us_hr_payroll/data/state/fl_florida.xml | 10 +- l10n_us_hr_payroll/data/state/ga_georgia.xml | 427 +--------- l10n_us_hr_payroll/data/state/hi_hawaii.xml | 67 +- l10n_us_hr_payroll/data/state/ia_iowa.xml | 200 +++-- l10n_us_hr_payroll/data/state/id_idaho.xml | 191 +---- l10n_us_hr_payroll/data/state/il_illinois.xml | 39 +- l10n_us_hr_payroll/data/state/in_indiana.xml | 8 +- l10n_us_hr_payroll/data/state/ks_kansas.xml | 4 + l10n_us_hr_payroll/data/state/ky_kentucky.xml | 15 + .../data/state/la_louisiana.xml | 63 +- l10n_us_hr_payroll/data/state/mi_michigan.xml | 30 +- .../data/state/mn_minnesota.xml | 60 +- l10n_us_hr_payroll/data/state/mo_missouri.xml | 78 +- .../data/state/ms_mississippi.xml | 49 +- l10n_us_hr_payroll/data/state/mt_montana.xml | 16 +- .../data/state/nc_northcarolina.xml | 48 +- .../data/state/nd_north_dakota.xml | 193 +++++ l10n_us_hr_payroll/data/state/ne_nebraska.xml | 11 + .../data/state/nh_new_hampshire.xml | 6 + .../data/state/nj_newjersey.xml | 775 +++++++++--------- .../data/state/nm_new_mexico.xml | 275 ++++++- l10n_us_hr_payroll/data/state/nv_nevada.xml | 6 + l10n_us_hr_payroll/data/state/ny_new_york.xml | 266 ++++-- l10n_us_hr_payroll/data/state/oh_ohio.xml | 39 +- l10n_us_hr_payroll/data/state/ok_oklahoma.xml | 18 +- .../data/state/pa_pennsylvania.xml | 24 +- .../data/state/ri_rhode_island.xml | 59 ++ .../data/state/sc_south_carolina.xml | 46 +- .../data/state/sd_south_dakota.xml | 2 + l10n_us_hr_payroll/data/state/tx_texas.xml | 24 +- l10n_us_hr_payroll/data/state/ut_utah.xml | 19 + l10n_us_hr_payroll/data/state/va_virginia.xml | 39 +- l10n_us_hr_payroll/data/state/vt_vermont.xml | 114 +++ .../data/state/wa_washington.xml | 106 ++- .../data/state/wi_wisconsin.xml | 7 +- .../data/state/wv_west_virginia.xml | 5 + l10n_us_hr_payroll/data/state/wy_wyoming.xml | 19 +- l10n_us_hr_payroll/tests/__init__.py | 77 +- .../tests/test_us_ak_alaska_payslip_2019.py | 61 -- .../tests/test_us_ak_alaska_payslip_2021.py | 15 + .../tests/test_us_al_alabama_payslip_2019.py | 264 ------ .../tests/test_us_al_alabama_payslip_2021.py | 36 + .../tests/test_us_ar_arkansas_payslip_2019.py | 72 -- .../tests/test_us_ar_arkansas_payslip_2021.py | 35 + .../tests/test_us_az_arizona_payslip_2019.py | 72 -- .../tests/test_us_az_arizona_payslip_2021.py | 34 + .../test_us_ca_california_payslip_2019.py | 245 ------ .../test_us_ca_california_payslip_2021.py | 43 + .../tests/test_us_co_colorado_payslip_2021.py | 37 + .../test_us_ct_connecticut_payslip_2019.py | 121 --- .../test_us_ct_connecticut_payslip_2021.py | 35 + .../tests/test_us_de_delaware_payslip_2020.py | 2 +- .../tests/test_us_de_delaware_payslip_2021.py | 36 + .../tests/test_us_fl_florida_payslip_2019.py | 84 -- .../tests/test_us_fl_florida_payslip_2021.py | 16 + .../tests/test_us_ga_georgia_payslip_2019.py | 135 --- .../tests/test_us_ga_georgia_payslip_2021.py | 39 + .../tests/test_us_hi_hawaii_payslip_2019.py | 93 --- .../tests/test_us_hi_hawaii_payslip_2021.py | 37 + .../tests/test_us_ia_iowa_payslip_2019.py | 152 ---- .../tests/test_us_ia_iowa_payslip_2021.py | 36 + .../tests/test_us_id_idaho_payslip_2019.py | 85 -- .../tests/test_us_id_idaho_payslip_2021.py | 35 + .../tests/test_us_il_illinois_payslip_2019.py | 71 -- .../tests/test_us_il_illinois_payslip_2021.py | 36 + .../tests/test_us_in_indiana_payslip_2021.py | 36 + .../tests/test_us_ks_kansas_payslip_2021.py | 36 + .../tests/test_us_ky_kentucky_payslip_2021.py | 36 + .../test_us_la_louisiana_payslip_2019.py | 91 -- .../test_us_la_louisiana_payslip_2021.py | 36 + .../tests/test_us_mi_michigan_payslip_2019.py | 194 ----- .../tests/test_us_mi_michigan_payslip_2021.py | 35 + .../test_us_mn_minnesota_payslip_2019.py | 159 ---- .../test_us_mn_minnesota_payslip_2021.py | 36 + .../tests/test_us_mo_missouri_payslip_2019.py | 188 ----- .../tests/test_us_mo_missouri_payslip_2021.py | 34 + .../test_us_ms_mississippi_payslip_2019.py | 94 --- .../test_us_ms_mississippi_payslip_2021.py | 35 + .../tests/test_us_mt_montana_payslip_2019.py | 139 ---- .../tests/test_us_mt_montana_payslip_2021.py | 37 + .../test_us_nc_northcarolina_payslip_2019.py | 270 ------ .../test_us_nc_northcarolina_payslip_2021.py | 39 + .../test_us_nd_north_dakota_payslip_2021.py | 37 + .../tests/test_us_ne_nebraska_payslip_2021.py | 38 + .../test_us_nh_new_hampshire_payslip_2021.py | 13 + .../test_us_nj_newjersey_payslip_2019.py | 128 --- .../test_us_nj_newjersey_payslip_2021.py | 51 ++ .../test_us_nm_new_mexico_payslip_2021.py | 36 + .../tests/test_us_nv_nevada_payslip_2021.py | 16 + .../tests/test_us_ny_new_york_payslip_2019.py | 133 --- .../tests/test_us_ny_new_york_payslip_2021.py | 39 + .../tests/test_us_oh_ohio_payslip_2019.py | 96 --- .../tests/test_us_oh_ohio_payslip_2021.py | 108 +++ .../tests/test_us_ok_oklahoma_payslip_2021.py | 38 + .../test_us_pa_pennsylvania_payslip_2019.py | 33 - .../test_us_pa_pennsylvania_payslip_2021.py | 43 + .../tests/test_us_payslip_2019.py | 338 -------- .../tests/test_us_payslip_2021.py | 294 +++++++ .../test_us_ri_rhode_island_payslip_2021.py | 37 + .../test_us_sc_south_carolina_payslip_2019.py | 97 --- .../test_us_sc_south_carolina_payslip_2020.py | 16 +- .../test_us_sc_south_carolina_payslip_2021.py | 36 + .../test_us_sd_south_dakota_payslip_2021.py | 13 + .../test_us_tn_tennessee_payslip_2021.py | 14 + .../tests/test_us_tx_texas_payslip_2019.py | 100 --- .../tests/test_us_tx_texas_payslip_2021.py | 17 + .../tests/test_us_us_utah_payslip_2021.py | 36 + .../tests/test_us_va_virginia_payslip_2019.py | 133 --- .../tests/test_us_va_virginia_payslip_2021.py | 116 +++ .../tests/test_us_vt_vermont_payslip_2021.py | 37 + .../test_us_wa_washington_payslip_2020.py | 1 + ... => test_us_wa_washington_payslip_2021.py} | 56 +- .../test_us_wi_wisconsin_payslip_2021.py | 39 + .../test_us_wv_west_virginia_payslip_2021.py | 36 + .../tests/test_us_wy_wyoming_payslip_2019.py | 58 -- .../tests/test_us_wy_wyoming_payslip_2021.py | 13 + 126 files changed, 4297 insertions(+), 6740 deletions(-) delete mode 100644 l10n_us_hr_payroll/tests/test_us_ak_alaska_payslip_2019.py create mode 100644 l10n_us_hr_payroll/tests/test_us_ak_alaska_payslip_2021.py delete mode 100644 l10n_us_hr_payroll/tests/test_us_al_alabama_payslip_2019.py create mode 100644 l10n_us_hr_payroll/tests/test_us_al_alabama_payslip_2021.py delete mode 100644 l10n_us_hr_payroll/tests/test_us_ar_arkansas_payslip_2019.py create mode 100644 l10n_us_hr_payroll/tests/test_us_ar_arkansas_payslip_2021.py delete mode 100644 l10n_us_hr_payroll/tests/test_us_az_arizona_payslip_2019.py create mode 100644 l10n_us_hr_payroll/tests/test_us_az_arizona_payslip_2021.py delete mode 100644 l10n_us_hr_payroll/tests/test_us_ca_california_payslip_2019.py create mode 100755 l10n_us_hr_payroll/tests/test_us_ca_california_payslip_2021.py create mode 100755 l10n_us_hr_payroll/tests/test_us_co_colorado_payslip_2021.py delete mode 100644 l10n_us_hr_payroll/tests/test_us_ct_connecticut_payslip_2019.py create mode 100644 l10n_us_hr_payroll/tests/test_us_ct_connecticut_payslip_2021.py create mode 100755 l10n_us_hr_payroll/tests/test_us_de_delaware_payslip_2021.py delete mode 100755 l10n_us_hr_payroll/tests/test_us_fl_florida_payslip_2019.py create mode 100755 l10n_us_hr_payroll/tests/test_us_fl_florida_payslip_2021.py delete mode 100755 l10n_us_hr_payroll/tests/test_us_ga_georgia_payslip_2019.py create mode 100755 l10n_us_hr_payroll/tests/test_us_ga_georgia_payslip_2021.py delete mode 100644 l10n_us_hr_payroll/tests/test_us_hi_hawaii_payslip_2019.py create mode 100755 l10n_us_hr_payroll/tests/test_us_hi_hawaii_payslip_2021.py delete mode 100644 l10n_us_hr_payroll/tests/test_us_ia_iowa_payslip_2019.py create mode 100755 l10n_us_hr_payroll/tests/test_us_ia_iowa_payslip_2021.py delete mode 100644 l10n_us_hr_payroll/tests/test_us_id_idaho_payslip_2019.py create mode 100755 l10n_us_hr_payroll/tests/test_us_id_idaho_payslip_2021.py delete mode 100644 l10n_us_hr_payroll/tests/test_us_il_illinois_payslip_2019.py create mode 100644 l10n_us_hr_payroll/tests/test_us_il_illinois_payslip_2021.py create mode 100755 l10n_us_hr_payroll/tests/test_us_in_indiana_payslip_2021.py create mode 100755 l10n_us_hr_payroll/tests/test_us_ks_kansas_payslip_2021.py create mode 100755 l10n_us_hr_payroll/tests/test_us_ky_kentucky_payslip_2021.py delete mode 100644 l10n_us_hr_payroll/tests/test_us_la_louisiana_payslip_2019.py create mode 100755 l10n_us_hr_payroll/tests/test_us_la_louisiana_payslip_2021.py delete mode 100755 l10n_us_hr_payroll/tests/test_us_mi_michigan_payslip_2019.py create mode 100755 l10n_us_hr_payroll/tests/test_us_mi_michigan_payslip_2021.py delete mode 100755 l10n_us_hr_payroll/tests/test_us_mn_minnesota_payslip_2019.py create mode 100755 l10n_us_hr_payroll/tests/test_us_mn_minnesota_payslip_2021.py delete mode 100755 l10n_us_hr_payroll/tests/test_us_mo_missouri_payslip_2019.py create mode 100755 l10n_us_hr_payroll/tests/test_us_mo_missouri_payslip_2021.py delete mode 100755 l10n_us_hr_payroll/tests/test_us_ms_mississippi_payslip_2019.py create mode 100755 l10n_us_hr_payroll/tests/test_us_ms_mississippi_payslip_2021.py delete mode 100755 l10n_us_hr_payroll/tests/test_us_mt_montana_payslip_2019.py create mode 100755 l10n_us_hr_payroll/tests/test_us_mt_montana_payslip_2021.py delete mode 100755 l10n_us_hr_payroll/tests/test_us_nc_northcarolina_payslip_2019.py create mode 100755 l10n_us_hr_payroll/tests/test_us_nc_northcarolina_payslip_2021.py create mode 100644 l10n_us_hr_payroll/tests/test_us_nd_north_dakota_payslip_2021.py create mode 100644 l10n_us_hr_payroll/tests/test_us_ne_nebraska_payslip_2021.py create mode 100644 l10n_us_hr_payroll/tests/test_us_nh_new_hampshire_payslip_2021.py delete mode 100755 l10n_us_hr_payroll/tests/test_us_nj_newjersey_payslip_2019.py create mode 100755 l10n_us_hr_payroll/tests/test_us_nj_newjersey_payslip_2021.py create mode 100755 l10n_us_hr_payroll/tests/test_us_nm_new_mexico_payslip_2021.py create mode 100755 l10n_us_hr_payroll/tests/test_us_nv_nevada_payslip_2021.py delete mode 100644 l10n_us_hr_payroll/tests/test_us_ny_new_york_payslip_2019.py create mode 100644 l10n_us_hr_payroll/tests/test_us_ny_new_york_payslip_2021.py delete mode 100755 l10n_us_hr_payroll/tests/test_us_oh_ohio_payslip_2019.py create mode 100755 l10n_us_hr_payroll/tests/test_us_oh_ohio_payslip_2021.py create mode 100755 l10n_us_hr_payroll/tests/test_us_ok_oklahoma_payslip_2021.py delete mode 100755 l10n_us_hr_payroll/tests/test_us_pa_pennsylvania_payslip_2019.py create mode 100755 l10n_us_hr_payroll/tests/test_us_pa_pennsylvania_payslip_2021.py delete mode 100644 l10n_us_hr_payroll/tests/test_us_payslip_2019.py create mode 100644 l10n_us_hr_payroll/tests/test_us_payslip_2021.py create mode 100755 l10n_us_hr_payroll/tests/test_us_ri_rhode_island_payslip_2021.py delete mode 100644 l10n_us_hr_payroll/tests/test_us_sc_south_carolina_payslip_2019.py create mode 100644 l10n_us_hr_payroll/tests/test_us_sc_south_carolina_payslip_2021.py create mode 100644 l10n_us_hr_payroll/tests/test_us_sd_south_dakota_payslip_2021.py create mode 100644 l10n_us_hr_payroll/tests/test_us_tn_tennessee_payslip_2021.py delete mode 100755 l10n_us_hr_payroll/tests/test_us_tx_texas_payslip_2019.py create mode 100755 l10n_us_hr_payroll/tests/test_us_tx_texas_payslip_2021.py create mode 100755 l10n_us_hr_payroll/tests/test_us_us_utah_payslip_2021.py delete mode 100644 l10n_us_hr_payroll/tests/test_us_va_virginia_payslip_2019.py create mode 100644 l10n_us_hr_payroll/tests/test_us_va_virginia_payslip_2021.py create mode 100755 l10n_us_hr_payroll/tests/test_us_vt_vermont_payslip_2021.py rename l10n_us_hr_payroll/tests/{test_us_wa_washington_payslip_2019.py => test_us_wa_washington_payslip_2021.py} (61%) create mode 100755 l10n_us_hr_payroll/tests/test_us_wi_wisconsin_payslip_2021.py create mode 100755 l10n_us_hr_payroll/tests/test_us_wv_west_virginia_payslip_2021.py delete mode 100644 l10n_us_hr_payroll/tests/test_us_wy_wyoming_payslip_2019.py create mode 100644 l10n_us_hr_payroll/tests/test_us_wy_wyoming_payslip_2021.py 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/data/state/ak_alaska.xml b/l10n_us_hr_payroll/data/state/ak_alaska.xml index 2c995088..fec273d2 100644 --- a/l10n_us_hr_payroll/data/state/ak_alaska.xml +++ b/l10n_us_hr_payroll/data/state/ak_alaska.xml @@ -1,22 +1,23 @@ + US AK Alaska SUTA Wage Base us_ak_suta_wage_base - - 39900.00 - - - 41500.00 + + 43600.00 + + + @@ -26,16 +27,16 @@ - - 1.780 - - - 1.590 + + 2.570 + + + @@ -44,16 +45,16 @@ - - 0.500 - - - 0.500 + + 0.500 + + + diff --git a/l10n_us_hr_payroll/data/state/al_alabama.xml b/l10n_us_hr_payroll/data/state/al_alabama.xml index fc3b3af1..f2b5ceeb 100644 --- a/l10n_us_hr_payroll/data/state/al_alabama.xml +++ b/l10n_us_hr_payroll/data/state/al_alabama.xml @@ -6,12 +6,9 @@ us_al_suta_wage_base + + - - 8000.0 - - - 8000.0 @@ -26,11 +23,8 @@ - - 2.7 - - - + + 2.7 @@ -44,22 +38,8 @@ - - { - '0': [ - ( 500, 2), - ( 3000, 4), - ('inf', 5), - ], - 'M': [ - ( 1000, 2), - ( 6000, 4), - ('inf', 5), - ], - } - - - + + { '0' : [ @@ -86,17 +66,7 @@ - - [ - ( 1000, 20000), - ( 500, 100000), - ( 300, 'inf'), - ] - - - - - + [ ( 1000, 20000), @@ -116,19 +86,7 @@ - - { - '0': ((23499.0, 2500.0), (33000.0, 2500.0, 25.0, 500.0), ('inf', 2000.0)), - 'S': ((23499.0, 2500.0), (33000.0, 2500.0, 25.0, 500.0), ('inf', 2000.0)), - 'MS': ((10749.0, 3750.0), (15500.0, 3750.0, 88.0, 250.0), ('inf', 2000.0)), - 'M': ((23499.0, 7500.0), (33000.0, 7500.0, 175.0, 500.0), ('inf', 4000.0)), - 'H': ((23499.0, 4700.0), (33000.0, 7500.0, 175.0, 500.0), ('inf', 4000.0)), - } - - - - - + { '0': ((23499.0, 2500.0), (33000.0, 2500.0, 25.0, 500.0), ('inf', 2000.0)), @@ -150,19 +108,7 @@ - - { - '0' : 0, - 'S' : 1500, - 'MS': 1500, - 'M' : 3000, - 'H' : 3000, - } - - - - - + { '0' : 0, diff --git a/l10n_us_hr_payroll/data/state/ar_arkansas.xml b/l10n_us_hr_payroll/data/state/ar_arkansas.xml index 3e5b8211..2c8f01a5 100644 --- a/l10n_us_hr_payroll/data/state/ar_arkansas.xml +++ b/l10n_us_hr_payroll/data/state/ar_arkansas.xml @@ -7,16 +7,17 @@ - - 10000.0 - - - + 8000.0 + + 10000.0 + + + @@ -26,16 +27,17 @@ - - 3.2 - - - + 2.9 + + 3.2 + + + @@ -44,24 +46,6 @@ - - [ - ( 4599, 0.0, 0.00), - ( 9099, 2.0, 91.98), - ( 13699, 3.0, 182.97), - ( 22599, 3.4, 237.77), - ( 37899, 5.0, 421.46), - ( 80800, 5.9, 762.55), - ( 81800, 6.6, 1243.40), - ( 82800, 6.6, 1143.40), - ( 84100, 6.6, 1043.40), - ( 85200, 6.6, 943.40), - ( 86200, 6.6, 843.40), - ( 'inf', 6.6, 803.40), - ] - - - @@ -82,6 +66,26 @@ + + + + [ + ( 4699, 0.0, 0.00), + ( 9199, 2.0, 93.98), + ( 13899, 3.0, 185.97), + ( 22899, 3.4, 241.57), + ( 38499, 5.0, 427.71), + ( 82000, 5.9, 774.20), + ( 83000, 5.9, 681.70), + ( 84000, 5.9, 581.70), + ( 85300, 5.9, 481.70), + ( 86400, 5.9, 381.70), + ( 87500, 5.9, 281.70), + ( 'inf', 5.9, 241.70), + ] + + + @@ -90,11 +94,8 @@ - - 2200.0 - - - + + 2200.0 diff --git a/l10n_us_hr_payroll/data/state/az_arizona.xml b/l10n_us_hr_payroll/data/state/az_arizona.xml index 80b800c1..87c4c2c5 100644 --- a/l10n_us_hr_payroll/data/state/az_arizona.xml +++ b/l10n_us_hr_payroll/data/state/az_arizona.xml @@ -7,11 +7,8 @@ - - 7000.0 - - - + + 7000.0 @@ -26,11 +23,8 @@ - - 2.0 - - - + + 2.0 @@ -38,6 +32,8 @@ + + US Arizona - Department of Economic Security (ADES) - Unemployment Tax diff --git a/l10n_us_hr_payroll/data/state/ca_california.xml b/l10n_us_hr_payroll/data/state/ca_california.xml index 2a907b3a..062cd764 100644 --- a/l10n_us_hr_payroll/data/state/ca_california.xml +++ b/l10n_us_hr_payroll/data/state/ca_california.xml @@ -7,11 +7,8 @@ - - 7000.0 - - - + + 7000.0 @@ -26,11 +23,8 @@ - - 3.5 - - - + + 3.4 @@ -45,11 +39,8 @@ - - 0.1 - - - + + 0.1 @@ -64,16 +55,17 @@ - - 1.0 - - - + 1.0 + + 1.2 + + + @@ -82,270 +74,6 @@ - - { - 'head_household': { - 'weekly': ( - ( 316, 0.0110, 0.00), - ( 750, 0.0220, 3.48), - ( 967, 0.0440, 13.03), - ( 1196, 0.0660, 22.58), - ( 1413, 0.0880, 37.69), - ( 7212, 0.1023, 56.79), - ( 8654, 0.1133, 650.03), - (14423, 0.1243, 813.41), - (19231, 0.1353, 1530.50), - ('inf', 0.1463, 2181.02), - ), - 'bi-weekly': ( - ( 632, 0.0110, 0.00), - ( 1500, 0.0220, 6.95), - ( 1934, 0.0440, 26.05), - ( 2392, 0.0660, 45.15), - ( 2826, 0.0880, 75.38), - (14424, 0.1023, 113.57), - (17308, 0.1133, 1300.05), - (28846, 0.1243, 1626.81), - (38462, 0.1353, 3060.98), - ('inf', 0.1463, 4362.02), - ), - 'semi-monthly': ( - ( 686, 0.0110, 0.00), - ( 1625, 0.0220, 7.55), - ( 2094, 0.0440, 28.21), - ( 2592, 0.0660, 48.85), - ( 3062, 0.0880, 81.72), - (15625, 0.1023, 123.08), - (18750, 0.1133, 1408.27), - (31250, 0.1243, 1762.33), - (41667, 0.1353, 3316.08), - ('inf', 0.1463, 4725.50), - ), - 'monthly': ( - ( 1372, 0.0110, 0.00), - ( 3250, 0.0220, 15.09), - ( 4188, 0.0440, 56.41), - ( 5184, 0.0660, 97.68), - ( 6124, 0.0880, 163.42), - (31250, 0.1023, 246.14), - (37500, 0.1133, 2816.53), - (62500, 0.1243, 3524.66), - (83334, 0.1353, 6632.16), - ('inf', 0.1463, 9451.00), - ), - 'quarterly': ( - ( 4114, 0.0110, 0.00), - ( 9748, 0.0220, 45.25), - ( 12566, 0.0440, 169.20), - ( 15552, 0.0660, 293.19), - ( 18369, 0.0880, 490.27), - ( 93751, 0.1023, 738.17), - (112501, 0.1133, 8449.75), - (187501, 0.1243, 10574.13), - (250000, 0.1353, 19896.63), - ( 'inf', 0.1463, 28352.74), - ), - 'semi-annual': ( - ( 8228, 0.0110, 0.00), - ( 19496, 0.0220, 90.51), - ( 25132, 0.0440, 338.41), - ( 31104, 0.0660, 586.39), - ( 36738, 0.0880, 980.54), - (187502, 0.1023, 1476.33), - (225002, 0.1133, 16899.49), - (375002, 0.1243, 21148.24), - (500000, 0.1353, 39793.24), - ( 'inf', 0.1463, 56705.47), - ), - 'annually': ( - ( 16457, 0.0110, 0.00), - ( 38991, 0.0220, 181.03), - ( 50264, 0.0440, 676.78), - ( 62206, 0.0660, 1172.79), - ( 73477, 0.0880, 1960.96), - ( 375002, 0.1023, 2952.81), - ( 450003, 0.1133, 33798.82), - ( 750003, 0.1243, 42296.43), - (1000000, 0.1353, 79586.43), - ( 'inf', 0.1463, 113411.02), - ), - }, - 'married': { - 'weekly': ( - ( 316, 0.0110, 0.00), - ( 750, 0.0220, 3.48), - ( 1184, 0.0440, 13.03), - ( 1642, 0.0660, 32.13), - ( 2076, 0.0880, 62.36), - (10606, 0.1023, 100.55), - (12726, 0.1133, 973.17), - (19231, 0.1243, 1213.37), - (21210, 0.1353, 2021.94), - ('inf', 0.1463, 2289.70), - ), - 'bi-weekly': ( - ( 632, 0.0110, 0.00), - ( 1500, 0.0220, 6.95), - ( 2368, 0.0440, 26.05), - ( 3284, 0.0660, 64.24), - ( 4152, 0.0880, 124.70), - (21212, 0.1023, 201.08), - (25452, 0.1133, 1946.32), - (38462, 0.1243, 2426.71), - (42420, 0.1353, 4043.85), - ('inf', 0.1463, 4579.37), - ), - 'semi-monthly': ( - ( 686, 0.0110, 0.00), - ( 1624, 0.0220, 7.55), - ( 2564, 0.0440, 28.19), - ( 3560, 0.0660, 69.55), - ( 4498, 0.0880, 135.29), - (22978, 0.1023, 217.83), - (27574, 0.1133, 2108.33), - (41667, 0.1243, 2629.06), - (45956, 0.1353, 4380.82), - ('inf', 0.1463, 4961.12), - ), - 'monthly': ( - ( 1372, 0.0110, 0.00), - ( 3248, 0.0220, 15.09), - ( 5128, 0.0440, 56.36), - ( 7120, 0.0660, 139.08), - ( 8996, 0.0880, 270.55), - (45956, 0.1023, 435.64), - (55148, 0.1133, 4216.65), - (83334, 0.1243, 5258.10), - (91912, 0.1353, 8761.62), - ('inf', 0.1463, 9922.22), - ), - 'quarterly': ( - ( 4112, 0.0110, 0.00), - ( 9748, 0.0220, 45.23), - ( 15384, 0.0440, 169.22), - ( 21356, 0.0660, 417.20), - ( 26990, 0.0880, 811.35), - (137870, 0.1023, 1307.14), - (165442, 0.1133, 12650.16), - (250000, 0.1243, 15774.07), - (275736, 0.1353, 26284.63), - ( 'inf', 0.1463, 29766.71), - ), - 'semi-annual': ( - ( 8224, 0.0110, 0.00), - ( 19496, 0.0220, 90.46), - ( 30768, 0.0440, 338.44), - ( 42712, 0.0660, 834.41), - ( 53980, 0.0880, 1622.71), - (275740, 0.1023, 2614.29), - (330884, 0.1133, 25300.34), - (500000, 0.1243, 31548.16), - (551472, 0.1353, 52569.28), - ( 'inf', 0.1463, 59533.44), - ), - 'annually': ( - ( 16446, 0.0110, 0.00), - ( 38990, 0.0220, 180.91), - ( 61538, 0.0440, 676.88), - ( 85422, 0.0660, 1668.99), - ( 107960, 0.0880, 3245.33), - ( 551476, 0.1023, 5228.67), - ( 661768, 0.1133, 50600.36), - (1000000, 0.1243, 63096.44), - (1102946, 0.1353, 105138.68), - ( 'inf', 0.1463, 119067.26), - ), - }, - 'single': { - 'weekly': ( - ( 158, 0.0110, 0.00), - ( 375, 0.0220, 1.74), - ( 592, 0.0440, 6.51), - ( 821, 0.0660, 16.06), - ( 1038, 0.0880, 31.17), - ( 5303, 0.1023, 50.27), - ( 6363, 0.1133, 486.58), - (10605, 0.1243, 606.68), - (19231, 0.1353, 1133.96), - ('inf', 0.1463, 2301.06), - ), - 'bi-weekly': ( - ( 316, 0.0110, 0.00), - ( 750, 0.0220, 3.48), - ( 1184, 0.0440, 13.03), - ( 1642, 0.066, 32.13), - ( 2076, 0.0880, 62.36), - (10606, 0.1023, 100.55), - (12726, 0.1133, 973.17), - (21210, 0.1243, 1213.37), - (38462, 0.1353, 2267.93), - ('inf', 0.1463, 4602.13), - ), - 'semi-monthly': ( - ( 343, 0.0110, 0.00), - ( 812, 0.0220, 3.77), - ( 1282, 0.0440, 14.09), - ( 1780, 0.0660, 34.77), - ( 2249, 0.0880, 67.64), - (11489, 0.1023, 108.91), - (13787, 0.1133, 1054.16), - (22978, 0.1243, 1314.52), - (41667, 0.1353, 2456.96), - ('inf', 0.1463, 4985.58), - ), - 'monthly': ( - ( 686, 0.0110, 0.00), - ( 1624, 0.0220, 7.55), - ( 2564, 0.0440, 28.19), - ( 3560, 0.0660, 69.55), - ( 4498, 0.0880, 135.29), - (22978, 0.1023, 217.83), - (27574, 0.1133, 2108.33), - (45956, 0.1243, 2629.06), - (83334, 0.1353, 4913.94), - ('inf', 0.1463, 9971.18), - ), - 'quarterly': ( - ( 2056, 0.0110, 0.00), - ( 4874, 0.0220, 22.62), - ( 7692, 0.0440, 84.62), - ( 10678, 0.066, 208.61), - ( 13495, 0.0880, 405.69), - ( 68935, 0.1023, 653.59), - ( 82721, 0.1133, 6325.10), - (137868, 0.1243, 7887.05), - (250000, 0.1353, 14741.82), - ( 'inf', 0.1463, 29913.28), - ), - 'semi-annual': ( - ( 4112, 0.0110, 0.00), - ( 9748, 0.0220, 45.23), - ( 15384, 0.0440, 169.22), - ( 21356, 0.0660, 417.20), - ( 26990, 0.0880, 811.35), - (137870, 0.1023, 1307.14), - (165442, 0.1133, 12650.16), - (275736, 0.1243, 15774.07), - (500000, 0.1353, 29483.61), - ('inf', 0.1463, 59826.53), - ), - 'annually': ( - ( 8223, 0.0110, 0.00), - ( 19495, 0.0220, 90.45), - ( 30769, 0.0440, 338.43), - ( 42711, 0.0660, 834.49), - ( 53980, 0.0880, 1622.66), - ( 275738, 0.1023, 2614.33), - ( 330884, 0.1133, 25300.17), - ( 551473, 0.1243, 31548.21), - (1000000, 0.1353, 58967.42), - ( 'inf', 0.1463, 119653.12), - ), - }, - } - - - @@ -612,6 +340,272 @@ + + + + { + 'head_household': { + 'weekly': ( + ( 344, 0.0110, 0.00), + ( 814, 0.0220, 3.78), + ( 1050, 0.0440, 14.12), + ( 1299, 0.0660, 24.50), + ( 1535, 0.0880, 40.93), + ( 7833, 0.1023, 61.70), + ( 9400, 0.1133, 705.99), + (15667, 0.1243, 883.53), + (19231, 0.1353, 1662.52), + ('inf', 0.1463, 2144.73), + ), + 'bi-weekly': ( + ( 688, 0.0110, 0.00), + ( 1628, 0.0220, 7.57), + ( 2100, 0.0440, 28.25), + ( 2598, 0.0660, 49.02), + ( 3070, 0.0880, 81.89), + (15666, 0.1023, 123.43), + (18800, 0.1133, 1412.00), + (31334, 0.1243, 1767.08), + (38462, 0.1353, 3325.06), + ('inf', 0.1463, 4289.48), + ), + 'semi-monthly': ( + ( 745, 0.0110, 0.00), + ( 1765, 0.0220, 8.20), + ( 2275, 0.0440, 30.64), + ( 2815, 0.0660, 53.08), + ( 3326, 0.0880, 88.72), + (16972, 0.1023, 133.69), + (20367, 0.1133, 1529.68), + (33944, 0.1243, 1914.33), + (41667, 0.1353, 3601.95), + ('inf', 0.1463, 4646.87), + ), + 'monthly': ( + ( 1490, 0.0110, 0.00), + ( 3530, 0.0220, 16.39), + ( 4550, 0.0440, 61.27), + ( 5630, 0.0660, 106.15), + ( 6652, 0.0880, 177.43), + (33944, 0.1023, 267.37), + (40734, 0.1133, 3059.34), + (67888, 0.1243, 3828.65), + (83334, 0.1353, 7203.89), + ('inf', 0.1463, 9293.73), + ), + 'quarterly': ( + ( 4469, 0.0110, 0.00), + ( 10588, 0.0220, 49.13), + ( 13649, 0.0440, 183.78), + ( 16892, 0.0660, 318.46), + ( 19953, 0.0880, 532.50), + (101832, 0.1023, 801.87), + (122199, 0.1133, 9178.09), + (203665, 0.1243, 11485.67), + (250000, 0.1353, 21611.89), + ( 'inf', 0.1463, 27881.02), + ), + 'semi-annual': ( + ( 8938, 0.0110, 0.00), + ( 21176, 0.0220, 98.32), + ( 27298, 0.0440, 367.56), + ( 33784, 0.0660, 636.93), + ( 39906, 0.0880, 1065.01), + (203664, 0.1023, 1603.75), + (244398, 0.1133, 18356.19), + (407330, 0.1243, 22971.35), + (500000, 0.1353, 43223.80), + ( 'inf', 0.1463, 55762.05), + ), + 'annually': ( + ( 17876, 0.0110, 0.00), + ( 42353, 0.0220, 196.64), + ( 54597, 0.0440, 735.13), + ( 67569, 0.0660, 1273.87), + ( 79812, 0.0880, 2130.02), + ( 407329, 0.1023, 3207.40), + ( 488796, 0.1133, 36712.39), + ( 814658, 0.1243, 45942.60), + (1000000, 0.1353, 86447.25), + ( 'inf', 0.1463, 111524.02), + ), + }, + 'married': { + 'weekly': ( + ( 344, 0.0110, 0.00), + ( 814, 0.0220, 3.78), + ( 1286, 0.0440, 14.12), + ( 1784, 0.0660, 34.89), + ( 2256, 0.0880, 67.76), + (11520, 0.1023, 109.30), + (13824, 0.1133, 1057.01), + (19231, 0.1243, 1318.05), + (23039, 0.1353, 1990.14), + ('inf', 0.1463, 2505.36), + ), + 'bi-weekly': ( + ( 688, 0.0110, 0.00), + ( 1628, 0.0220, 7.57), + ( 2572, 0.0440, 28.25), + ( 3568, 0.0660, 69.79), + ( 4512, 0.0880, 135.53), + (23040, 0.1023, 218.60), + (27648, 0.1133, 2114.01), + (38462, 0.1243, 2636.10), + (46078, 0.1353, 2398.28), + ('inf', 0.1463, 5010.72), + ), + 'semi-monthly': ( + ( 744, 0.0110, 0.00), + ( 1764, 0.0220, 8.18), + ( 2786, 0.0440, 30.62), + ( 3866, 0.0660, 75.59), + ( 4886, 0.0880, 146.87), + (24960, 0.1023, 236.63), + (29950, 0.1133, 2290.20), + (41667, 0.1243, 2855.57), + (49918, 0.1353, 4311.99), + ('inf', 0.1463, 5428.35), + ), + 'monthly': ( + ( 1488, 0.0110, 0.00), + ( 3528, 0.0220, 16.37), + ( 5572, 0.0440, 61.25), + ( 7732, 0.0660, 151.19), + ( 9772, 0.0880, 293.75), + (49920, 0.1023, 473.27), + (59900, 0.1133, 4580.41), + (83334, 0.1243, 5711.14), + (99836, 0.1353, 8623.99), + ('inf', 0.1463, 10856.71), + ), + 'quarterly': ( + ( 4466, 0.0110, 0.00), + ( 10588, 0.0220, 49.13), + ( 16710, 0.0440, 183.81), + ( 23198, 0.0660, 453.18), + ( 29318, 0.0880, 881.39), + (149754, 0.1023, 1419.95), + (179704, 0.1133, 13740.55), + (250000, 0.1243, 17133.89), + (299506, 0.1353, 25871.68), + ( 'inf', 0.1463, 32569.84), + ), + 'semi-annual': ( + ( 8932, 0.0110, 0.00), + ( 21176, 0.0220, 98.25), + ( 33420, 0.0440, 367.62), + ( 46396, 0.0660, 906.36), + ( 58636, 0.0880, 1762.78), + (299508, 0.1023, 2839.90), + (359408, 0.1133, 27481.11), + (500000, 0.1243, 34267.78), + (599012, 0.1353, 51743.37), + ( 'inf', 0.1463, 65139.69), + ), + 'annually': ( + ( 17864, 0.0110, 0.00), + ( 42350, 0.0220, 196.50), + ( 66842, 0.0440, 735.19), + ( 92788, 0.0660, 1812.84), + ( 117268, 0.0880, 3525.28), + ( 599016, 0.1023, 5679.52), + ( 718814, 0.1133, 54962.34), + (1000000, 0.1243, 68535.45), + (1198024, 0.1353, 103486.87), + ( 'inf', 0.1463, 130279.52), + ), + }, + 'single': { + 'weekly': ( + ( 172, 0.0110, 0.00), + ( 407, 0.0220, 1.89), + ( 643, 0.0440, 7.06), + ( 892, 0.0660, 17.44), + ( 1128, 0.0880, 33.87), + ( 5760, 0.1023, 54.64), + ( 6912, 0.1133, 528.49), + (11519, 0.1243, 659.01), + (19231, 0.1353, 1231.66), + ('inf', 0.1463, 2275.09), + ), + 'bi-weekly': ( + ( 344, 0.0110, 0.00), + ( 814, 0.0220, 3.78), + ( 1286, 0.0440, 14.12), + ( 1784, 0.0660, 34.89), + ( 2256, 0.0880, 67.76), + (11520, 0.1023, 109.30), + (13824, 0.1133, 1057.01), + (23038, 0.1243, 1318.05), + (38462, 0.1353, 2463.35), + ('inf', 0.1463, 4550.22), + ), + 'semi-monthly': ( + ( 372, 0.0110, 0.00), + ( 882, 0.0220, 4.09), + ( 1393, 0.0440, 15.31), + ( 1933, 0.0660, 37.79), + ( 2443, 0.0880, 73.43), + (12480, 0.1023, 118.31), + (14975, 0.1133, 1145.10), + (24959, 0.1243, 1427.78), + (41667, 0.1353, 2668.79), + ('inf', 0.1463, 4929.38), + ), + 'monthly': ( + ( 744, 0.0110, 0.00), + ( 1764, 0.0220, 8.18), + ( 2786, 0.0440, 30.62), + ( 3866, 0.0660, 75.59), + ( 4886, 0.0880, 146.87), + (24960, 0.1023, 236.63), + (29950, 0.1133, 2290.20), + (49918, 0.1243, 2855.57), + (83334, 0.1353, 5337.59), + ('inf', 0.1463, 9858.77), + ), + 'quarterly': ( + ( 2233, 0.0110, 0.00), + ( 5294, 0.0220, 24.56), + ( 8355, 0.0440, 91.90), + ( 11599, 0.0660, 226.58), + ( 14659, 0.0880, 440.68), + ( 74877, 0.1023, 709.96), + ( 89852, 0.1133, 6870.26), + (149753, 0.1243, 8566.93), + (250000, 0.1353, 16012.62), + ( 'inf', 0.1463, 29576.04), + ), + 'semi-annual': ( + ( 4466, 0.0110, 0.00), + ( 10588, 0.0220, 49.13), + ( 16710, 0.0440, 183.81), + ( 23198, 0.0660, 453.18), + ( 29318, 0.0880, 881.39), + (149754, 0.1023, 1419.95), + (179704, 0.1133, 13740.55), + (299506, 0.1243, 17133.89), + (500000, 0.1353, 32025.28), + ( 'inf', 0.1463, 59152.12), + ), + 'annually': ( + ( 8932, 0.0110, 0.00), + ( 21175, 0.0220, 98.25), + ( 33421, 0.0440, 367.60), + ( 46394, 0.0660, 906.42), + ( 58634, 0.0880, 1762.64), + ( 299508, 0.1023, 2839.76), + ( 359407, 0.1133, 27481.17), + ( 599012, 0.1243, 34267.73), + (1000000, 0.1353, 64050.63), + ( 'inf', 0.1463, 118304.31), + ), + }, + } + + + @@ -620,19 +614,6 @@ - - { - 'weekly': ( 280, 280, 561, 561), - 'bi-weekly': ( 561, 561, 1121, 1121), - 'semi-monthly': ( 607, 607, 1214, 1214), - 'monthly': ( 1214, 1214, 2429, 2429), - 'quarterly': ( 3643, 3643, 7287, 7287), - 'semi-annual': ( 7287, 7287, 14573, 14573), - 'annually': (14573, 14573, 29146, 29146), - } - - - @@ -648,6 +629,21 @@ + + + + { + 'weekly': ( 294, 294, 587, 587), + 'bi-weekly': ( 587, 587, 1174, 1174), + 'semi-monthly': ( 636, 636, 1272, 1272), + 'monthly': ( 1272, 1272, 2545, 2545), + 'quarterly': ( 3817, 3817, 7634, 7634), + 'semi-annual': ( 7634, 7634, 15267, 15267), + 'annually': (15267, 15267, 30534, 30534), + } + + + @@ -656,21 +652,9 @@ - - { - 'weekly': ( 19, 38, 58, 77, 96, 115, 135, 154, 173, 192), - 'bi-weekly': ( 38, 77, 115, 154, 192, 231, 269, 308, 346, 385), - 'semi-monthly': ( 42, 83, 125, 167, 208, 250, 292, 333, 375, 417), - 'monthly': ( 83, 167, 250, 333, 417, 500, 583, 667, 750, 833), - 'quarterly': ( 250, 500, 750, 1000, 1250, 1500, 1750, 2000, 2250, 2500), - 'semi-annual': ( 500, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000), - 'annually': (1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000), - } - - - + { 'weekly': ( 19, 38, 58, 77, 96, 115, 135, 154, 173, 192), @@ -692,19 +676,6 @@ - - { - 'weekly': ( 85, 85, 169, 169), - 'bi-weekly': ( 169, 169, 339, 339), - 'semi-monthly': ( 183, 183, 367, 367), - 'monthly': ( 367, 367, 734, 734), - 'quarterly': (1100, 1100, 2201, 2201), - 'semi-annual': (2201, 2201, 4401, 4401), - 'annually': (4401, 4401, 8802, 8802), - } - - - @@ -720,6 +691,21 @@ + + + + { + 'weekly': ( 88, 88, 177, 177), + 'bi-weekly': ( 177, 177, 354, 354), + 'semi-monthly': ( 192, 192, 383, 383), + 'monthly': ( 383, 383, 767, 767), + 'quarterly': (1150, 1150, 2301, 2301), + 'semi-annual': (2301, 2301, 4601, 4601), + 'annually': (4601, 4601, 9202, 9202), + } + + + @@ -728,19 +714,6 @@ - - { - 'weekly': ( 2.41, 4.82, 7.23, 9.65, 12.06, 14.47, 16.88, 19.29, 21.70, 24.12), - 'bi-weekly': ( 4.82, 9.65, 14.47, 19.29, 24.12, 28.94, 33.76, 38.58, 43.41, 48.23), - 'semi-monthly': ( 5.23, 10.45, 15.68, 20.90, 26.13, 31.35, 36.58, 41.80, 47.03, 52.25), - 'monthly': ( 10.45, 20.90, 31.35, 41.80, 52.25, 62.70, 73.15, 83.60, 94.05, 104.50), - 'quarterly': ( 31.35, 62.70, 94.05, 125.40, 156.75, 188.10, 219.45, 250.80, 282.15, 313.50), - 'semi-annual': ( 62.70, 125.40, 188.10, 250.80, 313.50, 376.20, 438.90, 501.60, 564.30, 627.00), - 'annually': (125.40, 250.80, 376.20, 501.60, 627.00, 752.40, 877.80, 1003.20, 1128.60, 1254.00), - } - - - @@ -756,6 +729,21 @@ + + + + { + 'weekly': ( 2.62, 5.25, 7.87, 10.49, 13.12, 15.74, 18.36, 20.98, 23.61, 26.23), + 'bi-weekly': ( 5.25, 10.49, 15.74, 20.98, 26.23, 31.48, 36.72, 41.97, 47.22, 52.46), + 'semi-monthly': ( 5.68, 11.37, 17.05, 22.73, 28.42, 34.10, 39.78, 45.47, 51.15, 56.83), + 'monthly': ( 11.37, 22.73, 34.10, 45.47, 56.83, 68.20, 79.57, 90.93, 102.30, 113.67), + 'quarterly': ( 34.10, 68.20, 102.30, 136.40, 170.50, 204.60, 238.70, 272.80, 306.90, 341.00), + 'semi-annual': ( 68.20, 136.40, 204.60, 272.80, 341.00, 409.20, 477.40, 545.60, 613.80, 682.00), + 'annually': (136.40, 272.80, 409.20, 545.60, 682.00, 818.40, 954.80, 1091.20, 1227.60, 1364.00), + } + + + diff --git a/l10n_us_hr_payroll/data/state/ct_connecticut.xml b/l10n_us_hr_payroll/data/state/ct_connecticut.xml index c4bf1dd1..ca211952 100644 --- a/l10n_us_hr_payroll/data/state/ct_connecticut.xml +++ b/l10n_us_hr_payroll/data/state/ct_connecticut.xml @@ -7,11 +7,8 @@ - - 15000.0 - - - + + 15000.0 @@ -26,11 +23,7 @@ - - 3.4 - - - + 3.2 @@ -44,59 +37,9 @@ - - { - 'a': [ - ( 10000, 0, 3.00), - ( 50000, 300, 5.00), - (100000, 2300, 5.50), - (200000, 5050, 6.00), - (250000, 11050, 6.50), - (500000, 14300, 6.90), - ( 'inf', 31550, 6.99), - ], - 'b': [ - ( 16000, 0, 3.00), - ( 80000, 480, 5.00), - (160000, 3680, 5.50), - (320000, 8080, 6.00), - (400000, 17680, 6.50), - (800000, 22880, 6.90), - ( 'inf', 50480, 6.99), - ], - 'c': [ - ( 20000, 0, 3.00), - ( 100000, 600, 5.00), - ( 200000, 4600, 5.50), - ( 400000, 10100, 6.00), - ( 500000, 22100, 6.50), - (1000000, 28600, 6.90), - ( 'inf', 63100, 6.99), - ], - 'd': [ - ( 10000, 0, 3.00), - ( 50000, 300, 5.00), - (100000, 2300, 5.50), - (200000, 5050, 6.00), - (250000, 11050, 6.50), - (500000, 14300, 6.90), - ( 'inf', 31550, 6.99), - ], - 'f': [ - ( 10000, 0, 3.00), - ( 50000, 300, 5.00), - (100000, 2300, 5.50), - (200000, 5050, 6.00), - (250000, 11050, 6.50), - (500000, 14300, 6.90), - ( 'inf', 31550, 6.99), - ], - } - - - + { 'a': [ @@ -156,80 +99,9 @@ - - { - 'a': [ - (50250, 0), - (52750, 20), - (55250, 40), - (57750, 60), - (60250, 80), - (62750, 100), - (65250, 120), - (67750, 140), - (70250, 160), - (72750, 180), - ('inf', 200), - ], - 'b': [ - ( 78500, 0), - ( 82500, 32), - ( 86500, 64), - ( 90500, 96), - ( 94500, 128), - ( 98500, 160), - (102500, 192), - (106500, 224), - (110500, 256), - (114500, 288), - ( 'inf', 320), - ], - 'c': [ - (100500, 0), - (105500, 40), - (110500, 80), - (115500, 120), - (120500, 160), - (125500, 200), - (130500, 240), - (135500, 280), - (140500, 320), - (145500, 360), - ( 'inf', 400), - - ], - 'd': [ - (50250, 0), - (52750, 20), - (55250, 40), - (57750, 60), - (60250, 80), - (62750, 100), - (65250, 120), - (67750, 140), - (70250, 160), - (72750, 180), - ('inf', 200), - ], - 'f': [ - ( 56500, 0), - ( 61500, 20), - ( 66500, 40), - ( 71500, 60), - ( 76500, 80), - ( 81500, 100), - ( 86500, 120), - ( 91500, 140), - ( 96500, 160), - (101500, 180), - ( 'inf', 200), - ], - } - - - + { 'a': [ @@ -310,134 +182,9 @@ - - { - 'a': [ - (15000, 0.75), - (15500, 0.70), - (16000, 0.65), - (16500, 0.60), - (17000, 0.55), - (17500, 0.50), - (18000, 0.45), - (18500, 0.40), - (20000, 0.35), - (20500, 0.30), - (21000, 0.25), - (21500, 0.20), - (25000, 0.15), - (25500, 0.14), - (26000, 0.13), - (26500, 0.12), - (27000, 0.11), - (48000, 0.10), - (48500, 0.09), - (49000, 0.08), - (49500, 0.08), - (50000, 0.06), - (50500, 0.05), - (51000, 0.03), - (51500, 0.03), - (52000, 0.02), - (52500, 0.01), - ('inf', 0.00), - ], - 'b': [ - (24000, 0.75), - (24500, 0.70), - (25000, 0.65), - (25500, 0.60), - (26000, 0.55), - (26500, 0.50), - (27000, 0.45), - (27500, 0.40), - (34000, 0.35), - (34500, 0.30), - (35000, 0.25), - (35500, 0.20), - (44000, 0.15), - (44500, 0.14), - (45000, 0.13), - (45500, 0.12), - (46000, 0.11), - (74000, 0.10), - (74500, 0.09), - (75000, 0.08), - (75500, 0.08), - (76000, 0.06), - (76500, 0.05), - (77000, 0.03), - (77500, 0.03), - (78000, 0.02), - (78500, 0.01), - ('inf', 0.00), - ], - 'c': [ - (30000, 0.75), - (30500, 0.70), - (31000, 0.65), - (31500, 0.60), - (32000, 0.55), - (32500, 0.50), - (33000, 0.45), - (33500, 0.40), - (40000, 0.35), - (40500, 0.30), - (41000, 0.25), - (41500, 0.20), - (50000, 0.15), - (50500, 0.14), - (51000, 0.13), - (51500, 0.12), - (52000, 0.11), - (96000, 0.10), - (96500, 0.09), - (97000, 0.08), - (97500, 0.08), - (98000, 0.06), - (98500, 0.05), - (99000, 0.03), - (99500, 0.03), - (100000, 0.02), - (100500, 0.01), - ('inf', 0.00), - ], - 'f': [ - (18800, 0.75), - (19300, 0.70), - (19800, 0.65), - (20300, 0.60), - (20800, 0.55), - (21300, 0.50), - (21800, 0.45), - (22300, 0.40), - (25000, 0.35), - (25500, 0.30), - (26000, 0.25), - (26500, 0.20), - (31300, 0.15), - (31800, 0.14), - (32300, 0.13), - (32800, 0.12), - (33300, 0.11), - (60000, 0.10), - (60500, 0.09), - (61000, 0.08), - (61500, 0.08), - (62000, 0.06), - (62500, 0.05), - (63000, 0.03), - (63500, 0.03), - (64000, 0.02), - (64500, 0.01), - ('inf', 0.00), - ], - } - - - + { 'a': [ @@ -572,224 +319,9 @@ - - { - 'a': [ - (200000, 0), - (205000, 90), - (210000, 180), - (215000, 270), - (220000, 360), - (225000, 450), - (230000, 540), - (235000, 630), - (240000, 720), - (245000, 810), - (250000, 900), - (255000, 990), - (260000, 1080), - (265000, 1170), - (270000, 1260), - (275000, 1350), - (280000, 1440), - (285000, 1530), - (290000, 1620), - (295000, 1710), - (300000, 1800), - (305000, 1890), - (310000, 1980), - (315000, 2070), - (320000, 2160), - (325000, 2250), - (330000, 2340), - (335000, 2430), - (340000, 2520), - (345000, 2610), - (500000, 2700), - (505000, 2750), - (510000, 2800), - (515000, 2850), - (520000, 2900), - (525000, 2950), - (530000, 3000), - (535000, 3050), - (540000, 3100), - ( 'inf', 200), - ], - 'b': [ - (320000, 0), - (328000, 140), - (336000, 280), - (344000, 420), - (352000, 560), - (360000, 700), - (368000, 840), - (376000, 980), - (384000, 1120), - (392000, 1260), - (400000, 1400), - (408000, 1540), - (416000, 1680), - (424000, 1820), - (432000, 1960), - (440000, 2100), - (448000, 2240), - (456000, 2380), - (464000, 2520), - (472000, 2660), - (480000, 2800), - (488000, 2940), - (496000, 3080), - (504000, 3220), - (512000, 3360), - (520000, 3500), - (528000, 3640), - (536000, 3780), - (544000, 3920), - (552000, 4060), - (800000, 4200), - (808000, 4280), - (816000, 4360), - (824000, 4440), - (832000, 4520), - (840000, 4600), - (848000, 4680), - (856000, 4760), - (864000, 4840), - ( 'inf', 4920), - ], - 'c': [ - ( 400000, 0), - ( 410000, 180), - ( 420000, 360), - ( 430000, 540), - ( 440000, 720), - ( 450000, 900), - ( 460000, 1080), - ( 470000, 1260), - ( 480000, 1440), - ( 490000, 1620), - ( 500000, 1800), - ( 510000, 1980), - ( 520000, 2160), - ( 530000, 2340), - ( 540000, 2520), - ( 550000, 2700), - ( 560000, 2880), - ( 570000, 3060), - ( 580000, 3240), - ( 590000, 3420), - ( 600000, 3600), - ( 610000, 3780), - ( 620000, 3960), - ( 630000, 4140), - ( 640000, 4320), - ( 650000, 4500), - ( 660000, 4680), - ( 670000, 4860), - ( 680000, 5040), - ( 690000, 5220), - (1000000, 5400), - (1010000, 5500), - (1020000, 5600), - (1030000, 5700), - (1040000, 5800), - (1050000, 5900), - (1060000, 6000), - (1070000, 6100), - (1080000, 6200), - ( 'inf', 6300), - ], - 'd': [ - (200000, 0), - (205000, 90), - (210000, 180), - (215000, 270), - (220000, 360), - (225000, 450), - (230000, 540), - (235000, 630), - (240000, 720), - (245000, 810), - (250000, 900), - (255000, 990), - (260000, 1080), - (265000, 1170), - (270000, 1260), - (275000, 1350), - (280000, 1440), - (285000, 1530), - (290000, 1620), - (295000, 1710), - (300000, 1800), - (305000, 1890), - (310000, 1980), - (315000, 2070), - (320000, 2160), - (325000, 2250), - (330000, 2340), - (335000, 2430), - (340000, 2520), - (345000, 2610), - (500000, 2700), - (505000, 2750), - (510000, 2800), - (515000, 2850), - (520000, 2900), - (525000, 2950), - (530000, 3000), - (535000, 3050), - (540000, 3100), - ( 'inf', 200), - ], - 'f': [ - (200000, 0), - (205000, 90), - (210000, 180), - (215000, 270), - (220000, 360), - (225000, 450), - (230000, 540), - (235000, 630), - (240000, 720), - (245000, 810), - (250000, 900), - (255000, 990), - (260000, 1080), - (265000, 1170), - (270000, 1260), - (275000, 1350), - (280000, 1440), - (285000, 1530), - (290000, 1620), - (295000, 1710), - (300000, 1800), - (305000, 1890), - (310000, 1980), - (315000, 2070), - (320000, 2160), - (325000, 2250), - (330000, 2340), - (335000, 2430), - (340000, 2520), - (345000, 2610), - (500000, 2700), - (505000, 2750), - (510000, 2800), - (515000, 2850), - (520000, 2900), - (525000, 2950), - (530000, 3000), - (535000, 3050), - (540000, 3100), - ( 'inf', 200), - ], - } - - - + { 'a': [ @@ -1014,96 +546,9 @@ - - { - 'a' : [ - (24000, 12000), - (25000, 11000), - (26000, 10000), - (27000, 9000), - (28000, 8000), - (29000, 7000), - (30000, 6000), - (31000, 5000), - (32000, 4000), - (33000, 3000), - (34000, 2000), - (35000, 1000), - ('inf', 0), - ], - 'b' : [ - (38000, 19000), - (39000, 18000), - (40000, 17000), - (41000, 16000), - (42000, 15000), - (43000, 14000), - (44000, 13000), - (45000, 12000), - (46000, 11000), - (47000, 10000), - (48000, 9000), - (49000, 8000), - (50000, 7000), - (51000, 6000), - (52000, 5000), - (53000, 4000), - (54000, 3000), - (55000, 2000), - (56000, 1000), - ('inf', 0), - ], - 'c': [ - (48000, 24000), - (49000, 23000), - (50000, 22000), - (51000, 21000), - (52000, 20000), - (53000, 19000), - (54000, 18000), - (55000, 17000), - (56000, 16000), - (57000, 15000), - (58000, 14000), - (59000, 13000), - (60000, 12000), - (61000, 11000), - (62000, 10000), - (63000, 9000), - (64000, 8000), - (65000, 7000), - (66000, 6000), - (67000, 5000), - (68000, 4000), - (69000, 3000), - (70000, 2000), - (71000, 1000), - ('inf', 0), - ], - 'f' : [ - (30000, 15000), - (31000, 14000), - (22000, 13000), - (33000, 12000), - (34000, 11000), - (35000, 10000), - (36000, 9000), - (37000, 8000), - (38000, 7000), - (39000, 6000), - (40000, 5000), - (41000, 4000), - (42000, 3000), - (43000, 2000), - (44000, 1000), - ('inf', 0), - ], - } - - - + { 'a' : [ diff --git a/l10n_us_hr_payroll/data/state/de_delaware.xml b/l10n_us_hr_payroll/data/state/de_delaware.xml index fad2abf6..70965b3e 100644 --- a/l10n_us_hr_payroll/data/state/de_delaware.xml +++ b/l10n_us_hr_payroll/data/state/de_delaware.xml @@ -7,6 +7,7 @@ + 16500.0 @@ -21,6 +22,7 @@ + 1.50 @@ -34,6 +36,7 @@ + [ ( 2000, 0.0, 0.00), @@ -56,6 +59,7 @@ + 3250 @@ -69,6 +73,7 @@ + 110 diff --git a/l10n_us_hr_payroll/data/state/fl_florida.xml b/l10n_us_hr_payroll/data/state/fl_florida.xml index 8002a2ee..995b3146 100644 --- a/l10n_us_hr_payroll/data/state/fl_florida.xml +++ b/l10n_us_hr_payroll/data/state/fl_florida.xml @@ -26,16 +26,16 @@ - - 2.7 - - - 2.7 + + 2.9 + + + diff --git a/l10n_us_hr_payroll/data/state/ga_georgia.xml b/l10n_us_hr_payroll/data/state/ga_georgia.xml index 659515db..3c900ce6 100644 --- a/l10n_us_hr_payroll/data/state/ga_georgia.xml +++ b/l10n_us_hr_payroll/data/state/ga_georgia.xml @@ -7,11 +7,7 @@ - - 9500.00 - - - + 9500.00 @@ -26,11 +22,7 @@ - - 2.7 - - - + 2.7 @@ -44,304 +36,9 @@ - - { - 'married filing joint, both spouses working': { - 'weekly': ( - ( 9.50, 0.00, 1.00), - (29.00, 0.10, 2.00), - (48.00, 0.48, 3.00), - (67.50, 1.06, 4.00), - (96.00, 1.83, 5.00), - ('inf', 3.27, 5.75), - ), - 'bi-weekly': ( - ( 19.00, 0.00, 1.00), - ( 57.50, 0.19, 2.00), - ( 96.00, 0.96, 3.00), - (135.00, 2.12, 4.00), - (192.00, 3.65, 5.00), - ( 'inf', 6.54, 5.75), - ), - 'semi-monthly': ( - ( 21.00, 0.00, 1.00), - ( 62.50, 0.21, 2.00), - (104.00, 1.04, 3.00), - (146.00, 2.29, 4.00), - (208.00, 3.96, 5.00), - ( 'inf', 7.08, 5.75), - ), - 'monthly': ( - ( 41.50, 0.00, 1.00), - (125.50, 0.42, 2.00), - (208.00, 2.08, 3.00), - (292.00, 4.58, 4.00), - (417.00, 7.92, 5.00), - ( 'inf', 14.17, 5.75), - ), - 'quarterly': ( - ( 125.00, 0.00, 1.00), - ( 375.00, 1.25, 2.00), - ( 625.00, 6.25, 3.00), - ( 875.00, 13.75, 4.00), - (1250.00, 23.75, 5.00), - ( 'inf', 42.50, 5.75), - ), - 'semi-annual': ( - ( 250.00, 0.00, 1.00), - ( 750.00, 2.50, 2.00), - (1250.00, 12.50, 3.00), - (1750.00, 27.50, 4.00), - (2500.00, 47.50, 5.00), - ( 'inf', 85.00, 5.75), - ), - 'annual': ( - ( 500.00, 0.00, 1.00), - (1500.00, 5.00, 2.00), - (2500.00, 25.00, 3.00), - (3500.00, 55.00, 4.00), - (5000.00, 95.00, 5.00), - ( 'inf', 170.00, 5.75), - ), - }, - 'married filing joint, one spouse working': { - 'weekly': ( - ( 19.00, 0.00, 1.00), - ( 57.50, 0.19, 2.00), - ( 96.00, 0.96, 3.00), - (135.00, 2.12, 4.00), - (192.50, 3.65, 5.00), - ( 'inf', 6.54, 5.75), - ), - 'bi-weekly': ( - ( 38.50, 0.00, 1.00), - (115.00, 0.38, 2.00), - (192.00, 1.92, 3.00), - (269.00, 4.23, 4.00), - (385.00, 7.31, 5.00), - ( 'inf', 13.08, 5.75), - ), - 'semi-monthly': ( - ( 41.50, 0.00, 1.00), - (125.00, 0.42, 2.00), - (208.00, 2.08, 3.00), - (292.00, 4.58, 4.00), - (417.00, 7.92, 5.00), - ( 'inf', 14.17, 5.75), - ), - 'monthly': ( - ( 83.00, 0.00, 1.00), - (250.00, 0.83, 2.00), - (417.00, 4.17, 3.00), - (583.00, 9.17, 4.00), - (833.00, 15.83, 5.00), - ( 'inf', 28.33, 5.75), - ), - 'quarterly': ( - ( 250.00, 0.00, 1.00), - ( 750.00, 2.50, 2.00), - (1250.00, 12.50, 3.00), - (1750.00, 27.50, 4.00), - (2500.00, 47.50, 5.00), - ( 'inf', 85.00, 5.75), - ), - 'semi-annual': ( - ( 500.00, 0.00, 1.00), - (1500.00, 5.00, 2.00), - (2500.00, 25.00, 3.00), - (3500.00, 55.00, 4.00), - (5000.00, 95.00, 5.00), - ( 'inf', 170.00, 5.75), - ), - 'annual': ( - ( 1000.00, 0.00, 1.00), - ( 3000.00, 10.00, 2.00), - ( 5000.00, 50.00, 3.00), - ( 7000.00, 110.00, 4.00), - (10000.00, 190.00, 5.00), - ( 'inf', 340.00, 5.75), - ), - }, - 'single': { - 'weekly': ( - ( 14.50, 0.00, 1.00), - ( 43.50, 0.14, 2.00), - ( 72.00, 0.72, 3.00), - (101.00, 1.59, 4.00), - (135.00, 2.74, 5.00), - ( 'inf', 4.42, 5.75), - ), - 'bi-weekly': ( - ( 29.00, 0.00, 1.00), - ( 86.50, 0.29, 2.00), - (144.00, 1.44, 3.00), - (202.00, 3.17, 4.00), - (269.00, 5.48, 5.00), - ( 'inf', 8.85, 5.75), - ), - 'semi-monthly': ( - ( 31.00, 0.00, 1.00), - ( 93.50, 0.31, 2.00), - (156.00, 1.56, 3.00), - (219.00, 3.34, 4.00), - (292.00, 5.94, 5.00), - ( 'inf', 9.58, 5.75), - ), - 'monthly': ( - ( 62.50, 0.00, 1.00), - (187.00, 0.62, 2.00), - (312.00, 3.12, 3.00), - (437.00, 6.87, 4.00), - (583.00, 11.87, 5.00), - ( 'inf', 19.17, 5.75), - ), - 'quarterly': ( - ( 187.50, 0.00, 1.00), - ( 562.50, 1.88, 2.00), - ( 937.50, 9.38, 3.00), - (1312.00, 20.63, 4.00), - (1750.00, 35.63, 5.00), - ( 'inf', 57.50, 5.75), - ), - 'semi-annual': ( - ( 375.00, 0.00, 1.00), - (1125.00, 3.75, 2.00), - (1875.00, 18.75, 3.00), - (2625.00, 41.25, 4.00), - (3500.00, 71.25, 5.00), - ( 'inf', 115.00, 5.75), - ), - 'annual': ( - ( 750.00, 0.00, 1.00), - (2250.00, 7.50, 2.00), - (3750.00, 37.50, 3.00), - (5250.00, 82.50, 4.00), - (7000.00, 142.50, 5.00), - ( 'inf', 230.00, 5.75), - ), - }, - 'head of household': { - 'weekly': ( - ( 19.00, 0.00, 1.00), - ( 57.50, 0.19, 2.00), - ( 96.00, 0.96, 3.00), - (135.00, 2.12, 4.00), - (192.50, 3.65, 5.00), - ( 'inf', 6.54, 5.75), - ), - 'bi-weekly': ( - ( 38.50, 0.00, 1.00), - (115.00, 0.38, 2.00), - (192.00, 1.92, 3.00), - (269.00, 4.23, 4.00), - (385.00, 7.31, 5.00), - ( 'inf', 13.08, 5.75), - ), - 'semi-monthly': ( - ( 41.50, 0.00, 1.00), - (125.00, 0.42, 2.00), - (208.00, 2.08, 3.00), - (292.00, 4.58, 4.00), - (417.00, 7.92, 5.00), - ( 'inf', 14.17, 5.75), - ), - 'monthly': ( - ( 83.00, 0.00, 1.00), - (250.00, 0.83, 2.00), - (417.00, 4.17, 3.00), - (583.00, 9.17, 4.00), - (833.00, 15.83, 5.00), - ( 'inf', 28.33, 5.75), - ), - 'quarterly': ( - ( 250.00, 0.00, 1.00), - ( 750.00, 2.50, 2.00), - (1250.00, 12.50, 3.00), - (1750.00, 27.50, 4.00), - (2500.00, 47.50, 5.00), - ( 'inf', 85.00, 5.75), - ), - 'semi-annual': ( - ( 500.00, 0.00, 1.00), - (1500.00, 5.00, 2.00), - (2500.00, 25.00, 3.00), - (3500.00, 55.00, 4.00), - (5000.00, 95.00, 5.00), - ( 'inf', 170.00, 5.75), - ), - 'annual': ( - ( 1000.00, 0.00, 1.00), - ( 3000.00, 10.00, 2.00), - ( 5000.00, 50.00, 3.00), - ( 7000.00, 110.00, 4.00), - (10000.00, 190.00, 5.00), - ( 'inf', 340.00, 5.75), - ), - }, - 'married filing separate': { - 'weekly': ( - ( 9.50, 0.00, 1.00), - (29.00, 0.10, 2.00), - (48.00, 0.48, 3.00), - (67.50, 1.06, 4.00), - (96.00, 1.83, 5.00), - ('inf', 3.27, 5.75), - ), - 'bi-weekly': ( - ( 19.00, 0.00, 1.00), - ( 57.50, 0.19, 2.00), - ( 96.00, 0.96, 3.00), - (135.00, 2.12, 4.00), - (192.00, 3.65, 5.00), - ( 'inf', 6.54, 5.75), - ), - 'semi-monthly': ( - ( 21.00, 0.00, 1.00), - ( 62.50, 0.21, 2.00), - (104.00, 1.04, 3.00), - (146.00, 2.29, 4.00), - (208.00, 3.96, 5.00), - ( 'inf', 7.08, 5.75), - ), - 'monthly': ( - ( 41.50, 0.00, 1.00), - (125.50, 0.42, 2.00), - (208.00, 2.08, 3.00), - (292.00, 4.58, 4.00), - (417.00, 7.92, 5.00), - ( 'inf', 14.17, 5.75), - ), - 'quarterly': ( - ( 125.00, 0.00, 1.00), - ( 375.00, 1.25, 2.00), - ( 625.00, 6.25, 3.00), - ( 875.00, 13.75, 4.00), - (1250.00, 23.75, 5.00), - ( 'inf', 42.50, 5.75), - ), - 'semi-annual': ( - ( 250.00, 0.00, 1.00), - ( 750.00, 2.50, 2.00), - (1250.00, 12.50, 3.00), - (1750.00, 27.50, 4.00), - (2500.00, 47.50, 5.00), - ( 'inf', 85.00, 5.75), - ), - 'annual': ( - ( 500.00, 0.00, 1.00), - (1500.00, 5.00, 2.00), - (2500.00, 25.00, 3.00), - (3500.00, 55.00, 4.00), - (5000.00, 95.00, 5.00), - ( 'inf', 170.00, 5.75), - ), - }, - } - - - + { 'married filing joint, both spouses working': { @@ -646,59 +343,9 @@ - - { - 'married filing joint, both spouses working': { - 'weekly': 142.30, - 'bi-weekly': 284.62, - 'semi-monthly': 308.33, - 'monthly': 616.67, - 'quarterly': 1850.00, - 'semi-annual': 3700.00, - 'annual': 7400.00, - }, - 'married filing joint, one spouse working': { - 'weekly': 142.30, - 'bi-weekly': 284.62, - 'semi-monthly': 308.33, - 'monthly': 616.67, - 'quarterly': 1850.00, - 'semi-annual': 3700.00, - 'annual': 7400.00, - }, - 'single': { - 'weekly': 51.92, - 'bi-weekly': 103.85, - 'semi-monthly': 112.50, - 'monthly': 225.00, - 'quarterly': 675.00, - 'semi-annual': 1350.00, - 'annual': 2700.00, - }, - 'head of household': { - 'weekly': 51.92, - 'bi-weekly': 103.85, - 'semi-monthly': 112.50, - 'monthly': 225.00, - 'quarterly': 675.00, - 'semi-annual': 1350.00, - 'annual': 2700.00, - }, - 'married filing separate': { - 'weekly': 71.15, - 'bi-weekly': 142.30, - 'semi-monthly': 154.16, - 'monthly': 308.33, - 'quarterly': 925.00, - 'semi-annual': 1850.00, - 'annual': 3700.00, - }, - } - - - + { 'married filing joint, both spouses working': { @@ -758,21 +405,9 @@ - - { - 'weekly': 57.50, - 'bi-weekly': 115.00, - 'semi-monthly': 125.00, - 'monthly': 250.00, - 'quarterly': 750.00, - 'semi-annual': 1500.00, - 'annual': 3000.00, - } - - - + { 'weekly': 57.50, @@ -794,59 +429,9 @@ - - { - 'married filing joint, both spouses working': { - 'weekly': 115.50, - 'bi-weekly': 230.75, - 'semi-monthly': 250.00, - 'monthly': 500.00, - 'quarterly': 1500.00, - 'semi-annual': 3000.00, - 'annual': 6000.00, - }, - 'married filing joint, one spouse working': { - 'weekly': 115.50, - 'bi-weekly': 230.75, - 'semi-monthly': 250.00, - 'monthly': 500.00, - 'quarterly': 1500.00, - 'semi-annual': 3000.00, - 'annual': 6000.00, - }, - 'single': { - 'weekly': 88.50, - 'bi-weekly': 177.00, - 'semi-monthly': 191.75, - 'monthly': 383.50, - 'quarterly': 1150.00, - 'semi-annual': 2300.00, - 'annual': 4600.00, - }, - 'head of household': { - 'weekly': 88.50, - 'bi-weekly': 177.00, - 'semi-monthly': 191.75, - 'monthly': 383.50, - 'quarterly': 1150.00, - 'semi-annual': 2300.00, - 'annual': 4600.00, - }, - 'married filing separate': { - 'weekly': 57.75, - 'bi-weekly': 115.50, - 'semi-monthly': 125.00, - 'monthly': 250.00, - 'quarterly': 750.00, - 'semi-annual': 1500.00, - 'annual': 3000.00, - }, - } - - - + { 'married filing joint, both spouses working': { diff --git a/l10n_us_hr_payroll/data/state/hi_hawaii.xml b/l10n_us_hr_payroll/data/state/hi_hawaii.xml index 798821f2..470c5239 100644 --- a/l10n_us_hr_payroll/data/state/hi_hawaii.xml +++ b/l10n_us_hr_payroll/data/state/hi_hawaii.xml @@ -7,16 +7,17 @@ - - 46800.0 - - - 48100.0 + + + 47400.0 + + + @@ -26,16 +27,17 @@ - - 2.40 - - - 2.40 + + + 5.2 + + + @@ -44,44 +46,9 @@ - - { - 'single': ( - ( 2400, 0.00, 1.40), - ( 4800, 34.00, 3.20), - ( 9600, 110.00, 5.50), - (14400, 374.00, 6.40), - (19200, 682.00, 6.80), - (24000, 1008.00, 7.20), - (36000, 1354.00, 7.60), - ('inf', 2266.00, 7.90), - ), - 'married': ( - ( 4800, 0.00, 1.40), - ( 9600, 67.00, 3.20), - (19200, 221.00, 5.50), - (28800, 749.00, 6.40), - (38400, 1363.00, 6.80), - (48000, 2016.00, 7.20), - (72000, 2707.00, 7.60), - ('inf', 4531.00, 7.90), - ), - 'head_of_household': ( - ( 2400, 0.00, 1.40), - ( 4800, 34.00, 3.20), - ( 9600, 110.00, 5.50), - (14400, 374.00, 6.40), - (19200, 682.00, 6.80), - (24000, 1008.00, 7.20), - (36000, 1354.00, 7.60), - ('inf', 2266.00, 7.90), - ), - } - - - - + + { 'single': ( @@ -126,11 +93,7 @@ - - 1144 - - - + 1144 diff --git a/l10n_us_hr_payroll/data/state/ia_iowa.xml b/l10n_us_hr_payroll/data/state/ia_iowa.xml index dcc90009..67328363 100644 --- a/l10n_us_hr_payroll/data/state/ia_iowa.xml +++ b/l10n_us_hr_payroll/data/state/ia_iowa.xml @@ -7,16 +7,16 @@ - - 30600.0 - - - 31600.0 + + 32400.0 + + + @@ -26,11 +26,6 @@ - - 1.0 - - - 1.0 @@ -44,78 +39,6 @@ - - { - 'daily': ( - ( 5.13, 0.0033, 0.00), - ( 10.25, 0.0067, 0.02), - ( 20.50, 0.0225, 0.05), - ( 46.13, 0.0414, 0.28), - ( 76.89, 0.0563, 1.34), - (102.52, 0.0596, 3.07), - (153.78, 0.0625, 4.60), - (230.68, 0.0744, 7.80), - ( 'inf', 0.0853, 13.52), - ), - 'weekly': ( - ( 25.63, 0.0033, 0.00), - ( 51.27, 0.0067, 0.08), - ( 102.52, 0.0225, 0.25), - ( 230.67, 0.0414, 1.40), - ( 384.46, 0.0563, 6.71), - ( 512.62, 0.0596, 15.37), - ( 768.92, 0.0625, 23.01), - (1153.38, 0.0744, 39.03), - ( 'inf', 0.0853, 67.63), - ), - 'bi-weekly': ( - ( 51.27, 0.0033, 0.00), - ( 102.54, 0.0067, 0.17), - ( 205.04, 0.0225, 0.51), - ( 461.35, 0.0414, 2.82), - ( 768.92, 0.0563, 13.43), - (1025.23, 0.0596, 30.75), - (1537.85, 0.0625, 46.03), - (2306.77, 0.0744, 78.07), - ( 'inf', 0.0853, 135.28), - ), - 'semi-monthly': ( - ( 55.54, 0.0033, 0.00), - ( 111.08, 0.0067, 0.18), - ( 222.13, 0.0225, 0.55), - ( 499.79, 0.0414, 3.05), - ( 833.00, 0.0563, 14.59), - (1110.67, 0.0596, 33.31), - (1666.00, 0.0625, 49.86), - (2499.00, 0.0744, 84.57), - ( 'inf', 0.0853, 146.55), - ), - 'monthly': ( - ( 111.08, 0.0033, 0.00), - ( 222.17, 0.0067, 0.37), - ( 444.25, 0.0225, 1.11), - ( 999.58, 0.0414, 6.11), - (1666.00, 0.0563, 29.10), - (2221.33, 0.0596, 62.66), - (3332.00, 0.0625, 99.72), - (4998.00, 0.0744, 169.14), - ( 'inf', 0.0853, 293.09), - ), - 'annual': ( - ( 1333.00, 0.0033, 0.00), - ( 2666.00, 0.0067, 4.40), - ( 5331.00, 0.0225, 13.33), - (11995.00, 0.0414, 73.29), - (19992.00, 0.0563, 349.19), - (26656.00, 0.0596, 799.41), - (39984.00, 0.0625, 1196.58), - (59976.00, 0.0744, 2029.58), - ( 'inf', 0.0853, 3516.98), - ), - } - - - @@ -190,6 +113,69 @@ + + + + { + 'weekly': ( + ( 32.23, 0.0033, 0.00), + ( 64.46, 0.0067, 0.11), + ( 128.92, 0.0225, 0.33), + ( 290.08, 0.0414, 1.78), + ( 483.46, 0.0563, 8.45), + ( 644.62, 0.0596, 19.34), + ( 966.92, 0.0625, 28.95), + (1450.38, 0.0744, 49.09), + ( 'inf', 0.0853, 85.06), + ), + 'bi-weekly': ( + ( 64.46, 0.0033, 0.00), + ( 128.92, 0.0067, 0.21), + ( 257.85, 0.0225, 0.64), + ( 580.15, 0.0414, 3.54), + ( 966.92, 0.0563, 16.88), + (1289.23, 0.0596, 38.66), + (1933.85, 0.0625, 57.87), + (2900.77, 0.0744, 98.16), + ( 'inf', 0.0853, 170.10), + ), + 'semi-monthly': ( + ( 69.83, 0.0033, 0.00), + ( 139.67, 0.0067, 0.23), + ( 279.33, 0.0225, 0.70), + ( 628.50, 0.0414, 3.84), + (1047.50, 0.0563, 18.30), + (1396.67, 0.0596, 41.89), + (2095.00, 0.0625, 62.70), + (3142.50, 0.0744, 106.35), + ( 'inf', 0.0853, 184.28), + ), + 'monthly': ( + ( 139.67, 0.0033, 0.00), + ( 279.33, 0.0067, 0.46), + ( 558.67, 0.0225, 1.40), + (1257.00, 0.0414, 7.69), + (2095.00, 0.0563, 36.60), + (2793.33, 0.0596, 83.78), + (4190.00, 0.0625, 125.40), + (6285.00, 0.0744, 212.69), + ( 'inf', 0.0853, 368.56), + ), + 'annual': ( + ( 1676.00, 0.0033, 0.00), + ( 3352.00, 0.0067, 5.53), + ( 6704.00, 0.0225, 16.76), + (15084.00, 0.0414, 92.18), + (25140.00, 0.0563, 439.11), + (33520.00, 0.0596, 1005.26), + (50280.00, 0.0625, 1504.71), + (75420.00, 0.0744, 2552.21), + ( 'inf', 0.0853, 4422.63), + ), + } + + + @@ -198,18 +184,6 @@ - - { - 'daily': ( 6.50, 16.00), - 'weekly': ( 32.50, 80.00), - 'bi-weekly': ( 65.00, 160.00), - 'semi-monthly': ( 70.42, 173.33), - 'monthly': ( 140.83, 346.67), - 'annually': (1690.00, 4160.00), - } - - - @@ -224,6 +198,19 @@ + + + + { + 'weekly': ( 40.96, 100.77), + 'bi-weekly': ( 81.92, 201.54), + 'semi-monthly': ( 88.75, 218.33), + 'monthly': ( 177.50, 436.67), + 'annually': (2130.00, 5240.00), + } + + + @@ -232,18 +219,6 @@ - - { - 'daily': 0.15, - 'weekly': 0.77, - 'bi-weekly': 1.54, - 'semi-monthly': 1.67, - 'monthly': 3.33, - 'annually': 40.00, - } - - - @@ -258,6 +233,19 @@ + + + + { + 'weekly': 0.77, + 'bi-weekly': 1.54, + 'semi-monthly': 1.67, + 'monthly': 3.33, + 'annually': 40.00, + } + + + diff --git a/l10n_us_hr_payroll/data/state/id_idaho.xml b/l10n_us_hr_payroll/data/state/id_idaho.xml index 46dcce9d..80995fcc 100644 --- a/l10n_us_hr_payroll/data/state/id_idaho.xml +++ b/l10n_us_hr_payroll/data/state/id_idaho.xml @@ -7,16 +7,16 @@ - - 40000.0 - - - 41600.0 + + 43000.0 + + + @@ -26,11 +26,7 @@ - - 1.0 - - - + 1.0 @@ -44,170 +40,9 @@ - - { - 'single': { - 'weekly': ( - ( 235, 0.00, 0.000), - ( 264, 0.00, 1.125), - ( 294, 0.00, 3.125), - ( 324, 1.00, 3.625), - ( 353, 2.00, 4.625), - ( 383, 4.00, 5.625), - ( 457, 5.00, 6.625), - ('inf', 10.00, 6.925), - ), - 'bi-weekly': ( - ( 469, 0.00, 0.000), - ( 529, 0.00, 1.125), - ( 588, 1.00, 3.125), - ( 647, 3.00, 3.625), - ( 706, 5.00, 4.625), - ( 766, 7.00, 5.625), - ( 914, 11.00, 6.625), - ('inf', 21.00, 6.925), - ), - 'semi-monthly': ( - ( 508, 0.00, 0.000), - ( 573, 0.00, 1.125), - ( 637, 1.00, 3.125), - ( 701, 3.00, 3.625), - ( 765, 5.00, 4.625), - ( 829, 8.00, 5.625), - ( 990, 12.00, 6.625), - ('inf', 22.00, 6.925), - ), - 'monthly': ( - ( 1017, 0.00, 0.000), - ( 1145, 0.00, 1.125), - ( 1273, 1.00, 3.125), - ( 1402, 5.00, 3.625), - ( 1530, 10.00, 4.625), - ( 1659, 16.00, 5.625), - ( 1980, 23.00, 6.625), - ('inf', 45.00, 6.925), - ), - 'annually': ( - (12200, 0.00, 0.000), - (13741, 0.00, 1.125), - (15281, 17.00, 3.125), - (16822, 65.00, 3.625), - (18362, 121.00, 4.625), - (19903, 192.00, 5.625), - (23754, 279.00, 6.625), - ('inf', 534.00, 6.925), - ), - }, - 'married': { - 'weekly': ( - ( 469, 0.00, 0.000), - ( 529, 0.00, 1.125), - ( 588, 0.00, 3.125), - ( 647, 1.00, 3.625), - ( 706, 2.00, 4.625), - ( 766, 4.00, 5.625), - ( 914, 5.00, 6.625), - ('inf', 10.00, 6.925), - ), - 'bi-weekly': ( - ( 938, 0.00, 0.000), - ( 1057, 0.00, 1.125), - ( 1175, 1.00, 3.125), - ( 1294, 5.00, 3.625), - ( 1412, 9.00, 4.625), - ( 1531, 15.00, 5.625), - ( 1827, 21.00, 6.625), - ('inf', 41.00, 6.925), - ), - 'semi-monthly': ( - ( 1017, 0.00, 0.000), - ( 1145, 0.00, 1.125), - ( 1273, 1.00, 3.125), - ( 1402, 5.00, 3.625), - ( 1530, 10.00, 4.625), - ( 1659, 16.00, 5.625), - ( 1980, 23.00, 6.625), - ('inf', 45.00, 6.925), - ), - 'monthly': ( - ( 2033, 0.00, 0.000), - ( 2290, 0.00, 1.125), - ( 2547, 3.00, 3.125), - ( 2804, 11.00, 3.625), - ( 3060, 20.00, 4.625), - ( 3317, 32.00, 5.625), - ( 3959, 47.00, 6.625), - ('inf', 89.00, 6.925), - ), - 'annually': ( - (24400, 0.00, 0.000), - (27482, 0.00, 1.125), - (30562, 35.00, 3.125), - (33644, 131.00, 3.625), - (36724, 243.00, 4.625), - (39806, 385.00, 5.625), - (47508, 558.00, 6.625), - ('inf', 1068.00, 6.925), - ), - }, - 'head of household': { - 'weekly': ( - ( 235, 0.00, 0.000), - ( 264, 0.00, 1.125), - ( 294, 0.00, 3.125), - ( 324, 1.00, 3.625), - ( 353, 2.00, 4.625), - ( 383, 4.00, 5.625), - ( 457, 5.00, 6.625), - ('inf', 10.00, 6.925), - ), - 'bi-weekly': ( - ( 469, 0.00, 0.000), - ( 529, 0.00, 1.125), - ( 588, 1.00, 3.125), - ( 647, 3.00, 3.625), - ( 706, 5.00, 4.625), - ( 766, 7.00, 5.625), - ( 914, 11.00, 6.625), - ('inf', 21.00, 6.925), - ), - 'semi-monthly': ( - ( 508, 0.00, 0.000), - ( 573, 0.00, 1.125), - ( 637, 1.00, 3.125), - ( 701, 3.00, 3.625), - ( 765, 5.00, 4.625), - ( 829, 8.00, 5.625), - ( 990, 12.00, 6.625), - ('inf', 22.00, 6.925), - ), - 'monthly': ( - ( 1017, 0.00, 0.000), - ( 1145, 0.00, 1.125), - ( 1273, 1.00, 3.125), - ( 1402, 5.00, 3.625), - ( 1530, 10.00, 4.625), - ( 1659, 16.00, 5.625), - ( 1980, 23.00, 6.625), - ('inf', 45.00, 6.925), - ), - 'annually': ( - (12200, 0.00, 0.000), - (13741, 0.00, 1.125), - (15281, 17.00, 3.125), - (16822, 65.00, 3.625), - (18362, 121.00, 4.625), - (19903, 192.00, 5.625), - (23754, 279.00, 6.625), - ('inf', 534.00, 6.925), - ), - }, - } - - - + { 'single': { @@ -378,19 +213,9 @@ - - { - 'weekly': 56.92, - 'bi-weekly': 113.85, - 'semi-monthly': 123.33, - 'monthly': 246.67, - 'annually': 2960.00, - } - - - + { 'weekly': 56.92, diff --git a/l10n_us_hr_payroll/data/state/il_illinois.xml b/l10n_us_hr_payroll/data/state/il_illinois.xml index 840b2a9b..ccc6e314 100644 --- a/l10n_us_hr_payroll/data/state/il_illinois.xml +++ b/l10n_us_hr_payroll/data/state/il_illinois.xml @@ -7,16 +7,17 @@ - - 12960.0 - - - 12740.0 + + + 12960.0 + + + @@ -26,16 +27,17 @@ - - 3.175 - - - 3.125 + + + 3.175 + + + @@ -44,16 +46,17 @@ - - 2275.0 - - - 2325.0 + + + 2375.0 + + + @@ -62,11 +65,7 @@ - - 1000.0 - - - + 1000.0 diff --git a/l10n_us_hr_payroll/data/state/in_indiana.xml b/l10n_us_hr_payroll/data/state/in_indiana.xml index 9bda9b1e..56b7a979 100644 --- a/l10n_us_hr_payroll/data/state/in_indiana.xml +++ b/l10n_us_hr_payroll/data/state/in_indiana.xml @@ -7,6 +7,7 @@ + 9500.00 @@ -14,19 +15,21 @@ - + US IN Indiana SUTA Rate us_in_suta_rate + 2.5 + US IN Indiana SUTA Income Rate @@ -34,6 +37,7 @@ + 3.23 @@ -47,6 +51,7 @@ + { 'daily': ( 2.74, 5.48, 8.22, 10.96, 13.70, 16.44), @@ -66,6 +71,7 @@ + { 'daily': ( 4.11, 8.22, 12.33, 16.44, 20.55), diff --git a/l10n_us_hr_payroll/data/state/ks_kansas.xml b/l10n_us_hr_payroll/data/state/ks_kansas.xml index 5b59d2b7..d69b6d37 100644 --- a/l10n_us_hr_payroll/data/state/ks_kansas.xml +++ b/l10n_us_hr_payroll/data/state/ks_kansas.xml @@ -7,6 +7,7 @@ + 14000.0 @@ -21,6 +22,7 @@ + 2.7 @@ -34,6 +36,7 @@ + { 'weekly' : 43.27, @@ -55,6 +58,7 @@ + { 'single': { diff --git a/l10n_us_hr_payroll/data/state/ky_kentucky.xml b/l10n_us_hr_payroll/data/state/ky_kentucky.xml index bcdd2274..d9e9b346 100644 --- a/l10n_us_hr_payroll/data/state/ky_kentucky.xml +++ b/l10n_us_hr_payroll/data/state/ky_kentucky.xml @@ -12,6 +12,12 @@ + + + 11100.0 + + + @@ -21,6 +27,7 @@ + 2.7 @@ -40,6 +47,12 @@ + + + 2690 + + + @@ -49,6 +62,8 @@ + + 5.0 diff --git a/l10n_us_hr_payroll/data/state/la_louisiana.xml b/l10n_us_hr_payroll/data/state/la_louisiana.xml index 7e4f5fe2..9ac40aae 100644 --- a/l10n_us_hr_payroll/data/state/la_louisiana.xml +++ b/l10n_us_hr_payroll/data/state/la_louisiana.xml @@ -7,11 +7,7 @@ - - 7700.0 - - - + 7700.0 @@ -26,16 +22,18 @@ - - 1.14 - - - 1.14 + + + + 1.0 + + + @@ -44,22 +42,6 @@ - - { - 'single': ( - (12500.00, 2.10), - (50000.00, 1.60), - ( 'inf', 1.35), - ), - 'married': ( - ( 25000.00, 2.10), - (100000.00, 1.65), - ( 'inf', 1.35), - ), - } - - - { 'single': ( @@ -76,6 +58,23 @@ + + + { + 'single': ( + (12500.00, 2.00), + (50000.00, 4.00), + ( 'inf', 6.00) + ), + 'married': ( + ( 25000.00, 2.00), + (100000.00, 4.00), + ( 'inf', 6.00) + ), + } + + + @@ -84,11 +83,7 @@ - - 4500 - - - + 4500 @@ -102,11 +97,7 @@ - - 1000.0 - - - + 1000.0 diff --git a/l10n_us_hr_payroll/data/state/mi_michigan.xml b/l10n_us_hr_payroll/data/state/mi_michigan.xml index 1ce32483..df67c982 100644 --- a/l10n_us_hr_payroll/data/state/mi_michigan.xml +++ b/l10n_us_hr_payroll/data/state/mi_michigan.xml @@ -7,16 +7,17 @@ - - 9500.0 - - - 9000.0 + + + 9500.0 + + + @@ -26,11 +27,7 @@ - - 2.7 - - - + 2.7 @@ -44,18 +41,21 @@ - - 4400.0 - - - 4750.0 + + + 4900.0 + + + + + US Michigan - Unemployment Insurance Agency - Unemployment Tax diff --git a/l10n_us_hr_payroll/data/state/mn_minnesota.xml b/l10n_us_hr_payroll/data/state/mn_minnesota.xml index d1044752..997fcb46 100644 --- a/l10n_us_hr_payroll/data/state/mn_minnesota.xml +++ b/l10n_us_hr_payroll/data/state/mn_minnesota.xml @@ -7,16 +7,12 @@ - - 34000.0 - - - 35000.0 + @@ -26,16 +22,12 @@ - - 1.11 - - - 1.11 + @@ -44,24 +36,6 @@ - - { - 'single': ( - ( 28920, 2400, 5.35, 0.00), - ( 89510, 28920, 7.05, 1418.82), - (166290, 89510, 7.85, 5690.42), - ( 'inf', 166290, 9.85, 11717.65), - ), - 'married': ( - ( 47820, 9050, 5.35, 0.00), - ( 163070, 47820, 7.05, 2074.20), - ( 282200, 163070, 7.85, 10199.33), - ( 'inf', 282200, 9.85, 19551.04), - ), - } - - - @@ -82,6 +56,25 @@ + + + { + 'single': ( + ( 31055, 3825, 5.35, 0.00), + ( 93265, 31055, 6.80, 1418.82), + (169865, 93265, 7.85, 5687.09), + ( 'inf', 169865, 9.85, 11700.19), + ), + 'married': ( + ( 51810, 12000, 5.35, 0.00), + ( 170140, 51810, 6.80, 2129.84), + ( 288200, 170140, 7.85, 10176.28), + ( 'inf', 288200, 9.85, 19443.99), + ), + } + + + @@ -90,11 +83,6 @@ - - 4250.0 - - - @@ -102,6 +90,12 @@ + + + 4350.0 + + + diff --git a/l10n_us_hr_payroll/data/state/mo_missouri.xml b/l10n_us_hr_payroll/data/state/mo_missouri.xml index 73ea5109..1e2cd863 100644 --- a/l10n_us_hr_payroll/data/state/mo_missouri.xml +++ b/l10n_us_hr_payroll/data/state/mo_missouri.xml @@ -7,16 +7,17 @@ - - 12000.0 - - - 11500.0 + + + 11000.0 + + + @@ -26,16 +27,18 @@ - - 2.376 - - - 2.376 + + + + 2.7 + + + @@ -44,22 +47,6 @@ - - - [ - (1053.0, 1.5), - (1053.0, 2.0), - (1053.0, 2.5), - (1053.0, 3.0), - (1053.0, 3.5), - (1053.0, 4.0), - (1053.0, 4.5), - (1053.0, 5.0), - ( 'inf', 5.4), - ] - - - @@ -77,6 +64,24 @@ + + + + + [ + (1088.0, 1.5), + (1088.0, 2.0), + (1088.0, 2.5), + (1088.0, 3.0), + (1088.0, 3.5), + (1088.0, 4.0), + (1088.0, 4.5), + (1088.0, 5.0), + ( 'inf', 5.4), + ] + + + @@ -85,16 +90,6 @@ - - - { - 'single': 12400.0, - 'married': 24800.0, - 'head_of_household': 18650.0, - } - - - @@ -106,6 +101,17 @@ + + + + { + 'single': 12550.0, + 'married': 25100.0, + 'head_of_household': 18800.0, + } + + + diff --git a/l10n_us_hr_payroll/data/state/ms_mississippi.xml b/l10n_us_hr_payroll/data/state/ms_mississippi.xml index a3868e8d..4c6566b7 100644 --- a/l10n_us_hr_payroll/data/state/ms_mississippi.xml +++ b/l10n_us_hr_payroll/data/state/ms_mississippi.xml @@ -7,11 +7,7 @@ - - 14000.0 - - - + 14000.0 @@ -26,16 +22,18 @@ - - 1.2 - - - 1.2 + + + + 1.0 + + + @@ -44,15 +42,6 @@ - - [ - ( 10000.00, 290.0, 0.05), - ( 5000.00, 90.0, 0.04), - ( 2000.00, 0.0, 0.03), - ] - - - @@ -64,6 +53,17 @@ + + + + [ + ( 10000.00, 230.0, 0.05), + ( 5000.00, 30.0, 0.04), + ( 3000.00, 0.0, 0.03), + ] + + + @@ -72,18 +72,9 @@ - - { - 'single': 2300.0, - 'head_of_household': 3400.0, - 'married_dual': 2300.0, - 'married': 4600.0, - } - - - + { 'single': 2300.0, diff --git a/l10n_us_hr_payroll/data/state/mt_montana.xml b/l10n_us_hr_payroll/data/state/mt_montana.xml index b777fb4e..7df6da1c 100644 --- a/l10n_us_hr_payroll/data/state/mt_montana.xml +++ b/l10n_us_hr_payroll/data/state/mt_montana.xml @@ -1,22 +1,23 @@ + US MT Montana SUTA Wage Base us_mt_suta_wage_base - - 33000.00 - - - 34100.00 + + 35300.00 + + + @@ -26,11 +27,6 @@ - - 1.18 - - - 1.18 diff --git a/l10n_us_hr_payroll/data/state/nc_northcarolina.xml b/l10n_us_hr_payroll/data/state/nc_northcarolina.xml index d09f8e3f..5134c4d0 100644 --- a/l10n_us_hr_payroll/data/state/nc_northcarolina.xml +++ b/l10n_us_hr_payroll/data/state/nc_northcarolina.xml @@ -1,41 +1,43 @@ + US NC North Carolina SUTA Wage Base us_nc_suta_wage_base - - 24300.0 - - - 25200.0 + + 26000.0 + + + + US NC North Carolina SUTA Rate us_nc_suta_rate - - 1.0 - - - 1.0 + + 1.0 + + + @@ -44,18 +46,6 @@ - - - - { - 'weekly': {'allowance': 48.08, 'standard_deduction': 192.31, 'standard_deduction_hh': 288.46}, - 'bi-weekly': {'allowance': 96.15, 'standard_deduction': 384.62, 'standard_deduction_hh': 576.92}, - 'semi-monthly': {'allowance': 104.17, 'standard_deduction': 416.67, 'standard_deduction_hh': 625.00}, - 'monthly': {'allowance': 208.33, 'standard_deduction': 833.33, 'standard_deduction_hh': 1250.00}, - } - - - @@ -68,6 +58,20 @@ + + + + + + { + 'weekly': {'allowance': 48.08, 'standard_deduction': 206.73, 'standard_deduction_hh': 310.10}, + 'bi-weekly': {'allowance': 96.15, 'standard_deduction': 413.46, 'standard_deduction_hh': 620.19}, + 'semi-monthly': {'allowance': 104.17, 'standard_deduction': 447.92, 'standard_deduction_hh': 671.88}, + 'monthly': {'allowance': 208.33, 'standard_deduction': 895.83, 'standard_deduction_hh': 1343.75}, + } + + + diff --git a/l10n_us_hr_payroll/data/state/nd_north_dakota.xml b/l10n_us_hr_payroll/data/state/nd_north_dakota.xml index d778c3aa..9c7fdd69 100644 --- a/l10n_us_hr_payroll/data/state/nd_north_dakota.xml +++ b/l10n_us_hr_payroll/data/state/nd_north_dakota.xml @@ -12,6 +12,12 @@ + + + 38500.0 + + + @@ -21,12 +27,15 @@ + + 1.02 + US ND North Dakota SIT Tax Rate @@ -214,6 +223,189 @@ + + + + { + 'single': { + 'weekly': ( + ( 121, 0.00, 0.00), + ( 900, 0.00, 1.10), + ( 2007, 8.57, 2.04), + ( 4057, 31.15, 2.27), + ( 8678, 77.69, 2.64), + ('inf', 199.68, 2.90), + ), + 'bi-weekly': ( + ( 241, 0.00, 0.00), + ( 1800, 0.00, 1.10), + ( 4014, 17.15, 2.04), + ( 8113, 62.31, 2.27), + ( 17357, 155.36, 2.64), + ( 'inf', 399.40, 2.90), + ), + 'semi-monthly': ( + ( 261, 0.00, 0.00), + ( 1950, 0.00, 1.10), + ( 4349, 18.58, 2.04), + ( 8790, 67.52, 2.27), + ( 18790, 168.33, 2.64), + ( 'inf', 432.67, 2.90), + ), + 'monthly': ( + ( 523, 0.00, 0.00), + ( 3900, 0.00, 1.10), + ( 8698, 37.15, 2.04), + ( 17579, 135.03, 2.27), + ( 37606, 336.62, 2.64), + ( 'inf', 865.34, 2.90), + ), + 'quarterly': ( + ( 1569, 0.00, 0.00), + ( 11700, 0.00, 1.10), + ( 26094, 111.44, 2.04), + ( 52738, 405.08, 2.27), + ( 112819, 1009.90, 2.64), + ( 'inf', 2596.04, 2.90), + ), + 'semi-annual': ( + ( 3138, 0.00, 0.00), + ( 23400, 0.00, 1.10), + ( 52188, 222.88, 2.04), + ( 105475, 810.16, 2.27), + ( 225638, 2019.77, 2.64), + ( 'inf', 5192.08, 2.90), + ), + 'annual': ( + ( 6275, 0.00, 0.00), + ( 46800, 0.00, 1.10), + ( 104375, 445.78, 2.04), + ( 210950, 1620.31, 2.27), + ( 451275, 4039.56, 2.64), + ( 'inf', 10384.14, 2.90), + ), + }, + 'married': { + 'weekly': ( + ( 241, 0.00, 0.00), + ( 892, 0.00, 1.10), + ( 1814, 7.16, 2.04), + ( 2637, 25.97, 2.27), + ( 4520, 44.65, 2.64), + ('inf', 94.36, 2.90), + ), + 'bi-weekly': ( + ( 483, 0.00, 0.00), + ( 1785, 0.00, 1.10), + ( 3628, 14.32, 2.04), + ( 5274, 51.92, 2.27), + ( 9040, 89.28, 2.64), + ( 'inf', 188.71, 2.90), + ), + 'semi-monthly': ( + ( 523, 0.00, 0.00), + ( 1933, 0.00, 1.10), + ( 3930, 15.51, 2.04), + ( 5714, 56.25, 2.27), + ( 9794, 96.75, 2.64), + ( 'inf', 204.46, 2.90), + ), + 'monthly': ( + ( 1046, 0.00, 0.00), + ( 3867, 0.00, 1.10), + ( 7860, 31.03, 2.04), + ( 11427, 112.49, 2.27), + ( 19588, 193.46, 2.64), + ( 'inf', 408.91, 2.90), + ), + 'quarterly': ( + ( 3138, 0.00, 0.00), + ( 11600, 0.00, 1.10), + ( 23581, 93.08, 2.04), + ( 34281, 337.49, 2.27), + ( 58763, 580.38, 2.64), + ( 'inf', 1226.71, 2.90), + ), + 'semi-annual': ( + ( 6275, 0.00, 0.00), + ( 23200, 0.00, 1.10), + ( 47163, 186.18, 2.04), + ( 68563, 675.02, 2.27), + ( 117525, 1160.80, 2.64), + ( 'inf', 2453.40, 2.90), + ), + 'annual': ( + ( 12550, 0.00, 0.00), + ( 46400, 0.00, 1.10), + ( 94325, 372.35, 2.04), + ( 137125, 1350.02, 2.27), + ( 235050, 2321.58, 2.64), + ( 'inf', 4906.80, 2.90), + ), + }, + 'head_household':{ + 'weekly': ( + ( 121, 0.00, 0.00), + ( 900, 0.00, 1.10), + ( 2007, 8.57, 2.04), + ( 4057, 31.15, 2.27), + ( 8678, 77.69, 2.64), + ('inf', 199.68, 2.90), + ), + 'bi-weekly': ( + ( 241, 0.00, 0.00), + ( 1800, 0.00, 1.10), + ( 4014, 17.15, 2.04), + ( 8113, 62.31, 2.27), + ( 17357, 155.36, 2.64), + ( 'inf', 399.40, 2.90), + ), + 'semi-monthly': ( + ( 261, 0.00, 0.00), + ( 1950, 0.00, 1.10), + ( 4349, 18.58, 2.04), + ( 8790, 67.52, 2.27), + ( 18790, 168.33, 2.64), + ( 'inf', 432.67, 2.90), + ), + 'monthly': ( + ( 523, 0.00, 0.00), + ( 3900, 0.00, 1.10), + ( 8698, 37.15, 2.04), + ( 17579, 135.03, 2.27), + ( 37606, 336.62, 2.64), + ( 'inf', 865.34, 2.90), + ), + 'quarterly': ( + ( 1569, 0.00, 0.00), + ( 11700, 0.00, 1.10), + ( 26094, 111.44, 2.04), + ( 52738, 405.08, 2.27), + ( 112819, 1009.90, 2.64), + ( 'inf', 2596.04, 2.90), + ), + 'semi-annual': ( + ( 3138, 0.00, 0.00), + ( 23400, 0.00, 1.10), + ( 52188, 222.88, 2.04), + ( 105475, 810.16, 2.27), + ( 225638, 2019.77, 2.64), + ( 'inf', 5192.08, 2.90), + ), + 'annual': ( + ( 6275, 0.00, 0.00), + ( 46800, 0.00, 1.10), + ( 104375, 445.78, 2.04), + ( 210950, 1620.31, 2.27), + ( 451275, 4039.56, 2.64), + ( 'inf', 10384.14, 2.90), + ), + }, + } + + + @@ -222,6 +414,7 @@ + { 'weekly' : 83.00, diff --git a/l10n_us_hr_payroll/data/state/ne_nebraska.xml b/l10n_us_hr_payroll/data/state/ne_nebraska.xml index 1951ff2f..ae668205 100644 --- a/l10n_us_hr_payroll/data/state/ne_nebraska.xml +++ b/l10n_us_hr_payroll/data/state/ne_nebraska.xml @@ -7,6 +7,7 @@ + 9000.0 @@ -26,7 +27,15 @@ + + + + 2.5 + + + + US NE Nebraska SIT Tax Rate @@ -34,6 +43,8 @@ + + { 'single': { diff --git a/l10n_us_hr_payroll/data/state/nh_new_hampshire.xml b/l10n_us_hr_payroll/data/state/nh_new_hampshire.xml index 374ff539..ed53b7e2 100644 --- a/l10n_us_hr_payroll/data/state/nh_new_hampshire.xml +++ b/l10n_us_hr_payroll/data/state/nh_new_hampshire.xml @@ -7,6 +7,7 @@ + 14000.00 @@ -26,6 +27,11 @@ + + 2.7 + + + diff --git a/l10n_us_hr_payroll/data/state/nj_newjersey.xml b/l10n_us_hr_payroll/data/state/nj_newjersey.xml index 50c72dcd..c1b7e003 100644 --- a/l10n_us_hr_payroll/data/state/nj_newjersey.xml +++ b/l10n_us_hr_payroll/data/state/nj_newjersey.xml @@ -7,16 +7,17 @@ - - 34400.00 - - - 35300.00 + + + 36200.00 + + + @@ -27,11 +28,7 @@ - - 2.6825 - - - + 2.6825 @@ -45,11 +42,7 @@ - - 0.3825 - - - + 0.3825 @@ -64,11 +57,7 @@ - - 0.5 - - - + 0.5 @@ -82,16 +71,17 @@ - - 0.17 - - - 0.26 + + + 0.47 + + + @@ -101,11 +91,7 @@ - - 0.1175 - - - + 0.1175 @@ -119,11 +105,7 @@ - - 0.0425 - - - + 0.0425 @@ -138,11 +120,7 @@ - - 0.0 - - - + 0.0 @@ -156,16 +134,17 @@ - - 0.08 - - - 0.16 + + + 0.28 + + + @@ -175,351 +154,6 @@ - - { - 'A': { - 'weekly': ( - ( 385, 0.00, 1.50), - ( 673, 5.77, 2.00), - ( 769, 11.54, 3.90), - ( 1442, 15.29, 6.10), - ( 9615, 56.34, 7.00), - (96154, 628.46, 9.90), - ('inf', 9195.77, 11.80), - ), - 'bi-weekly': ( - ( 769, 0.00, 1.50), - ( 1346, 12.00, 2.00), - ( 1538, 23.00, 3.90), - ( 2885, 31.00, 6.10), - ( 19231, 113.00, 7.00), - (192308, 1257.00, 9.90), - ( 'inf', 18392.00, 11.80), - ), - 'semi-monthly': ( - ( 833, 0.00, 1.50), - ( 1458, 13.00, 2.00), - ( 1667, 25.00, 3.90), - ( 3125, 33.00, 6.10), - ( 20833, 122.00, 7.00), - (208333, 1362.00, 9.90), - ( 'inf', 19924.00, 11.80), - ), - 'monthly': ( - ( 1667, 0.00, 1.50), - ( 2917, 25.00, 2.00), - ( 3333, 50.00, 3.90), - ( 6250, 66.00, 6.10), - ( 41667, 244.00, 7.00), - (416667, 2723.00, 9.90), - ( 'inf', 39848.00, 11.80), - ), - 'quarterly': ( - ( 5000, 0.00, 1.50), - ( 8750, 75.00, 2.00), - ( 10000, 150.00, 3.90), - ( 18750, 198.75, 6.10), - ( 125000, 732.50, 7.00), - (1250000, 8170.00, 9.90), - ( 'inf', 119545.00, 11.80), - ), - 'semi-annual': ( - ( 10000, 0.00, 1.50), - ( 17500, 150.00, 2.00), - ( 20000, 300.00, 3.90), - ( 37500, 397.50, 6.10), - ( 250000, 1465.00, 7.00), - (2500000, 16340.00, 9.90), - ( 'inf', 239090.00, 11.80), - ), - 'annual': ( - ( 20000, 0.00, 1.50), - ( 35000, 300.00, 2.00), - ( 40000, 600.00, 3.90), - ( 75000, 795.00, 6.10), - ( 500000, 2930.00, 7.00), - (5000000, 32680.00, 9.90), - ( 'inf', 478180.00, 11.80), - ), - }, - 'B': { - 'weekly': ( - ( 385, 0.00, 1.50), - ( 962, 5.77, 2.00), - ( 1346, 17.31, 2.70), - ( 1538, 27.69, 3.90), - ( 2885, 35.19, 6.10), - ( 9615, 117.31, 7.00), - (96154, 588.46, 9.90), - ('inf', 9155.77, 11.80), - ), - 'bi-weekly': ( - ( 769, 0.00, 1.50), - ( 1923, 12.00, 2.00), - ( 2692, 35.00, 2.70), - ( 3076, 55.00, 3.90), - ( 5769, 70.00, 6.10), - ( 19231, 235.00, 7.00), - (192308, 1177.00, 9.90), - ( 'inf', 18312.00, 11.80), - ), - 'semi-monthly': ( - ( 833, 0.00, 1.50), - ( 2083, 12.50, 2.00), - ( 2917, 37.50, 2.70), - ( 3333, 59.99, 3.90), - ( 6250, 76.25, 6.10), - ( 20833, 254.19, 7.00), - (208333, 1275.00, 9.90), - ( 'inf', 19838.00, 11.80), - ), - 'monthly': ( - ( 1667, 0.00, 1.50), - ( 4167, 25.00, 2.00), - ( 5833, 75.00, 2.70), - ( 6667, 120.00, 3.90), - ( 12500, 153.00, 6.10), - ( 41667, 508.00, 7.00), - (416667, 2550.00, 9.90), - ( 'inf', 39675.00, 11.80), - ), - 'quarterly': ( - ( 5000, 0.00, 1.50), - ( 12500, 75.00, 2.00), - ( 17500, 225.00, 2.70), - ( 20000, 360.00, 3.90), - ( 37500, 397.50, 6.10), - ( 125000, 1525.00, 7.00), - (1250000, 7650.00, 9.90), - ( 'inf', 119025.00, 11.80), - ), - 'semi-annual': ( - ( 10000, 0.00, 1.50), - ( 25000, 150.00, 2.00), - ( 35000, 450.00, 2.70), - ( 40000, 720.00, 3.90), - ( 75000, 915.00, 6.10), - ( 250000, 3050.00, 7.00), - (2500000, 15300.00, 9.90), - ( 'inf', 238050.00, 11.80), - ), - 'annual': ( - ( 20000, 0.00, 1.50), - ( 50000, 300.00, 2.00), - ( 70000, 900.00, 2.70), - (80000, 1440.00, 3.90), - ( 150000, 1830.00, 6.10), - ( 500000, 6100.00, 7.00), - (5000000, 30600.00, 9.90), - ( 'inf', 476100.00, 11.80), - ), - }, - 'C': { - 'weekly': ( - ( 385, 0.00, 1.50), - ( 769, 5.77, 2.30), - ( 962, 14.62, 2.80), - ( 1154, 20.00, 3.50), - ( 2885, 26.73, 5.60), - ( 9615, 123.65, 6.60), - (96154, 567.88, 9.90), - ('inf', 9135.19, 11.80), - ), - 'bi-weekly': ( - ( 769, 0.00, 1.50), - ( 1538, 11.54, 2.30), - ( 1923, 29.23, 2.80), - ( 2308, 40.00, 3.50), - ( 5769, 53.46, 5.60), - ( 19231, 247.31, 6.60), - (192308, 1135.77, 9.90), - ( 'inf', 18270.38, 11.80), - ), - 'semi-monthly': ( - ( 833, 0.00, 1.50), - ( 1667, 12.50, 2.30), - ( 2083, 31.67, 2.80), - ( 2500, 43.33, 3.50), - ( 6250, 57.92, 5.60), - ( 20833, 267.92, 6.60), - (208333, 1230.42, 9.90), - ( 'inf', 19792.92, 11.80), - ), - 'monthly': ( - ( 1667, 0.00, 1.50), - ( 3333, 25.00, 2.30), - ( 4167, 63.33, 2.80), - ( 5000, 86.67, 3.50), - ( 12500, 115.83, 5.60), - ( 41667, 535.85, 6.60), - (416667, 2460.83, 9.90), - ( 'inf', 39585.83, 11.80), - ), - 'quarterly': ( - ( 5000, 0.00, 1.50), - ( 10000, 75.00, 2.30), - ( 12500, 190.00, 2.80), - ( 15000, 260.00, 3.50), - ( 37500, 347.50, 5.60), - ( 125000, 1607.50, 6.60), - (1250000, 7382.50, 9.90), - ( 'inf', 118757.50, 11.80), - ), - 'semi-annual': ( - ( 10000, 0.00, 1.50), - ( 20000, 150.00, 2.30), - ( 25000, 380.00, 2.80), - ( 30000, 520.00, 3.50), - ( 75000, 695.00, 5.60), - ( 250000, 3215.00, 6.60), - (2500000, 14765.00, 9.90), - ( 'inf', 237515.00, 11.80), - ), - 'annual': ( - ( 20000, 0.00, 1.50), - ( 40000, 300.00, 2.30), - ( 50000, 760.00, 2.80), - ( 60000, 1040.00, 3.50), - ( 150000, 1390.00, 5.60), - ( 500000, 6430.00, 6.60), - (5000000, 29530.00, 9.90), - ( 'inf', 475030.00, 11.80), - ), - }, - 'D': { - 'weekly': ( - ( 385, 0.00, 1.50), - ( 769, 5.77, 2.70), - ( 962, 16.15, 3.40), - ( 1154, 22.69, 4.30), - ( 2885, 30.96, 5.60), - ( 9615, 127.88, 6.50), - ( 96154, 565.38, 9.90), - ( 'inf', 9132.69, 11.80), - ), - 'bi-weekly': ( - ( 769, 0.00, 1.50), - ( 1538, 11.54, 2.70), - ( 1923, 32.31, 3.40), - ( 2308, 45.38, 4.30), - ( 5769, 61.92, 5.60), - ( 19231, 255.77, 6.50), - (192308, 1130.77, 9.90), - ( 'inf', 18265.38, 11.80), - ), - 'semi-monthly': ( - ( 833, 0.00, 1.50), - ( 1667, 12.50, 2.70), - ( 2083, 35.00, 3.40), - ( 2500, 49.17, 4.30), - ( 6250, 67.08, 5.60), - ( 20833, 277.08, 6.50), - (208333, 1225.00, 9.90), - ( 'inf', 19787.50, 11.80), - ), - 'monthly': ( - ( 1667, 0.00, 1.50), - ( 3333, 25.00, 2.70), - ( 4167, 70.00, 3.40), - ( 5000, 98.33, 4.00), - ( 12500, 134.17, 5.60), - ( 41667, 554.17, 6.50), - (416667, 2450.00, 9.90), - ( 'inf', 39575.00, 11.80), - ), - 'quarterly': ( - ( 5000, 0.00, 1.50), - ( 10000, 75.00, 2.07), - ( 12500, 210.00, 3.40), - ( 15000, 295.00, 4.30), - ( 37500, 402.50, 5.60), - ( 125000, 1662.50, 6.50), - (1250000, 7350.00, 9.90), - ( 'inf', 118725.00, 11.80), - ), - 'semi-annual': ( - ( 10000, 0.00, 1.50), - ( 20000, 150.00, 2.70), - ( 25000, 420.00, 3.40), - ( 30000, 590.00, 4.30), - ( 75000, 805.00, 5.60), - ( 250000, 3325.00, 6.50), - (2500000, 14700.00, 9.90), - ( 'inf', 237450.00, 11.80), - ), - 'annual': ( - ( 20000, 0.00, 1.50), - ( 40000, 300.00, 2.70), - ( 50000, 840.00, 3.40), - ( 60000, 1180.00, 4.30), - ( 150000, 1610.00, 5.60), - ( 250000, 6650.00, 6.50), - (2500000, 29400.00, 9.90), - ( 'inf', 474900.00, 11.80), - ), - }, - 'E': { - 'weekly': ( - ( 385, 0.00, 1.50), - ( 673, 5.77, 2.00), - ( 1923, 11.54, 5.80), - ( 9615, 84.04, 6.50), - ( 96154, 584.04, 9.90), - ( 'inf', 9151.35, 11.80), - ), - 'bi-weekly': ( - ( 769, 0.00, 1.50), - ( 1346, 12.00, 2.00), - ( 3846, 23.00, 5.80), - ( 19231, 168.00, 6.50), - (192308, 1168.00, 9.90), - ( 'inf', 18303.00, 11.80), - ), - 'semi-monthly': ( - ( 833, 0.00, 1.50), - ( 1458, 13.00, 2.00), - ( 4167, 25.00, 5.80), - ( 20833, 182.00, 6.50), - (208333, 1265.00, 9.90), - ( 'inf', 19828.00, 11.80), - ), - 'monthly': ( - ( 1667, 0.00, 1.50), - ( 2916, 25.00, 2.00), - ( 8333, 50.00, 5.80), - ( 41667, 364.00, 6.50), - (416667, 2531.00, 9.90), - ( 'inf', 39656.00, 11.80), - ), - 'quarterly': ( - ( 5000, 0.00, 1.50), - ( 8750, 75.00, 2.00), - ( 25000, 150.00, 5.80), - ( 125000, 1092.50, 6.50), - (1250000, 7592.50, 9.90), - ( 'inf', 118967.50, 11.80), - ), - 'semi-annual': ( - ( 10000, 0.00, 1.50), - ( 17500, 150.00, 2.00), - ( 50000, 300.00, 5.80), - ( 250000, 2185.00, 6.50), - (2500000, 15185.00, 9.90), - ( 'inf', 237935.00, 11.80), - ), - 'annual': ( - ( 20000, 0.00, 1.50), - ( 35000, 300.00, 2.00), - ( 100000, 600.00, 5.80), - ( 500000, 4370.00, 6.50), - (5000000, 30370.00, 9.90), - ( 'inf', 475870.00, 11.80), - ), - }, - } - - - { @@ -866,6 +500,352 @@ + + + { + 'A': { + 'weekly': ( + ( 385, 0.00, 1.50), + ( 673, 5.77, 2.00), + ( 769, 11.54, 3.90), + ( 1442, 15.29, 6.10), + ( 9615, 56.34, 7.00), + (19231, 628.46, 9.90), + ('inf', 1580.38, 11.80), + ), + 'bi-weekly': ( + ( 769, 0.00, 1.50), + ( 1346, 12.00, 2.00), + ( 1538, 23.00, 3.90), + ( 2885, 31.00, 6.10), + ( 19231, 113.00, 7.00), + ( 38462, 1257.00, 9.90), + ( 'inf', 3161.00, 11.80), + ), + 'semi-monthly': ( + ( 833, 0.00, 1.50), + ( 1458, 13.00, 2.00), + ( 1667, 25.00, 3.90), + ( 3125, 33.00, 6.10), + ( 20833, 122.00, 7.00), + ( 41667, 1362.00, 9.90), + ( 'inf', 3424.00, 11.80), + ), + 'monthly': ( + ( 1667, 0.00, 1.50), + ( 2917, 25.00, 2.00), + ( 3333, 50.00, 3.90), + ( 6250, 66.00, 6.10), + ( 41667, 244.00, 7.00), + ( 83333, 2723.00, 9.90), + ( 'inf', 6848.00, 11.80), + ), + 'quarterly': ( + ( 5000, 0.00, 1.50), + ( 8750, 75.00, 2.00), + ( 10000, 150.00, 3.90), + ( 18750, 198.75, 6.10), + ( 125000, 732.50, 7.00), + ( 250000, 8170.00, 9.90), + ( 'inf', 20545.00, 11.80), + ), + 'semi-annual': ( + ( 10000, 0.00, 1.50), + ( 17500, 150.00, 2.00), + ( 20000, 300.00, 3.90), + ( 37500, 397.50, 6.10), + ( 250000, 1465.00, 7.00), + ( 500000, 16340.00, 9.90), + ( 'inf', 41060.00, 11.80), + ), + 'annual': ( + ( 20000, 0.00, 1.50), + ( 35000, 300.00, 2.00), + ( 40000, 600.00, 3.90), + ( 75000, 795.00, 6.10), + ( 500000, 2930.00, 7.00), + (1000000, 32680.00, 9.90), + ( 'inf', 82180.00, 11.80), + ), + }, + 'B': { + 'weekly': ( + ( 385, 0.00, 1.50), + ( 962, 5.77, 2.00), + ( 1346, 17.31, 2.70), + ( 1538, 27.69, 3.90), + ( 2885, 35.19, 6.10), + ( 9615, 117.31, 7.00), + (19231, 588.46, 9.90), + ('inf', 1540.38, 11.80), + ), + 'bi-weekly': ( + ( 769, 0.00, 1.50), + ( 1923, 12.00, 2.00), + ( 2692, 35.00, 2.70), + ( 3076, 55.00, 3.90), + ( 5769, 70.00, 6.10), + ( 19231, 235.00, 7.00), + ( 38462, 1177.00, 9.90), + ( 'inf', 3081.00, 11.80), + ), + 'semi-monthly': ( + ( 833, 0.00, 1.50), + ( 2083, 12.50, 2.00), + ( 2917, 37.50, 2.70), + ( 3333, 59.99, 3.90), + ( 6250, 76.25, 6.10), + ( 20833, 254.19, 7.00), + ( 41667, 1275.00, 9.90), + ( 'inf', 3338.00, 11.80), + ), + 'monthly': ( + ( 1667, 0.00, 1.50), + ( 4167, 25.00, 2.00), + ( 5833, 75.00, 2.70), + ( 6667, 120.00, 3.90), + ( 12500, 153.00, 6.10), + ( 41667, 508.00, 7.00), + ( 83333, 2550.00, 9.90), + ( 'inf', 6675.00, 11.80), + ), + 'quarterly': ( + ( 5000, 0.00, 1.50), + ( 12500, 75.00, 2.00), + ( 17500, 225.00, 2.70), + ( 20000, 360.00, 3.90), + ( 37500, 397.50, 6.10), + ( 125000, 1525.00, 7.00), + ( 250000, 7650.00, 9.90), + ( 'inf', 20025.00, 11.80), + ), + 'semi-annual': ( + ( 10000, 0.00, 1.50), + ( 25000, 150.00, 2.00), + ( 35000, 450.00, 2.70), + ( 40000, 720.00, 3.90), + ( 75000, 915.00, 6.10), + ( 250000, 3050.00, 7.00), + ( 500000, 15300.00, 9.90), + ( 'inf', 40050.00, 11.80), + ), + 'annual': ( + ( 20000, 0.00, 1.50), + ( 50000, 300.00, 2.00), + ( 70000, 900.00, 2.70), + (80000, 1440.00, 3.90), + ( 150000, 1830.00, 6.10), + ( 500000, 6100.00, 7.00), + (1000000, 30600.00, 9.90), + ( 'inf', 80100.00, 11.80), + ), + }, + 'C': { + 'weekly': ( + ( 385, 0.00, 1.50), + ( 769, 5.77, 2.30), + ( 962, 14.62, 2.80), + ( 1154, 20.00, 3.50), + ( 2885, 26.73, 5.60), + ( 9615, 123.65, 6.60), + (19231, 567.88, 9.90), + ('inf', 1519.81, 11.80), + ), + 'bi-weekly': ( + ( 769, 0.00, 1.50), + ( 1538, 11.54, 2.30), + ( 1923, 29.23, 2.80), + ( 2308, 40.00, 3.50), + ( 5769, 53.46, 5.60), + ( 19231, 247.31, 6.60), + ( 38462, 1135.77, 9.90), + ( 'inf', 3039.62, 11.80), + ), + 'semi-monthly': ( + ( 833, 0.00, 1.50), + ( 1667, 12.50, 2.30), + ( 2083, 31.67, 2.80), + ( 2500, 43.33, 3.50), + ( 6250, 57.92, 5.60), + ( 20833, 267.92, 6.60), + ( 41667, 1230.42, 9.90), + ( 'inf', 3292.92, 11.80), + ), + 'monthly': ( + ( 1667, 0.00, 1.50), + ( 3333, 25.00, 2.30), + ( 4167, 63.33, 2.80), + ( 5000, 86.67, 3.50), + ( 12500, 115.83, 5.60), + ( 41667, 535.85, 6.60), + ( 83333, 2460.83, 9.90), + ( 'inf', 6585.83, 11.80), + ), + 'quarterly': ( + ( 5000, 0.00, 1.50), + ( 10000, 75.00, 2.30), + ( 12500, 190.00, 2.80), + ( 15000, 260.00, 3.50), + ( 37500, 347.50, 5.60), + ( 125000, 1607.50, 6.60), + ( 250000, 7382.50, 9.90), + ( 'inf', 19757.50, 11.80), + ), + 'semi-annual': ( + ( 10000, 0.00, 1.50), + ( 20000, 150.00, 2.30), + ( 25000, 380.00, 2.80), + ( 30000, 520.00, 3.50), + ( 75000, 695.00, 5.60), + ( 250000, 3215.00, 6.60), + ( 500000, 14765.00, 9.90), + ( 'inf', 39515.00, 11.80), + ), + 'annual': ( + ( 20000, 0.00, 1.50), + ( 40000, 300.00, 2.30), + ( 50000, 760.00, 2.80), + ( 60000, 1040.00, 3.50), + ( 150000, 1390.00, 5.60), + ( 500000, 6430.00, 6.60), + (1000000, 29530.00, 9.90), + ( 'inf', 79030.00, 11.80), + ), + }, + 'D': { + 'weekly': ( + ( 385, 0.00, 1.50), + ( 769, 5.77, 2.70), + ( 962, 16.15, 3.40), + ( 1154, 22.69, 4.30), + ( 2885, 30.96, 5.60), + ( 9615, 127.88, 6.50), + ( 19231, 565.38, 9.90), + ( 'inf', 1517.31, 11.80), + ), + 'bi-weekly': ( + ( 769, 0.00, 1.50), + ( 1538, 11.54, 2.70), + ( 1923, 32.31, 3.40), + ( 2308, 45.38, 4.30), + ( 5769, 61.92, 5.60), + ( 19231, 255.77, 6.50), + ( 38462, 1130.77, 9.90), + ( 'inf', 3034.62, 11.80), + ), + 'semi-monthly': ( + ( 833, 0.00, 1.50), + ( 1667, 12.50, 2.70), + ( 2083, 35.00, 3.40), + ( 2500, 49.17, 4.30), + ( 6250, 67.08, 5.60), + ( 20833, 277.08, 6.50), + ( 41667, 1225.00, 9.90), + ( 'inf', 3287.50, 11.80), + ), + 'monthly': ( + ( 1667, 0.00, 1.50), + ( 3333, 25.00, 2.70), + ( 4167, 70.00, 3.40), + ( 5000, 98.33, 4.00), + ( 12500, 134.17, 5.60), + ( 41667, 554.17, 6.50), + ( 83333, 2450.00, 9.90), + ( 'inf', 6575.00, 11.80), + ), + 'quarterly': ( + ( 5000, 0.00, 1.50), + ( 10000, 75.00, 2.07), + ( 12500, 210.00, 3.40), + ( 15000, 295.00, 4.30), + ( 37500, 402.50, 5.60), + ( 125000, 1662.50, 6.50), + ( 250000, 7350.00, 9.90), + ( 'inf', 19725.00, 11.80), + ), + 'semi-annual': ( + ( 10000, 0.00, 1.50), + ( 20000, 150.00, 2.70), + ( 25000, 420.00, 3.40), + ( 30000, 590.00, 4.30), + ( 75000, 805.00, 5.60), + ( 250000, 3325.00, 6.50), + ( 500000, 14700.00, 9.90), + ( 'inf', 39450.00, 11.80), + ), + 'annual': ( + ( 20000, 0.00, 1.50), + ( 40000, 300.00, 2.70), + ( 50000, 840.00, 3.40), + ( 60000, 1180.00, 4.30), + ( 150000, 1610.00, 5.60), + ( 250000, 6650.00, 6.50), + (1000000, 29400.00, 9.90), + ( 'inf', 78900.00, 11.80), + ), + }, + 'E': { + 'weekly': ( + ( 385, 0.00, 1.50), + ( 673, 5.77, 2.00), + ( 1923, 11.54, 5.80), + ( 9615, 84.04, 6.50), + ( 19231, 584.04, 9.90), + ( 'inf', 1535.96, 11.80), + ), + 'bi-weekly': ( + ( 769, 0.00, 1.50), + ( 1346, 12.00, 2.00), + ( 3846, 23.00, 5.80), + ( 19231, 168.00, 6.50), + ( 38462, 1168.00, 9.90), + ( 'inf', 3072.00, 11.80), + ), + 'semi-monthly': ( + ( 833, 0.00, 1.50), + ( 1458, 13.00, 2.00), + ( 4167, 25.00, 5.80), + ( 20833, 182.00, 6.50), + ( 41667, 1265.00, 9.90), + ( 'inf', 3328.00, 11.80), + ), + 'monthly': ( + ( 1667, 0.00, 1.50), + ( 2916, 25.00, 2.00), + ( 8333, 50.00, 5.80), + ( 41667, 364.00, 6.50), + ( 83333, 2531.00, 9.90), + ( 'inf', 6656.00, 11.80), + ), + 'quarterly': ( + ( 5000, 0.00, 1.50), + ( 8750, 75.00, 2.00), + ( 25000, 150.00, 5.80), + ( 125000, 1092.50, 6.50), + ( 250000, 7592.50, 9.90), + ( 'inf', 19967.50, 11.80), + ), + 'semi-annual': ( + ( 10000, 0.00, 1.50), + ( 17500, 150.00, 2.00), + ( 50000, 300.00, 5.80), + ( 250000, 2185.00, 6.50), + ( 500000, 15185.00, 9.90), + ( 'inf', 39935.00, 11.80), + ), + 'annual': ( + ( 20000, 0.00, 1.50), + ( 35000, 300.00, 2.00), + ( 100000, 600.00, 5.80), + ( 500000, 4370.00, 6.50), + (1000000, 30370.00, 9.90), + ( 'inf', 79870.00, 11.80), + ), + }, + } + + + @@ -874,21 +854,8 @@ - - { - 'weekly': 19.20, - 'bi-weekly': 38.40, - 'semi-monthly': 41.60, - 'monthly': 83.30, - 'quarterly': 250.00, - 'semi-annual': 500.00, - 'annual': 1000.00, - 'daily or miscellaneous': 2.70, - } - - - + { 'weekly': 19.20, diff --git a/l10n_us_hr_payroll/data/state/nm_new_mexico.xml b/l10n_us_hr_payroll/data/state/nm_new_mexico.xml index 2c4249a0..970b1f48 100644 --- a/l10n_us_hr_payroll/data/state/nm_new_mexico.xml +++ b/l10n_us_hr_payroll/data/state/nm_new_mexico.xml @@ -12,6 +12,12 @@ + + + 27000.0 + + + @@ -21,6 +27,7 @@ + 1.0 @@ -34,7 +41,7 @@ - + { 'single': { @@ -257,6 +264,272 @@ + + + + { + 'single': { + 'weekly': ( + ( 121, 0.00, 0.0), + ( 226, 0.00, 1.7), + ( 332, 1.80, 3.2), + ( 428, 5.18, 4.7), + ( 621, 9.70, 4.9), + ( 928, 19.13, 4.9), + ( 1371, 34.20, 4.9), + ( 2525, 55.88, 4.9), + ( 4159, 112.41, 4.9), + ('inf', 192.51, 5.9), + ), + 'bi-weekly': ( + ( 241, 0.00, 0.0), + ( 453, 0.00, 1.7), + ( 664, 3.60, 3.2), + ( 857, 10.37, 4.7), + ( 1241, 19.40, 4.9), + ( 1857, 38.25, 4.9), + ( 2741, 68.40, 4.9), + ( 5049, 111.75, 4.9), + ( 8318, 224.83, 4.9), + ('inf', 385.02, 5.9), + ), + 'semi-monthly': ( + ( 261, 0.00, 0.0), + ( 491, 0.00, 1.7), + ( 720, 3.90, 3.2), + ( 928, 11.23, 4.7), + ( 1345, 21.02, 4.9), + ( 2011, 41.44, 4.9), + ( 2970, 74.10, 4.9), + ( 2470, 121.06, 4.9), + ( 9011, 243.56, 4.9), + ('inf', 417.10, 5.9), + ), + 'monthly': ( + ( 523, 0.00, 0.0), + ( 981, 0.00, 1.7), + ( 1440, 7.79, 3.2), + ( 1856, 22.46, 4.7), + ( 2690, 42.04, 4.9), + ( 4023, 82.88, 4.9), + ( 5940, 148.21, 4.9), + (10940, 242.13, 4.9), + (18023, 487.13, 4.9), + ('inf', 834.21, 5.9), + ), + 'quarterly': ( + ( 1569, 0.00, 0.0), + ( 2944, 0.00, 1.7), + ( 4319, 23.38, 3.2), + ( 5569, 67.38, 4.7), + ( 8069, 126.13, 4.9), + ( 12069, 248.63, 4.9), + ( 17819, 444.63, 4.9), + ( 32819, 726.38, 4.9), + ( 54069, 1461.38, 4.9), + ( 'inf', 2502.63, 5.9), + ), + 'semi-annual': ( + ( 3138, 0.00, 0.0), + ( 5888, 0.00, 1.7), + ( 8638, 46.75, 3.2), + ( 11138, 134.75, 4.7), + ( 16138, 252.25, 4.9), + ( 24138, 497.25, 4.9), + ( 35638, 889.25, 4.9), + ( 65638, 1452.75, 4.9), + (108138, 2922.75, 4.9), + ('inf' , 5005.25, 5.9), + ), + 'annually': ( + ( 6275, 0.00, 0.0), + ( 11775, 0.00, 1.7), + ( 17275, 93.50, 3.2), + ( 22275, 269.50, 4.7), + ( 32275, 504.50, 4.9), + ( 48275, 994.50, 4.9), + ( 71275, 1778.50, 4.9), + (131275, 2905.50, 4.9), + (216275, 5845.50, 4.9), + ( 'inf', 10010.50, 5.9), + ), + }, + 'married': { + 'weekly': ( + ( 241, 0.00, 0.0), + ( 395, 0.00, 1.7), + ( 549, 2.62, 3.2), + ( 703, 7.54, 4.7), + ( 1011, 14.77, 4.9), + ( 1472, 29.85, 4.9), + ( 2164, 52.46, 4.9), + ( 4088, 86.38, 4.9), + ( 6299, 180.62, 4.9), + ('inf', 288.98, 5.9), + ), + 'bi-weekly': ( + ( 483, 0.00, 0.0), + ( 790, 0.00, 1.7), + ( 1089, 5.23, 3.2), + ( 1406, 15.08, 4.7), + ( 2021, 29.54, 4.9), + ( 2944, 59.69, 4.9), + ( 4329, 104.92, 4.9), + ( 8175, 172.77, 4.9), + (12598, 361.23, 4.9), + ('inf', 577.96, 5.9), + ), + 'semi-monthly': ( + ( 523, 0.00, 0.0), + ( 856, 0.00, 1.7), + ( 1190, 5.67, 3.2), + ( 1523, 16.33, 4.7), + ( 2190, 32.00, 4.9), + ( 3190, 64.67, 4.9), + ( 4690, 113.67, 4.9), + ( 8856, 187.17, 4.9), + (13648, 391.33, 4.9), + ('inf', 626.13, 5.9), + ), + 'monthly': ( + ( 1046, 0.00, 0.0), + ( 1713, 0.00, 1.7), + ( 2379, 11.33, 3.2), + ( 3046, 32.67, 4.7), + ( 4379, 64.00, 4.9), + ( 6379, 129.33, 4.9), + ( 9379, 227.33, 4.9), + (17713, 374.33, 4.9), + (27296, 782.67, 4.9), + ('inf', 1252.25, 5.9), + ), + 'quarterly': ( + ( 3138, 0.00, 0.0), + ( 5138, 0.00, 1.7), + ( 7138, 34.00, 3.2), + ( 9138, 98.00, 4.7), + (13138, 192.00, 4.9), + (19138, 388.00, 4.9), + (28138, 682.00, 4.9), + (53138, 1123.00, 4.9), + (81888, 2348.00, 4.9), + ('inf', 3756.75, 5.9), + ), + 'semi-annual': ( + ( 6275, 0.00, 0.0), + ( 10275, 0.00, 1.7), + ( 14275, 68.00, 3.2), + ( 18275, 196.00, 4.7), + ( 26275, 384.00, 4.9), + ( 38275, 776.00, 4.9), + ( 56275, 1364.00, 4.9), + (106275, 2246.00, 4.9), + (163775, 4696.00, 4.9), + ( 'inf', 7513.50, 5.9), + ), + 'annually': ( + ( 12450, 0.00, 0.0), + ( 20450, 0.00, 1.7), + ( 28450, 136.00, 3.2), + ( 36450, 392.00, 4.7), + ( 52450, 768.00, 4.9), + ( 76450, 1552.00, 4.9), + (112450, 2728.00, 4.9), + (212550, 4492.00, 4.9), + (327550, 9392.00, 4.9), + ( 'inf', 15027.00, 5.9), + ), + }, + 'married_as_single': { + 'weekly': ( + ( 181, 0.00, 0.0), + ( 335, 0.00, 1.7), + ( 488, 2.62, 3.2), + ( 642, 7.54, 4.7), + ( 950, 14.77, 4.9), + ( 1412, 29.85, 4.9), + ( 2104, 52.46, 4.9), + ( 2027, 86.38, 4.9), + ( 6238, 180.62, 4.9), + ('inf', 288.98, 5.9), + ), + 'bi-weekly': ( + ( 362, 0.00, 0.0), + ( 669, 0.00, 1.7), + ( 977, 5.23, 3.2), + ( 1285, 15.08, 4.7), + ( 1900, 29.54, 4.9), + ( 2823, 59.69, 4.9), + ( 4208, 104.92, 4.9), + ( 8054, 172.77, 4.9), + (12477, 361.23, 4.9), + ('inf', 577.96, 5.9), + ), + 'semi-monthly': ( + ( 392, 0.00, 0.0), + ( 725, 0.00, 1.7), + ( 1058, 5.67, 3.2), + ( 1392, 16.33, 4.7), + ( 2058, 32.00, 4.9), + ( 3058, 64.67, 4.9), + ( 4558, 113.67, 4.9), + ( 8725, 187.17, 4.9), + (13517, 391.33, 4.9), + ('inf', 626.13, 5.9), + ), + 'monthly': ( + ( 783, 0.00, 0.0), + ( 1450, 0.00, 1.7), + ( 2117, 11.33, 3.2), + ( 2783, 32.67, 4.7), + ( 4117, 64.00, 4.9), + ( 6117, 129.33, 4.9), + ( 9117, 227.33, 4.9), + (17450, 374.33, 4.9), + (27033, 782.67, 4.9), + ('inf', 1252.25, 5.9), + ), + 'quarterly': ( + ( 2350, 0.00, 0.0), + ( 4350, 0.00, 1.7), + ( 6350, 34.00, 3.2), + ( 8350, 98.00, 4.7), + ( 12350, 192.00, 4.9), + ( 18350, 388.00, 4.9), + ( 27350, 682.00, 4.9), + ( 52350, 1123.00, 4.9), + ( 81100, 2348.00, 4.9), + ( 'inf', 3756.75, 5.9), + ), + 'semi-annual': ( + ( 4700, 0.00, 0.0), + ( 8700, 0.00, 1.7), + ( 12700, 68.00, 3.2), + ( 16700, 196.00, 4.7), + ( 24700, 384.00, 4.9), + ( 36700, 776.00, 4.9), + ( 54700, 1364.00, 4.9), + (104700, 2246.00, 4.9), + (162200, 4696.00, 4.9), + ( 'inf', 7513.50, 5.9), + ), + 'annually': ( + ( 9400, 0.00, 0.0), + ( 17400, 0.00, 1.7), + ( 25400, 136.00, 3.2), + ( 33400, 392.00, 4.7), + ( 49400, 768.00, 4.9), + ( 73400, 1552.00, 4.9), + (109400, 2728.00, 4.9), + (209400, 4492.00, 4.9), + (324400, 9392.00, 4.9), + ( 'inf', 15027.00, 5.9), + ), + } + } + + + diff --git a/l10n_us_hr_payroll/data/state/nv_nevada.xml b/l10n_us_hr_payroll/data/state/nv_nevada.xml index 46e3c2d5..b5b85f1e 100644 --- a/l10n_us_hr_payroll/data/state/nv_nevada.xml +++ b/l10n_us_hr_payroll/data/state/nv_nevada.xml @@ -12,6 +12,11 @@ + + 33400.00 + + + @@ -21,6 +26,7 @@ + 2.95 diff --git a/l10n_us_hr_payroll/data/state/ny_new_york.xml b/l10n_us_hr_payroll/data/state/ny_new_york.xml index a6f17a70..4bb0ac36 100644 --- a/l10n_us_hr_payroll/data/state/ny_new_york.xml +++ b/l10n_us_hr_payroll/data/state/ny_new_york.xml @@ -1,22 +1,23 @@ + US NY New York SUTA Wage Base us_ny_suta_wage_base - - 11400.0 - - - 11600.0 + + 11800.0 + + + @@ -25,6 +26,8 @@ us_ny_suta_rate + + 2.5 @@ -80,26 +83,6 @@ - - { - 'single': { - 'weekly': ((163, 0.0400, 0.0), (225, 0.0450, 6.54), (267, 0.0525, 9.31), (412, 0.0590, 11.54), (1551, 0.0633, 20.04), (1862, 0.0657, 92.17), (2070, 0.0758, 112.58), (3032, 0.0808, 128.38), (4142, 0.0707, 206.08), (5104, 0.0856, 284.60), (20722, 0.0735, 366.90), (21684, 0.5208, 1514.85), ('inf', 0.0962, 2015.62)), - 'bi-weekly': ((327, 0.0400, 0.0), (450, 0.0450, 13.08), (535, 0.0525, 18.62), (823, 0.0590, 23.08), (3102, 0.0633, 40.08), (3723, 0.0657, 184.35), (4140, 0.0758, 225.15), (6063, 0.0808, 256.77), (8285, 0.0707, 412.15), (10208, 0.0856, 569.19), (41444, 0.0735, 733.81), (43367, 0.5208, 3029.69), ('inf', 0.0962, 4021.23)), - 'semi-monthly': ((354, 0.0400, 0.0), (488, 0.0450, 14.17), (579, 0.0525, 20.17), (892, 0.0590, 25.00), (3360, 0.0633, 43.42), (4033, 0.0657, 199.71), (4485, 0.0758, 243.92), (6569, 0.0808, 278.17), (8975, 0.0707, 446.50), (11058, 0.0856, 616.63), (44898, 0.0735, 794.96), (46981, 0.5208, 3282.17), ('inf', 0.0962, 4367.17)), - 'monthly': ((708, 0.0400, 0.0), (975, 0.0450, 28.33), (1158, 0.0525, 40.33), (1783, 0.0590, 50.00), (6721, 0.0633, 86.83), (8067, 0.0657, 399.42), (8971, 0.0758, 487.83), (13138, 0.0808, 556.33), (17950, 0.0707, 893.00), (22117, 0.0856, 1233.25), (89796, 0.0735, 1589.92), (93963, 0.5208, 6564.33), ('inf', 0.0962, 8734.33)), - 'annually': ((8500, 0.0400, 0.0), (11700, 0.0450, 340.00), (13900, 0.0525, 484.00), (21400, 0.0590, 600.00), (80650, 0.0633, 1042.00), (96800, 0.0657, 4793.00), (107650, 0.0758, 5854.00), (157650, 0.0808, 6676.00), (215400, 0.0707, 10716.00), (265400, 0.0856, 14799.00), (1077550, 0.0735, 19079.00), (1127550, 0.5208, 78772.00), ('inf', 0.0962, 104812.00)), - }, - 'married': { - 'weekly': ((163, 0.0400, 0.0), (225, 0.0450, 6.54), (267, 0.0525, 9.31), (412, 0.0590, 11.54), (1551, 0.0633, 20.04), (1862, 0.0657, 92.17), (2070, 0.0783, 112.58), (3032, 0.0833, 128.90), (4068, 0.0785, 209.00), (6215, 0.0707, 290.37), (7177, 0.0916, 442.17), (20722, 0.0735, 530.25), (41449, 0.0765, 1525.83), (42411, 0.9454, 3111.42), ('inf', 0.0962, 4020.46)), - 'bi-weekly': ((327, 0.0400, 0.0), (450, 0.0450, 13.08), (535, 0.0525, 18.62), (823, 0.0590, 23.08), (3102, 0.0633, 40.08), (3723, 0.0657, 184.35), (4140, 0.0783, 225.15), (6063, 0.0833, 257.81), (8137, 0.0785, 418.00), (12431, 0.0707, 580.73), (14354, 0.0916, 884.35), (41444, 0.0735, 1060.50), (82898, 0.0765, 3051.65), (84821, 0.9454, 6222.85), ('inf', 0.0962, 8040.92)), - 'semi-monthly': ((354, 0.0400, 0.0), (488, 0.0450, 14.17), (579, 0.0525, 20.17), (892, 0.0590, 25.00), (3360, 0.0633, 43.42), (4033, 0.0657, 199.71), (4485, 0.0783, 243.92), (6569, 0.0833, 279.29), (8815, 0.0785, 452.83), (13476, 0.0707, 629.13), (15550, 0.0916, 958.04), (44898, 0.0735, 1148.88), (89806, 0.0765, 3305.96), (91890, 0.9454, 6741.42), ('inf', 0.0962, 8711.00)), - 'monthly': ((708, 0.0400, 0.0), (975, 0.0450, 28.33), (1158, 0.0525, 40.33), (1783, 0.0590, 50.00), (6721, 0.0633, 86.83), (8067, 0.0657, 399.42), (8971, 0.0783, 487.83), (13138, 0.0833, 558.58), (17629, 0.0785, 905.67), (26933, 0.0707, 1258.25), (31100, 0.0916, 1916.08), (89796, 0.0735, 2297.75), (179613, 0.0765, 6611.92), (183779, 0.9454, 13482.83), ('inf', 0.0962, 17422.00)), - 'annually': ((8500, 0.0400, 0.0), (11700, 0.0450, 340.00), (13900, 0.0525, 484.00), (21400, 0.0590, 600.00), (80650, 0.0633, 1042.00), (96800, 0.0657, 4793.00), (107650, 0.0783, 5854.00), (157650, 0.0833, 6703.00), (211550, 0.0785, 10868.00), (323200, 0.0707, 15099.00), (373200, 0.0916, 22993.00), (1077550, 0.0735, 27573.00), (2155350, 0.0765, 79343.00), (2205350, 0.9454, 161794.00), ('inf', 0.0962, 209064.00)), - } - } - - - { 'single': { @@ -270,6 +253,177 @@ + + + { + 'single': { + 'weekly': ( + ( 163, 0.0400, 0.00), + ( 225, 0.0450, 6.54), + ( 267, 0.0525, 9.31), + ( 412, 0.0590, 11.54), + ( 1551, 0.0597, 20.04), + ( 1862, 0.0633, 88.06), + ( 2070, 0.0738, 107.73), + ( 3032, 0.0788, 123.12), + ( 4142, 0.0683, 198.88), + ( 5104, 0.0959, 274.75), + (20722, 0.0735, 366.96), + (21684, 0.5208, 1514.90), + ('inf', 0.0962, 2015.67), + ), + 'bi-weekly': ( + ( 327, 0.0400, 0.00), + ( 450, 0.0450, 13.08), + ( 535, 0.0525, 18.62), + ( 823, 0.0590, 23.08), + ( 3102, 0.0597, 40.08), + ( 3723, 0.0633, 176.12), + ( 4140, 0.0738, 215.46), + ( 6063, 0.0788, 246.23), + ( 8285, 0.0683, 397.77), + (10208, 0.0959, 549.50), + (41444, 0.0735, 733.92), + (43367, 0.5208, 3029.81), + ('inf', 0.0962, 4031.45), + ), + 'semi-monthly': ( + ( 354, 0.0400, 0.00), + ( 488, 0.0450, 14.17), + ( 579, 0.0525, 20.17), + ( 892, 0.0590, 25.00), + ( 3360, 0.0597, 43.42), + ( 4033, 0.0633, 190.79), + ( 4485, 0.0738, 233.42), + ( 6569, 0.0788, 266.75), + ( 8975, 0.0683, 430.92), + (11058, 0.0959, 595.29), + (44898, 0.0735, 795.08), + (46981, 0.5208, 3282.29), + ('inf', 0.0962, 4367.29), + ), + 'monthly': ( + ( 708, 0.0400, 0.00), + ( 975, 0.0450, 28.33), + ( 1158, 0.0525, 40.33), + ( 1783, 0.0590, 50.00), + ( 6721, 0.0597, 86.83), + ( 8067, 0.0633, 381.58), + ( 8971, 0.0738, 466.83), + (13138, 0.0788, 533.50), + (17950, 0.0683, 861.83), + (22117, 0.0959, 1190.58), + (89796, 0.0735, 1590.17), + (93963, 0.5208, 6564.58), + ('inf', 0.0962, 8734.58), + ), + 'annually': ( + ( 8500, 0.0400, 0.00), + ( 11700, 0.0450, 340.00), + ( 13900, 0.0525, 484.00), + ( 21400, 0.0590, 600.00), + ( 80650, 0.0597, 1042.00), + ( 96800, 0.0633, 4579.00), + ( 107650, 0.0738, 5602.00), + ( 157650, 0.0788, 6402.00), + ( 215400, 0.0683, 10342.00), + ( 265400, 0.0959, 14287.00), + (1077550, 0.0735, 19082.00), + (1127550, 0.5208, 78775.00), + ( 'inf', 0.0962, 104815.00), + ), + }, + 'married': { + 'weekly': ( + ( 163, 0.0400, 0.00), + ( 225, 0.0450, 6.54), + ( 267, 0.0525, 9.31), + ( 412, 0.0590, 11.54), + ( 1551, 0.0597, 20.04), + ( 1862, 0.0633, 88.06), + ( 2070, 0.0728, 107.73), + ( 3032, 0.0778, 122.90), + ( 4068, 0.0799, 197.71), + ( 6215, 0.0683, 280.54), + ( 7177, 0.1071, 427.19), + (20722, 0.0735, 530.17), + (41449, 0.0765, 1525.73), + (42411, 0.9454, 3111.35), + ('inf', 0.0962, 4020.38), + ), + 'bi-weekly': ( + ( 327, 0.0400, 0.00), + ( 450, 0.0450, 13.08), + ( 535, 0.0525, 18.62), + ( 823, 0.0590, 23.08), + ( 3102, 0.0597, 40.08), + ( 3723, 0.0633, 176.12), + ( 4140, 0.0728, 215.46), + ( 6063, 0.0778, 245.81), + ( 8137, 0.0799, 395.42), + (12431, 0.0683, 561.08), + (14354, 0.1071, 854.38), + (41444, 0.0735, 1060.35), + (82898, 0.0765, 3051.46), + (84821, 0.9454, 6222.69), + ('inf', 0.0962, 8040.77), + ), + 'semi-monthly': ( + ( 354, 0.0400, 0.00), + ( 488, 0.0450, 14.17), + ( 579, 0.0525, 20.17), + ( 892, 0.0590, 25.00), + ( 3360, 0.0597, 43.42), + ( 4033, 0.0633, 190.79), + ( 4485, 0.0728, 233.42), + ( 6569, 0.0778, 266.29), + ( 8815, 0.0799, 428.38), + (13467, 0.0683, 607.83), + (15550, 0.1071, 925.58), + (44898, 0.0735, 1148.71), + (89806, 0.0765, 3305.75), + (91890, 0.9454, 6741.25), + ('inf', 0.0962, 8710.83), + ), + 'monthly': ( + ( 708, 0.0400, 0.00), + ( 975, 0.0450, 28.33), + ( 1158, 0.0525, 40.33), + ( 1783, 0.0590, 50.00), + ( 6721, 0.0597, 86.83), + ( 8067, 0.0633, 381.58), + ( 8971, 0.0728, 466.83), + ( 13138, 0.0778, 532.58), + ( 17629, 0.0799, 856.75), + ( 26933, 0.0683, 1215.67), + ( 31100, 0.1071, 1851.17), + ( 89796, 0.0735, 2297.42), + (179613, 0.0765, 6611.50), + (183779, 0.9454, 13482.50), + ( 'inf', 0.0962, 17421.67), + ), + 'annually': ( + ( 8500, 0.0400, 0.00), + ( 11700, 0.0450, 340.00), + ( 13900, 0.0525, 484.00), + ( 21400, 0.0590, 600.00), + ( 80650, 0.0597, 1042.00), + ( 96800, 0.0633, 4579.00), + ( 107650, 0.0728, 5602.00), + ( 157650, 0.0778, 6391.00), + ( 211550, 0.0799, 10281.00), + ( 323200, 0.0683, 14588.00), + ( 373200, 0.1071, 22214.00), + (1077550, 0.0735, 27569.00), + (2155350, 0.0765, 79338.00), + (2205350, 0.9454, 161790.00), + ( 'inf', 0.0962, 209060.00), + ), + } + } + + + @@ -278,17 +432,6 @@ - - { - 'weekly': (142.30, 152.90, 19.25), - 'bi-weekly': (284.60, 305.80, 38.50), - 'semi-monthly': (308.35, 331.25, 41.65), - 'monthly': (616.70, 662.50, 83.30), - 'annual': (7400, 7950, 1000), - } - - - { 'weekly': (142.30, 152.90, 19.25), @@ -300,6 +443,17 @@ + + { + 'weekly': (142.30, 152.90, 19.25), + 'bi-weekly': (284.60, 305.80, 38.50), + 'semi-monthly': (308.35, 331.25, 41.65), + 'monthly': (616.70, 662.50, 83.30), + 'annual': (7400, 7950, 1000), + } + + + @@ -308,26 +462,6 @@ - - { - 'single': { - 'weekly': (142.30, 161.55, 180.80, 200.05, 219.30, 238.55, 257.80, 277.05, 296.30, 315.55, 334.80), - 'bi-weekly': (284.60, 323.10, 361.60, 400.10, 438.60, 477.10, 515.60, 544.10, 592.60, 631.10, 669.60), - 'semi-monthly': (308.35, 350.0, 391.65, 433.30, 474.95, 516.60, 558.25, 599.90, 641.55, 683.20, 724.85), - 'monthly': (616.70, 700, 783.30, 866.60, 949.90, 1033.20, 1116.50, 1199.80, 1283.10, 1366.40, 1449.70), - 'annually': (7400, 8400, 9400, 10400, 11400, 12400, 13400, 14400, 15400, 16400, 17400), - }, - 'married': { - 'weekly': (152.90, 172.15, 191.40, 210.65, 229.90, 249.15, 268.40, 287.65, 306.90, 326.15, 345.40), - 'bi-weekly': (305.80, 344.30, 382.80, 421.30, 459.80, 498.30, 536.80, 575.30, 613.80, 652.30, 690.80), - 'semi-monthly': (331.25, 372.90, 414.55, 456.20, 497.85, 539.50, 581.15, 622.80, 664.45, 706.10, 747.75), - 'monthly': (662.50, 745.80, 829.10, 912.40, 995.70, 1079.00, 1162.30, 1245.60, 1328.90, 1412.20, 1495.50), - 'annually': (7950, 8950, 9950, 10950, 11950, 12950, 13950, 14950, 15950, 16950, 17950), - }, - } - - - { 'single': { @@ -348,6 +482,26 @@ + + { + 'single': { + 'weekly': (142.30, 161.55, 180.80, 200.05, 219.30, 238.55, 257.80, 277.05, 296.30, 315.55, 334.80), + 'bi-weekly': (284.60, 323.10, 361.60, 400.10, 438.60, 477.10, 515.60, 544.10, 592.60, 631.10, 669.60), + 'semi-monthly': (308.35, 350.0, 391.65, 433.30, 474.95, 516.60, 558.25, 599.90, 641.55, 683.20, 724.85), + 'monthly': (616.70, 700, 783.30, 866.60, 949.90, 1033.20, 1116.50, 1199.80, 1283.10, 1366.40, 1449.70), + 'annually': (7400, 8400, 9400, 10400, 11400, 12400, 13400, 14400, 15400, 16400, 17400), + }, + 'married': { + 'weekly': (152.90, 172.15, 191.40, 210.65, 229.90, 249.15, 268.40, 287.65, 306.90, 326.15, 345.40), + 'bi-weekly': (305.80, 344.30, 382.80, 421.30, 459.80, 498.30, 536.80, 575.30, 613.80, 652.30, 690.80), + 'semi-monthly': (331.25, 372.90, 414.55, 456.20, 497.85, 539.50, 581.15, 622.80, 664.45, 706.10, 747.75), + 'monthly': (662.50, 745.80, 829.10, 912.40, 995.70, 1079.00, 1162.30, 1245.60, 1328.90, 1412.20, 1495.50), + 'annually': (7950, 8950, 9950, 10950, 11950, 12950, 13950, 14950, 15950, 16950, 17950), + }, + } + + + diff --git a/l10n_us_hr_payroll/data/state/oh_ohio.xml b/l10n_us_hr_payroll/data/state/oh_ohio.xml index e6db8eb8..1d3344a0 100644 --- a/l10n_us_hr_payroll/data/state/oh_ohio.xml +++ b/l10n_us_hr_payroll/data/state/oh_ohio.xml @@ -7,11 +7,6 @@ - - 9500.00 - - - 9000.00 @@ -20,17 +15,13 @@ + US OH Ohio SUTA Rate us_oh_suta_rate - - 2.7 - - - 2.7 @@ -38,28 +29,14 @@ + + US OH Ohio SIT Rate Table us_oh_sit_rate - - - - [ - ( 5000.00, 0.0, 0.005), - ( 10000.00, 25.0, 0.010), - ( 15000.00, 75.0, 0.020), - ( 20000.00, 175.0, 0.025), - ( 40000.00, 300.0, 0.030), - ( 80000.00, 900.0, 0.035), - ( 100000.00, 2300.0, 0.040), - ( 'inf', 3100.0, 0.050), - ] - - - @@ -84,11 +61,6 @@ - - 650.0 - - - 650.0 @@ -102,11 +74,6 @@ - - 1.075 - - - 1.032 diff --git a/l10n_us_hr_payroll/data/state/ok_oklahoma.xml b/l10n_us_hr_payroll/data/state/ok_oklahoma.xml index 04aa8380..8968ea39 100644 --- a/l10n_us_hr_payroll/data/state/ok_oklahoma.xml +++ b/l10n_us_hr_payroll/data/state/ok_oklahoma.xml @@ -12,6 +12,12 @@ + + + 24000.0 + + + @@ -26,7 +32,14 @@ + + + 1.0 + + + + US OK Oklahoma Allowances Rate @@ -34,6 +47,7 @@ + { 'weekly' : 19.23, @@ -48,13 +62,15 @@ - + US OK Oklahoma SIT Tax Rate us_ok_sit_tax_rate + + { 'single': { diff --git a/l10n_us_hr_payroll/data/state/pa_pennsylvania.xml b/l10n_us_hr_payroll/data/state/pa_pennsylvania.xml index f46a92b4..c8002192 100644 --- a/l10n_us_hr_payroll/data/state/pa_pennsylvania.xml +++ b/l10n_us_hr_payroll/data/state/pa_pennsylvania.xml @@ -7,11 +7,7 @@ - - 10000.00 - - - + 10000.00 @@ -26,11 +22,7 @@ - - 3.6890 - - - + 3.6890 @@ -44,11 +36,7 @@ - - 0.06 - - - + 0.06 @@ -62,11 +50,7 @@ - - 3.07 - - - + 3.07 diff --git a/l10n_us_hr_payroll/data/state/ri_rhode_island.xml b/l10n_us_hr_payroll/data/state/ri_rhode_island.xml index 155a2c86..5c9e05c8 100644 --- a/l10n_us_hr_payroll/data/state/ri_rhode_island.xml +++ b/l10n_us_hr_payroll/data/state/ri_rhode_island.xml @@ -7,6 +7,7 @@ + 24000.0 @@ -21,12 +22,14 @@ + 1.06 + US RI Rhode Island Exemption Rate @@ -47,6 +50,20 @@ + + + { + 'weekly' : (( 0.00, 19.23), ( 4514.42, 0.00)), + 'bi-weekly' : (( 0.00, 38.46), ( 9028.85, 0.00)), + 'semi-monthly': (( 0.00, 41.67), ( 9781.25, 0.00)), + 'monthly' : (( 0.00, 83.33), ( 19562.50, 0.00)), + 'quarterly' : (( 0.00, 250.00), ( 58687.50, 0.00)), + 'semi-annually': (( 0.00, 500.00), ( 117375.00, 0.00)), + 'annually': (( 0.00, 1000.0), ( 234750.00, 0.00)), + } + + + @@ -96,6 +113,48 @@ + + + { + 'weekly': ( + ( 1273, 0.00, 3.75), + ( 2895, 47.74, 4.75), + ('inf', 124.79, 5.99), + ), + 'bi-weekly': ( + ( 2546, 0.00, 3.75), + ( 5790, 95.48, 4.75), + ('inf', 249.57, 5.99), + ), + 'semi-monthly': ( + ( 2758, 0.00, 3.75), + ( 6273, 103.43, 4.75), + ('inf', 270.39, 5.99), + ), + 'monthly': ( + ( 5517, 0.00, 3.75), + (12546, 206.89, 4.75), + ('inf', 540.77, 5.99), + ), + 'quarterly': ( + (16550, 0.00, 3.75), + (37638, 620.63, 4.75), + ('inf', 1622.31, 5.99), + ), + 'semi-annually': ( + (33100, 0.00, 3.75), + (75275, 1241.25, 4.75), + ('inf', 3244.56, 5.99), + ), + 'annually': ( + ( 66200, 0.00, 3.75), + (150550, 2482.50, 4.75), + ( 'inf', 6489.13, 5.99), + ), + } + + + diff --git a/l10n_us_hr_payroll/data/state/sc_south_carolina.xml b/l10n_us_hr_payroll/data/state/sc_south_carolina.xml index b2a46192..04a10d70 100644 --- a/l10n_us_hr_payroll/data/state/sc_south_carolina.xml +++ b/l10n_us_hr_payroll/data/state/sc_south_carolina.xml @@ -7,11 +7,7 @@ - - 14000.0 - - - + 14000.0 @@ -26,12 +22,8 @@ - - 1.09 - - - + 0.55 @@ -70,6 +62,19 @@ + + + [ + ( 2800, 0.5, 0.0), + ( 5610, 3.0, 70.00), + ( 8410, 4.0, 126.10), + (11220, 5.0, 210.20), + (14030, 6.0, 322.40), + ('inf', 7.0, 462.70), + ] + + + @@ -78,16 +83,17 @@ - - 2510 - - - 2590 + + + 2670 + + + @@ -96,16 +102,16 @@ - - 3470.0 - - - 3820.0 + + 4200 + + + diff --git a/l10n_us_hr_payroll/data/state/sd_south_dakota.xml b/l10n_us_hr_payroll/data/state/sd_south_dakota.xml index 95165ae5..0b44d1c8 100644 --- a/l10n_us_hr_payroll/data/state/sd_south_dakota.xml +++ b/l10n_us_hr_payroll/data/state/sd_south_dakota.xml @@ -7,6 +7,7 @@ + 15000.00 @@ -21,6 +22,7 @@ + 1.75 diff --git a/l10n_us_hr_payroll/data/state/tx_texas.xml b/l10n_us_hr_payroll/data/state/tx_texas.xml index 5d9c5772..d188e480 100644 --- a/l10n_us_hr_payroll/data/state/tx_texas.xml +++ b/l10n_us_hr_payroll/data/state/tx_texas.xml @@ -7,11 +7,7 @@ - - 9000.0 - - - + 9000.0 @@ -26,11 +22,7 @@ - - 2.7 - - - + 2.7 @@ -44,11 +36,7 @@ - - 0.0 - - - + 0.0 @@ -62,11 +50,7 @@ - - 0.1 - - - + 0.1 diff --git a/l10n_us_hr_payroll/data/state/ut_utah.xml b/l10n_us_hr_payroll/data/state/ut_utah.xml index cb57813c..cb3b9710 100644 --- a/l10n_us_hr_payroll/data/state/ut_utah.xml +++ b/l10n_us_hr_payroll/data/state/ut_utah.xml @@ -12,6 +12,12 @@ + + + 38900.0 + + + @@ -26,6 +32,13 @@ + + + + 0.1052 + + + @@ -34,6 +47,7 @@ + 0.0495 @@ -47,6 +61,9 @@ + + + { 'single': { @@ -88,6 +105,8 @@ + + { 'single': { diff --git a/l10n_us_hr_payroll/data/state/va_virginia.xml b/l10n_us_hr_payroll/data/state/va_virginia.xml index 5d19384a..d1c2db08 100644 --- a/l10n_us_hr_payroll/data/state/va_virginia.xml +++ b/l10n_us_hr_payroll/data/state/va_virginia.xml @@ -7,11 +7,7 @@ - - 8000.0 - - - + 8000.0 @@ -26,17 +22,20 @@ - - 2.51 - - - 2.51 + + + 2.5 + + + + + US VA Virginia SIT Rate Table @@ -44,7 +43,8 @@ - + + [ ( 0.00, 0.0, 2.00), ( 3000.00, 60.0, 3.00), @@ -52,7 +52,7 @@ ( 17000.00, 720.0, 5.75), ] - + @@ -62,10 +62,11 @@ - + + 930.0 - + @@ -75,10 +76,11 @@ - + + 800.0 - + @@ -88,10 +90,11 @@ - + + 4500.0 - + diff --git a/l10n_us_hr_payroll/data/state/vt_vermont.xml b/l10n_us_hr_payroll/data/state/vt_vermont.xml index 74f1a491..9ee8c497 100644 --- a/l10n_us_hr_payroll/data/state/vt_vermont.xml +++ b/l10n_us_hr_payroll/data/state/vt_vermont.xml @@ -12,6 +12,11 @@ + + 14100.0 + + + @@ -21,6 +26,7 @@ + 1.0 @@ -46,6 +52,19 @@ + + + { + 'weekly' : 84.62, + 'bi-weekly' : 169.23, + 'semi-monthly': 183.33, + 'monthly' : 366.67, + 'quarterly' : 1100.00, + 'annually': 4400.00, + } + + + @@ -148,6 +167,101 @@ + + + { + 'single': { + 'weekly': ( + ( 61, 0.00, 0.00), + ( 849, 0.00, 3.35), + ( 1969, 26.40, 6.60), + ( 4041, 100.32, 7.60), + ('inf', 257.79, 8.75), + ), + 'bi-weekly': ( + ( 122, 0.00, 0.00), + ( 1697, 0.00, 3.35), + ( 3938, 52.76, 6.60), + ( 8082, 200.67, 7.60), + ('inf', 515.61, 8.75), + ), + 'semi-monthly': ( + ( 132, 0.00, 0.00), + ( 1839, 0.00, 3.35), + ( 4266, 57.18, 6.60), + ( 8755, 217.37, 7.60), + ('inf', 558.53, 8.75), + ), + 'monthly': ( + ( 265, 0.00, 0.00), + ( 3677, 0.00, 3.35), + ( 8531, 114.30, 6.60), + (17510, 434.67, 7.60), + ('inf', 1117.07, 8.75), + ), + 'quarterly': ( + ( 794, 0.00, 0.00), + (11031, 0.00, 3.35), + (25594, 342.94, 6.60), + (52531, 1304.10, 7.60), + ('inf', 3351.31, 8.75), + ), + 'annually': ( + ( 3175, 0.00, 0.00), + ( 44125, 0.00, 3.35), + (102375, 1371.83, 6.60), + (210125, 5216.33, 7.60), + ( 'inf', 13405.33, 8.75), + ), + }, + 'married': { + 'weekly': ( + ( 183, 0.00, 0.00), + ( 1499, 0.00, 3.35), + ( 3363, 44.09, 6.60), + ( 5028, 167.11, 7.60), + ('inf', 293.65, 8.75), + ), + 'bi-weekly': ( + ( 366, 0.00, 0.00), + ( 2997, 0.00, 3.35), + ( 6726, 88.14, 6.60), + (10057, 334.25, 7.60), + ('inf', 587.41, 8.75), + ), + 'semi-monthly': ( + ( 397, 0.00, 0.00), + ( 3247, 0.00, 3.35), + ( 7286, 95.48, 6.60), + (10895, 362.05, 7.60), + ('inf', 636.33, 8.75), + ), + 'monthly': ( + ( 794, 0.00, 0.00), + ( 6494, 0.00, 3.35), + (14573, 190.95, 6.60), + (21790, 724.16, 7.60), + ('inf', 1272.66, 8.75), + ), + 'quarterly': ( + ( 2381, 0.00, 0.00), + (19481, 0.00, 3.35), + (43719, 572.85, 6.60), + (65719, 2172.56, 7.60), + ('inf', 3817.96, 8.75), + ), + 'annually': ( + ( 9525, 0.00, 0.00), + ( 77925, 0.00, 3.35), + (174875, 2291.40, 6.60), + (261475, 8690.10, 7.60), + ( 'inf', 15271.70, 8.75), + ), + }, + } + + + diff --git a/l10n_us_hr_payroll/data/state/wa_washington.xml b/l10n_us_hr_payroll/data/state/wa_washington.xml index 3307689c..53a4e491 100644 --- a/l10n_us_hr_payroll/data/state/wa_washington.xml +++ b/l10n_us_hr_payroll/data/state/wa_washington.xml @@ -1,22 +1,24 @@ + + US WA Washington SUTA Wage Base us_wa_suta_wage_base - - 49800.0 - - - 52700.00 + + 56500.00 + + + @@ -25,16 +27,17 @@ - - 132900.00 - - - + 137700.00 + + 142800.00 + + + @@ -43,17 +46,23 @@ us_wa_suta_rate + - - 1.18 - - - 1.0 + + + + + + + 2.16 + + + @@ -62,16 +71,17 @@ - - 0.4 - - - + 0.4 + + 0.4 + + + @@ -80,16 +90,18 @@ - - 66.33 - - - 66.33 + + + + 66.33 + + + @@ -98,16 +110,18 @@ - - 33.67 - - - 33.67 + + + + 33.67 + + + @@ -133,9 +147,13 @@ ER: US WA Washington State Unemployment (5208A/B) ER_US_WA_SUTA python - result, _ = general_state_unemployment(payslip, categories, worked_days, inputs, wage_base='us_wa_suta_wage_base', rate='us_wa_suta_rate', state_code='WA') + result, _ = general_state_unemployment(payslip, categories, worked_days, inputs, + wage_base='us_wa_suta_wage_base', rate='us_wa_suta_rate', state_code='WA') + code - result, result_rate = general_state_unemployment(payslip, categories, worked_days, inputs, wage_base='us_wa_suta_wage_base', rate='us_wa_suta_rate', state_code='WA') + result, result_rate = general_state_unemployment(payslip, categories, + worked_days, inputs, wage_base='us_wa_suta_wage_base', rate='us_wa_suta_rate', state_code='WA') + @@ -147,9 +165,12 @@ ER: US WA Washington State Family Medical Leave ER_US_WA_FML python - result, _ = wa_washington_fml_er(payslip, categories, worked_days, inputs) + result, _ = wa_washington_fml_er(payslip, categories, worked_days, inputs) + code - result, result_rate = wa_washington_fml_er(payslip, categories, worked_days, inputs) + result, result_rate = wa_washington_fml_er(payslip, categories, worked_days, + inputs) + @@ -161,9 +182,12 @@ EE: US WA Washington State Family Medical Leave EE_US_WA_FML python - result, _ = wa_washington_fml_ee(payslip, categories, worked_days, inputs) + result, _ = wa_washington_fml_ee(payslip, categories, worked_days, inputs) + code - result, result_rate = wa_washington_fml_ee(payslip, categories, worked_days, inputs) + result, result_rate = wa_washington_fml_ee(payslip, categories, worked_days, + inputs) + @@ -176,9 +200,11 @@ ER: US WA Washington State LNI ER_US_WA_LNI python - result = is_us_state(payslip, 'WA') and payslip.contract_id.us_payroll_config_value('workers_comp_ee_code') and worked_days.WORK100 and worked_days.WORK100.number_of_hours and payslip.rule_parameter(payslip.contract_id.us_payroll_config_value('workers_comp_er_code')) + result = is_us_state(payslip, 'WA') and payslip.contract_id.us_payroll_config_value('workers_comp_ee_code') and worked_days.WORK100 and worked_days.WORK100.number_of_hours and payslip.rule_parameter(payslip.contract_id.us_payroll_config_value('workers_comp_er_code')) code - result, result_rate = worked_days.WORK100.number_of_hours, -payslip.rule_parameter(payslip.contract_id.us_payroll_config_value('workers_comp_er_code')) + result, result_rate = worked_days.WORK100.number_of_hours, + -payslip.rule_parameter(payslip.contract_id.us_payroll_config_value('workers_comp_er_code')) + @@ -192,7 +218,9 @@ python result = is_us_state(payslip, 'WA') and payslip.contract_id.us_payroll_config_value('workers_comp_ee_code') and worked_days.WORK100 and worked_days.WORK100.number_of_hours and payslip.rule_parameter(payslip.contract_id.us_payroll_config_value('workers_comp_ee_code')) code - result, result_rate = worked_days.WORK100.number_of_hours, -payslip.rule_parameter(payslip.contract_id.us_payroll_config_value('workers_comp_ee_code')) + result, result_rate = worked_days.WORK100.number_of_hours, + -payslip.rule_parameter(payslip.contract_id.us_payroll_config_value('workers_comp_ee_code')) + diff --git a/l10n_us_hr_payroll/data/state/wi_wisconsin.xml b/l10n_us_hr_payroll/data/state/wi_wisconsin.xml index b62dc3f4..491c7311 100644 --- a/l10n_us_hr_payroll/data/state/wi_wisconsin.xml +++ b/l10n_us_hr_payroll/data/state/wi_wisconsin.xml @@ -7,6 +7,7 @@ + 14000.00 @@ -15,13 +16,14 @@ - US WI Wisconsin SUTA Rate us_wi_suta_rate + + 3.05 @@ -42,13 +44,14 @@ - US WI Wisconsin SIT Tax Rate us_wi_sit_tax_rate + + { 'single': ( diff --git a/l10n_us_hr_payroll/data/state/wv_west_virginia.xml b/l10n_us_hr_payroll/data/state/wv_west_virginia.xml index ee542c4a..8ded67b7 100644 --- a/l10n_us_hr_payroll/data/state/wv_west_virginia.xml +++ b/l10n_us_hr_payroll/data/state/wv_west_virginia.xml @@ -7,6 +7,7 @@ + 12000.0 @@ -21,12 +22,14 @@ + 2.7 + US WV West Virginia Exemption Rate @@ -34,6 +37,7 @@ + { 'weekly' : 38.46, @@ -53,6 +57,7 @@ + { 'single': { diff --git a/l10n_us_hr_payroll/data/state/wy_wyoming.xml b/l10n_us_hr_payroll/data/state/wy_wyoming.xml index 247603c5..2f5485e1 100644 --- a/l10n_us_hr_payroll/data/state/wy_wyoming.xml +++ b/l10n_us_hr_payroll/data/state/wy_wyoming.xml @@ -7,16 +7,17 @@ - - 25400.00 - - - 26400.00 + + + 27300.00 + + + @@ -26,11 +27,9 @@ - - 2.10 - - - + + + 8.5 diff --git a/l10n_us_hr_payroll/tests/__init__.py b/l10n_us_hr_payroll/tests/__init__.py index 0dcf26fb..9fd41db3 100755 --- a/l10n_us_hr_payroll/tests/__init__.py +++ b/l10n_us_hr_payroll/tests/__init__.py @@ -4,128 +4,147 @@ 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_2019 from . import test_us_ia_iowa_payslip_2020 +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_id_idaho_payslip_2021 -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_tx_texas_payslip_2021 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_wv_west_virginia_payslip_2021 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_ak_alaska_payslip_2019.py b/l10n_us_hr_payroll/tests/test_us_ak_alaska_payslip_2019.py deleted file mode 100644 index 3eb62184..00000000 --- a/l10n_us_hr_payroll/tests/test_us_ak_alaska_payslip_2019.py +++ /dev/null @@ -1,61 +0,0 @@ -# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. - -from .common import TestUsPayslip, process_payslip - - -class TestUsAKPayslip(TestUsPayslip): - # TAXES AND RATES - AK_UNEMP_MAX_WAGE = 39900.00 - AK_UNEMP = -(1.780 / 100.0) - AK_UNEMP_EE = -(0.5 / 100.0) - - def test_taxes_monthly_over_max(self): - salary = 50000.00 - schedule_pay = 'monthly' - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('AK'), - state_income_tax_additional_withholding=0.0, - schedule_pay=schedule_pay) - - self._log('2019 Alaska tax first payslip monthly:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], self.AK_UNEMP_MAX_WAGE * self.AK_UNEMP) - self.assertPayrollEqual(cats['EE_US_SUTA'], self.AK_UNEMP_MAX_WAGE * self.AK_UNEMP_EE) - - process_payslip(payslip) - - remaining_ak_unemp_wages = 0.00 # We already reached the maximum wage for unemployment insurance. - - self._log('2019 Alaska tax second payslip monthly:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_ak_unemp_wages * self.AK_UNEMP) # 0 - - def test_taxes_weekly_under_max(self): - salary = 5000.00 - schedule_pay = 'weekly' - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('AK'), - state_income_tax_additional_withholding=0.0, - schedule_pay=schedule_pay) - - self._log('2019 Alaska tax first payslip weekly:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.AK_UNEMP) - self.assertPayrollEqual(cats['EE_US_SUTA'], salary * self.AK_UNEMP_EE) - - process_payslip(payslip) diff --git a/l10n_us_hr_payroll/tests/test_us_ak_alaska_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_ak_alaska_payslip_2021.py new file mode 100644 index 00000000..ebf84eda --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_ak_alaska_payslip_2021.py @@ -0,0 +1,15 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date +from .common import TestUsPayslip + + +class TestUsAKPayslip(TestUsPayslip): + # TAXES AND RATES + AK_UNEMP_MAX_WAGE = 43600.00 + AK_UNEMP = 2.57 + AK_UNEMP_EE = 0.5 + + def test_2021_taxes(self): + self._test_er_suta('AK', self.AK_UNEMP, date(2021, 1, 1), wage_base=self.AK_UNEMP_MAX_WAGE) + self._test_ee_suta('AK', self.AK_UNEMP_EE, date(2021, 1, 1), wage_base=self.AK_UNEMP_MAX_WAGE) diff --git a/l10n_us_hr_payroll/tests/test_us_al_alabama_payslip_2019.py b/l10n_us_hr_payroll/tests/test_us_al_alabama_payslip_2019.py deleted file mode 100644 index 33ddb2f9..00000000 --- a/l10n_us_hr_payroll/tests/test_us_al_alabama_payslip_2019.py +++ /dev/null @@ -1,264 +0,0 @@ -# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. - -from .common import TestUsPayslip, process_payslip - - -class TestUsALPayslip(TestUsPayslip): - # TAXES AND RATES - AL_UNEMP_MAX_WAGE = 8000.00 - AL_UNEMP = -2.70 / 100.0 - - def test_taxes_weekly(self): - salary = 10000.00 - schedule_pay = 'weekly' - dependents = 1 - filing_status = 'S' - # see https://revenue.alabama.gov/wp-content/uploads/2019/01/whbooklet_0119.pdf for reference - # Hand Calculated Amount to Test - # Step 1 -> 10000.00 for wages per period , 52.0 for weekly -> 10000 * 52 -> 520000.0 - # Step 2A -> standard deduction for highest wage bracket -> 2000. Subtract from yearly income - # 520000 - 2000 = 518000.0 - # Step 2B -> Subtract Federal Income Tax in yearly form -> Our Fed withholding is -2999.66 * 52 = -155982.32 - # -> 518000.0 - 155982.32 = 362017.68 - # Step 2C -> Subtract the personal exemption -> 1500 for single filing_status - # -> 362017.68 - 1500 = 360517.68 - # Step 2D -> Since income is so high, only 300$ per dependent -> 300$. Subtract - # -> 360517.68 - 300 = 360217.68 - # - # Step 5 (after adding previous lines) -> Compute marginal taxes. - # (500 * (2.00 / 100)) + (2500 * (4.00 / 100)) + ((360217.68 - 500 - 2500) * (5.00 / 100)) -> 17970.884000000002 - # Convert back to pay period - # wh = round(17970.884000000002, 2) -> 17970.88 / 52.0 -> 345.59 - wh = -345.59 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('AL'), - al_a4_sit_exemptions=filing_status, - state_income_tax_additional_withholding=0.0, - state_income_tax_exempt=False, - al_a4_sit_dependents=dependents, - schedule_pay=schedule_pay) - - self._log('2019 Alabama tax first payslip weekly:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['EE_US_941_FIT'], -2999.66) # Hand Calculated. - self.assertPayrollEqual(cats['ER_US_SUTA'], self.AL_UNEMP_MAX_WAGE * self.AL_UNEMP) - self.assertPayrollEqual(cats['EE_US_SIT'], wh) - - process_payslip(payslip) - - remaining_AL_UNEMP_wages = 0.00 # We already reached the maximum wage for unemployment insurance. - - self._log('2019 Alabama tax second payslip weekly:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_AL_UNEMP_wages * self.AL_UNEMP) # 0 - - def test_taxes_married_jointly(self): - salary = 10000.00 - schedule_pay = 'weekly' - dependents = 1 - filing_status = 'M' - - # see https://revenue.alabama.gov/wp-content/uploads/2019/01/whbooklet_0119.pdf for reference - # Hand Calculated Amount to Test - # Step 1 -> 10000.00 for wages per period , 52.0 for weekly -> 10000 * 52 -> 520000.0 - # Step 2A -> standard deduction for highest wage bracket -> 4000. Subtract from yearly income - # 520000 - 4000 = 516000.0 - # Step 2B -> Subtract Federal Income Tax in yearly form -> Our Fed withholding is -2999.66 * 52 = -155982.32 - # -> 516000.0 - 155982.32 = 360017.68 - # Step 2C -> Subtract the personal exemption -> 3000 for married filing jointly. - # -> 360017.68 - 3000 = 357017.68 - # Step 2D -> Since income is so high, only 300$ per dependent -> 300$. Subtract - # -> 357017.68 - 300 = 356717.68 - # - # Step 5 (after adding previous lines) -> Compute marginal taxes. - # (1000 * (2.00 / 100)) + (5000 * (4.00 / 100)) + ((356717.68 - 1000 - 50000) * (5.00 / 100)) - # -> 17755.884000000002 - # Convert back to pay period - # wh = round(17755.884000000002, 2) -> 15505.88 / 52.0 -> 341.45923076923077 - wh = -341.46 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('AL'), - al_a4_sit_exemptions=filing_status, - state_income_tax_additional_withholding=0.0, - state_income_tax_exempt=False, - al_a4_sit_dependents=dependents, - schedule_pay=schedule_pay) - - self._log('2019 Alabama tax first payslip weekly:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['EE_US_941_FIT'], -2999.66) # Hand Calculated. - self.assertPayrollEqual(cats['ER_US_SUTA'], self.AL_UNEMP_MAX_WAGE * self.AL_UNEMP) - self.assertPayrollEqual(cats['EE_US_SIT'], wh) - - process_payslip(payslip) - - - def test_taxes_semimonthly_filing_seperate(self): - salary = 20000.00 - schedule_pay = 'monthly' - filing_status = 'MS' - dependents = 2 - - # see https://revenue.alabama.gov/wp-content/uploads/2019/01/whbooklet_0119.pdf for reference - # Hand Calculated Amount to Test - # Step 1 -> 10000.00 for wages per period , 12.0 for monthly -> 20000 * 12 -> 240000.00 - # Step 2A -> standard deduction for highest wage bracket -> 2000. Subtract from yearly income - # 240000.00 - 2000 = 238000.00 - # Step 2B -> Subtract Federal Income Tax in yearly form -> Our Fed withholding is -4821.99 * 12 = -57863.88 - # -> 238000.00 - 57863.88 = 180136.12 - # Step 2C -> Subtract the personal exemption -> 1500 for married filing separately - # -> 180136.12 - 1500 = 178636.12 - # Step 2D -> Since income is so high, only 300$ per dependent -> 600. Subtract - # -> 178636.12 - 600 = 178036.12 - # - # Step 5 (after adding previous lines) -> Compute marginal taxes. - # (500 * (2.00 / 100)) + (2500 * (4.00 / 100)) + ((178036.12 - 500 - 2500) * (5.00 / 100)) -> 8861.806 - # Convert back to pay period - # wh = 8861.806 / 12.0 rounded -> 738.48 - wh = -738.48 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('AL'), - al_a4_sit_exemptions=filing_status, - state_income_tax_additional_withholding=0.0, - state_income_tax_exempt=False, - al_a4_sit_dependents=dependents, - schedule_pay=schedule_pay) - - self._log('2019 Alabama tax first payslip monthly:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['EE_US_941_FIT'], -4822.00) # Hand Calculated. - self.assertPayrollEqual(cats['ER_US_SUTA'], self.AL_UNEMP_MAX_WAGE * self.AL_UNEMP) - self.assertPayrollEqual(cats['EE_US_SIT'], wh) - - process_payslip(payslip) - - def test_tax_exempt(self): - salary = 5500.00 - wh = 0 - schedule_pay = 'weekly' - dependents = 2 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('AL'), - al_a4_sit_exemptions='', - state_income_tax_additional_withholding=0.0, - state_income_tax_exempt=True, - al_a4_sit_dependents=dependents, - schedule_pay=schedule_pay) - - self._log('2019 Alabama tax first payslip exempt:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.AL_UNEMP) - self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), wh) - - def test_additional_withholding(self): - salary = 5500.0 - schedule_pay = 'weekly' - additional_wh = 40.0 - dependents = 2 - # filing status default is single - - # see https://revenue.alabama.gov/wp-content/uploads/2019/01/whbooklet_0119.pdf for reference - # Hand Calculated Amount to Test - # Step 1 -> 5500.00 for wages per period , 52.0 for monthly -> 5500 * 52.0 -> 286000.0 - # Step 2A -> standard deduction for highest wage bracket -> 2000. Subtract from yearly income - # 286000.0 - 2000 = 284000.0 - # Step 2B -> Subtract Federal Income Tax in yearly form -> Our Fed withholding is -1422.4 * 52.0 = -73964.8 - # -> 284000.0 - 73964.8 = 210035.2 - # Step 2C -> Subtract the personal exemption -> 1500 for single - # -> 210035.2 - 1500 = 208535.2 - # Step 2D -> Since income is so high, only 300$ per dependent -> 600. Subtract - # -> 208535.2 - 600 = 207935.2 - # - # Step 5 (after adding previous lines) -> Compute marginal taxes. - # (500 * (2.00 / 100)) + (2500 * (4.00 / 100)) + ((207935.2 - 500 - 2500) * (5.00 / 100)) -> 10356.76 - # Convert back to pay period - # wh = 10356.76 / 52.0 rounded -> 199.17 - wh = -199.17 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('AL'), - al_a4_sit_exemptions='S', - state_income_tax_additional_withholding=40.0, - state_income_tax_exempt=False, - al_a4_sit_dependents=dependents, - schedule_pay=schedule_pay) - - self._log('2019 Alabama tax first payslip additional withholding:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['EE_US_941_FIT'], -1422.4) # Hand Calculated. - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.AL_UNEMP) - self.assertPayrollEqual(cats['EE_US_SIT'], wh - additional_wh) - - def test_personal_exemption(self): - salary = 5500.0 - schedule_pay = 'weekly' - # filing status default is single - - # see https://revenue.alabama.gov/wp-content/uploads/2019/01/whbooklet_0119.pdf for reference - # Hand Calculated Amount to Test - # Step 1 -> 5500.00 for wages per period , 52.0 for monthly -> 5500 * 52.0 -> 286000.0 - # Step 2A -> standard deduction for highest wage bracket -> 2000. Subtract from yearly income - # 286000.0 - 2000 = 284000.0 - # Step 2B -> Subtract Federal Income Tax in yearly form -> Our Fed withholding is -1422.4 * 52.0 = -73964.8 - # -> 284000.0 - 73964.8 = 210035.2 - # Step 2C -> Subtract the personal exemption -> 0 for personal exemptioon - # -> 210035.2 - 0 = 210035.2 - # Step 2D -> Subtract per dependent. No dependents so 0 - # -> 210035.2 - 0 = 210035.2 - # - # Step 5 (after adding previous lines) -> Compute marginal taxes. - # (500 * (2.00 / 100)) + (2500 * (4.00 / 100)) + ((210035.2 - 500 - 2500) * (5.00 / 100)) -> 10461.76 - # Convert back to pay period - # wh = 10461.76 / 52.0 rounded -> 201.19 - wh = -199.74 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('AL'), - al_a4_sit_exemptions='S', - state_income_tax_additional_withholding=0.0, - state_income_tax_exempt=False, - al_a4_sit_dependents=0.0, - schedule_pay=schedule_pay) - - self._log('2019 Alabama tax first payslip additional withholding:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['EE_US_941_FIT'], -1422.4) # Hand Calculated. - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.AL_UNEMP) - self.assertPayrollEqual(cats['EE_US_SIT'], wh) diff --git a/l10n_us_hr_payroll/tests/test_us_al_alabama_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_al_alabama_payslip_2021.py new file mode 100644 index 00000000..382f679a --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_al_alabama_payslip_2021.py @@ -0,0 +1,36 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsALPayslip(TestUsPayslip): + # Taxes and Rates + AL_UNEMP_MAX_WAGE = 8000.00 + AL_UNEMP = 2.70 + + def _test_sit(self, wage, exempt, exemptions, additional_withholding, dependent, schedule_pay, date_start, expected_withholding): + + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('AL'), + al_a4_sit_exemptions=exempt, + state_income_tax_exempt=exemptions, + state_income_tax_additional_withholding=additional_withholding, + al_a4_sit_dependents=dependent, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + + self._log('Computed period tax: ' + str(expected_withholding)) + self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding) + + def test_2021_taxes_example(self): + self._test_er_suta('AL', self.AL_UNEMP, date(2021, 1, 1), wage_base=self.AL_UNEMP_MAX_WAGE) + self._test_sit(10000.0, 'S', False, 0.0, 1.0, 'weekly', date(2021, 1, 1), 349.08) + self._test_sit(850.0, 'M', False, 0.0, 2.0, 'weekly', date(2021, 1, 1), 29.98) + self._test_sit(5000.0, 'H', False, 0.0, 2.0, 'bi-weekly', date(2021, 1, 1), 191.15) + self._test_sit(20000.0, 'MS', False, 2.0, 0, 'monthly', date(2021, 1, 1), 757.6) + self._test_sit(5500.0, '', True, 2.0, 150, 'weekly', date(2021, 1, 1), 0.00) diff --git a/l10n_us_hr_payroll/tests/test_us_ar_arkansas_payslip_2019.py b/l10n_us_hr_payroll/tests/test_us_ar_arkansas_payslip_2019.py deleted file mode 100644 index 73b0f59c..00000000 --- a/l10n_us_hr_payroll/tests/test_us_ar_arkansas_payslip_2019.py +++ /dev/null @@ -1,72 +0,0 @@ -# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. - -from .common import TestUsPayslip, process_payslip - - -class TestUsARPayslip(TestUsPayslip): - # https://www.dfa.arkansas.gov/images/uploads/incomeTaxOffice/whformula.pdf Calculation based on this file. - AR_UNEMP_MAX_WAGE = 10000.00 - AR_UNEMP = -3.2 / 100.0 - AR_INC_TAX = -0.0535 - - def test_taxes_monthly(self): - salary = 2127.0 - schedule_pay = 'monthly' - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('AR'), - state_income_tax_additional_withholding=0.0, - ar_ar4ec_sit_allowances=2.0, - state_income_tax_exempt=False, - schedule_pay='monthly') - - self._log('2019 Arkansas tax first payslip weekly:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - # Not exempt from rule 1 or rule 2 - unemployment wages., and actual unemployment. - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.AR_UNEMP) - - process_payslip(payslip) - - # Make a new payslip, this one will have maximums - remaining_AR_UNEMP_wages = self.AR_UNEMP_MAX_WAGE - salary if (self.AR_UNEMP_MAX_WAGE - 2*salary < salary) else salary - # We reached the cap of 10000.0 in the first payslip. - self._log('2019 Arkansas tax second payslip weekly:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_AR_UNEMP_wages * self.AR_UNEMP) - - def test_additional_withholding(self): - salary = 5000.0 - schedule_pay = 'monthly' - pay_periods = 12 - allowances = 2 - # TODO: comment on how it was calculated - test_ar_amt = 2598.60 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('AR'), - state_income_tax_additional_withholding=100.0, - ar_ar4ec_sit_allowances=2.0, - state_income_tax_exempt=False, - schedule_pay='monthly') - - - self._log('2019 Arkansas tax first payslip weekly:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.AR_UNEMP) - # TODO: change to hand the test_ar_amt already be divided by pay periods - self.assertPayrollAlmostEqual(cats['EE_US_SIT'], -round(test_ar_amt / pay_periods) - 100) - - process_payslip(payslip) diff --git a/l10n_us_hr_payroll/tests/test_us_ar_arkansas_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_ar_arkansas_payslip_2021.py new file mode 100644 index 00000000..f7a2928e --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_ar_arkansas_payslip_2021.py @@ -0,0 +1,35 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsARPayslip(TestUsPayslip): + # Taxes and Rates + AR_UNEMP_MAX_WAGE = 10000.0 + AR_UNEMP = 3.2 + + def _test_sit(self, wage, exemptions, allowances, additional_withholding, schedule_pay, date_start, expected_withholding): + + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('AR'), + state_income_tax_exempt=exemptions, + state_income_tax_additional_withholding=additional_withholding, + ar_ar4ec_sit_allowances=allowances, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + + self._log('Computed period tax: ' + str(expected_withholding)) + self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding) + + def test_2021_taxes_example(self): + self._test_er_suta('AR', self.AR_UNEMP, date(2021, 1, 1), wage_base=self.AR_UNEMP_MAX_WAGE) + self._test_sit(5000.0, True, 0.0, 0, 'monthly', date(2021, 1, 1), 0.0) + self._test_sit(5000.0, False, 0.0, 0, 'monthly', date(2021, 1, 1), 220.0) + self._test_sit(700.0, False, 0.0, 150, 'weekly', date(2021, 1, 1), 175.0) + self._test_sit(7000.0, False, 2.0, 0, 'semi-monthly', date(2021, 1, 1), 395.0) + self._test_sit(3000.0, False, 1.0, 0, 'bi-weekly', date(2021, 1, 1), 141.0) diff --git a/l10n_us_hr_payroll/tests/test_us_az_arizona_payslip_2019.py b/l10n_us_hr_payroll/tests/test_us_az_arizona_payslip_2019.py deleted file mode 100644 index b97063b6..00000000 --- a/l10n_us_hr_payroll/tests/test_us_az_arizona_payslip_2019.py +++ /dev/null @@ -1,72 +0,0 @@ -# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. - -from .common import TestUsPayslip, process_payslip - - -class TestUsAZPayslip(TestUsPayslip): - - # TAXES AND RATES - AZ_UNEMP_MAX_WAGE = 7000.00 - AZ_UNEMP = -(2.00 / 100.0) - - def test_taxes_with_additional_wh(self): - salary = 15000.00 - schedule_pay = 'weekly' - withholding_percentage = 5.1 - percent_wh = (5.10 / 100) # 5.1% - additional_wh = 12.50 - - wh_to_test = -((percent_wh * salary) + additional_wh) - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('AZ'), - state_income_tax_additional_withholding=12.50, - az_a4_sit_withholding_percentage=withholding_percentage, - schedule_pay=schedule_pay) - - self._log('2019 Arizona tax first payslip weekly:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], self.AZ_UNEMP_MAX_WAGE * self.AZ_UNEMP) - self.assertPayrollEqual(cats['EE_US_SIT'], wh_to_test) - - process_payslip(payslip) - - remaining_AZ_UNEMP_wages = 0.0 # We already reached max unemployment wages. - - self._log('2019 Arizona tax second payslip weekly:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_AZ_UNEMP_wages * self.AZ_UNEMP) - - def test_taxes_monthly(self): - salary = 1000.00 - schedule_pay = 'monthly' - withholding_percentage = 2.7 - percent_wh = (2.70 / 100) # 2.7% - additional_wh = 0.0 - wh_to_test = -((percent_wh * salary) + additional_wh) - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('AZ'), - state_income_tax_additional_withholding=0.0, - az_a4_sit_withholding_percentage=withholding_percentage, - schedule_pay=schedule_pay) - - self._log('2019 Arizona tax first payslip monthly:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.AZ_UNEMP) - self.assertPayrollEqual(cats['EE_US_SIT'], wh_to_test) - - process_payslip(payslip) diff --git a/l10n_us_hr_payroll/tests/test_us_az_arizona_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_az_arizona_payslip_2021.py new file mode 100644 index 00000000..582fd58b --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_az_arizona_payslip_2021.py @@ -0,0 +1,34 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsAZPayslip(TestUsPayslip): + # Taxes and Rates + AZ_UNEMP_MAX_WAGE = 7000.0 + AZ_UNEMP = 2.0 + + def _test_sit(self, wage, additional_withholding, withholding_percent, schedule_pay, date_start, expected_withholding): + + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('AZ'), + state_income_tax_additional_withholding=additional_withholding, + az_a4_sit_withholding_percentage=withholding_percent, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + + self._log('Computed period tax: ' + str(expected_withholding)) + self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding) + + def test_2021_taxes_example(self): + self._test_er_suta('AZ', self.AZ_UNEMP, date(2021, 1, 1), wage_base=self.AZ_UNEMP_MAX_WAGE) + self._test_sit(1000.0, 0.0, 2.70, 'monthly', date(2021, 1, 1), 27.0) + self._test_sit(1000.0, 10.0, 2.70, 'monthly', date(2021, 1, 1), 37.0) + self._test_sit(15000.0, 0.0, 3.60, 'weekly', date(2021, 1, 1), 540.0) + self._test_sit(8000.0, 0.0, 4.20, 'semi-monthly', date(2021, 1, 1), 336.0) + self._test_sit(8000.0, 0.0, 0.00, 'semi-monthly', date(2021, 1, 1), 0.0) diff --git a/l10n_us_hr_payroll/tests/test_us_ca_california_payslip_2019.py b/l10n_us_hr_payroll/tests/test_us_ca_california_payslip_2019.py deleted file mode 100644 index b9331fe3..00000000 --- a/l10n_us_hr_payroll/tests/test_us_ca_california_payslip_2019.py +++ /dev/null @@ -1,245 +0,0 @@ -# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. - -from .common import TestUsPayslip, process_payslip - - -class TestUsCAPayslip(TestUsPayslip): - ### - # Taxes and Rates - ### - CA_MAX_WAGE = 7000 - CA_UIT = -3.5 / 100.0 - CA_ETT = -0.1 / 100.0 - CA_SDI = -1.0 / 100.0 - - # Examples from https://www.edd.ca.gov/pdf_pub_ctr/20methb.pdf - def test_example_a(self): - salary = 210 - schedule_pay = 'weekly' - allowances = 1 - additional_allowances = 0 - - wh = 0.00 - - employee = self._createEmployee() - - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('CA'), - ca_de4_sit_filing_status='single', - state_income_tax_additional_withholding=0.0, - ca_de4_sit_allowances=allowances, - ca_de4_sit_additional_allowances=additional_allowances, - schedule_pay=schedule_pay) - - self._log('2019 California tax first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * (self.CA_UIT + self.CA_ETT)) - self.assertPayrollEqual(cats['EE_US_SUTA'], salary * self.CA_SDI) - self.assertPayrollEqual(cats['EE_US_SIT'], wh) - - process_payslip(payslip) - - def test_example_b(self): - salary = 1250 - schedule_pay = 'bi-weekly' - allowances = 2 - additional_allowances = 1 - - # Example B - subject_to_withholding = salary - 38 - taxable_income = subject_to_withholding - 339 - computed_tax = (taxable_income - 632) * 0.022 + 6.95 # 6.95 Marginal Amount - wh = computed_tax - 9.65 # two exemption allowances - wh = -wh - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('CA'), - ca_de4_sit_filing_status='married', - state_income_tax_additional_withholding=0.0, - ca_de4_sit_allowances=allowances, - ca_de4_sit_additional_allowances=additional_allowances, - schedule_pay=schedule_pay) - - self._log('2019 California tax first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * (self.CA_UIT + self.CA_ETT)) - self.assertPayrollEqual(cats['EE_US_SUTA'], salary * self.CA_SDI) - self.assertPayrollEqual(cats['EE_US_SIT'], wh) - - process_payslip(payslip) - - - def test_example_c(self): - salary = 4100 - schedule_pay = 'monthly' - allowances = 5 - additional_allowances = 0.0 - - wh = -9.3 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('CA'), - ca_de4_sit_filing_status='married', - state_income_tax_additional_withholding=0.0, - ca_de4_sit_allowances=allowances, - ca_de4_sit_additional_allowances=additional_allowances, - schedule_pay=schedule_pay) - - self._log('2019 California tax first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * (self.CA_UIT + self.CA_ETT)) - self.assertPayrollEqual(cats['EE_US_SUTA'], salary * self.CA_SDI) - self.assertPayrollEqual(cats['EE_US_SIT'], wh) - - process_payslip(payslip) - - # Make a new payslip, this one will have maximums - - remaining_ca_uit_wages = self.CA_MAX_WAGE - salary if (self.CA_MAX_WAGE - 2 * salary < salary) \ - else salary - - self._log('2019 California tax second payslip:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], round((remaining_ca_uit_wages * (self.CA_UIT + self.CA_ETT)), 2)) - - def test_example_d(self): - salary = 800 - schedule_pay = 'weekly' - allowances = 3 - additional_allowances = 0 - - wh = -3.18 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('CA'), - ca_de4_sit_filing_status='head_household', - state_income_tax_additional_withholding=0.0, - ca_de4_sit_allowances=allowances, - ca_de4_sit_additional_allowances=additional_allowances, - schedule_pay=schedule_pay) - - self._log('2019 California tax first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * (self.CA_UIT + self.CA_ETT)) - self.assertPayrollEqual(cats['EE_US_SUTA'], salary * self.CA_SDI) - self.assertPayrollEqual(cats['EE_US_SIT'], wh) - - process_payslip(payslip) - - # Make a new payslip, this one will have maximums - - remaining_ca_uit_wages = self.CA_MAX_WAGE - salary if (self.CA_MAX_WAGE - 2 * salary < salary) \ - else salary - - self._log('2019 California tax second payslip:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], round((remaining_ca_uit_wages * (self.CA_UIT + self.CA_ETT)), 2)) - - def test_example_e(self): - salary = 1800 - schedule_pay = 'semi-monthly' - allowances = 4 - additional_allowances = 0 - - wh = -3.08 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('CA'), - ca_de4_sit_filing_status='married', - state_income_tax_additional_withholding=0.0, - ca_de4_sit_allowances=allowances, - ca_de4_sit_additional_allowances=additional_allowances, - schedule_pay=schedule_pay) - - self._log('2019 California tax first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * (self.CA_UIT + self.CA_ETT)) - self.assertPayrollEqual(cats['EE_US_SUTA'], salary * self.CA_SDI) - self.assertPayrollEqual(cats['EE_US_SIT'], wh) - - process_payslip(payslip) - - # Make a new payslip, this one will have maximums - - remaining_ca_uit_wages = self.CA_MAX_WAGE - salary if (self.CA_MAX_WAGE - 2 * salary < salary) \ - else salary - - self._log('2019 California tax second payslip:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], round((remaining_ca_uit_wages * (self.CA_UIT + self.CA_ETT)), 2)) - - def test_example_f(self): - salary = 45000 - schedule_pay = 'annually' - allowances = 4 - additional_allowances = 0 - - wh = -113.85 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('CA'), - ca_de4_sit_filing_status='married', - state_income_tax_additional_withholding=0.0, - ca_de4_sit_allowances=allowances, - ca_de4_sit_additional_allowances=additional_allowances, - schedule_pay=schedule_pay) - - self._log('2019 California tax first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - self.assertPayrollEqual(cats['ER_US_SUTA'], self.CA_MAX_WAGE * (self.CA_UIT + self.CA_ETT)) - self.assertPayrollEqual(cats['EE_US_SUTA'], self.CA_MAX_WAGE * self.CA_SDI) - self.assertPayrollEqual(cats['EE_US_SIT'], wh) - - process_payslip(payslip) \ No newline at end of file diff --git a/l10n_us_hr_payroll/tests/test_us_ca_california_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_ca_california_payslip_2021.py new file mode 100755 index 00000000..5a0b8b7f --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_ca_california_payslip_2021.py @@ -0,0 +1,43 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsCAPayslip(TestUsPayslip): + ### + # 2021 Taxes and Rates + ### + CA_UNEMP_MAX_WAGE = 7000.0 # Note that this is used for SDI and FLI as well + CA_UIT = 3.4 + CA_ETT = 0.1 + CA_SDI = 1.2 + + def _test_sit(self, wage, filing_status, allowances, additional_allowances, additional_withholding, schedule_pay, date_start, expected_withholding): + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('CA'), + ca_de4_sit_filing_status=filing_status, + ca_de4_sit_allowances=allowances, + ca_de4_sit_additional_allowances=additional_allowances, + state_income_tax_additional_withholding=additional_withholding, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding if filing_status else 0.0) + + def test_2021_taxes_example1(self): + combined_er_rate = self.CA_UIT + self.CA_ETT + self._test_er_suta('CA', combined_er_rate, date(2021, 1, 1), wage_base=self.CA_UNEMP_MAX_WAGE) + self._test_ee_suta('CA', self.CA_SDI, date(2021, 1, 1), wage_base=self.CA_UNEMP_MAX_WAGE, relaxed=True) + # these expected values come from examples in https://edd.ca.gov/pdf_pub_ctr/21methb.pdf + self._test_sit(210.0, 'single', 1, 0, 0, 'weekly', date(2021, 1, 1), 0.00) + self._test_sit(1250.0, 'married', 2, 1, 0, 'bi-weekly', date(2021, 1, 1), 0.82) + self._test_sit(4100.0, 'married', 5, 0, 0, 'monthly', date(2021, 1, 1), 0.13) + self._test_sit(800.0, 'head_household', 3, 0, 0, 'weekly', date(2021, 1, 1), 2.05) + self._test_sit(1800.0, 'married', 4, 0, 0, 'semi-monthly', date(2021, 1, 1), 0.24) + self._test_sit(45000.0, 'married', 4, 0, 0, 'annually', date(2021, 1, 1), 45.45) + self._test_sit(45000.0, 'married', 4, 0, 20.0, 'annually', date(2021, 1, 1), 65.45) + self._test_sit(6000.0, '', 4, 0, 20.0, 'annually', date(2021, 1, 1), 0.00) diff --git a/l10n_us_hr_payroll/tests/test_us_co_colorado_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_co_colorado_payslip_2021.py new file mode 100755 index 00000000..754e1623 --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_co_colorado_payslip_2021.py @@ -0,0 +1,37 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsCOPayslip(TestUsPayslip): + ### + # 2021 Taxes and Rates + ### + CO_UNEMP_MAX_WAGE = 13600.0 + CO_UNEMP = 1.7 + + def _test_sit(self, wage, filing_status, additional_withholding, schedule_pay, date_start, expected_withholding, state_income_tax_exempt=False): + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('CO'), + fed_941_fit_w4_filing_status=filing_status, + state_income_tax_additional_withholding=additional_withholding, + state_income_tax_exempt=state_income_tax_exempt, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + + self._log('Computed period tax: ' + str(expected_withholding)) + self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding) + + def test_2021_taxes_example(self): + self._test_er_suta('CO', self.CO_UNEMP, date(2021, 1, 1), wage_base=self.CO_UNEMP_MAX_WAGE) + self._test_sit(5000.0, 'married', 0.0, 'semi-monthly', date(2021, 1, 1), 216.07) + self._test_sit(800.0, 'single', 0.0, 'weekly', date(2021, 1, 1), 33.48) + self._test_sit(20000.0, 'married', 0.0, 'quarterly', date(2021, 1, 1), 833.4) + self._test_sit(20000.0, 'married', 10.0, 'quarterly', date(2021, 1, 1), 843.4) + self._test_sit(20000.0, 'married', 0.0, 'quarterly', date(2021, 1, 1), 0.0, True) + self._test_sit(800.0, '', 0.0, 'weekly', date(2021, 1, 1), 0.00) diff --git a/l10n_us_hr_payroll/tests/test_us_ct_connecticut_payslip_2019.py b/l10n_us_hr_payroll/tests/test_us_ct_connecticut_payslip_2019.py deleted file mode 100644 index ab423131..00000000 --- a/l10n_us_hr_payroll/tests/test_us_ct_connecticut_payslip_2019.py +++ /dev/null @@ -1,121 +0,0 @@ -# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. - -from .common import TestUsPayslip, process_payslip - - -class TestUsCTPayslip(TestUsPayslip): - # TAXES AND RATES - CT_UNEMP_MAX_WAGE = 15000.00 - CT_UNEMP = -(3.40 / 100.0) - - def test_taxes_weekly_with_additional_wh(self): - - # Tax tables can be found here: - # https://portal.ct.gov/-/media/DRS/Publications/pubsip/2019/IP-2019(1).pdf?la=en - # Step 1 - Wages per period -> 10000.00 - salary = 10000.00 - # Step 2 and 3 - Annual wages -> 10000.00 * 52.0 -> 520000.0 - schedule_pay = 'weekly' - # Step 4 Employee Withholding Code -> A - wh_code = 'a' - # Step 5 - Use annual wages and withholding code with table for exemption amount. - # exemption_amt = 0 since highest bracket. - # Step 6 - Subtract 5 from 3 for taxable income. - # taxable income = 520000.00 since we do not have an exemption. - # Step 7 - Determine initial amount from table - # initial = 31550 + ((6.99 / 100) * (520000.00 - 500000.00)) - # 32948.0 - # Step 8 - Determine the tax rate phase out add back from table. - # phase_out = 200 - # Step 9 - Determine the recapture amount from table. - # Close to top, but not top. -> 2900 - # Step 10 - Add Step 7, 8, 9 - # 32948.0 + 200 + 2900.00 - > 36048.0 - # Step 11 - Determine decimal amount from personal tax credits. - # We get no tax credit. - # Step 12 - Multiple Step 10 by 1.00 - Step 11 - # 36048.0 * 1.00 = 36048.0 - # Step 13 - Divide by the number of pay periods. - # 36048.0 / 52.0 = 693.23 - # Step 14 & 15 & 16- Add / Subtract the additional or under withholding amount. Then Add this to the amount - # for withholding per period. - additional_wh = 12.50 - # 693.23 + 12.50 -> - wh = -705.73 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('CT'), - ct_w4na_sit_code=wh_code, - state_income_tax_additional_withholding=additional_wh, - schedule_pay=schedule_pay) - - self._log('2019 Connecticut tax first payslip weekly:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.CT_UNEMP) - self.assertPayrollEqual(cats['EE_US_SIT'], wh) - - process_payslip(payslip) - - remaining_CT_UNEMP_wages = 5000.00 # We already reached the maximum wage for unemployment insurance. - self._log('2019 Connecticut tax second payslip weekly:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_CT_UNEMP_wages * self.CT_UNEMP) - - def test_taxes_weekly_with_different_code(self): - - # Tax tables can be found here: - # https://portal.ct.gov/-/media/DRS/Publications/pubsip/2019/IP-2019(1).pdf?la=en - # Step 1 - Wages per period -> 15000.00 - salary = 15000.00 - # Step 2 and 3 - Annual wages -> 15000.00 * 12.0 -> 180000.0 - schedule_pay = 'monthly' - # Step 4 Employee Withholding Code -> B - wh_code = 'b' - # Step 5 - Use annual wages and withholding code with table for exemption amount. - # exemption_amt = 0 since highest bracket. - # Step 6 - Subtract 5 from 3 for taxable income. - # taxable income = 180000.0 since we do not have an exemption. - # Step 7 - Determine initial amount from table - # initial = 8080 + ((6.00 / 100) * (180000.0 - 160000)) - # 9280.0 - # Step 8 - Determine the tax rate phase out add back from table. - # phase_out = 320 - # Step 9 - Determine the recapture amount from table. - # Bottom -> 0 - # Step 10 - Add Step 7, 8, 9 - # 9280.0 + 320 + 0 - > 9600.0 - # Step 11 - Determine decimal amount from personal tax credits. - # We get no tax credit. - # Step 12 - Multiple Step 10 by 1.00 - Step 11 - # 9600.0 * 1.00 = 9600.0 - # Step 13 - Divide by the number of pay periods. - # 9600.0 / 12.0 = 800.0 - # Step 14 & 15 & 16- Add / Subtract the additional or under withholding amount. Then Add this to the amount - # for withholding per period. - additional_wh = 15.00 - # 800.0 + 15.00 -> - wh = -815.0 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('CT'), - ct_w4na_sit_code=wh_code, - state_income_tax_additional_withholding=additional_wh, - schedule_pay=schedule_pay) - - self._log('2019 Connecticut tax first payslip monthly:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], self.CT_UNEMP_MAX_WAGE * self.CT_UNEMP) - self.assertPayrollEqual(cats['EE_US_SIT'], wh) diff --git a/l10n_us_hr_payroll/tests/test_us_ct_connecticut_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_ct_connecticut_payslip_2021.py new file mode 100644 index 00000000..661131ea --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_ct_connecticut_payslip_2021.py @@ -0,0 +1,35 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsCTPayslip(TestUsPayslip): + # Taxes and Rates + CT_UNEMP_MAX_WAGE = 15000.0 + CT_UNEMP = 3.2 + + def _test_sit(self, wage, withholding_code, additional_withholding, schedule_pay, date_start, expected_withholding): + + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('CT'), + ct_w4na_sit_code=withholding_code, + state_income_tax_additional_withholding=additional_withholding, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + + self._log('Computed period tax: ' + str(expected_withholding)) + self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding) + + def test_2021_taxes_example(self): + self._test_er_suta('CT', self.CT_UNEMP, date(2021, 1, 1), wage_base=self.CT_UNEMP_MAX_WAGE) + self._test_sit(10000.0, 'a', 0.0, 'weekly', date(2021, 1, 1), 693.23) + self._test_sit(12000.0, 'b', 15.0, 'bi-weekly', date(2021, 1, 1), 688.85) + self._test_sit(5000.0, 'f', 15.0, 'monthly', date(2021, 1, 1), 230.25) + self._test_sit(15000.0, 'c', 0.0, 'monthly', date(2021, 1, 1), 783.33) + self._test_sit(18000.0, 'b', 0.0, 'weekly', date(2021, 1, 1), 1254.35) + self._test_sit(500.0, 'd', 0.0, 'weekly', date(2021, 1, 1), 21.15) diff --git a/l10n_us_hr_payroll/tests/test_us_de_delaware_payslip_2020.py b/l10n_us_hr_payroll/tests/test_us_de_delaware_payslip_2020.py index ed285368..75c0e755 100755 --- a/l10n_us_hr_payroll/tests/test_us_de_delaware_payslip_2020.py +++ b/l10n_us_hr_payroll/tests/test_us_de_delaware_payslip_2020.py @@ -30,7 +30,7 @@ class TestUsDEPayslip(TestUsPayslip): def test_2020_taxes_example(self): self._test_er_suta('DE', self.DE_UNEMP, date(2020, 1, 1), wage_base=self.DE_UNEMP_MAX_WAGE) - self._test_sit(480.77, 'single', 0.0, 1.0, 'weekly', date(2020, 1, 1), 13.88) + self._test_sit(480.77, 'single', 0.0, 1.0, 'weekly', date(2020, 1, 1), 13.84) self._test_sit(5000.0, 'single', 0.0, 2.0, 'monthly', date(2020, 1, 1), 211.93) self._test_sit(5000.0, 'single', 10.0, 1.0, 'monthly', date(2020, 1, 1), 231.1) self._test_sit(20000.0, 'married', 0.0, 3.0, 'quarterly', date(2020, 1, 1), 876.0) diff --git a/l10n_us_hr_payroll/tests/test_us_de_delaware_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_de_delaware_payslip_2021.py new file mode 100755 index 00000000..55ae8983 --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_de_delaware_payslip_2021.py @@ -0,0 +1,36 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsDEPayslip(TestUsPayslip): + ### + # 2021 Taxes and Rates + ### + DE_UNEMP_MAX_WAGE = 16500.0 + DE_UNEMP = 1.50 + # Calculation based on section 17. https://revenue.delaware.gov/employers-guide-withholding-regulations-employers-duties/ + + def _test_sit(self, wage, filing_status, additional_withholding, dependents, schedule_pay, date_start, expected_withholding): + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('DE'), + de_w4_sit_filing_status=filing_status, + state_income_tax_additional_withholding=additional_withholding, + de_w4_sit_dependent=dependents, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + + self._log('Computed period tax: ' + str(expected_withholding)) + self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding) + + def test_2021_taxes_example(self): + self._test_er_suta('DE', self.DE_UNEMP, date(2021, 1, 1), wage_base=self.DE_UNEMP_MAX_WAGE) + self._test_sit(480.77, 'single', 0.0, 1.0, 'weekly', date(2021, 1, 1), 13.84) + self._test_sit(5000.0, 'single', 0.0, 2.0, 'monthly', date(2021, 1, 1), 211.93) + self._test_sit(5000.0, 'single', 10.0, 1.0, 'monthly', date(2021, 1, 1), 231.1) + self._test_sit(20000.0, 'married', 0.0, 3.0, 'quarterly', date(2021, 1, 1), 876.0) diff --git a/l10n_us_hr_payroll/tests/test_us_fl_florida_payslip_2019.py b/l10n_us_hr_payroll/tests/test_us_fl_florida_payslip_2019.py deleted file mode 100755 index 419be377..00000000 --- a/l10n_us_hr_payroll/tests/test_us_fl_florida_payslip_2019.py +++ /dev/null @@ -1,84 +0,0 @@ -# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. - -from .common import TestUsPayslip, process_payslip -from odoo.addons.l10n_us_hr_payroll.models.hr_contract import USHRContract - - -class TestUsFlPayslip(TestUsPayslip): - ### - # 2019 Taxes and Rates - ### - FL_UNEMP_MAX_WAGE = 7000.0 - FL_UNEMP = -2.7 / 100.0 - - def test_2019_taxes(self): - salary = 5000.0 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('FL')) - - self._log('2019 Florida tax first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.FL_UNEMP) - - process_payslip(payslip) - - # Make a new payslip, this one will have maximums - - remaining_fl_unemp_wages = self.FL_UNEMP_MAX_WAGE - salary if (self.FL_UNEMP_MAX_WAGE - 2*salary < salary) \ - else salary - - self._log('2019 Florida tax second payslip:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_fl_unemp_wages * self.FL_UNEMP) - - def test_2019_taxes_with_external(self): - salary = 5000.0 - external_wages = 6000.0 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - external_wages=external_wages, - state_id=self.get_us_state('FL')) - - self._log('2019 Forida_external tax first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], (self.FL_UNEMP_MAX_WAGE - external_wages) * self.FL_UNEMP) - - def test_2019_taxes_with_state_exempt(self): - salary = 5000.0 - external_wages = 6000.0 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - external_wages=external_wages, - futa_type=USHRContract.FUTA_TYPE_BASIC, - state_id=self.get_us_state('FL')) - - self._log('2019 Forida_external tax first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats.get('ER_US_SUTA', 0.0), 0.0) diff --git a/l10n_us_hr_payroll/tests/test_us_fl_florida_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_fl_florida_payslip_2021.py new file mode 100755 index 00000000..f146bf4e --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_fl_florida_payslip_2021.py @@ -0,0 +1,16 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date +from .common import TestUsPayslip + + +class TestUsFlPayslip(TestUsPayslip): + ### + # 2021 Taxes and Rates + ### + FL_UNEMP_MAX_WAGE = 7000.0 + FL_UNEMP = 2.9 + + def test_2021_taxes(self): + # Only has state unemployment + self._test_er_suta('FL', self.FL_UNEMP, date(2021, 1, 1), wage_base=self.FL_UNEMP_MAX_WAGE) diff --git a/l10n_us_hr_payroll/tests/test_us_ga_georgia_payslip_2019.py b/l10n_us_hr_payroll/tests/test_us_ga_georgia_payslip_2019.py deleted file mode 100755 index 98206965..00000000 --- a/l10n_us_hr_payroll/tests/test_us_ga_georgia_payslip_2019.py +++ /dev/null @@ -1,135 +0,0 @@ -# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. - -from .common import TestUsPayslip, process_payslip - - -class TestUsGAPayslip(TestUsPayslip): - - # TAXES AND RATES - GA_UNEMP_MAX_WAGE = 9500.00 - GA_UNEMP = -(2.70 / 100.0) - - def test_taxes_weekly_single_with_additional_wh(self): - salary = 15000.00 - schedule_pay = 'weekly' - allowances = 1 - filing_status = 'single' - additional_wh = 12.50 - # Hand Calculated Amount to Test - # Step 1 - Subtract standard deduction from wages. Std Deduct for single weekly is 88.50 - # step1 = 15000.00 - 88.50 = 14911.5 - # Step 2 - Subtract personal allowance from step1. Allowance for single weekly is 51.92 - # step2 = step1 - 51.92 = 14859.58 - # Step 3 - Subtract amount for dependents. Weekly dependent allowance is 57.50 - # step3 = 14859.58 - 57.50 = 14802.08 - # Step 4 -Determine wh amount from tables - # step4 = 4.42 + ((5.75 / 100.00) * (14802.08 - 135.00)) - # Add additional_wh - # wh = 847.7771 + 12.50 = 860.2771 - wh = -860.28 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('GA'), - ga_g4_sit_dependent_allowances=allowances, - ga_g4_sit_additional_allowances=0, - ga_g4_sit_filing_status=filing_status, - state_income_tax_additional_withholding=additional_wh, - schedule_pay=schedule_pay) - - self.assertEqual(contract.schedule_pay, 'weekly') - - self._log('2019 Georgia tax first payslip weekly:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], self.GA_UNEMP_MAX_WAGE * self.GA_UNEMP) - self.assertPayrollEqual(cats['EE_US_SIT'], wh) - - process_payslip(payslip) - - remaining_GA_UNEMP_wages = 0.0 # We already reached max unemployment wages. - - self._log('2019 Georgia tax second payslip weekly:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_GA_UNEMP_wages * self.GA_UNEMP) - - - def test_taxes_monthly_head_of_household(self): - salary = 25000.00 - schedule_pay = 'monthly' - allowances = 2 - filing_status = 'head of household' - additional_wh = 15.00 - # Hand Calculated Amount to Test - # Step 1 - Subtract standard deduction from wages. Std Deduct for head of household monthly is 383.50 - # step1 = 25000.00 - 383.50 = 24616.5 - # Step 2 - Subtract personal allowance from step1. Allowance for head of household monthly is 225.00 - # step2 = 24616.5 - 225.00 = 24391.5 - # Step 3 - Subtract amount for dependents. Weekly dependent allowance is 250.00 - # step3 = 24391.5 - (2 * 250.00) = 23891.5 - # Step 4 - Determine wh amount from tables - # step4 = 28.33 + ((5.75 / 100.00) * (23891.5 - 833.00)) = 1354.19375 - # Add additional_wh - # wh = 1354.19375 + 15.00 = 1369.19375 - wh = -1369.19 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('GA'), - ga_g4_sit_dependent_allowances=allowances, - ga_g4_sit_additional_allowances=0, - ga_g4_sit_filing_status=filing_status, - state_income_tax_additional_withholding=additional_wh, - schedule_pay=schedule_pay) - - self.assertEqual(contract.schedule_pay, 'monthly') - - self._log('2019 Georgia tax first payslip monthly:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], self.GA_UNEMP_MAX_WAGE * self.GA_UNEMP) - self.assertPayrollAlmostEqual(cats['EE_US_SIT'], wh) - - process_payslip(payslip) - - remaining_GA_UNEMP_wages = 0.0 # We already reached max unemployment wages. - - self._log('2019 Georgia tax second payslip weekly:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_GA_UNEMP_wages * self.GA_UNEMP) - - def test_taxes_exempt(self): - salary = 25000.00 - schedule_pay = 'monthly' - allowances = 2 - filing_status = '' - additional_wh = 15.00 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('GA'), - ga_g4_sit_dependent_allowances=allowances, - ga_g4_sit_additional_allowances=0, - ga_g4_sit_filing_status=filing_status, - state_income_tax_additional_withholding=additional_wh, - schedule_pay=schedule_pay) - - self._log('2019 Georgia tax first payslip exempt:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats.get('EE_US_SIT', 0), 0) diff --git a/l10n_us_hr_payroll/tests/test_us_ga_georgia_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_ga_georgia_payslip_2021.py new file mode 100755 index 00000000..56cb9abc --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_ga_georgia_payslip_2021.py @@ -0,0 +1,39 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsGAPayslip(TestUsPayslip): + + # TAXES AND RATES + GA_UNEMP_MAX_WAGE = 9500.00 + GA_UNEMP = 2.70 + + # Example calculated based on https://dor.georgia.gov/employers-tax-guide 2021_employer tax gauide + + def _test_sit(self, wage, filing_status, additional_withholding, dependent_allowances, additional_allowances, + schedule_pay, date_start, expected_withholding): + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('GA'), + ga_g4_sit_filing_status=filing_status, + state_income_tax_additional_withholding=additional_withholding, + ga_g4_sit_dependent_allowances=dependent_allowances, + ga_g4_sit_additional_allowances=additional_allowances, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + + self._log('Computed period tax: ' + str(expected_withholding)) + self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding) + + def test_2021_taxes_example(self): + self._test_er_suta('GA', self.GA_UNEMP, date(2021, 1, 1), wage_base=self.GA_UNEMP_MAX_WAGE) + self._test_sit(15000.0, 'single', 12.50, 1, 0, 'weekly', date(2021, 1, 1), 860.28) + self._test_sit(25000.0, 'head of household', 15.00, 2, 0, 'monthly', date(2021, 1, 1), 1369.19) + self._test_sit(425.0, 'married filing separate', 0.0, 1, 0, 'weekly', date(2021, 1, 1), 11.45) + self._test_sit(3000.0, 'single', 0.00, 1, 1, 'quarterly', date(2021, 1, 1), 0.0) + self._test_sit(2500.0, '', 0.00, 1, 1, 'quarterly', date(2021, 1, 1), 0.0) diff --git a/l10n_us_hr_payroll/tests/test_us_hi_hawaii_payslip_2019.py b/l10n_us_hr_payroll/tests/test_us_hi_hawaii_payslip_2019.py deleted file mode 100644 index 13f1f2b5..00000000 --- a/l10n_us_hr_payroll/tests/test_us_hi_hawaii_payslip_2019.py +++ /dev/null @@ -1,93 +0,0 @@ -# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. - -from .common import TestUsPayslip, process_payslip - - -class TestUsHIPayslip(TestUsPayslip): - - # TAXES AND RATES - HI_UNEMP_MAX_WAGE = 46800.00 - HI_UNEMP = -(2.40 / 100.0) - - def test_taxes_single_weekly(self): - salary = 375.00 - schedule_pay = 'weekly' - filing_status = 'single' - allowances = 3 - wh_to_check = -15.3 - # Taxable income = (wage * payperiod ) - (allownaces * personal_exemption) - # taxable_income = (375 * 52) - (3 * 1144) = 16068 - # Last = row[0] = 692 - # withholding = row[1] + ((row[2] / 100.0) * (taxable_income - last)) - # withholding = 682 + ((6.80 / 100.0 ) * (16068 - 14400)) = 795.42 - # wh_to_check = 795.42/52 = 15.3 - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('HI'), - hi_hw4_sit_filing_status=filing_status, - state_income_tax_additional_withholding=0.0, - hi_hw4_sit_allowances=allowances, - schedule_pay=schedule_pay) - - self._log('2019 Hawaii tax first payslip single:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.HI_UNEMP) - self.assertPayrollEqual(cats['EE_US_SIT'], wh_to_check) - - process_payslip(payslip) - - remaining_id_unemp_wages = self.HI_UNEMP_MAX_WAGE - salary if (self.HI_UNEMP_MAX_WAGE - 2*salary < salary) \ - else salary - - self._log('2019 Hawaii tax second payslip single:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_id_unemp_wages * self.HI_UNEMP) - - def test_taxes_married_monthly(self): - salary = 5000.00 - schedule_pay = 'monthly' - filing_status = 'married' - allowances = 2 - wh_to_check = -287.1 - # Taxable income = (wage * payperiod ) - (allownaces * personal_exemption) - # taxable_income = (5000 * 12) - (2 * 1144) = 57712 - # Last = row[0] = 48000 - # withholding = row[1] + ((row[2] / 100.0) * (taxable_income - last)) - # withholding = 2707 + ((7.70 / 100.0 ) * (57712 - 48000)) = 3445.112 - # wh_to_check = 3445.112/52 = 287.092 - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('HI'), - hi_hw4_sit_filing_status=filing_status, - state_income_tax_additional_withholding=0.0, - hi_hw4_sit_allowances=allowances, - schedule_pay=schedule_pay) - - self._log('2019 Hawaii tax first payslip monthly:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.HI_UNEMP) - self.assertPayrollEqual(cats['EE_US_SIT'], wh_to_check) - - process_payslip(payslip) - - remaining_id_unemp_wages = self.HI_UNEMP_MAX_WAGE - salary if (self.HI_UNEMP_MAX_WAGE - 2*salary < salary) \ - else salary - - self._log('2019 Hawaii tax second payslip monthly:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_id_unemp_wages * self.HI_UNEMP) - diff --git a/l10n_us_hr_payroll/tests/test_us_hi_hawaii_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_hi_hawaii_payslip_2021.py new file mode 100755 index 00000000..0463b227 --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_hi_hawaii_payslip_2021.py @@ -0,0 +1,37 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsHIPayslip(TestUsPayslip): + ### + # 2021 Taxes and Rates + ### + HI_UNEMP_MAX_WAGE = 47400.00 + HI_UNEMP = 5.2 + + def _test_sit(self, wage, filing_status, additional_withholding, allowances, schedule_pay, date_start, expected_withholding): + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('HI'), + hi_hw4_sit_filing_status=filing_status, + state_income_tax_additional_withholding=additional_withholding, + hi_hw4_sit_allowances=allowances, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + + self._log('Computed period tax: ' + str(expected_withholding)) + self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding) + + def test_2021_taxes_example(self): + self._test_er_suta('HI', self.HI_UNEMP, date(2021, 1, 1), wage_base=self.HI_UNEMP_MAX_WAGE) + self._test_sit(375.0, 'single', 0.0, 3.0, 'weekly', date(2021, 1, 1), 15.3) + self._test_sit(5000.0, 'married', 0.0, 2.0, 'monthly', date(2021, 1, 1), 287.1) + self._test_sit(5000.0, 'married', 10.0, 2.0, 'monthly', date(2021, 1, 1), 297.1) + self._test_sit(50000.0, 'head_of_household', 0.0, 3.0, 'weekly', date(2021, 1, 1), 3933.65) + self._test_sit(750.0, 'single', 10.0, 3.0, 'bi-weekly', date(2021, 1, 1), 40.59) + self._test_sit(3000.0, '', 0.0, 3.0, 'weekly', date(2021, 1, 1), 0.00) diff --git a/l10n_us_hr_payroll/tests/test_us_ia_iowa_payslip_2019.py b/l10n_us_hr_payroll/tests/test_us_ia_iowa_payslip_2019.py deleted file mode 100644 index cb3bccfd..00000000 --- a/l10n_us_hr_payroll/tests/test_us_ia_iowa_payslip_2019.py +++ /dev/null @@ -1,152 +0,0 @@ -# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. - -from .common import TestUsPayslip, process_payslip - - -class TestUsIAPayslip(TestUsPayslip): - IA_UNEMP_MAX_WAGE = 30600 - IA_UNEMP = -1.0 / 100.0 - IA_INC_TAX = -0.0535 - - def test_taxes_weekly(self): - wages = 30000.00 - schedule_pay = 'weekly' - allowances = 1 - additional_wh = 0.00 - employee = self._createEmployee() - contract = self._createContract(employee, - wage=wages, - state_id=self.get_us_state('IA'), - state_income_tax_additional_withholding=additional_wh, - ia_w4_sit_allowances=allowances, - schedule_pay=schedule_pay) - - self._log('2019 Iowa tax first payslip weekly:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - # T1 is the gross taxable wages for the pay period minus the Federal withholding amount. We add the federal - # withholding amount because it is calculated in the base US payroll module as a negative - # t1 = 30000 - (10399.66) = 19600.34 - t1_to_test = wages + cats['EE_US_941_FIT'] - self.assertPayrollAlmostEqual(t1_to_test, 19600.34) - - # T2 is T1 minus our standard deduction which is a table of flat rates dependent on the number of allowances. - # In our case, we have a weekly period which on the table has a std deduct. of $32.50 for 0 or 1 allowances, - # and 80.00 of 2 or more allowances. - standard_deduction = 32.50 # The allowance tells us what standard_deduction amount to use. - # t2 = 19600.34 - 32.50 = 19567.84 - t2_to_test = t1_to_test - standard_deduction - self.assertPayrollAlmostEqual(t2_to_test, 19567.84) - # T3 is T2 multiplied by the income rates in the large table plus a flat fee for that bracket. - # 1153.38 is the bracket floor. 8.53 is the rate, and 67.63 is the flat fee. - # t3 = 1638.38 - t3_to_test = ((t2_to_test - 1153.38) * (8.53 / 100)) + 67.63 - self.assertPayrollAlmostEqual(t3_to_test, 1638.38) - # T4 is T3 minus a flat amount determined by pay period * the number of deductions. For 2019, our weekly - # deduction amount per allowance is 0.77 - # t4 = 1638.38 - 0.77 = 155.03 - t4_to_test = t3_to_test - (0.77 * allowances) - self.assertPayrollAlmostEqual(t4_to_test, 1637.61) - # t5 is our T4 plus the additional withholding per period - # t5 = 1637.61 + 0.0 - # Convert to negative as well. - t5_to_test = -t4_to_test - additional_wh - self.assertPayrollAlmostEqual(t5_to_test, -1637.61) - - self.assertPayrollEqual(cats['ER_US_SUTA'], wages * self.IA_UNEMP) - self.assertPayrollEqual(cats['EE_US_SIT'], t5_to_test) - - - # Make a new payslip, this one will have maximums - - remaining_IA_UNEMP_wages = self.IA_UNEMP_MAX_WAGE - wages if (self.IA_UNEMP_MAX_WAGE - 2*wages < wages) \ - else wages - - self._log('2019 Iowa tax second payslip weekly:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], wages * self.IA_UNEMP) - - def test_taxes_biweekly(self): - wages = 3000.00 - schedule_pay = 'bi-weekly' - allowances = 1 - additional_wh = 0.00 - employee = self._createEmployee() - contract = self._createContract(employee, - wage=wages, - state_id=self.get_us_state('IA'), - state_income_tax_additional_withholding=additional_wh, - ia_w4_sit_allowances=allowances, - schedule_pay=schedule_pay) - - self._log('2019 Iowa tax first payslip bi-weekly:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - # T1 is the gross taxable wages for the pay period minus the Federal withholding amount. We add the federal - # withholding amount because it is calculated in the base US payroll module as a negative - t1_to_test = wages + cats['EE_US_941_FIT'] - # T2 is T1 minus our standard deduction which is a table of flat rates dependent on the number of allowances. - # In our case, we have a biweekly period which on the table has a std deduct. of $65.00 for 0 or 1 allowances, - # and $160.00 of 2 or more allowances. - standard_deduction = 65.00 # The allowance tells us what standard_deduction amount to use. - t2_to_test = t1_to_test - standard_deduction - # T3 is T2 multiplied by the income rates in the large table plus a flat fee for that bracket. - t3_to_test = ((t2_to_test - 2306.77) * (8.53 / 100)) + 135.28 - # T4 is T3 minus a flat amount determined by pay period * the number of deductions. For 2019, our weekly - # deduction amount per allowance is 0.77 - t4_to_test = t3_to_test - (1.54 * allowances) - # t5 is our T4 plus the additional withholding per period - t5_to_test = -t4_to_test - additional_wh - - self.assertPayrollEqual(cats['ER_US_SUTA'], wages * self.IA_UNEMP) - self.assertPayrollEqual(cats['EE_US_SIT'], t5_to_test - additional_wh) - - process_payslip(payslip) - - def test_taxes_with_external_weekly(self): - wages = 2500.00 - schedule_pay = 'weekly' - allowances = 1 - additional_wh = 0.00 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=wages, - state_id=self.get_us_state('IA'), - state_income_tax_additional_withholding=additional_wh, - ia_w4_sit_allowances=allowances, - schedule_pay=schedule_pay) - - self._log('2019 Iowa external tax first payslip external weekly:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - - # T1 is the gross taxable wages for the pay period minus the Federal withholding amount. We add the federal - # withholding amount because it is calculated in the base US payroll module as a negative - t1_to_test = wages + cats['EE_US_941_FIT'] - # T2 is T1 minus our standard deduction which is a table of flat rates dependent on the number of allowances. - # In our case, we have a weekly period which on the table has a std deduct. of $32.50 for 0 or 1 allowances, - # and 80.00 of 2 or more allowances. - standard_deduction = 32.50 # The allowance tells us what standard_deduction amount to use. - t2_to_test = t1_to_test - standard_deduction - # T3 is T2 multiplied by the income rates in the large table plus a flat fee for that bracket. - t3_to_test = ((t2_to_test - 1153.38) * (8.53 / 100)) + 67.63 - # T4 is T3 minus a flat amount determined by pay period * the number of deductions. For 2019, our weekly - # deduction amount per allowance is 0.77 - t4_to_test = t3_to_test - (0.77 * allowances) - # t5 is our T4 plus the additional withholding per period - t5_to_test = -t4_to_test - additional_wh - - self.assertPayrollEqual(cats['ER_US_SUTA'], wages * self.IA_UNEMP) - self.assertPayrollAlmostEqual(cats['EE_US_SIT'], t5_to_test) - - process_payslip(payslip) \ No newline at end of file diff --git a/l10n_us_hr_payroll/tests/test_us_ia_iowa_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_ia_iowa_payslip_2021.py new file mode 100755 index 00000000..df169186 --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_ia_iowa_payslip_2021.py @@ -0,0 +1,36 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsIAPayslip(TestUsPayslip): + ### + # 2021 Taxes and Rates + ### + IA_UNEMP_MAX_WAGE = 32400.0 + IA_UNEMP = 1.0 + + def _test_sit(self, wage, exempt, additional_withholding, allowances, schedule_pay, date_start, expected_withholding): + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('IA'), + state_income_tax_exempt=exempt, + state_income_tax_additional_withholding=additional_withholding, + ia_w4_sit_allowances=allowances, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + + self._log('Computed period tax: ' + str(expected_withholding)) + self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding) + + def test_2021_taxes_example(self): + self._test_er_suta('IA', self.IA_UNEMP, date(2021, 1, 1), wage_base=self.IA_UNEMP_MAX_WAGE) + self._test_sit(2100.0, False, 0.0, 3.0, 'bi-weekly', date(2021, 1, 1), 79.13) + self._test_sit(3000.0, True, 10.0, 1.0, 'bi-weekly', date(2021, 1, 1), 0.00) + self._test_sit(300.0, False, 0.0, 1.0, 'weekly', date(2021, 1, 1), 6.14) + self._test_sit(5000.0, False, 0.0, 1.0, 'monthly', date(2021, 1, 1), 217.60) + self._test_sit(7500.0, False, 10.0, 2.0, 'semi-monthly', date(2021, 1, 1), 420.87) diff --git a/l10n_us_hr_payroll/tests/test_us_id_idaho_payslip_2019.py b/l10n_us_hr_payroll/tests/test_us_id_idaho_payslip_2019.py deleted file mode 100644 index 8e3576d6..00000000 --- a/l10n_us_hr_payroll/tests/test_us_id_idaho_payslip_2019.py +++ /dev/null @@ -1,85 +0,0 @@ -# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. - -from .common import TestUsPayslip, process_payslip - - -class TestUsIDPayslip(TestUsPayslip): - - # TAXES AND RATES - ID_UNEMP_MAX_WAGE = 40000.00 - ID_UNEMP = -(1.00 / 100.0) - - def test_taxes_single_biweekly(self): - salary = 1212.00 - schedule_pay = 'bi-weekly' - filing_status = 'single' - allowances = 4 - # SEE https://tax.idaho.gov/i-1026.cfm?seg=compute for example calculations - wh_to_check = -10.00 - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('ID'), - id_w4_sit_filing_status=filing_status, - id_w4_sit_allowances=allowances, - schedule_pay=schedule_pay) - - self._log('2019 Idaho tax first payslip single:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.ID_UNEMP) - self.assertPayrollEqual(cats['EE_US_SIT'], wh_to_check) - - process_payslip(payslip) - - remaining_id_unemp_wages = self.ID_UNEMP_MAX_WAGE - salary if (self.ID_UNEMP_MAX_WAGE - 2*salary < salary) \ - else salary - - self._log('2019 Idaho tax second payslip single:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_id_unemp_wages * self.ID_UNEMP) - - def test_taxes_married_monthly(self): - salary = 5000.00 - schedule_pay = 'monthly' - filing_status = 'married' - allowances = 2 - - # ICTCAT says monthly allowances are 246.67 - # we have 2 so 246.67 * 2 = 493.34 - # 5000.00 - 493.34 = 4506.66 - # Wh is 89$ plus 6.925% over 3959,00 - # 126.92545499999999 - > 127.0 - wh_to_check = -127.0 - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('ID'), - id_w4_sit_filing_status=filing_status, - id_w4_sit_allowances=allowances, - schedule_pay=schedule_pay) - - self._log('2019 Idaho tax first payslip monthly:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.ID_UNEMP) - self.assertPayrollEqual(cats['EE_US_SIT'], wh_to_check) - - process_payslip(payslip) - - remaining_id_unemp_wages = self.ID_UNEMP_MAX_WAGE - salary if (self.ID_UNEMP_MAX_WAGE - 2*salary < salary) \ - else salary - - self._log('2019 Idaho tax second payslip monthly:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_id_unemp_wages * self.ID_UNEMP) diff --git a/l10n_us_hr_payroll/tests/test_us_id_idaho_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_id_idaho_payslip_2021.py new file mode 100755 index 00000000..c6149719 --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_id_idaho_payslip_2021.py @@ -0,0 +1,35 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsIDPayslip(TestUsPayslip): + ### + # 2021 Taxes and Rates + ### + ID_UNEMP_MAX_WAGE = 43000.00 + ID_UNEMP = 1.0 + + def _test_sit(self, wage, filing_status, allowances, schedule_pay, date_start, expected_withholding): + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('ID'), + id_w4_sit_filing_status=filing_status, + id_w4_sit_allowances=allowances, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + + self._log('Computed period tax: ' + str(expected_withholding)) + self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding) + + def test_2021_taxes_example(self): + self._test_er_suta('ID', self.ID_UNEMP, date(2021, 1, 1), wage_base=self.ID_UNEMP_MAX_WAGE) + self._test_sit(1212.0, 'single', 4.0, 'bi-weekly', date(2021, 1, 1), 10.0) + self._test_sit(10000.0, 'married', 1.0, 'annually', date(2021, 1, 1), 0.0) + self._test_sit(52000.0, 'married', 4.0, 'monthly', date(2021, 1, 1), 3345.0) + self._test_sit(5000.0, 'head of household', 0.0, 'semi-monthly', date(2021, 1, 1), 300.0) + self._test_sit(5900.0, 'single', 5.0, 'weekly', date(2021, 1, 1), 367.0) diff --git a/l10n_us_hr_payroll/tests/test_us_il_illinois_payslip_2019.py b/l10n_us_hr_payroll/tests/test_us_il_illinois_payslip_2019.py deleted file mode 100644 index ba633607..00000000 --- a/l10n_us_hr_payroll/tests/test_us_il_illinois_payslip_2019.py +++ /dev/null @@ -1,71 +0,0 @@ -# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. - -from .common import TestUsPayslip, process_payslip - - -class TestUsILPayslip(TestUsPayslip): - # TAXES AND RATES - IL_UNEMP_MAX_WAGE = 12960.00 - IL_UNEMP = -(3.175 / 100.0) - - def test_taxes_monthly(self): - salary = 15000.00 - schedule_pay = 'monthly' - basic_allowances = 1 - additional_allowances = 1 - flat_rate = (4.95 / 100) - wh_to_test = -(flat_rate * (salary - ((basic_allowances * 2275 + additional_allowances * 1000) / 12.0))) - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('IL'), - state_income_tax_additional_withholding=0.0, - il_w4_sit_basic_allowances=1.0, - il_w4_sit_additional_allowances=1.0, - schedule_pay='monthly') - - self._log('2019 Illinois tax first payslip monthly:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], self.IL_UNEMP_MAX_WAGE * self.IL_UNEMP) - self.assertPayrollEqual(cats['EE_US_SIT'], wh_to_test) - - process_payslip(payslip) - - remaining_IL_UNEMP_wages = 0.0 # We already reached max unemployment wages. - - self._log('2019 Illinois tax second payslip monthly:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_IL_UNEMP_wages * self.IL_UNEMP) - - def test_taxes_with_additional_wh(self): - salary = 15000.00 - schedule_pay = 'monthly' - basic_allowances = 1 - additional_allowances = 1 - additional_wh = 15.0 - flat_rate = (4.95 / 100) - wh_to_test = -(flat_rate * (salary - ((basic_allowances * 2275 + additional_allowances * 1000) / 12.0)) + additional_wh) - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('IL'), - state_income_tax_additional_withholding=15.0, - il_w4_sit_basic_allowances=1.0, - il_w4_sit_additional_allowances=1.0, - schedule_pay='monthly') - - self._log('2019 Illinois tax first payslip monthly:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], self.IL_UNEMP_MAX_WAGE * self.IL_UNEMP) - self.assertPayrollEqual(cats['EE_US_SIT'], wh_to_test) diff --git a/l10n_us_hr_payroll/tests/test_us_il_illinois_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_il_illinois_payslip_2021.py new file mode 100644 index 00000000..4f62cb5e --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_il_illinois_payslip_2021.py @@ -0,0 +1,36 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsILPayslip(TestUsPayslip): + # Taxes and Rates + IL_UNEMP_MAX_WAGE = 12960.0 + IL_UNEMP = 3.175 + + def _test_sit(self, wage, additional_withholding, basic_allowances, additional_allowances, schedule_pay, date_start, expected_withholding): + + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('IL'), + state_income_tax_additional_withholding=additional_withholding, + il_w4_sit_basic_allowances=basic_allowances, + il_w4_sit_additional_allowances=additional_allowances, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + + self._log('Computed period tax: ' + str(expected_withholding)) + self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding) + + def test_2021_taxes_example(self): + self._test_er_suta('IL', self.IL_UNEMP, date(2021, 1, 1), wage_base=self.IL_UNEMP_MAX_WAGE, relaxed=True) + self._test_sit(800.0, 0.0, 2, 2, 'weekly', date(2021, 1, 1), 33.17) + self._test_sit(800.0, 10.0, 2, 2, 'weekly', date(2021, 1, 1), 43.17) + self._test_sit(2500.0, 0.0, 1, 1, 'monthly', date(2021, 1, 1), 109.83) + self._test_sit(2500.0, 0.0, 0, 0, 'monthly', date(2021, 1, 1), 123.75) + self._test_sit(3000.0, 15.0, 0, 0, 'quarterly', date(2021, 1, 1), 163.50) + diff --git a/l10n_us_hr_payroll/tests/test_us_in_indiana_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_in_indiana_payslip_2021.py new file mode 100755 index 00000000..53b7ddf3 --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_in_indiana_payslip_2021.py @@ -0,0 +1,36 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsINPayslip(TestUsPayslip): + ### + # 2020 Taxes and Rates + ### + IN_UNEMP_MAX_WAGE = 9500.0 + IN_UNEMP = 2.5 + # Calculation based on https://www.in.gov/dor/files/dn01.pdf + + def _test_sit(self, wage, additional_withholding, personal_exemption, dependent_exemption, schedule_pay, date_start, expected_withholding): + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('IN'), + state_income_tax_additional_withholding=additional_withholding, + in_w4_sit_personal_exemption=personal_exemption, + in_w4_sit_dependent_exemption=dependent_exemption, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + + self._log('Computed period tax: ' + str(expected_withholding)) + self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding) + + def test_2020_taxes_example(self): + self._test_er_suta('IN', self.IN_UNEMP, date(2020, 1, 1), wage_base=self.IN_UNEMP_MAX_WAGE) + self._test_sit(800.0, 0.0, 5.0, 3.0, 'weekly', date(2020, 1, 1), 19.94) + self._test_sit(800.0, 10.0, 5.0, 3.0, 'weekly', date(2020, 1, 1), 29.94) + self._test_sit(9000.0, 0.0, 4.0, 3.0, 'monthly', date(2020, 1, 1), 267.82) + self._test_sit(10000.0, 0.0, 2.0, 2.0, 'bi-weekly', date(2020, 1, 1), 316.79) diff --git a/l10n_us_hr_payroll/tests/test_us_ks_kansas_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_ks_kansas_payslip_2021.py new file mode 100755 index 00000000..fba4c2f5 --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_ks_kansas_payslip_2021.py @@ -0,0 +1,36 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsKSPayslip(TestUsPayslip): + ### + # 2021 Taxes and Rates + ### + KS_UNEMP_MAX_WAGE = 14000.0 + KS_UNEMP = 2.7 + # Calculation based on example https://revenue.ky.gov/Forms/42A003(T)%20(12-2019)%202120%20Tax%20Tables.pdf + + def _test_sit(self, wage, filing_status, allowances, additional_withholding, schedule_pay, date_start, expected_withholding): + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('KS'), + ks_k4_sit_filing_status=filing_status, + ks_k4_sit_allowances=allowances, + state_income_tax_additional_withholding=additional_withholding, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + + self._log('Computed period tax: ' + str(expected_withholding)) + self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding) + + def test_2021_taxes_example(self): + self._test_er_suta('KS', self.KS_UNEMP, date(2021, 1, 1), wage_base=self.KS_UNEMP_MAX_WAGE) + self._test_sit(6250, 'married', 2, 0, 'semi-monthly', date(2021, 1, 1), 290.00) + self._test_sit(5000, 'single', 1, 0, 'monthly', date(2021, 1, 1), 222.00) + self._test_sit(1500, 'married', 0, 0, 'bi-weekly', date(2021, 1, 1), 39.00) + self._test_sit(750, 'single', 2, 10, 'weekly', date(2021, 1, 1), 36.00) diff --git a/l10n_us_hr_payroll/tests/test_us_ky_kentucky_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_ky_kentucky_payslip_2021.py new file mode 100755 index 00000000..d05add23 --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_ky_kentucky_payslip_2021.py @@ -0,0 +1,36 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsKYPayslip(TestUsPayslip): + ### + # 2021 Taxes and Rates + ### + KY_UNEMP_MAX_WAGE = 11100.0 + KY_UNEMP = 2.7 + # Calculation based on example https://revenue.ky.gov/Forms/42A003(T)%20(12-2019)%202120%20Tax%20Tables.pdf + + def _test_sit(self, wage, additional_withholding, schedule_pay, date_start, expected_withholding): + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('KY'), + state_income_tax_additional_withholding=additional_withholding, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + + self._log('Computed period tax: ' + str(expected_withholding)) + self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding) + + def test_2021_taxes_example(self): + self._test_er_suta('KY', self.KY_UNEMP, date(2021, 1, 1), wage_base=self.KY_UNEMP_MAX_WAGE) + # page 8 of https://revenue.ky.gov/Software-Developer/Software%20Development%20Documents/2021%20Withholding%20Tax%20Tables%20-%20Computer%20Formual%2042A003(T)(12-20)(10-15-20%20DRAFT).pdf + self._test_sit(3020, 0.0, 'monthly', date(2021, 1, 1), 139.79) + self._test_sit(1500, 0.0, 'bi-weekly', date(2021, 1, 1), 69.83) + self._test_sit(1500, 10.0, 'bi-weekly', date(2021, 1, 1), 79.83) + self._test_sit(750, 00.0, 'weekly', date(2021, 1, 1), 34.91) + self._test_sit(7000, 0.0, 'semi-monthly', date(2021, 1, 1), 344.39) diff --git a/l10n_us_hr_payroll/tests/test_us_la_louisiana_payslip_2019.py b/l10n_us_hr_payroll/tests/test_us_la_louisiana_payslip_2019.py deleted file mode 100644 index 1d01c618..00000000 --- a/l10n_us_hr_payroll/tests/test_us_la_louisiana_payslip_2019.py +++ /dev/null @@ -1,91 +0,0 @@ -# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. - -from .common import TestUsPayslip, process_payslip - - -class TestUsLAPayslip(TestUsPayslip): - - # TAXES AND RATES - LA_UNEMP_MAX_WAGE = 7700.00 - LA_UNEMP = -(1.14 / 100.0) - - def test_taxes_single_weekly(self): - salary = 700.00 - schedule_pay = 'weekly' - filing_status = 'single' - exemptions = 1 - dependents = 2 - additional_withholding = 0 - # SEE http://revenue.louisiana.gov/TaxForms/1306(1_12)TF.pdf for example calculations - # wh_to test is 19.42 - # Our algorithm correctly rounds whereas theirs does it prematurely. - wh_to_check = -19.43 - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('LA'), - la_l4_sit_filing_status=filing_status, - state_income_tax_additional_withholding=additional_withholding, - la_l4_sit_exemptions=exemptions, - la_l4_sit_dependents=dependents, - schedule_pay=schedule_pay) - - self._log('2019 Louisiana tax first payslip weekly:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.LA_UNEMP) - self.assertPayrollEqual(cats['EE_US_SIT'], wh_to_check) - - process_payslip(payslip) - - remaining_la_unemp_wages = self.LA_UNEMP_MAX_WAGE - salary if (self.LA_UNEMP_MAX_WAGE - 2*salary < salary) \ - else salary - - self._log('2019 Louisiana tax second payslip weekly:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_la_unemp_wages * self.LA_UNEMP) - - def test_taxes_married_biweekly(self): - salary = 4600.00 - schedule_pay = 'bi-weekly' - filing_status = 'married' - exemptions = 2 - dependents = 3 - additional_withholding = 0 - # SEE http://revenue.louisiana.gov/TaxForms/1306(1_12)TF.pdf for example calculations - # wh_to test is 157.12 - wh_to_check = -157.12 - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('LA'), - la_l4_sit_filing_status=filing_status, - state_income_tax_additional_withholding=additional_withholding, - la_l4_sit_exemptions=exemptions, - la_l4_sit_dependents=dependents, - schedule_pay=schedule_pay) - - self._log('2019 Louisiana tax first payslip bi-weekly:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.LA_UNEMP) - self.assertPayrollEqual(cats['EE_US_SIT'], wh_to_check) - - process_payslip(payslip) - - remaining_la_unemp_wages = self.LA_UNEMP_MAX_WAGE - salary if (self.LA_UNEMP_MAX_WAGE - 2*salary < salary) \ - else salary - - self._log('2019 Louisiana tax second payslip bi-weekly:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_la_unemp_wages * self.LA_UNEMP) diff --git a/l10n_us_hr_payroll/tests/test_us_la_louisiana_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_la_louisiana_payslip_2021.py new file mode 100755 index 00000000..d23c3ab3 --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_la_louisiana_payslip_2021.py @@ -0,0 +1,36 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsLAPayslip(TestUsPayslip): + ### + # 2020 Taxes and Rates + ### + LA_UNEMP_MAX_WAGE = 7700.0 + LA_UNEMP = 1.14 + # Calculation based on http://revenue.louisiana.gov/TaxForms/1306(1_12)TF.pdf + + def _test_sit(self, wage, filing_status, additional_withholding, exemptions, dependents, schedule_pay, date_start, expected_withholding): + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('LA'), + la_l4_sit_filing_status=filing_status, + state_income_tax_additional_withholding=additional_withholding, + la_l4_sit_exemptions=exemptions, + la_l4_sit_dependents=dependents, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + + self._log('Computed period tax: ' + str(expected_withholding)) + self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding) + + def test_2020_taxes_example(self): + self._test_er_suta('LA', self.LA_UNEMP, date(2020, 1, 1), wage_base=self.LA_UNEMP_MAX_WAGE) + self._test_sit(700.0, 'single', 0.0, 1.0, 2.0, 'weekly', date(2020, 1, 1), 19.43) + self._test_sit(4600.0, 'married', 0.0, 2.0, 3.0, 'bi-weekly', date(2020, 1, 1), 157.12) + self._test_sit(6000.0, 'single', 10.0, 2.0, 3.0, 'monthly', date(2020, 1, 1), 219.08) diff --git a/l10n_us_hr_payroll/tests/test_us_mi_michigan_payslip_2019.py b/l10n_us_hr_payroll/tests/test_us_mi_michigan_payslip_2019.py deleted file mode 100755 index b12baed2..00000000 --- a/l10n_us_hr_payroll/tests/test_us_mi_michigan_payslip_2019.py +++ /dev/null @@ -1,194 +0,0 @@ -# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. - -from .common import TestUsPayslip, process_payslip - - -class TestUsMIPayslip(TestUsPayslip): - # Taxes and Rates - MI_UNEMP_MAX_WAGE = 9500.0 - MI_UNEMP = - 2.7 / 100.0 - MI_INC_TAX = - 4.25 / 100.0 - ANNUAL_EXEMPTION_AMOUNT = 4400.00 - PAY_PERIOD_DIVISOR = { - 'weekly': 52.0, - 'bi-weekly': 26.0, - 'semi-monthly': 24.0, - 'monthly': 12.0 - } - - def test_2019_taxes_weekly(self): - salary = 5000.0 - schedule_pay = 'weekly' - exemptions = 1 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('MI'), - state_income_tax_additional_withholding=0.0, - mi_w4_sit_exemptions=1.0, - schedule_pay='weekly') - - allowance_amount = self.ANNUAL_EXEMPTION_AMOUNT / self.PAY_PERIOD_DIVISOR[schedule_pay] - wh = -((salary - (allowance_amount * exemptions)) * -self.MI_INC_TAX) - - self._log('2019 Michigan tax first payslip weekly:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.MI_UNEMP) - self.assertPayrollAlmostEqual(cats['EE_US_SIT'], wh) - # - process_payslip(payslip) - - # Make a new payslip, this one will have maximums - remaining_MI_UNEMP_wages = self.MI_UNEMP_MAX_WAGE - salary if (self.MI_UNEMP_MAX_WAGE - 2*salary < salary) \ - else salary - - self._log('2019 Michigan tax second payslip weekly:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_MI_UNEMP_wages * self.MI_UNEMP) - - def test_2019_taxes_biweekly(self): - salary = 5000.0 - schedule_pay = 'bi-weekly' - allowance_amount = self.ANNUAL_EXEMPTION_AMOUNT / self.PAY_PERIOD_DIVISOR[schedule_pay] - exemption = 2 - - wh = -((salary - (allowance_amount * exemption)) * -self.MI_INC_TAX) - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('MI'), - state_income_tax_additional_withholding=0.0, - mi_w4_sit_exemptions=2.0, - schedule_pay='bi-weekly') - - self._log('2019 Michigan tax first payslip bi-weekly:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.MI_UNEMP) - self.assertPayrollEqual(cats['EE_US_SIT'], wh) - - process_payslip(payslip) - - # Make a new payslip, this one will have maximums - remaining_MI_UNEMP_wages = self.MI_UNEMP_MAX_WAGE - salary if (self.MI_UNEMP_MAX_WAGE - 2*salary < salary) \ - else salary - - self._log('2019 Michigan tax second payslip bi-weekly:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_MI_UNEMP_wages * self.MI_UNEMP) - - def test_2019_taxes_semimonthly(self): - salary = 5000.0 - schedule_pay = 'semi-monthly' - allowance_amount = self.ANNUAL_EXEMPTION_AMOUNT / self.PAY_PERIOD_DIVISOR[schedule_pay] - exemption = 1 - - wh = -((salary - (allowance_amount * exemption)) * -self.MI_INC_TAX) - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('MI'), - state_income_tax_additional_withholding=0.0, - mi_w4_sit_exemptions=1.0, - schedule_pay='semi-monthly') - - self._log('2019 Michigan tax first payslip semi-monthly:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.MI_UNEMP) - self.assertPayrollEqual(cats['EE_US_SIT'], wh) - - process_payslip(payslip) - - # Make a new payslip, this one will have maximums - remaining_MI_UNEMP_wages = self.MI_UNEMP_MAX_WAGE - salary if (self.MI_UNEMP_MAX_WAGE - 2 * salary < salary) \ - else salary - - self._log('2019 Michigan tax second payslip semi-monthly:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_MI_UNEMP_wages * self.MI_UNEMP) - - def test_2019_taxes_monthly(self): - salary = 5000.0 - schedule_pay = 'monthly' - allowance_amount = self.ANNUAL_EXEMPTION_AMOUNT / self.PAY_PERIOD_DIVISOR[schedule_pay] - exemption = 1 - - wh = -((salary - (allowance_amount * exemption)) * -self.MI_INC_TAX) - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('MI'), - state_income_tax_additional_withholding=0.0, - mi_w4_sit_exemptions=1.0, - schedule_pay='monthly') - - self._log('2019 Michigan tax first payslip monthly:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.MI_UNEMP) - self.assertPayrollEqual(cats['EE_US_SIT'], wh) - - process_payslip(payslip) - - # Make a new payslip, this one will have maximums - remaining_MI_UNEMP_wages = self.MI_UNEMP_MAX_WAGE - salary if ( - self.MI_UNEMP_MAX_WAGE - (2 * salary) < salary) \ - else salary - - self._log('2019 Michigan tax second payslip monthly:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_MI_UNEMP_wages * self.MI_UNEMP) - - def test_additional_withholding(self): - salary = 5000.0 - schedule_pay = 'weekly' - allowance_amount = 0.0 - allowance_amount = self.ANNUAL_EXEMPTION_AMOUNT / self.PAY_PERIOD_DIVISOR[schedule_pay] - additional_wh = 40.0 - exemption = 1 - - wh = -(((salary - (allowance_amount * exemption)) * -self.MI_INC_TAX) + additional_wh) - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('MI'), - state_income_tax_additional_withholding=40.0, - mi_w4_sit_exemptions=1.0, - schedule_pay='weekly') - - self._log('2019 Michigan tax first payslip with additional withholding:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.MI_UNEMP) - self.assertPayrollAlmostEqual(cats['EE_US_SIT'], wh) - - process_payslip(payslip) diff --git a/l10n_us_hr_payroll/tests/test_us_mi_michigan_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_mi_michigan_payslip_2021.py new file mode 100755 index 00000000..690749f8 --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_mi_michigan_payslip_2021.py @@ -0,0 +1,35 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsMIPayslip(TestUsPayslip): + # Taxes and Rates + MI_UNEMP_MAX_WAGE = 9500.0 + MI_UNEMP = 2.7 + + def _test_sit(self, wage, exemptions, additional_withholding, schedule_pay, date_start, expected_withholding): + + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('MI'), + mi_w4_sit_exemptions=exemptions, + state_income_tax_additional_withholding=additional_withholding, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + + self._log('Computed period tax: ' + str(expected_withholding)) + self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding) + + def test_2021_taxes_example(self): + self._test_er_suta('MI', self.MI_UNEMP, date(2021, 1, 1), wage_base=self.MI_UNEMP_MAX_WAGE) + self._test_sit(750.0, 1, 100.0, 'weekly', date(2021, 1, 1), 127.87) + self._test_sit(1750.0, 1, 0.0, 'bi-weekly', date(2021, 1, 1), 66.37) + self._test_sit(5000.0, 1, 5.0, 'semi-monthly', date(2021, 1, 1), 208.83) + self._test_sit(8000.0, 1, 5.0, 'monthly', date(2021, 1, 1), 327.65) + self._test_sit(5000.0, 2, 0.0, 'monthly', date(2021, 1, 1), 177.79) + diff --git a/l10n_us_hr_payroll/tests/test_us_mn_minnesota_payslip_2019.py b/l10n_us_hr_payroll/tests/test_us_mn_minnesota_payslip_2019.py deleted file mode 100755 index 2a64b57d..00000000 --- a/l10n_us_hr_payroll/tests/test_us_mn_minnesota_payslip_2019.py +++ /dev/null @@ -1,159 +0,0 @@ -# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. - -from .common import TestUsPayslip, process_payslip - - -class TestUsMNPayslip(TestUsPayslip): - # TAXES AND RATES - MN_UNEMP_MAX_WAGE = 34000.0 - MN_UNEMP = -1.11 / 100.0 - - def test_taxes_weekly(self): - salary = 30000.0 - # Hand Calculated Amount to Test - # Step 1 -> 30000.00 for wages per period Step 2 -> 52.0 for weekly -> 30000 * 52 -> 1560000 - # Step 3 -> allowances * 4250.0 -> 4250.00 in this case. - # Step 4 -> Step 2 - Step 3 -> 1560000 - 4250.00 -> 1555750 - # Step 5 -> using chart -> we have last row -> ((1555750 - 166290) * (9.85 / 100)) + 11717.65 -> 148579.46 - # Step 6 -> Convert back to pay period amount and round - > 2857.297 - > 2857.0 - # wh = 2857.0 - wh = -2857.0 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('MN'), - mn_w4mn_sit_filing_status='single', - state_income_tax_additional_withholding=0.0, - mn_w4mn_sit_allowances=1.0, - schedule_pay='weekly') - - self._log('2019 Minnesota tax first payslip weekly:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.MN_UNEMP) - self.assertPayrollAlmostEqual(cats['EE_US_SIT'], wh) # Test numbers are off by 1 penny - - process_payslip(payslip) - - # Make a new payslip, this one will have maximums - remaining_MN_UNEMP_wages = self.MN_UNEMP_MAX_WAGE - salary if (self.MN_UNEMP_MAX_WAGE - 2*salary < salary) \ - else salary - - self._log('2019 Minnesota tax second payslip weekly:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_MN_UNEMP_wages * self.MN_UNEMP) - - def test_taxes_married(self): - salary = 5000.00 - - # Hand Calculated Amount to Test - # Step 1 -> 5000.0 for wages per period Step 2 -> 52.0 for weekly -> 5000 * 52 -> 260,000 - # Step 3 -> allowances * 4250.0 -> 4250.00 in this case. - # Step 4 -> Step 2 - Step 3 -> 260,000 - 4250.00 -> 255750.0 - # For step five we used the married section - # Step 5 -> using chart -> we have 2nd last row -> ((255750 - 163070) * (7.85 / 100)) + 10199.33 -> - # Step 6 -> Convert back to pay period amount and round - # wh = 336.0 - wh = -336.0 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('MN'), - mn_w4mn_sit_filing_status='married', - state_income_tax_additional_withholding=0.0, - mn_w4mn_sit_allowances=1.0, - schedule_pay='weekly') - - self._log('2019 Minnesota tax first payslip married:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.MN_UNEMP) - self.assertPayrollAlmostEqual(cats['EE_US_SIT'], wh) - - def test_taxes_semimonthly(self): - salary = 6500.00 - # Hand Calculated Amount to Test - # Step 1 -> 6500.00 for wages per period Step 2 -> 24 for semi-monthly -> 6500.00 * 24 -> 156000.00 - # Step 3 -> allowances * 4250.0 -> 4250.00 in this case. - # Step 4 -> Step 2 - Step 3 -> 156000.00 - 4250.00 -> 151750.0 - # Step 5 -> using chart -> we have 2nd last row -> ((151750.0- 89510) * (7.85 / 100)) + 5690.42 -> 10576.26 - # Step 6 -> Convert back to pay period amount and round - # wh = -441 - wh = -441.00 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('MN'), - mn_w4mn_sit_filing_status='single', - state_income_tax_additional_withholding=0.0, - mn_w4mn_sit_allowances=1.0, - schedule_pay='semi-monthly') - - - self._log('2019 Minnesota tax first payslip semimonthly:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.MN_UNEMP) - self.assertPayrollAlmostEqual(cats['EE_US_SIT'], wh) - - def test_tax_exempt(self): - salary = 5500.00 - wh = 0 - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('MN'), - mn_w4mn_sit_filing_status='', - state_income_tax_additional_withholding=0.0, - mn_w4mn_sit_allowances=2.0, - schedule_pay='weekly') - - self._log('2019 Minnesota tax first payslip exempt:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.MN_UNEMP) - self.assertPayrollAlmostEqual(cats['EE_US_SIT'], wh) - - def test_additional_withholding(self): - salary = 5500.0 - # Hand Calculated Amount to Test - # Step 1 -> 5500 for wages per period Step 2 -> 52 for weekly -> 5500 * 52 -> 286000.00 - # Step 3 -> allowances * 4250.0 -> 8500 in this case. - # Step 4 -> Step 2 - Step 3 -> 286000.00 - 8500 -> 277500 - # Step 5 -> using chart -> we have last row -> ((277500- 166290) * (9.85 / 100)) + 11717.65 -> 22671.835 - # Step 6 -> Convert back to pay period amount and round - # wh = -436.0 - # Add additional_withholding - # wh = -436.0 + 40.0 - wh = -476.0 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('MN'), - mn_w4mn_sit_filing_status='single', - state_income_tax_additional_withholding=40.0, - mn_w4mn_sit_allowances=2.0, - schedule_pay='weekly') - - self._log('2019 Minnesota tax first payslip additional withholding:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.MN_UNEMP) - self.assertPayrollAlmostEqual(cats['EE_US_SIT'], wh) diff --git a/l10n_us_hr_payroll/tests/test_us_mn_minnesota_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_mn_minnesota_payslip_2021.py new file mode 100755 index 00000000..dbae6ddd --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_mn_minnesota_payslip_2021.py @@ -0,0 +1,36 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsMNPayslip(TestUsPayslip): + # TAXES AND RATES + MN_UNEMP_MAX_WAGE = 35000.0 + MN_UNEMP = 1.11 + + def _test_sit(self, wage, filing_status, allowances, additional_withholding, schedule_pay, date_start, expected_withholding): + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('MN'), + mn_w4mn_sit_filing_status=filing_status, + state_income_tax_additional_withholding=additional_withholding, + mn_w4mn_sit_allowances=allowances, + schedule_pay=schedule_pay) + + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + + self._log('Computed period tax: ' + str(expected_withholding)) + self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding) + + def test_2021_taxes_example(self): + self._test_er_suta('MN', self.MN_UNEMP, date(2021, 1, 1), wage_base=self.MN_UNEMP_MAX_WAGE) + self._test_sit(5000.0, 'single', 1.0, 0.0, 'weekly', date(2021, 1, 1), 388.0) + self._test_sit(30000.0, 'single', 1.0, 0.0, 'weekly', date(2021, 1, 1), 2850.0) + self._test_sit(5000.0, 'married', 1.0, 0.0, 'weekly', date(2021, 1, 1), 325.0) + self._test_sit(6500.0, 'single', 1.0, 0.0, 'semi-monthly', date(2021, 1, 1), 428.0) + self._test_sit(5500.0, '', 2.0, 0.0, 'weekly', date(2021, 1, 1), 0.0) + self._test_sit(5500.0, 'single', 2.0, 40.0, 'weekly', date(2021, 1, 1), 469.0) diff --git a/l10n_us_hr_payroll/tests/test_us_mo_missouri_payslip_2019.py b/l10n_us_hr_payroll/tests/test_us_mo_missouri_payslip_2019.py deleted file mode 100755 index 27a0ad93..00000000 --- a/l10n_us_hr_payroll/tests/test_us_mo_missouri_payslip_2019.py +++ /dev/null @@ -1,188 +0,0 @@ - -from datetime import date -from .common import TestUsPayslip - - -class TestUsMoPayslip(TestUsPayslip): - # Calculations from http://dor.mo.gov/forms/4282_2019.pdf - SALARY = 12000.0 - MO_UNEMP = -2.376 / 100.0 - - TAX = [ - (1053.0, 1.5), - (1053.0, 2.0), - (1053.0, 2.5), - (1053.0, 3.0), - (1053.0, 3.5), - (1053.0, 4.0), - (1053.0, 4.5), - (1053.0, 5.0), - (999999999.0, 5.4), - ] - - def test_2019_taxes_single(self): - # Payroll Period Monthly - salary = self.SALARY - pp = 12.0 - gross_salary = salary * pp - spouse_employed = False - - # Single - standard_deduction = 12400.0 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('MO'), - mo_mow4_sit_filing_status='single', - state_income_tax_additional_withholding=0.0, - schedule_pay='monthly') - - self._log('2019 Missouri tax single first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.MO_UNEMP) - - mo_taxable_income = gross_salary - standard_deduction - self._log('%s = %s - %s -' % (mo_taxable_income, gross_salary, standard_deduction)) - - remaining_taxable_income = mo_taxable_income - tax = 0.0 - for amt, rate in self.TAX: - amt = float(amt) - rate = rate / 100.0 - self._log(str(amt) + ' : ' + str(rate) + ' : ' + str(remaining_taxable_income)) - if (remaining_taxable_income - amt) > 0.0 or (remaining_taxable_income - amt) == 0.0: - tax += rate * amt - else: - tax += rate * remaining_taxable_income - break - remaining_taxable_income = remaining_taxable_income - amt - - tax = -tax - self._log('Computed annual tax: ' + str(tax)) - - tax = tax / pp - tax = round(tax) - self._log('Computed period tax: ' + str(tax)) - self.assertPayrollEqual(cats['EE_US_SIT'], tax) - - def test_2019_spouse_not_employed(self): - # Payroll Period Semi-monthly - salary = self.SALARY - pp = 24.0 - gross_salary = salary * pp - - # Married - standard_deduction = 24800.0 - - employee = self._createEmployee() - - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('MO'), - mo_mow4_sit_filing_status='married', - state_income_tax_additional_withholding=0.0, - schedule_pay='semi-monthly') - - self._log('2019 Missouri tax first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - mo_taxable_income = gross_salary - standard_deduction - self._log(mo_taxable_income) - - remaining_taxable_income = mo_taxable_income - tax = 0.0 - for amt, rate in self.TAX: - amt = float(amt) - rate = rate / 100.0 - self._log(str(amt) + ' : ' + str(rate) + ' : ' + str(remaining_taxable_income)) - if (remaining_taxable_income - amt) > 0.0 or (remaining_taxable_income - amt) == 0.0: - tax += rate * amt - else: - tax += rate * remaining_taxable_income - break - remaining_taxable_income = remaining_taxable_income - amt - - tax = -tax - self._log('Computed annual tax: ' + str(tax)) - - tax = tax / pp - tax = round(tax) - self._log('Computed period tax: ' + str(tax)) - self.assertPayrollEqual(cats['EE_US_SIT'], tax) - - def test_2019_head_of_household(self): - # Payroll Period Weekly - salary = self.SALARY - - # Payroll Period Weekly - salary = self.SALARY - pp = 52.0 - gross_salary = salary * pp - - # Single HoH - standard_deduction = 18650.0 - - employee = self._createEmployee() - - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('MO'), - mo_mow4_sit_filing_status='head_of_household', - state_income_tax_additional_withholding=0.0, - schedule_pay='weekly') - - self._log('2019 Missouri tax first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - mo_taxable_income = gross_salary - standard_deduction - self._log(mo_taxable_income) - - remaining_taxable_income = mo_taxable_income - tax = 0.0 - for amt, rate in self.TAX: - amt = float(amt) - rate = rate / 100.0 - self._log(str(amt) + ' : ' + str(rate) + ' : ' + str(remaining_taxable_income)) - if (remaining_taxable_income - amt) > 0.0 or (remaining_taxable_income - amt) == 0.0: - tax += rate * amt - else: - tax += rate * remaining_taxable_income - break - remaining_taxable_income = remaining_taxable_income - amt - tax = -tax - self._log('Computed annual tax: ' + str(tax)) - - tax = tax / pp - tax = round(tax) - self._log('Computed period tax: ' + str(tax)) - self.assertPayrollEqual(cats['EE_US_SIT'], tax) - - def test_2019_underflow(self): - # Payroll Period Weekly - salary = 200.0 - - employee = self._createEmployee() - - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('MO')) - - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['EE_US_SIT'], 0.0) diff --git a/l10n_us_hr_payroll/tests/test_us_mo_missouri_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_mo_missouri_payslip_2021.py new file mode 100755 index 00000000..0824e2b9 --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_mo_missouri_payslip_2021.py @@ -0,0 +1,34 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsMoPayslip(TestUsPayslip): + # Calculations from http://dor.mo.gov/forms/4282_2021.pdf + MO_UNEMP_MAX_WAGE = 11000.0 + MO_UNEMP = 2.7 + + def _test_sit(self, wage, filing_status, additional_withholding, schedule_pay, date_start, expected_withholding): + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('MO'), + mo_mow4_sit_filing_status=filing_status, + state_income_tax_additional_withholding=additional_withholding, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + + self._log('Computed period tax: ' + str(expected_withholding)) + self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding) + + def test_2021_taxes_example(self): + self._test_er_suta('MO', self.MO_UNEMP, date(2021, 1, 1), wage_base=self.MO_UNEMP_MAX_WAGE) + self._test_sit(750.0, 'single', 0.0, 'weekly', date(2021, 1, 1), 24.00) + self._test_sit(2500.0, 'single', 5.0, 'bi-weekly', date(2021, 1, 1), 107.00) + self._test_sit(7000.0, 'married', 0.0, 'monthly', date(2021, 1, 1), 249.00) + self._test_sit(5000.0, 'married', 10.0, 'semi-monthly', date(2021, 1, 1), 216.00) + self._test_sit(6000.0, '', 0.0, 'monthly', date(2021, 1, 1), 0.00) + diff --git a/l10n_us_hr_payroll/tests/test_us_ms_mississippi_payslip_2019.py b/l10n_us_hr_payroll/tests/test_us_ms_mississippi_payslip_2019.py deleted file mode 100755 index e7ce35d0..00000000 --- a/l10n_us_hr_payroll/tests/test_us_ms_mississippi_payslip_2019.py +++ /dev/null @@ -1,94 +0,0 @@ -# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. - -from .common import TestUsPayslip - - -class TestUsMsPayslip(TestUsPayslip): - # Calculations from https://www.dor.ms.gov/Documents/Computer%20Payroll%20Accounting%201-2-19.pdf - MS_UNEMP = -1.2 / 100.0 - - def test_2019_taxes_one(self): - salary = 1250.0 - ms_89_350_exemption = 11000.0 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('MS'), - ms_89_350_sit_filing_status='head_of_household', - ms_89_350_sit_exemption_value=ms_89_350_exemption, - state_income_tax_additional_withholding=0.0, - schedule_pay='semi-monthly') - - self._log('2019 Mississippi tax single first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.MS_UNEMP) - - STDED = 3400.0 # Head of Household - AGP = salary * 24 # Semi-Monthly - TI = AGP - (ms_89_350_exemption + STDED) - self.assertPayrollEqual(TI, 15600.0) - TAX = ((TI - 10000) * 0.05) + 290 # Over 10,000 - self.assertPayrollEqual(TAX, 570.0) - - ms_withhold = round(TAX / 24) # Semi-Monthly - self.assertPayrollEqual(cats['EE_US_SIT'], -ms_withhold) - - def test_2019_taxes_one_exempt(self): - salary = 1250.0 - ms_89_350_exemption = 11000.0 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('MS'), - ms_89_350_sit_filing_status='', - ms_89_350_sit_exemption_value=ms_89_350_exemption, - state_income_tax_additional_withholding=0.0, - schedule_pay='semi-monthly') - - self._log('2019 Mississippi tax single first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), 0.0) - - def test_2019_taxes_additional(self): - salary = 1250.0 - ms_89_350_exemption = 11000.0 - additional = 40.0 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('MS'), - ms_89_350_sit_filing_status='head_of_household', - ms_89_350_sit_exemption_value=ms_89_350_exemption, - state_income_tax_additional_withholding=additional, - schedule_pay='semi-monthly') - - self._log('2019 Mississippi tax single first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.MS_UNEMP) - - STDED = 3400.0 # Head of Household - AGP = salary * 24 # Semi-Monthly - TI = AGP - (ms_89_350_exemption + STDED) - self.assertPayrollEqual(TI, 15600.0) - TAX = ((TI - 10000) * 0.05) + 290 # Over 10,000 - self.assertPayrollEqual(TAX, 570.0) - - ms_withhold = round(TAX / 24) # Semi-Monthly - self.assertPayrollEqual(cats['EE_US_SIT'], -ms_withhold + -additional) diff --git a/l10n_us_hr_payroll/tests/test_us_ms_mississippi_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_ms_mississippi_payslip_2021.py new file mode 100755 index 00000000..d59bded9 --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_ms_mississippi_payslip_2021.py @@ -0,0 +1,35 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsMsPayslip(TestUsPayslip): + # Calculations from https://www.dor.ms.gov/Documents/Computer%20Payroll%20Flowchart.pdf + MS_UNEMP = 1.0 + MS_UNEMP_MAX_WAGE = 14000.0 + + def _test_sit(self, wage, filing_status, additional_withholding, exemption, schedule_pay, date_start, expected_withholding): + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('MS'), + ms_89_350_sit_filing_status=filing_status, + state_income_tax_additional_withholding=additional_withholding, + ms_89_350_sit_exemption_value=exemption, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + + self._log('Computed period tax: ' + str(expected_withholding)) + self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding) + + def test_2021_taxes_example(self): + self._test_er_suta('MS', self.MS_UNEMP, date(2021, 1, 1), wage_base=self.MS_UNEMP_MAX_WAGE) + self._test_sit(1250.0, 'head_of_household', 0.0, 11000, 'semi-monthly', date(2021, 1, 1), 21.00) + self._test_sit(500.0, '', 5.0, 0, 'bi-weekly', date(2021, 1, 1), 0.00) + self._test_sit(12000.0, 'single', 0.0, 11000, 'monthly', date(2021, 1, 1), 522.00) + self._test_sit(2500.0, 'married', 5.0, 500, 'bi-weekly', date(2021, 1, 1), 110.00) + + diff --git a/l10n_us_hr_payroll/tests/test_us_mt_montana_payslip_2019.py b/l10n_us_hr_payroll/tests/test_us_mt_montana_payslip_2019.py deleted file mode 100755 index ff6e2daf..00000000 --- a/l10n_us_hr_payroll/tests/test_us_mt_montana_payslip_2019.py +++ /dev/null @@ -1,139 +0,0 @@ -# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. - -from .common import TestUsPayslip, process_payslip - - -class TestUsMtPayslip(TestUsPayslip): - # Calculations from https://app.mt.gov/myrevenue/Endpoint/DownloadPdf?yearId=705 - MT_UNEMP = -1.18 / 100.0 - MT_UNEMP_AFT = -0.13 / 100.0 - - def test_2019_taxes_one(self): - # Payroll Period Semi-Monthly example - salary = 550 - mt_mw4_exemptions = 5 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('MT'), - mt_mw4_sit_exemptions=mt_mw4_exemptions, - schedule_pay='semi-monthly') - - self._log('2019 Montana tax single first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * (self.MT_UNEMP + self.MT_UNEMP_AFT)) # New non-combined... - - mt_taxable_income = salary - (79.0 * mt_mw4_exemptions) - mt_withhold = round(0 + (0.018 * (mt_taxable_income - 0))) - self.assertPayrollEqual(mt_taxable_income, 155.0) - self.assertPayrollEqual(mt_withhold, 3.0) - self.assertPayrollEqual(cats['EE_US_SIT'], -mt_withhold) - - def test_2019_taxes_two(self): - # Payroll Period Bi-Weekly example - salary = 2950 - mt_mw4_exemptions = 2 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('MT'), - mt_mw4_sit_exemptions=mt_mw4_exemptions, - schedule_pay='bi-weekly') - - self._log('2019 Montana tax single first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], round(salary * (self.MT_UNEMP + self.MT_UNEMP_AFT), 2)) - - # Note!! - # The example calculation uses A = 16 but the actual table describes this as A = 18 - mt_taxable_income = salary - (73.0 * mt_mw4_exemptions) - mt_withhold = round(18 + (0.06 * (mt_taxable_income - 577))) - self.assertPayrollEqual(mt_taxable_income, 2804.0) - self.assertPayrollEqual(mt_withhold, 152.0) - self.assertPayrollEqual(cats['EE_US_SIT'], -mt_withhold) - - def test_2019_taxes_three(self): - # Payroll Period Weekly example - salary = 135 - mt_mw4_exemptions = 1 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('MT'), - mt_mw4_sit_exemptions=mt_mw4_exemptions, - schedule_pay='weekly') - - self._log('2019 Montana tax single first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], round(salary * (self.MT_UNEMP + self.MT_UNEMP_AFT), 2)) - - mt_taxable_income = salary - (37.0 * mt_mw4_exemptions) - mt_withhold = round(0 + (0.018 * (mt_taxable_income - 0))) - self.assertPayrollEqual(mt_taxable_income, 98.0) - self.assertPayrollEqual(mt_withhold, 2.0) - self.assertPayrollEqual(cats['EE_US_SIT'], -mt_withhold) - - def test_2019_taxes_three_exempt(self): - # Payroll Period Weekly example - salary = 135 - mt_mw4_exemptions = 1 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('MT'), - mt_mw4_sit_exemptions=mt_mw4_exemptions, - mt_mw4_sit_exempt='reserve', - schedule_pay='weekly') - - self._log('2019 Montana tax single first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), 0.0) - - def test_2019_taxes_three_additional(self): - # Payroll Period Weekly example - salary = 135 - mt_mw4_exemptions = 1 - mt_mw4_additional_withholding = 20.0 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('MT'), - mt_mw4_sit_exemptions=mt_mw4_exemptions, - state_income_tax_additional_withholding=mt_mw4_additional_withholding, - schedule_pay='weekly') - - self._log('2019 Montana tax single first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - cats = self._getCategories(payslip) - - mt_taxable_income = salary - (37.0 * mt_mw4_exemptions) - mt_withhold = round(0 + (0.018 * (mt_taxable_income - 0))) - self.assertPayrollEqual(mt_taxable_income, 98.0) - self.assertPayrollEqual(mt_withhold, 2.0) - self.assertPayrollEqual(cats['EE_US_SIT'], -mt_withhold + -mt_mw4_additional_withholding) diff --git a/l10n_us_hr_payroll/tests/test_us_mt_montana_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_mt_montana_payslip_2021.py new file mode 100755 index 00000000..755f6208 --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_mt_montana_payslip_2021.py @@ -0,0 +1,37 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsMtPayslip(TestUsPayslip): + ### + # 2021 Taxes and Rates + ### + MT_UNEMP_WAGE_MAX = 35300.0 + MT_UNEMP = 1.18 + MT_UNEMP_AFT = 0.13 + + # Calculations from https://app.mt.gov/myrevenue/Endpoint/DownloadPdf?yearId=705 + def _test_sit(self, wage, additional_withholding, exemptions, schedule_pay, date_start, expected_withholding): + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('MT'), + state_income_tax_additional_withholding=additional_withholding, + mt_mw4_sit_exemptions=exemptions, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + + self._log('Computed period tax: ' + str(expected_withholding)) + self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding) + + def test_2021_taxes_one(self): + combined_rate = self.MT_UNEMP + self.MT_UNEMP_AFT # Combined for test as they both go to the same category and have the same cap + self._test_er_suta('MT', combined_rate + .0001, date(2021, 1, 1), wage_base=self.MT_UNEMP_WAGE_MAX, relaxed=True) + self._test_sit(550.0, 0.0, 5.0, 'semi-monthly', date(2021, 1, 1), 3.0) + self._test_sit(2950.0, 10.0, 2.0, 'bi-weekly', date(2021, 1, 1), 162.0) + self._test_sit(5000.0, 0.0, 1.0, 'monthly', date(2021, 1, 1), 256.0) + self._test_sit(750.0, 0.0, 1.0, 'weekly', date(2021, 1, 1), 34.0) diff --git a/l10n_us_hr_payroll/tests/test_us_nc_northcarolina_payslip_2019.py b/l10n_us_hr_payroll/tests/test_us_nc_northcarolina_payslip_2019.py deleted file mode 100755 index 14c1c5b2..00000000 --- a/l10n_us_hr_payroll/tests/test_us_nc_northcarolina_payslip_2019.py +++ /dev/null @@ -1,270 +0,0 @@ -# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. - -from .common import TestUsPayslip, process_payslip - - -class TestUsNCPayslip(TestUsPayslip): - ### - # Taxes and Rates - ### - NC_UNEMP_MAX_WAGE = 24300.0 - NC_UNEMP = -1.0 / 100.0 - NC_INC_TAX = -0.0535 - - - def test_2019_taxes_weekly(self): - salary = 20000.0 - # allowance_multiplier and Portion of Standard Deduction for weekly - allowance_multiplier = 48.08 - PST = 192.31 - exemption = 1 - # Algorithm derived from percentage method in https://files.nc.gov/ncdor/documents/files/nc-30_book_web.pdf - wh = -round((salary - (PST + (allowance_multiplier * exemption))) * -self.NC_INC_TAX) - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('NC'), - nc_nc4_sit_filing_status='married', - state_income_tax_additional_withholding=0.0, - nc_nc4_sit_allowances=1.0, - schedule_pay='weekly') - - self._log('2019 North Carolina tax first payslip weekly:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['EE_US_SIT'], wh) - - process_payslip(payslip) - - # Make a new payslip, this one will have maximums - - remaining_NC_UNEMP_wages = self.NC_UNEMP_MAX_WAGE - salary if (self.NC_UNEMP_MAX_WAGE - 2*salary < salary) \ - else salary - self._log('2019 North Carolina tax second payslip weekly:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_NC_UNEMP_wages * self.NC_UNEMP) - - def test_2019_taxes_with_external_weekly(self): - salary = 5000.0 - schedule_pay = 'weekly' - - employee = self._createEmployee() - - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('NC'), - nc_nc4_sit_filing_status='married', - state_income_tax_additional_withholding=0.0, - nc_nc4_sit_allowances=1.0, - schedule_pay='weekly') - - self._log('2019 NorthCarolina_external tax first payslip weekly:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.NC_UNEMP) - - def test_2019_taxes_biweekly(self): - salary = 5000.0 - schedule_pay = 'bi-weekly' - # allowance_multiplier and Portion of Standard Deduction for weekly - allowance_multiplier = 96.15 - PST = 384.62 - - allowances = 2 - # Algorithm derived from percentage method in https://files.nc.gov/ncdor/documents/files/nc-30_book_web.pdf - - wh = -round((salary - (PST + (allowance_multiplier * allowances))) * -self.NC_INC_TAX) - - employee = self._createEmployee() - - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('NC'), - nc_nc4_sit_filing_status='married', - state_income_tax_additional_withholding=0.0, - nc_nc4_sit_allowances=2.0, - schedule_pay='bi-weekly') - - self._log('2019 North Carolina tax first payslip bi-weekly:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.NC_UNEMP) - self.assertPayrollEqual(cats['EE_US_SIT'], wh) - - process_payslip(payslip) - - # Make a new payslip, this one will have maximums - - remaining_NC_UNEMP_wages = self.NC_UNEMP_MAX_WAGE - salary if (self.NC_UNEMP_MAX_WAGE - 2*salary < salary) \ - else salary - - self._log('2019 North Carolina tax second payslip bi-weekly:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_NC_UNEMP_wages * self.NC_UNEMP) - - def test_2019_taxes_semimonthly(self): - salary = 4000.0 - # allowance_multiplier and Portion of Standard Deduction for weekly - allowance_multiplier = 104.17 - PST = 625.00 - - allowances = 1 - # Algorithm derived from percentage method in https://files.nc.gov/ncdor/documents/files/nc-30_book_web.pdf - - wh = -round((salary - (PST + (allowance_multiplier * allowances))) * -self.NC_INC_TAX) - - employee = self._createEmployee() - - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('NC'), - nc_nc4_sit_filing_status='head_household', - state_income_tax_additional_withholding=0.0, - nc_nc4_sit_allowances=1.0, - schedule_pay='semi-monthly') - - self._log('2019 North Carolina tax first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.NC_UNEMP) - self.assertPayrollEqual(cats['EE_US_SIT'], wh) - - process_payslip(payslip) - - # Make a new payslip, this one will have maximums - - remaining_NC_UNEMP_wages = self.NC_UNEMP_MAX_WAGE - salary if (self.NC_UNEMP_MAX_WAGE - 2 * salary < salary) \ - else salary - - self._log('2019 North Carolina tax second payslip:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_NC_UNEMP_wages * self.NC_UNEMP) - - def test_2019_taxes_monthly(self): - salary = 4000.0 - schedule_pay = 'monthly' - # allowance_multiplier and Portion of Standard Deduction for weekly - allowance_multiplier = 208.33 - PST = 833.33 - - allowances = 1 - # Algorithm derived from percentage method in https://files.nc.gov/ncdor/documents/files/nc-30_book_web.pdf - - wh = -round((salary - (PST + (allowance_multiplier * allowances))) * -self.NC_INC_TAX) - - employee = self._createEmployee() - - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('NC'), - nc_nc4_sit_filing_status='single', - state_income_tax_additional_withholding=0.0, - nc_nc4_sit_allowances=1.0, - schedule_pay='monthly') - - self._log('2019 North Carolina tax first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.NC_UNEMP) - self.assertPayrollEqual(cats['EE_US_SIT'], wh) - - process_payslip(payslip) - - # Make a new payslip, this one will have maximums - - remaining_NC_UNEMP_wages = self.NC_UNEMP_MAX_WAGE - salary if ( - self.NC_UNEMP_MAX_WAGE - 2 * salary < salary) \ - else salary - - self._log('2019 North Carolina tax second payslip:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_NC_UNEMP_wages * self.NC_UNEMP) - - def test_additional_withholding(self): - salary = 4000.0 - # allowance_multiplier and Portion of Standard Deduction for weekly - allowance_multiplier = 48.08 - PST = 192.31 - additional_wh = 40.0 - - #4000 - (168.27 + (48.08 * 1) - - allowances = 1 - # Algorithm derived from percentage method in https://files.nc.gov/ncdor/documents/files/nc-30_book_web.pdf - - wh = -round(((salary - (PST + (allowance_multiplier * allowances))) * -self.NC_INC_TAX) + additional_wh) - - employee = self._createEmployee() - - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('NC'), - nc_nc4_sit_filing_status='married', - state_income_tax_additional_withholding=40.0, - nc_nc4_sit_allowances=1.0, - schedule_pay='weekly') - - self._log('2019 North Carolina tax first payslip weekly:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - self.assertPayrollEqual(cats['EE_US_SIT'], wh) - - process_payslip(payslip) - - # Make a new payslip, this one will have maximums - - remaining_NC_UNEMP_wages = self.NC_UNEMP_MAX_WAGE - salary if (self.NC_UNEMP_MAX_WAGE - 2 * salary < salary) \ - else salary - - self._log('2019 North Carolina tax second payslip weekly:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_NC_UNEMP_wages * self.NC_UNEMP) diff --git a/l10n_us_hr_payroll/tests/test_us_nc_northcarolina_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_nc_northcarolina_payslip_2021.py new file mode 100755 index 00000000..b8119f21 --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_nc_northcarolina_payslip_2021.py @@ -0,0 +1,39 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsNCPayslip(TestUsPayslip): + ### + # 2021 Taxes and Rates + ### + # Example based on https://files.nc.gov/ncdor/documents/files/2021-NC-30-Final.pdf page 19 + NC_UNEMP_MAX_WAGE = 26000.0 + NC_UNEMP = 1.0 + # get NC_INC_TAX from 'Annualized Tax" line 8 in the example on page 19 + NC_INC_TAX = 0.0535 + + def _test_sit(self, wage, filing_status, allowances, additional_withholding, schedule_pay, date_start, expected_withholding): + + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('NC'), + nc_nc4_sit_filing_status=filing_status, + nc_nc4_sit_allowances=allowances, + state_income_tax_additional_withholding=additional_withholding, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + + self._log('Computed period tax: ' + str(expected_withholding)) + self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding if filing_status else 0.0) + + def test_2021_taxes_example(self): + self._test_er_suta('NC', self.NC_UNEMP, date(2021, 1, 1), wage_base=self.NC_UNEMP_MAX_WAGE) + self._test_sit(20000.0, 'single', 1, 100.0, 'weekly', date(2021, 1, 1), 1156.0) + self._test_sit(5000.0, 'married', 1, 0.0, 'weekly', date(2021, 1, 1), 254.0) + self._test_sit(4000.0, 'head_household', 1, 5.0, 'semi-monthly', date(2021, 1, 1), 177.0) + self._test_sit(7000.0, '', 1, 5.0, 'monthly', date(2021, 1, 1), 0.0) diff --git a/l10n_us_hr_payroll/tests/test_us_nd_north_dakota_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_nd_north_dakota_payslip_2021.py new file mode 100644 index 00000000..c4dfaeb5 --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_nd_north_dakota_payslip_2021.py @@ -0,0 +1,37 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsNDPayslip(TestUsPayslip): + ### + # 2021 Taxes and Rates + ### + ND_UNEMP_MAX_WAGE = 38500.0 + ND_UNEMP = 1.02 + # Calculation based on this file page.47 https://www.nd.gov/tax/data/upfiles/media/rates-and-instructions.pdf?20210110115917 + + def _test_sit(self, wage, filing_status, additional_withholding, allowances, schedule_pay, date_start, expected_withholding): + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('ND'), + nd_w4_sit_filing_status=filing_status, + state_income_tax_additional_withholding=additional_withholding, + nd_w4_sit_allowances=allowances, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + + self._log('Computed period tax: ' + str(expected_withholding)) + self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding) + + def test_2021_taxes_example(self): + self._test_er_suta('ND', self.ND_UNEMP, date(2021, 1, 1), wage_base=self.ND_UNEMP_MAX_WAGE) + self._test_sit(700.0, 'single', 0.0, 0.0, 'weekly', date(2021, 1, 1), 6.0) + self._test_sit(5000.0, 'married', 0.0, 2.0, 'bi-weekly', date(2021, 1, 1), 76.0) + self._test_sit(25000.0, 'head_household', 0.0, 0.0, 'monthly', date(2021, 1, 1), 533.0) + self._test_sit(25000.0, 'head_household', 10.0, 2.0, 'monthly', date(2021, 1, 1), 524.0) + self._test_sit(3000.0, '', 10.0, 2.0, 'monthly', date(2021, 1, 1), 0.0) diff --git a/l10n_us_hr_payroll/tests/test_us_ne_nebraska_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_ne_nebraska_payslip_2021.py new file mode 100644 index 00000000..294856a7 --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_ne_nebraska_payslip_2021.py @@ -0,0 +1,38 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsNEPayslip(TestUsPayslip): + ### + # 2021 Taxes and Rates + ### + NE_UNEMP_MAX_WAGE = 9000.0 + NE_UNEMP = 2.5 + + def _test_sit(self, wage, filing_status, exempt, additional_withholding, allowances, schedule_pay, date_start, expected_withholding): + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('NE'), + ne_w4n_sit_filing_status=filing_status, + state_income_tax_exempt=exempt, + state_income_tax_additional_withholding=additional_withholding, + ne_w4n_sit_allowances=allowances, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + + self._log('Computed period tax: ' + str(expected_withholding)) + self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding) + + def test_2021_taxes_example(self): + self._test_er_suta('NE', self.NE_UNEMP, date(2021, 1, 1), wage_base=self.NE_UNEMP_MAX_WAGE) + self._test_sit(750.0, 'single', False, 0.0, 2, 'weekly', date(2021, 1, 1), 27.53) + self._test_sit(9500.0, 'single', False, 0.0, 1, 'bi-weekly', date(2021, 1, 1), 612.63) + self._test_sit(10500.0, 'married', False, 0.0, 1, 'bi-weekly', date(2021, 1, 1), 659.85) + self._test_sit(9500.0, 'single', True, 0.0, 1, 'bi-weekly', date(2021, 1, 1), 0.0) + self._test_sit(10500.0, 'single', False, 10.0, 2, 'monthly', date(2021, 1, 1), 625.2) + self._test_sit(4000.0, 'single', False, 0.0, 1, 'monthly', date(2021, 1, 1), 179.44) diff --git a/l10n_us_hr_payroll/tests/test_us_nh_new_hampshire_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_nh_new_hampshire_payslip_2021.py new file mode 100644 index 00000000..5c1b4a1f --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_nh_new_hampshire_payslip_2021.py @@ -0,0 +1,13 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date +from .common import TestUsPayslip + + +class TestUsNHPayslip(TestUsPayslip): + # TAXES AND RATES + NH_UNEMP_MAX_WAGE = 14000.00 + NH_UNEMP = 2.7 + + def test_2021_taxes(self): + self._test_er_suta('NH', self.NH_UNEMP, date(2021, 1, 1), wage_base=self.NH_UNEMP_MAX_WAGE) diff --git a/l10n_us_hr_payroll/tests/test_us_nj_newjersey_payslip_2019.py b/l10n_us_hr_payroll/tests/test_us_nj_newjersey_payslip_2019.py deleted file mode 100755 index c28849b5..00000000 --- a/l10n_us_hr_payroll/tests/test_us_nj_newjersey_payslip_2019.py +++ /dev/null @@ -1,128 +0,0 @@ -# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. - -from .common import TestUsPayslip, process_payslip - - -class TestUsNJPayslip(TestUsPayslip): - ### - # 2019 Taxes and Rates - ### - NJ_UNEMP_MAX_WAGE = 34400.0 # Note that this is used for SDI and FLI as well - - ER_NJ_UNEMP = -2.6825 / 100.0 - EE_NJ_UNEMP = -0.3825 / 100.0 - - ER_NJ_SDI = -0.5 / 100.0 - EE_NJ_SDI = -0.17 / 100.0 - - ER_NJ_WF = -0.1175 / 100.0 - EE_NJ_WF = -0.0425 / 100.0 - - ER_NJ_FLI = 0.0 - EE_NJ_FLI = -0.08 / 100.0 - - # Examples found on page 24 of http://www.state.nj.us/treasury/taxation/pdf/current/njwt.pdf - def test_2019_taxes_example1(self): - salary = 300 - - # Tax Percentage Method for Single, taxable under $385 - wh = -4.21 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('NJ'), - nj_njw4_sit_filing_status='single', - nj_njw4_sit_allowances=1, - state_income_tax_additional_withholding=0.0, - nj_njw4_sit_rate_table='A', - schedule_pay='weekly') - - self._log('2019 New Jersey tax first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['EE_US_SUTA'], salary * (self.EE_NJ_UNEMP + self.EE_NJ_SDI + self.EE_NJ_WF + self.EE_NJ_FLI)) - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * (self.ER_NJ_UNEMP + self.ER_NJ_SDI + self.ER_NJ_WF + self.ER_NJ_FLI)) - self.assertTrue(all((cats['EE_US_SUTA'], cats['ER_US_SUTA']))) - # self.assertPayrollEqual(cats['EE_US_NJ_SDI_SIT'], cats['EE_US_NJ_SDI_SIT'] * self.EE_NJ_SDI) - # self.assertPayrollEqual(cats['ER_US_NJ_SDI_SUTA'], cats['ER_US_NJ_SDI_SUTA'] * self.ER_NJ_SDI) - # self.assertPayrollEqual(cats['EE_US_NJ_FLI_SIT'], cats['EE_US_NJ_FLI_SIT'] * self.EE_NJ_FLI) - # self.assertPayrollEqual(cats['EE_US_NJ_WF_SIT'], cats['EE_US_NJ_WF_SIT'] * self.EE_NJ_WF) - self.assertPayrollEqual(cats['EE_US_SIT'], wh) - - process_payslip(payslip) - - # # Make a new payslip, this one will have maximums - # - remaining_nj_unemp_wages = self.NJ_UNEMP_MAX_WAGE - salary if (self.NJ_UNEMP_MAX_WAGE - 2 * salary < salary) \ - else salary - - self._log('2019 New Jersey tax second payslip:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - # self.assertPayrollEqual(cats['WAGE_US_NJ_UNEMP'], remaining_nj_unemp_wages) - self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_nj_unemp_wages * (self.ER_NJ_UNEMP + self.ER_NJ_SDI + self.ER_NJ_WF + self.ER_NJ_FLI)) - self.assertPayrollEqual(cats['EE_US_SUTA'], remaining_nj_unemp_wages * (self.EE_NJ_UNEMP + self.EE_NJ_SDI + self.EE_NJ_WF + self.EE_NJ_FLI)) - - def test_2019_taxes_example2(self): - salary = 1400.00 - - # Tax Percentage Method for Single, taxable pay over $962, under $1346 - wh = -27.58 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('NJ'), - nj_njw4_sit_filing_status='married_separate', - nj_njw4_sit_allowances=3, - state_income_tax_additional_withholding=0.0, - #nj_njw4_sit_rate_table='B', - schedule_pay='weekly') - - self.assertEqual(contract.schedule_pay, 'weekly') - - self._log('2019 New Jersey tax first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['EE_US_SIT'], wh) - - - def test_2019_taxes_to_the_limits(self): - salary = 30000.00 - - # Tax Percentage Method for Single, taxable pay over $18750, under 125000 - wh = -1467.51 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('NJ'), - nj_njw4_sit_filing_status='married_joint', - nj_njw4_sit_allowances=3, - state_income_tax_additional_withholding=0.0, - # nj_njw4_sit_rate_table='B', - schedule_pay='quarterly') - - self.assertEqual(contract.schedule_pay, 'quarterly') - - self._log('2019 New Jersey tax first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-03-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['EE_US_SIT'], wh) diff --git a/l10n_us_hr_payroll/tests/test_us_nj_newjersey_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_nj_newjersey_payslip_2021.py new file mode 100755 index 00000000..2b3fc627 --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_nj_newjersey_payslip_2021.py @@ -0,0 +1,51 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsNJPayslip(TestUsPayslip): + ### + # 2021 Taxes and Rates + ### + NJ_UNEMP_MAX_WAGE = 36200.0 # Note that this is used for SDI and FLI as well + + ER_NJ_UNEMP = 2.6825 + EE_NJ_UNEMP = 0.3825 + + ER_NJ_SDI = 0.5 + EE_NJ_SDI = 0.47 + + ER_NJ_WF = 0.1175 + EE_NJ_WF = 0.0425 + + ER_NJ_FLI = 0.0 + EE_NJ_FLI = 0.28 + + def _test_sit(self, wage, filing_status, allowances, schedule_pay, date_start, expected_withholding, rate_table=False): + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('NJ'), + nj_njw4_sit_filing_status=filing_status, + nj_njw4_sit_allowances=allowances, + state_income_tax_additional_withholding=0.0, + nj_njw4_sit_rate_table=rate_table, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding if filing_status else 0.0) + + def test_2021_taxes_example1(self): + combined_er_rate = self.ER_NJ_UNEMP + self.ER_NJ_FLI + self.ER_NJ_SDI + self.ER_NJ_WF + self._test_er_suta('NJ', combined_er_rate, date(2021, 1, 1), wage_base=self.NJ_UNEMP_MAX_WAGE, relaxed=True) + combined_ee_rate = self.EE_NJ_UNEMP + self.EE_NJ_FLI + self.EE_NJ_SDI + self.EE_NJ_WF + self._test_ee_suta('NJ', combined_ee_rate, date(2021, 1, 1), wage_base=self.NJ_UNEMP_MAX_WAGE, relaxed=True) + # these expected values come from https://www.state.nj.us/treasury/taxation/pdf/current/njwt.pdf + self._test_sit(300.0, 'single', 1, 'weekly', date(2021, 1, 1), 4.21) + self._test_sit(375.0, 'married_separate', 3, 'weekly', date(2021, 1, 1), 4.76) + self._test_sit(1400.0, 'head_household', 3, 'weekly', date(2021, 1, 1), 27.60) + self._test_sit(1400.0, '', 3, 'weekly', date(2021, 1, 1), 0.00) + self._test_sit(2500.0, 'single', 3, 'bi-weekly', date(2021, 1, 1), 82.66) + self._test_sit(15000.0, 'married_joint', 2, 'monthly', date(2021, 1, 1), 844.85) diff --git a/l10n_us_hr_payroll/tests/test_us_nm_new_mexico_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_nm_new_mexico_payslip_2021.py new file mode 100755 index 00000000..317977ba --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_nm_new_mexico_payslip_2021.py @@ -0,0 +1,36 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsNMPayslip(TestUsPayslip): + ### + # 2021 Taxes and Rates + ### + NM_UNEMP_MAX_WAGE = 27000.0 + NM_UNEMP = 1.0 + # Calculation based on section 17. https://s3.amazonaws.com/realFile34821a95-73ca-43e7-b06d-fad20f5183fd/a9bf1098-533b-4a3d-806a-4bf6336af6e4?response-content-disposition=filename%3D%22FYI-104+-+New+Mexico+Withholding+Tax+-+Effective+January+1%2C+2021.pdf%22&response-content-type=application%2Fpdf&AWSAccessKeyId=AKIAJBI25DHBYGD7I7TA&Signature=feu%2F1oJvU6BciRfKcoR0iNxoVZE%3D&Expires=1585159702 + + def _test_sit(self, wage, filing_status, additional_withholding, schedule_pay, date_start, expected_withholding): + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('NM'), + fed_941_fit_w4_filing_status=filing_status, + state_income_tax_additional_withholding=additional_withholding, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + + self._log('Computed period tax: ' + str(expected_withholding)) + self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding) + + def test_2021_taxes_example(self): + self._test_er_suta('NM', self.NM_UNEMP, date(2021, 1, 1), wage_base=self.NM_UNEMP_MAX_WAGE) + self._test_sit(1000.0, 'married', 0.0, 'weekly', date(2021, 1, 1), 29.32) + self._test_sit(1000.0, 'married', 10.0, 'weekly', date(2021, 1, 1), 39.32) + self._test_sit(25000.0, 'single', 0.0, 'bi-weekly', date(2021, 1, 1), 1369.25) + self._test_sit(25000.0, 'married_as_single', 0.0, 'monthly', date(2021, 1, 1), 1152.63) + self._test_sit(4400.0, '', 0.0, 'monthly', date(2021, 1, 1), 0.00) diff --git a/l10n_us_hr_payroll/tests/test_us_nv_nevada_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_nv_nevada_payslip_2021.py new file mode 100755 index 00000000..284990a0 --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_nv_nevada_payslip_2021.py @@ -0,0 +1,16 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date +from .common import TestUsPayslip + + +class TestUsNVPayslip(TestUsPayslip): + ### + # 2021 Taxes and Rates + ### + NV_UNEMP_MAX_WAGE = 33400.0 + NV_UNEMP = 2.95 + + def test_2021_taxes(self): + # Only has state unemployment + self._test_er_suta('NV', self.NV_UNEMP, date(2021, 1, 1), wage_base=self.NV_UNEMP_MAX_WAGE) diff --git a/l10n_us_hr_payroll/tests/test_us_ny_new_york_payslip_2019.py b/l10n_us_hr_payroll/tests/test_us_ny_new_york_payslip_2019.py deleted file mode 100644 index 2c3b9306..00000000 --- a/l10n_us_hr_payroll/tests/test_us_ny_new_york_payslip_2019.py +++ /dev/null @@ -1,133 +0,0 @@ -# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. - -from .common import TestUsPayslip, process_payslip - - -class TestUsNYPayslip(TestUsPayslip): - ### - # Taxes and Rates - ### - NY_UNEMP_MAX_WAGE = 11400.0 - NY_UNEMP = 2.5 - NY_RSF = 0.075 - NY_MCTMT = 0.0 - - def test_single_example1(self): - salary = 400 - schedule_pay = 'weekly' - allowances = 3 - additional_withholding = 0 - filing_status = 'single' - additional = 0.0 - wh = -8.20 - - employee = self._createEmployee() - - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('NY'), - ny_it2104_sit_filing_status=filing_status, - state_income_tax_additional_withholding=additional, - ny_it2104_sit_allowances=allowances, - schedule_pay=schedule_pay) - - self.assertEqual(contract.schedule_pay, 'weekly') - self._log('2018 New York tax first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['NY_UNEMP'], cats['NY_UNEMP_WAGES'] * self.NY_UNEMP) - self.assertPayrollEqual(cats['NY_RSF'], cats['NY_UNEMP_WAGES'] * self.NY_RSF) - self.assertPayrollEqual(cats['NY_MCTMT'], cats['NY_UNEMP_WAGES'] * self.NY_MCTMT) - self.assertPayrollEqual(cats['EE_US_SIT'], wh) - - process_payslip(payslip) - - def test_married_example2(self): - salary = 5000 - schedule_pay = 'semi-monthly' - allowances = 3 - additional = 0 - filing_status = 'married' - wh = -284.19 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('NY'), - ny_it2104_sit_filing_status=filing_status, - state_income_tax_additional_withholding=additional, - ny_it2104_sit_allowances=allowances, - schedule_pay=schedule_pay) - - self._log('2019 New York tax first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['NY_UNEMP'], cats['NY_UNEMP_WAGES'] * self.NY_UNEMP) - self.assertPayrollEqual(cats['NY_RSF'], cats['NY_UNEMP_WAGES'] * self.NY_RSF) - self.assertPayrollEqual(cats['NY_MCTMT'], cats['NY_UNEMP_WAGES'] * self.NY_MCTMT) - self.assertPayrollEqual(cats['EE_US_SIT'], wh) - - process_payslip(payslip) - - def test_single_example3(self): - salary = 50000 - schedule_pay = 'monthly' - allowances = 3 - additional = 0 - filing_status = 'single' - wh = -3575.63 - - employee = self._createEmployee() - - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('NY'), - ny_it2104_sit_filing_status=filing_status, - state_income_tax_additional_withholding=additional, - ny_it2104_sit_allowances=allowances, - schedule_pay=schedule_pay) - - self._log('2019 New York tax first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['EE_US_SIT'], wh) - - def test_exempt_example3(self): - salary = 50000 - schedule_pay = 'monthly' - allowances = 3 - additional = 0 - filing_status = '' - wh = 0.0 - - employee = self._createEmployee() - - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('NY'), - ny_it2104_sit_filing_status=filing_status, - state_income_tax_additional_withholding=additional, - ny_it2104_sit_allowances=allowances, - schedule_pay=schedule_pay) - - self._log('2019 New York tax first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['EE_US_SIT'], wh) - diff --git a/l10n_us_hr_payroll/tests/test_us_ny_new_york_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_ny_new_york_payslip_2021.py new file mode 100644 index 00000000..e8f0383d --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_ny_new_york_payslip_2021.py @@ -0,0 +1,39 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsNYPayslip(TestUsPayslip): + ### + # 2021 Taxes and Rates + ### + NY_UNEMP_MAX_WAGE = 11800.0 + NY_UNEMP = 2.5 #todo: update Feb 2021 + NY_RSF = 0.075 #todo: update Feb 2021 + NY_MCTMT = 0.0 #todo: update Feb 2021 + + def _test_sit(self, wage, filing_status, additional_withholding, allowances, schedule_pay, date_start, expected_withholding): + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('NY'), + ny_it2104_sit_filing_status=filing_status, + state_income_tax_additional_withholding=additional_withholding, + ny_it2104_sit_allowances=allowances, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + + self._log('Computed period tax: ' + str(expected_withholding)) + self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding) + + def test_2020_taxes_example(self): + combined_er_rate = self.NY_UNEMP + self.NY_RSF + self.NY_MCTMT + self._test_er_suta('NY', combined_er_rate, date(2021, 1, 1), wage_base=self.NY_UNEMP_MAX_WAGE, relaxed=True) + self._test_sit(400.0, 'single', 0.0, 3, 'weekly', date(2021, 1, 1), 8.20) + self._test_sit(10000.0, 'single', 0.0, 3, 'monthly', date(2021, 1, 1), 546.30) + self._test_sit(8000.0, 'married', 0.0, 5, 'monthly', date(2021, 1, 1), 394.24) + self._test_sit(4500.0, 'married', 10.0, 3, 'semi-monthly', date(2021, 1, 1), 244.21) + self._test_sit(50000.0, '', 0.0, 0, 'monthly', date(2021, 1, 1), 0.00) diff --git a/l10n_us_hr_payroll/tests/test_us_oh_ohio_payslip_2019.py b/l10n_us_hr_payroll/tests/test_us_oh_ohio_payslip_2019.py deleted file mode 100755 index d1f65f05..00000000 --- a/l10n_us_hr_payroll/tests/test_us_oh_ohio_payslip_2019.py +++ /dev/null @@ -1,96 +0,0 @@ -# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. - -from .common import TestUsPayslip, process_payslip -from odoo.addons.l10n_us_hr_payroll.models.hr_contract import USHRContract - - -class TestUsOhPayslip(TestUsPayslip): - ### - # Taxes and Rates - ### - OH_UNEMP_MAX_WAGE = 9500.0 - OH_UNEMP = -2.7 / 100.0 - - def test_2019_taxes(self): - salary = 5000.0 - - # For formula here - # http://www.tax.ohio.gov/Portals/0/employer_withholding/August2015Rates/WTH_OptionalComputerFormula_073015.pdf - tw = salary * 12 # = 60000 - wd = ((tw - 40000) * 0.035 + 900) / 12 * 1.075 - - employee = self._createEmployee() - - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('OH'), - ) - - self._log('2019 Ohio tax first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.OH_UNEMP) - self.assertPayrollAlmostEqual(cats['EE_US_SIT'], -wd) # Off by 0.6 cents so it rounds off by a penny - #self.assertPayrollEqual(cats['EE_US_SIT'], -wd) - - process_payslip(payslip) - - # Make a new payslip, this one will have maximums - - remaining_oh_unemp_wages = self.OH_UNEMP_MAX_WAGE - salary if (self.OH_UNEMP_MAX_WAGE - 2*salary < salary) \ - else salary - - self._log('2019 Ohio tax second payslip:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_oh_unemp_wages * self.OH_UNEMP) - - def test_2019_taxes_with_external(self): - salary = 5000.0 - external_wages = 6000.0 - - employee = self._createEmployee() - - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('OH'), - external_wages=external_wages, - ) - - self._log('2019 Ohio_external tax first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], (self.OH_UNEMP_MAX_WAGE - external_wages) * self.OH_UNEMP) - - def test_2019_taxes_with_state_exempt(self): - salary = 5000.0 - external_wages = 6000.0 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('OH'), - external_wages=external_wages, - futa_type=USHRContract.FUTA_TYPE_BASIC) - - self._log('2019 Ohio exempt tax first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - # FUTA_TYPE_BASIC - self.assertPayrollEqual(cats.get('ER_US_SUTA', 0.0), salary * 0.0) diff --git a/l10n_us_hr_payroll/tests/test_us_oh_ohio_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_oh_ohio_payslip_2021.py new file mode 100755 index 00000000..a05ff6ca --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_oh_ohio_payslip_2021.py @@ -0,0 +1,108 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date +from .common import TestUsPayslip, process_payslip + + +class TestUsOhPayslip(TestUsPayslip): + ### + # Taxes and Rates + ### + OH_UNEMP_MAX_WAGE = 9000.0 + OH_UNEMP = 2.7 + + def test_2021_taxes(self): + self._test_er_suta('OH', self.OH_UNEMP, date(2021, 1, 1), wage_base=self.OH_UNEMP_MAX_WAGE) + + def _run_test_sit(self, + wage=0.0, + schedule_pay='monthly', + filing_status='single', + dependent_credit=0.0, + other_income=0.0, + deductions=0.0, + additional_withholding=0.0, + is_nonresident_alien=False, + state_income_tax_exempt=False, + state_income_tax_additional_withholding=0.0, + oh_it4_sit_exemptions=0, + expected=0.0, + ): + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + schedule_pay=schedule_pay, + fed_941_fit_w4_is_nonresident_alien=is_nonresident_alien, + fed_941_fit_w4_filing_status=filing_status, + fed_941_fit_w4_multiple_jobs_higher=False, + fed_941_fit_w4_dependent_credit=dependent_credit, + fed_941_fit_w4_other_income=other_income, + fed_941_fit_w4_deductions=deductions, + fed_941_fit_w4_additional_withholding=additional_withholding, + state_income_tax_exempt=state_income_tax_exempt, + state_income_tax_additional_withholding=state_income_tax_additional_withholding, + oh_it4_sit_exemptions=oh_it4_sit_exemptions, + state_id=self.get_us_state('OH'), + ) + payslip = self._createPayslip(employee, '2021-01-01', '2021-01-31') + payslip.compute_sheet() + cats = self._getCategories(payslip) + # Instead of PayrollEqual after initial first round of testing. + self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected) + return payslip + + def test_2021_sit_1(self): + wage = 400.0 + exemptions = 1 + additional = 10.0 + pay_periods = 12.0 + annual_adjusted_wage = (wage * pay_periods) - (650.0 * exemptions) + self.assertPayrollEqual(4150.0, annual_adjusted_wage) + WD = ((annual_adjusted_wage * 0.005) / pay_periods) * 1.032 + self.assertPayrollEqual(WD, 1.7845) + expected = WD + additional + self._run_test_sit(wage=wage, + schedule_pay='monthly', + state_income_tax_exempt=False, + state_income_tax_additional_withholding=additional, + oh_it4_sit_exemptions=exemptions, + expected=expected, + ) + + # the above agrees with online calculator to the penny 0.01 + # below expected coming from calculator to 0.10 + # + # semi-monthly + self._run_test_sit(wage=1200, + schedule_pay='semi-monthly', + state_income_tax_exempt=False, + state_income_tax_additional_withholding=20.0, + oh_it4_sit_exemptions=2, + expected=42.58, + ) + + # bi-weekly + self._run_test_sit(wage=3000, + schedule_pay='bi-weekly', + state_income_tax_exempt=False, + #state_income_tax_additional_withholding=0.0, + oh_it4_sit_exemptions=0, + expected=88.51, + ) + # weekly + self._run_test_sit(wage=355, + schedule_pay='weekly', + state_income_tax_exempt=False, + # state_income_tax_additional_withholding=0.0, + oh_it4_sit_exemptions=1, + expected=4.87, + ) + + # Exempt! + self._run_test_sit(wage=355, + schedule_pay='weekly', + state_income_tax_exempt=True, + # state_income_tax_additional_withholding=0.0, + oh_it4_sit_exemptions=1, + expected=0.0, + ) diff --git a/l10n_us_hr_payroll/tests/test_us_ok_oklahoma_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_ok_oklahoma_payslip_2021.py new file mode 100755 index 00000000..096f3dfd --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_ok_oklahoma_payslip_2021.py @@ -0,0 +1,38 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsOKPayslip(TestUsPayslip): + ### + # 2021 Taxes and Rates + ### + OK_UNEMP_MAX_WAGE = 24000.0 + OK_UNEMP = 1.0 + # Calculation based on example https://www.ok.gov/tax/documents/2021WHTables.pdf + + def _test_sit(self, wage, filing_status, allowances, additional_withholding, exempt, schedule_pay, date_start, expected_withholding): + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('OK'), + ok_w4_sit_filing_status=filing_status, + ok_w4_sit_allowances=allowances, + state_income_tax_additional_withholding=additional_withholding, + state_income_tax_exempt=exempt, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + + self._log('Computed period tax: ' + str(expected_withholding)) + self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding) + + def test_2021_taxes_example(self): + self._test_er_suta('OK', self.OK_UNEMP, date(2021, 1, 1), wage_base=self.OK_UNEMP_MAX_WAGE) + self._test_sit(1825, 'married', 2, 0, False, 'semi-monthly', date(2021, 1, 1), 46.00) + self._test_sit(1825, 'married', 2, 0, True, 'monthly', date(2021, 1, 1), 0.00) + self._test_sit(1000, 'single', 1, 0, False, 'weekly', date(2021, 1, 1), 39.00) + self._test_sit(1000, 'single', 1, 10, False, 'weekly', date(2021, 1, 1), 49.00) + self._test_sit(5000, 'head_household', 2, 10, False, 'monthly', date(2021, 1, 1), 210.00) diff --git a/l10n_us_hr_payroll/tests/test_us_pa_pennsylvania_payslip_2019.py b/l10n_us_hr_payroll/tests/test_us_pa_pennsylvania_payslip_2019.py deleted file mode 100755 index ce7e4fb4..00000000 --- a/l10n_us_hr_payroll/tests/test_us_pa_pennsylvania_payslip_2019.py +++ /dev/null @@ -1,33 +0,0 @@ -# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. - -from .common import TestUsPayslip, process_payslip - - -class TestUsPAPayslip(TestUsPayslip): - ### - # Taxes and Rates - ### - PA_UNEMP_MAX_WAGE = 10000.0 - ER_PA_UNEMP = -3.6890 / 100.0 - EE_PA_UNEMP = -0.06 / 100.0 - PA_INC_WITHHOLD = 3.07 - - def test_2019_taxes(self): - salary = 4166.67 - wh = -127.92 - - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('PA')) - - self._log('2019 Pennsylvania tax first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['EE_US_SUTA'], cats['GROSS'] * self.EE_PA_UNEMP) - self.assertPayrollEqual(cats['ER_US_SUTA'], cats['GROSS'] * self.ER_PA_UNEMP) - self.assertPayrollEqual(cats['EE_US_SIT'], wh) diff --git a/l10n_us_hr_payroll/tests/test_us_pa_pennsylvania_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_pa_pennsylvania_payslip_2021.py new file mode 100755 index 00000000..800fe972 --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_pa_pennsylvania_payslip_2021.py @@ -0,0 +1,43 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date +from .common import TestUsPayslip + + +class TestUsPAPayslip(TestUsPayslip): + ### + # Taxes and Rates + ### + PA_UNEMP_MAX_WAGE = 10000.0 + ER_PA_UNEMP = 3.6890 + EE_PA_UNEMP = 0.06 + PA_INC_WITHHOLD = 3.07 + + def test_2021_taxes(self): + self._test_er_suta('PA', self.ER_PA_UNEMP, date(2021, 1, 1), wage_base=self.PA_UNEMP_MAX_WAGE) + self._test_ee_suta('PA', self.EE_PA_UNEMP, date(2021, 1, 1)) + + salary = 4166.67 + wh = -127.90 + employee = self._createEmployee() + contract = self._createContract(employee, + wage=salary, + state_id=self.get_us_state('PA')) + + self._log('2019 Pennsylvania tax first payslip:') + payslip = self._createPayslip(employee, '2021-01-01', '2021-01-31') + payslip.compute_sheet() + cats = self._getCategories(payslip) + self.assertPayrollEqual(cats['EE_US_SIT'], wh) + + # Test Additional + contract.us_payroll_config_id.state_income_tax_additional_withholding = 100.0 + payslip.compute_sheet() + cats = self._getCategories(payslip) + self.assertPayrollEqual(cats['EE_US_SIT'], wh - 100.0) + + # Test Exempt + contract.us_payroll_config_id.state_income_tax_exempt = True + payslip.compute_sheet() + cats = self._getCategories(payslip) + self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), 0.0) 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, + ) diff --git a/l10n_us_hr_payroll/tests/test_us_ri_rhode_island_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_ri_rhode_island_payslip_2021.py new file mode 100755 index 00000000..3fe9a189 --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_ri_rhode_island_payslip_2021.py @@ -0,0 +1,37 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsRIPayslip(TestUsPayslip): + ### + # 2021 Taxes and Rates + ### + RI_UNEMP_MAX_WAGE = 24000.0 + RI_UNEMP = 1.06 + # Calculation based on example http://www.tax.ri.gov/forms/2021/Withholding/2021%20Withhholding%20Tax%20Booklet.pdf + + def _test_sit(self, wage, allowances, additional_withholding, exempt, schedule_pay, date_start, expected_withholding): + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('RI'), + ri_w4_sit_allowances=allowances, + state_income_tax_additional_withholding=additional_withholding, + state_income_tax_exempt=exempt, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + + self._log('Computed period tax: ' + str(expected_withholding)) + self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding) + + def test_2021_taxes_example(self): + self._test_er_suta('RI', self.RI_UNEMP, date(2021, 1, 1), wage_base=self.RI_UNEMP_MAX_WAGE) + self._test_sit(2195, 1, 0, False, 'weekly', date(2021, 1, 1), 90.62) + self._test_sit(1800, 2, 10, True, 'weekly', date(2021, 1, 1), 0.00) + self._test_sit(10000, 1, 0, False, 'bi-weekly', date(2021, 1, 1), 501.75) + self._test_sit(18000, 2, 0, False, 'monthly', date(2021, 1, 1), 857.48) + self._test_sit(18000, 2, 10, False, 'monthly', date(2021, 1, 1), 867.47) diff --git a/l10n_us_hr_payroll/tests/test_us_sc_south_carolina_payslip_2019.py b/l10n_us_hr_payroll/tests/test_us_sc_south_carolina_payslip_2019.py deleted file mode 100644 index 793f84c4..00000000 --- a/l10n_us_hr_payroll/tests/test_us_sc_south_carolina_payslip_2019.py +++ /dev/null @@ -1,97 +0,0 @@ -# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. - -from .common import TestUsPayslip, process_payslip - - -class TestUsSCPayslip(TestUsPayslip): - - # Taxes and Rates - SC_UNEMP_MAX_WAGE = 14000.0 - US_SC_UNEMP = -1.09 / 100 - US_SC_exemption_amount = 2510.00 - - def test_2019_taxes_weekly(self): - # We will hand calculate the amount to test for state withholding. - schedule_pay = 'weekly' - salary = 50000.00 # Employee is paid 50000 per week to be in top tax bracket - allowances = 2 - # Calculate annual wages - annual = 50000 * 52.0 - # From our annual we deduct personal exemption amounts. - # We deduct 2510.00 per exemption. Since we have two exemptions: - personal_exemption = self.US_SC_exemption_amount * allowances # 5020.0 - # From annual, we will also deduct a standard_deduction of 3470.00 or .1 of salary, which ever - # is small -> if 1 or more exemptions, else 0 - standard_deduction = 3470.00 - taxable_income = annual - personal_exemption - standard_deduction # 2591510.0 - # We then calculate the amounts off the SC tax pdf tables. - # 2591478.0 is in the highest bracket - test_amt = (taxable_income * (7.0 / 100.0)) - 467.95 - test_amt = 180935.51 - # Make it per period then negative - test_amt = (test_amt / 52.0) # Divided by 52 since it is weekly. - # test_amt = 3479.52 - test_amt = -test_amt - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('SC'), - state_income_tax_exempt=False, - sc_w4_sit_allowances=allowances, - schedule_pay=schedule_pay) - - self._log('2019 South Carolina tax first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollAlmostEqual(cats['ER_US_SUTA'], self.SC_UNEMP_MAX_WAGE * self.US_SC_UNEMP) - self.assertPayrollAlmostEqual(cats['EE_US_SIT'], test_amt) - - process_payslip(payslip) - - remaining_SC_UNEMP_wages = self.SC_UNEMP_MAX_WAGE - annual if (annual < self.SC_UNEMP_MAX_WAGE) \ - else 0.00 - - self._log('2019 South Carolina tax second payslip:') - - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertEqual(0.0, remaining_SC_UNEMP_wages) - self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_SC_UNEMP_wages * self.US_SC_UNEMP) - - def test_2019_taxes_filing_status(self): - salary = 20000.00 # Wages per pay period - schedule_pay = 'monthly' - annual = salary * 12 - allowances = 1 - # Hand Calculations - personal_exemption = 2510.00 - standard_deduction = min(3470.00, .1 * annual) # 3470.0 but min is shown for the process - taxable = annual - personal_exemption - standard_deduction - # taxable = 234020 - test_amt = ((taxable) * (7.0 / 100.0)) - 467.95 # 15991.850000000002 - test_amt = test_amt / 12.0 # Put it into monthly -> 1332.654166666667 - # Make it negative - test_amt = -test_amt - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('SC'), - state_income_tax_exempt=False, - sc_w4_sit_allowances=allowances, - schedule_pay=schedule_pay) - - self._log('2019 South Carolina tax first payslip: ') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], self.SC_UNEMP_MAX_WAGE * self.US_SC_UNEMP) - self.assertPayrollAlmostEqual(cats['EE_US_SIT'], test_amt) - - process_payslip(payslip) diff --git a/l10n_us_hr_payroll/tests/test_us_sc_south_carolina_payslip_2020.py b/l10n_us_hr_payroll/tests/test_us_sc_south_carolina_payslip_2020.py index 170c3bf5..086af309 100644 --- a/l10n_us_hr_payroll/tests/test_us_sc_south_carolina_payslip_2020.py +++ b/l10n_us_hr_payroll/tests/test_us_sc_south_carolina_payslip_2020.py @@ -6,11 +6,11 @@ from .common import TestUsPayslip class TestUsSCPayslip(TestUsPayslip): ### - # 2020 Taxes and Rates + # 2021 Taxes and Rates ### SC_UNEMP_MAX_WAGE = 14000.0 SC_UNEMP = 0.55 - # Calculation based on https://dor.sc.gov/forms-site/Forms/WH1603F_2020.pdf + # Calculation based on https://dor.sc.gov/forms-site/Forms/WH1603F_2021.pdf def _test_sit(self, wage, additional_withholding, exempt, allowances, schedule_pay, date_start, expected_withholding): employee = self._createEmployee() @@ -28,9 +28,9 @@ class TestUsSCPayslip(TestUsPayslip): self._log('Computed period tax: ' + str(expected_withholding)) self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding) - def test_2020_taxes_example(self): - self._test_er_suta('SC', self.SC_UNEMP, date(2020, 1, 1), wage_base=self.SC_UNEMP_MAX_WAGE) - self._test_sit(750.0, 0.0, False, 3.0, 'weekly', date(2020, 1, 1), 28.73) - self._test_sit(800.0, 0.0, True, 0.0, 'weekly', date(2020, 1, 1), 0.00) - self._test_sit(9000.0, 0.0, False, 0.0, 'monthly', date(2020, 1, 1), 594.61) - self._test_sit(5000.0, 10.0, False, 2.0, 'semi-monthly', date(2020, 1, 1), 316.06) + def test_2021_taxes_example(self): + self._test_er_suta('SC', self.SC_UNEMP, date(2021, 1, 1), wage_base=self.SC_UNEMP_MAX_WAGE) + self._test_sit(750.0, 0.0, False, 3.0, 'weekly', date(2021, 1, 1), 28.73) + self._test_sit(800.0, 0.0, True, 0.0, 'weekly', date(2021, 1, 1), 0.00) + self._test_sit(9000.0, 0.0, False, 0.0, 'monthly', date(2021, 1, 1), 594.61) + self._test_sit(5000.0, 10.0, False, 2.0, 'semi-monthly', date(2021, 1, 1), 316.06) diff --git a/l10n_us_hr_payroll/tests/test_us_sc_south_carolina_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_sc_south_carolina_payslip_2021.py new file mode 100644 index 00000000..3fb11459 --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_sc_south_carolina_payslip_2021.py @@ -0,0 +1,36 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsSCPayslip(TestUsPayslip): + ### + # 2021 Taxes and Rates + ### + SC_UNEMP_MAX_WAGE = 14000.0 + SC_UNEMP = 0.55 + # Calculation based on https://dor.sc.gov/forms-site/Forms/WH1603F_2021.pdf + + def _test_sit(self, wage, additional_withholding, exempt, allowances, schedule_pay, date_start, expected_withholding): + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('SC'), + state_income_tax_additional_withholding=additional_withholding, + state_income_tax_exempt=exempt, + sc_w4_sit_allowances=allowances, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + + self._log('Computed period tax: ' + str(expected_withholding)) + self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding) + + def test_2021_taxes_example(self): + self._test_er_suta('SC', self.SC_UNEMP, date(2021, 1, 1), wage_base=self.SC_UNEMP_MAX_WAGE) + self._test_sit(750.0, 0.0, False, 3.0, 'weekly', date(2021, 1, 1), 27.57) + self._test_sit(800.0, 0.0, True, 0.0, 'weekly', date(2021, 1, 1), 0.00) + self._test_sit(9000.0, 0.0, False, 0.0, 'monthly', date(2021, 1, 1), 591.44) + self._test_sit(5000.0, 10.0, False, 2.0, 'semi-monthly', date(2021, 1, 1), 312.90) diff --git a/l10n_us_hr_payroll/tests/test_us_sd_south_dakota_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_sd_south_dakota_payslip_2021.py new file mode 100644 index 00000000..577a82ec --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_sd_south_dakota_payslip_2021.py @@ -0,0 +1,13 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date +from .common import TestUsPayslip + + +class TestUsSDPayslip(TestUsPayslip): + # TAXES AND RATES + SD_UNEMP_MAX_WAGE = 15000.00 + SD_UNEMP = 1.75 + + def test_2021_taxes(self): + self._test_er_suta('SD', self.SD_UNEMP, date(2021, 1, 1), wage_base=self.SD_UNEMP_MAX_WAGE) diff --git a/l10n_us_hr_payroll/tests/test_us_tn_tennessee_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_tn_tennessee_payslip_2021.py new file mode 100644 index 00000000..3a3080e6 --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_tn_tennessee_payslip_2021.py @@ -0,0 +1,14 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date +from .common import TestUsPayslip + + +class TestUsTNPayslip(TestUsPayslip): + # TAXES AND RATES + # todo: 2021 rates not published yet + TN_UNEMP_MAX_WAGE = 7000.00 + TN_UNEMP = 2.7 + + def test_2021_taxes(self): + self._test_er_suta('TN', self.TN_UNEMP, date(2021, 1, 1), wage_base=self.TN_UNEMP_MAX_WAGE) diff --git a/l10n_us_hr_payroll/tests/test_us_tx_texas_payslip_2019.py b/l10n_us_hr_payroll/tests/test_us_tx_texas_payslip_2019.py deleted file mode 100755 index 15e657ae..00000000 --- a/l10n_us_hr_payroll/tests/test_us_tx_texas_payslip_2019.py +++ /dev/null @@ -1,100 +0,0 @@ -# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. - -from .common import TestUsPayslip, process_payslip -from odoo.addons.l10n_us_hr_payroll.models.hr_contract import USHRContract - -class TestUsTXPayslip(TestUsPayslip): - ### - # 2019 Taxes and Rates - ### - TX_UNEMP_MAX_WAGE = 9000.0 - TX_UNEMP = -2.7 / 100.0 - TX_OA = 0.0 - TX_ETIA = -0.1 / 100.0 - - def test_2019_taxes(self): - salary = 5000.0 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('TX'), - ) - - self._log('2019 Texas 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['ER_US_TX_SUTA'], salary * self.TX_UNEMP) - self.assertPayrollEqual(rules['ER_US_TX_SUTA_OA'], salary * self.TX_OA) - self.assertPayrollEqual(rules['ER_US_TX_SUTA_ETIA'], salary * self.TX_ETIA) - - process_payslip(payslip) - - # Make a new payslip, this one will have maximums - - remaining_tx_unemp_wages = self.TX_UNEMP_MAX_WAGE - salary if (self.TX_UNEMP_MAX_WAGE - 2*salary < salary) \ - else salary - - self._log('2019 Texas 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['ER_US_TX_SUTA'], remaining_tx_unemp_wages * self.TX_UNEMP) - - def test_2019_taxes_with_external(self): - salary = 5000.0 - external_wages = 6000.0 - - employee = self._createEmployee() - - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('TX'), - external_wages=external_wages, - ) - - self._log('2019 Texas_external tax first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - rules = self._getRules(payslip) - - expected_wage = self.TX_UNEMP_MAX_WAGE - external_wages - self.assertPayrollEqual(rules['ER_US_TX_SUTA'], expected_wage * self.TX_UNEMP) - self.assertPayrollEqual(rules['ER_US_TX_SUTA_OA'], expected_wage * self.TX_OA) - self.assertPayrollEqual(rules['ER_US_TX_SUTA_ETIA'], expected_wage * self.TX_ETIA) - - def test_2019_taxes_with_state_exempt(self): - salary = 5000.0 - external_wages = 6000.0 - - employee = self._createEmployee() - - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('TX'), - external_wages=external_wages, - futa_type=USHRContract.FUTA_TYPE_BASIC) - - self._log('2019 Texas_external 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.get('ER_US_TX_SUTA', 0.0), 0.0) - self.assertPayrollEqual(rules.get('ER_US_TX_SUTA_OA', 0.0), 0.0) - self.assertPayrollEqual(rules.get('ER_US_TX_SUTA_ETIA', 0.0), 0.0) diff --git a/l10n_us_hr_payroll/tests/test_us_tx_texas_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_tx_texas_payslip_2021.py new file mode 100755 index 00000000..14d8066f --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_tx_texas_payslip_2021.py @@ -0,0 +1,17 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date +from .common import TestUsPayslip + +class TestUsTXPayslip(TestUsPayslip): + ### + # 2021 Taxes and Rates + ### + TX_UNEMP_MAX_WAGE = 9000.0 + TX_UNEMP = 2.7 + TX_OA = 0.0 + TX_ETIA = 0.1 + + def test_2021_taxes(self): + combined_rate = self.TX_UNEMP + self.TX_OA + self.TX_ETIA + self._test_er_suta('TX', combined_rate, date(2021, 1, 1), wage_base=self.TX_UNEMP_MAX_WAGE) diff --git a/l10n_us_hr_payroll/tests/test_us_us_utah_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_us_utah_payslip_2021.py new file mode 100755 index 00000000..0b23b462 --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_us_utah_payslip_2021.py @@ -0,0 +1,36 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsUTPayslip(TestUsPayslip): + ### + # 2021 Taxes and Rates + ### + UT_UNEMP_MAX_WAGE = 38900.0 + UT_UNEMP = 0.1052 + # Calculation based on example https://tax.utah.gov/forms/pubs/pub-14.pdf + + def _test_sit(self, wage, filing_status, additional_withholding, schedule_pay, date_start, expected_withholding): + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('UT'), + ut_w4_sit_filing_status=filing_status, + state_income_tax_additional_withholding=additional_withholding, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + + self._log('Computed period tax: ' + str(expected_withholding)) + self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding) + + def test_2021_taxes_example(self): + self._test_er_suta('UT', self.UT_UNEMP, date(2021, 1, 1), wage_base=self.UT_UNEMP_MAX_WAGE) + self._test_sit(400, 'single', 0, 'weekly', date(2021, 1, 1), 16.00) + self._test_sit(1000, 'single', 0, 'bi-weekly', date(2021, 1, 1), 45.00) + self._test_sit(855, 'married', 0, 'semi-monthly', date(2021, 1, 1), 16.00) + self._test_sit(2500, 'married', 0, 'monthly', date(2021, 1, 1), 81.00) + self._test_sit(8000, 'head_household', 10, 'quarterly', date(2021, 1, 1), 397.00) diff --git a/l10n_us_hr_payroll/tests/test_us_va_virginia_payslip_2019.py b/l10n_us_hr_payroll/tests/test_us_va_virginia_payslip_2019.py deleted file mode 100644 index b8f14393..00000000 --- a/l10n_us_hr_payroll/tests/test_us_va_virginia_payslip_2019.py +++ /dev/null @@ -1,133 +0,0 @@ -# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. - -from datetime import date -from .common import TestUsPayslip, process_payslip -from odoo.addons.l10n_us_hr_payroll.models.hr_contract import USHRContract - - -class TestUsVaPayslip(TestUsPayslip): - ### - # Taxes and Rates - ### - VA_UNEMP_MAX_WAGE = 8000.0 - VA_UNEMP = 2.51 - VA_SIT_DEDUCTION = 4500.0 - VA_SIT_EXEMPTION = 930.0 - VA_SIT_OTHER_EXEMPTION = 800.0 - - def test_2019_taxes(self): - salary = 5000.0 - - # For formula from https://www.tax.virginia.gov/withholding-calculator - """ - Key - G = Gross Pay for Pay Period P = Pay periods per year - A = Annualized gross pay E1 = Personal and Dependent Exemptions - T = Annualized taxable income E2 = Age 65 and Over & Blind Exemptions - WH = Tax to be withheld for pay period W = Annualized tax to be withheld - G x P - [$3000+ (E1 x 930) + (E2 x 800)] = T - Calculate W as follows: - If T is: W is: - Not over $3,000 2% of T - Over But Not Over Then - $3,000 $5,000 $60 + (3% of excess over $3,000) - $5,000 $17,000 $120 + (5% of excess over $5,000) - $17,000 $720 + (5.75% of excess over $17,000) - W / P = WH - """ - e1 = 2 - e2 = 0 - t = salary * 12 - (self.VA_SIT_DEDUCTION + (e1 * self.VA_SIT_EXEMPTION) + (e2 * self.VA_SIT_OTHER_EXEMPTION)) - - if t <= 3000: - w = 0.02 * t - elif t <= 5000: - w = 60 + (0.03 * (t - 3000)) - elif t <= 17000: - w = 120 + (0.05 * (t - 5000)) - else: - w = 720 + (0.0575 * (t - 17000)) - - wh = w / 12 - - employee = self._createEmployee() - - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('VA'), - va_va4_sit_exemptions=e1, - va_va4_sit_other_exemptions=e2 - ) - - # tax rates - va_unemp = self.VA_UNEMP / -100.0 - - self._log('2019 Virginia tax first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * va_unemp) - self.assertPayrollEqual(cats['EE_US_SIT'], -wh) - - process_payslip(payslip) - - # Make a new payslip, this one will have maximums - - remaining_va_unemp_wages = self.VA_UNEMP_MAX_WAGE - salary if (self.VA_UNEMP_MAX_WAGE - 2*salary < salary) \ - else salary - - self._log('2019 Virginia tax second payslip:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_va_unemp_wages * va_unemp) - - def test_2019_taxes_with_external(self): - salary = 5000.0 - external_wages = 6000.0 - - employee = self._createEmployee() - - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('VA'), - external_wages=external_wages, - ) - - # tax rates - va_unemp = self.VA_UNEMP / -100.0 - - self._log('2019 Virginia_external tax first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - self.assertPayrollEqual(cats['ER_US_SUTA'], (self.VA_UNEMP_MAX_WAGE - external_wages) * va_unemp) - - def test_2019_taxes_with_state_exempt(self): - salary = 5000.0 - external_wages = 6000.0 - - employee = self._createEmployee() - - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('VA'), - external_wages=external_wages, - futa_type=USHRContract.FUTA_TYPE_BASIC) - - # tax rates - self._log('2019 Virginia exempt tax first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], 0.0) diff --git a/l10n_us_hr_payroll/tests/test_us_va_virginia_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_va_virginia_payslip_2021.py new file mode 100644 index 00000000..dc81a3ff --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_va_virginia_payslip_2021.py @@ -0,0 +1,116 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date +from .common import TestUsPayslip + + +class TestUsVaPayslip(TestUsPayslip): + ### + # Taxes and Rates + ### + VA_UNEMP_MAX_WAGE = 8000.0 + VA_UNEMP = 2.5 + VA_SIT_DEDUCTION = 4500.0 + VA_SIT_EXEMPTION = 930.0 + VA_SIT_OTHER_EXEMPTION = 800.0 + + def _run_test_sit(self, + wage=0.0, + schedule_pay='monthly', + filing_status='single', + dependent_credit=0.0, + other_income=0.0, + deductions=0.0, + additional_withholding=0.0, + is_nonresident_alien=False, + state_income_tax_exempt=False, + state_income_tax_additional_withholding=0.0, + va_va4_sit_exemptions=0, + va_va4_sit_other_exemptions=0, + expected=0.0, + ): + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + schedule_pay=schedule_pay, + fed_941_fit_w4_is_nonresident_alien=is_nonresident_alien, + fed_941_fit_w4_filing_status=filing_status, + fed_941_fit_w4_multiple_jobs_higher=False, + fed_941_fit_w4_dependent_credit=dependent_credit, + fed_941_fit_w4_other_income=other_income, + fed_941_fit_w4_deductions=deductions, + fed_941_fit_w4_additional_withholding=additional_withholding, + state_income_tax_exempt=state_income_tax_exempt, + state_income_tax_additional_withholding=state_income_tax_additional_withholding, + va_va4_sit_exemptions=va_va4_sit_exemptions, + va_va4_sit_other_exemptions=va_va4_sit_other_exemptions, + state_id=self.get_us_state('VA'), + ) + payslip = self._createPayslip(employee, '2020-01-01', '2020-01-31') + payslip.compute_sheet() + cats = self._getCategories(payslip) + # Instead of PayrollEqual after initial first round of testing. + self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected) + return payslip + + def test_2020_taxes(self): + self._test_er_suta('VA', self.VA_UNEMP, date(2020, 1, 1), wage_base=self.VA_UNEMP_MAX_WAGE) + + salary = 5000.0 + + # For formula from https://www.tax.virginia.gov/withholding-calculator + e1 = 2 + e2 = 0 + t = salary * 12 - (self.VA_SIT_DEDUCTION + (e1 * self.VA_SIT_EXEMPTION) + (e2 * self.VA_SIT_OTHER_EXEMPTION)) + + if t <= 3000: + w = 0.02 * t + elif t <= 5000: + w = 60 + (0.03 * (t - 3000)) + elif t <= 17000: + w = 120 + (0.05 * (t - 5000)) + else: + w = 720 + (0.0575 * (t - 17000)) + + wh = w / 12 + + self._run_test_sit(wage=salary, + schedule_pay='monthly', + state_income_tax_exempt=False, + state_income_tax_additional_withholding=0.0, + va_va4_sit_exemptions=e1, + va_va4_sit_other_exemptions=e2, + expected=wh,) + self.assertPayrollEqual(wh, 235.57) # To test against calculator + + # Below expected comes from the calculator linked above + self._run_test_sit(wage=450.0, + schedule_pay='weekly', + state_income_tax_exempt=False, + state_income_tax_additional_withholding=0.0, + va_va4_sit_exemptions=3, + va_va4_sit_other_exemptions=1, + expected=12.22,) + self._run_test_sit(wage=2500.0, + schedule_pay='bi-weekly', + state_income_tax_exempt=False, + state_income_tax_additional_withholding=0.0, + va_va4_sit_exemptions=1, + va_va4_sit_other_exemptions=0, + expected=121.84,) + self._run_test_sit(wage=10000.0, + schedule_pay='semi-monthly', + state_income_tax_exempt=False, + state_income_tax_additional_withholding=100.0, + va_va4_sit_exemptions=0, + va_va4_sit_other_exemptions=1, + expected=651.57,) + + # Test exempt + self._run_test_sit(wage=2400.0, + schedule_pay='monthly', + state_income_tax_exempt=True, + state_income_tax_additional_withholding=0.0, + va_va4_sit_exemptions=1, + va_va4_sit_other_exemptions=1, + expected=0.0,) diff --git a/l10n_us_hr_payroll/tests/test_us_vt_vermont_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_vt_vermont_payslip_2021.py new file mode 100755 index 00000000..67fb7a99 --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_vt_vermont_payslip_2021.py @@ -0,0 +1,37 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsVTPayslip(TestUsPayslip): + ### + # 2021 Taxes and Rates + ### + VT_UNEMP_MAX_WAGE = 14100.0 + VT_UNEMP = 1.0 + # Calculation based on example https://tax.vermont.gov/sites/tax/files/documents/WithholdingInstructions.pdf + + def _test_sit(self, wage, filing_status, allowances, additional_withholding, exempt, schedule_pay, date_start, expected_withholding): + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('VT'), + vt_w4vt_sit_filing_status=filing_status, + vt_w4vt_sit_allowances=allowances, + state_income_tax_additional_withholding=additional_withholding, + state_income_tax_exempt=exempt, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + + self._log('Computed period tax: ' + str(expected_withholding)) + self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding) + + def test_2021_taxes_example(self): + self._test_er_suta('VT', self.VT_UNEMP, date(2021, 1, 1), wage_base=self.VT_UNEMP_MAX_WAGE) + self._test_sit(1800, 'married', 2, 0, False, 'weekly', date(2021, 1, 1), 52.79) + self._test_sit(1800, 'married', 2, 10, False, 'weekly', date(2021, 1, 1), 62.79) + self._test_sit(1000, 'single', 1, 0, True, 'weekly', date(2021, 1, 1), 0.00) + self._test_sit(8000, 'single', 1, 10, False, 'bi-weekly', date(2021, 1, 1), 506.52) diff --git a/l10n_us_hr_payroll/tests/test_us_wa_washington_payslip_2020.py b/l10n_us_hr_payroll/tests/test_us_wa_washington_payslip_2020.py index e02e55a0..2aeb940a 100755 --- a/l10n_us_hr_payroll/tests/test_us_wa_washington_payslip_2020.py +++ b/l10n_us_hr_payroll/tests/test_us_wa_washington_payslip_2020.py @@ -22,6 +22,7 @@ class TestUsWAPayslip(TestUsPayslip): # 'rate': 0.1261, # 'rate_emp_withhold': 0.05575, # }) + # todo: figure out how the two rates below corralate with ee and er rates above self.test_ee_lni = 0.05575 # per 100 hours self.test_er_lni = 0.1261 # per 100 hours self.parameter_lni_ee = self.env['hr.rule.parameter'].create({ diff --git a/l10n_us_hr_payroll/tests/test_us_wa_washington_payslip_2019.py b/l10n_us_hr_payroll/tests/test_us_wa_washington_payslip_2021.py similarity index 61% rename from l10n_us_hr_payroll/tests/test_us_wa_washington_payslip_2019.py rename to l10n_us_hr_payroll/tests/test_us_wa_washington_payslip_2021.py index a0fda5c9..180494e0 100755 --- a/l10n_us_hr_payroll/tests/test_us_wa_washington_payslip_2019.py +++ b/l10n_us_hr_payroll/tests/test_us_wa_washington_payslip_2021.py @@ -8,8 +8,9 @@ class TestUsWAPayslip(TestUsPayslip): ### # Taxes and Rates ### - WA_UNEMP_MAX_WAGE = 49800.0 - WA_UNEMP_RATE = 1.18 + WA_UNEMP_MAX_WAGE = 56500.00 + WA_UNEMP_RATE = 2.16 + WA_FML_MAX_WAGE = 142800.00 WA_FML_RATE = 0.4 WA_FML_RATE_EE = 66.33 WA_FML_RATE_ER = 33.67 @@ -27,7 +28,7 @@ class TestUsWAPayslip(TestUsPayslip): 'name': 'Test LNI EE', 'code': 'test_lni_ee', 'parameter_version_ids': [(0, 0, { - 'date_from': date(2019, 1, 1), + 'date_from': date(2021, 1, 1), 'parameter_value': str(self.test_ee_lni * 100), })], }) @@ -35,13 +36,15 @@ class TestUsWAPayslip(TestUsPayslip): 'name': 'Test LNI ER', 'code': 'test_lni_er', 'parameter_version_ids': [(0, 0, { - 'date_from': date(2019, 1, 1), + 'date_from': date(2021, 1, 1), 'parameter_value': str(self.test_er_lni * 100), })], }) - def test_2019_taxes(self): - salary = 25000.0 + def test_2021_taxes(self): + self._test_er_suta('WA', self.WA_UNEMP_RATE, date(2021, 1, 1), wage_base=self.WA_UNEMP_MAX_WAGE) + + salary = (self.WA_FML_MAX_WAGE / 2.0) + 1000.0 employee = self._createEmployee() @@ -54,39 +57,34 @@ class TestUsWAPayslip(TestUsPayslip): self._log(str(contract.resource_calendar_id) + ' ' + contract.resource_calendar_id.name) - # tax rates - wa_unemp = self.WA_UNEMP_RATE / -100.0 - - self._log('2019 Washington tax first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') + # Non SUTA + self._log('2021 Washington tax first payslip:') + payslip = self._createPayslip(employee, '2021-01-01', '2021-01-31') hours_in_period = payslip.worked_days_line_ids.filtered(lambda l: l.code == 'WORK100').number_of_hours - self.assertAlmostEqual(hours_in_period, 184) # only asserted to test algorithm + self.assertPayrollAlmostEqual(hours_in_period, 169) # only asserted to test algorithm payslip.compute_sheet() - - cats = self._getCategories(payslip) rules = self._getRules(payslip) - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * wa_unemp) - self.assertPayrollEqual(rules['EE_US_WA_LNI'], -(self.test_ee_lni * hours_in_period)) + self.assertPayrollAlmostEqual(rules['EE_US_WA_LNI'], -(self.test_ee_lni * hours_in_period)) self.assertPayrollEqual(rules['ER_US_WA_LNI'], -(self.test_er_lni * hours_in_period)) # Both of these are known to be within 1 penny self.assertPayrollAlmostEqual(rules['EE_US_WA_FML'], -(salary * (self.WA_FML_RATE / 100.0) * (self.WA_FML_RATE_EE / 100.0))) self.assertPayrollAlmostEqual(rules['ER_US_WA_FML'], -(salary * (self.WA_FML_RATE / 100.0) * (self.WA_FML_RATE_ER / 100.0))) - - # FML - process_payslip(payslip) - # Make a new payslip, this one will have maximums - - remaining_wa_unemp_wages = self.WA_UNEMP_MAX_WAGE - salary if (self.WA_UNEMP_MAX_WAGE - 2*salary < salary) \ - else salary - - self._log('2019 Washington tax second payslip:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') + # Second payslip + remaining_wage = self.WA_FML_MAX_WAGE - salary + payslip = self._createPayslip(employee, '2021-03-01', '2021-03-31') payslip.compute_sheet() + rules = self._getRules(payslip) + self.assertPayrollAlmostEqual(rules['EE_US_WA_FML'], -(remaining_wage * (self.WA_FML_RATE / 100.0) * (self.WA_FML_RATE_EE / 100.0))) + self.assertPayrollAlmostEqual(rules['ER_US_WA_FML'], -(remaining_wage * (self.WA_FML_RATE / 100.0) * (self.WA_FML_RATE_ER / 100.0))) + process_payslip(payslip) - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_wa_unemp_wages * wa_unemp) + # Third payslip + payslip = self._createPayslip(employee, '2021-04-01', '2021-04-30') + payslip.compute_sheet() + rules = self._getRules(payslip) + self.assertPayrollAlmostEqual(rules['EE_US_WA_FML'], 0.0) + self.assertPayrollAlmostEqual(rules['ER_US_WA_FML'], 0.0) diff --git a/l10n_us_hr_payroll/tests/test_us_wi_wisconsin_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_wi_wisconsin_payslip_2021.py new file mode 100755 index 00000000..59a9e814 --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_wi_wisconsin_payslip_2021.py @@ -0,0 +1,39 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsWIPayslip(TestUsPayslip): + ### + # 2021 Taxes and Rates + ### + WI_UNEMP_MAX_WAGE = 14000.0 + WI_UNEMP = 3.05 + # Calculation based on example https://www.revenue.wi.gov/DOR%20Publications/pb166.pdf + + def _test_sit(self, wage, filing_status, exemption, additional_withholding, exempt, schedule_pay, date_start, expected_withholding): + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('WI'), + wi_wt4_sit_filing_status=filing_status, + wi_wt4_sit_exemptions=exemption, + state_income_tax_additional_withholding=additional_withholding, + state_income_tax_exempt=exempt, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + + self._log('Computed period tax: ' + str(expected_withholding)) + self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding) + + def test_2021_taxes_example(self): + self._test_er_suta('WI', self.WI_UNEMP, date(2021, 1, 1), wage_base=self.WI_UNEMP_MAX_WAGE) + self._test_sit(300, 'single', 1, 0, False, 'weekly', date(2021, 1, 1), 7.21) + self._test_sit(700, 'married', 3, 0, False, 'bi-weekly', date(2021, 1, 1), 13.35) + self._test_sit(7000, 'single', 1, 10, True, 'bi-weekly', date(2021, 1, 1), 0.00) + self._test_sit(10000, 'married', 3, 10, False, 'bi-weekly', date(2021, 1, 1), 633.65) + # ((48000 - 26227) * (7.0224 /100) + 1073.55 - 44) / 12 + self._test_sit(4000, 'single', 2, 0, False, 'monthly', date(2021, 1, 1), 213.21) diff --git a/l10n_us_hr_payroll/tests/test_us_wv_west_virginia_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_wv_west_virginia_payslip_2021.py new file mode 100755 index 00000000..ec16d379 --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_wv_west_virginia_payslip_2021.py @@ -0,0 +1,36 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date, timedelta +from .common import TestUsPayslip + + +class TestUsWVPayslip(TestUsPayslip): + ### + # 2021 Taxes and Rates + ### + WV_UNEMP_MAX_WAGE = 12000.0 + WV_UNEMP = 2.7 + # Calculation based on example https://tax.wv.gov/Documents/TaxForms/it100.1a.pdf + + def _test_sit(self, wage, filing_status, exemption, additional_withholding, schedule_pay, date_start, expected_withholding): + employee = self._createEmployee() + contract = self._createContract(employee, + wage=wage, + state_id=self.get_us_state('WV'), + wv_it104_sit_filing_status=filing_status, + wv_it104_sit_exemptions=exemption, + state_income_tax_additional_withholding=additional_withholding, + schedule_pay=schedule_pay) + payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7)) + payslip.compute_sheet() + cats = self._getCategories(payslip) + + self._log('Computed period tax: ' + str(expected_withholding)) + self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding) + + def test_2021_taxes_example(self): + self._test_er_suta('WV', self.WV_UNEMP, date(2021, 1, 1), wage_base=self.WV_UNEMP_MAX_WAGE) + self._test_sit(1250, 'married', 2, 0, 'semi-monthly', date(2021, 1, 1), 44.00) + self._test_sit(1300, 'single', 1, 0, 'bi-weekly', date(2021, 1, 1), 46.00) + self._test_sit(1300, 'single', 1, 10, 'bi-weekly', date(2021, 1, 1), 56.00) + self._test_sit(15000, 'single', 2, 0, 'monthly', date(2021, 1, 1), 860.00) diff --git a/l10n_us_hr_payroll/tests/test_us_wy_wyoming_payslip_2019.py b/l10n_us_hr_payroll/tests/test_us_wy_wyoming_payslip_2019.py deleted file mode 100644 index a8fa3df8..00000000 --- a/l10n_us_hr_payroll/tests/test_us_wy_wyoming_payslip_2019.py +++ /dev/null @@ -1,58 +0,0 @@ -# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. - -from datetime import date -from .common import TestUsPayslip, process_payslip - - -class TestUsWYPayslip(TestUsPayslip): - - # TAXES AND RATES - WY_UNEMP_MAX_WAGE = 25400 - WY_UNEMP = -2.10 / 100.0 - - def test_2019_taxes(self): - salary = 15000.00 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('WY')) - - self._log('2019 Wyoming tax first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.WY_UNEMP) - - process_payslip(payslip) - - # Make a new payslip, this one will have maximums - - remaining_wy_unemp_wages = self.WY_UNEMP_MAX_WAGE - salary if (self.WY_UNEMP_MAX_WAGE - 2*salary < salary) \ - else salary - - self._log('2019 Wyoming tax second payslip:') - payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_wy_unemp_wages * self.WY_UNEMP) - - def test_2019_taxes_with_external(self): - # Wage is the cap itself, 25400 - # so salary is equal to self.WY_UNEMP - salary = 25400 - - employee = self._createEmployee() - contract = self._createContract(employee, - wage=salary, - state_id=self.get_us_state('WY')) - - self._log('2019 Wyoming External tax first payslip:') - payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') - payslip.compute_sheet() - cats = self._getCategories(payslip) - - self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.WY_UNEMP) diff --git a/l10n_us_hr_payroll/tests/test_us_wy_wyoming_payslip_2021.py b/l10n_us_hr_payroll/tests/test_us_wy_wyoming_payslip_2021.py new file mode 100644 index 00000000..8d651a9a --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_wy_wyoming_payslip_2021.py @@ -0,0 +1,13 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from datetime import date +from .common import TestUsPayslip + + +class TestUsWYPayslip(TestUsPayslip): + # TAXES AND RATES + WY_UNEMP_MAX_WAGE = 27300.00 + WY_UNEMP = 8.5 + + def test_2021_taxes(self): + self._test_er_suta('WY', self.WY_UNEMP, date(2021, 1, 1), wage_base=self.WY_UNEMP_MAX_WAGE)