diff --git a/changelog.d/fix-ut-military-retirement-credit-choice.fixed.md b/changelog.d/fix-ut-military-retirement-credit-choice.fixed.md new file mode 100644 index 00000000000..0a855d679c8 --- /dev/null +++ b/changelog.d/fix-ut-military-retirement-credit-choice.fixed.md @@ -0,0 +1 @@ +Utah's military retirement credit no longer goes unclaimed when the filer has neither a retirement credit nor a Social Security benefits credit; the retirement-credit choice now weighs the military credit alongside the Social Security credit; and the credit uses the income tax rate, as 59-10-1043 requires (4.45% in 2026), starting in 2021. diff --git a/policyengine_us/parameters/gov/states/ut/tax/income/credits/military_retirement/in_effect.yaml b/policyengine_us/parameters/gov/states/ut/tax/income/credits/military_retirement/in_effect.yaml new file mode 100644 index 00000000000..69c129cae93 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/tax/income/credits/military_retirement/in_effect.yaml @@ -0,0 +1,18 @@ +description: Utah allows the military retirement credit when this is true. +values: + 0000-01-01: false + # 59-10-1043 applies to taxable years beginning on or after January 1, 2021. + 2021-01-01: true +metadata: + unit: bool + period: year + label: Utah military retirement credit in effect + reference: + - title: Utah Code §59-10-1043 + href: https://le.utah.gov/xcode/Title59/Chapter10/59-10-S1043.html + - title: Utah Military Retirement Credit + href: https://incometax.utah.gov/credits/military-retirement + - title: 2021 Utah TC-40 Instructions, Military Retirement Credit Worksheet + href: https://files.tax.utah.gov/tax/forms/2021/tc-40inst.pdf#page=22 + - title: 2025 Utah TC-40 Instructions, Military Retirement Credit (code AJ) + href: https://files.tax.utah.gov/tax/forms/2025/tc-40inst.pdf#page=23 diff --git a/policyengine_us/parameters/gov/states/ut/tax/income/credits/military_retirement/rate.yaml b/policyengine_us/parameters/gov/states/ut/tax/income/credits/military_retirement/rate.yaml deleted file mode 100644 index f72e0bf9f0b..00000000000 --- a/policyengine_us/parameters/gov/states/ut/tax/income/credits/military_retirement/rate.yaml +++ /dev/null @@ -1,26 +0,0 @@ -description: Utah military retirement credit rate applied to taxable military retirement pay. -values: - 2021-01-01: 0.0495 - 2022-01-01: 0.0485 - 2023-01-01: 0.0465 - 2024-01-01: 0.0455 - 2025-01-01: 0.045 -metadata: - unit: /1 - period: year - label: Utah military retirement credit rate - reference: - - title: Utah Code §59-10-1043 - href: https://le.utah.gov/xcode/Title59/Chapter10/59-10-S1043.html - - title: Utah Military Retirement Credit - href: https://incometax.utah.gov/credits/military-retirement - - title: 2021 Utah TC-40 Instructions, Military Retirement Credit Worksheet - href: https://files.tax.utah.gov/tax/forms/2021/tc-40inst.pdf#page=22 - - title: 2022 Utah TC-40 Instructions, Military Retirement Credit Worksheet - href: https://files.tax.utah.gov/tax/forms/2022/tc-40inst.pdf#page=22 - - title: 2023 Utah TC-40 Instructions, Military Retirement Credit Worksheet - href: https://files.tax.utah.gov/tax/forms/2023/tc-40inst.pdf#page=23 - - title: 2024 Utah TC-40 Instructions, Military Retirement Credit Worksheet - href: https://tax.utah.gov/forms/current/tc-40inst.pdf#page=23 - - title: 2025 Utah TC-40 Instructions, Military Retirement Credit Worksheet - href: https://files.tax.utah.gov/tax/forms/2025/tc-40inst.pdf#page=24 diff --git a/policyengine_us/tests/core/test_dependent_retirement_income_state_invariants.py b/policyengine_us/tests/core/test_dependent_retirement_income_state_invariants.py index 49595f2d791..a399dbaa23d 100644 --- a/policyengine_us/tests/core/test_dependent_retirement_income_state_invariants.py +++ b/policyengine_us/tests/core/test_dependent_retirement_income_state_invariants.py @@ -452,9 +452,9 @@ def test_dependents_retirement_income_never_reduces_state_income_tax(year): assert (unit_has_dependent_income & filer_social_security).any() assert (unit_has_dependent_income & filer_aged_73).any() assert (unit_has_dependent_income & elderly_dependent).any() - # Utah's military retirement credit is open only when the retirement - # credit is not claimed, which needs Social Security worth more than the - # age-gated retirement credit. + # Utah's military retirement credit is open only when the filer does not + # claim the retirement credit: when that credit is worth nothing, or less + # than the Social Security and military retirement credits together. dependent_military_pay = np.tile( [any(d["income"]["military_retirement_pay"] > 0 for d in u["dependents"]) for u in units], diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/tax/income/credits/military_retirement_credit/ut_military_retirement_credit.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/tax/income/credits/military_retirement_credit/ut_military_retirement_credit.yaml index 8902bd5b6ad..4ac71fab495 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ut/tax/income/credits/military_retirement_credit/ut_military_retirement_credit.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/tax/income/credits/military_retirement_credit/ut_military_retirement_credit.yaml @@ -98,3 +98,45 @@ state_code: UT output: ut_military_retirement_credit: 1350 + +- name: UT military retirement credit - retiree too young for the retirement credit gets the military credit + period: 2025 + input: + people: + person1: + age: 45 + military_retirement_pay: 30_000 + tax_units: + tax_unit: + members: [person1] + ut_income_tax_before_non_refundable_credits: 1_000_000 + households: + household: + members: [person1] + state_code: UT + output: + ut_claims_retirement_credit: false + ut_military_retirement_credit_eligible: true + ut_military_retirement_credit: 1_350 + +- name: UT military retirement credit - older retiree with little military pay takes the retirement credit instead + period: 2025 + input: + people: + person1: + age: 76 + military_retirement_pay: 4_000 + tax_units: + tax_unit: + members: [person1] + ut_income_tax_before_non_refundable_credits: 1_000_000 + households: + household: + members: [person1] + state_code: UT + output: + ut_retirement_credit_max: 450 + ut_military_retirement_credit_max: 180 + ut_claims_retirement_credit: true + ut_military_retirement_credit_eligible: false + ut_military_retirement_credit: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/tax/income/credits/military_retirement_credit/ut_military_retirement_credit_max.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/tax/income/credits/military_retirement_credit/ut_military_retirement_credit_max.yaml new file mode 100644 index 00000000000..f62fe9068b0 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/tax/income/credits/military_retirement_credit/ut_military_retirement_credit_max.yaml @@ -0,0 +1,63 @@ +- name: UT military retirement credit maximum - 4.5% of military retirement pay in 2025 + period: 2025 + input: + people: + person1: + military_retirement_pay: 30_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: UT + output: + ut_military_retirement_credit_max: 1_350 + +- name: UT military retirement credit maximum - survivor benefits count as military retirement pay + period: 2025 + input: + people: + person1: + military_retirement_pay_survivors: 10_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: UT + output: + ut_military_retirement_credit_max: 450 + +- name: UT military retirement credit maximum - none before the credit took effect in 2021 + period: 2020 + input: + people: + person1: + military_retirement_pay: 30_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: UT + output: + ut_military_retirement_credit_max: 0 + +- name: UT military retirement credit maximum - follows the 4.45% income tax rate in 2026 + period: 2026 + input: + people: + person1: + military_retirement_pay: 30_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: UT + output: + ut_military_retirement_credit_max: 1_335 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/tax/income/credits/retirement_credit/ut_claims_retirement_credit.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/tax/income/credits/retirement_credit/ut_claims_retirement_credit.yaml index b6bc3cf82c4..afa1f905fce 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ut/tax/income/credits/retirement_credit/ut_claims_retirement_credit.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/tax/income/credits/retirement_credit/ut_claims_retirement_credit.yaml @@ -25,11 +25,41 @@ output: ut_claims_retirement_credit: true -- name: UT claims retirement credit unit test 4 +- name: UT claims retirement credit unit test 4 - a retirement credit worth nothing is never claimed period: 2022 input: ut_retirement_credit_max: 0 ut_ss_benefits_credit_max: 0 state_code: UT + output: + ut_claims_retirement_credit: false + +- name: UT claims retirement credit - military credit alone outweighs the retirement credit + period: 2025 + input: + ut_retirement_credit_max: 450 + ut_ss_benefits_credit_max: 0 + ut_military_retirement_credit_max: 1_350 + state_code: UT + output: + ut_claims_retirement_credit: false + +- name: UT claims retirement credit - Social Security and military credits combine against the retirement credit + period: 2025 + input: + ut_retirement_credit_max: 450 + ut_ss_benefits_credit_max: 300 + ut_military_retirement_credit_max: 200 + state_code: UT + output: + ut_claims_retirement_credit: false + +- name: UT claims retirement credit - retirement credit outweighs both alternatives combined + period: 2025 + input: + ut_retirement_credit_max: 450 + ut_ss_benefits_credit_max: 100 + ut_military_retirement_credit_max: 225 + state_code: UT output: ut_claims_retirement_credit: true diff --git a/policyengine_us/variables/gov/states/ut/tax/income/credits/military_retirement_credit/ut_military_retirement_credit_max.py b/policyengine_us/variables/gov/states/ut/tax/income/credits/military_retirement_credit/ut_military_retirement_credit_max.py new file mode 100644 index 00000000000..dfef909fbe3 --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/tax/income/credits/military_retirement_credit/ut_military_retirement_credit_max.py @@ -0,0 +1,26 @@ +from policyengine_us.model_api import * + + +class ut_military_retirement_credit_max(Variable): + value_type = float + entity = TaxUnit + label = "Utah military retirement credit maximum amount" + unit = USD + definition_period = YEAR + reference = "https://le.utah.gov/xcode/Title59/Chapter10/59-10-S1043.html" + defined_for = StateCode.UT + + def formula(tax_unit, period, parameters): + # 59-10-1043(2)(b): only the pay included in adjusted gross income on + # the claimant's federal return, which excludes dependents' income; + # dependents report it on their own return. + military_retirement_pay = tax_unit_non_dep_add( + tax_unit, + period, + ["military_retirement_income"], + ) + # 59-10-1043(2)(a): the percentage listed in 59-10-104(2), the + # income tax rate. + p = parameters(period).gov.states.ut.tax.income + in_effect = p.credits.military_retirement.in_effect + return in_effect * military_retirement_pay * p.rate diff --git a/policyengine_us/variables/gov/states/ut/tax/income/credits/military_retirement_credit/ut_military_retirement_credit_potential.py b/policyengine_us/variables/gov/states/ut/tax/income/credits/military_retirement_credit/ut_military_retirement_credit_potential.py index 011e94faa60..545d873d72f 100644 --- a/policyengine_us/variables/gov/states/ut/tax/income/credits/military_retirement_credit/ut_military_retirement_credit_potential.py +++ b/policyengine_us/variables/gov/states/ut/tax/income/credits/military_retirement_credit/ut_military_retirement_credit_potential.py @@ -10,15 +10,4 @@ class ut_military_retirement_credit_potential(Variable): reference = "https://le.utah.gov/xcode/Title59/Chapter10/59-10-S1043.html" defined_for = "ut_military_retirement_credit_eligible" - def formula(tax_unit, period, parameters): - # 59-10-1043(2)(b): only the pay included in adjusted gross income on - # the claimant's federal return, which excludes dependents' income; - # dependents report it on their own return. - military_retirement_pay = tax_unit_non_dep_add( - tax_unit, - period, - ["military_retirement_income"], - ) - - p = parameters(period).gov.states.ut.tax.income.credits.military_retirement - return military_retirement_pay * p.rate + adds = ["ut_military_retirement_credit_max"] diff --git a/policyengine_us/variables/gov/states/ut/tax/income/credits/retirement_credit/ut_claims_retirement_credit.py b/policyengine_us/variables/gov/states/ut/tax/income/credits/retirement_credit/ut_claims_retirement_credit.py index c5ada7d2d58..f400862dc62 100644 --- a/policyengine_us/variables/gov/states/ut/tax/income/credits/retirement_credit/ut_claims_retirement_credit.py +++ b/policyengine_us/variables/gov/states/ut/tax/income/credits/retirement_credit/ut_claims_retirement_credit.py @@ -6,11 +6,33 @@ class ut_claims_retirement_credit(Variable): entity = TaxUnit label = "claims the Utah retirement credit" unit = USD - documentation = "Utah residents can claim only one of the retirement credit or the social security benefits credit. We assume they claim the one with higher value." + documentation = ( + "A Utah filer who claims the retirement credit cannot also claim the " + "Social Security benefits credit or the military retirement credit, " + "but can claim those two together. We assume the filer takes whichever " + "option is worth more, and never claims a retirement credit worth " + "nothing." + ) + reference = ( + # Each section's subsection (3)(b) bars its credit alongside the + # retirement credit; nothing bars 59-10-1042 with 59-10-1043. + "https://le.utah.gov/xcode/Title59/Chapter10/59-10-S1019.html", + "https://le.utah.gov/xcode/Title59/Chapter10/59-10-S1042.html", + "https://le.utah.gov/xcode/Title59/Chapter10/59-10-S1043.html", + "https://files.tax.utah.gov/tax/forms/2025/tc-40inst.pdf#page=21", + "https://files.tax.utah.gov/tax/forms/2025/tc-40inst.pdf#page=23", + ) definition_period = YEAR defined_for = StateCode.UT def formula(tax_unit, period, parameters): - max_retirement_credit = tax_unit("ut_retirement_credit_max", period) - max_ss_benefits_credit = tax_unit("ut_ss_benefits_credit_max", period) - return max_retirement_credit >= max_ss_benefits_credit + retirement_credit = tax_unit("ut_retirement_credit_max", period) + # The Social Security benefits credit and the military retirement + # credit can be claimed together, so the retirement credit competes + # with their sum. + alternative_credits = add( + tax_unit, + period, + ["ut_ss_benefits_credit_max", "ut_military_retirement_credit_max"], + ) + return (retirement_credit > 0) & (retirement_credit >= alternative_credits)