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/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,)