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: patch
changes:
fixed:
- Fix Virginia spouse tax adjustment to calculate separate VAGI per person instead of prorating combined VAGI.
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,25 @@
va_income_tax_before_non_refundable_credits: 0
output:
va_spouse_tax_adjustment: 0

- name: Elderly head with income below age deduction - not eligible for STA (issue 6958)
period: 2024
absolute_error_margin: 1
input:
people:
head:
age: 75
employment_income: 11_752.73
spouse:
age: 40
employment_income: 55_728.48
tax_units:
tax_unit:
members: [head, spouse]
households:
household:
members: [head, spouse]
state_code: VA
output:
va_spouse_tax_adjustment: 0
va_income_tax: 1_402.22
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@
output:
va_spouse_tax_adjustment_eligible: true

- name: Spouse and Head with AGI less exemption at 0
- name: Spouse and Head with AGI less exemption at 0
period: 2021
input:
people:
Expand All @@ -128,3 +128,27 @@
tax_unit_is_joint: true
output:
va_spouse_tax_adjustment_eligible: false

- name: Elderly head with income below age deduction should not be STA eligible
period: 2021
input:
people:
person1:
adjusted_gross_income_person: 11_753
age: 75
is_tax_unit_head: true
person2:
adjusted_gross_income_person: 55_728
age: 40
is_tax_unit_spouse: true
tax_units:
tax_unit:
members: [person1, person2]
adjusted_gross_income: 67_481
filing_status: JOINT
households:
household:
members: [person1, person2]
state_code: VA
output:
va_spouse_tax_adjustment_eligible: false
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
tax_units:
tax_unit:
members: [person1, person2]
va_agi: 30_000
va_subtractions: 10_000
households:
household:
members: [person1, person2]
Expand All @@ -28,10 +28,34 @@
tax_units:
tax_unit:
members: [person1, person2]
va_agi: 8_000
va_subtractions: 2_000
households:
household:
members: [person1, person2]
state_code: VA
output:
va_agi_person: [8_000, 0]

- name: Age deduction applied directly to eligible person, not prorated
period: 2021
input:
people:
person1:
adjusted_gross_income_person: 11_753
age: 75
is_tax_unit_head_or_spouse: true
person2:
adjusted_gross_income_person: 55_728
age: 40
is_tax_unit_head_or_spouse: true
tax_units:
tax_unit:
members: [person1, person2]
va_subtractions: 12_000
va_age_deduction: 12_000
households:
household:
members: [person1, person2]
state_code: VA
output:
va_agi_person: [-247, 55_728]
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from policyengine_us.model_api import *


class va_age_deduction_person(Variable):
value_type = float
entity = Person
label = "Virginia age deduction allocated to each person"
unit = USD
definition_period = YEAR
reference = "https://www.tax.virginia.gov/sites/default/files/vatax-pdf/2022-760-instructions.pdf#page=16"
defined_for = StateCode.VA

def formula(person, period, parameters):
p = parameters(
period
).gov.states.va.tax.income.subtractions.age_deduction

total_deduction = person.tax_unit("va_age_deduction", period)

age = person("age", period)
is_head_or_spouse = person("is_tax_unit_head_or_spouse", period)
eligible = is_head_or_spouse & (age >= p.age_minimum)

count_eligible = person.tax_unit.sum(eligible)
return where(
eligible & (count_eligible > 0),
total_deduction / count_eligible,
0,
)
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,26 @@ class va_agi_person(Variable):
defined_for = StateCode.VA

def formula(person, period, parameters):
total_agi = person.tax_unit("va_agi", period)
person_agi = person("adjusted_gross_income_person", period)
total_federal_agi = person.tax_unit.sum(person_agi)

prorate = np.zeros_like(total_agi)
mask = total_federal_agi > 0
prorate[mask] = person_agi[mask] / total_federal_agi[mask]
return total_agi * prorate
person_fagi = person("adjusted_gross_income_person", period)
# Apply person-level age deduction directly
age_deduction = person("va_age_deduction_person", period)
# Prorate non-age subtractions by federal AGI share
total_subtractions = person.tax_unit("va_subtractions", period)
total_age_deduction = person.tax_unit("va_age_deduction", period)
non_age_subtractions = max_(
total_subtractions - total_age_deduction, 0
)
total_federal_agi = person.tax_unit.sum(person_fagi)
prorate = where(
total_federal_agi > 0, person_fagi / total_federal_agi, 0
)
person_non_age_subtractions = non_age_subtractions * prorate
# Prorate additions the same way
additions = person.tax_unit("va_additions", period)
person_additions = additions * prorate
return (
person_fagi
+ person_additions
- age_deduction
- person_non_age_subtractions
)