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