mirror of
https://gitlab.com/hibou-io/hibou-odoo/suite.git
synced 2025-01-20 12:37:31 +02:00
IMP l10n_us_hr_payroll Port l10n_us_va_hr_payroll VA Virginia including migration
This commit is contained in:
@@ -33,6 +33,7 @@ USA Payroll Rules.
|
|||||||
'data/state/oh_ohio.xml',
|
'data/state/oh_ohio.xml',
|
||||||
'data/state/pa_pennsylvania.xml',
|
'data/state/pa_pennsylvania.xml',
|
||||||
'data/state/tx_texas.xml',
|
'data/state/tx_texas.xml',
|
||||||
|
'data/state/va_virginia.xml',
|
||||||
'data/state/wa_washington.xml',
|
'data/state/wa_washington.xml',
|
||||||
'data/final.xml',
|
'data/final.xml',
|
||||||
'views/hr_contract_views.xml',
|
'views/hr_contract_views.xml',
|
||||||
|
|||||||
@@ -33,6 +33,9 @@
|
|||||||
ref('hr_payroll_rule_er_us_tx_suta_oa'),
|
ref('hr_payroll_rule_er_us_tx_suta_oa'),
|
||||||
ref('hr_payroll_rule_er_us_tx_suta_etia'),
|
ref('hr_payroll_rule_er_us_tx_suta_etia'),
|
||||||
|
|
||||||
|
ref('hr_payroll_rule_er_us_va_suta'),
|
||||||
|
ref('hr_payroll_rule_ee_us_va_sit'),
|
||||||
|
|
||||||
ref('hr_payroll_rule_er_us_wa_suta'),
|
ref('hr_payroll_rule_er_us_wa_suta'),
|
||||||
ref('hr_payroll_rule_er_us_wa_fml'),
|
ref('hr_payroll_rule_er_us_wa_fml'),
|
||||||
ref('hr_payroll_rule_ee_us_wa_fml'),
|
ref('hr_payroll_rule_ee_us_wa_fml'),
|
||||||
|
|||||||
124
l10n_us_hr_payroll/data/state/va_virginia.xml
Normal file
124
l10n_us_hr_payroll/data/state/va_virginia.xml
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<odoo>
|
||||||
|
<!-- Wage Base -->
|
||||||
|
<data noupdate="1">
|
||||||
|
<record id="rule_parameter_us_va_suta_wage_base_2019" model="hr.payroll.rate">
|
||||||
|
<field name="name">US VA Virginia SUTA Wage Base</field>
|
||||||
|
<field name="code">us_va_suta_wage_base</field>
|
||||||
|
<field name="parameter_value">8000.0</field>
|
||||||
|
<field name="date_from" eval="datetime(2019, 1, 1).date()"/>
|
||||||
|
</record>
|
||||||
|
<record id="rule_parameter_us_va_suta_wage_base_2020" model="hr.payroll.rate">
|
||||||
|
<field name="name">US VA Virginia SUTA Wage Base</field>
|
||||||
|
<field name="code">us_va_suta_wage_base</field>
|
||||||
|
<field name="parameter_value">8000.0</field>
|
||||||
|
<field name="date_from" eval="datetime(2020, 1, 1).date()"/>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
<!-- Rate -->
|
||||||
|
<data noupdate="1">
|
||||||
|
<record id="rule_parameter_us_va_suta_rate_2019" model="hr.payroll.rate">
|
||||||
|
<field name="name">US VA Virginia SUTA Rate</field>
|
||||||
|
<field name="code">us_va_suta_rate</field>
|
||||||
|
<field name="parameter_value">2.51</field>
|
||||||
|
<field name="date_from" eval="datetime(2019, 1, 1).date()"/>
|
||||||
|
</record>
|
||||||
|
<record id="rule_parameter_us_va_suta_rate_2020" model="hr.payroll.rate">
|
||||||
|
<field name="name">US VA Virginia SUTA Rate</field>
|
||||||
|
<field name="code">us_va_suta_rate</field>
|
||||||
|
<field name="parameter_value">2.51</field>
|
||||||
|
<field name="date_from" eval="datetime(2020, 1, 1).date()"/>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
<data noupdate="1">
|
||||||
|
<record id="rule_parameter_us_va_sit_rate_2019" model="hr.payroll.rate">
|
||||||
|
<field name="name">US VA Virginia SIT Rate Table</field>
|
||||||
|
<field name="code">us_va_sit_rate</field>
|
||||||
|
<field name="parameter_value">[
|
||||||
|
( 0.00, 0.0, 2.00),
|
||||||
|
( 3000.00, 60.0, 3.00),
|
||||||
|
( 5000.00, 120.0, 5.00),
|
||||||
|
( 17000.00, 720.0, 5.75),
|
||||||
|
]</field>
|
||||||
|
<field name="date_from" eval="datetime(2019, 1, 1).date()"/>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
<data noupdate="1">
|
||||||
|
<record id="rule_parameter_us_va_sit_exemption_rate_2019" model="hr.payroll.rate">
|
||||||
|
<field name="name">US VA Virginia SIT Exemption Rate Table</field>
|
||||||
|
<field name="code">us_va_sit_exemption_rate</field>
|
||||||
|
<field name="parameter_value">930.0</field>
|
||||||
|
<field name="date_from" eval="datetime(2019, 1, 1).date()"/>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
<data noupdate="1">
|
||||||
|
<record id="rule_parameter_us_va_sit_other_exemption_rate_2019" model="hr.payroll.rate">
|
||||||
|
<field name="name">US VA Virginia SIT Other Exemption Rate Table</field>
|
||||||
|
<field name="code">us_va_sit_other_exemption_rate</field>
|
||||||
|
<field name="parameter_value">800.0</field>
|
||||||
|
<field name="date_from" eval="datetime(2019, 1, 1).date()"/>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
<data noupdate="1">
|
||||||
|
<record id="rule_parameter_us_va_sit_deduction_2019" model="hr.payroll.rate">
|
||||||
|
<field name="name">US VA Virginia SIT Deduction</field>
|
||||||
|
<field name="code">us_va_sit_deduction</field>
|
||||||
|
<field name="parameter_value">4500.0</field>
|
||||||
|
<field name="date_from" eval="datetime(2019, 1, 1).date()"/>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
<!-- Partners and Contribution Registers -->
|
||||||
|
<record id="res_partner_us_va_dor" model="res.partner">
|
||||||
|
<field name="name">US Virginia - Department of Taxation - Unemployment Tax</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="contrib_register_us_va_dor" model="hr.contribution.register">
|
||||||
|
<field name="name">US Virginia - Department of Taxation - Unemployment Tax</field>
|
||||||
|
<field name="partner_id" ref="res_partner_us_va_dor"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="res_partner_us_va_dor_sit" model="res.partner">
|
||||||
|
<field name="name">US Virginia - Department of Taxation - Income Tax</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="contrib_register_us_va_dor_sit" model="hr.contribution.register">
|
||||||
|
<field name="name">US Virginia - Department of Taxation - Income Tax</field>
|
||||||
|
<field name="partner_id" ref="res_partner_us_va_dor_sit"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- Categories -->
|
||||||
|
|
||||||
|
<!-- Rules -->
|
||||||
|
<record id="hr_payroll_rule_er_us_va_suta" model="hr.salary.rule">
|
||||||
|
<field name="sequence" eval="450"/>
|
||||||
|
<field name="category_id" ref="hr_payroll_category_er_us_suta"/>
|
||||||
|
<field name="name">ER: US VA Virginia State Unemployment</field>
|
||||||
|
<field name="code">ER_US_VA_SUTA</field>
|
||||||
|
<field name="condition_select">python</field>
|
||||||
|
<field name="condition_python">result, _ = general_state_unemployment(payslip, categories, worked_days, inputs, wage_base='us_va_suta_wage_base', rate='us_va_suta_rate', state_code='VA')</field>
|
||||||
|
<field name="amount_select">code</field>
|
||||||
|
<field name="amount_python_compute">result, result_rate = general_state_unemployment(payslip, categories, worked_days, inputs, wage_base='us_va_suta_wage_base', rate='us_va_suta_rate', state_code='VA')</field>
|
||||||
|
<field name="register_id" ref="contrib_register_us_va_dor"/>
|
||||||
|
<field name="appears_on_payslip" eval="False"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="hr_payroll_rule_ee_us_va_sit" model="hr.salary.rule">
|
||||||
|
<field name="sequence" eval="195"/>
|
||||||
|
<field name="category_id" ref="hr_payroll_category_ee_us_sit"/>
|
||||||
|
<field name="name">EE: US VA Virginia State Income Tax Withholding</field>
|
||||||
|
<field name="code">EE_US_VA_SIT</field>
|
||||||
|
<field name="condition_select">python</field>
|
||||||
|
<field name="condition_python">result, _ = va_virginia_state_income_withholding(payslip, categories, worked_days, inputs)</field>
|
||||||
|
<field name="amount_select">code</field>
|
||||||
|
<field name="amount_python_compute">result, result_rate = va_virginia_state_income_withholding(payslip, categories, worked_days, inputs)</field>
|
||||||
|
<field name="register_id" ref="contrib_register_us_va_dor_sit"/>
|
||||||
|
<field name="appears_on_payslip" eval="True"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</odoo>
|
||||||
@@ -17,6 +17,9 @@ FIELDS_CONTRACT_TO_US_PAYROLL_FORMS_2020 = {
|
|||||||
'oh_income_allowances': 'oh_it4_sit_exemptions',
|
'oh_income_allowances': 'oh_it4_sit_exemptions',
|
||||||
|
|
||||||
'pa_additional_withholding': 'state_income_tax_additional_withholding',
|
'pa_additional_withholding': 'state_income_tax_additional_withholding',
|
||||||
|
|
||||||
|
'va_va4_exemptions': 'va_va4_sit_exemptions',
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XMLIDS_TO_REMOVE_2020 = [
|
XMLIDS_TO_REMOVE_2020 = [
|
||||||
@@ -66,6 +69,11 @@ XMLIDS_TO_REMOVE_2020 = [
|
|||||||
'l10n_us_tx_hr_payroll.hr_payroll_tx_etia',
|
'l10n_us_tx_hr_payroll.hr_payroll_tx_etia',
|
||||||
'l10n_us_tx_hr_payroll.hr_payroll_rules_tx_unemp_wages_2018',
|
'l10n_us_tx_hr_payroll.hr_payroll_rules_tx_unemp_wages_2018',
|
||||||
|
|
||||||
|
'l10n_us_va_hr_payroll.hr_payroll_va_unemp_wages',
|
||||||
|
'l10n_us_va_hr_payroll.hr_payroll_va_unemp',
|
||||||
|
'l10n_us_va_hr_payroll.hr_payroll_va_income_withhold',
|
||||||
|
'l10n_us_va_hr_payroll.hr_payroll_rules_va_unemp_wages_2018',
|
||||||
|
|
||||||
'l10n_us_wa_hr_payroll.hr_payroll_wa_unemp_wages',
|
'l10n_us_wa_hr_payroll.hr_payroll_wa_unemp_wages',
|
||||||
'l10n_us_wa_hr_payroll.hr_payroll_wa_unemp',
|
'l10n_us_wa_hr_payroll.hr_payroll_wa_unemp',
|
||||||
'l10n_us_wa_hr_payroll.hr_payroll_wa_lni',
|
'l10n_us_wa_hr_payroll.hr_payroll_wa_lni',
|
||||||
@@ -120,6 +128,13 @@ XMLIDS_TO_RENAME_2020 = {
|
|||||||
'l10n_us_tx_hr_payroll.hr_payroll_rules_tx_oa_2018': 'l10n_us_hr_payroll.hr_payroll_rule_er_us_tx_suta_oa',
|
'l10n_us_tx_hr_payroll.hr_payroll_rules_tx_oa_2018': 'l10n_us_hr_payroll.hr_payroll_rule_er_us_tx_suta_oa',
|
||||||
'l10n_us_tx_hr_payroll.hr_payroll_rules_tx_etia_2018': 'l10n_us_hr_payroll.hr_payroll_rule_er_us_tx_suta_etia',
|
'l10n_us_tx_hr_payroll.hr_payroll_rules_tx_etia_2018': 'l10n_us_hr_payroll.hr_payroll_rule_er_us_tx_suta_etia',
|
||||||
|
|
||||||
|
'l10n_us_va_hr_payroll.res_partner_vador_unemp': 'l10n_us_hr_payroll.res_partner_us_va_dor',
|
||||||
|
'l10n_us_va_hr_payroll.res_partner_vador_withhold': 'l10n_us_hr_payroll.res_partner_us_va_dor_sit',
|
||||||
|
'l10n_us_va_hr_payroll.contrib_register_vador_unemp': 'l10n_us_hr_payroll.contrib_register_us_va_dor',
|
||||||
|
'l10n_us_va_hr_payroll.contrib_register_vador_withhold': 'l10n_us_hr_payroll.contrib_register_us_va_dor_sit',
|
||||||
|
'l10n_us_va_hr_payroll.hr_payroll_rules_va_unemp_2018': 'l10n_us_hr_payroll.hr_payroll_rule_er_us_va_suta',
|
||||||
|
'l10n_us_va_hr_payroll.hr_payroll_rules_va_inc_withhold_2018': 'l10n_us_hr_payroll.hr_payroll_rule_ee_us_va_sit',
|
||||||
|
|
||||||
'l10n_us_wa_hr_payroll.res_partner_wador_unemp': 'l10n_us_hr_payroll.res_partner_us_wa_dor',
|
'l10n_us_wa_hr_payroll.res_partner_wador_unemp': 'l10n_us_hr_payroll.res_partner_us_wa_dor',
|
||||||
'l10n_us_wa_hr_payroll.res_partner_wador_lni': 'l10n_us_hr_payroll.res_partner_us_wa_dor_lni',
|
'l10n_us_wa_hr_payroll.res_partner_wador_lni': 'l10n_us_hr_payroll.res_partner_us_wa_dor_lni',
|
||||||
'l10n_us_wa_hr_payroll.contrib_register_wador_unemp': 'l10n_us_hr_payroll.contrib_register_us_wa_dor',
|
'l10n_us_wa_hr_payroll.contrib_register_wador_unemp': 'l10n_us_hr_payroll.contrib_register_us_wa_dor',
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ from .state.general import general_state_unemployment, \
|
|||||||
is_us_state
|
is_us_state
|
||||||
from .state.mt_montana import mt_montana_state_income_withholding
|
from .state.mt_montana import mt_montana_state_income_withholding
|
||||||
from .state.oh_ohio import oh_ohio_state_income_withholding
|
from .state.oh_ohio import oh_ohio_state_income_withholding
|
||||||
|
from .state.va_virginia import va_virginia_state_income_withholding
|
||||||
from .state.wa_washington import wa_washington_fml_er, \
|
from .state.wa_washington import wa_washington_fml_er, \
|
||||||
wa_washington_fml_ee
|
wa_washington_fml_ee
|
||||||
|
|
||||||
@@ -50,6 +51,7 @@ class HRPayslip(models.Model):
|
|||||||
'is_us_state': is_us_state,
|
'is_us_state': is_us_state,
|
||||||
'mt_montana_state_income_withholding': mt_montana_state_income_withholding,
|
'mt_montana_state_income_withholding': mt_montana_state_income_withholding,
|
||||||
'oh_ohio_state_income_withholding': oh_ohio_state_income_withholding,
|
'oh_ohio_state_income_withholding': oh_ohio_state_income_withholding,
|
||||||
|
'va_virginia_state_income_withholding': va_virginia_state_income_withholding,
|
||||||
'wa_washington_fml_er': wa_washington_fml_er,
|
'wa_washington_fml_er': wa_washington_fml_er,
|
||||||
'wa_washington_fml_ee': wa_washington_fml_ee,
|
'wa_washington_fml_ee': wa_washington_fml_ee,
|
||||||
}
|
}
|
||||||
|
|||||||
43
l10n_us_hr_payroll/models/state/va_virginia.py
Normal file
43
l10n_us_hr_payroll/models/state/va_virginia.py
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from .general import _state_applies
|
||||||
|
|
||||||
|
|
||||||
|
def va_virginia_state_income_withholding(payslip, categories, worked_days, inputs):
|
||||||
|
"""
|
||||||
|
Returns SIT eligible wage and rate.
|
||||||
|
WAGE = GROSS - WAGE_US_941_FIT_EXEMPT
|
||||||
|
|
||||||
|
:return: result, result_rate (wage, percent)
|
||||||
|
"""
|
||||||
|
state_code = 'VA'
|
||||||
|
if not _state_applies(payslip, state_code):
|
||||||
|
return 0.0, 0.0
|
||||||
|
|
||||||
|
if payslip.dict.contract_id.us_payroll_config_value('state_income_tax_exempt'):
|
||||||
|
return 0.0, 0.0
|
||||||
|
|
||||||
|
# Determine Wage
|
||||||
|
wage = categories.GROSS - categories.WAGE_US_941_FIT_EXEMPT
|
||||||
|
pay_periods = payslip.dict.get_pay_periods_in_year()
|
||||||
|
additional = payslip.dict.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
|
||||||
|
personal_exemptions = payslip.dict.contract_id.us_payroll_config_value('va_va4_sit_exemptions')
|
||||||
|
other_exemptions = payslip.dict.contract_id.us_payroll_config_value('va_va4_sit_other_exemptions')
|
||||||
|
personal_exemption_rate = payslip.dict.rule_parameter('us_va_sit_exemption_rate')
|
||||||
|
other_exemption_rate = payslip.dict.rule_parameter('us_va_sit_other_exemption_rate')
|
||||||
|
deduction = payslip.dict.rule_parameter('us_va_sit_deduction')
|
||||||
|
withholding_rate = payslip.dict.rule_parameter('us_va_sit_rate')
|
||||||
|
if wage == 0.0:
|
||||||
|
return 0.0, 0.0
|
||||||
|
|
||||||
|
taxable_wage = (wage * pay_periods) - (deduction + (personal_exemptions * personal_exemption_rate) + (other_exemptions * other_exemption_rate))
|
||||||
|
withholding = 0.0
|
||||||
|
if taxable_wage > 0.0:
|
||||||
|
for row in withholding_rate:
|
||||||
|
if taxable_wage > row[0]:
|
||||||
|
selected_row = row
|
||||||
|
wage_min, base, rate = selected_row
|
||||||
|
withholding = base + ((taxable_wage - wage_min) * rate / 100.0)
|
||||||
|
withholding /= pay_periods
|
||||||
|
withholding += additional
|
||||||
|
return wage, -((withholding / wage) * 100.0)
|
||||||
@@ -66,3 +66,8 @@ class HRContractUSPayrollConfig(models.Model):
|
|||||||
# Ohio will use generic SIT exempt and additional fields
|
# Ohio will use generic SIT exempt and additional fields
|
||||||
oh_it4_sit_exemptions = fields.Integer(string='Ohio IT-4 Exemptions',
|
oh_it4_sit_exemptions = fields.Integer(string='Ohio IT-4 Exemptions',
|
||||||
help='Line 4')
|
help='Line 4')
|
||||||
|
|
||||||
|
va_va4_sit_exemptions = fields.Integer(string='Virginia VA-4(P) Personal Exemptions',
|
||||||
|
help='VA-4(P) 1(a)')
|
||||||
|
va_va4_sit_other_exemptions = fields.Integer(string='Virginia VA-4(P) Age & Blindness Exemptions',
|
||||||
|
help='VA-4(P) 1(b)')
|
||||||
|
|||||||
@@ -19,5 +19,8 @@ from . import test_us_pa_pennsylvania_payslip_2020
|
|||||||
from . import test_us_tx_texas_payslip_2019
|
from . import test_us_tx_texas_payslip_2019
|
||||||
from . import test_us_tx_texas_payslip_2020
|
from . import test_us_tx_texas_payslip_2020
|
||||||
|
|
||||||
|
from . import test_us_va_virginia_payslip_2019
|
||||||
|
from . import test_us_va_virginia_payslip_2020
|
||||||
|
|
||||||
from . import test_us_wa_washington_payslip_2019
|
from . import test_us_wa_washington_payslip_2019
|
||||||
from . import test_us_wa_washington_payslip_2020
|
from . import test_us_wa_washington_payslip_2020
|
||||||
|
|||||||
133
l10n_us_hr_payroll/tests/test_us_va_virginia_payslip_2019.py
Normal file
133
l10n_us_hr_payroll/tests/test_us_va_virginia_payslip_2019.py
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
# 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)
|
||||||
116
l10n_us_hr_payroll/tests/test_us_va_virginia_payslip_2020.py
Normal file
116
l10n_us_hr_payroll/tests/test_us_va_virginia_payslip_2020.py
Normal file
@@ -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.51
|
||||||
|
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,)
|
||||||
@@ -66,6 +66,13 @@
|
|||||||
<group name="state_tx_texas" string="TX Texas" attrs="{'invisible':[('state_id', '!=', %(base.state_us_44)s)]}">
|
<group name="state_tx_texas" string="TX Texas" attrs="{'invisible':[('state_id', '!=', %(base.state_us_44)s)]}">
|
||||||
<p colspan="2"><h3>No additional fields.</h3></p>
|
<p colspan="2"><h3>No additional fields.</h3></p>
|
||||||
</group>
|
</group>
|
||||||
|
<group name="state_va_virginia" string="VA Virginia" attrs="{'invisible':[('state_id', '!=', %(base.state_us_47)s)]}">
|
||||||
|
<p colspan="2"><h3>Form VA-4/VA-4P - State Income Tax</h3></p>
|
||||||
|
<field name="va_va4_sit_exemptions" string="Personal Exemptions (Line 1(a))"/>
|
||||||
|
<field name="va_va4_sit_other_exemptions" string="Age & Blindness Exemptions (Line 1(b))"/>
|
||||||
|
<field name="state_income_tax_additional_withholding" string="Additional Withholding (Line 2)"/>
|
||||||
|
<field name="state_income_tax_exempt" string="Exempt (Line 3 or 4)"/>
|
||||||
|
</group>
|
||||||
<group name="state_wa_washington" string="WA Washington" attrs="{'invisible':[('state_id', '!=', %(base.state_us_48)s)]}">
|
<group name="state_wa_washington" string="WA Washington" attrs="{'invisible':[('state_id', '!=', %(base.state_us_48)s)]}">
|
||||||
<p colspan="2"><h3>No additional fields.</h3></p>
|
<p colspan="2"><h3>No additional fields.</h3></p>
|
||||||
<p colspan="2">Ensure that your Employee and Employer workers' comp code fields are filled in for WA LNI withholding.</p>
|
<p colspan="2">Ensure that your Employee and Employer workers' comp code fields are filled in for WA LNI withholding.</p>
|
||||||
|
|||||||
Reference in New Issue
Block a user