diff --git a/changelog.d/fix-mt-ehrc-household-income.fixed.md b/changelog.d/fix-mt-ehrc-household-income.fixed.md new file mode 100644 index 00000000000..94e8059efd0 --- /dev/null +++ b/changelog.d/fix-mt-ehrc-household-income.fixed.md @@ -0,0 +1 @@ +Apply the Montana Elderly Homeowner/Renter Credit multiplier to household-level gross income and include the full Social Security amount. diff --git a/policyengine_us/parameters/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/gross_income_sources.yaml b/policyengine_us/parameters/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/gross_income_sources.yaml index 6a2de2109e5..538b7b2585d 100644 --- a/policyengine_us/parameters/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/gross_income_sources.yaml +++ b/policyengine_us/parameters/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/gross_income_sources.yaml @@ -3,7 +3,7 @@ metadata: unit: list period: year label: Montana elderly homeowner or renter credit gross income sources - reference: + reference: - title: Montana 2022 Form2 Individual Income Tax Instructions, Page47, Gross Household Income href: https://mtrevenue.gov/wp-content/uploads/dlm_uploads/2022/12/Form-2-2022-Instructions.pdf#page=47 - title: 2022 Montana Code Annotated, Title 15, Chapter 30, Part 23, 15-30-2337 (9) @@ -13,12 +13,22 @@ metadata: values: 2009-01-01: - - adjusted_gross_income_person # Line 1: Federal adjusted gross income - - tax_exempt_interest_income # Line 2: Exempt interest - - taxable_ira_distributions # Line 3: IRA distribution reported - # Requests 4a from 1040, which includes Roth IRA distributions. + - adjusted_gross_income_person # Federal AGI baseline; covers taxable + # pensions, IRA, wages, interest, dividends, etc. + - tax_exempt_interest_income # § 15-30-2337(9)(a)(vii) + # AGI already includes taxable IRA distributions via + # taxable_retirement_distributions; only the tax-exempt portion + # (Roth distributions) is added back here. - tax_exempt_ira_distributions - - pension_income # Line 4: Pensions and annuities + # AGI already includes taxable pension income; only the tax-exempt + # portion is added back here per § 15-30-2337(9)(a)(i). + - tax_exempt_pension_income + - veterans_benefits # § 15-30-2337(9)(a)(i) – veterans' disability benefits + - child_support_received # § 15-30-2337(9)(a)(iv) – support money + - strike_benefits # § 15-30-2337(9)(a)(v) – nontaxable strike benefits + - general_assistance # § 15-30-2337(9)(a)(vi) – cash public assistance - mt_refundable_credits_before_renter_credit # Line 7: Refundable credits -# exclude the renter credit from the gross income computation -# due to a potential circular reference +# Social Security under § 15-30-2337(9)(a)(viii) is added separately in +# mt_elderly_homeowner_or_renter_credit_gross_household_income.py because the +# untaxed portion is computed as social_security - taxable_social_security. +# The renter credit itself is excluded to avoid a circular reference. diff --git a/policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit.yaml b/policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit.yaml index 8a9b3d29202..be8cdec579d 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit.yaml @@ -92,6 +92,70 @@ # 1000+ 9000*0.15 - (43000-12600)*0.05 = 830 # 830*10% = 83 mt_elderly_homeowner_or_renter_credit: [83, 0, 0] +- name: Multiplier uses household-aggregated gross income, not per-person + period: 2022 + input: + people: + person1: + rent: 9_000 + real_estate_taxes: 1_500 + mt_elderly_homeowner_or_renter_credit_gross_household_income: 22_000 + mt_elderly_homeowner_or_renter_credit_net_household_income: 700 + mt_elderly_homeowner_or_renter_credit_eligible: true + person2: + rent: 9_000 + real_estate_taxes: 0 + mt_elderly_homeowner_or_renter_credit_gross_household_income: 22_000 + mt_elderly_homeowner_or_renter_credit_net_household_income: 0 + mt_elderly_homeowner_or_renter_credit_eligible: true + tax_units: + tax_unit: + members: [person1, person2] + output: + # Each person's gross household income is under the $35,000 threshold + # (multiplier 1.0 per-person), but the tax-unit sum is $44,000 which + # falls in the 0.1 multiplier bracket. capped credit = $1,150 * 0.1 = $115. + mt_elderly_homeowner_or_renter_credit: [115, 0] + +- name: MT EHRC zero at exactly the $45,000 gross household income threshold + period: 2022 + input: + people: + person1: + rent: 9_000 + real_estate_taxes: 1_500 + mt_elderly_homeowner_or_renter_credit_gross_household_income: 45_000 + mt_elderly_homeowner_or_renter_credit_net_household_income: 0 + mt_elderly_homeowner_or_renter_credit_eligible: true + tax_units: + tax_unit: + members: [person1] + output: + mt_elderly_homeowner_or_renter_credit: 0 + +- name: MT EHRC denied when household income exceeds $45,000 due to SS + period: 2025 + input: + people: + head: + age: 75 + employment_income: 20_000 + taxable_interest_income: 5_280 + social_security_retirement: 51_792 + rent: 17_139 + spouse: + age: 75 + employment_income: 10_000 + tax_units: + tax_unit: + members: [head, spouse] + households: + household: + members: [head, spouse] + state_name: MT + output: + mt_elderly_homeowner_or_renter_credit: 0 + - name: Integration test period: 2022 absolute_error_margin: 0.01 diff --git a/policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit_gross_household_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit_gross_household_income.yaml new file mode 100644 index 00000000000..cee870a82af --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit_gross_household_income.yaml @@ -0,0 +1,39 @@ +- name: Statutory nontaxable income sources are counted + period: 2025 + input: + people: + person1: + age: 75 + veterans_benefits: 5_000 + child_support_received: 3_000 + strike_benefits: 2_000 + general_assistance: 1_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_name: MT + output: + # § 15-30-2337(9)(a)(i), (iv), (v), (vi). Sum: 5,000 + 3,000 + 2,000 + 1,000. + mt_elderly_homeowner_or_renter_credit_gross_household_income: 11_000 + +- name: Untaxed Social Security is fully counted in gross household income + period: 2025 + input: + people: + person1: + age: 75 + social_security_retirement: 30_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_name: MT + output: + # § 15-30-2337(9)(a)(viii) requires all SS to be counted, even the + # portion excluded from federal AGI. + mt_elderly_homeowner_or_renter_credit_gross_household_income: 30_000 diff --git a/policyengine_us/variables/gov/states/mt/tax/income/credits/mt_elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit.py b/policyengine_us/variables/gov/states/mt/tax/income/credits/mt_elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit.py index 3053a934490..d233f4ad92c 100644 --- a/policyengine_us/variables/gov/states/mt/tax/income/credits/mt_elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit.py +++ b/policyengine_us/variables/gov/states/mt/tax/income/credits/mt_elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit.py @@ -13,9 +13,13 @@ def formula(person, period, parameters): p = parameters( period ).gov.states.mt.tax.income.credits.elderly_homeowner_or_renter - gross_household_income = person( - "mt_elderly_homeowner_or_renter_credit_gross_household_income", + # § 15-30-2337(4) defines gross household income at the household + # (tax-unit) level, so the multiplier phase-out must be applied to + # the aggregated amount rather than each person's share. + gross_household_income = add( + person.tax_unit, period, + ["mt_elderly_homeowner_or_renter_credit_gross_household_income"], ) # Get net_household_income and allocate it to the head head = person("is_tax_unit_head", period) diff --git a/policyengine_us/variables/gov/states/mt/tax/income/credits/mt_elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit_gross_household_income.py b/policyengine_us/variables/gov/states/mt/tax/income/credits/mt_elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit_gross_household_income.py index fa446410695..e4a6976f246 100644 --- a/policyengine_us/variables/gov/states/mt/tax/income/credits/mt_elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit_gross_household_income.py +++ b/policyengine_us/variables/gov/states/mt/tax/income/credits/mt_elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit_gross_household_income.py @@ -8,5 +8,16 @@ class mt_elderly_homeowner_or_renter_credit_gross_household_income(Variable): unit = USD definition_period = YEAR defined_for = StateCode.MT + reference = "https://law.justia.com/codes/montana/2022/title-15/chapter-30/part-23/section-15-30-2337/" - adds = "gov.states.mt.tax.income.credits.elderly_homeowner_or_renter.gross_income_sources" + def formula(person, period, parameters): + p = parameters( + period + ).gov.states.mt.tax.income.credits.elderly_homeowner_or_renter + sources = add(person, period, p.gross_income_sources) + # AGI only captures the taxable portion of Social Security; add the + # untaxed portion so all SS is counted per § 15-30-2337(9)(a)(viii). + social_security = person("social_security", period) + taxable_social_security = person("taxable_social_security", period) + untaxed_social_security = max_(social_security - taxable_social_security, 0) + return sources + untaxed_social_security