diff --git a/changelog.d/8317.added.md b/changelog.d/8317.added.md new file mode 100644 index 00000000000..52ba11d97b7 --- /dev/null +++ b/changelog.d/8317.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 b0346611bd8..0c3a85872d5 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 @@ -134,6 +134,27 @@ 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 + - mn_renters_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/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/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..321764a2714 --- /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: + 2024-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/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/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/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..2ca40f32e77 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief.yaml @@ -0,0 +1,214 @@ +- 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: + 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 + +- name: Case 5, homeowner credit capped by property tax paid. + period: 2025 + absolute_error_margin: 0.01 + input: + 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 + +- 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: + 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 + +- 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 + +- 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_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 new file mode 100644 index 00000000000..6a81fc9a496 --- /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,164 @@ +- 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 + +- 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_unit1: + members: [person1] + spm_unit2: + members: [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] + +- 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/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" 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..6d5688ee06b --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief.py @@ -0,0 +1,33 @@ +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 + 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 + ) + 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(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 new file mode 100644 index 00000000000..5e8ff590ec3 --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_eligible.py @@ -0,0 +1,23 @@ +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): + pre_eligible = tax_unit( + "ut_homeowner_renter_relief_pre_one_claimant_eligible", period + ) + 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 new file mode 100644 index 00000000000..5cdac989557 --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/tax/property/homeowner_renter_relief/ut_homeowner_renter_relief_household_income.py @@ -0,0 +1,43 @@ +from policyengine_us.model_api import * + + +class ut_homeowner_renter_relief_household_income(Variable): + value_type = float + entity = Household + 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(household, period, parameters): + p = parameters(period).gov.states.ut.tax.property.homeowner_renter_relief + 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) + 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 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))