From 5404c2559f5202f802a6ac2387e5c074f7377cd8 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 3 Nov 2026 21:56:32 +0000 Subject: [PATCH 1/4] Weigh NJ refundable credits in the property tax election; base NE itemized deductions on federal SALT as claimed New Jersey: the deduction-or-credit choice compared only the tax saving with the $50 credit, but the deduction also lowers NJ taxable income, which sets the refundable NJ child tax credit and the NJ child and dependent care credit. A filer just above $30,000 kept the $50 credit and lost a $200 child tax credit increase. The choice now counts those credit changes. The child count moves to nj_ctc_qualifying_children so both formulas share it. Nebraska: itemized deductions added real estate taxes capped by the static SALT cap to the non-SALT deductions. That dropped sales taxes claimed on Schedule A and, from 2025, could exceed the federal SALT deduction after the cap phase-down. They now start from the federal SALT deduction and remove only the income taxes in it, counting real estate taxes first. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01LwQq6L5ENJPWh7rPevAeE7 --- changelog.d/state-choice-bugs-nj-ne.fixed.md | 1 + .../deductions/ne_itemized_deductions.yaml | 82 +++++++++++++ .../nj_taking_property_tax_deduction.yaml | 109 ++++++++++++++++++ .../deductions/ne_itemized_deductions.py | 26 ++++- .../nj/tax/income/credits/ctc/nj_ctc.py | 7 +- .../credits/ctc/nj_ctc_qualifying_children.py | 21 ++++ .../nj_taking_property_tax_deduction.py | 28 ++++- 7 files changed, 264 insertions(+), 10 deletions(-) create mode 100644 changelog.d/state-choice-bugs-nj-ne.fixed.md create mode 100644 policyengine_us/variables/gov/states/nj/tax/income/credits/ctc/nj_ctc_qualifying_children.py diff --git a/changelog.d/state-choice-bugs-nj-ne.fixed.md b/changelog.d/state-choice-bugs-nj-ne.fixed.md new file mode 100644 index 00000000000..a44908e4e91 --- /dev/null +++ b/changelog.d/state-choice-bugs-nj-ne.fixed.md @@ -0,0 +1 @@ +New Jersey now weighs the change in its refundable child tax credit and child and dependent care credit when choosing between the property tax deduction and the $50 credit, and Nebraska itemized deductions now start from the federal SALT deduction as claimed, removing only the income taxes in it. diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/tax/income/deductions/ne_itemized_deductions.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/tax/income/deductions/ne_itemized_deductions.yaml index e11a586976d..fde3be8209e 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ne/tax/income/deductions/ne_itemized_deductions.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/tax/income/deductions/ne_itemized_deductions.yaml @@ -6,6 +6,11 @@ deductible_interest_expense: 24_000 salt_deduction: 10_000 real_estate_taxes: 9_000 + # Income taxes are claimed on Schedule A. + state_withheld_income_tax: 5_000 + local_income_tax: 0 + state_sales_tax: 0 + local_sales_tax: 0 state_code: NE output: ne_itemized_deductions: 2_000 + 24_000 + 9_000 @@ -18,6 +23,83 @@ deductible_interest_expense: 7_000 salt_deduction: 10_000 real_estate_taxes: 6_000 + # Income taxes are claimed on Schedule A. + state_withheld_income_tax: 5_000 + local_income_tax: 0 + state_sales_tax: 0 + local_sales_tax: 0 state_code: NE output: ne_itemized_deductions: 3_000 + 7_000 + 6_000 + +- name: Sales taxes claimed on Schedule A stay in the Nebraska deduction + # Federal itemized: 15,000 other + 8,000 SALT (sales taxes 3,000 exceed + # income taxes 1,000, so sales taxes are claimed) = 23,000. No income taxes + # are claimed, so Nebraska subtracts nothing. + period: 2023 + input: + filing_status: SINGLE + itemized_deductions_less_salt: 15_000 + salt_deduction: 8_000 + real_estate_taxes: 5_000 + state_withheld_income_tax: 1_000 + local_income_tax: 0 + state_sales_tax: 3_000 + local_sales_tax: 0 + state_code: NE + output: + ne_itemized_deductions: 23_000 + +- name: Income taxes claimed on Schedule A are removed from the Nebraska deduction + # Federal SALT 7,000 = 2,000 income taxes + 5,000 real estate taxes. + # Nebraska: 15,000 + 7,000 - 2,000 = 20,000. + period: 2023 + input: + filing_status: SINGLE + itemized_deductions_less_salt: 15_000 + salt_deduction: 7_000 + real_estate_taxes: 5_000 + state_withheld_income_tax: 2_000 + local_income_tax: 0 + state_sales_tax: 500 + local_sales_tax: 0 + state_code: NE + output: + ne_itemized_deductions: 20_000 + +- name: Real estate taxes count only up to the SALT deduction claimed federally + # 2025: the federal SALT cap has phased down to 10,000, so Schedule A + # claims 10,000 of the 35,000 income taxes and 30,000 real estate taxes. + # Real estate taxes count first, so no income taxes are claimed and + # Nebraska keeps the full 10,000: 15,000 + 10,000 = 25,000, never more + # than the 25,000 federal total. + period: 2025 + input: + filing_status: SINGLE + itemized_deductions_less_salt: 15_000 + salt_deduction: 10_000 + real_estate_taxes: 30_000 + state_withheld_income_tax: 35_000 + local_income_tax: 0 + state_sales_tax: 0 + local_sales_tax: 0 + state_code: NE + output: + ne_itemized_deductions: 25_000 + +- name: Income taxes above real estate taxes take the rest of the capped SALT deduction + # Federal SALT capped at 10,000: real estate taxes 4,000 count first, the + # other 6,000 is income taxes. Nebraska: 15,000 + 10,000 - 6,000 = 19,000. + period: 2023 + input: + filing_status: SINGLE + itemized_deductions_less_salt: 15_000 + salt_deduction: 10_000 + real_estate_taxes: 4_000 + state_withheld_income_tax: 12_000 + local_income_tax: 0 + state_sales_tax: 1_000 + local_sales_tax: 0 + state_code: NE + output: + ne_itemized_deductions: 19_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/deductions/property_tax/nj_taking_property_tax_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/deductions/property_tax/nj_taking_property_tax_deduction.yaml index 5615c00bc86..0da96737e36 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/deductions/property_tax/nj_taking_property_tax_deduction.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/deductions/property_tax/nj_taking_property_tax_deduction.yaml @@ -33,3 +33,112 @@ state_code: NJ output: nj_taking_property_tax_deduction: false + +- name: Deduction that moves taxable income into a higher NJ child tax credit bracket beats the $50 credit + # 2023 single rates: 1.4% to $20,000, 1.75% from $20,000 to $35,000. + # Tax on $30,500 = 280 + 10,500 x 1.75% = 463.75; on $27,800 = 280 + + # 7,800 x 1.75% = 416.50; saving 47.25 is below the $50 credit. + # The NJ child tax credit rises from $800 (over $30,000) to $1,000 (up to + # $30,000) for the one child: 47.25 + 200 = 247.25 > 50. + period: 2023 + absolute_error_margin: 0 + input: + people: + parent: + age: 35 + child: + age: 3 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [parent, child] + filing_status: SINGLE + nj_property_tax_deduction_eligible: true + nj_potential_property_tax_deduction: 2_700 + nj_taxable_income_before_property_tax_deduction: 30_500 + cdcc: 0 + households: + household: + members: [parent, child] + state_code: NJ + output: + nj_ctc_qualifying_children: 1 + nj_taking_property_tax_deduction: true + +- name: Same tax saving without a qualifying child keeps the $50 credit + period: 2023 + absolute_error_margin: 0 + input: + nj_property_tax_deduction_eligible: true + nj_potential_property_tax_deduction: 2_700 + nj_taxable_income_before_property_tax_deduction: 30_500 + filing_status: SINGLE + cdcc: 0 + state_code: NJ + output: + nj_taking_property_tax_deduction: false + +- name: Deduction that raises the NJ child and dependent care credit rate beats the $50 credit + # Tax saving: (30,500 - 28,500) x 1.75% = 35. The NJ CDCC match rate rises + # from 40% (over $30,000) to 50% (up to $30,000) of the $600 federal + # credit: 35 + 60 = 95 > 50. + period: 2023 + absolute_error_margin: 0 + input: + nj_property_tax_deduction_eligible: true + nj_potential_property_tax_deduction: 2_000 + nj_taxable_income_before_property_tax_deduction: 30_500 + filing_status: SINGLE + cdcc: 600 + state_code: NJ + output: + nj_taking_property_tax_deduction: true + +- name: A small NJ child and dependent care credit gain does not beat the $50 credit + # 35 tax saving + 10% x $100 federal credit = 45 < 50. + period: 2023 + absolute_error_margin: 0 + input: + nj_property_tax_deduction_eligible: true + nj_potential_property_tax_deduction: 2_000 + nj_taxable_income_before_property_tax_deduction: 30_500 + filing_status: SINGLE + cdcc: 100 + state_code: NJ + output: + nj_taking_property_tax_deduction: false + +- name: Renter with one child takes the deduction and gets the higher NJ child tax credit + # Wages $33,000 less $2,500 exemptions (1,000 personal + 1,500 dependent) + # = $30,500. Property tax: 18% x $15,000 rent = $2,700. Taking the + # deduction gives $27,800 taxable income, $416.50 tax and a $1,000 NJ + # child tax credit; the credit route gives $463.75 tax, an $800 child tax + # credit and the $50 property tax credit. + period: 2023 + absolute_error_margin: 0.01 + input: + people: + parent: + age: 35 + employment_income: 33_000 + rent: 15_000 + child: + age: 3 + tax_units: + tax_unit: + members: [parent, child] + spm_units: + spm_unit: + members: [parent, child] + households: + household: + members: [parent, child] + state_code: NJ + output: + nj_taxable_income_before_property_tax_deduction: 30_500 + nj_potential_property_tax_deduction: 2_700 + nj_taking_property_tax_deduction: true + nj_taxable_income: 27_800 + nj_main_income_tax: 416.50 + nj_ctc: 1_000 + nj_property_tax_credit: 0 diff --git a/policyengine_us/variables/gov/states/ne/tax/income/deductions/ne_itemized_deductions.py b/policyengine_us/variables/gov/states/ne/tax/income/deductions/ne_itemized_deductions.py index 6205c08b1d3..fb986cb5d33 100644 --- a/policyengine_us/variables/gov/states/ne/tax/income/deductions/ne_itemized_deductions.py +++ b/policyengine_us/variables/gov/states/ne/tax/income/deductions/ne_itemized_deductions.py @@ -10,10 +10,32 @@ class ne_itemized_deductions(Variable): reference = ( "https://revenue.nebraska.gov/files/doc/tax-forms/2021/f_1040n_booklet.pdf", "https://revenue.nebraska.gov/files/doc/2022_Ne_Individual_Income_Tax_Booklet_8-307-2022_final_5.pdf", + "https://nebraskalegislature.gov/laws/statutes.php?statute=77-2716", ) defined_for = StateCode.NE def formula(tax_unit, period, parameters): + # Nebraska allows federal itemized deductions minus the state and + # local income taxes claimed on federal Schedule A (see the Form + # 1040N booklet quoted in ne_taxable_income). itm_deds_less_salt = tax_unit("itemized_deductions_less_salt", period) - capped_property_taxes = tax_unit("capped_property_taxes", period) - return itm_deds_less_salt + capped_property_taxes + # The SALT deduction as claimed federally, after the federal cap. + federal_salt = tax_unit("salt_deduction", period) + # Schedule A claims either income taxes or sales taxes, whichever is + # larger (state_and_local_sales_or_income_tax). Sales taxes stay in + # the Nebraska deduction. + income_taxes = add( + tax_unit, period, ["state_withheld_income_tax", "local_income_tax"] + ) + sales_taxes = add(tax_unit, period, ["state_sales_tax", "local_sales_tax"]) + claims_income_taxes = income_taxes > sales_taxes + # When income taxes are claimed, real estate taxes count first toward + # the capped federal SALT deduction, so the income taxes removed are + # the rest of it. + real_estate_taxes = add(tax_unit, period, ["real_estate_taxes"]) + salt_kept = where( + claims_income_taxes, + min_(federal_salt, real_estate_taxes), + federal_salt, + ) + return itm_deds_less_salt + salt_kept diff --git a/policyengine_us/variables/gov/states/nj/tax/income/credits/ctc/nj_ctc.py b/policyengine_us/variables/gov/states/nj/tax/income/credits/ctc/nj_ctc.py index ad5080093f3..f700c038d1a 100644 --- a/policyengine_us/variables/gov/states/nj/tax/income/credits/ctc/nj_ctc.py +++ b/policyengine_us/variables/gov/states/nj/tax/income/credits/ctc/nj_ctc.py @@ -22,12 +22,7 @@ def formula(tax_unit, period, parameters): taxable_income = tax_unit("nj_taxable_income", period) amount_per_qualifying_child = p.amount.calc(taxable_income) - # Get the number of eligible children dependents - person = tax_unit.members - age_eligible = person("age", period) < p.age_limit - dependent = person("is_tax_unit_dependent", period) - age_eligible_dependent = age_eligible & dependent - count_eligible = tax_unit.sum(age_eligible_dependent) + count_eligible = tax_unit("nj_ctc_qualifying_children", period) # Calculate total child tax credit return count_eligible * amount_per_qualifying_child diff --git a/policyengine_us/variables/gov/states/nj/tax/income/credits/ctc/nj_ctc_qualifying_children.py b/policyengine_us/variables/gov/states/nj/tax/income/credits/ctc/nj_ctc_qualifying_children.py new file mode 100644 index 00000000000..272566104ab --- /dev/null +++ b/policyengine_us/variables/gov/states/nj/tax/income/credits/ctc/nj_ctc_qualifying_children.py @@ -0,0 +1,21 @@ +from policyengine_us.model_api import * + + +class nj_ctc_qualifying_children(Variable): + value_type = int + entity = TaxUnit + label = "New Jersey child tax credit qualifying children" + unit = "child" + definition_period = YEAR + reference = ( + "https://law.justia.com/codes/new-jersey/2022/title-54a/section-54a-4-17-1/", + "https://www.state.nj.us/treasury/taxation/pdf/current/1040i.pdf#page=46", + ) + defined_for = StateCode.NJ + + def formula(tax_unit, period, parameters): + p = parameters(period).gov.states.nj.tax.income.credits.ctc + person = tax_unit.members + age_eligible = person("age", period) < p.age_limit + dependent = person("is_tax_unit_dependent", period) + return tax_unit.sum(age_eligible & dependent) diff --git a/policyengine_us/variables/gov/states/nj/tax/income/property_tax/nj_taking_property_tax_deduction.py b/policyengine_us/variables/gov/states/nj/tax/income/property_tax/nj_taking_property_tax_deduction.py index 9bda5c4618b..6fc5cc3fa8e 100644 --- a/policyengine_us/variables/gov/states/nj/tax/income/property_tax/nj_taking_property_tax_deduction.py +++ b/policyengine_us/variables/gov/states/nj/tax/income/property_tax/nj_taking_property_tax_deduction.py @@ -8,7 +8,11 @@ class nj_taking_property_tax_deduction(Variable): unit = USD definition_period = YEAR reference = ( - "https://law.justia.com/codes/new-jersey/2022/title-54a/section-54a-3a-17/" + "https://law.justia.com/codes/new-jersey/2022/title-54a/section-54a-3a-17/", + # The NJ child tax credit and the NJ child and dependent care credit + # are refundable and both depend on NJ taxable income. + "https://law.justia.com/codes/new-jersey/2022/title-54a/section-54a-4-17-1/", + "https://www.state.nj.us/treasury/taxation/pdf/current/1040i.pdf#page=46", ) defined_for = "nj_property_tax_deduction_eligible" @@ -70,5 +74,25 @@ def formula(tax_unit, period, parameters): cohabitating = tax_unit("cohabitating_spouses", period) credit_amount = credit_amount / (1 + separate * cohabitating) + # The deduction also lowers NJ taxable income for the refundable NJ + # child tax credit and NJ child and dependent care credit, whose + # amounts depend on it, so its benefit includes their change. + p_credits = parameters(period).gov.states.nj.tax.income.credits + ctc_children = tax_unit("nj_ctc_qualifying_children", period) * tax_unit( + "nj_ctc_eligible", period + ) + ctc_gain = ctc_children * ( + p_credits.ctc.amount.calc(taxable_income_after_deduction) + - p_credits.ctc.amount.calc(taxable_income_before_deduction) + ) + federal_cdcc = tax_unit("cdcc", period) + cdcc_gain = federal_cdcc * ( + p_credits.cdcc.rate.calc(taxable_income_after_deduction, right=True) + - p_credits.cdcc.rate.calc(taxable_income_before_deduction, right=True) + ) + deduction_benefit = ( + taxes_without_deduction - taxes_with_deduction + ctc_gain + cdcc_gain + ) + # choose between taxable income deduction and refundable credit - return (taxes_without_deduction - taxes_with_deduction) > credit_amount + return deduction_benefit > credit_amount From e9502f5dfa0386e28bcac35c50bc5651d30b2b06 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 3 Nov 2026 23:50:55 +0000 Subject: [PATCH 2/4] Subtract all Schedule A income taxes from NE itemized deductions, uncapped Neb. Rev. Stat. 77-2716.01(4) allows federal itemized deductions except the state or local income taxes "before any federal disallowance", and the Form 1040N line 8 instructions say to enter the line 5a income taxes even when the SALT cap limited line 5e. The prior formula counted real estate taxes first inside the capped SALT deduction and removed only the rest, so it left too much whenever the cap bound. Start from itemized_taxable_income_deductions (Schedule A line 17), subtract the income taxes in full when line 5a holds them, and floor at zero. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01LwQq6K6CPev5JwhCMUY7j6 --- changelog.d/state-choice-bugs-nj-ne.fixed.md | 2 +- .../deductions/ne_itemized_deductions.yaml | 108 +++++++++++++----- .../deductions/ne_itemized_deductions.py | 36 +++--- 3 files changed, 98 insertions(+), 48 deletions(-) diff --git a/changelog.d/state-choice-bugs-nj-ne.fixed.md b/changelog.d/state-choice-bugs-nj-ne.fixed.md index a44908e4e91..2dce3bf13e7 100644 --- a/changelog.d/state-choice-bugs-nj-ne.fixed.md +++ b/changelog.d/state-choice-bugs-nj-ne.fixed.md @@ -1 +1 @@ -New Jersey now weighs the change in its refundable child tax credit and child and dependent care credit when choosing between the property tax deduction and the $50 credit, and Nebraska itemized deductions now start from the federal SALT deduction as claimed, removing only the income taxes in it. +New Jersey now weighs the change in its refundable child tax credit and child and dependent care credit when choosing between the property tax deduction and the $50 credit, and Nebraska itemized deductions now subtract the full state and local income taxes on Schedule A line 5a from federal itemized deductions, before the federal SALT cap, under Neb. Rev. Stat. 77-2716.01(4). diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/tax/income/deductions/ne_itemized_deductions.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/tax/income/deductions/ne_itemized_deductions.yaml index fde3be8209e..6a8908e8b26 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ne/tax/income/deductions/ne_itemized_deductions.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/tax/income/deductions/ne_itemized_deductions.yaml @@ -1,4 +1,11 @@ +# Neb. Rev. Stat. 77-2716.01(4) and Form 1040N lines 7-9: federal itemized +# deductions (Schedule A line 17) minus the income taxes on Schedule A line 5a, +# in full, before the federal SALT cap. Nothing is removed when line 5a holds +# sales taxes. + - name: Unit test 1 + # Federal: 2,000 + 24,000 + 10,000 capped SALT = 36,000. Income taxes (5,000) + # exceed sales taxes (0), so all 5,000 is removed: 36,000 - 5,000 = 31,000. period: 2021 input: filing_status: JOINT @@ -6,16 +13,17 @@ deductible_interest_expense: 24_000 salt_deduction: 10_000 real_estate_taxes: 9_000 - # Income taxes are claimed on Schedule A. state_withheld_income_tax: 5_000 local_income_tax: 0 state_sales_tax: 0 local_sales_tax: 0 state_code: NE output: - ne_itemized_deductions: 2_000 + 24_000 + 9_000 + ne_itemized_deductions: 31_000 - name: Unit test 2 + # Federal: 3,000 + 7,000 + 10,000 capped SALT = 20,000. Income taxes (5,000) + # exceed sales taxes (0): 20,000 - 5,000 = 15,000. period: 2022 input: filing_status: JOINT @@ -23,23 +31,22 @@ deductible_interest_expense: 7_000 salt_deduction: 10_000 real_estate_taxes: 6_000 - # Income taxes are claimed on Schedule A. state_withheld_income_tax: 5_000 local_income_tax: 0 state_sales_tax: 0 local_sales_tax: 0 state_code: NE output: - ne_itemized_deductions: 3_000 + 7_000 + 6_000 + ne_itemized_deductions: 15_000 -- name: Sales taxes claimed on Schedule A stay in the Nebraska deduction - # Federal itemized: 15,000 other + 8,000 SALT (sales taxes 3,000 exceed - # income taxes 1,000, so sales taxes are claimed) = 23,000. No income taxes - # are claimed, so Nebraska subtracts nothing. +- name: Sales taxes on Schedule A line 5a stay in the Nebraska deduction + # Federal: 15,000 interest + 8,000 SALT = 23,000. Sales taxes (3,000) exceed + # income taxes (1,000), so line 5a holds sales taxes and Nebraska removes + # nothing: 23,000. period: 2023 input: filing_status: SINGLE - itemized_deductions_less_salt: 15_000 + deductible_interest_expense: 15_000 salt_deduction: 8_000 real_estate_taxes: 5_000 state_withheld_income_tax: 1_000 @@ -50,13 +57,13 @@ output: ne_itemized_deductions: 23_000 -- name: Income taxes claimed on Schedule A are removed from the Nebraska deduction - # Federal SALT 7,000 = 2,000 income taxes + 5,000 real estate taxes. - # Nebraska: 15,000 + 7,000 - 2,000 = 20,000. +- name: Income taxes on Schedule A line 5a are removed when the cap does not bind + # Federal: 15,000 interest + 7,000 SALT (2,000 income taxes + 5,000 real + # estate taxes) = 22,000. Nebraska: 22,000 - 2,000 = 20,000. period: 2023 input: filing_status: SINGLE - itemized_deductions_less_salt: 15_000 + deductible_interest_expense: 15_000 salt_deduction: 7_000 real_estate_taxes: 5_000 state_withheld_income_tax: 2_000 @@ -67,33 +74,59 @@ output: ne_itemized_deductions: 20_000 -- name: Real estate taxes count only up to the SALT deduction claimed federally - # 2025: the federal SALT cap has phased down to 10,000, so Schedule A - # claims 10,000 of the 35,000 income taxes and 30,000 real estate taxes. - # Real estate taxes count first, so no income taxes are claimed and - # Nebraska keeps the full 10,000: 15,000 + 10,000 = 25,000, never more - # than the 25,000 federal total. +- name: Income taxes above the federal SALT cap are removed in full, floored at zero + # 2025, single, AGI 700,000. Federal SALT cap: 40,000 - 30% x (700,000 - + # 500,000) = -20,000, floored at 10,000. Schedule A line 5a: 35,000 income + # taxes; SALT deduction min(35,000 + 30,000, 10,000) = 10,000. Federal + # itemized: 10,000 + 20,000 mortgage interest = 30,000 (above the 15,750 + # federal standard deduction, so the filer itemizes). + # Nebraska: 30,000 - 35,000 = -5,000, floored at 0. Taxable income takes the + # larger 8,600 standard deduction: 700,000 - 8,600 = 691,400. period: 2025 input: filing_status: SINGLE - itemized_deductions_less_salt: 15_000 - salt_deduction: 10_000 + employment_income: 700_000 real_estate_taxes: 30_000 + deductible_mortgage_interest: 20_000 state_withheld_income_tax: 35_000 local_income_tax: 0 state_sales_tax: 0 local_sales_tax: 0 state_code: NE output: - ne_itemized_deductions: 25_000 + salt_deduction: 10_000 + itemized_taxable_income_deductions: 30_000 + ne_itemized_deductions: 0 + ne_taxable_income: 691_400 -- name: Income taxes above real estate taxes take the rest of the capped SALT deduction - # Federal SALT capped at 10,000: real estate taxes 4,000 count first, the - # other 6,000 is income taxes. Nebraska: 15,000 + 10,000 - 6,000 = 19,000. +- name: A binding SALT cap does not shield income taxes below the cap + # 2024, single. SALT: min(8,000 income taxes + 5,000 real estate taxes, + # 10,000) = 10,000. Federal itemized: 10,000 + 15,000 mortgage interest = + # 25,000. Nebraska removes all 8,000 of income taxes: 25,000 - 8,000 = + # 17,000. + period: 2024 + input: + filing_status: SINGLE + employment_income: 100_000 + real_estate_taxes: 5_000 + deductible_mortgage_interest: 15_000 + state_withheld_income_tax: 8_000 + local_income_tax: 0 + state_sales_tax: 0 + local_sales_tax: 0 + state_code: NE + output: + salt_deduction: 10_000 + itemized_taxable_income_deductions: 25_000 + ne_itemized_deductions: 17_000 + +- name: Income taxes above the cap and above real estate taxes are removed in full + # Federal: 15,000 interest + 10,000 capped SALT = 25,000. Income taxes + # (12,000) exceed sales taxes (1,000): 25,000 - 12,000 = 13,000. period: 2023 input: filing_status: SINGLE - itemized_deductions_less_salt: 15_000 + deductible_interest_expense: 15_000 salt_deduction: 10_000 real_estate_taxes: 4_000 state_withheld_income_tax: 12_000 @@ -102,4 +135,25 @@ local_sales_tax: 0 state_code: NE output: - ne_itemized_deductions: 19_000 + ne_itemized_deductions: 13_000 + +- name: Income taxes equal to sales taxes count as sales taxes, so nothing is removed + # Income taxes 3,000 = sales taxes 2,000 + 1,000. Line 5a holds 3,000 either + # way; a tie counts as sales taxes. SALT: 3,000 + 5,000 real estate taxes = + # 8,000. Federal itemized: 8,000 + 15,000 mortgage interest = 23,000. + # Nebraska removes nothing: 23,000. + period: 2023 + input: + filing_status: SINGLE + employment_income: 100_000 + real_estate_taxes: 5_000 + deductible_mortgage_interest: 15_000 + state_withheld_income_tax: 3_000 + local_income_tax: 0 + state_sales_tax: 2_000 + local_sales_tax: 1_000 + state_code: NE + output: + salt_deduction: 8_000 + itemized_taxable_income_deductions: 23_000 + ne_itemized_deductions: 23_000 diff --git a/policyengine_us/variables/gov/states/ne/tax/income/deductions/ne_itemized_deductions.py b/policyengine_us/variables/gov/states/ne/tax/income/deductions/ne_itemized_deductions.py index fb986cb5d33..2b974a7fca9 100644 --- a/policyengine_us/variables/gov/states/ne/tax/income/deductions/ne_itemized_deductions.py +++ b/policyengine_us/variables/gov/states/ne/tax/income/deductions/ne_itemized_deductions.py @@ -8,34 +8,30 @@ class ne_itemized_deductions(Variable): unit = USD definition_period = YEAR reference = ( + "https://nebraskalegislature.gov/laws/statutes.php?statute=77-2716.01", "https://revenue.nebraska.gov/files/doc/tax-forms/2021/f_1040n_booklet.pdf", "https://revenue.nebraska.gov/files/doc/2022_Ne_Individual_Income_Tax_Booklet_8-307-2022_final_5.pdf", - "https://nebraskalegislature.gov/laws/statutes.php?statute=77-2716", ) defined_for = StateCode.NE def formula(tax_unit, period, parameters): - # Nebraska allows federal itemized deductions minus the state and - # local income taxes claimed on federal Schedule A (see the Form - # 1040N booklet quoted in ne_taxable_income). - itm_deds_less_salt = tax_unit("itemized_deductions_less_salt", period) - # The SALT deduction as claimed federally, after the federal cap. - federal_salt = tax_unit("salt_deduction", period) - # Schedule A claims either income taxes or sales taxes, whichever is - # larger (state_and_local_sales_or_income_tax). Sales taxes stay in - # the Nebraska deduction. + # Neb. Rev. Stat. 77-2716.01(4): federal itemized deductions "except + # for the amount for state or local income taxes included in federal + # itemized deductions before any federal disallowance". + # Form 1040N line 7: federal Schedule A line 17. + federal_itemized = tax_unit("itemized_taxable_income_deductions", period) + # Form 1040N line 8: the income taxes on Schedule A line 5a, even when + # the federal SALT cap limits line 5e, so they are removed in full. + # Line 5a holds income taxes or general sales taxes, whichever is + # larger (state_and_local_sales_or_income_tax); a tie counts as sales + # taxes, and then nothing is removed. income_taxes = add( tax_unit, period, ["state_withheld_income_tax", "local_income_tax"] ) sales_taxes = add(tax_unit, period, ["state_sales_tax", "local_sales_tax"]) claims_income_taxes = income_taxes > sales_taxes - # When income taxes are claimed, real estate taxes count first toward - # the capped federal SALT deduction, so the income taxes removed are - # the rest of it. - real_estate_taxes = add(tax_unit, period, ["real_estate_taxes"]) - salt_kept = where( - claims_income_taxes, - min_(federal_salt, real_estate_taxes), - federal_salt, - ) - return itm_deds_less_salt + salt_kept + income_taxes_removed = where(claims_income_taxes, income_taxes, 0) + # Form 1040N line 9 (line 7 minus line 8) can be negative, but line 10 + # takes the larger of it and the standard deduction, so the floor + # changes no tax. + return max_(0, federal_itemized - income_taxes_removed) From ae2a795084e4f3190ace272e43eb3760222ee447 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 4 Nov 2026 15:05:06 +0000 Subject: [PATCH 3/4] Say how the NJ property tax election differs from Worksheet H, and test two edges The comment said the formula follows Worksheet H, but since the last round it also counts the change in the refundable NJ CTC and CDCC, which the worksheet leaves out. Two review cases close gaps no existing case covered: a separate filer, who cannot claim the NJ CTC, keeps the $50 credit; and a deduction that lands taxable income exactly on $30,000 gets the 50% NJ CDCC rate, as nj_cdcc's right=True reads it. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01QpcqEDJ2tmDgRbDecMcN7j --- .../nj_taking_property_tax_deduction.yaml | 45 +++++++++++++++++++ .../nj_taking_property_tax_deduction.py | 2 +- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/deductions/property_tax/nj_taking_property_tax_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/deductions/property_tax/nj_taking_property_tax_deduction.yaml index 0da96737e36..41b1f5360a9 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/deductions/property_tax/nj_taking_property_tax_deduction.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/deductions/property_tax/nj_taking_property_tax_deduction.yaml @@ -78,6 +78,36 @@ output: nj_taking_property_tax_deduction: false +- name: Separate filer with a child gets no NJ child tax credit gain, so keeps the $50 credit + # Tax saving 463.75 - 416.50 = 47.25 < 50; a separate filer cannot claim the + # NJ child tax credit, so its bracket change adds nothing. + period: 2023 + absolute_error_margin: 0 + input: + people: + parent: + age: 35 + child: + age: 3 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [parent, child] + filing_status: SEPARATE + cohabitating_spouses: false + nj_property_tax_deduction_eligible: true + nj_potential_property_tax_deduction: 2_700 + nj_taxable_income_before_property_tax_deduction: 30_500 + cdcc: 0 + households: + household: + members: [parent, child] + state_code: NJ + output: + nj_ctc_qualifying_children: 1 + nj_ctc_eligible: false + nj_taking_property_tax_deduction: false + - name: Deduction that raises the NJ child and dependent care credit rate beats the $50 credit # Tax saving: (30,500 - 28,500) x 1.75% = 35. The NJ CDCC match rate rises # from 40% (over $30,000) to 50% (up to $30,000) of the $600 federal @@ -108,6 +138,21 @@ output: nj_taking_property_tax_deduction: false +- name: Deduction that lands NJ taxable income exactly on $30,000 gets the 50% NJ CDCC rate + # Tax saving: 500 x 1.75% = 8.75. At $30,000 the NJ CDCC rate is 50%, not + # 40%: 8.75 + 10% x $600 = 68.75 > 50. + period: 2023 + absolute_error_margin: 0 + input: + nj_property_tax_deduction_eligible: true + nj_potential_property_tax_deduction: 500 + nj_taxable_income_before_property_tax_deduction: 30_500 + filing_status: SINGLE + cdcc: 600 + state_code: NJ + output: + nj_taking_property_tax_deduction: true + - name: Renter with one child takes the deduction and gets the higher NJ child tax credit # Wages $33,000 less $2,500 exemptions (1,000 personal + 1,500 dependent) # = $30,500. Property tax: 18% x $15,000 rent = $2,700. Taking the diff --git a/policyengine_us/variables/gov/states/nj/tax/income/property_tax/nj_taking_property_tax_deduction.py b/policyengine_us/variables/gov/states/nj/tax/income/property_tax/nj_taking_property_tax_deduction.py index 6fc5cc3fa8e..90b171ee1f0 100644 --- a/policyengine_us/variables/gov/states/nj/tax/income/property_tax/nj_taking_property_tax_deduction.py +++ b/policyengine_us/variables/gov/states/nj/tax/income/property_tax/nj_taking_property_tax_deduction.py @@ -19,7 +19,7 @@ class nj_taking_property_tax_deduction(Variable): def formula(tax_unit, period, parameters): p = parameters(period).gov.states.nj.tax.income.main - # follows NJ-1040 form Worksheet H + # Worksheet H compares the tax saving with the credit; this also counts the change in the refundable NJ CTC and CDCC (below). deduction = tax_unit("nj_potential_property_tax_deduction", period) # calculate taxes without deduction From 1511c2c92243134e63051a43b4bfa803819dfe99 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 5 Nov 2026 01:16:09 +0000 Subject: [PATCH 4/4] Cite 54A:3A-20 and test the halved NJ credit for cohabiting separate filers The election's reading rests on N.J.S.A. 54A:3A-20, which the property tax credit parameter already cites, so cite it here too. Add a case for a separate filer who lives with the spouse: the $50 credit halves to $25, so a $47.25 tax saving makes the deduction the better choice. Without the case, dropping the halving passed every test in the file. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01LwQq6HWtPqg7fKcLTqL3ef --- .../nj_taking_property_tax_deduction.yaml | 17 +++++++++++++++++ .../nj_taking_property_tax_deduction.py | 1 + 2 files changed, 18 insertions(+) diff --git a/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/deductions/property_tax/nj_taking_property_tax_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/deductions/property_tax/nj_taking_property_tax_deduction.yaml index 41b1f5360a9..9e30951de47 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/deductions/property_tax/nj_taking_property_tax_deduction.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/deductions/property_tax/nj_taking_property_tax_deduction.yaml @@ -187,3 +187,20 @@ nj_main_income_tax: 416.50 nj_ctc: 1_000 nj_property_tax_credit: 0 + +- name: Cohabiting separate filer weighs the deduction against a $25 credit + # Tax saving 463.75 - 416.50 = 47.25. A separate filer who lives with + # the spouse gets half the $50 credit, $25, so the filer takes the + # deduction: 47.25 exceeds 25. + period: 2023 + absolute_error_margin: 0 + input: + nj_property_tax_deduction_eligible: true + nj_potential_property_tax_deduction: 2_700 + nj_taxable_income_before_property_tax_deduction: 30_500 + filing_status: SEPARATE + cohabitating_spouses: true + cdcc: 0 + state_code: NJ + output: + nj_taking_property_tax_deduction: true diff --git a/policyengine_us/variables/gov/states/nj/tax/income/property_tax/nj_taking_property_tax_deduction.py b/policyengine_us/variables/gov/states/nj/tax/income/property_tax/nj_taking_property_tax_deduction.py index 90b171ee1f0..5193d04a5da 100644 --- a/policyengine_us/variables/gov/states/nj/tax/income/property_tax/nj_taking_property_tax_deduction.py +++ b/policyengine_us/variables/gov/states/nj/tax/income/property_tax/nj_taking_property_tax_deduction.py @@ -9,6 +9,7 @@ class nj_taking_property_tax_deduction(Variable): definition_period = YEAR reference = ( "https://law.justia.com/codes/new-jersey/2022/title-54a/section-54a-3a-17/", + "https://law.justia.com/codes/new-jersey/2022/title-54a/section-54a-3a-20/", # The NJ child tax credit and the NJ child and dependent care credit # are refundable and both depend on NJ taxable income. "https://law.justia.com/codes/new-jersey/2022/title-54a/section-54a-4-17-1/",