policyengine-us 1.358.1__py3-none-any.whl → 1.359.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of policyengine-us might be problematic. Click here for more details.
- policyengine_us/parameters/gov/states/vt/tax/income/agi/retirement_income_exemption/military_retirement/amount.yaml +3 -1
- policyengine_us/parameters/gov/states/vt/tax/income/agi/retirement_income_exemption/military_retirement/full_exemption_threshold.yaml +11 -0
- policyengine_us/parameters/gov/states/vt/tax/income/agi/retirement_income_exemption/military_retirement/income_based_structure/in_effect.yaml +11 -0
- policyengine_us/parameters/gov/states/vt/tax/income/agi/retirement_income_exemption/military_retirement/partial_exemption_threshold.yaml +11 -0
- policyengine_us/parameters/gov/states/vt/tax/income/agi/retirement_income_exemption/social_security/reduction/end.yaml +7 -0
- policyengine_us/parameters/gov/states/vt/tax/income/agi/retirement_income_exemption/social_security/reduction/start.yaml +7 -0
- policyengine_us/parameters/gov/states/vt/tax/income/credits/ctc/age_limit.yaml +3 -0
- policyengine_us/parameters/gov/states/vt/tax/income/credits/eitc/enhanced_structure/in_effect.yaml +13 -0
- policyengine_us/parameters/gov/states/vt/tax/income/credits/eitc/enhanced_structure/rate.yaml +21 -0
- policyengine_us/parameters/gov/states/vt/tax/income/credits/refundable.yaml +8 -1
- policyengine_us/parameters/gov/states/vt/tax/income/credits/veteran/amount.yaml +11 -0
- policyengine_us/parameters/gov/states/vt/tax/income/credits/veteran/full_credit_threshold.yaml +11 -0
- policyengine_us/parameters/gov/states/vt/tax/income/credits/veteran/income_increment.yaml +11 -0
- policyengine_us/parameters/gov/states/vt/tax/income/credits/veteran/partial_credit_threshold.yaml +11 -0
- policyengine_us/parameters/gov/states/vt/tax/income/credits/veteran/reduction_per_increment.yaml +11 -0
- policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/agi/subtractions/vt_military_retirement_pay_exclusion.yaml +55 -0
- policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/agi/subtractions/vt_retirement_income_exemption.yaml +53 -0
- policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/credits/vt_ctc.yaml +37 -0
- policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/credits/vt_veteran_tax_credit.yaml +151 -0
- policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/vt_eitc.yaml +39 -0
- policyengine_us/tests/variables/gov/states/vt/tax/income/adjusted_gross_income/subtractions/retirement_income_exemption/vt_military_retirement_income_based_exemption.yaml +106 -0
- policyengine_us/tests/variables/gov/states/vt/tax/income/credits/vt_veteran_tax_credit.yaml +129 -0
- policyengine_us/tests/variables/gov/states/vt/tax/income/vt_eitc.yaml +100 -0
- policyengine_us/variables/gov/states/vt/tax/income/adjusted_gross_income/subtractions/retirement_income_exemption/vt_military_retirement_cap_based_exemption.py +25 -0
- policyengine_us/variables/gov/states/vt/tax/income/adjusted_gross_income/subtractions/retirement_income_exemption/vt_military_retirement_income_based_exemption.py +79 -0
- policyengine_us/variables/gov/states/vt/tax/income/adjusted_gross_income/subtractions/retirement_income_exemption/vt_military_retirement_pay_exclusion.py +19 -4
- policyengine_us/variables/gov/states/vt/tax/income/credits/vt_veteran_tax_credit.py +58 -0
- policyengine_us/variables/gov/states/vt/tax/income/vt_eitc.py +9 -1
- {policyengine_us-1.358.1.dist-info → policyengine_us-1.359.1.dist-info}/METADATA +1 -1
- {policyengine_us-1.358.1.dist-info → policyengine_us-1.359.1.dist-info}/RECORD +33 -16
- {policyengine_us-1.358.1.dist-info → policyengine_us-1.359.1.dist-info}/WHEEL +0 -0
- {policyengine_us-1.358.1.dist-info → policyengine_us-1.359.1.dist-info}/entry_points.txt +0 -0
- {policyengine_us-1.358.1.dist-info → policyengine_us-1.359.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
- name: No military retirement pay - zero exemption
|
|
2
|
+
period: 2025
|
|
3
|
+
input:
|
|
4
|
+
state_code: VT
|
|
5
|
+
military_retirement_pay: 0
|
|
6
|
+
adjusted_gross_income: 100_000
|
|
7
|
+
output:
|
|
8
|
+
vt_military_retirement_income_based_exemption: 0
|
|
9
|
+
|
|
10
|
+
- name: Before 2025 - no income-based exemption (thresholds are infinity)
|
|
11
|
+
period: 2024
|
|
12
|
+
input:
|
|
13
|
+
state_code: VT
|
|
14
|
+
military_retirement_pay: 15_000
|
|
15
|
+
adjusted_gross_income: 50_000 # Low AGI but before effective date
|
|
16
|
+
output:
|
|
17
|
+
vt_military_retirement_income_based_exemption: 0
|
|
18
|
+
|
|
19
|
+
- name: 2025 full exemption - AGI below threshold
|
|
20
|
+
period: 2025
|
|
21
|
+
input:
|
|
22
|
+
state_code: VT
|
|
23
|
+
military_retirement_pay: 15_000
|
|
24
|
+
adjusted_gross_income: 100_000 # Below $125,000 threshold
|
|
25
|
+
output:
|
|
26
|
+
vt_military_retirement_income_based_exemption: 15_000
|
|
27
|
+
|
|
28
|
+
- name: 2025 no exemption - AGI above partial threshold
|
|
29
|
+
period: 2025
|
|
30
|
+
input:
|
|
31
|
+
state_code: VT
|
|
32
|
+
military_retirement_pay: 15_000
|
|
33
|
+
adjusted_gross_income: 180_000 # Above $175,000 threshold
|
|
34
|
+
output:
|
|
35
|
+
vt_military_retirement_income_based_exemption: 0
|
|
36
|
+
|
|
37
|
+
- name: 2025 partial exemption - midpoint calculation
|
|
38
|
+
period: 2025
|
|
39
|
+
input:
|
|
40
|
+
state_code: VT
|
|
41
|
+
military_retirement_pay: 20_000
|
|
42
|
+
adjusted_gross_income: 150_000 # Midpoint between $125K and $175K thresholds
|
|
43
|
+
output:
|
|
44
|
+
# (175,000 - 150,000) / (175,000 - 125,000) = 25,000 / 50,000 = 0.5
|
|
45
|
+
# 0.5 * 20,000 = 10,000
|
|
46
|
+
vt_military_retirement_income_based_exemption: 10_000
|
|
47
|
+
|
|
48
|
+
- name: 2025 partial exemption - near full threshold
|
|
49
|
+
period: 2025
|
|
50
|
+
input:
|
|
51
|
+
state_code: VT
|
|
52
|
+
military_retirement_pay: 30_000
|
|
53
|
+
adjusted_gross_income: 130_000 # $5K above full threshold
|
|
54
|
+
output:
|
|
55
|
+
# (175,000 - 130,000) / (175,000 - 125,000) = 45,000 / 50,000 = 0.9
|
|
56
|
+
# 0.9 * 30,000 = 27,000
|
|
57
|
+
vt_military_retirement_income_based_exemption: 27_000
|
|
58
|
+
|
|
59
|
+
- name: 2025 full exemption at threshold boundary
|
|
60
|
+
period: 2025
|
|
61
|
+
input:
|
|
62
|
+
state_code: VT
|
|
63
|
+
military_retirement_pay: 20_000
|
|
64
|
+
adjusted_gross_income: 124_999 # Just below $125,000 threshold
|
|
65
|
+
output:
|
|
66
|
+
vt_military_retirement_income_based_exemption: 20_000
|
|
67
|
+
|
|
68
|
+
- name: 2025 zero exemption exactly at partial threshold
|
|
69
|
+
period: 2025
|
|
70
|
+
input:
|
|
71
|
+
state_code: VT
|
|
72
|
+
military_retirement_pay: 15_000
|
|
73
|
+
adjusted_gross_income: 175_000 # Exactly at $175,000 threshold
|
|
74
|
+
output:
|
|
75
|
+
vt_military_retirement_income_based_exemption: 0
|
|
76
|
+
|
|
77
|
+
- name: 2025 small partial exemption near upper threshold
|
|
78
|
+
period: 2025
|
|
79
|
+
input:
|
|
80
|
+
state_code: VT
|
|
81
|
+
military_retirement_pay: 25_000
|
|
82
|
+
adjusted_gross_income: 170_000 # $5K below partial threshold
|
|
83
|
+
output:
|
|
84
|
+
# (175,000 - 170,000) / (175,000 - 125,000) = 5,000 / 50,000 = 0.1
|
|
85
|
+
# 0.1 * 25,000 = 2,500
|
|
86
|
+
vt_military_retirement_income_based_exemption: 2_500
|
|
87
|
+
|
|
88
|
+
- name: 2025 zero AGI - full exemption
|
|
89
|
+
period: 2025
|
|
90
|
+
input:
|
|
91
|
+
state_code: VT
|
|
92
|
+
military_retirement_pay: 10_000
|
|
93
|
+
adjusted_gross_income: 0
|
|
94
|
+
output:
|
|
95
|
+
vt_military_retirement_income_based_exemption: 10_000
|
|
96
|
+
|
|
97
|
+
- name: 2025 large retirement amount with partial exemption
|
|
98
|
+
period: 2025
|
|
99
|
+
input:
|
|
100
|
+
state_code: VT
|
|
101
|
+
military_retirement_pay: 100_000
|
|
102
|
+
adjusted_gross_income: 160_000 # In partial range
|
|
103
|
+
output:
|
|
104
|
+
# (175,000 - 160,000) / (175,000 - 125,000) = 15,000 / 50,000 = 0.3
|
|
105
|
+
# 0.3 * 100,000 = 30,000
|
|
106
|
+
vt_military_retirement_income_based_exemption: 30_000
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
- name: No veteran status - zero credit
|
|
2
|
+
period: 2025
|
|
3
|
+
input:
|
|
4
|
+
is_veteran: false
|
|
5
|
+
adjusted_gross_income: 20_000
|
|
6
|
+
output:
|
|
7
|
+
vt_veteran_tax_credit: 0
|
|
8
|
+
|
|
9
|
+
- name: Veteran with low AGI - full credit amount
|
|
10
|
+
period: 2025
|
|
11
|
+
input:
|
|
12
|
+
state_code: VT
|
|
13
|
+
is_veteran: true
|
|
14
|
+
adjusted_gross_income: 20_000 # Below $25,000 threshold
|
|
15
|
+
output:
|
|
16
|
+
vt_veteran_tax_credit: 250
|
|
17
|
+
|
|
18
|
+
- name: Veteran at full credit threshold boundary
|
|
19
|
+
period: 2025
|
|
20
|
+
input:
|
|
21
|
+
state_code: VT
|
|
22
|
+
is_veteran: true
|
|
23
|
+
adjusted_gross_income: 24_999 # Just below $25,000 threshold
|
|
24
|
+
output:
|
|
25
|
+
vt_veteran_tax_credit: 250
|
|
26
|
+
|
|
27
|
+
- name: Veteran just above full credit threshold
|
|
28
|
+
period: 2025
|
|
29
|
+
input:
|
|
30
|
+
state_code: VT
|
|
31
|
+
is_veteran: true
|
|
32
|
+
adjusted_gross_income: 25_050 # $50 above threshold, triggers first increment
|
|
33
|
+
output:
|
|
34
|
+
# ceil(50/100) = 1 increment, $250 - (1 * $5) = $245
|
|
35
|
+
vt_veteran_tax_credit: 245
|
|
36
|
+
|
|
37
|
+
- name: Veteran at exact increment boundary
|
|
38
|
+
period: 2025
|
|
39
|
+
input:
|
|
40
|
+
state_code: VT
|
|
41
|
+
is_veteran: true
|
|
42
|
+
adjusted_gross_income: 25_200 # Exactly 2 increments above threshold
|
|
43
|
+
output:
|
|
44
|
+
# ceil(200/100) = 2 increments, $250 - (2 * $5) = $240
|
|
45
|
+
vt_veteran_tax_credit: 240
|
|
46
|
+
|
|
47
|
+
- name: Veteran with moderate income reduction
|
|
48
|
+
period: 2025
|
|
49
|
+
input:
|
|
50
|
+
state_code: VT
|
|
51
|
+
is_veteran: true
|
|
52
|
+
adjusted_gross_income: 27_000 # $2,000 above threshold
|
|
53
|
+
output:
|
|
54
|
+
# ceil(2000/100) = 20 increments, $250 - (20 * $5) = $150
|
|
55
|
+
vt_veteran_tax_credit: 150
|
|
56
|
+
|
|
57
|
+
- name: Veteran near phaseout boundary
|
|
58
|
+
period: 2025
|
|
59
|
+
input:
|
|
60
|
+
is_veteran: true
|
|
61
|
+
adjusted_gross_income: 29_950 # $50 below $30,000 threshold
|
|
62
|
+
output:
|
|
63
|
+
# ceil(4950/100) = 50 increments, $250 - (50 * $5) = $0 (max reduction reached)
|
|
64
|
+
vt_veteran_tax_credit: 0
|
|
65
|
+
|
|
66
|
+
- name: Veteran above partial credit threshold - no credit
|
|
67
|
+
period: 2025
|
|
68
|
+
input:
|
|
69
|
+
is_veteran: true
|
|
70
|
+
adjusted_gross_income: 35_000 # Above $30,000 threshold
|
|
71
|
+
output:
|
|
72
|
+
vt_veteran_tax_credit: 0
|
|
73
|
+
|
|
74
|
+
- name: Before 2025 - no credit regardless of veteran status and income
|
|
75
|
+
period: 2024
|
|
76
|
+
input:
|
|
77
|
+
is_veteran: true
|
|
78
|
+
adjusted_gross_income: 15_000 # Low income but before effective date
|
|
79
|
+
output:
|
|
80
|
+
vt_veteran_tax_credit: 0
|
|
81
|
+
|
|
82
|
+
- name: Veteran with zero AGI - full credit
|
|
83
|
+
period: 2025
|
|
84
|
+
input:
|
|
85
|
+
state_code: VT
|
|
86
|
+
is_veteran: true
|
|
87
|
+
adjusted_gross_income: 0
|
|
88
|
+
output:
|
|
89
|
+
vt_veteran_tax_credit: 250
|
|
90
|
+
|
|
91
|
+
- name: Multiple veterans in tax unit
|
|
92
|
+
period: 2025
|
|
93
|
+
input:
|
|
94
|
+
people:
|
|
95
|
+
veteran1:
|
|
96
|
+
is_veteran: true
|
|
97
|
+
veteran2:
|
|
98
|
+
is_veteran: true
|
|
99
|
+
tax_units:
|
|
100
|
+
tax_unit:
|
|
101
|
+
members: [veteran1, veteran2]
|
|
102
|
+
adjusted_gross_income: 20_000
|
|
103
|
+
households:
|
|
104
|
+
household:
|
|
105
|
+
members: [veteran1, veteran2]
|
|
106
|
+
state_code: VT
|
|
107
|
+
output:
|
|
108
|
+
# Credit applies per tax unit, not per veteran
|
|
109
|
+
vt_veteran_tax_credit: 250
|
|
110
|
+
|
|
111
|
+
- name: Mixed household with one veteran
|
|
112
|
+
period: 2025
|
|
113
|
+
input:
|
|
114
|
+
people:
|
|
115
|
+
veteran:
|
|
116
|
+
is_veteran: true
|
|
117
|
+
non_veteran:
|
|
118
|
+
is_veteran: false
|
|
119
|
+
tax_units:
|
|
120
|
+
tax_unit:
|
|
121
|
+
members: [veteran, non_veteran]
|
|
122
|
+
adjusted_gross_income: 20_000
|
|
123
|
+
households:
|
|
124
|
+
household:
|
|
125
|
+
members: [veteran, non_veteran]
|
|
126
|
+
state_code: VT
|
|
127
|
+
output:
|
|
128
|
+
# Credit applies if any member is veteran
|
|
129
|
+
vt_veteran_tax_credit: 250
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
- name: Zero federal EITC - zero Vermont EITC
|
|
2
|
+
period: 2022
|
|
3
|
+
input:
|
|
4
|
+
eitc: 0
|
|
5
|
+
tax_unit_child_dependents: 1
|
|
6
|
+
output:
|
|
7
|
+
vt_eitc: 0
|
|
8
|
+
|
|
9
|
+
- name: Federal EITC with one child - 38% match rate in 2022
|
|
10
|
+
period: 2022
|
|
11
|
+
input:
|
|
12
|
+
state_code: VT
|
|
13
|
+
eitc: 1_000
|
|
14
|
+
tax_unit_child_dependents: 1
|
|
15
|
+
output:
|
|
16
|
+
vt_eitc: 380 # 38% of $1,000
|
|
17
|
+
|
|
18
|
+
- name: Federal EITC with multiple children - 38% match rate in 2022
|
|
19
|
+
period: 2022
|
|
20
|
+
input:
|
|
21
|
+
state_code: VT
|
|
22
|
+
eitc: 2_000
|
|
23
|
+
tax_unit_child_dependents: 2
|
|
24
|
+
output:
|
|
25
|
+
vt_eitc: 760 # 38% of $2,000
|
|
26
|
+
|
|
27
|
+
- name: Federal EITC with no children - 38% match rate in 2022 (before enhancement)
|
|
28
|
+
period: 2022
|
|
29
|
+
input:
|
|
30
|
+
state_code: VT
|
|
31
|
+
eitc: 500
|
|
32
|
+
tax_unit_child_dependents: 0
|
|
33
|
+
output:
|
|
34
|
+
vt_eitc: 190 # 38% of $500
|
|
35
|
+
|
|
36
|
+
- name: Enhanced structure not in effect - use basic match rate in 2024
|
|
37
|
+
period: 2024
|
|
38
|
+
input:
|
|
39
|
+
state_code: VT
|
|
40
|
+
eitc: 1_200
|
|
41
|
+
tax_unit_child_dependents: 1
|
|
42
|
+
output:
|
|
43
|
+
vt_eitc: 456 # 38% of $1,200 (using basic match rate)
|
|
44
|
+
|
|
45
|
+
- name: Enhanced structure in effect for childless workers in 2025
|
|
46
|
+
period: 2025
|
|
47
|
+
input:
|
|
48
|
+
state_code: VT
|
|
49
|
+
eitc: 600
|
|
50
|
+
tax_unit_child_dependents: 0
|
|
51
|
+
output:
|
|
52
|
+
# Enhanced structure should provide 100% match for childless workers
|
|
53
|
+
vt_eitc: 600
|
|
54
|
+
|
|
55
|
+
- name: Enhanced structure in effect for workers with children in 2025
|
|
56
|
+
period: 2025
|
|
57
|
+
input:
|
|
58
|
+
state_code: VT
|
|
59
|
+
eitc: 1_500
|
|
60
|
+
tax_unit_child_dependents: 1
|
|
61
|
+
output:
|
|
62
|
+
# Enhanced structure should still use 38% match for workers with children
|
|
63
|
+
vt_eitc: 570
|
|
64
|
+
|
|
65
|
+
- name: Large federal EITC amount
|
|
66
|
+
period: 2022
|
|
67
|
+
input:
|
|
68
|
+
state_code: VT
|
|
69
|
+
eitc: 5_000
|
|
70
|
+
tax_unit_child_dependents: 3
|
|
71
|
+
output:
|
|
72
|
+
vt_eitc: 1_900 # 38% of $5,000
|
|
73
|
+
|
|
74
|
+
- name: Very small federal EITC amount
|
|
75
|
+
period: 2022
|
|
76
|
+
input:
|
|
77
|
+
state_code: VT
|
|
78
|
+
eitc: 1
|
|
79
|
+
tax_unit_child_dependents: 1
|
|
80
|
+
output:
|
|
81
|
+
vt_eitc: 0.38 # 38% of $1
|
|
82
|
+
|
|
83
|
+
- name: Federal EITC in 2021 with 36% match rate
|
|
84
|
+
period: 2021
|
|
85
|
+
input:
|
|
86
|
+
state_code: VT
|
|
87
|
+
eitc: 1_000
|
|
88
|
+
tax_unit_child_dependents: 1
|
|
89
|
+
output:
|
|
90
|
+
vt_eitc: 360 # 36% of $1,000 (2021 rate)
|
|
91
|
+
|
|
92
|
+
- name: Three children in enhanced structure
|
|
93
|
+
period: 2025
|
|
94
|
+
input:
|
|
95
|
+
state_code: VT
|
|
96
|
+
eitc: 2_000
|
|
97
|
+
tax_unit_child_dependents: 3
|
|
98
|
+
output:
|
|
99
|
+
# Enhanced structure should use parameterized rate for 3 children
|
|
100
|
+
vt_eitc: 760 # Should be 38% for children in most cases
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from policyengine_us.model_api import *
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class vt_military_retirement_cap_based_exemption(Variable):
|
|
5
|
+
value_type = float
|
|
6
|
+
entity = TaxUnit
|
|
7
|
+
definition_period = YEAR
|
|
8
|
+
label = "Vermont military retirement cap-based exemption"
|
|
9
|
+
reference = "https://tax.vermont.gov/sites/tax/files/documents/IN-112-Instr-2024.pdf#page=2"
|
|
10
|
+
unit = USD
|
|
11
|
+
defined_for = StateCode.VT
|
|
12
|
+
documentation = "Vermont military retirement benefits exempt from Vermont taxation up to cap amount (pre-2025)."
|
|
13
|
+
|
|
14
|
+
def formula(tax_unit, period, parameters):
|
|
15
|
+
p = parameters(
|
|
16
|
+
period
|
|
17
|
+
).gov.states.vt.tax.income.agi.retirement_income_exemption.military_retirement
|
|
18
|
+
|
|
19
|
+
# Get retirement amount from military retirement system
|
|
20
|
+
tax_unit_military_retirement_pay = add(
|
|
21
|
+
tax_unit, period, ["military_retirement_pay"]
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
# Cap exemption at the specified amount
|
|
25
|
+
return min_(tax_unit_military_retirement_pay, p.amount)
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
from policyengine_us.model_api import *
|
|
2
|
+
import numpy as np
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class vt_military_retirement_income_based_exemption(Variable):
|
|
6
|
+
value_type = float
|
|
7
|
+
entity = TaxUnit
|
|
8
|
+
definition_period = YEAR
|
|
9
|
+
label = "Vermont military retirement income-based exemption"
|
|
10
|
+
reference = "https://legislature.vermont.gov/Documents/2026/Docs/BILLS/S-0051/S-0051%20As%20Passed%20by%20Both%20House%20and%20Senate%20Official.pdf#page=10"
|
|
11
|
+
unit = USD
|
|
12
|
+
defined_for = StateCode.VT
|
|
13
|
+
documentation = "Vermont military retirement benefits exempt from Vermont taxation based on AGI thresholds (2025+)."
|
|
14
|
+
|
|
15
|
+
def formula(tax_unit, period, parameters):
|
|
16
|
+
p = parameters(
|
|
17
|
+
period
|
|
18
|
+
).gov.states.vt.tax.income.agi.retirement_income_exemption.military_retirement
|
|
19
|
+
|
|
20
|
+
# Get retirement amount from military retirement system
|
|
21
|
+
tax_unit_military_retirement_pay = add(
|
|
22
|
+
tax_unit, period, ["military_retirement_pay"]
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
agi = tax_unit("adjusted_gross_income", period)
|
|
26
|
+
|
|
27
|
+
# Check if thresholds are finite (feature is active)
|
|
28
|
+
thresholds_are_finite = ~np.isinf(
|
|
29
|
+
p.full_exemption_threshold
|
|
30
|
+
) & ~np.isinf(p.partial_exemption_threshold)
|
|
31
|
+
|
|
32
|
+
# Full exemption if below the threshold AND thresholds are finite
|
|
33
|
+
eligible_for_full_exemption = thresholds_are_finite & (
|
|
34
|
+
agi < p.full_exemption_threshold
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
# Partial exemption if between the thresholds AND thresholds are finite
|
|
38
|
+
eligible_for_partial_exemption = (
|
|
39
|
+
thresholds_are_finite
|
|
40
|
+
& (agi >= p.full_exemption_threshold)
|
|
41
|
+
& (agi <= p.partial_exemption_threshold)
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
# Calculate partial exemption amount (linear phaseout)
|
|
45
|
+
threshold_difference = (
|
|
46
|
+
p.partial_exemption_threshold - p.full_exemption_threshold
|
|
47
|
+
)
|
|
48
|
+
agi_below_threshold = max_(p.partial_exemption_threshold - agi, 0)
|
|
49
|
+
|
|
50
|
+
# Use mask to avoid division by zero
|
|
51
|
+
valid_threshold_difference = threshold_difference != 0
|
|
52
|
+
partial_exemption_amount = where(
|
|
53
|
+
valid_threshold_difference,
|
|
54
|
+
tax_unit_military_retirement_pay
|
|
55
|
+
* agi_below_threshold
|
|
56
|
+
/ threshold_difference,
|
|
57
|
+
0,
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
# Calculate exemption amounts for each case
|
|
61
|
+
full_exemption_amount = tax_unit_military_retirement_pay
|
|
62
|
+
partial_exemption_amount_capped = max_(partial_exemption_amount, 0)
|
|
63
|
+
no_exemption_amount = 0
|
|
64
|
+
|
|
65
|
+
# First determine if partial or no exemption
|
|
66
|
+
partial_or_no_exemption = where(
|
|
67
|
+
eligible_for_partial_exemption,
|
|
68
|
+
partial_exemption_amount_capped,
|
|
69
|
+
no_exemption_amount,
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
# Then determine final exemption amount
|
|
73
|
+
exemption_amount = where(
|
|
74
|
+
eligible_for_full_exemption,
|
|
75
|
+
full_exemption_amount,
|
|
76
|
+
partial_or_no_exemption,
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
return exemption_amount
|
|
@@ -17,7 +17,6 @@ class vt_military_retirement_pay_exclusion(Variable):
|
|
|
17
17
|
)
|
|
18
18
|
|
|
19
19
|
def formula(tax_unit, period, parameters):
|
|
20
|
-
person = tax_unit.members
|
|
21
20
|
p = parameters(
|
|
22
21
|
period
|
|
23
22
|
).gov.states.vt.tax.income.agi.retirement_income_exemption
|
|
@@ -25,7 +24,23 @@ class vt_military_retirement_pay_exclusion(Variable):
|
|
|
25
24
|
tax_unit_military_retirement_pay = add(
|
|
26
25
|
tax_unit, period, ["military_retirement_pay"]
|
|
27
26
|
)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
|
|
28
|
+
# S.51 (2025): Income-based military pension exemption
|
|
29
|
+
is_income_based_system = (
|
|
30
|
+
p.military_retirement.income_based_structure.in_effect
|
|
31
|
+
)
|
|
32
|
+
agi = tax_unit("adjusted_gross_income", period)
|
|
33
|
+
|
|
34
|
+
# Calculate exemption based on system type
|
|
35
|
+
income_based_exemption = tax_unit(
|
|
36
|
+
"vt_military_retirement_income_based_exemption", period
|
|
37
|
+
)
|
|
38
|
+
cap_based_exemption = tax_unit(
|
|
39
|
+
"vt_military_retirement_cap_based_exemption", period
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
return where(
|
|
43
|
+
is_income_based_system,
|
|
44
|
+
income_based_exemption,
|
|
45
|
+
cap_based_exemption,
|
|
31
46
|
)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from policyengine_us.model_api import *
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class vt_veteran_tax_credit(Variable):
|
|
5
|
+
value_type = float
|
|
6
|
+
entity = TaxUnit
|
|
7
|
+
label = "Vermont veteran tax credit"
|
|
8
|
+
definition_period = YEAR
|
|
9
|
+
unit = USD
|
|
10
|
+
reference = [
|
|
11
|
+
"https://vtdigger.org/2025/06/25/gov-phil-scott-signs-13-5-million-tax-credit-package-benefiting-low-income-workers-families-retirees-and-veterans/"
|
|
12
|
+
]
|
|
13
|
+
defined_for = StateCode.VT
|
|
14
|
+
documentation = "Vermont veteran tax credit providing $250 refundable credit for low-income veterans as part of S.51 (2025) tax relief package."
|
|
15
|
+
|
|
16
|
+
def formula(tax_unit, period, parameters):
|
|
17
|
+
# Check if anyone in tax unit is a veteran
|
|
18
|
+
person = tax_unit.members
|
|
19
|
+
is_veteran = person("is_veteran", period)
|
|
20
|
+
veteran_present = tax_unit.any(is_veteran)
|
|
21
|
+
|
|
22
|
+
# Get parameters for veteran credit
|
|
23
|
+
p = parameters(period).gov.states.vt.tax.income.credits.veteran
|
|
24
|
+
|
|
25
|
+
# Get adjusted gross income for phaseout
|
|
26
|
+
agi = tax_unit("adjusted_gross_income", period)
|
|
27
|
+
|
|
28
|
+
# Full credit for households under $25k AGI
|
|
29
|
+
# Partial credit for households under $30k AGI
|
|
30
|
+
|
|
31
|
+
# Calculate credit amount based on veteran status and income
|
|
32
|
+
eligible_for_full_credit = veteran_present & (
|
|
33
|
+
agi < p.full_credit_threshold
|
|
34
|
+
)
|
|
35
|
+
eligible_for_partial_credit = (
|
|
36
|
+
veteran_present
|
|
37
|
+
& (agi >= p.full_credit_threshold)
|
|
38
|
+
& (agi < p.partial_credit_threshold)
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
# Calculate partial credit amount based on parameterized reduction structure
|
|
42
|
+
excess_income = agi - p.full_credit_threshold
|
|
43
|
+
# Number of income increments (rounded up)
|
|
44
|
+
income_increments = np.ceil(excess_income / p.income_increment)
|
|
45
|
+
# Reduction per increment
|
|
46
|
+
reduction_amount = income_increments * p.reduction_per_increment
|
|
47
|
+
# Calculate partial credit (minimum of 0)
|
|
48
|
+
partial_credit_amount = max_(p.amount - reduction_amount, 0)
|
|
49
|
+
|
|
50
|
+
return where(
|
|
51
|
+
eligible_for_full_credit,
|
|
52
|
+
p.amount,
|
|
53
|
+
where(
|
|
54
|
+
eligible_for_partial_credit,
|
|
55
|
+
partial_credit_amount,
|
|
56
|
+
0,
|
|
57
|
+
),
|
|
58
|
+
)
|
|
@@ -12,5 +12,13 @@ class vt_eitc(Variable):
|
|
|
12
12
|
|
|
13
13
|
def formula(tax_unit, period, parameters):
|
|
14
14
|
federal_eitc = tax_unit("eitc", period)
|
|
15
|
-
|
|
15
|
+
p = parameters(period).gov.states.vt.tax.income.credits.eitc
|
|
16
|
+
child_dependents = tax_unit("tax_unit_child_dependents", period)
|
|
17
|
+
|
|
18
|
+
rate = where(
|
|
19
|
+
p.enhanced_structure.in_effect,
|
|
20
|
+
p.enhanced_structure.rate.calc(child_dependents),
|
|
21
|
+
p.match,
|
|
22
|
+
)
|
|
23
|
+
|
|
16
24
|
return federal_eitc * rate
|