From 6f2f3df3f9e07bbc823f45933b22c14396805af0 Mon Sep 17 00:00:00 2001 From: Daphne Hansell <128793799+daphnehanse11@users.noreply.github.com> Date: Thu, 14 May 2026 16:11:41 -0400 Subject: [PATCH 1/5] Add Utah homeowner renter property tax relief --- changelog.d/8182.added.md | 1 + .../household/state_property_tax_credits.yaml | 20 +++++ .../age_threshold.yaml | 13 +++ .../homeowner_renter_relief/income_limit.yaml | 12 +++ .../homeowner_renter_relief/maximum.yaml | 45 ++++++++++ .../homeowner_renter_relief/renter/rate.yaml | 45 ++++++++++ .../ut_homeowner_renter_relief.yaml | 90 +++++++++++++++++++ .../ut_homeowner_renter_relief_eligible.yaml | 61 +++++++++++++ .../ut_homeowner_renter_relief.py | 25 ++++++ .../ut_homeowner_renter_relief_eligible.py | 32 +++++++ 10 files changed, 344 insertions(+) create mode 100644 changelog.d/8182.added.md create mode 100644 policyengine_us/parameters/gov/states/ut/tax/property/homeowner_renter_relief/age_threshold.yaml create mode 100644 policyengine_us/parameters/gov/states/ut/tax/property/homeowner_renter_relief/income_limit.yaml create mode 100644 policyengine_us/parameters/gov/states/ut/tax/property/homeowner_renter_relief/maximum.yaml create mode 100644 policyengine_us/parameters/gov/states/ut/tax/property/homeowner_renter_relief/renter/rate.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_eligible.yaml create mode 100644 policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief.py create mode 100644 policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_eligible.py diff --git a/changelog.d/8182.added.md b/changelog.d/8182.added.md new file mode 100644 index 00000000000..52ba11d97b7 --- /dev/null +++ b/changelog.d/8182.added.md @@ -0,0 +1 @@ +Added Utah Homeowner's/Renter's Relief. diff --git a/policyengine_us/parameters/gov/states/household/state_property_tax_credits.yaml b/policyengine_us/parameters/gov/states/household/state_property_tax_credits.yaml index b5c719c31cf..e4861d8d1c7 100644 --- a/policyengine_us/parameters/gov/states/household/state_property_tax_credits.yaml +++ b/policyengine_us/parameters/gov/states/household/state_property_tax_credits.yaml @@ -114,6 +114,26 @@ values: - wi_homestead_credit - wi_property_tax_credit - wv_homestead_excess_property_tax_credit + 2025-01-01: + - az_property_tax_credit + - ct_property_tax_credit + - dc_ptc + - il_property_tax_credit + - ma_senior_circuit_breaker + - me_property_tax_fairness_credit + - mi_homestead_property_tax_credit + - mo_property_tax_credit + - mt_elderly_homeowner_or_renter_credit + - mt_property_tax_rebate + - nj_property_tax_credit + - nm_property_tax_rebate + - ny_real_property_tax_credit + - ok_ptc + - ri_property_tax_credit + - ut_homeowner_renter_relief + - wi_homestead_credit + - wi_property_tax_credit + - wv_homestead_excess_property_tax_credit metadata: unit: list diff --git a/policyengine_us/parameters/gov/states/ut/tax/property/homeowner_renter_relief/age_threshold.yaml b/policyengine_us/parameters/gov/states/ut/tax/property/homeowner_renter_relief/age_threshold.yaml new file mode 100644 index 00000000000..47ea686f3fc --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/tax/property/homeowner_renter_relief/age_threshold.yaml @@ -0,0 +1,13 @@ +description: Utah limits age to this threshold under the Homeowner's/Renter's Relief program. +values: + 2025-01-01: 66 + 2026-01-01: 67 +metadata: + unit: year + period: year + label: Utah homeowner's/renter's relief age threshold + reference: + - title: Utah State Tax Commission Renter's Credit eligibility + href: https://tax.utah.gov/relief/renter-refund/ + - title: Utah Code Section 59-2a-101 + href: https://le.utah.gov/xcode/Title59/Chapter2A/C59-2a_2026010120250507.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/ut/tax/property/homeowner_renter_relief/income_limit.yaml b/policyengine_us/parameters/gov/states/ut/tax/property/homeowner_renter_relief/income_limit.yaml new file mode 100644 index 00000000000..483a0cc93b9 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/tax/property/homeowner_renter_relief/income_limit.yaml @@ -0,0 +1,12 @@ +description: Utah limits household income to this amount under the Homeowner's/Renter's Relief program. +values: + 2025-01-01: 44_221 +metadata: + unit: currency-USD + period: year + label: Utah homeowner's/renter's relief income limit + reference: + - title: Utah State Tax Commission Homeowner's or Renter's Relief 2025 Household Income Schedule + href: https://tax.utah.gov/relief/homeowner-renter-relief/ + - title: 2025 Utah TC-90CB Renter Refund Application + href: https://files.tax.utah.gov/tax/forms/current/tc-90cb.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/ut/tax/property/homeowner_renter_relief/maximum.yaml b/policyengine_us/parameters/gov/states/ut/tax/property/homeowner_renter_relief/maximum.yaml new file mode 100644 index 00000000000..00c9fa1311d --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/tax/property/homeowner_renter_relief/maximum.yaml @@ -0,0 +1,45 @@ +description: Utah provides this maximum credit amount under the Homeowner's/Renter's Relief program. +metadata: + type: single_amount + threshold_unit: currency-USD + amount_unit: currency-USD + period: year + label: Utah homeowner's/renter's relief maximum amount + reference: + - title: Utah State Tax Commission Homeowner's or Renter's Relief 2025 Household Income Schedule + href: https://tax.utah.gov/relief/homeowner-renter-relief/ + - title: Utah Code Section 59-2a-305 + href: https://le.utah.gov/xcode/Title59/Chapter2A/C59-2a_2026010120250507.pdf#page=14 +brackets: + - threshold: + 2025-01-01: 0 + amount: + 2025-01-01: 1_412 + - threshold: + 2025-01-01: 15_034 + amount: + 2025-01-01: 1_245 + - threshold: + 2025-01-01: 20_049 + amount: + 2025-01-01: 1_082 + - threshold: + 2025-01-01: 25_058 + amount: + 2025-01-01: 835 + - threshold: + 2025-01-01: 30_070 + amount: + 2025-01-01: 674 + - threshold: + 2025-01-01: 35_084 + amount: + 2025-01-01: 429 + - threshold: + 2025-01-01: 39_797 + amount: + 2025-01-01: 262 + - threshold: + 2025-01-01: 44_222 + amount: + 2025-01-01: 0 diff --git a/policyengine_us/parameters/gov/states/ut/tax/property/homeowner_renter_relief/renter/rate.yaml b/policyengine_us/parameters/gov/states/ut/tax/property/homeowner_renter_relief/renter/rate.yaml new file mode 100644 index 00000000000..0c2527352f8 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/tax/property/homeowner_renter_relief/renter/rate.yaml @@ -0,0 +1,45 @@ +description: Utah provides this percentage of gross rent under the Homeowner's/Renter's Relief program. +metadata: + type: single_amount + threshold_unit: currency-USD + amount_unit: /1 + period: year + label: Utah homeowner's/renter's relief renter rate + reference: + - title: 2025 Utah TC-90CB Renter Refund Application + href: https://files.tax.utah.gov/tax/forms/current/tc-90cb.pdf#page=4 + - title: Utah Code Section 59-2a-205 + href: https://le.utah.gov/xcode/Title59/Chapter2A/C59-2a_2026010120250507.pdf#page=11 +brackets: + - threshold: + 2025-01-01: 0 + amount: + 2025-01-01: 0.095 + - threshold: + 2025-01-01: 15_034 + amount: + 2025-01-01: 0.085 + - threshold: + 2025-01-01: 20_049 + amount: + 2025-01-01: 0.07 + - threshold: + 2025-01-01: 25_058 + amount: + 2025-01-01: 0.055 + - threshold: + 2025-01-01: 30_070 + amount: + 2025-01-01: 0.04 + - threshold: + 2025-01-01: 35_084 + amount: + 2025-01-01: 0.03 + - threshold: + 2025-01-01: 39_797 + amount: + 2025-01-01: 0.025 + - threshold: + 2025-01-01: 44_222 + amount: + 2025-01-01: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief.yaml new file mode 100644 index 00000000000..73f07998840 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief.yaml @@ -0,0 +1,90 @@ +- name: Case 1, renter credit based on gross rent. + period: 2025 + absolute_error_margin: 0.01 + input: + age_head: 66 + adjusted_gross_income: 10_000 + rent: 12_000 + state_code: UT + output: + ut_homeowner_renter_relief: 1_140 + +- name: Case 2, renter credit capped by maximum amount. + period: 2025 + absolute_error_margin: 0.01 + input: + age_head: 66 + adjusted_gross_income: 10_000 + rent: 20_000 + state_code: UT + output: + ut_homeowner_renter_relief: 1_412 + +- name: Case 3, renter credit in a middle income bracket. + period: 2025 + absolute_error_margin: 0.01 + input: + age_head: 66 + adjusted_gross_income: 25_058 + rent: 10_000 + state_code: UT + output: + ut_homeowner_renter_relief: 550 + +- name: Case 4, homeowner credit capped by the income schedule. + period: 2025 + absolute_error_margin: 0.01 + input: + age_head: 66 + adjusted_gross_income: 35_084 + rent: 0 + real_estate_taxes: 600 + state_code: UT + output: + ut_homeowner_renter_relief: 429 + +- name: Case 5, homeowner credit capped by property tax paid. + period: 2025 + absolute_error_margin: 0.01 + input: + age_head: 66 + adjusted_gross_income: 10_000 + rent: 0 + real_estate_taxes: 900 + state_code: UT + output: + ut_homeowner_renter_relief: 900 + +- name: Case 6, surviving spouse renter in the top eligible bracket. + period: 2025 + absolute_error_margin: 0.01 + input: + age_head: 45 + adjusted_gross_income: 39_797 + filing_status: SURVIVING_SPOUSE + rent: 10_000 + state_code: UT + output: + ut_homeowner_renter_relief: 250 + +- name: Case 7, renter and homeowner amounts can both apply. + period: 2025 + absolute_error_margin: 0.01 + input: + age_head: 66 + adjusted_gross_income: 10_000 + rent: 10_000 + real_estate_taxes: 600 + state_code: UT + output: + ut_homeowner_renter_relief: 1_550 + +- name: Case 8, ineligible claimant receives no relief. + period: 2025 + input: + age_head: 60 + adjusted_gross_income: 10_000 + rent: 12_000 + state_code: UT + output: + ut_homeowner_renter_relief: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_eligible.yaml new file mode 100644 index 00000000000..f0e0667b69b --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_eligible.yaml @@ -0,0 +1,61 @@ +- name: Case 1, age-eligible renter. + period: 2025 + input: + age_head: 66 + adjusted_gross_income: 15_000 + rent: 12_000 + state_code: UT + output: + ut_homeowner_renter_relief_eligible: true + +- name: Case 2, surviving spouse under the age threshold. + period: 2025 + input: + age_head: 45 + adjusted_gross_income: 15_000 + filing_status: SURVIVING_SPOUSE + rent: 12_000 + state_code: UT + output: + ut_homeowner_renter_relief_eligible: true + +- name: Case 3, income above the limit. + period: 2025 + input: + age_head: 66 + adjusted_gross_income: 44_222 + rent: 12_000 + state_code: UT + output: + ut_homeowner_renter_relief_eligible: false + +- name: Case 4, no rent or property tax paid. + period: 2025 + input: + age_head: 66 + adjusted_gross_income: 15_000 + rent: 0 + real_estate_taxes: 0 + state_code: UT + output: + ut_homeowner_renter_relief_eligible: false + +- name: Case 5, age 66 after the transition year. + period: 2026 + input: + age_head: 66 + adjusted_gross_income: 15_000 + rent: 12_000 + state_code: UT + output: + ut_homeowner_renter_relief_eligible: false + +- name: Case 6, age 67 after the transition year. + period: 2026 + input: + age_head: 67 + adjusted_gross_income: 15_000 + rent: 12_000 + state_code: UT + output: + ut_homeowner_renter_relief_eligible: true diff --git a/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief.py b/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief.py new file mode 100644 index 00000000000..3a1ee95433d --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief.py @@ -0,0 +1,25 @@ +from policyengine_us.model_api import * + + +class ut_homeowner_renter_relief(Variable): + value_type = float + entity = TaxUnit + label = "Utah Homeowner's/Renter's Relief" + unit = USD + definition_period = YEAR + reference = ( + "https://tax.utah.gov/relief/homeowner-renter-relief/", + "https://files.tax.utah.gov/tax/forms/current/tc-90cb.pdf#page=4", + "https://le.utah.gov/xcode/Title59/Chapter2A/C59-2a_2026010120250507.pdf#page=11", + "https://le.utah.gov/xcode/Title59/Chapter2A/C59-2a_2026010120250507.pdf#page=14", + ) + defined_for = "ut_homeowner_renter_relief_eligible" + + def formula(tax_unit, period, parameters): + p = parameters(period).gov.states.ut.tax.property.homeowner_renter_relief + income = tax_unit("adjusted_gross_income", period) + maximum = p.maximum.calc(income) + rent = add(tax_unit, period, ["rent"]) + renter_credit = min_(rent * p.renter.rate.calc(income), maximum) + homeowner_credit = min_(add(tax_unit, period, ["real_estate_taxes"]), maximum) + return renter_credit + homeowner_credit diff --git a/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_eligible.py b/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_eligible.py new file mode 100644 index 00000000000..0f7b6ebdded --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_eligible.py @@ -0,0 +1,32 @@ +from policyengine_us.model_api import * + + +class ut_homeowner_renter_relief_eligible(Variable): + value_type = bool + entity = TaxUnit + label = "Eligible for Utah Homeowner's/Renter's Relief" + definition_period = YEAR + reference = ( + "https://tax.utah.gov/relief/homeowner-renter-relief/", + "https://tax.utah.gov/relief/renter-refund/", + "https://le.utah.gov/xcode/Title59/Chapter2A/C59-2a_2026010120250507.pdf#page=1", + ) + defined_for = StateCode.UT + + def formula(tax_unit, period, parameters): + p = parameters(period).gov.states.ut.tax.property.homeowner_renter_relief + age_head = tax_unit("age_head", period) + age_spouse = tax_unit("age_spouse", period) + filing_status = tax_unit("filing_status", period) + statuses = filing_status.possible_values + age_eligible = (age_head >= p.age_threshold) | (age_spouse >= p.age_threshold) + surviving_spouse = filing_status == statuses.SURVIVING_SPOUSE + income = tax_unit("adjusted_gross_income", period) + paid_rent_or_property_tax = ( + add(tax_unit, period, ["rent", "real_estate_taxes"]) > 0 + ) + return ( + (age_eligible | surviving_spouse) + & (income <= p.income_limit) + & paid_rent_or_property_tax + ) From 9d67fe10592884deec2d393cbe5e6242da47588d Mon Sep 17 00:00:00 2001 From: Daphne Hansell <128793799+daphnehanse11@users.noreply.github.com> Date: Thu, 14 May 2026 16:53:59 -0400 Subject: [PATCH 2/5] Rename changelog fragment for PR 8317 --- changelog.d/{8182.added.md => 8317.added.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename changelog.d/{8182.added.md => 8317.added.md} (100%) diff --git a/changelog.d/8182.added.md b/changelog.d/8317.added.md similarity index 100% rename from changelog.d/8182.added.md rename to changelog.d/8317.added.md From fd308d2c037a5dc93fad6ed49fdb7984f8365455 Mon Sep 17 00:00:00 2001 From: Daphne Hansell <128793799+daphnehanse11@users.noreply.github.com> Date: Mon, 18 May 2026 16:45:56 -0400 Subject: [PATCH 3/5] Wire ut_homeowner_renter_relief into net income Add ut_homeowner_renter_relief to a new gov.states.ut.tax.income.credits.refundable list and wire ut_refundable_credits to it. The relief now flows through household_refundable_state_tax_credits to household_net_income, matching the pattern used for WI homestead credit and other state property tax rebates. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../states/ut/tax/income/credits/refundable.yaml | 16 ++++++++++++++++ .../tax/income/credits/ut_refundable_credits.py | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 policyengine_us/parameters/gov/states/ut/tax/income/credits/refundable.yaml diff --git a/policyengine_us/parameters/gov/states/ut/tax/income/credits/refundable.yaml b/policyengine_us/parameters/gov/states/ut/tax/income/credits/refundable.yaml new file mode 100644 index 00000000000..61354c3489e --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/tax/income/credits/refundable.yaml @@ -0,0 +1,16 @@ +description: Utah provides these refundable income tax credits. +values: + 2025-01-01: + - ut_homeowner_renter_relief + +metadata: + unit: list + period: year + label: Utah refundable credits + reference: + - title: Utah State Tax Commission Homeowner's or Renter's Relief + href: https://tax.utah.gov/relief/homeowner-renter-relief/ + - title: Utah Code Section 59-2a-205 + href: https://le.utah.gov/xcode/Title59/Chapter2A/C59-2a_2026010120250507.pdf#page=11 + - title: Utah Code Section 59-2a-305 + href: https://le.utah.gov/xcode/Title59/Chapter2A/C59-2a_2026010120250507.pdf#page=14 diff --git a/policyengine_us/variables/gov/states/ut/tax/income/credits/ut_refundable_credits.py b/policyengine_us/variables/gov/states/ut/tax/income/credits/ut_refundable_credits.py index d12f2525aff..90630823614 100644 --- a/policyengine_us/variables/gov/states/ut/tax/income/credits/ut_refundable_credits.py +++ b/policyengine_us/variables/gov/states/ut/tax/income/credits/ut_refundable_credits.py @@ -8,4 +8,4 @@ class ut_refundable_credits(Variable): unit = USD definition_period = YEAR defined_for = StateCode.UT - reference = "" + adds = "gov.states.ut.tax.income.credits.refundable" From e5d024874c072fc44500d9111b496b6864202a5b Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Tue, 19 May 2026 09:50:23 -0400 Subject: [PATCH 4/5] Fix Utah relief household income --- .../adult_age_threshold.yaml | 10 ++++ .../ut_homeowner_renter_relief.yaml | 29 +++++++++++ .../ut_homeowner_renter_relief_eligible.yaml | 49 +++++++++++++++++++ .../ut_homeowner_renter_relief.py | 4 +- .../ut_homeowner_renter_relief_eligible.py | 15 +++++- ...omeowner_renter_relief_household_income.py | 38 ++++++++++++++ 6 files changed, 143 insertions(+), 2 deletions(-) create mode 100644 policyengine_us/parameters/gov/states/ut/tax/property/homeowner_renter_relief/adult_age_threshold.yaml create mode 100644 policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_household_income.py diff --git a/policyengine_us/parameters/gov/states/ut/tax/property/homeowner_renter_relief/adult_age_threshold.yaml b/policyengine_us/parameters/gov/states/ut/tax/property/homeowner_renter_relief/adult_age_threshold.yaml new file mode 100644 index 00000000000..d7886b6f7f6 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/tax/property/homeowner_renter_relief/adult_age_threshold.yaml @@ -0,0 +1,10 @@ +description: Utah includes household members at or above this age in household income under the Homeowner's/Renter's Relief program. +values: + 2025-01-01: 18 +metadata: + unit: year + period: year + label: Utah homeowner's/renter's relief household income adult age threshold + reference: + - title: Utah Code Section 59-2a-101 + href: https://le.utah.gov/xcode/Title59/Chapter2A/C59-2a_2026010120250507.pdf#page=1 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief.yaml index 73f07998840..9dfd369e590 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief.yaml @@ -88,3 +88,32 @@ state_code: UT output: ut_homeowner_renter_relief: 0 + +- name: Case 9, other adult household income affects the renter credit. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 66 + employment_income: 10_000 + pre_subsidy_rent: 10_000 + is_tax_unit_head: true + person2: + age: 40 + employment_income: 15_058 + is_tax_unit_head: true + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + ut_homeowner_renter_relief: [550, 0] diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_eligible.yaml index f0e0667b69b..c4dff44fb50 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_eligible.yaml @@ -59,3 +59,52 @@ state_code: UT output: ut_homeowner_renter_relief_eligible: true + +- name: Case 7, claimed dependent claimant is ineligible. + period: 2025 + input: + people: + person1: + age: 66 + employment_income: 10_000 + pre_subsidy_rent: 12_000 + is_tax_unit_head: true + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: UT + output: + ut_homeowner_renter_relief_eligible: false + +- name: Case 8, other adult household income counts. + period: 2025 + input: + people: + person1: + age: 66 + employment_income: 10_000 + pre_subsidy_rent: 12_000 + is_tax_unit_head: true + person2: + age: 40 + employment_income: 60_000 + is_tax_unit_head: true + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + ut_homeowner_renter_relief_household_income: 70_000 + ut_homeowner_renter_relief_eligible: [false, false] diff --git a/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief.py b/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief.py index 3a1ee95433d..f2bdd138748 100644 --- a/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief.py +++ b/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief.py @@ -17,7 +17,9 @@ class ut_homeowner_renter_relief(Variable): def formula(tax_unit, period, parameters): p = parameters(period).gov.states.ut.tax.property.homeowner_renter_relief - income = tax_unit("adjusted_gross_income", period) + income = tax_unit.spm_unit( + "ut_homeowner_renter_relief_household_income", period + ) maximum = p.maximum.calc(income) rent = add(tax_unit, period, ["rent"]) renter_credit = min_(rent * p.renter.rate.calc(income), maximum) diff --git a/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_eligible.py b/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_eligible.py index 0f7b6ebdded..4ba36c57fdb 100644 --- a/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_eligible.py +++ b/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_eligible.py @@ -21,12 +21,25 @@ def formula(tax_unit, period, parameters): statuses = filing_status.possible_values age_eligible = (age_head >= p.age_threshold) | (age_spouse >= p.age_threshold) surviving_spouse = filing_status == statuses.SURVIVING_SPOUSE - income = tax_unit("adjusted_gross_income", period) + income = tax_unit.spm_unit( + "ut_homeowner_renter_relief_household_income", period + ) paid_rent_or_property_tax = ( add(tax_unit, period, ["rent", "real_estate_taxes"]) > 0 ) + claimants = tax_unit.members("is_tax_unit_head_or_spouse", period) + claimant_is_tax_unit_dependent = tax_unit.any( + claimants & tax_unit.members("is_tax_unit_dependent", period) + ) + claimant_is_dependent_elsewhere = tax_unit( + "head_is_dependent_elsewhere", period + ) | tax_unit("spouse_is_dependent_elsewhere", period) + claimant_is_dependent = ( + claimant_is_tax_unit_dependent | claimant_is_dependent_elsewhere + ) return ( (age_eligible | surviving_spouse) & (income <= p.income_limit) & paid_rent_or_property_tax + & ~claimant_is_dependent ) diff --git a/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_household_income.py b/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_household_income.py new file mode 100644 index 00000000000..d6f606826b6 --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_household_income.py @@ -0,0 +1,38 @@ +from policyengine_us.model_api import * + + +class ut_homeowner_renter_relief_household_income(Variable): + value_type = float + entity = SPMUnit + label = "Utah homeowner's/renter's relief household income" + unit = USD + definition_period = YEAR + reference = ( + "https://tax.utah.gov/relief/homeowner-renter-relief/", + "https://files.tax.utah.gov/tax/forms/current/tc-90cb.pdf#page=4", + "https://le.utah.gov/xcode/Title59/Chapter2A/C59-2a_2026010120250507.pdf#page=1", + ) + documentation = ( + "Counts adult household members' adjusted gross income. Parent and " + "grandparent exclusions are not modeled because household relationship " + "data do not identify those relatives." + ) + defined_for = StateCode.UT + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.ut.tax.property.homeowner_renter_relief + person = spm_unit.members + person_agi = person("adjusted_gross_income_person", period) + is_adult = person("age", period) >= p.adult_age_threshold + tax_unit_person_agi = person.tax_unit.sum(person_agi) + tax_unit_agi = person.tax_unit("adjusted_gross_income", period) + tax_unit_has_adult = ( + person.tax_unit("age_head", period) >= p.adult_age_threshold + ) | (person.tax_unit("age_spouse", period) >= p.adult_age_threshold) + tax_unit_agi_fallback = ( + (tax_unit_person_agi == 0) + * person("is_tax_unit_head", period) + * tax_unit_has_adult + * tax_unit_agi + ) + return spm_unit.sum(person_agi * is_adult + tax_unit_agi_fallback) From bdd8fac3461825dea7e144083a00e528f4d76cf1 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Tue, 19 May 2026 10:08:44 -0400 Subject: [PATCH 5/5] Use Utah relief household income definition --- .../adult_age_threshold.yaml | 2 +- .../nontaxable_income/sources.yaml | 23 ++++ .../ut_homeowner_renter_relief.yaml | 129 +++++++++++++++--- .../ut_homeowner_renter_relief_eligible.yaml | 58 +++++++- .../ut_homeowner_renter_relief.py | 14 +- .../ut_homeowner_renter_relief_eligible.py | 32 +---- ...omeowner_renter_relief_household_income.py | 13 +- ...meowner_renter_relief_nontaxable_income.py | 36 +++++ ...renter_relief_pre_one_claimant_eligible.py | 47 +++++++ ...meowner_renter_relief_selected_claimant.py | 26 ++++ 10 files changed, 325 insertions(+), 55 deletions(-) create mode 100644 policyengine_us/parameters/gov/states/ut/tax/property/homeowner_renter_relief/nontaxable_income/sources.yaml create mode 100644 policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_nontaxable_income.py create mode 100644 policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_pre_one_claimant_eligible.py create mode 100644 policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_selected_claimant.py diff --git a/policyengine_us/parameters/gov/states/ut/tax/property/homeowner_renter_relief/adult_age_threshold.yaml b/policyengine_us/parameters/gov/states/ut/tax/property/homeowner_renter_relief/adult_age_threshold.yaml index d7886b6f7f6..321764a2714 100644 --- a/policyengine_us/parameters/gov/states/ut/tax/property/homeowner_renter_relief/adult_age_threshold.yaml +++ b/policyengine_us/parameters/gov/states/ut/tax/property/homeowner_renter_relief/adult_age_threshold.yaml @@ -1,6 +1,6 @@ description: Utah includes household members at or above this age in household income under the Homeowner's/Renter's Relief program. values: - 2025-01-01: 18 + 2024-01-01: 18 metadata: unit: year period: year diff --git a/policyengine_us/parameters/gov/states/ut/tax/property/homeowner_renter_relief/nontaxable_income/sources.yaml b/policyengine_us/parameters/gov/states/ut/tax/property/homeowner_renter_relief/nontaxable_income/sources.yaml new file mode 100644 index 00000000000..409a999269a --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/tax/property/homeowner_renter_relief/nontaxable_income/sources.yaml @@ -0,0 +1,23 @@ +description: Utah adds these modeled nontaxable income sources to adjusted gross income under the Homeowner's/Renter's Relief program. +values: + 2024-01-01: + - alimony_income + - child_support_received + - railroad_benefits + - strike_benefits + - tax_exempt_interest_income + - tax_exempt_pension_income + - tax_exempt_retirement_distributions + - traditional_401k_contributions + - traditional_403b_contributions + - traditional_ira_contributions + - self_employed_pension_contributions + - veterans_benefits + - workers_compensation +metadata: + unit: list + period: year + label: Utah homeowner's/renter's relief modeled nontaxable income sources + reference: + - title: Utah Code Section 59-2a-101 + href: https://le.utah.gov/xcode/Title59/Chapter2A/C59-2a_2026010120250507.pdf#page=5 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief.yaml index 9dfd369e590..2ca40f32e77 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief.yaml @@ -35,11 +35,23 @@ period: 2025 absolute_error_margin: 0.01 input: - age_head: 66 - adjusted_gross_income: 35_084 - rent: 0 - real_estate_taxes: 600 - state_code: UT + people: + person1: + age: 66 + employment_income: + 2024: 35_084 + 2025: 35_084 + real_estate_taxes: 600 + is_tax_unit_head: true + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: + 2024: UT + 2025: UT output: ut_homeowner_renter_relief: 429 @@ -47,11 +59,23 @@ period: 2025 absolute_error_margin: 0.01 input: - age_head: 66 - adjusted_gross_income: 10_000 - rent: 0 - real_estate_taxes: 900 - state_code: UT + people: + person1: + age: 66 + employment_income: + 2024: 10_000 + 2025: 10_000 + real_estate_taxes: 900 + is_tax_unit_head: true + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: + 2024: UT + 2025: UT output: ut_homeowner_renter_relief: 900 @@ -71,11 +95,24 @@ period: 2025 absolute_error_margin: 0.01 input: - age_head: 66 - adjusted_gross_income: 10_000 - rent: 10_000 - real_estate_taxes: 600 - state_code: UT + people: + person1: + age: 66 + employment_income: + 2024: 10_000 + 2025: 10_000 + pre_subsidy_rent: 10_000 + real_estate_taxes: 600 + is_tax_unit_head: true + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: + 2024: UT + 2025: UT output: ut_homeowner_renter_relief: 1_550 @@ -109,11 +146,69 @@ tax_unit2: members: [person2] spm_units: - spm_unit: - members: [person1, person2] + spm_unit1: + members: [person1] + spm_unit2: + members: [person2] households: household: members: [person1, person2] state_code: UT output: ut_homeowner_renter_relief: [550, 0] + +- name: Case 10, homeowner credit uses prior-year household income. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 66 + employment_income: + 2024: 10_000 + 2025: 50_000 + real_estate_taxes: 600 + is_tax_unit_head: true + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: + 2024: UT + 2025: UT + output: + ut_homeowner_renter_relief: 600 + +- name: Case 11, only one eligible claimant receives relief per household. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + employment_income: 10_000 + pre_subsidy_rent: 10_000 + is_tax_unit_head: true + person2: + age: 66 + employment_income: 10_000 + pre_subsidy_rent: 10_000 + is_tax_unit_head: true + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2] + spm_units: + spm_unit1: + members: [person1] + spm_unit2: + members: [person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + ut_homeowner_renter_relief: [850, 0] diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_eligible.yaml index c4dff44fb50..6a81fc9a496 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_eligible.yaml @@ -99,8 +99,10 @@ tax_unit2: members: [person2] spm_units: - spm_unit: - members: [person1, person2] + spm_unit1: + members: [person1] + spm_unit2: + members: [person2] households: household: members: [person1, person2] @@ -108,3 +110,55 @@ output: ut_homeowner_renter_relief_household_income: 70_000 ut_homeowner_renter_relief_eligible: [false, false] + +- name: Case 9, nontaxable income counts. + period: 2025 + input: + people: + person1: + age: 66 + employment_income: 40_000 + tax_exempt_interest_income: 5_000 + pre_subsidy_rent: 12_000 + is_tax_unit_head: true + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: UT + output: + ut_homeowner_renter_relief_household_income: 45_000 + ut_homeowner_renter_relief_eligible: false + +- name: Case 10, only one claimant is eligible per household. + period: 2025 + input: + people: + person1: + age: 70 + employment_income: 10_000 + pre_subsidy_rent: 10_000 + is_tax_unit_head: true + person2: + age: 66 + employment_income: 10_000 + pre_subsidy_rent: 10_000 + is_tax_unit_head: true + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2] + spm_units: + spm_unit1: + members: [person1] + spm_unit2: + members: [person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + ut_homeowner_renter_relief_eligible: [true, false] diff --git a/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief.py b/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief.py index f2bdd138748..6d5688ee06b 100644 --- a/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief.py +++ b/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief.py @@ -17,11 +17,17 @@ class ut_homeowner_renter_relief(Variable): def formula(tax_unit, period, parameters): p = parameters(period).gov.states.ut.tax.property.homeowner_renter_relief - income = tax_unit.spm_unit( + renter_income = tax_unit.household( "ut_homeowner_renter_relief_household_income", period ) - maximum = p.maximum.calc(income) + homeowner_income = tax_unit.household( + "ut_homeowner_renter_relief_household_income", period.last_year + ) + renter_maximum = p.maximum.calc(renter_income) + homeowner_maximum = p.maximum.calc(homeowner_income) rent = add(tax_unit, period, ["rent"]) - renter_credit = min_(rent * p.renter.rate.calc(income), maximum) - homeowner_credit = min_(add(tax_unit, period, ["real_estate_taxes"]), maximum) + renter_credit = min_(rent * p.renter.rate.calc(renter_income), renter_maximum) + homeowner_credit = min_( + add(tax_unit, period, ["real_estate_taxes"]), homeowner_maximum + ) return renter_credit + homeowner_credit diff --git a/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_eligible.py b/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_eligible.py index 4ba36c57fdb..5e8ff590ec3 100644 --- a/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_eligible.py +++ b/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_eligible.py @@ -14,32 +14,10 @@ class ut_homeowner_renter_relief_eligible(Variable): defined_for = StateCode.UT def formula(tax_unit, period, parameters): - p = parameters(period).gov.states.ut.tax.property.homeowner_renter_relief - age_head = tax_unit("age_head", period) - age_spouse = tax_unit("age_spouse", period) - filing_status = tax_unit("filing_status", period) - statuses = filing_status.possible_values - age_eligible = (age_head >= p.age_threshold) | (age_spouse >= p.age_threshold) - surviving_spouse = filing_status == statuses.SURVIVING_SPOUSE - income = tax_unit.spm_unit( - "ut_homeowner_renter_relief_household_income", period + pre_eligible = tax_unit( + "ut_homeowner_renter_relief_pre_one_claimant_eligible", period ) - paid_rent_or_property_tax = ( - add(tax_unit, period, ["rent", "real_estate_taxes"]) > 0 - ) - claimants = tax_unit.members("is_tax_unit_head_or_spouse", period) - claimant_is_tax_unit_dependent = tax_unit.any( - claimants & tax_unit.members("is_tax_unit_dependent", period) - ) - claimant_is_dependent_elsewhere = tax_unit( - "head_is_dependent_elsewhere", period - ) | tax_unit("spouse_is_dependent_elsewhere", period) - claimant_is_dependent = ( - claimant_is_tax_unit_dependent | claimant_is_dependent_elsewhere - ) - return ( - (age_eligible | surviving_spouse) - & (income <= p.income_limit) - & paid_rent_or_property_tax - & ~claimant_is_dependent + selected_claimant = tax_unit( + "ut_homeowner_renter_relief_selected_claimant", period ) + return pre_eligible & selected_claimant diff --git a/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_household_income.py b/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_household_income.py index d6f606826b6..5cdac989557 100644 --- a/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_household_income.py +++ b/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_household_income.py @@ -3,7 +3,7 @@ class ut_homeowner_renter_relief_household_income(Variable): value_type = float - entity = SPMUnit + entity = Household label = "Utah homeowner's/renter's relief household income" unit = USD definition_period = YEAR @@ -19,10 +19,13 @@ class ut_homeowner_renter_relief_household_income(Variable): ) defined_for = StateCode.UT - def formula(spm_unit, period, parameters): + def formula(household, period, parameters): p = parameters(period).gov.states.ut.tax.property.homeowner_renter_relief - person = spm_unit.members + person = household.members person_agi = person("adjusted_gross_income_person", period) + nontaxable_income = person( + "ut_homeowner_renter_relief_nontaxable_income", period + ) is_adult = person("age", period) >= p.adult_age_threshold tax_unit_person_agi = person.tax_unit.sum(person_agi) tax_unit_agi = person.tax_unit("adjusted_gross_income", period) @@ -35,4 +38,6 @@ def formula(spm_unit, period, parameters): * tax_unit_has_adult * tax_unit_agi ) - return spm_unit.sum(person_agi * is_adult + tax_unit_agi_fallback) + return household.sum( + (person_agi + nontaxable_income) * is_adult + tax_unit_agi_fallback + ) diff --git a/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_nontaxable_income.py b/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_nontaxable_income.py new file mode 100644 index 00000000000..c883faddaf8 --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_nontaxable_income.py @@ -0,0 +1,36 @@ +from policyengine_us.model_api import * + + +class ut_homeowner_renter_relief_nontaxable_income(Variable): + value_type = float + entity = Person + label = "Utah homeowner's/renter's relief nontaxable income" + unit = USD + definition_period = YEAR + reference = ( + "https://le.utah.gov/xcode/Title59/Chapter2A/C59-2a_2026010120250507.pdf#page=5" + ) + defined_for = StateCode.UT + + def formula(person, period, parameters): + p = parameters(period).gov.states.ut.tax.property.homeowner_renter_relief + listed_sources = add(person, period, p.nontaxable_income.sources) + social_security = person("social_security", period) + ssdi = person("social_security_disability", period) + taxable_social_security = person("taxable_social_security", period) + nontaxable_social_security = max_( + 0, social_security - ssdi - taxable_social_security + ) + unemployment_compensation = person("unemployment_compensation", period) + taxable_unemployment_compensation = person( + "taxable_unemployment_compensation", period + ) + nontaxable_unemployment_compensation = max_( + 0, + unemployment_compensation - taxable_unemployment_compensation, + ) + return ( + listed_sources + + nontaxable_social_security + + nontaxable_unemployment_compensation + ) diff --git a/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_pre_one_claimant_eligible.py b/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_pre_one_claimant_eligible.py new file mode 100644 index 00000000000..28c3dbbdf03 --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_pre_one_claimant_eligible.py @@ -0,0 +1,47 @@ +from policyengine_us.model_api import * + + +class ut_homeowner_renter_relief_pre_one_claimant_eligible(Variable): + value_type = bool + entity = TaxUnit + label = "Eligible for Utah Homeowner's/Renter's Relief before one-claimant limit" + definition_period = YEAR + reference = ( + "https://tax.utah.gov/relief/homeowner-renter-relief/", + "https://tax.utah.gov/relief/renter-refund/", + "https://le.utah.gov/xcode/Title59/Chapter2A/C59-2a_2026010120250507.pdf#page=1", + ) + defined_for = StateCode.UT + + def formula(tax_unit, period, parameters): + p = parameters(period).gov.states.ut.tax.property.homeowner_renter_relief + age_head = tax_unit("age_head", period) + age_spouse = tax_unit("age_spouse", period) + filing_status = tax_unit("filing_status", period) + statuses = filing_status.possible_values + age_eligible = (age_head >= p.age_threshold) | (age_spouse >= p.age_threshold) + surviving_spouse = filing_status == statuses.SURVIVING_SPOUSE + renter_income = tax_unit.household( + "ut_homeowner_renter_relief_household_income", period + ) + homeowner_income = tax_unit.household( + "ut_homeowner_renter_relief_household_income", period.last_year + ) + rent = add(tax_unit, period, ["rent"]) + real_estate_taxes = add(tax_unit, period, ["real_estate_taxes"]) + income_eligible = ((rent > 0) & (renter_income <= p.income_limit)) | ( + (real_estate_taxes > 0) & (homeowner_income <= p.income_limit) + ) + claimants = tax_unit.members("is_tax_unit_head_or_spouse", period) + claimant_is_tax_unit_dependent = tax_unit.any( + claimants & tax_unit.members("is_tax_unit_dependent", period) + ) + claimant_is_dependent_elsewhere = tax_unit( + "head_is_dependent_elsewhere", period + ) | tax_unit("spouse_is_dependent_elsewhere", period) + claimant_is_dependent = ( + claimant_is_tax_unit_dependent | claimant_is_dependent_elsewhere + ) + return ( + (age_eligible | surviving_spouse) & income_eligible & ~claimant_is_dependent + ) diff --git a/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_selected_claimant.py b/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_selected_claimant.py new file mode 100644 index 00000000000..7110954ae42 --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_selected_claimant.py @@ -0,0 +1,26 @@ +from policyengine_us.model_api import * + + +class ut_homeowner_renter_relief_selected_claimant(Variable): + value_type = bool + entity = TaxUnit + label = "Selected claimant for Utah Homeowner's/Renter's Relief" + definition_period = YEAR + reference = ( + "https://le.utah.gov/xcode/Title59/Chapter2A/C59-2a_2026010120250507.pdf#page=1" + ) + defined_for = StateCode.UT + + def formula(tax_unit, period, parameters): + person = tax_unit.members + pre_eligible = person.tax_unit( + "ut_homeowner_renter_relief_pre_one_claimant_eligible", period + ) + claimant = person("is_tax_unit_head_or_spouse", period) + age = person("age", period) + claimant_rank = person.get_rank( + person.household, + -age, + condition=claimant & pre_eligible, + ) + return tax_unit.any(claimant & pre_eligible & (claimant_rank == 0))