diff --git a/changelog.d/fix-mi-disabled-veteran-exemption.fixed.md b/changelog.d/fix-mi-disabled-veteran-exemption.fixed.md new file mode 100644 index 00000000000..6f3408cb8ad --- /dev/null +++ b/changelog.d/fix-mi-disabled-veteran-exemption.fixed.md @@ -0,0 +1 @@ +Give Michigan's qualified disabled veteran exemption to every veteran with a service-connected disability, at any rating, as MCL 206.30(3)(b) does, through a new `has_service_connected_disability` input; the home heating credit's exemption count follows. diff --git a/policyengine_us/parameters/gov/states/mi/tax/income/exemptions/disabled/amount/veteran.yaml b/policyengine_us/parameters/gov/states/mi/tax/income/exemptions/disabled/amount/veteran.yaml index c90677f6c72..a968f4eb64f 100644 --- a/policyengine_us/parameters/gov/states/mi/tax/income/exemptions/disabled/amount/veteran.yaml +++ b/policyengine_us/parameters/gov/states/mi/tax/income/exemptions/disabled/amount/veteran.yaml @@ -1,4 +1,4 @@ -description: Michigan provides this exemption amount for each disabled veteran in the household. +description: Michigan provides this exemption amount for each qualified disabled veteran in the household, a veteran with a service-connected disability at any rating. values: # Law specifies $250 as of 2008. # Tax guide specifies $400 since 2017. @@ -22,5 +22,7 @@ metadata: href: https://www.michigan.gov/taxes/-/media/Project/Websites/taxes/Forms/IIT/TY2023/BOOK_MI-1040.pdf#page=3 - title: Michigan 2024 Individual Income Tax Instructions href: https://www.michigan.gov/taxes/-/media/Project/Websites/taxes/Forms/IIT/TY2024/MI-1040-Instructions.pdf#page=3 + - title: Michigan 2025 Individual Income Tax Instructions, line 9c + href: https://www.michigan.gov/taxes/-/media/Project/Websites/taxes/Forms/IIT/TY2025/MI-1040-Book.pdf#page=10 - title: Michigan 2025 Income Tax Withholding Guide (Form 446) href: https://www.michigan.gov/taxes/-/media/Project/Websites/taxes/Forms/SUW/TY2025/446_Withholding-Guide_2025.pdf#page=2 diff --git a/policyengine_us/tests/core/test_state_tax_head_spouse_swap_invariance.py b/policyengine_us/tests/core/test_state_tax_head_spouse_swap_invariance.py index 71b4b936235..703eadaf71f 100644 --- a/policyengine_us/tests/core/test_state_tax_head_spouse_swap_invariance.py +++ b/policyengine_us/tests/core/test_state_tax_head_spouse_swap_invariance.py @@ -116,6 +116,7 @@ def adults(draw): "pre_subsidy_care_expenses": draw(money(6_000)), "social_security_survivors": draw(money(20_000)), "is_fully_disabled_service_connected_veteran": draw(st.booleans()), + "has_service_connected_disability": draw(st.booleans()), } @@ -190,6 +191,7 @@ def signed(low, high, p): "pre_subsidy_care_expenses": some(6_000, 0.05), "social_security_survivors": some(20_000, 0.05 if age >= 55 else 0.0), "is_fully_disabled_service_connected_veteran": bool(rng.random() < 0.03), + "has_service_connected_disability": bool(rng.random() < 0.05), } diff --git a/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/exemptions/mi_exemptions.yaml b/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/exemptions/mi_exemptions.yaml index e67f331c532..6164f142871 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/exemptions/mi_exemptions.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/exemptions/mi_exemptions.yaml @@ -534,3 +534,73 @@ output: # $1,500 claimable-filer allowance + $5,800 for their child. mi_exemptions: 7_300 + +- name: 2026 veteran with a partial service-connected disability rating gets the qualified disabled veteran exemption + period: 2026 + input: + people: + person1: + has_service_connected_disability: true + is_fully_disabled_service_connected_veteran: false + tax_units: + tax_unit: + mi_personal_exemptions: 5_900 + members: [person1] + household: + members: [person1] + state_code: MI + output: + # MCL 206.30(3)(b) and MI-1040 line 9c: $5,900 personal + $500 qualified disabled veteran. + mi_exemptions: 6_400 + +- name: 2026 fully disabled service-connected veteran gets the exemption once + period: 2026 + input: + people: + person1: + is_fully_disabled_service_connected_veteran: true + tax_units: + tax_unit: + mi_personal_exemptions: 5_900 + members: [person1] + household: + members: [person1] + state_code: MI + output: + mi_exemptions: 6_400 + +- name: 2026 joint return where each spouse has a service-connected disability + period: 2026 + input: + people: + person1: + has_service_connected_disability: true + person2: + has_service_connected_disability: true + tax_units: + tax_unit: + mi_personal_exemptions: 11_800 + members: [person1, person2] + household: + members: [person1, person2] + state_code: MI + output: + # $11,800 personal + 2 x $500 qualified disabled veteran. + mi_exemptions: 12_800 + +- name: 2026 veteran without a service-connected disability gets no veteran exemption + period: 2026 + input: + people: + person1: + has_service_connected_disability: false + veterans_benefits: 1_000 + tax_units: + tax_unit: + mi_personal_exemptions: 5_900 + members: [person1] + household: + members: [person1] + state_code: MI + output: + mi_exemptions: 5_900 diff --git a/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/exemptions/mi_exemptions_count.yaml b/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/exemptions/mi_exemptions_count.yaml index 63fc17ccc64..c3e74f723c9 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/exemptions/mi_exemptions_count.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/exemptions/mi_exemptions_count.yaml @@ -56,3 +56,22 @@ state_code: MI output: # 6 + 0 mi_exemptions_count: 6 + +- name: 2026 a veteran with a partial service-connected disability rating adds an exemption to the count + period: 2026 + input: + people: + person1: + mi_disabled_exemption_eligible_person: false + has_service_connected_disability: true + person2: + mi_disabled_exemption_eligible_person: false + has_service_connected_disability: false + tax_units: + tax_unit: + members: [person1, person2] + household: + members: [person1, person2] + state_code: MI + output: # 2 people + 1 qualified disabled veteran + mi_exemptions_count: 3 diff --git a/policyengine_us/tests/policy/baseline/household/demographic/person/has_service_connected_disability.yaml b/policyengine_us/tests/policy/baseline/household/demographic/person/has_service_connected_disability.yaml new file mode 100644 index 00000000000..62b800904c2 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/household/demographic/person/has_service_connected_disability.yaml @@ -0,0 +1,21 @@ +- name: A fully disabled service-connected veteran has a service-connected disability. + period: 2026 + input: + is_fully_disabled_service_connected_veteran: true + output: + has_service_connected_disability: true + +- name: Without either input, the person has no service-connected disability. + period: 2026 + input: + is_fully_disabled_service_connected_veteran: false + output: + has_service_connected_disability: false + +- name: A veteran with a partial rating sets the input directly. + period: 2026 + input: + is_fully_disabled_service_connected_veteran: false + has_service_connected_disability: true + output: + has_service_connected_disability: true diff --git a/policyengine_us/variables/gov/states/mi/tax/income/exemptions/mi_exemptions.py b/policyengine_us/variables/gov/states/mi/tax/income/exemptions/mi_exemptions.py index 7c9874052ea..cff54598ebc 100644 --- a/policyengine_us/variables/gov/states/mi/tax/income/exemptions/mi_exemptions.py +++ b/policyengine_us/variables/gov/states/mi/tax/income/exemptions/mi_exemptions.py @@ -27,10 +27,9 @@ def formula(tax_unit, period, parameters): ) disabled_exemption = disabled_people * p.disabled.amount.base - # Disabled veteran exemptions - disabled_veterans = add( - tax_unit, period, ["is_fully_disabled_service_connected_veteran"] - ) + # MCL 206.30(3)(b): each qualified disabled veteran, a veteran with + # a service-connected disability at any rating, adds an exemption. + disabled_veterans = add(tax_unit, period, ["has_service_connected_disability"]) disabled_veteran_exemption = disabled_veterans * p.disabled.amount.veteran # MCL 206.30(4): an individual who can be claimed as a dependent on diff --git a/policyengine_us/variables/gov/states/mi/tax/income/exemptions/mi_exemptions_count.py b/policyengine_us/variables/gov/states/mi/tax/income/exemptions/mi_exemptions_count.py index bc7bcd2dba7..c15a0c89a12 100644 --- a/policyengine_us/variables/gov/states/mi/tax/income/exemptions/mi_exemptions_count.py +++ b/policyengine_us/variables/gov/states/mi/tax/income/exemptions/mi_exemptions_count.py @@ -17,5 +17,5 @@ class mi_exemptions_count(Variable): adds = [ "tax_unit_size", "mi_disabled_exemption_eligible_person", - "is_fully_disabled_service_connected_veteran", + "has_service_connected_disability", ] diff --git a/policyengine_us/variables/household/demographic/person/has_service_connected_disability.py b/policyengine_us/variables/household/demographic/person/has_service_connected_disability.py new file mode 100644 index 00000000000..3b19cb8c2c2 --- /dev/null +++ b/policyengine_us/variables/household/demographic/person/has_service_connected_disability.py @@ -0,0 +1,20 @@ +from policyengine_us.model_api import * + + +class has_service_connected_disability(Variable): + value_type = bool + entity = Person + label = "Is a veteran with a service-connected disability" + documentation = ( + "Whether the person is a veteran with a disability incurred or " + "aggravated in the line of duty in the active military, naval, air, " + "or space service (38 U.S.C. 101(16)), at any disability rating. " + "Defaults to is_fully_disabled_service_connected_veteran, since a " + "fully disabled service-connected veteran has such a disability; set " + "it to true for a veteran with a partial rating." + ) + definition_period = YEAR + reference = "https://www.law.cornell.edu/uscode/text/38/101#16" + + def formula(person, period, parameters): + return person("is_fully_disabled_service_connected_veteran", period)