diff --git a/changelog.d/al-misc-deduction-own-floor.fixed.md b/changelog.d/al-misc-deduction-own-floor.fixed.md new file mode 100644 index 00000000000..6fe02c6b15a --- /dev/null +++ b/changelog.d/al-misc-deduction-own-floor.fixed.md @@ -0,0 +1 @@ +Compute Alabama's miscellaneous itemized deduction from unreimbursed employee and other section 212 expenses above 2% of Alabama AGI, which Alabama kept after the federal suspension, instead of from the federal deduction. diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/tax/income/deductions/itemized/al_misc_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/tax/income/deductions/itemized/al_misc_deduction.yaml index a2de34c3f83..153c9b5355b 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/tax/income/deductions/itemized/al_misc_deduction.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/tax/income/deductions/itemized/al_misc_deduction.yaml @@ -1,20 +1,48 @@ - name: Alabama work related itemized deductions unit test 1 period: 2021 input: - misc_deduction: 2_000 + total_misc_deductions: 2_000 al_agi: 70_000 state_code: AL output: al_misc_deduction: 600 -#2000-70000*0.2=600 +#2000-70000*0.02=600 - name: Alabama work related itemized deductions unit test 2 period: 2021 input: - misc_deduction: 7_000 + total_misc_deductions: 7_000 al_agi: 30_000 state_code: AL output: al_misc_deduction: 6_400 #7000-30000*0.02=6400 + +# Ala. Code 40-18-15(a)(23); 2024 Form 40 instructions, Schedule A lines 20 to +# 24: unreimbursed employee expenses (line 20) and other expenses such as tax +# preparation fees (line 21), less 2% of Alabama AGI (line 23). The federal +# miscellaneous deduction is zero from 2018. +- name: Case 3, 2025 Alabama keeps the miscellaneous deduction the federal return suspends. + period: 2025 + input: + unreimbursed_business_employee_expenses: 3_000 + tax_preparation_fees: 500 + al_agi: 50_000 + state_code: AL + output: + misc_deduction: 0 + # 3,500 - 2% * 50,000 + al_misc_deduction: 2_500 + +- name: Case 4, 2017 only Alabama's 2% floor applies, not the federal floor as well. + period: 2017 + input: + adjusted_gross_income: 100_000 + total_misc_deductions: 5_000 + al_agi: 90_000 + state_code: AL + output: + # Federal deduction 5,000 - 2,000 = 3,000; Alabama 5,000 - 1,800. + misc_deduction: 3_000 + al_misc_deduction: 3_200 diff --git a/policyengine_us/variables/gov/states/al/tax/income/deductions/itemized/al_misc_deduction.py b/policyengine_us/variables/gov/states/al/tax/income/deductions/itemized/al_misc_deduction.py index a671f82d69c..bc1b6369e94 100644 --- a/policyengine_us/variables/gov/states/al/tax/income/deductions/itemized/al_misc_deduction.py +++ b/policyengine_us/variables/gov/states/al/tax/income/deductions/itemized/al_misc_deduction.py @@ -11,11 +11,18 @@ class al_misc_deduction(Variable): "https://law.justia.com/codes/alabama/2022/title-40/chapter-18/article-1/section-40-18-15/", # Code of Alabama Section 40-18-15, h(23) "https://www.revenue.alabama.gov/ultraviewer/viewer/basic_viewer/index.html?form=2023/01/22f40schabdc_blk.pdf#page=1", # 2022 Schedule A (Form 1040) "https://www.revenue.alabama.gov/ultraviewer/viewer/basic_viewer/index.html?form=2022/06/21f40schabdc_blk.pdf#page=1", # 2021 Schedule A (Form 1040) + # 2024 Form 40 instructions, Schedule A lines 20 to 24. + "https://www.revenue.alabama.gov/wp-content/uploads/2025/01/24f40bk.pdf#page=20", ) defined_for = StateCode.AL def formula(tax_unit, period, parameters): - misc_expense = add(tax_unit, period, ["misc_deduction"]) + # Ala. Code 40-18-15(a)(23) allows unreimbursed employee business + # expenses and section 212 expenses above 2% of Alabama AGI. Alabama + # kept this deduction after the federal suspension (26 U.S.C. 67(g)), + # so start from the expenses, not the federal misc_deduction, which is + # zero from 2018 and already net of the federal 2% floor. + misc_expense = tax_unit("total_misc_deductions", period) p = parameters(period).gov.states.al.tax.income.deductions.itemized misc_floor = p.work_related_expense_rate * tax_unit("al_agi", period) return max_(0, misc_expense - misc_floor)