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/tests/__init__.py b/l10n_us_hr_payroll/tests/__init__.py index 9254cbf3..a1944823 100755 --- a/l10n_us_hr_payroll/tests/__init__.py +++ b/l10n_us_hr_payroll/tests/__init__.py @@ -40,8 +40,8 @@ from . import test_us_ga_georgia_payslip_2020 from . import test_us_hi_hawaii_payslip_2019 from . import test_us_hi_hawaii_payslip_2020 -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 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)