diff --git a/changelog.d/claimable-filer-nj-pa.fixed.md b/changelog.d/claimable-filer-nj-pa.fixed.md new file mode 100644 index 00000000000..598e38b27de --- /dev/null +++ b/changelog.d/claimable-filer-nj-pa.fixed.md @@ -0,0 +1 @@ +Apply the federal dependent test and refund-only filing exception to New Jersey, Ohio, Oklahoma and Pennsylvania dependent counts. Exclude dependents' Ohio medical expenses when another taxpayer can claim a filer, retaining the head's and spouse's expenses. Remove Oklahoma's regular exemption for a claimable filer and retain its special and blind exemptions. Deny Pennsylvania tax forgiveness to claimable filers without a parental exception, and preserve the other spouse's forgiveness on their own tax. Allow North Dakota's stillborn subtraction without a dependency condition. Limit Ohio tuition credits to dependents and New Jersey and Oklahoma childless EITC age tests to filers, regardless of claimability. diff --git a/policyengine_us/parameters/gov/states/nd/tax/income/taxable_income/subtractions/stillborn.yaml b/policyengine_us/parameters/gov/states/nd/tax/income/taxable_income/subtractions/stillborn.yaml index 234449623b0..118d674ddc0 100644 --- a/policyengine_us/parameters/gov/states/nd/tax/income/taxable_income/subtractions/stillborn.yaml +++ b/policyengine_us/parameters/gov/states/nd/tax/income/taxable_income/subtractions/stillborn.yaml @@ -1,4 +1,4 @@ -description: North Dakota provides this subtraction from federal taxable income for each child who was stillborn during the tax year, provided a Fetal Death Record was filed with the North Dakota Division of Vital Records and the child would have been a dependent. The amount is adjusted annually for inflation. +description: North Dakota provides this subtraction from federal taxable income for each birth resulting in stillbirth during the tax year with a filed fetal death certificate. The statute imposes no dependency condition. North Dakota adjusts the amount annually for inflation. values: 2021-01-01: 4_310 2022-01-01: 4_530 diff --git a/policyengine_us/reforms/state_dependent_exemptions/repeal_state_dependent_exemptions.py b/policyengine_us/reforms/state_dependent_exemptions/repeal_state_dependent_exemptions.py index d9d35617cc0..c2402f8814c 100644 --- a/policyengine_us/reforms/state_dependent_exemptions/repeal_state_dependent_exemptions.py +++ b/policyengine_us/reforms/state_dependent_exemptions/repeal_state_dependent_exemptions.py @@ -136,17 +136,29 @@ def formula(tax_unit, period, parameters): fagi = tax_unit("adjusted_gross_income", period) - roth_conversions filing_status = tax_unit("filing_status", period) agi_eligible = fagi <= p.special_agi_limit[filing_status] + # Regular exemptions as in the baseline: none for a filer who can + # be claimed as a dependent on another return. + claimable = person("claimable_as_dependent_on_another_return", period) + head_claimable = tax_unit.any( + person("is_tax_unit_head", period) & claimable + ) + spouse_claimable = tax_unit.any( + person("is_tax_unit_spouse", period) & claimable + ) # head exemptions age_eligible = tax_unit("age_head", period) >= p.special_age_minimum - head_exemptions = where(tax_unit("blind_head", period), 2, 1) + where( - agi_eligible & age_eligible, 1, 0 + head_exemptions = ( + where(head_claimable, 0, 1) + + where(tax_unit("blind_head", period), 1, 0) + + where(agi_eligible & age_eligible, 1, 0) ) # spouse exemptions age_eligible = tax_unit("age_spouse", period) >= p.special_age_minimum spouse_exemptions = where( filing_status == filing_status.possible_values.JOINT, ( - where(tax_unit("blind_spouse", period), 2, 1) + where(spouse_claimable, 0, 1) + + where(tax_unit("blind_spouse", period), 1, 0) + where(agi_eligible & age_eligible, 1, 0) ), 0, diff --git a/policyengine_us/reforms/states/nj/dependent_exemption/nj_dependent_exemption_reform.py b/policyengine_us/reforms/states/nj/dependent_exemption/nj_dependent_exemption_reform.py index 0acd05db3ff..a0e437b6b54 100644 --- a/policyengine_us/reforms/states/nj/dependent_exemption/nj_dependent_exemption_reform.py +++ b/policyengine_us/reforms/states/nj/dependent_exemption/nj_dependent_exemption_reform.py @@ -18,11 +18,17 @@ def formula(tax_unit, period, parameters): period ).gov.states.nj.tax.income.exemptions.dependents.amount person = tax_unit.members - is_dependent = person("is_tax_unit_dependent", period) + # A return on which the filer (or, if joint, either spouse) can be + # claimed as a dependent has no dependents (IRC 152(b)(1)). + # Publication 501 excepts a return whose would-be claimant files only + # for a refund. + is_dependent = person("is_tax_unit_dependent", period) & ~person.tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) # Age gate: when in effect, only dependents under the chosen age # are re-priced to the reform amount; older dependents keep the # baseline exemption. Otherwise every dependent is re-priced, - # matching the baseline tax_unit_dependents count at the default. + # matching the baseline dependent count at the default. if p.age_limit.in_effect: age = person("age", period) young = is_dependent & (age < p.age_limit.threshold) diff --git a/policyengine_us/reforms/states/ok/dependent_exemption/ok_dependent_exemption_reform.py b/policyengine_us/reforms/states/ok/dependent_exemption/ok_dependent_exemption_reform.py index 9478fd10a62..762babe6a52 100644 --- a/policyengine_us/reforms/states/ok/dependent_exemption/ok_dependent_exemption_reform.py +++ b/policyengine_us/reforms/states/ok/dependent_exemption/ok_dependent_exemption_reform.py @@ -15,7 +15,13 @@ def formula(tax_unit, period, parameters): person = tax_unit.members age = person("age", period) - is_dependent = person("is_tax_unit_dependent", period) + # A return on which the filer (or, if joint, either spouse) can be + # claimed as a dependent has no dependents (IRC 152(b)(1)). + # Publication 501 excepts a return whose would-be claimant files only + # for a refund. + is_dependent = person("is_tax_unit_dependent", period) & ~person.tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) # Apply age limit if in effect if p.age_limit.in_effect: @@ -49,7 +55,11 @@ class ok_older_dependents_count(Variable): def formula(tax_unit, period, parameters): person = tax_unit.members - is_dependent = person("is_tax_unit_dependent", period) + # A return on which the filer (or, if joint, either spouse) can be + # claimed as a dependent has no dependents (IRC 152(b)(1)). + is_dependent = person("is_tax_unit_dependent", period) & ~person.tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) total_dependents = tax_unit.sum(is_dependent) eligible_dependent_exemptions = tax_unit( "ok_eligible_dependents_count", period @@ -67,9 +77,16 @@ class ok_exemptions(Variable): def formula(tax_unit, period, parameters): p_base = parameters(period).gov.states.ok.tax.income.exemptions - # Personal exemptions exclude the dependent portion. + # Personal exemptions exclude the dependent portion, which + # ok_count_exemptions counts only when no filer can be claimed as + # a dependent (IRC 152(b)(1)). total_exemptions_count = tax_unit("ok_count_exemptions", period) - dependents = tax_unit("tax_unit_dependents", period) + filer_is_dependent = tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) + dependents = where( + filer_is_dependent, 0, tax_unit("tax_unit_dependents", period) + ) older_dependents = tax_unit("ok_older_dependents_count", period) personal_exemptions_count = ( total_exemptions_count - dependents + older_dependents diff --git a/policyengine_us/reforms/taxsim.py b/policyengine_us/reforms/taxsim.py index cd05f49dd4c..e8ab831696c 100644 --- a/policyengine_us/reforms/taxsim.py +++ b/policyengine_us/reforms/taxsim.py @@ -20,7 +20,16 @@ def formula(tax_unit, period, parameters): is_child_dependent = person("is_child_of_tax_head", period) & person( "is_tax_unit_dependent", period ) - child_dependents = tax_unit.sum(is_child_dependent) + # As in the baseline, a return on which the filer (or, if joint, + # either spouse) can be claimed as a dependent has no dependents. + # Publication 501 excepts a return whose would-be claimant files only + # for a refund. + filer_is_dependent = tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) + child_dependents = where( + filer_is_dependent, 0, tax_unit.sum(is_child_dependent) + ) # filing status affects the base, where it doubles for married claimants filing_status = tax_unit("filing_status", period) filing_statuses = filing_status.possible_values diff --git a/policyengine_us/tests/code_health/test_source_conflicts.py b/policyengine_us/tests/code_health/test_source_conflicts.py index 9ceab10c355..cb84f6f229a 100644 --- a/policyengine_us/tests/code_health/test_source_conflicts.py +++ b/policyengine_us/tests/code_health/test_source_conflicts.py @@ -178,6 +178,8 @@ "policyengine_us/variables/gov/states/mn/dcyf/mfip/income/earned/mn_mfip_dependent_care_deduction.py": 1, "policyengine_us/variables/gov/states/mn/tax/income/deductions/mn_itemized_deductions.py": 1, "policyengine_us/variables/gov/states/mo/dese/ccs/eligibility/mo_ccs_income_eligible.py": 1, + "policyengine_us/variables/gov/states/nd/tax/income/subtractions/nd_stillborn_subtraction.py": 1, + "policyengine_us/variables/gov/states/pa/tax/income/forgiveness/pa_tax_forgiveness_eligible.py": 1, "policyengine_us/variables/gov/states/sc/tax/income/subtractions/retirement/sc_retirement_deduction_survivors.py": 1, "policyengine_us/variables/gov/states/vt/tax/income/credits/cdcc/vt_low_income_cdcc_eligible.py": 1, "policyengine_us/variables/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_pte_categorical_eligible.py": 1, diff --git a/policyengine_us/tests/core/test_claimable_filer_nj_pa_invariants.py b/policyengine_us/tests/core/test_claimable_filer_nj_pa_invariants.py new file mode 100644 index 00000000000..e0ca00c7e3f --- /dev/null +++ b/policyengine_us/tests/core/test_claimable_filer_nj_pa_invariants.py @@ -0,0 +1,138 @@ +"""Check claimable-filer invariants in New Jersey, North Carolina, North Dakota, +Ohio, Oklahoma and Pennsylvania. + +Hypothesis draws couples with each adult's claimability, actual claim and +refund-only claimant exception. These tests exchange head and spouse labels +and check that each output stays unchanged. They also mark another filer as +claimed and check that the listed exemptions, credits, deductions and +forgiveness never rise, using generated and seeded populations. + +For Pennsylvania, they bound the eligible share between zero and one and +require a full share when neither filer can be claimed. They also check that +forgiveness stays between zero and tax before forgiveness. YAML cases cover +North Dakota's stillborn subtraction; these populations supply no stillborn +children. +""" + +import numpy as np +import pytest +from hypothesis import HealthCheck, given, settings +from hypothesis import strategies as st + +from policyengine_us.system import system +from policyengine_us.tests.core.test_claimable_filer_federal_invariants import ( + check_monotone, + check_swap, +) +from policyengine_us.tests.core.test_dependent_elsewhere_head_spouse_swap_invariance import ( + CLAIM_PATTERNS, + _calc, + _crafted_cases, + _seeded_couples, + adults, + dependents, + money, +) + +STATES = ["NJ", "NC", "ND", "OH", "OK", "PA"] +YEARS = [2022, 2025, 2026] +# Amounts that marking another filer as claimed must never raise. +MONOTONE = [ + "nj_dependents_exemption", + "nj_dependents_attending_college_exemption", + "nj_ctc", + "nj_eitc", + "nc_child_deduction", + "oh_non_public_school_credits_potential", + "ok_count_exemptions", + "ok_stc", + "ok_eitc", + "pa_tax_forgiveness_eligible_share", + "pa_tax_forgiveness_amount", +] +# The Oklahoma child care / child tax credit takes the larger of a care and a +# child tax credit branch; the care branch follows the federal credit, whose +# tax-liability limit can rise when a filer is claimable, so it is checked for +# swap invariance only. Taxes can rise too. +OUTPUTS = MONOTONE + [ + "ok_child_care_child_tax_credit", + "nj_income_tax", + "nc_income_tax", + "nd_income_tax", + "oh_income_tax", + "ok_income_tax", + "pa_income_tax", +] + + +@st.composite +def children(draw): + child = draw(dependents()) + return { + **child, + "is_full_time_college_student": child["is_full_time_student"], + "non_public_school_tuition": draw(money(3_000)), + } + + +@st.composite +def couples(draw): + # As in the swap-invariance test: who can be claimed, who of them is + # actually claimed, and, for the unclaimed, whether the would-be claimant + # files only for a refund (Publication 501's exception). + claimable = draw(st.sampled_from(CLAIM_PATTERNS)) + claimed = tuple(can_claim and draw(st.booleans()) for can_claim in claimable) + return { + "state": draw(st.sampled_from(STATES)), + "adults": [draw(adults()), draw(adults())], + "dependents": draw(st.lists(children(), max_size=2)), + "claimed": claimed, + "claimable": claimable, + "exception": tuple( + not is_claimed and draw(st.booleans()) for is_claimed in claimed + ), + } + + +def _claim_only(units): + # Monotonicity marks filers as claimed; without separate claimability or + # exception inputs, claimability follows the claim. + return [ + {k: v for k, v in unit.items() if k not in ("claimable", "exception")} + for unit in units + ] + + +def _pa_forgiveness_bounds(sim, year): + share = _calc(sim, "pa_tax_forgiveness_eligible_share", year) + assert ((share >= 0) & (share <= 1)).all() + in_pa = np.asarray(sim.calculate("PA", year, map_to="tax_unit"), dtype=bool) + claimable_filer = _calc(sim, "head_or_spouse_is_dependent_elsewhere", year) > 0 + np.testing.assert_allclose(share[in_pa & ~claimable_filer], 1, atol=0, rtol=0) + forgiveness = _calc(sim, "pa_tax_forgiveness_amount", year) + tax = _calc(sim, "pa_income_tax_before_forgiveness", year) + assert (forgiveness >= 0).all() + assert (forgiveness <= tax).all() + + +def test_pa_tax_forgiveness_has_no_parent_qualification_input(): + assert "pa_tax_forgiveness_parent_qualifies" not in system.variables + + +@settings( + max_examples=2, + deadline=None, + derandomize=True, + suppress_health_check=[HealthCheck.too_slow, HealthCheck.data_too_large], +) +@given(st.sampled_from(YEARS), st.lists(couples(), min_size=6, max_size=12)) +def test_nj_pa_claimable_filer_rules_are_label_free(year, units): + check_swap(units, year, OUTPUTS, _pa_forgiveness_bounds) + check_monotone(_claim_only(units), year, MONOTONE, _pa_forgiveness_bounds) + + +@pytest.mark.parametrize("year", YEARS) +def test_nj_pa_claimable_filer_rules_seeded_population(year): + units = _seeded_couples(STATES, per_state=2) + _crafted_cases(STATES) + check_swap(units, year, OUTPUTS, _pa_forgiveness_bounds) + check_monotone(units, year, MONOTONE, _pa_forgiveness_bounds) diff --git a/policyengine_us/tests/policy/baseline/gov/states/nc/tax/income/deductions/nc_child_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/nc/tax/income/deductions/nc_child_deduction.yaml index 392db18f429..a3e7b6de530 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/nc/tax/income/deductions/nc_child_deduction.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/nc/tax/income/deductions/nc_child_deduction.yaml @@ -141,3 +141,196 @@ output: ctc_qualifying_children: 1 nc_child_deduction: 3_000 + + +- name: "2025 single filer who can be claimed as a dependent: North Carolina child deduction" + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 10_000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child_1] + households: + household: + members: [person_a, child_1] + state_code: NC + output: + # G.S. 105-153.5(a1) needs a child for whom the taxpayer is allowed + # a federal child tax credit, and IRC 24(a) allows it only for a + # dependent; IRC 152(b)(1) leaves none here. + nc_child_deduction: 0 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: North Carolina child deduction (the claimable spouse is the head)" + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 22 + employment_income: 5000 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: NC + output: + nc_child_deduction: 0 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: North Carolina child deduction (the claimable spouse is the spouse)" + period: 2025 + input: + people: + person_b: + age: 22 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_a: + age: 22 + employment_income: 5000 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child_1] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child_1] + state_code: NC + output: + nc_child_deduction: 0 + +- name: "2025 joint return on which both spouses can be claimed as dependents: North Carolina child deduction" + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 22 + employment_income: 5000 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: NC + output: + nc_child_deduction: 0 + +- name: "2025 joint return on which neither spouse can be claimed: North Carolina child deduction" + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_b: + age: 22 + employment_income: 5000 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: NC + output: + # AGI $10,000 is in the lowest bracket: $3,000 per child. + nc_child_deduction: 3000 + +- name: "2025 single filer who cannot be claimed as a dependent: North Carolina child deduction" + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 10_000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child_1] + households: + household: + members: [person_a, child_1] + state_code: NC + output: + nc_child_deduction: 3000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/nd/tax/income/subtractions/nd_stillborn_subtraction.yaml b/policyengine_us/tests/policy/baseline/gov/states/nd/tax/income/subtractions/nd_stillborn_subtraction.yaml index 0c076735a3b..4e098f3a10a 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/nd/tax/income/subtractions/nd_stillborn_subtraction.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/nd/tax/income/subtractions/nd_stillborn_subtraction.yaml @@ -61,3 +61,216 @@ tax_unit_stillborn_children: 1 output: nd_stillborn_subtraction: 0 + + +- name: "2025 single filer who can be claimed as a dependent: North Dakota stillborn child subtraction" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_a] + tax_unit_stillborn_children: 1 + households: + household: + members: [person_a] + state_code: ND + output: + nd_stillborn_subtraction: 5241 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: North Dakota stillborn child subtraction (the claimable spouse is the head)" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + tax_unit_stillborn_children: 1 + households: + household: + members: [person_a, person_b] + state_code: ND + output: + nd_stillborn_subtraction: 5241 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: North Dakota stillborn child subtraction (the claimable spouse is the spouse)" + period: 2025 + input: + people: + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_b, person_a] + filing_status: JOINT + tax_unit_stillborn_children: 1 + households: + household: + members: [person_b, person_a] + state_code: ND + output: + nd_stillborn_subtraction: 5241 + +- name: "2025 joint return on which both spouses can be claimed as dependents: North Dakota stillborn child subtraction" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + tax_unit_stillborn_children: 1 + households: + household: + members: [person_a, person_b] + state_code: ND + output: + nd_stillborn_subtraction: 5241 + +- name: "2025 joint return on which neither spouse can be claimed: North Dakota stillborn child subtraction" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + tax_unit_stillborn_children: 1 + households: + household: + members: [person_a, person_b] + state_code: ND + output: + nd_stillborn_subtraction: 5241 + +- name: "2025 single filer who cannot be claimed as a dependent: North Dakota stillborn child subtraction" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: [person_a] + tax_unit_stillborn_children: 1 + households: + household: + members: [person_a] + state_code: ND + output: + nd_stillborn_subtraction: 5241 + + +- name: "2025 single filer who can be claimed as a dependent by someone who files only for a refund: North Dakota stillborn child subtraction" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: true + tax_units: + tax_unit: + members: [person_a] + tax_unit_stillborn_children: 1 + households: + household: + members: [person_a] + state_code: ND + output: + nd_stillborn_subtraction: 5241 + +- name: "2025 single filer who can be claimed as a dependent but is not claimed: North Dakota stillborn child subtraction" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_a] + tax_unit_stillborn_children: 1 + households: + household: + members: [person_a] + state_code: ND + output: + nd_stillborn_subtraction: 5241 diff --git a/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/credits/ctc/nj_ctc.yaml b/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/credits/ctc/nj_ctc.yaml index d6bd5d40752..b7351d605c1 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/credits/ctc/nj_ctc.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/credits/ctc/nj_ctc.yaml @@ -475,3 +475,386 @@ state_code: NJ output: nj_ctc: 0 + + +- name: "2025 single filer who can be claimed as a dependent: New Jersey child tax credit" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child_1] + households: + household: + members: [person_a, child_1] + state_code: NJ + output: + # N.J.S.A. 54A:4-17.1 counts each child who qualifies for the + # 54A:3-1 dependent exemption. IRC 152(b)(1): a return on which the filer (or, if joint, either spouse) can be claimed as a dependent has no dependents. + nj_ctc: 0 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: New Jersey child tax credit (the claimable spouse is the head)" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: NJ + output: + nj_ctc: 0 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: New Jersey child tax credit (the claimable spouse is the spouse)" + period: 2025 + input: + people: + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child_1] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child_1] + state_code: NJ + output: + nj_ctc: 0 + +- name: "2025 joint return on which both spouses can be claimed as dependents: New Jersey child tax credit" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: NJ + output: + nj_ctc: 0 + +- name: "2025 joint return on which neither spouse can be claimed: New Jersey child tax credit" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: NJ + output: + # NJ taxable income under $30,000: $1,000 per child under 6. + nj_ctc: 1000 + +- name: "2025 single filer who cannot be claimed as a dependent: New Jersey child tax credit" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child_1] + households: + household: + members: [person_a, child_1] + state_code: NJ + output: + nj_ctc: 1000 + +- name: "2026 single filer who can be claimed as a dependent: New Jersey child tax credit" + period: 2026 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child_1] + households: + household: + members: [person_a, child_1] + state_code: NJ + output: + # N.J.S.A. 54A:4-17.1 counts each child who qualifies for the + # 54A:3-1 dependent exemption. IRC 152(b)(1): a return on which the filer (or, if joint, either spouse) can be claimed as a dependent has no dependents. + nj_ctc: 0 + +- name: "2026 joint return with one spouse who can be claimed as a dependent: New Jersey child tax credit (the claimable spouse is the head)" + period: 2026 + input: + people: + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: NJ + output: + nj_ctc: 0 + +- name: "2026 joint return with one spouse who can be claimed as a dependent: New Jersey child tax credit (the claimable spouse is the spouse)" + period: 2026 + input: + people: + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child_1] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child_1] + state_code: NJ + output: + nj_ctc: 0 + +- name: "2026 joint return on which both spouses can be claimed as dependents: New Jersey child tax credit" + period: 2026 + input: + people: + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: NJ + output: + nj_ctc: 0 + +- name: "2026 joint return on which neither spouse can be claimed: New Jersey child tax credit" + period: 2026 + input: + people: + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: NJ + output: + # NJ taxable income under $30,000: $1,250 per child under 6. + nj_ctc: 1250 + +- name: "2026 single filer who cannot be claimed as a dependent: New Jersey child tax credit" + period: 2026 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child_1] + households: + household: + members: [person_a, child_1] + state_code: NJ + output: + nj_ctc: 1250 diff --git a/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/credits/eitc/nj_childless_eitc_age_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/credits/eitc/nj_childless_eitc_age_eligible.yaml index 048a0ebd39a..e9c4abb2a24 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/credits/eitc/nj_childless_eitc_age_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/credits/eitc/nj_childless_eitc_age_eligible.yaml @@ -156,3 +156,32 @@ foreign_earned_income_exclusion: 0 section_911_excluded_income: 0 nj_childless_eitc_age_eligible: false + + +- name: 2025 the NJ age test applies to the filer, not to a dependent + period: 2025 + input: + people: + person_a: + age: 17 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + relative: + age: 40 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, relative] + nj_eitc_income_eligible: true + households: + household: + members: [person_a, relative] + state_code: NJ + output: + # A 17-year-old filer misses the age-18 minimum even with an adult dependent. + nj_childless_eitc_age_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/credits/eitc/nj_eitc.yaml b/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/credits/eitc/nj_eitc.yaml index 75cb463cbd8..dd06d46cc12 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/credits/eitc/nj_eitc.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/credits/eitc/nj_eitc.yaml @@ -139,6 +139,498 @@ output: nj_eitc: 0 + +- name: "2025 single filer who can be claimed as a dependent: New Jersey childless EITC below the federal age" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 20 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_a] + households: + household: + members: [person_a] + state_code: NJ + output: + # P.L.2021 c.130 keeps every federal qualification except age, including + # IRC 32(c)(1)(A)(ii)(III): not a dependent of another taxpayer (either + # spouse on a joint return). The worksheet also requires that "You are not + # listed as a dependent on another tax return." + nj_childless_eitc_age_eligible: false + nj_eitc: 0 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: New Jersey childless EITC below the federal age (the claimable spouse is the head)" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 20 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 20 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: NJ + output: + nj_childless_eitc_age_eligible: false + nj_eitc: 0 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: New Jersey childless EITC below the federal age (the claimable spouse is the spouse)" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_b: + age: 20 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_a: + age: 20 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_b, person_a] + filing_status: JOINT + households: + household: + members: [person_b, person_a] + state_code: NJ + output: + nj_childless_eitc_age_eligible: false + nj_eitc: 0 + +- name: "2025 joint return on which both spouses can be claimed as dependents: New Jersey childless EITC below the federal age" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 20 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 20 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: NJ + output: + nj_childless_eitc_age_eligible: false + nj_eitc: 0 + +- name: "2025 joint return on which neither spouse can be claimed: New Jersey childless EITC below the federal age" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 20 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_b: + age: 20 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: NJ + output: + # Federally ineligible at 20; NJ pays 40% of the $649 childless maximum. + nj_childless_eitc_age_eligible: true + nj_eitc: 259.6 + +- name: "2025 single filer who cannot be claimed as a dependent: New Jersey childless EITC below the federal age" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 20 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: [person_a] + households: + household: + members: [person_a] + state_code: NJ + output: + nj_childless_eitc_age_eligible: true + nj_eitc: 259.6 + +- name: "2025 single filer who can be claimed as a dependent: New Jersey childless EITC at federal ages" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 3000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_a] + households: + household: + members: [person_a] + state_code: NJ + output: + # Neither the federal credit nor the NJ age fallback is available. + nj_eitc: 0 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: New Jersey childless EITC at federal ages (the claimable spouse is the head)" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 1500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 1500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: NJ + output: + nj_eitc: 0 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: New Jersey childless EITC at federal ages (the claimable spouse is the spouse)" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_b: + age: 30 + employment_income: 1500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_a: + age: 30 + employment_income: 1500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_b, person_a] + filing_status: JOINT + households: + household: + members: [person_b, person_a] + state_code: NJ + output: + nj_eitc: 0 + +- name: "2025 joint return on which both spouses can be claimed as dependents: New Jersey childless EITC at federal ages" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 1500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 1500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: NJ + output: + nj_eitc: 0 + +- name: "2025 joint return on which neither spouse can be claimed: New Jersey childless EITC at federal ages" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 1500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_b: + age: 30 + employment_income: 1500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: NJ + output: + # $3,000 x 7.65% = $229.50 federal EITC; 40% = $91.80. + nj_eitc: 91.8 + +- name: "2025 single filer who cannot be claimed as a dependent: New Jersey childless EITC at federal ages" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 3000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: [person_a] + households: + household: + members: [person_a] + state_code: NJ + output: + nj_eitc: 91.8 + + +- name: "2025 single filer who can be claimed as a dependent but is not claimed: New Jersey childless EITC below the federal age" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 20 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_a] + households: + household: + members: [person_a] + state_code: NJ + output: + # The federal childless test (kept by P.L.2021 c.130) bars a filer who can + # be claimed, claimed or not. + nj_childless_eitc_age_eligible: false + nj_eitc: 0 + +- name: "2025 single filer who can be claimed as a dependent by someone who files only for a refund: New Jersey childless EITC below the federal age" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 20 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: true + tax_units: + tax_unit: + members: [person_a] + households: + household: + members: [person_a] + state_code: NJ + output: + # Publication 596's exception lets the filer meet the federal test, and + # the filer is not listed as a dependent on another return: 40% of $649. + nj_childless_eitc_age_eligible: true + nj_eitc: 259.6 + +- name: "2025 joint return with one spouse who can be claimed as a dependent by someone who files only for a refund: New Jersey childless EITC below the federal age (the claimable spouse is the head)" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 20 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: true + person_b: + age: 20 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: NJ + output: + # Neither spouse is barred or listed as a dependent: 40% of $649. + nj_childless_eitc_age_eligible: true + nj_eitc: 259.6 + +- name: "2025 joint return with one spouse who can be claimed as a dependent by someone who files only for a refund: New Jersey childless EITC below the federal age (the claimable spouse is the spouse)" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_b: + age: 20 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: false + person_a: + age: 20 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: true + tax_units: + tax_unit: + members: [person_b, person_a] + filing_status: JOINT + households: + household: + members: [person_b, person_a] + state_code: NJ + output: + nj_childless_eitc_age_eligible: true + nj_eitc: 259.6 + +- name: "2025 single filer listed as a dependent by someone who files only for a refund: New Jersey childless EITC below the federal age" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 20 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: true + tax_units: + tax_unit: + members: [person_a] + households: + household: + members: [person_a] + state_code: NJ + output: + # The NJ-1040 line 58 worksheet requires "You are not listed as a + # dependent on another tax return", whatever the federal exception. + nj_childless_eitc_age_eligible: false + nj_eitc: 0 + - name: Married separated head of household without a qualifying child gets no NJ age fallback # The filer is married under IRC 7703(a) (7703(b) gives only HoH status), # lived apart six months (is_separated default), but has no EITC @@ -450,3 +942,4 @@ # child: 40% x the $600 zero-child maximum = $240 (54A:4-7(a)(4)). nj_childless_eitc_age_eligible: true nj_eitc: 240 + diff --git a/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/exemptions/nj_dependents_attending_college_exemption.yaml b/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/exemptions/nj_dependents_attending_college_exemption.yaml index 767f66005c4..8a6500ebe0e 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/exemptions/nj_dependents_attending_college_exemption.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/exemptions/nj_dependents_attending_college_exemption.yaml @@ -98,3 +98,201 @@ output: nj_dependents_attending_college_exemption: 1_000 + + +- name: "2025 single filer who can be claimed as a dependent: New Jersey college dependent exemption" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 20 + is_full_time_college_student: true + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child_1] + households: + household: + members: [person_a, child_1] + state_code: NJ + output: + # NJ-1040 line 12: the student must be claimed as a dependent on + # line 10 or 11, and IRC 152(b)(1) leaves no dependents here. + nj_dependents_attending_college_exemption: 0 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: New Jersey college dependent exemption (the claimable spouse is the head)" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 20 + is_full_time_college_student: true + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: NJ + output: + nj_dependents_attending_college_exemption: 0 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: New Jersey college dependent exemption (the claimable spouse is the spouse)" + period: 2025 + input: + people: + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 20 + is_full_time_college_student: true + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child_1] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child_1] + state_code: NJ + output: + nj_dependents_attending_college_exemption: 0 + +- name: "2025 joint return on which both spouses can be claimed as dependents: New Jersey college dependent exemption" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 20 + is_full_time_college_student: true + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: NJ + output: + nj_dependents_attending_college_exemption: 0 + +- name: "2025 joint return on which neither spouse can be claimed: New Jersey college dependent exemption" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 20 + is_full_time_college_student: true + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: NJ + output: + # One full-time student under 22 at $1,000. + nj_dependents_attending_college_exemption: 1000 + +- name: "2025 single filer who cannot be claimed as a dependent: New Jersey college dependent exemption" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 20 + is_full_time_college_student: true + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child_1] + households: + household: + members: [person_a, child_1] + state_code: NJ + output: + nj_dependents_attending_college_exemption: 1000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/exemptions/nj_dependents_exemption.yaml b/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/exemptions/nj_dependents_exemption.yaml index b625cbf20a0..c5bbf79e30a 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/exemptions/nj_dependents_exemption.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/exemptions/nj_dependents_exemption.yaml @@ -29,3 +29,329 @@ tax_unit_dependents: 2 output: nj_dependents_exemption: 0 + + +- name: "2025 single filer who can be claimed as a dependent: New Jersey dependent exemption" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child_1] + households: + household: + members: [person_a, child_1] + state_code: NJ + output: + # NJ-1040 lines 10-11: each child who qualifies as your dependent + # for federal tax purposes. IRC 152(b)(1): a return on which the filer (or, if joint, either spouse) can be claimed as a dependent has no dependents. + nj_dependents_exemption: 0 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: New Jersey dependent exemption (the claimable spouse is the head)" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: NJ + output: + nj_dependents_exemption: 0 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: New Jersey dependent exemption (the claimable spouse is the spouse)" + period: 2025 + input: + people: + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child_1] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child_1] + state_code: NJ + output: + nj_dependents_exemption: 0 + +- name: "2025 joint return on which both spouses can be claimed as dependents: New Jersey dependent exemption" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: NJ + output: + nj_dependents_exemption: 0 + +- name: "2025 joint return on which neither spouse can be claimed: New Jersey dependent exemption" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: NJ + output: + # One dependent at $1,500. + nj_dependents_exemption: 1500 + +- name: "2025 single filer who cannot be claimed as a dependent: New Jersey dependent exemption" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child_1] + households: + household: + members: [person_a, child_1] + state_code: NJ + output: + nj_dependents_exemption: 1500 + + +- name: "2025 single filer who can be claimed as a dependent but is not claimed: New Jersey dependent exemption" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child_1] + households: + household: + members: [person_a, child_1] + state_code: NJ + output: + # The federal Dependent Taxpayer Test turns on whether the filer can be + # claimed, not on an actual claim. + nj_dependents_exemption: 0 + +- name: "2025 single filer who can be claimed as a dependent by someone who files only for a refund: New Jersey dependent exemption" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child_1] + households: + household: + members: [person_a, child_1] + state_code: NJ + output: + # Publication 501: such a filer can still claim their own dependents. + nj_dependents_exemption: 1500 + +- name: "2025 joint return with one spouse who can be claimed as a dependent by someone who files only for a refund: New Jersey dependent exemption (the claimable spouse is the head)" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: true + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: false + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: NJ + output: + # Publication 501's exception restores the dependent. + nj_dependents_exemption: 1500 + +- name: "2025 joint return with one spouse who can be claimed as a dependent by someone who files only for a refund: New Jersey dependent exemption (the claimable spouse is the spouse)" + period: 2025 + input: + people: + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: false + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child_1] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child_1] + state_code: NJ + output: + nj_dependents_exemption: 1500 diff --git a/policyengine_us/tests/policy/baseline/gov/states/oh/tax/income/credits/oh_non_public_school_credits.yaml b/policyengine_us/tests/policy/baseline/gov/states/oh/tax/income/credits/oh_non_public_school_credits.yaml index 593d0d979e3..9bd6b91cb6a 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/oh/tax/income/credits/oh_non_public_school_credits.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/oh/tax/income/credits/oh_non_public_school_credits.yaml @@ -1,100 +1,483 @@ +# R.C. 5747.75 counts tuition paid for the taxpayer's dependents, so each +# case records the tuition on a dependent child. - name: AGI Not eligible period: 2021 input: - adjusted_gross_income: 100000 - non_public_school_tuition: 1000 - state_code: OH - oh_income_tax_before_non_refundable_credits: 1000000 + people: + parent: + age: 40 + child1: + age: 10 + is_tax_unit_dependent: true + non_public_school_tuition: 1000 + tax_units: + tax_unit: + members: [parent, child1] + adjusted_gross_income: 100000 + oh_income_tax_before_non_refundable_credits: 1000000 + households: + household: + members: [parent, child1] + state_code: OH output: oh_non_public_school_credits: 0 + - name: Non public tuition less than cap period: 2021 input: - adjusted_gross_income: 49999 - non_public_school_tuition: 400 - state_code: OH - oh_income_tax_before_non_refundable_credits: 1000000 + people: + parent: + age: 40 + child1: + age: 10 + is_tax_unit_dependent: true + non_public_school_tuition: 400 + tax_units: + tax_unit: + members: [parent, child1] + adjusted_gross_income: 49999 + oh_income_tax_before_non_refundable_credits: 1000000 + households: + household: + members: [parent, child1] + state_code: OH output: oh_non_public_school_credits: 400 + - name: AGI less than $50,000 period: 2021 input: - adjusted_gross_income: 49999 - non_public_school_tuition: 1000 - state_code: OH - oh_income_tax_before_non_refundable_credits: 1000000 + people: + parent: + age: 40 + child1: + age: 10 + is_tax_unit_dependent: true + non_public_school_tuition: 1000 + tax_units: + tax_unit: + members: [parent, child1] + adjusted_gross_income: 49999 + oh_income_tax_before_non_refundable_credits: 1000000 + households: + household: + members: [parent, child1] + state_code: OH output: oh_non_public_school_credits: 500 + - name: AGI greater that $50,000 capped period: 2021 input: - adjusted_gross_income: 50000 - non_public_school_tuition: 1500 - state_code: OH - oh_income_tax_before_non_refundable_credits: 1000000 + people: + parent: + age: 40 + child1: + age: 10 + is_tax_unit_dependent: true + non_public_school_tuition: 1500 + tax_units: + tax_unit: + members: [parent, child1] + adjusted_gross_income: 50000 + oh_income_tax_before_non_refundable_credits: 1000000 + households: + household: + members: [parent, child1] + state_code: OH output: oh_non_public_school_credits: 1000 + - name: AGI greater that $50,000 not capped period: 2021 input: - adjusted_gross_income: 80000 - non_public_school_tuition: 1000 - state_code: OH - oh_income_tax_before_non_refundable_credits: 1000000 + people: + parent: + age: 40 + child1: + age: 10 + is_tax_unit_dependent: true + non_public_school_tuition: 1000 + tax_units: + tax_unit: + members: [parent, child1] + adjusted_gross_income: 80000 + oh_income_tax_before_non_refundable_credits: 1000000 + households: + household: + members: [parent, child1] + state_code: OH output: oh_non_public_school_credits: 1000 + - name: AGI greater that $50,000 case 3 period: 2021 input: - adjusted_gross_income: 99999 - non_public_school_tuition: 250 - state_code: OH - oh_income_tax_before_non_refundable_credits: 1000000 + people: + parent: + age: 40 + child1: + age: 10 + is_tax_unit_dependent: true + non_public_school_tuition: 250 + tax_units: + tax_unit: + members: [parent, child1] + adjusted_gross_income: 99999 + oh_income_tax_before_non_refundable_credits: 1000000 + households: + household: + members: [parent, child1] + state_code: OH output: oh_non_public_school_credits: 250 + - name: Not capped at tuition expenses period: 2021 input: people: - person1: + parent: + age: 40 + child1: + age: 10 + is_tax_unit_dependent: true non_public_school_tuition: 200 - person2: + child2: + age: 10 + is_tax_unit_dependent: true non_public_school_tuition: 400 - households: - household: - members: - - person1 - - person2 - state_code: OH tax_units: tax_unit: - members: - - person1 - - person2 + members: [parent, child1, child2] adjusted_gross_income: 49999 oh_income_tax_before_non_refundable_credits: 1000000 + households: + household: + members: [parent, child1, child2] + state_code: OH output: oh_non_public_school_credits: 500 + - name: Credit is capped at tuition expenses period: 2021 input: people: - person1: + parent: + age: 40 + child1: + age: 10 + is_tax_unit_dependent: true non_public_school_tuition: 200 - person2: + child2: + age: 10 + is_tax_unit_dependent: true non_public_school_tuition: 200 - households: - household: - members: - - person1 - - person2 - state_code: OH tax_units: tax_unit: - members: - - person1 - - person2 + members: [parent, child1, child2] adjusted_gross_income: 49999 oh_income_tax_before_non_refundable_credits: 1000000 + households: + household: + members: [parent, child1, child2] + state_code: OH output: oh_non_public_school_credits: 400 + +- name: "2024 single filer who can be claimed as a dependent: Ohio nonpublic school tuition credit" + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 1000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 6 + non_public_school_tuition: 400 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child_1] + households: + household: + members: [person_a, child_1] + state_code: OH + output: + # R.C. 5747.75 counts tuition paid for the taxpayer's dependents, and + # 5747.01(O) takes dependents from the IRC. IRC 152(b)(1): a return on which the filer (or, if joint, either spouse) can be claimed as a dependent has no dependents. + oh_non_public_school_credits_potential: 0 + +- name: "2024 joint return with one spouse who can be claimed as a dependent: Ohio nonpublic school tuition credit (the claimable spouse is the head)" + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 6 + non_public_school_tuition: 400 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: OH + output: + oh_non_public_school_credits_potential: 0 + +- name: "2024 joint return with one spouse who can be claimed as a dependent: Ohio nonpublic school tuition credit (the claimable spouse is the spouse)" + period: 2024 + input: + people: + person_b: + age: 30 + employment_income: 500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_a: + age: 30 + employment_income: 500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 6 + non_public_school_tuition: 400 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child_1] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child_1] + state_code: OH + output: + oh_non_public_school_credits_potential: 0 + +- name: "2024 joint return on which both spouses can be claimed as dependents: Ohio nonpublic school tuition credit" + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 6 + non_public_school_tuition: 400 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: OH + output: + oh_non_public_school_credits_potential: 0 + +- name: "2024 joint return on which neither spouse can be claimed: Ohio nonpublic school tuition credit" + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_b: + age: 30 + employment_income: 500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 6 + non_public_school_tuition: 400 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: OH + output: + # $400 of tuition, under the $1,000 cap below $50,000 of AGI. + oh_non_public_school_credits_potential: 400 + +- name: "2024 single filer who cannot be claimed as a dependent: Ohio nonpublic school tuition credit" + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 1000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 6 + non_public_school_tuition: 400 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child_1] + households: + household: + members: [person_a, child_1] + state_code: OH + output: + oh_non_public_school_credits_potential: 400 + +- name: 2024 tuition a filer pays for their own schooling does not count + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 1000 + non_public_school_tuition: 400 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: [person_a] + households: + household: + members: [person_a] + state_code: OH + output: + # The credit covers tuition paid for the taxpayer's dependents only. + oh_non_public_school_credits_potential: 0 + + +- name: "2024 joint return with one spouse who can be claimed as a dependent by someone who files only for a refund: Ohio nonpublic school tuition credit (the claimable spouse is the head)" + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: true + person_b: + age: 30 + employment_income: 500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: false + child_1: + age: 6 + non_public_school_tuition: 400 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: OH + output: + # Publication 501's exception restores the dependent: $400 of tuition. + oh_non_public_school_credits_potential: 400 + +- name: "2024 joint return with one spouse who can be claimed as a dependent by someone who files only for a refund: Ohio nonpublic school tuition credit (the claimable spouse is the spouse)" + period: 2024 + input: + people: + person_b: + age: 30 + employment_income: 500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: false + person_a: + age: 30 + employment_income: 500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: true + child_1: + age: 6 + non_public_school_tuition: 400 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child_1] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child_1] + state_code: OH + output: + oh_non_public_school_credits_potential: 400 diff --git a/policyengine_us/tests/policy/baseline/gov/states/oh/tax/income/deductions/medical_expense/oh_claimable_filer_medical_expenses.yaml b/policyengine_us/tests/policy/baseline/gov/states/oh/tax/income/deductions/medical_expense/oh_claimable_filer_medical_expenses.yaml new file mode 100644 index 00000000000..fda5518905a --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/oh/tax/income/deductions/medical_expense/oh_claimable_filer_medical_expenses.yaml @@ -0,0 +1,297 @@ +# R.C. 5747.01(A)(10)(a)-(c), (O), and IRC 152(b)(1). +# https://codes.ohio.gov/ohio-revised-code/section-5747.01 +# https://uscode.house.gov/us/usc/t26/s152/ +# 2025 IT 1040 Unreimbursed Medical Care Expenses Worksheet, page 41. + +- name: Claimable filer cannot deduct a child's $1,000 premiums + period: 2025 + input: + people: + head: + age: 35 + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: false + child: + age: 5 + is_tax_unit_dependent: true + health_insurance_premiums: 1000 + is_medicare_eligible: false + employer_contribution_to_health_insurance_premiums_category: NONE + tax_units: + tax_unit: + members: [head, child] + adjusted_gross_income: 0 + households: + household: + members: [head, child] + state_code: OH + output: + oh_unreimbursed_medical_care_expense_deduction: 0 + +- name: Independent filer deducts a child's $1,000 premiums + period: 2025 + input: + people: + head: + age: 35 + claimable_as_dependent_on_another_return: false + dependent_claimant_filing_exception: false + child: + age: 5 + is_tax_unit_dependent: true + health_insurance_premiums: 1000 + is_medicare_eligible: false + employer_contribution_to_health_insurance_premiums_category: NONE + tax_units: + tax_unit: + members: [head, child] + adjusted_gross_income: 0 + households: + household: + members: [head, child] + state_code: OH + output: + oh_unreimbursed_medical_care_expense_deduction: 1000 + +- name: Claimant filing exception preserves the child's medical premiums + period: 2025 + input: + people: + head: + age: 35 + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: true + child: + age: 5 + is_tax_unit_dependent: true + health_insurance_premiums: 1000 + is_medicare_eligible: false + employer_contribution_to_health_insurance_premiums_category: NONE + tax_units: + tax_unit: + members: [head, child] + adjusted_gross_income: 0 + households: + household: + members: [head, child] + state_code: OH + output: + oh_unreimbursed_medical_care_expense_deduction: 1000 + +- name: A claimable child does not disqualify an independent filer + period: 2025 + input: + people: + head: + age: 35 + claimable_as_dependent_on_another_return: false + dependent_claimant_filing_exception: false + child: + age: 5 + is_tax_unit_dependent: true + health_insurance_premiums: 1000 + is_medicare_eligible: false + employer_contribution_to_health_insurance_premiums_category: NONE + claimable_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [head, child] + adjusted_gross_income: 0 + households: + household: + members: [head, child] + state_code: OH + output: + oh_unreimbursed_medical_care_expense_deduction: 1000 + +- name: Claimable head retains both filers' unsubsidized and long-term care premiums + period: 2025 + input: + people: + head: + age: 35 + health_insurance_premiums: 100 + long_term_health_insurance_premiums: 10 + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: false + is_medicare_eligible: false + employer_contribution_to_health_insurance_premiums_category: NONE + spouse: + age: 33 + health_insurance_premiums: 200 + long_term_health_insurance_premiums: 20 + claimable_as_dependent_on_another_return: false + dependent_claimant_filing_exception: false + is_medicare_eligible: false + employer_contribution_to_health_insurance_premiums_category: NONE + child: + age: 5 + is_tax_unit_dependent: true + health_insurance_premiums: 1000 + long_term_health_insurance_premiums: 100 + claimable_as_dependent_on_another_return: false + dependent_claimant_filing_exception: false + is_medicare_eligible: false + employer_contribution_to_health_insurance_premiums_category: NONE + tax_units: + tax_unit: + members: [head, spouse, child] + adjusted_gross_income: 0 + marital_units: + couple: + members: [head, spouse] + households: + household: + members: [head, spouse, child] + state_code: OH + output: + oh_uninsured_unreimbursed_medical_care_expenses: [100, 200, 0] + oh_long_term_care_insurance_premiums: [10, 20, 0] + oh_unreimbursed_medical_care_expense_deduction_person: [110, 220, 0] + oh_unreimbursed_medical_care_expense_deduction: 330 + +- name: Claimable head excludes the child's medical care before the AGI floor and proration + period: 2025 + input: + people: + head: + age: 35 + health_insurance_premiums: 400 + long_term_health_insurance_premiums: 10 + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: false + is_medicare_eligible: false + employer_contribution_to_health_insurance_premiums_category: SOME + other_medical_expenses: 600 + spouse: + age: 33 + health_insurance_premiums: 500 + long_term_health_insurance_premiums: 20 + claimable_as_dependent_on_another_return: false + dependent_claimant_filing_exception: false + is_medicare_eligible: false + employer_contribution_to_health_insurance_premiums_category: SOME + other_medical_expenses: 500 + child: + age: 5 + is_tax_unit_dependent: true + health_insurance_premiums: 1000 + long_term_health_insurance_premiums: 100 + claimable_as_dependent_on_another_return: false + dependent_claimant_filing_exception: false + is_medicare_eligible: false + employer_contribution_to_health_insurance_premiums_category: SOME + other_medical_expenses: 5000 + tax_units: + tax_unit: + members: [head, spouse, child] + adjusted_gross_income: 8000 + marital_units: + couple: + members: [head, spouse] + households: + household: + members: [head, spouse, child] + state_code: OH + output: + oh_insured_unreimbursed_medical_care_expense_amount: [1000, 1000, 0] + oh_insured_unreimbursed_medical_care_expenses: 1400 + oh_insured_unreimbursed_medical_care_expenses_person: [700, 700, 0] + oh_unreimbursed_medical_care_expense_deduction_person: [710, 720, 0] + oh_unreimbursed_medical_care_expense_deduction: 1430 + +- name: Claimable spouse retains both filers' unsubsidized and long-term care premiums + period: 2025 + input: + people: + head: + age: 35 + health_insurance_premiums: 100 + long_term_health_insurance_premiums: 10 + claimable_as_dependent_on_another_return: false + dependent_claimant_filing_exception: false + is_medicare_eligible: false + employer_contribution_to_health_insurance_premiums_category: NONE + spouse: + age: 33 + health_insurance_premiums: 200 + long_term_health_insurance_premiums: 20 + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: false + is_medicare_eligible: false + employer_contribution_to_health_insurance_premiums_category: NONE + child: + age: 5 + is_tax_unit_dependent: true + health_insurance_premiums: 1000 + long_term_health_insurance_premiums: 100 + claimable_as_dependent_on_another_return: false + dependent_claimant_filing_exception: false + is_medicare_eligible: false + employer_contribution_to_health_insurance_premiums_category: NONE + tax_units: + tax_unit: + members: [head, spouse, child] + adjusted_gross_income: 0 + marital_units: + couple: + members: [head, spouse] + households: + household: + members: [head, spouse, child] + state_code: OH + output: + oh_uninsured_unreimbursed_medical_care_expenses: [100, 200, 0] + oh_long_term_care_insurance_premiums: [10, 20, 0] + oh_unreimbursed_medical_care_expense_deduction_person: [110, 220, 0] + oh_unreimbursed_medical_care_expense_deduction: 330 + +- name: Claimable spouse excludes the child's medical care before the AGI floor and proration + period: 2025 + input: + people: + head: + age: 35 + health_insurance_premiums: 400 + long_term_health_insurance_premiums: 10 + claimable_as_dependent_on_another_return: false + dependent_claimant_filing_exception: false + is_medicare_eligible: false + employer_contribution_to_health_insurance_premiums_category: SOME + other_medical_expenses: 600 + spouse: + age: 33 + health_insurance_premiums: 500 + long_term_health_insurance_premiums: 20 + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: false + is_medicare_eligible: false + employer_contribution_to_health_insurance_premiums_category: SOME + other_medical_expenses: 500 + child: + age: 5 + is_tax_unit_dependent: true + health_insurance_premiums: 1000 + long_term_health_insurance_premiums: 100 + claimable_as_dependent_on_another_return: false + dependent_claimant_filing_exception: false + is_medicare_eligible: false + employer_contribution_to_health_insurance_premiums_category: SOME + other_medical_expenses: 5000 + tax_units: + tax_unit: + members: [head, spouse, child] + adjusted_gross_income: 8000 + marital_units: + couple: + members: [head, spouse] + households: + household: + members: [head, spouse, child] + state_code: OH + output: + oh_insured_unreimbursed_medical_care_expense_amount: [1000, 1000, 0] + oh_insured_unreimbursed_medical_care_expenses: 1400 + oh_insured_unreimbursed_medical_care_expenses_person: [700, 700, 0] + oh_unreimbursed_medical_care_expense_deduction_person: [710, 720, 0] + oh_unreimbursed_medical_care_expense_deduction: 1430 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ok/tax/income/credits/eitc/federal_credit/ok_federal_eitc_demographic_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ok/tax/income/credits/eitc/federal_credit/ok_federal_eitc_demographic_eligible.yaml index 212f9f7de3c..842c4c7da00 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ok/tax/income/credits/eitc/federal_credit/ok_federal_eitc_demographic_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ok/tax/income/credits/eitc/federal_credit/ok_federal_eitc_demographic_eligible.yaml @@ -47,3 +47,32 @@ state_code: OK output: ok_federal_eitc_demographic_eligible: false + + +- name: 2025 the 2020 age test applies to the filer, not to a dependent + period: 2025 + input: + people: + person_a: + age: 20 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + relative: + age: 40 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, relative] + households: + household: + members: [person_a, relative] + state_code: OK + output: + # A 20-year-old filer misses the 2020 age-25 minimum even with an older + # dependent who is not a qualifying child. + ok_federal_eitc_demographic_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/ok/tax/income/credits/eitc/ok_eitc.yaml b/policyengine_us/tests/policy/baseline/gov/states/ok/tax/income/credits/eitc/ok_eitc.yaml index 0098018092c..f9cfff404e0 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ok/tax/income/credits/eitc/ok_eitc.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ok/tax/income/credits/eitc/ok_eitc.yaml @@ -145,6 +145,234 @@ # No federal EITC = no OK EITC ok_eitc: 0 + +- name: "2025 single filer who can be claimed as a dependent: Oklahoma childless EITC" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_a] + households: + household: + members: [person_a] + state_code: OK + output: + # 68 O.S. 2357.43 uses the 2020 federal rules, which bar a childless + # filer who can be claimed as a dependent (IRC 32(c)(1)(A)(ii)(III); on a + # joint return, either spouse). + ok_federal_eitc_demographic_eligible: false + ok_eitc: 0 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: Oklahoma childless EITC (the claimable spouse is the head)" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: OK + output: + ok_federal_eitc_demographic_eligible: false + ok_eitc: 0 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: Oklahoma childless EITC (the claimable spouse is the spouse)" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_b, person_a] + filing_status: JOINT + households: + household: + members: [person_b, person_a] + state_code: OK + output: + ok_federal_eitc_demographic_eligible: false + ok_eitc: 0 + +- name: "2025 joint return on which both spouses can be claimed as dependents: Oklahoma childless EITC" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: OK + output: + ok_federal_eitc_demographic_eligible: false + ok_eitc: 0 + +- name: "2025 joint return on which neither spouse can be claimed: Oklahoma childless EITC" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: OK + output: + # 2020 rules: min($5,000 x 7.65%, $538) = $382.50; 5% = $19.125. + ok_federal_eitc_demographic_eligible: true + ok_eitc: 19.125 + +- name: "2025 single filer who cannot be claimed as a dependent: Oklahoma childless EITC" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: [person_a] + households: + household: + members: [person_a] + state_code: OK + output: + ok_federal_eitc_demographic_eligible: true + ok_eitc: 19.125 + + +- name: "2025 single filer who can be claimed as a dependent by someone who files only for a refund: Oklahoma childless EITC" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: true + tax_units: + tax_unit: + members: [person_a] + households: + household: + members: [person_a] + state_code: OK + output: + # The 2020 federal test lets the filer qualify under Publication 596's + # exception: 5% of $382.50. + ok_federal_eitc_demographic_eligible: true + ok_eitc: 19.125 + +- name: "2025 single filer who can be claimed as a dependent but is not claimed: Oklahoma childless EITC" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_a] + households: + household: + members: [person_a] + state_code: OK + output: + # The 2020 federal test bars a filer who can be claimed, claimed or not. + ok_federal_eitc_demographic_eligible: false + ok_eitc: 0 + - name: OK EITC - 2025 - a spouse's self-employment loss reduces the phase-in base period: 2025 absolute_error_margin: 0.01 @@ -211,3 +439,4 @@ # give 5,920 - 21.06% x 14,780 = 2,807.33. ok_federal_eitc: 4_913.33 ok_eitc: 245.67 + diff --git a/policyengine_us/tests/policy/baseline/gov/states/ok/tax/income/ok_child_care_child_tax_credit.yaml b/policyengine_us/tests/policy/baseline/gov/states/ok/tax/income/ok_child_care_child_tax_credit.yaml index 1f7b77e70cc..35838e10aeb 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ok/tax/income/ok_child_care_child_tax_credit.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ok/tax/income/ok_child_care_child_tax_credit.yaml @@ -174,3 +174,201 @@ ok_federal_ctc: 2_799 ok_child_care_child_tax_credit: 140 taxsim_ok_child_tax_credit_component: 140 + + +- name: "2025 single filer who can be claimed as a dependent: Oklahoma child tax credit component" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 10_000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child_1] + households: + household: + members: [person_a, child_1] + state_code: OK + output: + # 68 O.S. 2357: 5% of the federal child tax credit allowed, which IRC 24(a) + # and 152(b)(1) deny on this return. + ok_child_care_child_tax_credit: 0 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: Oklahoma child tax credit component (the claimable spouse is the head)" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 5000 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: OK + output: + ok_child_care_child_tax_credit: 0 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: Oklahoma child tax credit component (the claimable spouse is the spouse)" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_b: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child_1] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child_1] + state_code: OK + output: + ok_child_care_child_tax_credit: 0 + +- name: "2025 joint return on which both spouses can be claimed as dependents: Oklahoma child tax credit component" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 5000 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: OK + output: + ok_child_care_child_tax_credit: 0 + +- name: "2025 joint return on which neither spouse can be claimed: Oklahoma child tax credit component" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_b: + age: 30 + employment_income: 5000 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: OK + output: + # Refundable CTC 15% x ($10,000 - $2,500) = $1,125; 5% = $56.25. + ok_child_care_child_tax_credit: 56.25 + +- name: "2025 single filer who cannot be claimed as a dependent: Oklahoma child tax credit component" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 10_000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child_1] + households: + household: + members: [person_a, child_1] + state_code: OK + output: + ok_child_care_child_tax_credit: 56.25 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ok/tax/income/ok_count_exemptions.yaml b/policyengine_us/tests/policy/baseline/gov/states/ok/tax/income/ok_count_exemptions.yaml index 53ab4207cd1..f8efe7f1586 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ok/tax/income/ok_count_exemptions.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ok/tax/income/ok_count_exemptions.yaml @@ -116,3 +116,556 @@ +- name: "2025 single filer who can be claimed as a dependent: Oklahoma exemptions" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_a] + households: + household: + members: [person_a] + state_code: OK + output: + # Form 511 item F: "If you can be claimed as a dependent on another + # return, enter '0' for your exemption." + ok_count_exemptions: 0 + ok_exemptions: 0 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: Oklahoma exemptions (the claimable spouse is the head)" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: OK + output: + # Only the spouse who cannot be claimed keeps a $1,000 exemption. + ok_count_exemptions: 1 + ok_exemptions: 1000 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: Oklahoma exemptions (the claimable spouse is the spouse)" + period: 2025 + input: + people: + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_b, person_a] + filing_status: JOINT + households: + household: + members: [person_b, person_a] + state_code: OK + output: + ok_count_exemptions: 1 + ok_exemptions: 1000 + +- name: "2025 joint return on which both spouses can be claimed as dependents: Oklahoma exemptions" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: OK + output: + ok_count_exemptions: 0 + ok_exemptions: 0 + +- name: "2025 joint return on which neither spouse can be claimed: Oklahoma exemptions" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: OK + output: + ok_count_exemptions: 2 + ok_exemptions: 2000 + +- name: "2025 single filer who cannot be claimed as a dependent: Oklahoma exemptions" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: [person_a] + households: + household: + members: [person_a] + state_code: OK + output: + ok_count_exemptions: 1 + ok_exemptions: 1000 + +- name: "2025 single filer who can be claimed as a dependent: Oklahoma exemptions with a child" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child_1] + households: + household: + members: [person_a, child_1] + state_code: OK + output: + # Dependents are "as defined in IRC Sec. 152" (item F). IRC 152(b)(1) + # leaves none here. + ok_count_exemptions: 0 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: Oklahoma exemptions with a child (the claimable spouse is the head)" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: OK + output: + ok_count_exemptions: 1 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: Oklahoma exemptions with a child (the claimable spouse is the spouse)" + period: 2025 + input: + people: + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child_1] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child_1] + state_code: OK + output: + ok_count_exemptions: 1 + +- name: "2025 joint return on which both spouses can be claimed as dependents: Oklahoma exemptions with a child" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: OK + output: + ok_count_exemptions: 0 + +- name: "2025 joint return on which neither spouse can be claimed: Oklahoma exemptions with a child" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: OK + output: + ok_count_exemptions: 3 + +- name: "2025 single filer who cannot be claimed as a dependent: Oklahoma exemptions with a child" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child_1] + households: + household: + members: [person_a, child_1] + state_code: OK + output: + ok_count_exemptions: 2 + +- name: 2025 a claimable filer aged 65 or older keeps the special exemption + period: 2025 + input: + people: + person_a: + age: 66 + taxable_interest_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_a] + households: + household: + members: [person_a] + state_code: OK + output: + # The special (65 or older) exemption is a separate box with no + # dependency bar; only the regular exemption is zero. + ok_count_exemptions: 1 + +- name: 2025 a claimable blind filer keeps the blind exemption + period: 2025 + input: + people: + person_a: + age: 30 + is_blind: true + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_a] + households: + household: + members: [person_a] + state_code: OK + output: + # The blind exemption is a separate box with no dependency bar. + ok_count_exemptions: 1 + + +- name: "2025 single filer who can be claimed as a dependent but is not claimed: Oklahoma exemptions with a child" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child_1] + households: + household: + members: [person_a, child_1] + state_code: OK + output: + # Form 511: "If you can be claimed as a dependent on another return, + # enter '0' for your exemption"; no dependents either (IRC 152(b)(1)). + ok_count_exemptions: 0 + +- name: "2025 single filer who can be claimed as a dependent by someone who files only for a refund: Oklahoma exemptions with a child" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child_1] + households: + household: + members: [person_a, child_1] + state_code: OK + output: + # Still no regular exemption (the filer can be claimed), but + # Publication 501's exception restores the dependent. + ok_count_exemptions: 1 + ok_exemptions: 1000 + +- name: "2025 joint return with one spouse who can be claimed as a dependent by someone who files only for a refund: Oklahoma exemptions with a child (the claimable spouse is the head)" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: true + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: false + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: OK + output: + # The other spouse and restored dependent give two exemptions. + # The sales tax credit pays $40 per exemption: $80. + ok_count_exemptions: 2 + ok_stc: 80 + +- name: "2025 joint return with one spouse who can be claimed as a dependent by someone who files only for a refund: Oklahoma exemptions with a child (the claimable spouse is the spouse)" + period: 2025 + input: + people: + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: false + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child_1] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child_1] + state_code: OK + output: + ok_count_exemptions: 2 + ok_stc: 80 + +- name: Claimable 66-year-old single filer keeps the special exemption + period: 2025 + input: + state_code: OK + age: 66 + filing_status: SINGLE + claimable_as_dependent_on_another_return: true + adjusted_gross_income: 10000 + output: + ok_count_exemptions: 1 + ok_exemptions: 1000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ok/tax/income/ok_stc.yaml b/policyengine_us/tests/policy/baseline/gov/states/ok/tax/income/ok_stc.yaml index 9fdae1540a5..7536447b99b 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ok/tax/income/ok_stc.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ok/tax/income/ok_stc.yaml @@ -219,3 +219,544 @@ # elderly $50,000 limit and restoring the $40-per-person credit. ok_gross_income: 38_565.84 ok_stc: 80 + + +- name: "2025 single filer who can be claimed as a dependent: Oklahoma sales tax credit" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_a] + households: + household: + members: [person_a] + state_code: OK + output: + # 68 O.S. 5011(D): $40 times the allowable personal exemptions under + # the Income Tax Act, which gives a claimable filer none. + ok_stc: 0 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: Oklahoma sales tax credit (the claimable spouse is the head)" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: OK + output: + ok_stc: 40 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: Oklahoma sales tax credit (the claimable spouse is the spouse)" + period: 2025 + input: + people: + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_b, person_a] + filing_status: JOINT + households: + household: + members: [person_b, person_a] + state_code: OK + output: + ok_stc: 40 + +- name: "2025 joint return on which both spouses can be claimed as dependents: Oklahoma sales tax credit" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: OK + output: + ok_stc: 0 + +- name: "2025 joint return on which neither spouse can be claimed: Oklahoma sales tax credit" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: OK + output: + ok_stc: 80 + +- name: "2025 single filer who cannot be claimed as a dependent: Oklahoma sales tax credit" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: [person_a] + households: + household: + members: [person_a] + state_code: OK + output: + ok_stc: 40 + +- name: "2025 single filer who can be claimed as a dependent: Oklahoma sales tax credit with a child" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child_1] + households: + household: + members: [person_a, child_1] + state_code: OK + output: + ok_stc: 0 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: Oklahoma sales tax credit with a child (the claimable spouse is the head)" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: OK + output: + # The child is not an allowable exemption on this return (IRC 152(b)(1)). + ok_stc: 40 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: Oklahoma sales tax credit with a child (the claimable spouse is the spouse)" + period: 2025 + input: + people: + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child_1] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child_1] + state_code: OK + output: + ok_stc: 40 + +- name: "2025 joint return on which both spouses can be claimed as dependents: Oklahoma sales tax credit with a child" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: OK + output: + ok_stc: 0 + +- name: "2025 joint return on which neither spouse can be claimed: Oklahoma sales tax credit with a child" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 2500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_b: + age: 30 + employment_income: 2500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: OK + output: + ok_stc: 120 + +- name: "2025 single filer who cannot be claimed as a dependent: Oklahoma sales tax credit with a child" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child_1] + households: + household: + members: [person_a, child_1] + state_code: OK + output: + ok_stc: 80 + +- name: "2025 single filer who can be claimed as a dependent: Oklahoma sales tax credit income limit with a child" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 30_000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child_1] + households: + household: + members: [person_a, child_1] + state_code: OK + output: + # Income $30,000 is over the $20,000 limit; the $50,000 limit needs a + # dependent the filer can claim, or age 65+, or a disability. + ok_stc: 0 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: Oklahoma sales tax credit income limit with a child (the claimable spouse is the head)" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 15_000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 15_000 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: OK + output: + ok_stc: 0 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: Oklahoma sales tax credit income limit with a child (the claimable spouse is the spouse)" + period: 2025 + input: + people: + person_b: + age: 30 + employment_income: 15_000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_a: + age: 30 + employment_income: 15_000 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child_1] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child_1] + state_code: OK + output: + ok_stc: 0 + +- name: "2025 joint return on which both spouses can be claimed as dependents: Oklahoma sales tax credit income limit with a child" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 15_000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 15_000 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: OK + output: + ok_stc: 0 + +- name: "2025 joint return on which neither spouse can be claimed: Oklahoma sales tax credit income limit with a child" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 15_000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_b: + age: 30 + employment_income: 15_000 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: OK + output: + # The child qualifies the return for the $50,000 limit: 3 x $40. + ok_stc: 120 + +- name: "2025 single filer who cannot be claimed as a dependent: Oklahoma sales tax credit income limit with a child" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 30_000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child_1] + households: + household: + members: [person_a, child_1] + state_code: OK + output: + ok_stc: 80 diff --git a/policyengine_us/tests/policy/baseline/gov/states/pa/tax/income/credits/pa_cdcc.yaml b/policyengine_us/tests/policy/baseline/gov/states/pa/tax/income/credits/pa_cdcc.yaml index 6492d950f84..9553d4075e4 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/pa/tax/income/credits/pa_cdcc.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/pa/tax/income/credits/pa_cdcc.yaml @@ -79,3 +79,207 @@ # cdcc_rate at 45k AGI = 20% floor; potential = 600; PA match 100% in 2023 cdcc_potential: 600 pa_cdcc: 600 + + +- name: "2025 single filer who can be claimed as a dependent: Pennsylvania child care credit for an ordinary child" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 20_000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 4 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child_1] + households: + household: + members: [person_a, child_1] + state_code: PA + output: + # IRC 21(b)(1)(A) needs a dependent of the taxpayer under 13; IRC 152(b)(1) + # leaves none here. + pa_cdcc: 0 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: Pennsylvania child care credit for an ordinary child (the claimable spouse is the head)" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 10_000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 10_000 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 4 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: PA + output: + pa_cdcc: 0 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: Pennsylvania child care credit for an ordinary child (the claimable spouse is the spouse)" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_b: + age: 30 + employment_income: 10_000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_a: + age: 30 + employment_income: 10_000 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 4 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child_1] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child_1] + state_code: PA + output: + pa_cdcc: 0 + +- name: "2025 joint return on which both spouses can be claimed as dependents: Pennsylvania child care credit for an ordinary child" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 10_000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 10_000 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 4 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: PA + output: + pa_cdcc: 0 + +- name: "2025 joint return on which neither spouse can be claimed: Pennsylvania child care credit for an ordinary child" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 10_000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_b: + age: 30 + employment_income: 10_000 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 4 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: PA + output: + # AGI $20,000: 35% less 3 points = 32% of $1,000 = $320, matched 100%. + pa_cdcc: 320 + +- name: "2025 single filer who cannot be claimed as a dependent: Pennsylvania child care credit for an ordinary child" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 20_000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 4 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child_1] + households: + household: + members: [person_a, child_1] + state_code: PA + output: + pa_cdcc: 320 diff --git a/policyengine_us/tests/policy/baseline/gov/states/pa/tax/income/credits/pa_eitc.yaml b/policyengine_us/tests/policy/baseline/gov/states/pa/tax/income/credits/pa_eitc.yaml index aef5ec3dbb7..0f2881e316c 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/pa/tax/income/credits/pa_eitc.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/pa/tax/income/credits/pa_eitc.yaml @@ -24,3 +24,171 @@ eitc: 7_430 output: pa_eitc: 743 + + +- name: "2025 single filer who can be claimed as a dependent: Working Pennsylvanians credit without a child" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 3000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_a] + households: + household: + members: [person_a] + state_code: PA + output: + # 10% of the federal EITC, which IRC 32(c)(1)(A)(ii)(III) denies a childless + # return with a filer who can be claimed as a dependent. + pa_eitc: 0 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: Working Pennsylvanians credit without a child (the claimable spouse is the head)" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 1500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 1500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: PA + output: + pa_eitc: 0 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: Working Pennsylvanians credit without a child (the claimable spouse is the spouse)" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_b: + age: 30 + employment_income: 1500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_a: + age: 30 + employment_income: 1500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_b, person_a] + filing_status: JOINT + households: + household: + members: [person_b, person_a] + state_code: PA + output: + pa_eitc: 0 + +- name: "2025 joint return on which both spouses can be claimed as dependents: Working Pennsylvanians credit without a child" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 1500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 1500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: PA + output: + pa_eitc: 0 + +- name: "2025 joint return on which neither spouse can be claimed: Working Pennsylvanians credit without a child" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 1500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_b: + age: 30 + employment_income: 1500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: PA + output: + # $3,000 x 7.65% = $229.50; 10% = $22.95. + pa_eitc: 22.95 + +- name: "2025 single filer who cannot be claimed as a dependent: Working Pennsylvanians credit without a child" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 3000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: [person_a] + households: + household: + members: [person_a] + state_code: PA + output: + pa_eitc: 22.95 diff --git a/policyengine_us/tests/policy/baseline/gov/states/pa/tax/income/forgiveness/pa_tax_forgiveness_amount.yaml b/policyengine_us/tests/policy/baseline/gov/states/pa/tax/income/forgiveness/pa_tax_forgiveness_amount.yaml index 0d0664d46b8..a600522c2c9 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/pa/tax/income/forgiveness/pa_tax_forgiveness_amount.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/pa/tax/income/forgiveness/pa_tax_forgiveness_amount.yaml @@ -6,3 +6,530 @@ pa_tax_forgiveness_rate: 0.5 output: pa_tax_forgiveness_amount: 1 + + +- name: "2025 single filer who can be claimed as a dependent: Pennsylvania tax forgiveness" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 3000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_a] + households: + household: + members: [person_a] + state_code: PA + output: + pa_tax_forgiveness_eligible_share: 0 + pa_tax_forgiveness_amount: 0 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: Pennsylvania tax forgiveness (the claimable spouse is the head)" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 3000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 3000 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: PA + output: + pa_tax_forgiveness_eligible_share: 0.5 + pa_tax_forgiveness_amount: 92.1 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: Pennsylvania tax forgiveness (the claimable spouse is the spouse)" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_b: + age: 30 + employment_income: 3000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_a: + age: 30 + employment_income: 3000 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_b, person_a] + filing_status: JOINT + households: + household: + members: [person_b, person_a] + state_code: PA + output: + pa_tax_forgiveness_eligible_share: 0.5 + pa_tax_forgiveness_amount: 92.1 + +- name: "2025 joint return on which both spouses can be claimed as dependents: Pennsylvania tax forgiveness" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 3000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 3000 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: PA + output: + pa_tax_forgiveness_eligible_share: 0 + pa_tax_forgiveness_amount: 0 + +- name: "2025 joint return on which neither spouse can be claimed: Pennsylvania tax forgiveness" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 3000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_b: + age: 30 + employment_income: 3000 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: PA + output: + pa_tax_forgiveness_eligible_share: 1 + pa_tax_forgiveness_amount: 184.2 + +- name: "2025 single filer who cannot be claimed as a dependent: Pennsylvania tax forgiveness" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 3000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: [person_a] + households: + household: + members: [person_a] + state_code: PA + output: + pa_tax_forgiveness_eligible_share: 1 + pa_tax_forgiveness_amount: 92.1 + +- name: "2025 single filer who can be claimed as a dependent: Pennsylvania tax forgiveness with a child" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 8000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child_1] + households: + household: + members: [person_a, child_1] + state_code: PA + output: + pa_tax_forgiveness_rate: 0.4 + pa_tax_forgiveness_amount: 0 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: Pennsylvania tax forgiveness with a child (the claimable spouse is the head)" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 7500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 7500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: PA + output: + pa_tax_forgiveness_rate: 0.2 + pa_tax_forgiveness_amount: 46.05 + +- name: "2025 joint return with one spouse who can be claimed as a dependent: Pennsylvania tax forgiveness with a child (the claimable spouse is the spouse)" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_b: + age: 30 + employment_income: 7500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_a: + age: 30 + employment_income: 7500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child_1] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child_1] + state_code: PA + output: + pa_tax_forgiveness_rate: 0.2 + pa_tax_forgiveness_amount: 46.05 + +- name: "2025 joint return on which neither spouse can be claimed: Pennsylvania tax forgiveness with a child" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 7500 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + person_b: + age: 30 + employment_income: 7500 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child_1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child_1] + state_code: PA + output: + pa_tax_forgiveness_rate: 1 + pa_tax_forgiveness_amount: 460.5 + +- name: "2025 single filer who cannot be claimed as a dependent: Pennsylvania tax forgiveness with a child" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 8000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child_1] + households: + household: + members: [person_a, child_1] + state_code: PA + output: + pa_tax_forgiveness_rate: 1 + pa_tax_forgiveness_amount: 245.6 + + +- name: "2025 single filer who can be claimed as a dependent but is not claimed: Pennsylvania tax forgiveness" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 3000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_a] + households: + household: + members: [person_a] + state_code: PA + output: + pa_tax_forgiveness_eligible_share: 0 + pa_tax_forgiveness_amount: 0 + +- name: "2025 joint return with one spouse who can be claimed as a dependent but is not claimed: Pennsylvania tax forgiveness (the claimable spouse is the head)" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 3000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 3000 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: PA + output: + pa_tax_forgiveness_eligible_share: 0.5 + pa_tax_forgiveness_amount: 92.1 + +- name: "2025 joint return with one spouse who can be claimed as a dependent but is not claimed: Pennsylvania tax forgiveness (the claimable spouse is the spouse)" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_b: + age: 30 + employment_income: 3000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: false + person_a: + age: 30 + employment_income: 3000 + is_tax_unit_head: false + is_tax_unit_spouse: true + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_b, person_a] + filing_status: JOINT + households: + household: + members: [person_b, person_a] + state_code: PA + output: + pa_tax_forgiveness_eligible_share: 0.5 + pa_tax_forgiveness_amount: 92.1 + +- name: "2025 single filer who can be claimed as a dependent but is not claimed: Pennsylvania tax forgiveness with a child" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 8000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child_1] + households: + household: + members: [person_a, child_1] + state_code: PA + output: + pa_tax_forgiveness_rate: 0.4 + pa_tax_forgiveness_amount: 0 + +- name: "2025 single filer who can be claimed as a dependent by someone who files only for a refund: Pennsylvania tax forgiveness" + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person_a: + age: 30 + employment_income: 8000 + is_tax_unit_head: true + is_tax_unit_spouse: false + is_tax_unit_dependent: false + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: true + child_1: + age: 5 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child_1] + households: + household: + members: [person_a, child_1] + state_code: PA + output: + pa_tax_forgiveness_rate: 1 + pa_tax_forgiveness_amount: 0 + +- name: 2025 single filer claimed and claimable with $6,000 Pennsylvania income + period: 2025 + absolute_error_margin: 0.01 + input: + state_code: PA + is_tax_unit_head: true + claimed_as_dependent_on_another_return: true + claimable_as_dependent_on_another_return: true + pa_eligibility_income: 6000 + pa_adjusted_taxable_income: 6000 + output: + pa_income_tax_before_forgiveness: 184.20 + pa_tax_forgiveness_amount: 0 + +- name: 2025 single filer claimable and not claimed with $6,000 Pennsylvania income + period: 2025 + absolute_error_margin: 0.01 + input: + state_code: PA + is_tax_unit_head: true + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: true + pa_eligibility_income: 6000 + pa_adjusted_taxable_income: 6000 + output: + pa_income_tax_before_forgiveness: 184.20 + pa_tax_forgiveness_amount: 0 + +- name: 2025 single filer neither claimed nor claimable with $6,000 Pennsylvania income + period: 2025 + absolute_error_margin: 0.01 + input: + state_code: PA + is_tax_unit_head: true + claimed_as_dependent_on_another_return: false + claimable_as_dependent_on_another_return: false + pa_eligibility_income: 6000 + pa_adjusted_taxable_income: 6000 + output: + pa_income_tax_before_forgiveness: 184.20 + pa_tax_forgiveness_amount: 184.2 diff --git a/policyengine_us/tests/policy/contrib/state_dependent_exemptions/repeal_state_dependent_exemptions.yaml b/policyengine_us/tests/policy/contrib/state_dependent_exemptions/repeal_state_dependent_exemptions.yaml index a476fc6a3b3..6874647088b 100644 --- a/policyengine_us/tests/policy/contrib/state_dependent_exemptions/repeal_state_dependent_exemptions.yaml +++ b/policyengine_us/tests/policy/contrib/state_dependent_exemptions/repeal_state_dependent_exemptions.yaml @@ -495,6 +495,70 @@ # Baseline keeps the dependent add: 7,600 + 1 x 1,000 + 6,800 = 15,400. ma_income_tax_exemption_threshold: 15_400 +- name: Oklahoma joint filers with one dependent, one spouse claimable elsewhere - reform keeps only the other spouse's exemption + period: 2025 + reforms: policyengine_us.reforms.state_dependent_exemptions.repeal_state_dependent_exemptions.repeal_state_dependent_exemptions + input: + gov.contrib.repeal_state_dependent_exemptions.in_effect: true + people: + person_a: + age: 30 + employment_income: 2_500 + is_tax_unit_head: true + is_tax_unit_spouse: false + claimed_as_dependent_on_another_return: true + person_b: + age: 30 + employment_income: 2_500 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 5 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: OK + output: + # As in the baseline, a spouse who can be claimed as a dependent has no + # regular exemption (Form 511 item F); the reform removes the dependent. + ok_count_exemptions: 1 + +- name: Oklahoma joint filers with one dependent, one spouse claimable elsewhere - reform keeps only the other spouse's exemption (labels exchanged) + period: 2025 + reforms: policyengine_us.reforms.state_dependent_exemptions.repeal_state_dependent_exemptions.repeal_state_dependent_exemptions + input: + gov.contrib.repeal_state_dependent_exemptions.in_effect: true + people: + person_b: + age: 30 + employment_income: 2_500 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 30 + employment_income: 2_500 + is_tax_unit_head: false + is_tax_unit_spouse: true + claimed_as_dependent_on_another_return: true + child: + age: 5 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child] + state_code: OK + output: + ok_count_exemptions: 1 + # California keeps its personal credits under the repeal, with the baseline's # rule that a filer who can be claimed as a dependent gets none (RTC 17054; # Form 540 line 7). 2025: $153 per credit. diff --git a/policyengine_us/tests/policy/contrib/states/nj/dependent_exemption_reform_test.yaml b/policyengine_us/tests/policy/contrib/states/nj/dependent_exemption_reform_test.yaml index fc009406f12..4ee2a31b3de 100644 --- a/policyengine_us/tests/policy/contrib/states/nj/dependent_exemption_reform_test.yaml +++ b/policyengine_us/tests/policy/contrib/states/nj/dependent_exemption_reform_test.yaml @@ -92,3 +92,30 @@ households: {household: {members: [parent, child1], state_name: NJ}} # Dependent one year under the limit (12 < 13) is re-priced to the reform amount (0). output: {nj_dependents_exemption: 0} + +- name: NJ dependent exemption reform - a filer who can be claimed as a dependent has no dependents + period: 2025 + reforms: policyengine_us.reforms.states.nj.dependent_exemption.nj_dependent_exemption_reform.nj_dependent_exemption_reform + input: + gov.contrib.states.nj.dependent_exemption.in_effect: true + gov.contrib.states.nj.dependent_exemption.amount: 3_000 + people: + parent: {age: 20, employment_income: 10_000, claimed_as_dependent_on_another_return: true} + child1: {age: 2, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [parent, child1], filing_status: SINGLE}} + households: {household: {members: [parent, child1], state_name: NJ}} + output: {nj_dependents_exemption: 0} # IRC 152(b)(1) + +- name: NJ dependent exemption reform - one claimable spouse leaves the joint return with no dependents + period: 2025 + reforms: policyengine_us.reforms.states.nj.dependent_exemption.nj_dependent_exemption_reform.nj_dependent_exemption_reform + input: + gov.contrib.states.nj.dependent_exemption.in_effect: true + gov.contrib.states.nj.dependent_exemption.amount: 3_000 + people: + spouse_b: {age: 22, employment_income: 10_000, is_tax_unit_head: true, is_tax_unit_spouse: false} + spouse_a: {age: 20, is_tax_unit_head: false, is_tax_unit_spouse: true, claimed_as_dependent_on_another_return: true} + child1: {age: 2, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [spouse_b, spouse_a, child1], filing_status: JOINT}} + households: {household: {members: [spouse_b, spouse_a, child1], state_name: NJ}} + output: {nj_dependents_exemption: 0} diff --git a/policyengine_us/tests/policy/contrib/states/ok/dependent_exemption_reform_test.yaml b/policyengine_us/tests/policy/contrib/states/ok/dependent_exemption_reform_test.yaml index 993c3c34fbb..ed2d4fc8db6 100644 --- a/policyengine_us/tests/policy/contrib/states/ok/dependent_exemption_reform_test.yaml +++ b/policyengine_us/tests/policy/contrib/states/ok/dependent_exemption_reform_test.yaml @@ -251,3 +251,65 @@ # $95, from 1,997.38 to 2,092.38. output: ok_income_tax: 2092.38 + +- name: OK dependent exemption reform - a single filer who can be claimed as a dependent has no exemptions + period: 2025 + reforms: policyengine_us.reforms.states.ok.dependent_exemption.ok_dependent_exemption_reform.ok_dependent_exemption_reform + input: + gov.contrib.states.ok.dependent_exemption.in_effect: true + gov.contrib.states.ok.dependent_exemption.amount: 2_000 + people: + parent: + age: 20 + employment_income: 10_000 + claimed_as_dependent_on_another_return: true + child1: + age: 2 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [parent, child1] + filing_status: SINGLE + households: + household: + members: [parent, child1] + state_name: OK + output: + # No regular exemption for the claimable filer, and no dependents on the + # return (IRC 152(b)(1)), so the reform's dependent amount never applies. + ok_eligible_dependents_count: 0 + ok_dependent_exemption: 0 + ok_exemptions: 0 + +- name: OK dependent exemption reform - one claimable spouse keeps only the other spouse's exemption + period: 2025 + reforms: policyengine_us.reforms.states.ok.dependent_exemption.ok_dependent_exemption_reform.ok_dependent_exemption_reform + input: + gov.contrib.states.ok.dependent_exemption.in_effect: true + gov.contrib.states.ok.dependent_exemption.amount: 2_000 + people: + spouse_b: + age: 22 + employment_income: 10_000 + is_tax_unit_head: true + is_tax_unit_spouse: false + spouse_a: + age: 20 + is_tax_unit_head: false + is_tax_unit_spouse: true + claimed_as_dependent_on_another_return: true + child1: + age: 2 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [spouse_b, spouse_a, child1] + filing_status: JOINT + households: + household: + members: [spouse_b, spouse_a, child1] + state_name: OK + output: + ok_eligible_dependents_count: 0 + ok_older_dependents_count: 0 + ok_exemptions: 1_000 diff --git a/policyengine_us/tests/test_eitc_marital_eligibility_properties.py b/policyengine_us/tests/test_eitc_marital_eligibility_properties.py index 8a640b47a71..44801693e53 100644 --- a/policyengine_us/tests/test_eitc_marital_eligibility_properties.py +++ b/policyengine_us/tests/test_eitc_marital_eligibility_properties.py @@ -250,6 +250,7 @@ def nj_units(rows, marital_eligible): marital = np.asarray(marital_eligible, dtype=bool) eligible = other_federal.astype(bool) & marital zeros = np.zeros(len(rows)) + no_one = np.zeros(len(rows), dtype=bool) values = { "filing_status": status.view(FilingStatuses), "eitc_marital_eligible": marital, @@ -263,10 +264,15 @@ def nj_units(rows, marital_eligible): "foreign_earned_income_exclusion": zeros, "section_911_excluded_income": zeros, **{variable: zeros for variable in SECTION_911_LEAF_INPUTS}, + # Each unit's only member files the return, and no other return + # claims or lists them, so the dependent-filer bars never apply. + "head_or_spouse_is_dependent_elsewhere_without_filing_exception": no_one, } person_values = { "age": age, "is_tax_unit_head_or_spouse": np.ones(len(rows), dtype=bool), + "is_tax_unit_dependent": no_one, + "claimed_as_dependent_on_another_return": no_one, "is_separated_under_decree": decree.astype(bool), } return Units(np.arange(len(rows)), person_values, values) diff --git a/policyengine_us/variables/gov/states/nd/tax/income/subtractions/nd_stillborn_subtraction.py b/policyengine_us/variables/gov/states/nd/tax/income/subtractions/nd_stillborn_subtraction.py index c06800bc923..0926532a84f 100644 --- a/policyengine_us/variables/gov/states/nd/tax/income/subtractions/nd_stillborn_subtraction.py +++ b/policyengine_us/variables/gov/states/nd/tax/income/subtractions/nd_stillborn_subtraction.py @@ -8,9 +8,15 @@ class nd_stillborn_subtraction(Variable): unit = USD definition_period = YEAR defined_for = StateCode.ND - reference = "https://ndlegis.gov/cencode/t57c38.pdf#nameddest=57-38-30p3" + reference = ( + "https://ndlegis.gov/cencode/t57c38.pdf#nameddest=57-38-30p3", + # 2025 Schedule ND-1SA instructions, line 8. + "https://www.tax.nd.gov/sites/www/files/documents/forms/individual/2025-iit/28710-schedule-nd-1sa-2025.pdf#page=2", + ) def formula(tax_unit, period, parameters): p = parameters(period).gov.states.nd.tax.income.taxable_income.subtractions stillborn = tax_unit("tax_unit_stillborn_children", period) + # The instructions say the child must qualify as a federal dependent. + # N.D.C.C. 57-38-30.3(2)(p) imposes no dependency condition. return stillborn * p.stillborn 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..1ea849d16e8 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 @@ -12,6 +12,7 @@ class nj_ctc(Variable): "https://www.nj.gov/treasury/taxation/pdf/other_forms/tgi-ee/2021/1040i.pdf#page=44", "https://www.nj.gov/treasury/taxation/pdf/other_forms/tgi-ee/2022/1040i.pdf#page=44", "https://www.state.nj.us/treasury/taxation/pdf/current/1040i.pdf#page=46", + "https://www.law.cornell.edu/uscode/text/26/152#b_1", ) defined_for = "nj_ctc_eligible" @@ -22,10 +23,19 @@ 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 + # Get the number of eligible children dependents. N.J.S.A. 54A:4-17.1 + # counts each child who qualifies for the dependent exemption under + # 54A:3-1, which follows federal dependency, and a return on which the + # filer (or, if joint, either spouse) can be claimed as a dependent + # has no dependents (IRC 152(b)(1)). + # Publication 501 excepts a return whose would-be claimant files only + # for a refund. person = tax_unit.members age_eligible = person("age", period) < p.age_limit - dependent = person("is_tax_unit_dependent", period) + filer_is_dependent = person.tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) + dependent = person("is_tax_unit_dependent", period) & ~filer_is_dependent age_eligible_dependent = age_eligible & dependent count_eligible = tax_unit.sum(age_eligible_dependent) diff --git a/policyengine_us/variables/gov/states/nj/tax/income/credits/eitc/nj_childless_eitc_age_eligible.py b/policyengine_us/variables/gov/states/nj/tax/income/credits/eitc/nj_childless_eitc_age_eligible.py index 70c7251cd86..f33603d829c 100644 --- a/policyengine_us/variables/gov/states/nj/tax/income/credits/eitc/nj_childless_eitc_age_eligible.py +++ b/policyengine_us/variables/gov/states/nj/tax/income/credits/eitc/nj_childless_eitc_age_eligible.py @@ -13,6 +13,9 @@ class nj_childless_eitc_age_eligible(Variable): # qualifications, except for the minimum or maximum age, for the # federal earned income tax credit". "https://pub.njleg.state.nj.us/Bills/2020/PL21/130_.HTM", + "https://www.law.cornell.edu/uscode/text/26/32#c_1_A_ii", + # 2025 NJ-1040 instructions, line 58. + "https://www.nj.gov/treasury/taxation/pdf/current/1040i.pdf#page=44", ) defined_for = StateCode.NJ @@ -31,14 +34,31 @@ def formula(tax_unit, period, parameters): # Get the NJ EITC paramaeter tree. p = parameters(period).gov.states.nj.tax.income.credits.eitc - # Check if the filer meets NJ EITC age requirements. + # Check if the filer meets NJ EITC age requirements. The age test + # applies to the filer or, on a joint return, either spouse, never to + # a dependent (IRC 32(c)(1)(A)(ii)(II)). age = person("age", period) - age_eligible = age >= p.eligibility.age.min + is_filer_or_spouse = ~person("is_tax_unit_dependent", period) + age_eligible = (age >= p.eligibility.age.min) & is_filer_or_spouse # Section 32(c)(1)(C): a filer who claims the benefits of section 911 # fails a federal qualification other than age. claims_section_911 = elects_section_911_exclusion(tax_unit, period) + # Section 32(c)(1)(A)(ii)(III): without a qualifying child, the filer + # must not be a dependent of another taxpayer, and on a joint return + # neither spouse may be, unless the would-be claimant files only for a + # refund (Publication 596), as for the federal credit. + dependent_elsewhere = tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) + # The NJ-1040 line 58 worksheet also requires "You are not listed as a + # dependent on another tax return", an actual claim. + filer = person("is_tax_unit_head_or_spouse", period) + listed_elsewhere = tax_unit.any( + filer & person("claimed_as_dependent_on_another_return", period) + ) + return ( marital_eligible & nj_separate_filer_eligible @@ -46,4 +66,6 @@ def formula(tax_unit, period, parameters): & tax_unit.any(age_eligible) & tax_unit("nj_eitc_income_eligible", period) & ~claims_section_911 + & ~dependent_elsewhere + & ~listed_elsewhere ) diff --git a/policyengine_us/variables/gov/states/nj/tax/income/exemptions/nj_dependents_attending_college_exemption.py b/policyengine_us/variables/gov/states/nj/tax/income/exemptions/nj_dependents_attending_college_exemption.py index 1bc22ebbdc8..eaf1e94258c 100644 --- a/policyengine_us/variables/gov/states/nj/tax/income/exemptions/nj_dependents_attending_college_exemption.py +++ b/policyengine_us/variables/gov/states/nj/tax/income/exemptions/nj_dependents_attending_college_exemption.py @@ -7,6 +7,12 @@ class nj_dependents_attending_college_exemption(Variable): label = "New Jersey dependents attending college exemption" unit = USD definition_period = YEAR + reference = ( + "https://law.justia.com/codes/new-jersey/title-54a/section-54a-3-1-1/", + # 2025 NJ-1040 instructions, line 12. + "https://www.nj.gov/treasury/taxation/pdf/current/1040i.pdf#page=9", + "https://www.law.cornell.edu/uscode/text/26/152#b_1", + ) defined_for = StateCode.NJ def formula(tax_unit, period, parameters): @@ -21,8 +27,16 @@ def formula(tax_unit, period, parameters): # Get person under 22 is_qualifying_age = person("age", period) <= p.age_threshold - # Get dependents in the members - is_dependent = person("is_tax_unit_dependent", period) + # Get dependents in the members. The student "must be claimed as a + # dependent on line 10 or 11" (NJ-1040 line 12), and a return on which + # the filer (or, if joint, either spouse) can be claimed as a + # dependent has no dependents (IRC 152(b)(1)). + # Publication 501 excepts a return whose would-be claimant files only + # for a refund. + filer_is_dependent = person.tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) + is_dependent = person("is_tax_unit_dependent", period) & ~filer_is_dependent # Get full time students is_full_time_college_student = person("is_full_time_college_student", period) diff --git a/policyengine_us/variables/gov/states/nj/tax/income/exemptions/nj_dependents_exemption.py b/policyengine_us/variables/gov/states/nj/tax/income/exemptions/nj_dependents_exemption.py index 9edea8f5072..d0fb51f0eea 100644 --- a/policyengine_us/variables/gov/states/nj/tax/income/exemptions/nj_dependents_exemption.py +++ b/policyengine_us/variables/gov/states/nj/tax/income/exemptions/nj_dependents_exemption.py @@ -5,7 +5,12 @@ class nj_dependents_exemption(Variable): value_type = float entity = TaxUnit label = "New Jersey qualified and other dependent children exemption" - reference = "https://law.justia.com/codes/new-jersey/title-54a/section-54a-3-1/" + reference = ( + "https://law.justia.com/codes/new-jersey/title-54a/section-54a-3-1/", + # 2025 NJ-1040 instructions, lines 10 and 11. + "https://www.nj.gov/treasury/taxation/pdf/current/1040i.pdf#page=9", + "https://www.law.cornell.edu/uscode/text/26/152#b_1", + ) unit = USD definition_period = YEAR defined_for = StateCode.NJ @@ -14,8 +19,16 @@ def formula(tax_unit, period, parameters): # Then get the NJ Exemptions part of the parameter tree. p = parameters(period).gov.states.nj.tax.income.exemptions.dependents - # Total the number of dependents. + # Total the number of dependents. Each must qualify "as your dependent + # for federal tax purposes" (NJ-1040 lines 10 and 11), and under IRC + # 152(b)(1) a return on which the filer (or, if joint, either spouse) + # can be claimed as a dependent has none. + # Publication 501 excepts a return whose would-be claimant files only + # for a refund. dependents = tax_unit("tax_unit_dependents", period) + filer_is_dependent = tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) # Get their dependent exemption amount based on their filing status. - return dependents * p.amount + return where(filer_is_dependent, 0, dependents) * p.amount diff --git a/policyengine_us/variables/gov/states/oh/tax/income/credits/oh_non_public_school_credits_potential.py b/policyengine_us/variables/gov/states/oh/tax/income/credits/oh_non_public_school_credits_potential.py index 0df3f8e3150..90f410d5ba3 100644 --- a/policyengine_us/variables/gov/states/oh/tax/income/credits/oh_non_public_school_credits_potential.py +++ b/policyengine_us/variables/gov/states/oh/tax/income/credits/oh_non_public_school_credits_potential.py @@ -7,13 +7,29 @@ class oh_non_public_school_credits_potential(Variable): label = "Ohio Nonchartered, Nonpublic, School Tuition Credit AGI Credit" unit = USD definition_period = YEAR - reference = "https://tax.ohio.gov/static/forms/ohio_individual/individual/2021/pit-it1040-booklet.pdf#page=21" + reference = ( + "https://tax.ohio.gov/static/forms/ohio_individual/individual/2021/pit-it1040-booklet.pdf#page=21", + "https://codes.ohio.gov/ohio-revised-code/section-5747.75", + # 5747.01(O): "Dependents" means dependents as defined in the IRC. + "https://codes.ohio.gov/ohio-revised-code/section-5747.01", + "https://www.law.cornell.edu/uscode/text/26/152#b_1", + ) defined_for = StateCode.OH def formula(tax_unit, period, parameters): p = parameters(period).gov.states.oh.tax.income.credits agi = tax_unit("adjusted_gross_income", period) person = tax_unit.members - tuition = tax_unit.sum(person("non_public_school_tuition", period)) + # R.C. 5747.75 counts the tuition paid "for all of the taxpayer's + # dependents", and 5747.01(O) takes dependents from the IRC, under + # which a return on which the filer (or, if joint, either spouse) can + # be claimed as a dependent has none (IRC 152(b)(1)). + # Publication 501 excepts a return whose would-be claimant files only + # for a refund. + filer_is_dependent = person.tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) + dependent = person("is_tax_unit_dependent", period) & ~filer_is_dependent + tuition = tax_unit.sum(person("non_public_school_tuition", period) * dependent) cap = p.non_public_tuition.calc(agi) return min_(tuition, cap) diff --git a/policyengine_us/variables/gov/states/oh/tax/income/deductions/medical_exepenses/insured_unreimbursed_expenses/oh_insured_unreimbursed_medical_care_expense_amount.py b/policyengine_us/variables/gov/states/oh/tax/income/deductions/medical_exepenses/insured_unreimbursed_expenses/oh_insured_unreimbursed_medical_care_expense_amount.py index fac1790799c..12031d3a32a 100644 --- a/policyengine_us/variables/gov/states/oh/tax/income/deductions/medical_exepenses/insured_unreimbursed_expenses/oh_insured_unreimbursed_medical_care_expense_amount.py +++ b/policyengine_us/variables/gov/states/oh/tax/income/deductions/medical_exepenses/insured_unreimbursed_expenses/oh_insured_unreimbursed_medical_care_expense_amount.py @@ -9,6 +9,7 @@ class oh_insured_unreimbursed_medical_care_expense_amount(Variable): definition_period = YEAR reference = ( "https://codes.ohio.gov/ohio-revised-code/section-5747.01", # R.C. 5747.01(A)(10)(b) + "https://uscode.house.gov/us/usc/t26/s152/", # IRC 152(b)(1) "https://dam.assets.ohio.gov/image/upload/v1767095693/tax.ohio.gov/forms/ohio_individual/individual/2025/it1040-booklet.pdf#page=25", # Line 44, pp. 25-26 "https://dam.assets.ohio.gov/image/upload/v1767095693/tax.ohio.gov/forms/ohio_individual/individual/2025/it1040-booklet.pdf#page=41", # Worksheet lines 3 and 4 "https://tax.ohio.gov/help-center/faqs/income-medical-and-health-care-expenses/income-medical-and-health-care-expenses", # Q8 and Q9: after-tax premiums go on line 3 @@ -26,4 +27,10 @@ def formula(person, period, parameters): eligible_premiums = premiums * (medicare_eligible | employer_plan_eligible) # Line 4 other_medical_expenses = person("other_medical_expenses", period) - return eligible_premiums + other_medical_expenses + filer_is_dependent = person.tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) + eligible_person = ( + person("is_tax_unit_head_or_spouse", period) | ~filer_is_dependent + ) + return eligible_person * (eligible_premiums + other_medical_expenses) diff --git a/policyengine_us/variables/gov/states/oh/tax/income/deductions/medical_exepenses/oh_long_term_care_insurance_premiums.py b/policyengine_us/variables/gov/states/oh/tax/income/deductions/medical_exepenses/oh_long_term_care_insurance_premiums.py index aa4bc562b6b..f43b3daf46e 100644 --- a/policyengine_us/variables/gov/states/oh/tax/income/deductions/medical_exepenses/oh_long_term_care_insurance_premiums.py +++ b/policyengine_us/variables/gov/states/oh/tax/income/deductions/medical_exepenses/oh_long_term_care_insurance_premiums.py @@ -9,6 +9,7 @@ class oh_long_term_care_insurance_premiums(Variable): definition_period = YEAR reference = ( "https://codes.ohio.gov/ohio-revised-code/section-5747.01", # R.C. 5747.01(A)(10) + "https://uscode.house.gov/us/usc/t26/s152/", # IRC 152(b)(1) "https://dam.assets.ohio.gov/image/upload/v1767095693/tax.ohio.gov/forms/ohio_individual/individual/2025/it1040-booklet.pdf#page=41", # Worksheet ) documentation = ( @@ -39,4 +40,10 @@ def formula(person, period, parameters): - long_term_care_part - person("medical_expense_health_insurance_premiums", period), ) - return max_(premiums - long_term_care_part - unabsorbed, 0) + filer_is_dependent = person.tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) + eligible_person = ( + person("is_tax_unit_head_or_spouse", period) | ~filer_is_dependent + ) + return eligible_person * max_(premiums - long_term_care_part - unabsorbed, 0) diff --git a/policyengine_us/variables/gov/states/oh/tax/income/deductions/medical_exepenses/oh_uninsured_unreimbursed_medical_care_expenses.py b/policyengine_us/variables/gov/states/oh/tax/income/deductions/medical_exepenses/oh_uninsured_unreimbursed_medical_care_expenses.py index 166bd2ab754..5d0d40b4c55 100644 --- a/policyengine_us/variables/gov/states/oh/tax/income/deductions/medical_exepenses/oh_uninsured_unreimbursed_medical_care_expenses.py +++ b/policyengine_us/variables/gov/states/oh/tax/income/deductions/medical_exepenses/oh_uninsured_unreimbursed_medical_care_expenses.py @@ -9,6 +9,7 @@ class oh_uninsured_unreimbursed_medical_care_expenses(Variable): definition_period = YEAR reference = ( "https://codes.ohio.gov/ohio-revised-code/section-5747.01", # R.C. 5747.01(A)(10)(a) + "https://uscode.house.gov/us/usc/t26/s152/", # IRC 152(b)(1) "https://dam.assets.ohio.gov/image/upload/v1767095693/tax.ohio.gov/forms/ohio_individual/individual/2025/it1040-booklet.pdf#page=25", # Line 44, pp. 25-26 "https://dam.assets.ohio.gov/image/upload/v1767095693/tax.ohio.gov/forms/ohio_individual/individual/2025/it1040-booklet.pdf#page=41", # Worksheet line 1 ) @@ -20,6 +21,14 @@ def formula(person, period, parameters): employer_plan_eligible = person.tax_unit( "oh_employer_subsidized_health_plan_eligible", period ) + filer_is_dependent = person.tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) + eligible_person = ( + person("is_tax_unit_head_or_spouse", period) | ~filer_is_dependent + ) # Line 1: premiums paid while eligible for neither Medicare nor an # employer-paid plan. Otherwise they go on line 3. - return premiums * ~(medicare_eligible | employer_plan_eligible) + return ( + eligible_person * premiums * ~(medicare_eligible | employer_plan_eligible) + ) diff --git a/policyengine_us/variables/gov/states/ok/tax/income/credits/eitc/federal_credit/eligible/ok_federal_eitc_demographic_eligible.py b/policyengine_us/variables/gov/states/ok/tax/income/credits/eitc/federal_credit/eligible/ok_federal_eitc_demographic_eligible.py index 389080f2312..c1ed46c5c87 100644 --- a/policyengine_us/variables/gov/states/ok/tax/income/credits/eitc/federal_credit/eligible/ok_federal_eitc_demographic_eligible.py +++ b/policyengine_us/variables/gov/states/ok/tax/income/credits/eitc/federal_credit/eligible/ok_federal_eitc_demographic_eligible.py @@ -9,6 +9,8 @@ class ok_federal_eitc_demographic_eligible(Variable): reference = ( # Oklahoma Statutes 68 O.S. Section 2357.43 "https://law.justia.com/codes/oklahoma/title-68/section-68-2357-43/", + "https://www.law.cornell.edu/uscode/text/26/32#c_1_A_ii", + "https://www.irs.gov/pub/irs-prior/p596--2020.pdf#page=16", ) defined_for = StateCode.OK documentation = """ @@ -16,10 +18,11 @@ class ok_federal_eitc_demographic_eligible(Variable): Tax units are demographically eligible if: 1. They have qualifying children, OR - 2. At least one filer meets age requirements (without children) + 2. At least one filer meets age requirements (without children), and + neither filer can be claimed as a dependent on another return 2020 Age requirements (for filers without qualifying children): - - Minimum age: 25 (or 19 if full-time student) + - Minimum age: 25 for students and nonstudents - Maximum age: 64 Note: If the tax unit has qualifying children, age requirements @@ -39,9 +42,24 @@ def formula(tax_unit, period, parameters): "2020-01-01" ) student = person("is_full_time_student", period) - # Students have a lower minimum age requirement + # Both frozen 2020 minimum ages equal 25. min_age = where(student, min_age_student, min_age_non_student) max_age = parameters.gov.irs.credits.eitc.eligibility.age.max("2020-01-01") - # Check if at least one filer meets age requirements + # Check if at least one filer meets age requirements. The age test + # applies to the filer or, on a joint return, either spouse, never to + # a dependent (IRC 32(c)(1)(A)(ii)(II)). meets_age_requirements = (age >= min_age) & (age <= max_age) - return has_child | tax_unit.any(meets_age_requirements) + is_filer_or_spouse = ~person("is_tax_unit_dependent", period) + # IRC 32(c)(1)(A)(ii)(III), unchanged since 2020: without a + # qualifying child, the filer must not be a dependent of another + # taxpayer; on a joint return, "neither you nor your spouse can be + # claimed as a dependent by another person" (2020 Publication 596), + # unless the would-be claimant files only for a refund. + dependent_elsewhere = tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) + childless_eligible = ( + tax_unit.any(meets_age_requirements & is_filer_or_spouse) + & ~dependent_elsewhere + ) + return has_child | childless_eligible diff --git a/policyengine_us/variables/gov/states/ok/tax/income/credits/ok_stc.py b/policyengine_us/variables/gov/states/ok/tax/income/credits/ok_stc.py index c4988fec04d..e47c17e65b9 100644 --- a/policyengine_us/variables/gov/states/ok/tax/income/credits/ok_stc.py +++ b/policyengine_us/variables/gov/states/ok/tax/income/credits/ok_stc.py @@ -10,12 +10,15 @@ class ok_stc(Variable): reference = ( # 2025 Form 538-S (Sales Tax Relief Credit form) "https://oklahoma.gov/content/dam/ok/en/tax/documents/forms/individuals/current/538-S.pdf", + # 68 O.S. 5011 as codified in 2021, quoted in HB 1013XX (2023). + "https://oklegislature.gov/cf_pdf/2023-24%20INT/hB/HB1013XX%20INT.PDF#page=5", + "https://www.law.cornell.edu/regulations/oklahoma/OAC-710-50-15-96", ) defined_for = StateCode.OK documentation = """ Oklahoma Sales Tax Relief Credit. - This refundable credit provides $40 per household member to help offset + This refundable credit provides $40 per allowable exemption to help offset sales taxes paid by low-income Oklahoma residents. Eligibility has TWO alternative pathways: @@ -33,7 +36,11 @@ class ok_stc(Variable): - Not receiving TANF benefits Credit calculation: - - $40 per person in the tax unit (head, spouse, and dependents) + - $40 per allowable personal exemption (head, spouse, and dependents), + not counting the 65-or-older and blind exemptions. A filer who can be + claimed as a dependent on another return has no exemption, and a + return on which the filer (or, if joint, either spouse) can be claimed + has no dependents. Example 1 - Pathway 1 (low income): - Gross income: $18,000 (eligible under $20,000 limit) @@ -73,8 +80,19 @@ def formula(tax_unit, period, parameters): # Pathway 1: Low income (gross income <= $20,000) income_eligible1 = income <= p.income_limit1 # Pathway 2: Moderate income with qualifying circumstances - # Must have dependents, or be elderly (65+), or be disabled - has_dependents = tax_unit("tax_unit_dependents", period) > 0 + # Must have dependents, or be elderly (65+), or be disabled. The + # dependent must "qualify and be claimed as a dependent for federal + # income tax purposes" (Form 538-S instructions), and a return on + # which the filer (or, if joint, either spouse) can be claimed as a + # dependent has none (IRC 152(b)(1)). + # Publication 501 excepts a return whose would-be claimant files only + # for a refund. + filer_is_dependent = tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) + has_dependents = (tax_unit("tax_unit_dependents", period) > 0) & ~( + filer_is_dependent + ) elderly_head_or_spouse = ( tax_unit("greater_age_head_spouse", period) >= p.age_minimum ) @@ -86,6 +104,10 @@ def formula(tax_unit, period, parameters): income_eligible2 = unit_eligible & (income <= p.income_limit2) # Overall eligibility: not on TANF AND (Pathway 1 OR Pathway 2) eligible = ~tanf_ineligible & (income_eligible1 | income_eligible2) - # Credit = $40 per person in tax unit - qualified_exemptions = tax_unit("tax_unit_size", period) + # 68 O.S. 5011(D): $40 times "the number of allowable personal + # exemptions", those the Oklahoma Income Tax Act allows other than the + # 65-or-older and blind exemptions. Those are the federal personal + # exemptions (68 O.S. 2358(E)): one per filer who cannot be claimed as + # a dependent, plus the dependents when no filer can be claimed. + qualified_exemptions = tax_unit("exemptions_count", period) return eligible * qualified_exemptions * p.amount diff --git a/policyengine_us/variables/gov/states/ok/tax/income/exemptions/ok_count_exemptions.py b/policyengine_us/variables/gov/states/ok/tax/income/exemptions/ok_count_exemptions.py index fd57c921890..47e7d4140a6 100644 --- a/policyengine_us/variables/gov/states/ok/tax/income/exemptions/ok_count_exemptions.py +++ b/policyengine_us/variables/gov/states/ok/tax/income/exemptions/ok_count_exemptions.py @@ -9,7 +9,10 @@ class ok_count_exemptions(Variable): definition_period = YEAR reference = ( "https://oklahoma.gov/content/dam/ok/en/tax/documents/forms/individuals/past-year/2021/511-Pkt-2021.pdf#page=9", - "https://oklahoma.gov/content/dam/ok/en/tax/documents/forms/individuals/current/511-Pkt.pdf#page=9", + # 2025 Form 511 instructions, item F (Exemptions). + # PDF pages 8-9 + "https://oklahoma.gov/content/dam/ok/en/tax/documents/forms/individuals/current/511-Pkt.pdf#page=8", + "https://www.law.cornell.edu/uscode/text/26/152#b_1", ) defined_for = StateCode.OK @@ -24,22 +27,49 @@ def formula(tax_unit, period, parameters): fagi = tax_unit("adjusted_gross_income", period) - roth_conversions filing_status = tax_unit("filing_status", period) agi_eligible = fagi <= p.special_agi_limit[filing_status] + # Regular exemptions: "You may claim an exemption for yourself if you + # cannot be claimed as a dependent on another person's return", and + # for a joint spouse who "cannot be claimed as a dependent on another + # person's return" (Form 511 instructions, item F). The special (65 or + # older) and blind exemptions are separate boxes with no such bar. + # Each filer's own regular exemption follows that filer's own flag. + claimable = person("claimable_as_dependent_on_another_return", period) + head_claimable = tax_unit.any(person("is_tax_unit_head", period) & claimable) + spouse_claimable = tax_unit.any( + person("is_tax_unit_spouse", period) & claimable + ) + head_regular = where(head_claimable, 0, 1) + spouse_regular = where(spouse_claimable, 0, 1) # head exemptions age_eligible = tax_unit("age_head", period) >= p.special_age_minimum - head_exemptions = where(tax_unit("blind_head", period), 2, 1) + where( - agi_eligible & age_eligible, 1, 0 + head_exemptions = ( + head_regular + + where(tax_unit("blind_head", period), 1, 0) + + where(agi_eligible & age_eligible, 1, 0) ) # spouse exemptions age_eligible = tax_unit("age_spouse", period) >= p.special_age_minimum spouse_exemptions = where( filing_status == filing_status.possible_values.JOINT, ( - where(tax_unit("blind_spouse", period), 2, 1) + spouse_regular + + where(tax_unit("blind_spouse", period), 1, 0) + where(agi_eligible & age_eligible, 1, 0) ), 0, ) - # dependent exemptions + # dependent exemptions: each "dependent, as defined in IRC Sec. 152" + # (item F), and a return on which the filer (or, if joint, either + # spouse) can be claimed as a dependent has none (IRC 152(b)(1)). + # Publication 501 excepts a return whose would-be claimant files only + # for a refund. dependents = tax_unit("tax_unit_dependents", period) + filer_is_dependent = tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) # total number of exemptions - return head_exemptions + spouse_exemptions + dependents + return ( + head_exemptions + + spouse_exemptions + + where(filer_is_dependent, 0, dependents) + ) diff --git a/policyengine_us/variables/gov/states/pa/tax/income/forgiveness/pa_tax_forgiveness_amount.py b/policyengine_us/variables/gov/states/pa/tax/income/forgiveness/pa_tax_forgiveness_amount.py index 29615db302d..23a237b2834 100644 --- a/policyengine_us/variables/gov/states/pa/tax/income/forgiveness/pa_tax_forgiveness_amount.py +++ b/policyengine_us/variables/gov/states/pa/tax/income/forgiveness/pa_tax_forgiveness_amount.py @@ -13,4 +13,6 @@ class pa_tax_forgiveness_amount(Variable): def formula(tax_unit, period, parameters): income_tax = tax_unit("pa_income_tax_before_forgiveness", period) rate = tax_unit("pa_tax_forgiveness_rate", period) - return income_tax * rate + # Forgiveness applies only to the tax of a filer who can claim it. + eligible_share = tax_unit("pa_tax_forgiveness_eligible_share", period) + return income_tax * rate * eligible_share diff --git a/policyengine_us/variables/gov/states/pa/tax/income/forgiveness/pa_tax_forgiveness_eligible.py b/policyengine_us/variables/gov/states/pa/tax/income/forgiveness/pa_tax_forgiveness_eligible.py new file mode 100644 index 00000000000..c2417680bf5 --- /dev/null +++ b/policyengine_us/variables/gov/states/pa/tax/income/forgiveness/pa_tax_forgiveness_eligible.py @@ -0,0 +1,30 @@ +from policyengine_us.model_api import * + + +class pa_tax_forgiveness_eligible(Variable): + value_type = bool + entity = Person + label = "Eligible to claim Pennsylvania tax forgiveness" + documentation = ( + "Whether this head or spouse can claim Pennsylvania tax forgiveness. " + "A filer who can be claimed as a dependent on another return cannot " + "claim forgiveness under Tax Reform Code section 301(c.2)." + ) + definition_period = YEAR + defined_for = StateCode.PA + reference = ( + # Tax Reform Code of 1971, section 301(c.2): a "Claimant" "is not a + # dependent of another taxpayer for purposes of section 151". + "https://www.legis.state.pa.us/WU01/LI/LI/US/PDF/1971/0/0002..PDF#page=112", + # 2025 PA-40 Schedule SP instructions. + # PDF pages 3-5 + "https://www.pa.gov/content/dam/copapwp-pagov/en/revenue/documents/formsandpublications/formsforindividuals/pit/documents/2025/2025_pa-40sp.pdf#page=3", + "https://www.pa.gov/agencies/revenue/forms-and-publications/pa-personal-income-tax-guide/tax-forgiveness", + ) + + def formula(person, period, parameters): + head_or_spouse = person("is_tax_unit_head_or_spouse", period) + claimable = person("claimable_as_dependent_on_another_return", period) + # The instructions say a dependent child can qualify through a parent. + # Sections 301(c.2) and 304 exclude dependents without that exception. + return head_or_spouse & ~claimable diff --git a/policyengine_us/variables/gov/states/pa/tax/income/forgiveness/pa_tax_forgiveness_eligible_share.py b/policyengine_us/variables/gov/states/pa/tax/income/forgiveness/pa_tax_forgiveness_eligible_share.py new file mode 100644 index 00000000000..b59b742e5ec --- /dev/null +++ b/policyengine_us/variables/gov/states/pa/tax/income/forgiveness/pa_tax_forgiveness_eligible_share.py @@ -0,0 +1,60 @@ +from policyengine_us.model_api import * + + +class pa_tax_forgiveness_eligible_share(Variable): + value_type = float + entity = TaxUnit + label = "Share of Pennsylvania tax on which tax forgiveness can be claimed" + documentation = ( + "The share of the return's Pennsylvania income tax that belongs to a " + "head or spouse who can claim Tax Forgiveness. It is one unless a " + "filer can be claimed as a dependent on another return. When one " + "spouse can be claimed, the spouses must file separate Pennsylvania " + "returns and each spouse's Tax Forgiveness is determined separately, " + "so it applies only to the tax on the eligible spouse's own income. " + "Each spouse's tax is approximated by that spouse's share of the " + "spouses' Pennsylvania taxable income, leaving out amounts recorded " + "only for the tax unit." + ) + unit = "/1" + definition_period = YEAR + defined_for = StateCode.PA + reference = ( + # 2025 PA-40 Schedule SP instructions, Section I: "When one spouse is + # claimed as a dependent on another person's federal income tax + # return, otherwise qualifying married taxpayers must file separately." + "https://www.pa.gov/content/dam/copapwp-pagov/en/revenue/documents/formsandpublications/formsforindividuals/pit/documents/2025/2025_pa-40sp.pdf#page=5", + # "Each spouse's tax forgiveness, if any, must be determined separately." + "https://www.pa.gov/agencies/revenue/forms-and-publications/pa-personal-income-tax-guide/tax-forgiveness", + ) + + def formula(tax_unit, period, parameters): + person = tax_unit.members + filer = person("is_tax_unit_head_or_spouse", period) + eligible = person("pa_tax_forgiveness_eligible", period) + # Each filer's own Pennsylvania taxable income: federal gross income + # less the person-level amounts Pennsylvania does not tax. + sources = parameters(period).gov.states.pa.tax.income.nontaxable_income_sources + person_sources = [ + source + for source in sources + if tax_unit.entity.get_variable( + source, check_existence=True + ).entity.is_person + ] + nontaxable = add(person, period, person_sources) + own = max_(0, person("irs_gross_income", period) - nontaxable) * filer + total = tax_unit.sum(own) + eligible_income = tax_unit.sum(own * eligible) + # With no taxable income there is no tax; split evenly. + eligible_count = tax_unit.sum(filer & eligible) + filer_count = max_(tax_unit.sum(filer), 1) + share = where( + total > 0, + eligible_income / where(total > 0, total, 1), + eligible_count / filer_count, + ) + # Section 301(c.2) excludes any filer who can be claimed elsewhere. + claimable = person("claimable_as_dependent_on_another_return", period) + filer_is_claimable = tax_unit.any(filer & claimable) + return where(filer_is_claimable, share, 1) diff --git a/policyengine_us/variables/gov/states/pa/tax/income/forgiveness/pa_tax_forgiveness_rate.py b/policyengine_us/variables/gov/states/pa/tax/income/forgiveness/pa_tax_forgiveness_rate.py index 8a13de6b969..6343d11b49c 100644 --- a/policyengine_us/variables/gov/states/pa/tax/income/forgiveness/pa_tax_forgiveness_rate.py +++ b/policyengine_us/variables/gov/states/pa/tax/income/forgiveness/pa_tax_forgiveness_rate.py @@ -11,6 +11,8 @@ class pa_tax_forgiveness_rate(Variable): "https://www.palegis.us/statutes/unconsolidated/law-information/view-statute?txtType=PDF&SessYr=1971&SessInd=0&ActNum=0002.&chpt=003.&subchpt=000.&sctn=004.&subsctn=000.", # 72 P.S. 7304(d)(1) "https://www.pa.gov/content/dam/copapwp-pagov/en/revenue/documents/formsandpublications/formsforindividuals/pit/documents/2025/2025_pa-40in.pdf#page=36", "https://www.pa.gov/content/dam/copapwp-pagov/en/revenue/documents/formsandpublications/formsforindividuals/pit/documents/2021/2021_pa-40in.pdf#page=39", + "https://www.legis.state.pa.us/WU01/LI/LI/US/PDF/1971/0/0002..PDF#page=113", + "https://www.law.cornell.edu/uscode/text/26/152#b_1", ) defined_for = StateCode.PA @@ -18,7 +20,18 @@ def formula(tax_unit, period, parameters): own_eligibility_income = tax_unit("pa_eligibility_income", period) person = tax_unit.members is_child_dependent = person("is_qualifying_child_dependent", period) - child_dependents = tax_unit.sum(is_child_dependent) + # A dependent child must be "the dependent of a claimant for purposes + # of section 151" (Tax Reform Code section 301(e.1)), and a return on + # which the filer (or, if joint, either spouse) can be claimed as a + # dependent has no dependents (IRC 152(b)(1)). + # Publication 501 excepts a return whose would-be claimant files only + # for a refund. + filer_is_dependent = tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) + child_dependents = where( + filer_is_dependent, 0, tax_unit.sum(is_child_dependent) + ) # 72 P.S. 7304(d)(1)(i)-(ii): a claimant who files a separate return # and lives apart from the spouse for all of the last six months of # the year (or under a written separation agreement) is not diff --git a/source_conflicts/candidates.yaml b/source_conflicts/candidates.yaml index 30643a51291..06ce204c147 100644 --- a/source_conflicts/candidates.yaml +++ b/source_conflicts/candidates.yaml @@ -6717,17 +6717,17 @@ candidates: citation: 2025 Schedule ND-1SA line 8, p. 2 url: https://www.tax.nd.gov/sites/www/files/documents/forms/individual/2025-iit/28710-schedule-nd-1sa-2025.pdf#page=2 readings: - statute: The subtraction applies for each birth resulting in stillbirth without the added dependency condition. + statute: A filer subtracts an allowance for each birth resulting in stillbirth without a dependency condition. other: The filer must have been eligible to claim the child federally. example: A claimable filer receives $5,241 under the statutory reading versus $0 under the form. pe_us: - follows: conflicting-source - code: [] + follows: statute + code: + - policyengine_us/variables/gov/states/nd/tax/income/subtractions/nd_stillborn_subtraction.py prs: - https://github.com/PolicyEngine/policyengine-us/pull/10043 - state: open - note: 'The statute-first rule requires removing the form''s added dependency condition if confirmed; the requested - decision remains open. Code not yet on main: nd_stillborn_subtraction.' + state: ruled + note: PE-US counts tax_unit_stillborn_children without a dependency test, following section 57-38-30.3(2)(p). - id: us-ne:claim-of-right-obsolete-revenue-ruling program: income-tax years: @@ -8731,34 +8731,38 @@ candidates: dependent exclusion? sources: - kind: statute - citation: Tax Reform Code 301(c.2) + citation: Tax Reform Code sections 301(c.2) and 304, PDF pages 112, 127-128 url: https://www.legis.state.pa.us/WU01/LI/LI/US/PDF/1971/0/0002..PDF#page=112 - kind: form citation: 2025 PA-40 Schedule SP, pp. 3-5 url: https://www.pa.gov/content/dam/copapwp-pagov/en/revenue/documents/formsandpublications/formsforindividuals/pit/documents/2025/2025_pa-40sp.pdf#page=3 readings: - statute: A dependent cannot be a claimant. - other: A dependent child may qualify when the claiming parent qualifies. + statute: A filer who can be claimed as a dependent cannot claim forgiveness, even without an actual claim or + when a parent qualifies. + other: A dependent child may qualify when the claiming parent qualifies; Schedule SP asks about an actual + federal claim. pe_us: - follows: conflicting-source - code: [] + follows: statute + code: + - policyengine_us/variables/gov/states/pa/tax/income/forgiveness/pa_tax_forgiveness_eligible.py + - policyengine_us/variables/gov/states/pa/tax/income/forgiveness/pa_tax_forgiveness_eligible_share.py + - policyengine_us/variables/gov/states/pa/tax/income/forgiveness/pa_tax_forgiveness_amount.py prs: - https://github.com/PolicyEngine/policyengine-us/pull/10043 - state: open - note: 'The statute-first rule requires removing the form''s dependent-child exception if confirmed; the requested - decision remains open. Code not yet on main: pa_tax_forgiveness_eligible, pa_tax_forgiveness_parent_qualifies, - pa_tax_forgiveness_amount.' + state: ruled + note: PE-US excludes a claimable head or spouse even if no one claims them and removes the parent-qualification + input. - id: us-pa:tax-forgiveness-one-claimed-spouse-table program: income-tax years: from: 2025 to: 2025 type: tax - question: Which tax-forgiveness table and allocation apply when one spouse is claimed elsewhere and the other + question: Which tax-forgiveness table and allocation apply when one spouse can be claimed elsewhere and the other qualifies? sources: - kind: statute - citation: Tax Reform Code 301(c.2) + citation: Tax Reform Code sections 301(c.2) and 304, PDF pages 112, 127-128 url: https://www.legis.state.pa.us/WU01/LI/LI/US/PDF/1971/0/0002..PDF#page=112 - kind: form citation: 2025 PA-40 Schedule SP, pp. 3-5 @@ -8767,18 +8771,22 @@ candidates: citation: PA Personal Income Tax Guide, Tax Forgiveness url: https://www.pa.gov/agencies/revenue/forms-and-publications/pa-personal-income-tax-guide/tax-forgiveness readings: - statute: The statute does not specify the table for this mixed-spouse case. - other: Schedule SP supplies married treatment; the guide's classification of married-separate claimants points - to the single table. - example: The supplied case with $3,000 income for each spouse gives $92.10 under Schedule SP. + statute: A claimable spouse cannot claim forgiveness. The General Assembly does not specify how the other + spouse allocates forgiveness. + other: An eligible spouse claims forgiveness on their own tax, using both spouses' eligibility income and the + married table under Schedule SP. + example: With $3,000 income per spouse, the eligible spouse receives $92.10 under Schedule SP. pe_us: follows: gap-fill - code: [] + code: + - policyengine_us/variables/gov/states/pa/tax/income/forgiveness/pa_tax_forgiveness_eligible_share.py + - policyengine_us/variables/gov/states/pa/tax/income/forgiveness/pa_tax_forgiveness_amount.py prs: - https://github.com/PolicyEngine/policyengine-us/pull/10043 - state: open - note: 'PE-US follows Schedule SP''s gap-fill; reconcile it with the guide''s single-claimant category. Code not - yet on main: pa_tax_forgiveness_eligible_share, pa_tax_forgiveness_amount.' + state: ruled + note: PE-US excludes the claimable spouse and allocates forgiveness to the eligible spouse's own tax. Both + spouses contribute eligibility income, and the eligible spouse uses the married table. The PIT guide excludes + dependent spouses as claimants. - id: us-pr:eitc-minimum-age-gap-fill program: income-tax years: