-
Notifications
You must be signed in to change notification settings - Fork 201
Utah Refundable EITC reform #6823
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
PavelMakarchuk
merged 6 commits into
PolicyEngine:master
from
DTrim99:DTrim99/issue6822
Nov 25, 2025
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
acbb404
Utah Refundable EITC reform
DTrim99 93ddacc
Update policyengine_us/reforms/states/ut/ut_refundable_eitc.py
DTrim99 fdc1ce6
split variables
DTrim99 2d126c8
use adds and subtracts
DTrim99 53052bb
Update policyengine_us/reforms/states/ut/ut_refundable_eitc.py
DTrim99 68fb63e
syntax
DTrim99 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| - bump: minor | ||
| changes: | ||
| added: | ||
| - Utah refundable EITC contributed reform. |
9 changes: 9 additions & 0 deletions
9
policyengine_us/parameters/gov/contrib/states/ut/eitc/in_effect.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| description: The Utah EITC is refundable for households with children below a certain age when this parameter is in effect. | ||
|
|
||
| values: | ||
| 0000-01-01: false | ||
|
|
||
| metadata: | ||
| unit: bool | ||
| period: year | ||
| label: Utah refundable EITC in effect |
9 changes: 9 additions & 0 deletions
9
policyengine_us/parameters/gov/contrib/states/ut/eitc/max_age.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| description: The maximum age for a child to qualify the household for the refundable Utah EITC. | ||
|
|
||
| values: | ||
| 0000-01-01: 2 | ||
|
|
||
| metadata: | ||
| unit: year | ||
| period: year | ||
| label: Utah refundable EITC maximum child age |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| from .ut_refundable_eitc import ( | ||
| create_ut_refundable_eitc_reform, | ||
| ) |
118 changes: 118 additions & 0 deletions
118
policyengine_us/reforms/states/ut/ut_refundable_eitc.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,118 @@ | ||
| from policyengine_us.model_api import * | ||
| from policyengine_core.periods import period as period_ | ||
|
|
||
|
|
||
| def create_ut_refundable_eitc() -> Reform: | ||
| class ut_has_qualifying_child_for_refundable_eitc(Variable): | ||
| value_type = bool | ||
| entity = TaxUnit | ||
| label = "Utah tax unit has qualifying child for refundable EITC" | ||
| defined_for = StateCode.UT | ||
| definition_period = YEAR | ||
|
|
||
| def formula(tax_unit, period, parameters): | ||
| person = tax_unit.members | ||
| p = parameters(period).gov.contrib.states.ut.eitc | ||
| age = person("age", period) | ||
| is_dependent = person("is_tax_unit_dependent", period) | ||
| is_qualifying_child = (age <= p.max_age) & is_dependent | ||
| return tax_unit.any(is_qualifying_child) | ||
|
|
||
| class ut_refundable_eitc(Variable): | ||
| value_type = float | ||
| entity = TaxUnit | ||
| label = "Utah refundable EITC" | ||
| unit = USD | ||
| definition_period = YEAR | ||
| defined_for = "ut_has_qualifying_child_for_refundable_eitc" | ||
|
|
||
| adds = ["ut_eitc"] | ||
|
|
||
| class ut_eitc(Variable): | ||
| value_type = float | ||
| entity = TaxUnit | ||
| label = "Utah Earned Income Tax Credit" | ||
| unit = USD | ||
| documentation = "This credit is a fraction of the federal EITC." | ||
| definition_period = YEAR | ||
| defined_for = StateCode.UT | ||
| reference = "https://le.utah.gov/xcode/Title59/Chapter10/59-10-S1044.html?v=C59-10-S1044_2022050420220504" | ||
|
|
||
| def formula(tax_unit, period, parameters): | ||
| p = parameters( | ||
| period | ||
| ).gov.states.ut.tax.income.credits.earned_income | ||
| federal_eitc = tax_unit("eitc", period) | ||
| return p.rate * federal_eitc | ||
|
|
||
| class ut_non_refundable_eitc(Variable): | ||
| value_type = float | ||
| entity = TaxUnit | ||
| label = "Utah non-refundable EITC" | ||
| unit = USD | ||
| definition_period = YEAR | ||
| defined_for = StateCode.UT | ||
|
|
||
| adds = ["ut_eitc"] | ||
| subtracts = ["ut_refundable_eitc"] | ||
DTrim99 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| class ut_non_refundable_credits(Variable): | ||
| value_type = float | ||
| entity = TaxUnit | ||
| label = "Utah non-refundable tax credits" | ||
| unit = USD | ||
| definition_period = YEAR | ||
| defined_for = StateCode.UT | ||
|
|
||
| adds = [ | ||
| "ut_non_refundable_eitc", | ||
| "ut_retirement_credit", | ||
| "ut_ss_benefits_credit", | ||
| "ut_at_home_parent_credit", | ||
| "ut_ctc", | ||
| ] | ||
|
|
||
| class ut_refundable_credits(Variable): | ||
| value_type = float | ||
| entity = TaxUnit | ||
| label = "Utah refundable credits" | ||
| unit = USD | ||
| definition_period = YEAR | ||
| defined_for = StateCode.UT | ||
|
|
||
| adds = ["ut_refundable_eitc"] | ||
|
|
||
| class reform(Reform): | ||
| def apply(self): | ||
| self.add_variable(ut_has_qualifying_child_for_refundable_eitc) | ||
| self.add_variable(ut_refundable_eitc) | ||
| self.add_variable(ut_non_refundable_eitc) | ||
| self.update_variable(ut_eitc) | ||
| self.update_variable(ut_non_refundable_credits) | ||
| self.update_variable(ut_refundable_credits) | ||
|
|
||
| return reform | ||
|
|
||
|
|
||
| def create_ut_refundable_eitc_reform(parameters, period, bypass: bool = False): | ||
| if bypass: | ||
| return create_ut_refundable_eitc() | ||
|
|
||
| p = parameters.gov.contrib.states.ut.eitc | ||
|
|
||
| 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_ut_refundable_eitc() | ||
| else: | ||
| return None | ||
|
|
||
|
|
||
| ut_refundable_eitc = create_ut_refundable_eitc_reform(None, None, bypass=True) | ||
214 changes: 214 additions & 0 deletions
214
policyengine_us/tests/policy/contrib/states/ut/ut_refundable_eitc.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,214 @@ | ||
| - name: Single parent with child under max age - full EITC refundable | ||
| period: 2024 | ||
| reforms: policyengine_us.reforms.states.ut.ut_refundable_eitc.ut_refundable_eitc | ||
| input: | ||
| gov.contrib.states.ut.eitc.in_effect: true | ||
| people: | ||
| parent: | ||
| age: 30 | ||
| child: | ||
| age: 2 | ||
| is_tax_unit_dependent: true | ||
| tax_units: | ||
| tax_unit: | ||
| members: [parent, child] | ||
| eitc: 5_000 | ||
| households: | ||
| household: | ||
| members: [parent, child] | ||
| state_code: UT | ||
| output: | ||
| # Utah EITC = 20% of federal EITC = 0.2 * 5_000 = 1_000 | ||
| # Since child is age 2 (at max_age threshold), full amount is refundable | ||
| ut_eitc: 1_000 # Total EITC | ||
| ut_refundable_eitc: 1_000 | ||
| ut_non_refundable_eitc: 0 # Non-refundable portion is reduced to zero | ||
| ut_has_qualifying_child_for_refundable_eitc: true | ||
|
|
||
| - name: Single parent with child at age 1 | ||
| period: 2024 | ||
| reforms: policyengine_us.reforms.states.ut.ut_refundable_eitc.ut_refundable_eitc | ||
| input: | ||
| gov.contrib.states.ut.eitc.in_effect: true | ||
| people: | ||
| parent: | ||
| age: 30 | ||
| child: | ||
| age: 1 | ||
| is_tax_unit_dependent: true | ||
| tax_units: | ||
| tax_unit: | ||
| members: [parent, child] | ||
| eitc: 3_000 | ||
| households: | ||
| household: | ||
| members: [parent, child] | ||
| state_code: UT | ||
| output: | ||
| # Utah EITC = 20% of federal EITC = 0.2 * 3_000 = 600 | ||
| ut_eitc: 600 | ||
| ut_refundable_eitc: 600 | ||
| ut_non_refundable_eitc: 0 | ||
| ut_has_qualifying_child_for_refundable_eitc: true | ||
|
|
||
| - name: Single parent with child age 3 - not eligible for refundable EITC | ||
| period: 2024 | ||
| reforms: policyengine_us.reforms.states.ut.ut_refundable_eitc.ut_refundable_eitc | ||
| input: | ||
| gov.contrib.states.ut.eitc.in_effect: true | ||
| people: | ||
| parent: | ||
| age: 30 | ||
| child: | ||
| age: 3 | ||
| is_tax_unit_dependent: true | ||
| tax_units: | ||
| tax_unit: | ||
| members: [parent, child] | ||
| eitc: 4_000 | ||
| households: | ||
| household: | ||
| members: [parent, child] | ||
| state_code: UT | ||
| output: | ||
| # Child is too old (max_age is 2) | ||
| # Utah EITC = 0.2 * 4_000 = 800 | ||
| ut_eitc: 800 | ||
| ut_refundable_eitc: 0 | ||
| ut_non_refundable_eitc: 800 # Remains fully non-refundable | ||
| ut_has_qualifying_child_for_refundable_eitc: false | ||
|
|
||
| - name: Single parent with multiple children, one qualifying | ||
| period: 2024 | ||
| reforms: policyengine_us.reforms.states.ut.ut_refundable_eitc.ut_refundable_eitc | ||
| input: | ||
| gov.contrib.states.ut.eitc.in_effect: true | ||
| people: | ||
| parent: | ||
| age: 35 | ||
| child1: | ||
| age: 1 | ||
| is_tax_unit_dependent: true | ||
| child2: | ||
| age: 5 | ||
| is_tax_unit_dependent: true | ||
| tax_units: | ||
| tax_unit: | ||
| members: [parent, child1, child2] | ||
| eitc: 6_000 | ||
| households: | ||
| household: | ||
| members: [parent, child1, child2] | ||
| state_code: UT | ||
| output: | ||
| # Has at least one qualifying child, so full EITC is refundable | ||
| # Utah EITC = 0.2 * 6_000 = 1_200 | ||
| ut_eitc: 1_200 | ||
| ut_refundable_eitc: 1_200 | ||
| ut_non_refundable_eitc: 0 | ||
| ut_has_qualifying_child_for_refundable_eitc: true | ||
|
|
||
| - name: Childless tax unit - not eligible | ||
| period: 2024 | ||
| reforms: policyengine_us.reforms.states.ut.ut_refundable_eitc.ut_refundable_eitc | ||
| input: | ||
| gov.contrib.states.ut.eitc.in_effect: true | ||
| people: | ||
| person: | ||
| age: 30 | ||
| tax_units: | ||
| tax_unit: | ||
| members: [person] | ||
| eitc: 500 | ||
| households: | ||
| household: | ||
| members: [person] | ||
| state_code: UT | ||
| output: | ||
| # Utah EITC = 0.2 * 500 = 100 (all non-refundable) | ||
| ut_eitc: 100 | ||
| ut_refundable_eitc: 0 | ||
| ut_non_refundable_eitc: 100 | ||
| ut_has_qualifying_child_for_refundable_eitc: false | ||
|
|
||
| - name: Married couple with infant (age 0) | ||
| period: 2024 | ||
| reforms: policyengine_us.reforms.states.ut.ut_refundable_eitc.ut_refundable_eitc | ||
| input: | ||
| gov.contrib.states.ut.eitc.in_effect: true | ||
| people: | ||
| parent1: | ||
| age: 28 | ||
| parent2: | ||
| age: 30 | ||
| child: | ||
| age: 0 | ||
| is_tax_unit_dependent: true | ||
| tax_units: | ||
| tax_unit: | ||
| members: [parent1, parent2, child] | ||
| eitc: 7_000 | ||
| households: | ||
| household: | ||
| members: [parent1, parent2, child] | ||
| state_code: UT | ||
| output: | ||
| # Utah EITC = 0.2 * 7_000 = 1_400 | ||
| ut_eitc: 1_400 | ||
| ut_refundable_eitc: 1_400 | ||
| ut_non_refundable_eitc: 0 | ||
| ut_has_qualifying_child_for_refundable_eitc: true | ||
|
|
||
| - name: Tax unit with qualifying child but no federal EITC | ||
| period: 2024 | ||
| reforms: policyengine_us.reforms.states.ut.ut_refundable_eitc.ut_refundable_eitc | ||
| input: | ||
| gov.contrib.states.ut.eitc.in_effect: true | ||
| people: | ||
| parent: | ||
| age: 30 | ||
| child: | ||
| age: 2 | ||
| is_tax_unit_dependent: true | ||
| tax_units: | ||
| tax_unit: | ||
| members: [parent, child] | ||
| eitc: 0 | ||
| households: | ||
| household: | ||
| members: [parent, child] | ||
| state_code: UT | ||
| output: | ||
| # No federal EITC means no Utah EITC | ||
| ut_eitc: 0 | ||
| ut_refundable_eitc: 0 | ||
| ut_non_refundable_eitc: 0 | ||
| ut_has_qualifying_child_for_refundable_eitc: true | ||
|
|
||
| - name: Custom max_age parameter - child at age 4 qualifies | ||
| period: 2024 | ||
| reforms: policyengine_us.reforms.states.ut.ut_refundable_eitc.ut_refundable_eitc | ||
| input: | ||
| gov.contrib.states.ut.eitc.in_effect: true | ||
| gov.contrib.states.ut.eitc.max_age: 4 | ||
| people: | ||
| parent: | ||
| age: 30 | ||
| child: | ||
| age: 4 | ||
| is_tax_unit_dependent: true | ||
| tax_units: | ||
| tax_unit: | ||
| members: [parent, child] | ||
| eitc: 5_000 | ||
| households: | ||
| household: | ||
| members: [parent, child] | ||
| state_code: UT | ||
| output: | ||
| # With max_age = 4, child age 4 qualifies | ||
| # Utah EITC = 0.2 * 5_000 = 1_000 | ||
| ut_eitc: 1_000 | ||
| ut_refundable_eitc: 1_000 | ||
| ut_non_refundable_eitc: 0 | ||
| ut_has_qualifying_child_for_refundable_eitc: true |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.