Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions changelog_entry.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
- bump: minor
changes:
added:
- Create reform to separate dependent children from Virginia personal exemption.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
description: Virginia limits the dependent exemption to dependents under a certain age, if this is true.

values:
0000-01-01: false

metadata:
unit: bool
period: year
label: Virginia dependent exemption age limit in effect
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
description: Virginia limits the dependent exemption to dependents under this age.

values:
2025-01-01: 18

metadata:
label: Virginia dependent exemption age threshold
period: year
unit: year
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
description: Virginia provides this dependent exemption amount per eligible dependent child under the reform.

values:
2025-01-01: 930

metadata:
label: Virginia dependent exemption amount
period: year
unit: currency-USD
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
description: Virginia applies the dependent exemption reform, if this is true (separates dependent children from the personal exemption with configurable amounts and phaseout).

values:
0000-01-01: false

metadata:
unit: bool
period: year
label: Virginia dependent exemption reform in effect
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
description: Virginia phases out the dependent exemption at this rate per dollar of excess AGI.

values:
2025-01-01: 0

metadata:
label: Virginia dependent exemption phaseout rate
period: year
unit: /1
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
description: Virginia phases the dependent exemption out for filers with adjusted gross income above this threshold, based on filing status.

metadata:
label: Virginia dependent exemption phaseout threshold
period: year
unit: currency-USD
breakdown:
- filing_status

JOINT:
2025-01-01: 0

HEAD_OF_HOUSEHOLD:
2025-01-01: 0

SURVIVING_SPOUSE:
2025-01-01: 0

SINGLE:
2025-01-01: 0

SEPARATE:
2025-01-01: 0
7 changes: 7 additions & 0 deletions policyengine_us/reforms/reforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@
from .states.de.dependent_credit.de_dependent_credit_reform import (
create_de_dependent_credit_reform_fn,
)
from .states.va.dependent_exemption.va_dependent_exemption_reform import (
create_va_dependent_exemption_reform_fn,
)
from .aca import (
create_aca_ptc_additional_bracket_reform,
create_aca_ptc_simplified_bracket_reform,
Expand Down Expand Up @@ -283,6 +286,9 @@ def create_structural_reforms_from_parameters(parameters, period):
de_dependent_credit = create_de_dependent_credit_reform_fn(
parameters, period
)
va_dependent_exemption = create_va_dependent_exemption_reform_fn(
parameters, period
)
aca_ptc_additional_bracket = create_aca_ptc_additional_bracket_reform(
parameters, period
)
Expand Down Expand Up @@ -348,6 +354,7 @@ def create_structural_reforms_from_parameters(parameters, period):
ri_ctc,
ri_exemption,
de_dependent_credit,
va_dependent_exemption,
aca_ptc_additional_bracket,
aca_ptc_simplified_bracket,
aca_ptc_700_fpl_cliff,
Expand Down
3 changes: 3 additions & 0 deletions policyengine_us/reforms/states/va/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .dependent_exemption.va_dependent_exemption_reform import (
create_va_dependent_exemption_reform_fn,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
from policyengine_us.model_api import *
from policyengine_core.periods import period as period_
from policyengine_core.periods import instant


def create_va_dependent_exemption_reform() -> Reform:
class va_eligible_dependents_count(Variable):
value_type = int
entity = TaxUnit
label = "Virginia eligible dependents count"
definition_period = YEAR
defined_for = StateCode.VA

def formula(tax_unit, period, parameters):
p = parameters(period).gov.contrib.states.va.dependent_exemption

person = tax_unit.members
age = person("age", period)
is_dependent = person("is_tax_unit_dependent", period)

# Apply age limit if in effect
if p.age_limit.in_effect:
age_threshold = p.age_limit.threshold
eligible_dependents = is_dependent & (age < age_threshold)
else:
eligible_dependents = is_dependent

return tax_unit.sum(eligible_dependents)

class va_dependent_exemption_maximum(Variable):
value_type = float
entity = TaxUnit
label = "Virginia dependent exemption maximum before phaseout"
unit = USD
definition_period = YEAR
defined_for = StateCode.VA

def formula(tax_unit, period, parameters):
p = parameters(period).gov.contrib.states.va.dependent_exemption

dependents_count = tax_unit("va_eligible_dependents_count", period)
return dependents_count * p.amount

class va_dependent_exemption_phaseout(Variable):
value_type = float
entity = TaxUnit
label = "Virginia dependent exemption phaseout amount"
unit = USD
definition_period = YEAR
defined_for = StateCode.VA

def formula(tax_unit, period, parameters):
p = parameters(period).gov.contrib.states.va.dependent_exemption

filing_status = tax_unit("filing_status", period)
agi = tax_unit("va_agi", period)

threshold = p.phaseout.threshold[filing_status]
excess_income = max_(agi - threshold, 0)
return excess_income * p.phaseout.rate

class va_dependent_exemption(Variable):
value_type = float
entity = TaxUnit
label = "Virginia dependent exemption"
unit = USD
definition_period = YEAR
defined_for = StateCode.VA

def formula(tax_unit, period, parameters):

maximum = tax_unit("va_dependent_exemption_maximum", period)
phaseout = tax_unit("va_dependent_exemption_phaseout", period)

return max_(maximum - phaseout, 0)

class va_older_dependents_count(Variable):
value_type = float
entity = TaxUnit
label = "Virginia older dependents count"
unit = USD
definition_period = YEAR
defined_for = StateCode.VA

def formula(tax_unit, period, parameters):
person = tax_unit.members
is_dependent = person("is_tax_unit_dependent", period)
total_dependents = tax_unit.sum(is_dependent)
eligible_dependent_exemptions = tax_unit(
"va_eligible_dependents_count", period
)
return max_(0, total_dependents - eligible_dependent_exemptions)

class va_personal_exemption(Variable):
value_type = float
entity = TaxUnit
label = "Virginia personal exemption"
unit = USD
definition_period = YEAR
defined_for = StateCode.VA

def formula(tax_unit, period, parameters):
p_base = parameters(
period
).gov.states.va.tax.income.exemptions.personal

# Calculate personal exemptions base amount (filer + spouse + older dependents)
filing_status = tax_unit("filing_status", period)
older_dependents = tax_unit("va_older_dependents_count", period)
personal_count = (
where(
filing_status == filing_status.possible_values.JOINT,
2,
1,
)
+ older_dependents
)
personal_exemption_amount = personal_count * p_base

# Add dependent exemption (has its own phase-out logic)
dependent_exemption_amount = tax_unit(
"va_dependent_exemption", period
)

return personal_exemption_amount + dependent_exemption_amount

class reform(Reform):
def apply(self):
self.update_variable(va_eligible_dependents_count)
self.update_variable(va_dependent_exemption_maximum)
self.update_variable(va_dependent_exemption_phaseout)
self.update_variable(va_dependent_exemption)
self.update_variable(va_older_dependents_count)
self.update_variable(va_personal_exemption)

return reform


def create_va_dependent_exemption_reform_fn(
parameters, period, bypass: bool = False
):
if bypass:
return create_va_dependent_exemption_reform()

p = parameters.gov.contrib.states.va.dependent_exemption

reform_active = False
current_period = period_(period)

for i in range(5):
if p(current_period).in_effect:
reform_active = True
break
current_period = current_period.offset(1, "year")

if reform_active:
return create_va_dependent_exemption_reform()
else:
return None


va_dependent_exemption_reform = create_va_dependent_exemption_reform_fn(
None, None, bypass=True
)
Loading
Loading