Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create phaseout for NYC school credit for NYC CTC proposal #5510

Merged
merged 6 commits into from
Jan 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions changelog_entry.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
- bump: minor
changes:
added:
- NYC school tax credit phase out reform.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
description: The NYC school tax credit phases out with state adjusted gross income, if this is true.

values:
0000-01-01: false

metadata:
unit: bool
period: year
label: NYC school tax credit phase out in effect
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
description: New York reduces the NYC school tax credit for joint filers and surviving spouses at this rate, based on state adjusted gross income.
metadata:
type: marginal_rate
threshold_unit: currency-USD
rate_unit: /1
period: year
label: NYC school tax credit joint and surviving spouse reduction rate
reference:
- title: New York Senate Bill S2238 §1(4-c)(B)
href: https://www.nysenate.gov/legislation/bills/2025/S2238

brackets:
- threshold:
2025-01-01: 0
rate:
2025-01-01: 0
- threshold:
2025-01-01: 150_000
rate:
2025-01-01: 0.05
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
description: New York reduces the NYC school tax credit for single, separate, and head of household filers, based on state adjusted gross income.
metadata:
type: marginal_rate
threshold_unit: currency-USD
rate_unit: /1
period: year
label: NYC school tax credit other reduction rate
reference:
- title: New York Senate Bill S2238 §1(4-c)(A)
href: https://www.nysenate.gov/legislation/bills/2025/S2238

brackets:
- threshold:
2025-01-01: 0
rate:
2025-01-01: 0
- threshold:
2025-01-01: 75_000
rate:
2025-01-01: 0.05
7 changes: 7 additions & 0 deletions policyengine_us/reforms/local/nyc/stc/phase_out/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
## NYC School Tax Credit Reform with Phase-Out

# This code defines a policy reform for implementing a New York City School Tax Credit with a phase-out mechanism, as outlined in [Senate Bill S2238](https://www.nysenate.gov/legislation/bills/2025/S2238).

# The credit is phased out based on state adjusted gross income (AGI) and filing status.

# The phase-out start threshold is doubled for joint filers and surviving spouses.
3 changes: 3 additions & 0 deletions policyengine_us/reforms/local/nyc/stc/phase_out/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .nyc_school_tax_credit_with_phase_out import (
create_nyc_school_tax_credit_with_phase_out_reform,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
from policyengine_us.model_api import *
from policyengine_core.periods import period as period_


def create_nyc_school_tax_credit_with_phase_out() -> Reform:
class nyc_school_tax_credit_phase_out(Variable):
value_type = float
unit = USD
entity = TaxUnit
label = "NYC School Tax Credit Phase Out"
definition_period = YEAR
defined_for = "in_nyc"
reference = "https://www.nysenate.gov/legislation/bills/2025/S2238"

def formula(tax_unit, period, parameters):
agi = tax_unit("ny_agi", period)
filing_status = tax_unit("filing_status", period)
joint = filing_status == filing_status.possible_values.JOINT
surviving_spouse = (
filing_status == filing_status.possible_values.SURVIVING_SPOUSE
)
joint_filers = joint | surviving_spouse
p = parameters(period).gov.contrib.local.nyc.stc.phase_out.rate
return where(
joint_filers,
p.joint_and_surviving_spouse.calc(agi),
p.other.calc(agi),
)

class nyc_school_tax_credit(Variable):
value_type = float
entity = TaxUnit
label = "NYC School Tax Credit"
unit = USD
definition_period = YEAR
defined_for = "in_nyc"
reference = "https://www.nysenate.gov/legislation/bills/2025/S2238"

def formula(tax_unit, period, parameters):
base_amount = add(
tax_unit,
period,
[
"nyc_school_tax_credit_fixed_amount",
"nyc_school_tax_credit_rate_reduction_amount",
],
)
phase_out = tax_unit("nyc_school_tax_credit_phase_out", period)
return max_(0, base_amount - phase_out)

class reform(Reform):
def apply(self):
self.update_variable(nyc_school_tax_credit_phase_out)
self.update_variable(nyc_school_tax_credit)

return reform


def create_nyc_school_tax_credit_with_phase_out_reform(
parameters, period, bypass: bool = False
):
if bypass:
return create_nyc_school_tax_credit_with_phase_out()

p = parameters.gov.contrib.local.nyc.stc.phase_out

reform_active = False
current_period = period_(period)

for i in range(5):
if p(current_period).in_effect:
reform_active = True
break
current_period = current_period.offset(1, "year")

if reform_active:
return create_nyc_school_tax_credit_with_phase_out()
else:
return None


nyc_school_tax_credit_with_phase_out = (
create_nyc_school_tax_credit_with_phase_out_reform(None, None, bypass=True)
)
8 changes: 8 additions & 0 deletions policyengine_us/reforms/reforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@
create_limit_salt_deduction_to_property_taxes_reform,
)

from .local.nyc.stc.phase_out import (
create_nyc_school_tax_credit_with_phase_out_reform,
)

from policyengine_core.reforms import Reform
import warnings

Expand Down Expand Up @@ -181,6 +185,9 @@ def create_structural_reforms_from_parameters(parameters, period):
parameters, period
)
)
nyc_school_tax_credit_with_phase_out = (
create_nyc_school_tax_credit_with_phase_out_reform(parameters, period)
)

reforms = [
afa_reform,
Expand Down Expand Up @@ -218,6 +225,7 @@ def create_structural_reforms_from_parameters(parameters, period):
dc_property_tax_credit,
ny_2025_inflation_rebates,
limit_salt_deduction_to_property_taxes,
nyc_school_tax_credit_with_phase_out,
]
reforms = tuple(filter(lambda x: x is not None, reforms))

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
- name: Joint, with AGI below phase out threshold
period: 2025
reforms: policyengine_us.reforms.local.nyc.stc.phase_out.nyc_school_tax_credit_with_phase_out.nyc_school_tax_credit_with_phase_out
input:
gov.contrib.local.nyc.stc.phase_out.in_effect: true
in_nyc: True
ny_agi: 150_000
filing_status: JOINT
output:
nyc_school_tax_credit_phase_out: 0

- name: Single, with AGI above phase out threshold
period: 2025
reforms: policyengine_us.reforms.local.nyc.stc.phase_out.nyc_school_tax_credit_with_phase_out.nyc_school_tax_credit_with_phase_out
input:
gov.contrib.local.nyc.stc.phase_out.in_effect: true
in_nyc: True
ny_agi: 150_000
filing_status: SINGLE
output:
nyc_school_tax_credit_phase_out: 3_750

- name: Single, with AGI above phase out threshold, with credit amount, fully reduced
period: 2025
reforms: policyengine_us.reforms.local.nyc.stc.phase_out.nyc_school_tax_credit_with_phase_out.nyc_school_tax_credit_with_phase_out
input:
gov.contrib.local.nyc.stc.phase_out.in_effect: true
in_nyc: True
ny_agi: 150_000
filing_status: SINGLE
nyc_school_tax_credit_fixed_amount: 1_000
nyc_school_tax_credit_rate_reduction_amount: 500
output:
nyc_school_tax_credit_phase_out: 3_750
nyc_school_tax_credit: 0

- name: Single, with AGI above phase out threshold, with credit amount, partially reduced
period: 2025
reforms: policyengine_us.reforms.local.nyc.stc.phase_out.nyc_school_tax_credit_with_phase_out.nyc_school_tax_credit_with_phase_out
input:
gov.contrib.local.nyc.stc.phase_out.in_effect: true
in_nyc: True
ny_agi: 160_000
filing_status: SURVIVING_SPOUSE
nyc_school_tax_credit_fixed_amount: 1_000
nyc_school_tax_credit_rate_reduction_amount: 600
output:
nyc_school_tax_credit_phase_out: 500
nyc_school_tax_credit: 1_100
Loading