From f6beed71652efafc87323ff3a0774bd885cad211 Mon Sep 17 00:00:00 2001
From: Bhoomi Vaishnani
Date: Tue, 24 Mar 2020 15:50:48 -0400
Subject: [PATCH] IMP `l10n_us_hr_payroll` Port `l10n_us_ia_hr_payroll` IA Iowa
including migration
---
l10n_us_hr_payroll/__manifest__.py | 1 +
l10n_us_hr_payroll/data/state/ia_iowa.xml | 177 ++++++++++++++++++
l10n_us_hr_payroll/models/hr_payslip.py | 2 +
l10n_us_hr_payroll/models/state/ia_iowa.py | 44 +++++
.../models/us_payroll_config.py | 2 +
l10n_us_hr_payroll/tests/__init__.py | 3 +
.../tests/test_us_ia_iowa_payslip_2019.py | 152 +++++++++++++++
.../tests/test_us_ia_iowa_payslip_2020.py | 33 ++++
.../views/us_payroll_config_views.xml | 6 +
9 files changed, 420 insertions(+)
create mode 100644 l10n_us_hr_payroll/data/state/ia_iowa.xml
create mode 100644 l10n_us_hr_payroll/models/state/ia_iowa.py
create 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_2020.py
diff --git a/l10n_us_hr_payroll/__manifest__.py b/l10n_us_hr_payroll/__manifest__.py
index 1a3214ff..d04c4772 100644
--- a/l10n_us_hr_payroll/__manifest__.py
+++ b/l10n_us_hr_payroll/__manifest__.py
@@ -36,6 +36,7 @@ United States of America - Payroll Rules.
'data/state/fl_florida.xml',
'data/state/ga_georgia.xml',
'data/state/hi_hawaii.xml',
+ 'data/state/ia_iowa.xml',
'data/state/id_idaho.xml',
'data/state/il_illinois.xml',
'data/state/mi_michigan.xml',
diff --git a/l10n_us_hr_payroll/data/state/ia_iowa.xml b/l10n_us_hr_payroll/data/state/ia_iowa.xml
new file mode 100644
index 00000000..6a7d060d
--- /dev/null
+++ b/l10n_us_hr_payroll/data/state/ia_iowa.xml
@@ -0,0 +1,177 @@
+
+
+
+
+ US IA Iowa SUTA Wage Base
+ us_ia_suta_wage_base
+
+
+
+
+ 30600.0
+
+
+
+
+ 31600.0
+
+
+
+
+
+
+
+ US IA Iowa SUTA Rate
+ us_ia_suta_rate
+
+
+
+
+ 1.0
+
+
+
+
+ 1.0
+
+
+
+
+
+
+ US IA Iowa SIT Tax Rate
+ us_ia_sit_tax_rate
+
+
+
+
+ {
+ 'daily': [(5.13, 0.0033, 0.0), (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.0), (51.27, 0.0067, 0.08), (102.52, 0.0225, 0.025), (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.00225, 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)],
+ }
+
+
+
+
+ {
+ 'daily': [(5.69, 0.0033, 0.0), (11.38, 0.0067, 0.02), (22.76, 0.0225, 0.06), (51.22, 0.0414, 0.32), (85.36, 0.0563, 1.50), (113.81, 0.0596, 3.42), (170.71, 0.0625, 5.12), (256.07, 0.0744, 8.68), ('inf', 0.0853, 15.03)],
+ 'weekly': [(28.46, 0.0033, 0.0), (56.90, 0.0067, 0.09), (113.81, 0.0225, 0.028), (256.08, 0.0414, 1.56), (426.79, 0.0563, 7.45), (569.04, 0.0596, 17.06), (853.56, 0.0625, 25.54), (1280.35, 0.0744, 43.32), ('inf', 0.0853, 75.07)],
+ 'bi-weekly': [(56.92, 0.0033, 0.00), (113.81, 0.0067, 0.19), (227.62, 0.00225, 0.57), (512.15, 0.0414, 3.13), (853.58, 0.0563, 14.91), (1138.08, 0.0596, 34.13), (1707.12, 0.0625, 51.09), (2560.69, 0.0744, 86.66), ('inf', 0.0853, 150.17)],
+ 'semi-monthly': [(61.67, 0.0033, 0.00), (123.29, 0.0067, 0.20), (246.58, 0.0225, 0.61), (554.83, 0.0414, 3.38), (924.71, 0.0563, 16.14), (1232.92, 0.0596, 36.96), (1849.38, 0.0625, 55.33), (2774.08, 0.0744, 93.86), ('inf', 0.0853, 162.66)],
+ 'monthly': [(123.33, 0.0033, 0.00), (246.58, 0.0067, 0.41), (493.17, 0.0225, 1.24), (1109.67, 0.0414, 6.79), (1849.42, 0.0563, 32.31), (2465.83, 0.0596, 73.96), (3698.75, 0.0625, 110.70), (5548.17, 0.0744, 187.76), ('inf', 0.0853, 325.36)],
+ 'annual': [(1480.00, 0.0033, 0.00), (2959.00, 0.0067, 4.88), (5918.00, 0.0225, 14.79), (13316.00, 0.0414, 81.37), (22193.00, 0.0563, 387.65), (29590.00, 0.0596, 887.43), (44385.00, 0.0625, 1328.29), (66578.00, 0.0744, 2252.98), ('inf', 0.0853, 3904.14)],
+ }
+
+
+
+
+
+
+ US IA Iowa Standard Deduction Rate
+ us_ia_sit_standard_deduction_rate
+
+
+
+
+ {
+ '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),
+ }
+
+
+
+
+ {
+ 'daily': ( 7.23, 17.81),
+ 'weekly': ( 36.15, 89.04),
+ 'bi-weekly': ( 72.31, 178.08),
+ 'semi-monthly': ( 78.33, 192.92),
+ 'monthly': ( 156.67, 385.83),
+ 'annually': (1880.00, 4630.00),
+ }
+
+
+
+
+
+
+ US IA Iowa Deduction Allowance Rate
+ us_ia_sit_deduction_allowance_rate
+
+
+
+
+ {
+ 'daily': 0.15,
+ 'weekly': 0.77,
+ 'bi-weekly': 1.54,
+ 'semi-monthly': 1.67,
+ 'monthly': 3.33,
+ 'annually': 40.00,
+ }
+
+
+
+
+ {
+ 'daily': 0.15,
+ 'weekly': 0.77,
+ 'bi-weekly': 1.54,
+ 'semi-monthly': 1.67,
+ 'monthly': 3.33,
+ 'annually': 40.00,
+ }
+
+
+
+
+
+
+
+ US Iowa - Department of Economic Security (IDES) - Unemployment Tax
+
+
+
+ US Iowa - Department of Revenue (IDOR) - Income Tax
+
+
+
+
+
+
+
+
+
+ ER: US IA Iowa State Unemployment
+ ER_US_IA_SUTA
+ python
+ result, _ = general_state_unemployment(payslip, categories, worked_days, inputs, wage_base='us_ia_suta_wage_base', rate='us_ia_suta_rate', state_code='IA')
+ code
+ result, result_rate = general_state_unemployment(payslip, categories, worked_days, inputs, wage_base='us_ia_suta_wage_base', rate='us_ia_suta_rate', state_code='IA')
+
+
+
+
+
+
+
+
+ EE: US IA Iowa State Income Tax Withholding
+ EE_US_IA_SIT
+ python
+ result, _ = ia_iowa_state_income_withholding(payslip, categories, worked_days, inputs)
+ code
+ result, result_rate = ia_iowa_state_income_withholding(payslip, categories, worked_days, inputs)
+
+
+
+
+
\ No newline at end of file
diff --git a/l10n_us_hr_payroll/models/hr_payslip.py b/l10n_us_hr_payroll/models/hr_payslip.py
index c0667415..24bf0548 100644
--- a/l10n_us_hr_payroll/models/hr_payslip.py
+++ b/l10n_us_hr_payroll/models/hr_payslip.py
@@ -21,6 +21,7 @@ from .state.ct_connecticut import ct_connecticut_state_income_withholding
from .state.de_delaware import de_delaware_state_income_withholding
from .state.ga_georgia import ga_georgia_state_income_withholding
from .state.hi_hawaii import hi_hawaii_state_income_withholding
+from .state.ia_iowa import ia_iowa_state_income_withholding
from .state.id_idaho import id_idaho_state_income_withholding
from .state.il_illinois import il_illinois_state_income_withholding
from .state.mi_michigan import mi_michigan_state_income_withholding
@@ -74,6 +75,7 @@ class HRPayslip(models.Model):
'de_delaware_state_income_withholding': de_delaware_state_income_withholding,
'ga_georgia_state_income_withholding': ga_georgia_state_income_withholding,
'hi_hawaii_state_income_withholding': hi_hawaii_state_income_withholding,
+ 'ia_iowa_state_income_withholding': ia_iowa_state_income_withholding,
'id_idaho_state_income_withholding': id_idaho_state_income_withholding,
'il_illinois_state_income_withholding': il_illinois_state_income_withholding,
'mi_michigan_state_income_withholding': mi_michigan_state_income_withholding,
diff --git a/l10n_us_hr_payroll/models/state/ia_iowa.py b/l10n_us_hr_payroll/models/state/ia_iowa.py
new file mode 100644
index 00000000..d12adc64
--- /dev/null
+++ b/l10n_us_hr_payroll/models/state/ia_iowa.py
@@ -0,0 +1,44 @@
+# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
+
+from .general import _state_applies, sit_wage
+
+
+def ia_iowa_state_income_withholding(payslip, categories, worked_days, inputs):
+ """
+ Returns SIT eligible wage and rate.
+
+ :return: result, result_rate (wage, percent)
+ """
+ state_code = 'IA'
+ if not _state_applies(payslip, state_code):
+ return 0.0, 0.0
+
+ # Determine Wage
+ wage = sit_wage(payslip, categories)
+ if not wage:
+ return 0.0, 0.0
+
+ schedule_pay = payslip.contract_id.schedule_pay
+ fed_withholding = categories.EE_US_941_FIT
+ additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
+ allowances = payslip.contract_id.us_payroll_config_value('ia_w4_sit_allowances')
+ standard_deduction = payslip.rule_parameter('us_ia_sit_standard_deduction_rate')[schedule_pay]
+ tax_table = payslip.rule_parameter('us_ia_sit_tax_rate')[schedule_pay]
+ deduction_per_allowance = payslip.rule_parameter('us_ia_sit_deduction_allowance_rate')[schedule_pay]
+
+ t1 = wage + fed_withholding
+ t2 = t1 - standard_deduction[0] if allowances < 2 else standard_deduction[1]
+ t3 = 0.0
+ last = 0.0
+ for row in tax_table:
+ cap, rate, flat_fee = row
+ if float(cap) > float(t2):
+ taxed_amount = t2 - last
+ t3 = flat_fee + (rate * taxed_amount)
+ break
+ last = cap
+ withholding = t3 - (deduction_per_allowance * allowances)
+
+ withholding = max(withholding, 0.0)
+ withholding += additional
+ return wage, -((withholding / wage) * 100.0)
diff --git a/l10n_us_hr_payroll/models/us_payroll_config.py b/l10n_us_hr_payroll/models/us_payroll_config.py
index 55c48951..b1aa0699 100644
--- a/l10n_us_hr_payroll/models/us_payroll_config.py
+++ b/l10n_us_hr_payroll/models/us_payroll_config.py
@@ -112,6 +112,8 @@ class HRContractUSPayrollConfig(models.Model):
], string='Hawaii HW-4 Marital Status', help='HI HW-4 3.')
hi_hw4_sit_allowances = fields.Integer(string='Hawaii HW-4 Allowances', help='HI HW-4 4.')
+ ia_w4_sit_allowances = fields.Integer(string='Iowa W-4 allowances', help='IA W-4 6.')
+
id_w4_sit_filing_status = fields.Selection([
('single', 'Single'),
('married', 'Married'),
diff --git a/l10n_us_hr_payroll/tests/__init__.py b/l10n_us_hr_payroll/tests/__init__.py
index fd80b46d..ffbcfba4 100755
--- a/l10n_us_hr_payroll/tests/__init__.py
+++ b/l10n_us_hr_payroll/tests/__init__.py
@@ -35,6 +35,9 @@ 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_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
new file mode 100644
index 00000000..cb3bccfd
--- /dev/null
+++ b/l10n_us_hr_payroll/tests/test_us_ia_iowa_payslip_2019.py
@@ -0,0 +1,152 @@
+# 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_2020.py b/l10n_us_hr_payroll/tests/test_us_ia_iowa_payslip_2020.py
new file mode 100755
index 00000000..d5d66b16
--- /dev/null
+++ b/l10n_us_hr_payroll/tests/test_us_ia_iowa_payslip_2020.py
@@ -0,0 +1,33 @@
+# 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):
+ ###
+ # 2020 Taxes and Rates
+ ###
+ IA_UNEMP_MAX_WAGE = 31600.00
+ IA_UNEMP = 1.0
+
+ def _test_sit(self, wage, 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_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.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
+
+ def test_2020_taxes_example(self):
+ self._test_er_suta('IA', self.IA_UNEMP, date(2020, 1, 1), wage_base=self.IA_UNEMP_MAX_WAGE)
+ self._test_sit(3000.0, 0.0, 1.0, 'bi-weekly', date(2020, 1, 1), 146.68)
+ self._test_sit(3000.0, 10.0, 1.0, 'bi-weekly', date(2020, 1, 1), 156.68)
+ self._test_sit(30000.0, 0.0, 1.0, 'weekly', date(2020, 1, 1), 1640.04)
diff --git a/l10n_us_hr_payroll/views/us_payroll_config_views.xml b/l10n_us_hr_payroll/views/us_payroll_config_views.xml
index eaa0c8d0..a1afad81 100644
--- a/l10n_us_hr_payroll/views/us_payroll_config_views.xml
+++ b/l10n_us_hr_payroll/views/us_payroll_config_views.xml
@@ -102,6 +102,12 @@
+
+ Form IA W-4 - State Income Tax
+
+
+
+
Form ID W-4 - State Income Tax