policyengine-us 1.354.0__py3-none-any.whl → 1.356.0__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/aca/ineligible_immigration_statuses.yaml +11 -0
- policyengine_us/parameters/gov/hhs/medicaid/eligibility/work_requirements/age_range.yaml +25 -0
- policyengine_us/parameters/gov/hhs/medicaid/eligibility/work_requirements/applies.yaml +13 -0
- policyengine_us/parameters/gov/hhs/medicaid/eligibility/work_requirements/dependent_age_limit.yaml +12 -0
- policyengine_us/parameters/gov/hhs/medicaid/eligibility/work_requirements/monthly_hours_threshold.yaml +12 -0
- policyengine_us/parameters/gov/territories/pr/tax/income/taxable_income/deductions/casualty_loss/separate_percentage.yaml +14 -0
- policyengine_us/parameters/gov/territories/pr/tax/income/taxable_income/deductions/charity/floor.yaml +14 -0
- policyengine_us/parameters/gov/territories/pr/tax/income/taxable_income/deductions/education/age_threshold.yaml +12 -0
- policyengine_us/parameters/gov/territories/pr/tax/income/taxable_income/deductions/education/max.yaml +12 -0
- policyengine_us/parameters/gov/territories/pr/tax/income/taxable_income/deductions/medical/floor.yaml +14 -0
- policyengine_us/parameters/gov/territories/pr/tax/income/taxable_income/deductions/mortgage/age_threshold.yaml +12 -0
- policyengine_us/parameters/gov/territories/pr/tax/income/taxable_income/deductions/mortgage/floor.yaml +14 -0
- policyengine_us/parameters/gov/territories/pr/tax/income/taxable_income/deductions/mortgage/max.yaml +14 -0
- policyengine_us/parameters/gov/territories/pr/tax/income/taxable_income/deductions/retirement/age_threshold.yaml +12 -0
- policyengine_us/parameters/gov/territories/pr/tax/income/taxable_income/deductions/retirement/max.yaml +12 -0
- policyengine_us/parameters/gov/territories/pr/tax/income/taxable_income/exemptions/dependent/amount/non_separate.yaml +12 -0
- policyengine_us/parameters/gov/territories/pr/tax/income/taxable_income/exemptions/dependent/amount/separate.yaml +12 -0
- policyengine_us/parameters/gov/usda/snap/work_requirements/abawd/age_threshold/dependent.yaml +4 -2
- policyengine_us/parameters/gov/usda/snap/work_requirements/abawd/age_threshold/exempted.yaml +4 -1
- policyengine_us/parameters/gov/usda/snap/work_requirements/abawd/amended_structure/in_effect.yaml +13 -0
- policyengine_us/parameters/gov/usda/snap/work_requirements/abawd/amended_structure/sunset_provisions_apply.yaml +13 -0
- policyengine_us/parameters/gov/usda/snap/work_requirements/general/age_threshold/caring_dependent_child.yaml +1 -1
- policyengine_us/parameters/gov/usda/snap/work_requirements/general/age_threshold/exempted.yaml +1 -1
- policyengine_us/parameters/gov/usda/snap/work_requirements/general/weekly_hours_threshold.yaml +1 -1
- policyengine_us/reforms/reconciliation/__init__.py +0 -9
- policyengine_us/reforms/reforms.py +0 -18
- policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/medicaid_work_requirement_eligible.yaml +88 -0
- policyengine_us/tests/policy/baseline/gov/territories/pr/tax/income/taxable_income/deductions/education/pr_education_deduction.yaml +17 -0
- policyengine_us/tests/policy/baseline/gov/territories/pr/tax/income/taxable_income/deductions/education/pr_education_deduction_beneficiary_count.yaml +21 -0
- policyengine_us/tests/policy/baseline/gov/territories/pr/tax/income/taxable_income/deductions/pr_casualty_loss_deduction.yaml +17 -0
- policyengine_us/tests/policy/baseline/gov/territories/pr/tax/income/taxable_income/deductions/pr_charitable_deduction.yaml +19 -0
- policyengine_us/tests/policy/baseline/gov/territories/pr/tax/income/taxable_income/deductions/pr_medical_expense_deduction.yaml +38 -0
- policyengine_us/tests/policy/baseline/gov/territories/pr/tax/income/taxable_income/deductions/pr_mortgage_deduction.yaml +87 -0
- policyengine_us/tests/policy/baseline/gov/territories/pr/tax/income/taxable_income/deductions/retirement/pr_retirement_deduction.yaml +39 -0
- policyengine_us/tests/policy/baseline/gov/territories/pr/tax/income/taxable_income/deductions/retirement/pr_retirement_deduction_eligibility.yaml +15 -0
- policyengine_us/tests/policy/baseline/gov/usda/snap/eligibility/work_requirements/meets_snap_abawd_work_requirements.yaml +105 -0
- policyengine_us/variables/gov/hhs/medicaid/eligibility/is_medicaid_eligible.py +9 -0
- policyengine_us/variables/gov/hhs/medicaid/eligibility/medicaid_work_requirement_eligible.py +57 -0
- policyengine_us/variables/gov/territories/pr/tax/income/pr_agi.py +11 -0
- policyengine_us/variables/gov/territories/pr/tax/income/taxable_income/deductions/education/pr_education_deduction.py +20 -0
- policyengine_us/variables/gov/territories/pr/tax/income/taxable_income/deductions/education/pr_education_deduction_beneficiary_count.py +20 -0
- policyengine_us/variables/gov/territories/pr/tax/income/taxable_income/deductions/pr_casualty_loss_deduction.py +27 -0
- policyengine_us/variables/gov/territories/pr/tax/income/taxable_income/deductions/pr_charitable_deduction.py +23 -0
- policyengine_us/variables/gov/territories/pr/tax/income/taxable_income/deductions/pr_medical_expense_deduction.py +19 -0
- policyengine_us/variables/gov/territories/pr/tax/income/taxable_income/deductions/pr_mortgage_deduction.py +42 -0
- policyengine_us/variables/gov/territories/pr/tax/income/taxable_income/deductions/retirement/pr_retirement_deduction.py +25 -0
- policyengine_us/variables/gov/territories/pr/tax/income/taxable_income/deductions/retirement/pr_retirement_deduction_eligibility.py +20 -0
- policyengine_us/variables/gov/usda/snap/eligibility/work_requirements/meets_snap_abawd_work_requirements.py +37 -7
- {policyengine_us-1.354.0.dist-info → policyengine_us-1.356.0.dist-info}/METADATA +1 -1
- {policyengine_us-1.354.0.dist-info → policyengine_us-1.356.0.dist-info}/RECORD +53 -21
- policyengine_us/parameters/gov/contrib/reconciliation/aca_ptc_immigration_status/in_effect.yaml +0 -13
- policyengine_us/reforms/reconciliation/aca_ptc_immigration_status.py +0 -55
- policyengine_us/reforms/reconciliation/reconciled_medicaid_work_requirement.py +0 -157
- policyengine_us/reforms/reconciliation/reconciled_snap_abawd_work_requirement.py +0 -125
- policyengine_us/tests/policy/contrib/reconciliation/reconciled_snap_abawd_work_requirement.yaml +0 -118
- {policyengine_us-1.354.0.dist-info → policyengine_us-1.356.0.dist-info}/WHEEL +0 -0
- {policyengine_us-1.354.0.dist-info → policyengine_us-1.356.0.dist-info}/entry_points.txt +0 -0
- {policyengine_us-1.354.0.dist-info → policyengine_us-1.356.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
- name: Taxpayer over 65 years old over maximum deduction amount
|
|
2
|
+
period: 2024
|
|
3
|
+
input:
|
|
4
|
+
people:
|
|
5
|
+
person1:
|
|
6
|
+
age: 65
|
|
7
|
+
is_tax_unit_head_or_spouse: true
|
|
8
|
+
deductible_mortgage_interest: 20_000
|
|
9
|
+
person2:
|
|
10
|
+
age: 40
|
|
11
|
+
is_tax_unit_head_or_spouse: true
|
|
12
|
+
deductible_mortgage_interest: 20_000
|
|
13
|
+
tax_units:
|
|
14
|
+
tax_unit:
|
|
15
|
+
members: [person1, person2]
|
|
16
|
+
pr_agi: 10_000
|
|
17
|
+
households:
|
|
18
|
+
household:
|
|
19
|
+
state_code: PR
|
|
20
|
+
output:
|
|
21
|
+
pr_mortgage_deduction: 35_000
|
|
22
|
+
|
|
23
|
+
- name: Spouse over 65 years old under maximum deduction amount
|
|
24
|
+
period: 2024
|
|
25
|
+
input:
|
|
26
|
+
people:
|
|
27
|
+
person1:
|
|
28
|
+
age: 40
|
|
29
|
+
is_tax_unit_head_or_spouse: true
|
|
30
|
+
deductible_mortgage_interest: 30_000
|
|
31
|
+
person2:
|
|
32
|
+
age: 65
|
|
33
|
+
is_tax_unit_head_or_spouse: true
|
|
34
|
+
deductible_mortgage_interest: 4_000
|
|
35
|
+
tax_units:
|
|
36
|
+
tax_unit:
|
|
37
|
+
members: [person1, person2]
|
|
38
|
+
pr_agi: 10_000
|
|
39
|
+
households:
|
|
40
|
+
household:
|
|
41
|
+
state_code: PR
|
|
42
|
+
output:
|
|
43
|
+
pr_mortgage_deduction: 34_000
|
|
44
|
+
|
|
45
|
+
- name: Taxpayer under 65 years old limited by AGI
|
|
46
|
+
period: 2024
|
|
47
|
+
input:
|
|
48
|
+
people:
|
|
49
|
+
person1:
|
|
50
|
+
age: 40
|
|
51
|
+
is_tax_unit_head_or_spouse: true
|
|
52
|
+
deductible_mortgage_interest: 20_000
|
|
53
|
+
person2:
|
|
54
|
+
age: 64
|
|
55
|
+
is_tax_unit_head_or_spouse: true
|
|
56
|
+
deductible_mortgage_interest: 10_000
|
|
57
|
+
tax_units:
|
|
58
|
+
tax_unit:
|
|
59
|
+
members: [person1, person2]
|
|
60
|
+
pr_agi: 10_000
|
|
61
|
+
households:
|
|
62
|
+
household:
|
|
63
|
+
state_code: PR
|
|
64
|
+
output:
|
|
65
|
+
pr_mortgage_deduction: 3_000
|
|
66
|
+
|
|
67
|
+
- name: Base test
|
|
68
|
+
period: 2024
|
|
69
|
+
input:
|
|
70
|
+
people:
|
|
71
|
+
person1:
|
|
72
|
+
age: 64
|
|
73
|
+
is_tax_unit_head_or_spouse: true
|
|
74
|
+
deductible_mortgage_interest: 3_000
|
|
75
|
+
person2:
|
|
76
|
+
age: 64
|
|
77
|
+
is_tax_unit_head_or_spouse: true
|
|
78
|
+
deductible_mortgage_interest: 3_001
|
|
79
|
+
tax_units:
|
|
80
|
+
tax_unit:
|
|
81
|
+
members: [person1, person2]
|
|
82
|
+
pr_agi: 20_000
|
|
83
|
+
households:
|
|
84
|
+
household:
|
|
85
|
+
state_code: PR
|
|
86
|
+
output:
|
|
87
|
+
pr_mortgage_deduction: 6_000
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
- name: Contributions are higher than maximum deduction
|
|
2
|
+
period: 2024
|
|
3
|
+
input:
|
|
4
|
+
pr_agi_person: 10_000
|
|
5
|
+
traditional_ira_contributions: 3_001
|
|
6
|
+
roth_ira_contributions: 2_000
|
|
7
|
+
state_code: PR
|
|
8
|
+
output:
|
|
9
|
+
pr_retirement_deduction: 5_000
|
|
10
|
+
|
|
11
|
+
- name: Contributions are lower than maximum deduction
|
|
12
|
+
period: 2024
|
|
13
|
+
input:
|
|
14
|
+
pr_agi_person: 1_300
|
|
15
|
+
traditional_ira_contributions: 500
|
|
16
|
+
roth_ira_contributions: 300
|
|
17
|
+
state_code: PR
|
|
18
|
+
output:
|
|
19
|
+
pr_retirement_deduction: 800
|
|
20
|
+
|
|
21
|
+
- name: Contributions are lower than AGI
|
|
22
|
+
period: 2024
|
|
23
|
+
input:
|
|
24
|
+
pr_agi_person: 4_000
|
|
25
|
+
traditional_ira_contributions: 500
|
|
26
|
+
roth_ira_contributions: 301
|
|
27
|
+
state_code: PR
|
|
28
|
+
output:
|
|
29
|
+
pr_retirement_deduction: 801
|
|
30
|
+
|
|
31
|
+
- name: Contributions are higher than AGI
|
|
32
|
+
period: 2024
|
|
33
|
+
input:
|
|
34
|
+
pr_agi_person: 4_000
|
|
35
|
+
traditional_ira_contributions: 5000
|
|
36
|
+
roth_ira_contributions: 3000
|
|
37
|
+
state_code: PR
|
|
38
|
+
output:
|
|
39
|
+
pr_retirement_deduction: 4_000
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
- name: Not eligible
|
|
2
|
+
period: 2024
|
|
3
|
+
input:
|
|
4
|
+
age: 75
|
|
5
|
+
state_code: PR
|
|
6
|
+
output:
|
|
7
|
+
pr_retirement_deduction_eligibility: False
|
|
8
|
+
|
|
9
|
+
- name: Eligible
|
|
10
|
+
period: 2024
|
|
11
|
+
input:
|
|
12
|
+
age: 74
|
|
13
|
+
state_code: PR
|
|
14
|
+
output:
|
|
15
|
+
pr_retirement_deduction_eligibility: True
|
|
@@ -84,3 +84,108 @@
|
|
|
84
84
|
members: [person1, person2]
|
|
85
85
|
output:
|
|
86
86
|
meets_snap_abawd_work_requirements: [false, true]
|
|
87
|
+
|
|
88
|
+
- name: Case 1, baseline, age 55 exempted from general work requirement.
|
|
89
|
+
period: 2026
|
|
90
|
+
absolute_error_margin: 0.9
|
|
91
|
+
input:
|
|
92
|
+
age: 55
|
|
93
|
+
weekly_hours_worked: 1
|
|
94
|
+
is_disabled: false
|
|
95
|
+
output:
|
|
96
|
+
meets_snap_abawd_work_requirements: true
|
|
97
|
+
|
|
98
|
+
- name: Case 2, reform, age 55 is not exempted from general work requirement.
|
|
99
|
+
period: 2027
|
|
100
|
+
absolute_error_margin: 0.9
|
|
101
|
+
input:
|
|
102
|
+
age: 55
|
|
103
|
+
weekly_hours_worked: 1
|
|
104
|
+
is_disabled: false
|
|
105
|
+
output:
|
|
106
|
+
meets_snap_abawd_work_requirements: false
|
|
107
|
+
|
|
108
|
+
- name: Case 3, baseline, have a child at age 15.
|
|
109
|
+
period: 2026-01
|
|
110
|
+
absolute_error_margin: 0.9
|
|
111
|
+
input:
|
|
112
|
+
people:
|
|
113
|
+
person1:
|
|
114
|
+
age: 55
|
|
115
|
+
weekly_hours_worked: 1
|
|
116
|
+
is_disabled: false
|
|
117
|
+
is_parent: true
|
|
118
|
+
person2:
|
|
119
|
+
age: 15
|
|
120
|
+
is_disabled: false
|
|
121
|
+
is_tax_unit_dependent: true
|
|
122
|
+
output:
|
|
123
|
+
meets_snap_abawd_work_requirements: [true, true]
|
|
124
|
+
|
|
125
|
+
- name: Case 4, reform, have a child at age 15.
|
|
126
|
+
period: 2027
|
|
127
|
+
absolute_error_margin: 0.9
|
|
128
|
+
input:
|
|
129
|
+
people:
|
|
130
|
+
person1:
|
|
131
|
+
age: 55
|
|
132
|
+
weekly_hours_worked: 1
|
|
133
|
+
is_disabled: false
|
|
134
|
+
is_parent: true
|
|
135
|
+
person2:
|
|
136
|
+
age: 15
|
|
137
|
+
is_disabled: false
|
|
138
|
+
is_tax_unit_dependent: true
|
|
139
|
+
output:
|
|
140
|
+
meets_snap_abawd_work_requirements: [false, true]
|
|
141
|
+
|
|
142
|
+
- name: Case 5, reform, have a child at age 6.
|
|
143
|
+
period: 2027
|
|
144
|
+
absolute_error_margin: 0.9
|
|
145
|
+
input:
|
|
146
|
+
people:
|
|
147
|
+
person1:
|
|
148
|
+
age: 55
|
|
149
|
+
weekly_hours_worked: 1
|
|
150
|
+
is_disabled: false
|
|
151
|
+
is_parent: true
|
|
152
|
+
person2:
|
|
153
|
+
age: 6
|
|
154
|
+
is_disabled: false
|
|
155
|
+
is_tax_unit_dependent: true
|
|
156
|
+
output:
|
|
157
|
+
meets_snap_abawd_work_requirements: [true, true]
|
|
158
|
+
|
|
159
|
+
- name: Case 6, reform, is veteran with a child 15 in 2027.
|
|
160
|
+
period: 2027
|
|
161
|
+
absolute_error_margin: 0.9
|
|
162
|
+
input:
|
|
163
|
+
people:
|
|
164
|
+
person1:
|
|
165
|
+
age: 55
|
|
166
|
+
weekly_hours_worked: 1
|
|
167
|
+
is_disabled: false
|
|
168
|
+
is_veteran: true
|
|
169
|
+
person2:
|
|
170
|
+
age: 15
|
|
171
|
+
is_disabled: false
|
|
172
|
+
is_tax_unit_dependent: true
|
|
173
|
+
output:
|
|
174
|
+
meets_snap_abawd_work_requirements: [true, true]
|
|
175
|
+
|
|
176
|
+
- name: Case 7, reform, is veteran with a child 15 in 2031, sunset provision in effect.
|
|
177
|
+
period: 2031
|
|
178
|
+
absolute_error_margin: 0.9
|
|
179
|
+
input:
|
|
180
|
+
people:
|
|
181
|
+
person1:
|
|
182
|
+
age: 55
|
|
183
|
+
weekly_hours_worked: 1
|
|
184
|
+
is_disabled: false
|
|
185
|
+
is_veteran: true
|
|
186
|
+
person2:
|
|
187
|
+
age: 15
|
|
188
|
+
is_disabled: false
|
|
189
|
+
is_tax_unit_dependent: true
|
|
190
|
+
output:
|
|
191
|
+
meets_snap_abawd_work_requirements: [false, true]
|
|
@@ -25,6 +25,15 @@ class is_medicaid_eligible(Variable):
|
|
|
25
25
|
~undocumented | undocumented & state_covers_undocumented
|
|
26
26
|
)
|
|
27
27
|
ca_ffyp_eligible = person("ca_ffyp_eligible", period)
|
|
28
|
+
if p.work_requirements.applies:
|
|
29
|
+
work_requirement_eligible = person(
|
|
30
|
+
"medicaid_work_requirement_eligible", period
|
|
31
|
+
)
|
|
32
|
+
return (
|
|
33
|
+
categorically_eligible
|
|
34
|
+
& immigration_status_eligible
|
|
35
|
+
& work_requirement_eligible
|
|
36
|
+
) | ca_ffyp_eligible
|
|
28
37
|
return (
|
|
29
38
|
categorically_eligible & immigration_status_eligible
|
|
30
39
|
) | ca_ffyp_eligible
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
from policyengine_us.model_api import *
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class medicaid_work_requirement_eligible(Variable):
|
|
5
|
+
value_type = bool
|
|
6
|
+
entity = Person
|
|
7
|
+
label = "Eligible person for Medicaid via work requirement"
|
|
8
|
+
definition_period = YEAR
|
|
9
|
+
reference = (
|
|
10
|
+
"https://www.congress.gov/bill/119th-congress/house-bill/1/text"
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
def formula(person, period, parameters):
|
|
14
|
+
p = parameters(period).gov.hhs.medicaid.eligibility.work_requirements
|
|
15
|
+
# Works no less than 80 hours p.680 (2)(A)
|
|
16
|
+
monthly_hours_worked = person("monthly_hours_worked", period)
|
|
17
|
+
meets_monthly_work_hours = (
|
|
18
|
+
monthly_hours_worked >= p.monthly_hours_threshold
|
|
19
|
+
)
|
|
20
|
+
# The individual is enrolled in an educational program at least half-time. p.680 (2)(D)
|
|
21
|
+
is_full_time_student = person("is_full_time_student", period)
|
|
22
|
+
# pregnant or postpartum medical assistance p.681 (3)(A)(i)(II)(bb)
|
|
23
|
+
is_pregnant = person("is_pregnant", period)
|
|
24
|
+
# Has attained age of 19 and is under 65 is require to work p.693 (bb)
|
|
25
|
+
age = person("age", period)
|
|
26
|
+
work_required_age = p.age_range.calc(age)
|
|
27
|
+
# parent, guardian, caretaker of a disabled person
|
|
28
|
+
is_dependent = person("is_tax_unit_dependent", period)
|
|
29
|
+
is_disabled = person("is_disabled", period)
|
|
30
|
+
has_disabled = person.tax_unit.any(is_dependent & is_disabled)
|
|
31
|
+
# veteran and is_permanently_and_totally_disabled p.694 (IV)
|
|
32
|
+
is_veteran = person("is_veteran", period)
|
|
33
|
+
is_permanently_and_totally_disabled = person(
|
|
34
|
+
"is_permanently_and_totally_disabled", period
|
|
35
|
+
)
|
|
36
|
+
eligible_veteran = is_veteran & is_permanently_and_totally_disabled
|
|
37
|
+
# blind or disabled or is_incapable_of_self_care p.694 (V)
|
|
38
|
+
is_blind = person("is_blind", period)
|
|
39
|
+
is_incapable_of_self_care = person("is_incapable_of_self_care", period)
|
|
40
|
+
eligible_disabled = is_blind | is_disabled | is_incapable_of_self_care
|
|
41
|
+
# parent, guardian, caretaker of a dependent child 13 years of age or under p.694 (III)
|
|
42
|
+
child_age_eligible = age <= p.dependent_age_limit
|
|
43
|
+
has_eligible_dependent_child = person.tax_unit.any(
|
|
44
|
+
is_dependent & child_age_eligible
|
|
45
|
+
)
|
|
46
|
+
exempted_from_work = (
|
|
47
|
+
is_full_time_student
|
|
48
|
+
| is_pregnant
|
|
49
|
+
| has_disabled
|
|
50
|
+
| eligible_veteran
|
|
51
|
+
| eligible_disabled
|
|
52
|
+
)
|
|
53
|
+
meets_base_requirement = meets_monthly_work_hours | exempted_from_work
|
|
54
|
+
meets_conditions = (
|
|
55
|
+
meets_base_requirement | has_eligible_dependent_child
|
|
56
|
+
)
|
|
57
|
+
return where(work_required_age, meets_conditions, True)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from policyengine_us.model_api import *
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class pr_agi(Variable):
|
|
5
|
+
value_type = float
|
|
6
|
+
entity = TaxUnit
|
|
7
|
+
label = "Puerto Rico adjusted gross income"
|
|
8
|
+
unit = USD
|
|
9
|
+
definition_period = YEAR
|
|
10
|
+
defined_for = StateCode.PR
|
|
11
|
+
reference = "https://law.justia.com/codes/puerto-rico/title-thirteen/subtitle-17/part-ii/chapter-1005/subchapter-a/30103/"
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from policyengine_us.model_api import *
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class pr_education_deduction(Variable):
|
|
5
|
+
value_type = float
|
|
6
|
+
entity = TaxUnit
|
|
7
|
+
label = "Puerto Rico education contribution deduction"
|
|
8
|
+
unit = USD
|
|
9
|
+
definition_period = YEAR
|
|
10
|
+
reference = "https://law.justia.com/codes/puerto-rico/title-thirteen/subtitle-17/part-ii/chapter-1005/subchapter-c/30135/" # (8)
|
|
11
|
+
defined_for = StateCode.PR
|
|
12
|
+
|
|
13
|
+
def formula(tax_unit, period, parameters):
|
|
14
|
+
p = parameters(
|
|
15
|
+
period
|
|
16
|
+
).gov.territories.pr.tax.income.taxable_income.deductions.education
|
|
17
|
+
contributions = add(tax_unit, period, ["investment_in_529_plan"])
|
|
18
|
+
count = tax_unit("pr_education_deduction_beneficiary_count", period)
|
|
19
|
+
maximum_contribution = p.max * count
|
|
20
|
+
return min_(maximum_contribution, contributions)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from policyengine_us.model_api import *
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class pr_education_deduction_beneficiary_count(Variable):
|
|
5
|
+
value_type = float
|
|
6
|
+
entity = TaxUnit
|
|
7
|
+
label = "Puerto Rico education contribution deduction beneficiary count"
|
|
8
|
+
unit = USD
|
|
9
|
+
definition_period = YEAR
|
|
10
|
+
reference = "https://law.justia.com/codes/puerto-rico/title-thirteen/subtitle-17/part-ii/chapter-1005/subchapter-c/30135/" # (8)
|
|
11
|
+
defined_for = StateCode.PR
|
|
12
|
+
|
|
13
|
+
def formula(tax_unit, period, parameters):
|
|
14
|
+
p = parameters(
|
|
15
|
+
period
|
|
16
|
+
).gov.territories.pr.tax.income.taxable_income.deductions.education
|
|
17
|
+
person = tax_unit.members
|
|
18
|
+
is_dependent = person("is_tax_unit_dependent", period)
|
|
19
|
+
age_eligible = person("age", period) < p.age_threshold
|
|
20
|
+
return tax_unit.sum(is_dependent & age_eligible)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from policyengine_us.model_api import *
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class pr_casualty_loss_deduction(Variable):
|
|
5
|
+
value_type = float
|
|
6
|
+
entity = TaxUnit
|
|
7
|
+
label = "Puerto Rico casualty loss deduction"
|
|
8
|
+
unit = USD
|
|
9
|
+
definition_period = YEAR
|
|
10
|
+
reference = "https://law.justia.com/codes/puerto-rico/title-thirteen/subtitle-17/part-ii/chapter-1005/subchapter-c/30135/" # (10)
|
|
11
|
+
defined_for = StateCode.PR
|
|
12
|
+
|
|
13
|
+
def formula(tax_unit, period, parameters):
|
|
14
|
+
p = parameters(
|
|
15
|
+
period
|
|
16
|
+
).gov.territories.pr.tax.income.taxable_income.deductions.casualty_loss
|
|
17
|
+
loss = add(tax_unit, period, ["casualty_loss"])
|
|
18
|
+
filing_status = tax_unit("filing_status", period)
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
where(
|
|
22
|
+
filing_status == filing_status.possible_values.SEPARATE,
|
|
23
|
+
p.separate_percentage,
|
|
24
|
+
1,
|
|
25
|
+
)
|
|
26
|
+
* loss
|
|
27
|
+
)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from policyengine_us.model_api import *
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class pr_charitable_deduction(Variable):
|
|
5
|
+
value_type = float
|
|
6
|
+
entity = TaxUnit
|
|
7
|
+
label = "Puerto Rico charitable deduction"
|
|
8
|
+
unit = USD
|
|
9
|
+
definition_period = YEAR
|
|
10
|
+
reference = "https://law.justia.com/codes/puerto-rico/title-thirteen/subtitle-17/part-ii/chapter-1005/subchapter-c/30135/" # (3)(B)(i)(IV)
|
|
11
|
+
defined_for = StateCode.PR
|
|
12
|
+
|
|
13
|
+
def formula(tax_unit, period, parameters):
|
|
14
|
+
p = parameters(
|
|
15
|
+
period
|
|
16
|
+
).gov.territories.pr.tax.income.taxable_income.deductions.charity
|
|
17
|
+
charitable_contributions = add(
|
|
18
|
+
tax_unit,
|
|
19
|
+
period,
|
|
20
|
+
["charitable_cash_donations", "charitable_non_cash_donations"],
|
|
21
|
+
)
|
|
22
|
+
charity_floor = p.floor * tax_unit("pr_agi", period)
|
|
23
|
+
return min_(charitable_contributions, charity_floor)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from policyengine_us.model_api import *
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class pr_medical_expense_deduction(Variable):
|
|
5
|
+
value_type = float
|
|
6
|
+
entity = TaxUnit
|
|
7
|
+
label = "Puerto Rico medical expense deduction"
|
|
8
|
+
unit = USD
|
|
9
|
+
definition_period = YEAR
|
|
10
|
+
reference = "https://law.justia.com/codes/puerto-rico/title-thirteen/subtitle-17/part-ii/chapter-1005/subchapter-c/30135/" # (4)
|
|
11
|
+
defined_for = StateCode.PR
|
|
12
|
+
|
|
13
|
+
def formula(tax_unit, period, parameters):
|
|
14
|
+
expense = add(tax_unit, period, ["medical_out_of_pocket_expenses"])
|
|
15
|
+
p = parameters(
|
|
16
|
+
period
|
|
17
|
+
).gov.territories.pr.tax.income.taxable_income.deductions.medical
|
|
18
|
+
medical_floor = p.floor * tax_unit("pr_agi", period)
|
|
19
|
+
return max_(0, expense - medical_floor)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
from policyengine_us.model_api import *
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class pr_mortgage_deduction(Variable):
|
|
5
|
+
value_type = float
|
|
6
|
+
entity = TaxUnit
|
|
7
|
+
label = "Puerto Rico home mortgage deduction"
|
|
8
|
+
unit = USD
|
|
9
|
+
definition_period = YEAR
|
|
10
|
+
reference = "https://law.justia.com/codes/puerto-rico/title-thirteen/subtitle-17/part-ii/chapter-1005/subchapter-c/30135/" # (1)(C)
|
|
11
|
+
defined_for = StateCode.PR
|
|
12
|
+
|
|
13
|
+
def formula(tax_unit, period, parameters):
|
|
14
|
+
p = parameters(
|
|
15
|
+
period
|
|
16
|
+
).gov.territories.pr.tax.income.taxable_income.deductions.mortgage
|
|
17
|
+
|
|
18
|
+
agi = tax_unit("pr_agi", period)
|
|
19
|
+
limit = agi * p.floor # plus any income excluded from AGI
|
|
20
|
+
|
|
21
|
+
mortgage_interest = add(
|
|
22
|
+
tax_unit, period, ["deductible_mortgage_interest"]
|
|
23
|
+
)
|
|
24
|
+
person = tax_unit.members
|
|
25
|
+
age = person("age", period)
|
|
26
|
+
|
|
27
|
+
is_senior_exception = tax_unit.any(
|
|
28
|
+
person("is_tax_unit_head_or_spouse", period)
|
|
29
|
+
& (age >= p.age_threshold)
|
|
30
|
+
)
|
|
31
|
+
# True if any member fulfills condition
|
|
32
|
+
|
|
33
|
+
# people 65+ years old are capped at max deduction amount
|
|
34
|
+
interest_capped_by_max = min_(mortgage_interest, p.max)
|
|
35
|
+
# otherwise capped by both AGI and max deduction amount
|
|
36
|
+
combined_cap = min_(limit, p.max)
|
|
37
|
+
interest_capped_by_combined = min_(mortgage_interest, combined_cap)
|
|
38
|
+
return where(
|
|
39
|
+
is_senior_exception,
|
|
40
|
+
interest_capped_by_max,
|
|
41
|
+
interest_capped_by_combined,
|
|
42
|
+
)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from policyengine_us.model_api import *
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class pr_retirement_deduction(Variable):
|
|
5
|
+
value_type = float
|
|
6
|
+
entity = Person
|
|
7
|
+
label = "Puerto Rico retirement contribution deduction"
|
|
8
|
+
unit = USD
|
|
9
|
+
definition_period = YEAR
|
|
10
|
+
reference = "https://law.justia.com/codes/puerto-rico/title-thirteen/subtitle-17/part-ii/chapter-1005/subchapter-c/30135/" # (7)
|
|
11
|
+
defined_for = "pr_retirement_deduction_eligibility"
|
|
12
|
+
|
|
13
|
+
def formula(person, period, parameters):
|
|
14
|
+
p = parameters(
|
|
15
|
+
period
|
|
16
|
+
).gov.territories.pr.tax.income.taxable_income.deductions.retirement
|
|
17
|
+
|
|
18
|
+
agi = person("pr_agi_person", period)
|
|
19
|
+
max_deduction = min_(p.max, agi)
|
|
20
|
+
contributions = add(
|
|
21
|
+
person,
|
|
22
|
+
period,
|
|
23
|
+
["traditional_ira_contributions", "roth_ira_contributions"],
|
|
24
|
+
)
|
|
25
|
+
return min_(max_deduction, contributions)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from policyengine_us.model_api import *
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class pr_retirement_deduction_eligibility(Variable):
|
|
5
|
+
value_type = float
|
|
6
|
+
entity = Person
|
|
7
|
+
label = "Puerto Rico retirement contribution deduction eligibility"
|
|
8
|
+
unit = USD
|
|
9
|
+
definition_period = YEAR
|
|
10
|
+
reference = "https://law.justia.com/codes/puerto-rico/title-thirteen/subtitle-17/part-ii/chapter-1005/subchapter-c/30135/" # (7)(D)
|
|
11
|
+
defined_for = StateCode.PR
|
|
12
|
+
|
|
13
|
+
def formula(person, period, parameters):
|
|
14
|
+
p = parameters(
|
|
15
|
+
period
|
|
16
|
+
).gov.territories.pr.tax.income.taxable_income.deductions.retirement
|
|
17
|
+
|
|
18
|
+
# additionally no deduction if income is only from pension and annuities
|
|
19
|
+
age = person("age", period)
|
|
20
|
+
return age < p.age_threshold
|
|
@@ -14,16 +14,16 @@ class meets_snap_abawd_work_requirements(Variable):
|
|
|
14
14
|
weekly_hours_worked = person("weekly_hours_worked", period.this_year)
|
|
15
15
|
# Work at least 20 hours a week
|
|
16
16
|
is_working = weekly_hours_worked >= p.weekly_hours_threshold
|
|
17
|
-
#
|
|
18
|
-
|
|
17
|
+
# Adults within an age range are exempt
|
|
18
|
+
working_age_exempt = p.age_threshold.exempted.calc(age)
|
|
19
19
|
# Unable to work due to a physical or mental limitation
|
|
20
20
|
is_disabled = person("is_disabled", period)
|
|
21
21
|
# Parent of a household member under 18
|
|
22
22
|
is_dependent = person("is_tax_unit_dependent", period)
|
|
23
|
-
|
|
23
|
+
is_qualifying_child = age < p.age_threshold.dependent
|
|
24
24
|
is_parent = person("is_parent", period)
|
|
25
|
-
has_child = person.spm_unit.any(is_dependent &
|
|
26
|
-
|
|
25
|
+
has_child = person.spm_unit.any(is_dependent & is_qualifying_child)
|
|
26
|
+
exempt_parent = is_parent & has_child
|
|
27
27
|
# Exempted from the general work requirements
|
|
28
28
|
meets_snap_general_work_requirements = person(
|
|
29
29
|
"meets_snap_general_work_requirements", period
|
|
@@ -34,11 +34,41 @@ class meets_snap_abawd_work_requirements(Variable):
|
|
|
34
34
|
is_homeless = person.household("is_homeless", period)
|
|
35
35
|
# A veteran
|
|
36
36
|
is_veteran = person("is_veteran", period)
|
|
37
|
+
if p.amended_structure.in_effect:
|
|
38
|
+
is_child = person("is_child", period)
|
|
39
|
+
older_child_dependent = (
|
|
40
|
+
is_dependent & is_child & ~is_qualifying_child
|
|
41
|
+
)
|
|
42
|
+
is_married = person.family("is_married", period)
|
|
43
|
+
has_older_child_dependent = person.spm_unit.any(
|
|
44
|
+
older_child_dependent
|
|
45
|
+
)
|
|
46
|
+
is_head_or_spouse = person("is_tax_unit_head_or_spouse", period)
|
|
47
|
+
has_head_or_spouse_working = person.spm_unit.any(
|
|
48
|
+
is_head_or_spouse & is_working
|
|
49
|
+
)
|
|
50
|
+
exempt_married_person = where(
|
|
51
|
+
is_married & has_older_child_dependent,
|
|
52
|
+
has_head_or_spouse_working,
|
|
53
|
+
0,
|
|
54
|
+
)
|
|
55
|
+
base_conditions = (
|
|
56
|
+
is_working
|
|
57
|
+
| working_age_exempt
|
|
58
|
+
| is_disabled
|
|
59
|
+
| exempt_parent
|
|
60
|
+
| meets_snap_general_work_requirements
|
|
61
|
+
| is_pregnant
|
|
62
|
+
| exempt_married_person
|
|
63
|
+
)
|
|
64
|
+
if p.amended_structure.sunset_provisions_apply:
|
|
65
|
+
return base_conditions
|
|
66
|
+
return base_conditions | is_homeless | is_veteran
|
|
37
67
|
return (
|
|
38
68
|
is_working
|
|
39
|
-
|
|
|
69
|
+
| working_age_exempt
|
|
40
70
|
| is_disabled
|
|
41
|
-
|
|
|
71
|
+
| exempt_parent
|
|
42
72
|
| meets_snap_general_work_requirements
|
|
43
73
|
| is_pregnant
|
|
44
74
|
| is_homeless
|