diff --git a/changelog.d/statute-bugs-nyc-in-va-wa.fixed.md b/changelog.d/statute-bugs-nyc-in-va-wa.fixed.md new file mode 100644 index 00000000000..f3cc5741a82 --- /dev/null +++ b/changelog.d/statute-bugs-nyc-in-va-wa.fixed.md @@ -0,0 +1 @@ +Follow the statute for four credits and deductions: the NYC school tax credit rate reduction amount uses the fixed $37, $25 and $21 second-band bases (Tax Law § 606(ggg)(4-b)); the Indiana supplemental homestead credit requires homestead standard deduction qualification and uses the homestead's liability net of referendum taxes (IC 6-1.1-20.6-7.7); the Virginia Commonwealth Savers deduction caps each account separately and carries forward undeducted contributions (Va. Code § 58.1-322.03(7)); and the Washington senior and disabled persons property tax exemption requires retirement by reason of disability or the VA-rated veteran pathway instead of generic disability (RCW 84.36.381(3)(a)). diff --git a/policyengine_us/parameters/gov/local/ny/nyc/tax/income/credits/school/rate_reduction/amount/base.yaml b/policyengine_us/parameters/gov/local/ny/nyc/tax/income/credits/school/rate_reduction/amount/base.yaml new file mode 100644 index 00000000000..99323aaabce --- /dev/null +++ b/policyengine_us/parameters/gov/local/ny/nyc/tax/income/credits/school/rate_reduction/amount/base.yaml @@ -0,0 +1,35 @@ +description: New York City provides this base school tax credit rate reduction amount to filers with city taxable income above the threshold, before adding a share of the excess. +metadata: + propagate_metadata_to_children: true + unit: currency-USD + period: year + label: NYC school tax credit rate reduction amount base + breakdown: + - filing_status + reference: + - title: NY Tax Law § 606(ggg)(4-b) + href: https://www.nysenate.gov/legislation/laws/TAX/606 + - title: "L.2017, ch. 59, Part C, §§ 2, 7 (S.2009-C) #page 8-9,14" + href: https://legislation.nysenate.gov/pdf/bills/2017/S2009C#page=8 + - title: Instructions for Form IT-201, 2017, Line 69a + href: https://www.tax.ny.gov/pdf/2017/inc/it201i_2017.pdf#page=30 + - title: Instructions for Form IT-201, 2018, Line 69a + href: https://www.tax.ny.gov/pdf/2018/inc/it201i_2018.pdf#page=31 + - title: Instructions for Form IT-201, 2022, Line 69a + href: https://www.tax.ny.gov/pdf/2022/printable-pdfs/inc/it201i-2022.pdf#page=27 + - title: Instructions for Form IT-201, 2023, Line 69a + href: https://web.archive.org/web/20240317205657/https://www.tax.ny.gov/pdf/2023/printable-pdfs/inc/it201i-2023.pdf#page=29 + - title: Instructions for Form IT-201, 2024, Line 69a + href: https://www.tax.ny.gov/pdf/2024/inc/it201i_2024.pdf#page=21 + - title: Instructions for Form IT-201, 2025, Line 69a + href: https://www.tax.ny.gov/pdf/2025/inc/it201i_2025.pdf#page=21 +SINGLE: + 2017-01-01: 21 +JOINT: + 2017-01-01: 37 +SEPARATE: + 2017-01-01: 21 +HEAD_OF_HOUSEHOLD: + 2017-01-01: 25 +SURVIVING_SPOUSE: + 2017-01-01: 37 diff --git a/policyengine_us/parameters/gov/local/ny/nyc/tax/income/credits/school/rate_reduction/amount/excess_rate.yaml b/policyengine_us/parameters/gov/local/ny/nyc/tax/income/credits/school/rate_reduction/amount/excess_rate.yaml new file mode 100644 index 00000000000..fd870773186 --- /dev/null +++ b/policyengine_us/parameters/gov/local/ny/nyc/tax/income/credits/school/rate_reduction/amount/excess_rate.yaml @@ -0,0 +1,24 @@ +description: New York City adds this share of city taxable income above the threshold to the base school tax credit rate reduction amount. +values: + 2017-01-01: 0.00228 +metadata: + unit: /1 + period: year + label: NYC school tax credit rate reduction amount excess rate + reference: + - title: NY Tax Law § 606(ggg)(4-b) + href: https://www.nysenate.gov/legislation/laws/TAX/606 + - title: "L.2017, ch. 59, Part C, §§ 2, 7 (S.2009-C) #page 8-9,14" + href: https://legislation.nysenate.gov/pdf/bills/2017/S2009C#page=8 + - title: Instructions for Form IT-201, 2017, Line 69a + href: https://www.tax.ny.gov/pdf/2017/inc/it201i_2017.pdf#page=30 + - title: Instructions for Form IT-201, 2018, Line 69a + href: https://www.tax.ny.gov/pdf/2018/inc/it201i_2018.pdf#page=31 + - title: Instructions for Form IT-201, 2022, Line 69a + href: https://www.tax.ny.gov/pdf/2022/printable-pdfs/inc/it201i-2022.pdf#page=27 + - title: Instructions for Form IT-201, 2023, Line 69a + href: https://web.archive.org/web/20240317205657/https://www.tax.ny.gov/pdf/2023/printable-pdfs/inc/it201i-2023.pdf#page=29 + - title: Instructions for Form IT-201, 2024, Line 69a + href: https://www.tax.ny.gov/pdf/2024/inc/it201i_2024.pdf#page=21 + - title: Instructions for Form IT-201, 2025, Line 69a + href: https://www.tax.ny.gov/pdf/2025/inc/it201i_2025.pdf#page=21 diff --git a/policyengine_us/parameters/gov/local/ny/nyc/tax/income/credits/school/rate_reduction/amount/first_band_rate.yaml b/policyengine_us/parameters/gov/local/ny/nyc/tax/income/credits/school/rate_reduction/amount/first_band_rate.yaml new file mode 100644 index 00000000000..39defec623a --- /dev/null +++ b/policyengine_us/parameters/gov/local/ny/nyc/tax/income/credits/school/rate_reduction/amount/first_band_rate.yaml @@ -0,0 +1,24 @@ +description: New York City provides this share of city taxable income as the school tax credit rate reduction amount for filers with city taxable income not over the threshold. +values: + 2017-01-01: 0.00171 +metadata: + unit: /1 + period: year + label: NYC school tax credit rate reduction amount first band rate + reference: + - title: NY Tax Law § 606(ggg)(4-b) + href: https://www.nysenate.gov/legislation/laws/TAX/606 + - title: "L.2017, ch. 59, Part C, §§ 2, 7 (S.2009-C) #page 8-9,14" + href: https://legislation.nysenate.gov/pdf/bills/2017/S2009C#page=8 + - title: Instructions for Form IT-201, 2017, Line 69a + href: https://www.tax.ny.gov/pdf/2017/inc/it201i_2017.pdf#page=30 + - title: Instructions for Form IT-201, 2018, Line 69a + href: https://www.tax.ny.gov/pdf/2018/inc/it201i_2018.pdf#page=31 + - title: Instructions for Form IT-201, 2022, Line 69a + href: https://www.tax.ny.gov/pdf/2022/printable-pdfs/inc/it201i-2022.pdf#page=27 + - title: Instructions for Form IT-201, 2023, Line 69a + href: https://web.archive.org/web/20240317205657/https://www.tax.ny.gov/pdf/2023/printable-pdfs/inc/it201i-2023.pdf#page=29 + - title: Instructions for Form IT-201, 2024, Line 69a + href: https://www.tax.ny.gov/pdf/2024/inc/it201i_2024.pdf#page=21 + - title: Instructions for Form IT-201, 2025, Line 69a + href: https://www.tax.ny.gov/pdf/2025/inc/it201i_2025.pdf#page=21 diff --git a/policyengine_us/parameters/gov/local/ny/nyc/tax/income/credits/school/rate_reduction/amount/head_of_household.yaml b/policyengine_us/parameters/gov/local/ny/nyc/tax/income/credits/school/rate_reduction/amount/head_of_household.yaml deleted file mode 100644 index df4da353eb3..00000000000 --- a/policyengine_us/parameters/gov/local/ny/nyc/tax/income/credits/school/rate_reduction/amount/head_of_household.yaml +++ /dev/null @@ -1,26 +0,0 @@ -description: NYC provides a School Tax Credit reduction amount based on filing status. -metadata: - type: marginal_rate - threshold_unit: currency-USD - rate_unit: /1 - label: NYC School Tax Credit Reduction Amount (Head of Household) - reference: - - title: NY Tax Law § 606(ggg)(4-b)(B) - href: https://www.nysenate.gov/legislation/laws/TAX/606 - - title: Instructions for Form IT-201, 2022, Line 69a - href: https://www.tax.ny.gov/pdf/2022/printable-pdfs/inc/it201i-2022.pdf#page=27 - - title: Instructions for Form IT-201, 2023, Line 69a - href: https://web.archive.org/web/20240317205657/https://www.tax.ny.gov/pdf/2023/printable-pdfs/inc/it201i-2023.pdf#page=29 - - title: Instructions for Form IT-201, 2024, Line 69a - href: https://www.tax.ny.gov/pdf/2024/inc/it201i_2024.pdf#page=21 - - title: Instructions for Form IT-201, 2025, Line 69a - href: https://www.tax.ny.gov/pdf/2025/inc/it201i_2025.pdf#page=21 -brackets: - - rate: - 2022-01-01: 0.00171 - threshold: - 2022-01-01: 0 - - rate: - 2022-01-01: 0.00228 - threshold: - 2022-01-01: 14_400 diff --git a/policyengine_us/parameters/gov/local/ny/nyc/tax/income/credits/school/rate_reduction/amount/joint.yaml b/policyengine_us/parameters/gov/local/ny/nyc/tax/income/credits/school/rate_reduction/amount/joint.yaml deleted file mode 100644 index ecdbfdde5e5..00000000000 --- a/policyengine_us/parameters/gov/local/ny/nyc/tax/income/credits/school/rate_reduction/amount/joint.yaml +++ /dev/null @@ -1,26 +0,0 @@ -description: NYC provides a School Tax Credit reduction amount based on filing status. -metadata: - type: marginal_rate - threshold_unit: currency-USD - rate_unit: /1 - label: NYC School Tax Credit Reduction Amount (Joint) - reference: - - title: NY Tax Law § 606(ggg)(4-b)(A) - href: https://www.nysenate.gov/legislation/laws/TAX/606 - - title: Instructions for Form IT-201, 2022, Line 69a - href: https://www.tax.ny.gov/pdf/2022/printable-pdfs/inc/it201i-2022.pdf#page=27 - - title: Instructions for Form IT-201, 2023, Line 69a - href: https://web.archive.org/web/20240317205657/https://www.tax.ny.gov/pdf/2023/printable-pdfs/inc/it201i-2023.pdf#page=29 - - title: Instructions for Form IT-201, 2024, Line 69a - href: https://www.tax.ny.gov/pdf/2024/inc/it201i_2024.pdf#page=21 - - title: Instructions for Form IT-201, 2025, Line 69a - href: https://www.tax.ny.gov/pdf/2025/inc/it201i_2025.pdf#page=21 -brackets: - - rate: - 2022-01-01: 0.00171 - threshold: - 2022-01-01: 0 - - rate: - 2022-01-01: 0.00228 - threshold: - 2022-01-01: 21_600 diff --git a/policyengine_us/parameters/gov/local/ny/nyc/tax/income/credits/school/rate_reduction/amount/separate.yaml b/policyengine_us/parameters/gov/local/ny/nyc/tax/income/credits/school/rate_reduction/amount/separate.yaml deleted file mode 100644 index d194c6c7f7c..00000000000 --- a/policyengine_us/parameters/gov/local/ny/nyc/tax/income/credits/school/rate_reduction/amount/separate.yaml +++ /dev/null @@ -1,26 +0,0 @@ -description: NYC provides a School Tax Credit reduction amount based on filing status. -metadata: - type: marginal_rate - threshold_unit: currency-USD - rate_unit: /1 - label: NYC School Tax Credit Reduction Amount (Separate) - reference: - - title: NY Tax Law § 606(ggg)(4-b)(C) - href: https://www.nysenate.gov/legislation/laws/TAX/606 - - title: Instructions for Form IT-201, 2022, Line 69a - href: https://www.tax.ny.gov/pdf/2022/printable-pdfs/inc/it201i-2022.pdf#page=27 - - title: Instructions for Form IT-201, 2023, Line 69a - href: https://web.archive.org/web/20240317205657/https://www.tax.ny.gov/pdf/2023/printable-pdfs/inc/it201i-2023.pdf#page=29 - - title: Instructions for Form IT-201, 2024, Line 69a - href: https://www.tax.ny.gov/pdf/2024/inc/it201i_2024.pdf#page=21 - - title: Instructions for Form IT-201, 2025, Line 69a - href: https://www.tax.ny.gov/pdf/2025/inc/it201i_2025.pdf#page=21 -brackets: - - rate: - 2022-01-01: 0.00171 - threshold: - 2022-01-01: 0 - - rate: - 2022-01-01: 0.00228 - threshold: - 2022-01-01: 12_000 diff --git a/policyengine_us/parameters/gov/local/ny/nyc/tax/income/credits/school/rate_reduction/amount/single.yaml b/policyengine_us/parameters/gov/local/ny/nyc/tax/income/credits/school/rate_reduction/amount/single.yaml deleted file mode 100644 index 0b1b627491d..00000000000 --- a/policyengine_us/parameters/gov/local/ny/nyc/tax/income/credits/school/rate_reduction/amount/single.yaml +++ /dev/null @@ -1,26 +0,0 @@ -description: NYC provides a School Tax Credit reduction amount based on filing status. -metadata: - type: marginal_rate - threshold_unit: currency-USD - rate_unit: /1 - label: NYC School Tax Credit Reduction Amount (Single) - reference: - - title: NY Tax Law § 606(ggg)(4-b)(C) - href: https://www.nysenate.gov/legislation/laws/TAX/606 - - title: Instructions for Form IT-201, 2022, Line 69a - href: https://www.tax.ny.gov/pdf/2022/printable-pdfs/inc/it201i-2022.pdf#page=27 - - title: Instructions for Form IT-201, 2023, Line 69a - href: https://web.archive.org/web/20240317205657/https://www.tax.ny.gov/pdf/2023/printable-pdfs/inc/it201i-2023.pdf#page=29 - - title: Instructions for Form IT-201, 2024, Line 69a - href: https://www.tax.ny.gov/pdf/2024/inc/it201i_2024.pdf#page=21 - - title: Instructions for Form IT-201, 2025, Line 69a - href: https://www.tax.ny.gov/pdf/2025/inc/it201i_2025.pdf#page=21 -brackets: - - rate: - 2022-01-01: 0.00171 - threshold: - 2022-01-01: 0 - - rate: - 2022-01-01: 0.00228 - threshold: - 2022-01-01: 12_000 diff --git a/policyengine_us/parameters/gov/local/ny/nyc/tax/income/credits/school/rate_reduction/amount/surviving_spouse.yaml b/policyengine_us/parameters/gov/local/ny/nyc/tax/income/credits/school/rate_reduction/amount/surviving_spouse.yaml deleted file mode 100644 index 434b7172ba6..00000000000 --- a/policyengine_us/parameters/gov/local/ny/nyc/tax/income/credits/school/rate_reduction/amount/surviving_spouse.yaml +++ /dev/null @@ -1,26 +0,0 @@ -description: NYC provides a School Tax Credit reduction amount based on filing status. -metadata: - type: marginal_rate - threshold_unit: currency-USD - rate_unit: /1 - label: NYC School Tax Credit Reduction Amount (Surviving Spouse) - reference: - - title: NY Tax Law § 606(ggg)(4-b)(A) - href: https://www.nysenate.gov/legislation/laws/TAX/606 - - title: Instructions for Form IT-201, 2022, Line 69a - href: https://www.tax.ny.gov/pdf/2022/printable-pdfs/inc/it201i-2022.pdf#page=27 - - title: Instructions for Form IT-201, 2023, Line 69a - href: https://web.archive.org/web/20240317205657/https://www.tax.ny.gov/pdf/2023/printable-pdfs/inc/it201i-2023.pdf#page=29 - - title: Instructions for Form IT-201, 2024, Line 69a - href: https://www.tax.ny.gov/pdf/2024/inc/it201i_2024.pdf#page=21 - - title: Instructions for Form IT-201, 2025, Line 69a - href: https://www.tax.ny.gov/pdf/2025/inc/it201i_2025.pdf#page=21 -brackets: - - rate: - 2022-01-01: 0.00171 - threshold: - 2022-01-01: 0 - - rate: - 2022-01-01: 0.00228 - threshold: - 2022-01-01: 21_600 diff --git a/policyengine_us/parameters/gov/local/ny/nyc/tax/income/credits/school/rate_reduction/amount/threshold.yaml b/policyengine_us/parameters/gov/local/ny/nyc/tax/income/credits/school/rate_reduction/amount/threshold.yaml new file mode 100644 index 00000000000..851c6d88e48 --- /dev/null +++ b/policyengine_us/parameters/gov/local/ny/nyc/tax/income/credits/school/rate_reduction/amount/threshold.yaml @@ -0,0 +1,35 @@ +description: New York City computes the school tax credit rate reduction amount as a share of city taxable income up to this amount, and as a base amount plus a share of the excess above it. +metadata: + propagate_metadata_to_children: true + unit: currency-USD + period: year + label: NYC school tax credit rate reduction amount threshold + breakdown: + - filing_status + reference: + - title: NY Tax Law § 606(ggg)(4-b) + href: https://www.nysenate.gov/legislation/laws/TAX/606 + - title: "L.2017, ch. 59, Part C, §§ 2, 7 (S.2009-C) #page 8-9,14" + href: https://legislation.nysenate.gov/pdf/bills/2017/S2009C#page=8 + - title: Instructions for Form IT-201, 2017, Line 69a + href: https://www.tax.ny.gov/pdf/2017/inc/it201i_2017.pdf#page=30 + - title: Instructions for Form IT-201, 2018, Line 69a + href: https://www.tax.ny.gov/pdf/2018/inc/it201i_2018.pdf#page=31 + - title: Instructions for Form IT-201, 2022, Line 69a + href: https://www.tax.ny.gov/pdf/2022/printable-pdfs/inc/it201i-2022.pdf#page=27 + - title: Instructions for Form IT-201, 2023, Line 69a + href: https://web.archive.org/web/20240317205657/https://www.tax.ny.gov/pdf/2023/printable-pdfs/inc/it201i-2023.pdf#page=29 + - title: Instructions for Form IT-201, 2024, Line 69a + href: https://www.tax.ny.gov/pdf/2024/inc/it201i_2024.pdf#page=21 + - title: Instructions for Form IT-201, 2025, Line 69a + href: https://www.tax.ny.gov/pdf/2025/inc/it201i_2025.pdf#page=21 +SINGLE: + 2017-01-01: 12_000 +JOINT: + 2017-01-01: 21_600 +SEPARATE: + 2017-01-01: 12_000 +HEAD_OF_HOUSEHOLD: + 2017-01-01: 14_400 +SURVIVING_SPOUSE: + 2017-01-01: 21_600 diff --git a/policyengine_us/parameters/gov/states/wa/dor/property_tax_exemption/senior_disabled/veteran/combined_rating_threshold.yaml b/policyengine_us/parameters/gov/states/wa/dor/property_tax_exemption/senior_disabled/veteran/combined_rating_threshold.yaml new file mode 100644 index 00000000000..5c5efcc83a0 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wa/dor/property_tax_exemption/senior_disabled/veteran/combined_rating_threshold.yaml @@ -0,0 +1,21 @@ +description: Washington qualifies a veteran entitled to and receiving VA compensation for the senior citizens and disabled persons property tax exemption at a combined service-connected evaluation rating of at least this share. +values: + # 2015 3rd sp.s. c 30 s 2: only a total disability rating qualifies. + 2016-01-01: .inf + # 2019 c 453 s 1, for taxes levied for collection in 2020 and after (s 9). + 2020-01-01: 0.8 + # 2025 c 200 s 1, for taxes levied for collection in 2027 and after (s 3). + 2027-01-01: 0.4 +metadata: + unit: /1 + period: year + label: Washington senior and disabled property tax exemption veteran combined rating threshold + reference: + - title: RCW 84.36.381(3)(a)(ii)(A) + href: https://app.leg.wa.gov/RCW/default.aspx?cite=84.36.381 + - title: RCW 84.36.381 as amended by 2015 3rd sp.s. c 30 s 2, with the s 4 application note + href: https://lawfilestestext.leg.wa.gov/LawTest/RCW%20Supplement/RCW%20%2084%20%20TITLE/RCW%20%2084%20.%2036%20%20CHAPTER/RCW%20%2084%20.%2036%20.381.htm + - title: "2019 c 453 ss 1, 9 (SSB 5160) #page 3,13" + href: https://lawfilesext.leg.wa.gov/biennium/2019-20/Pdf/Bills/Session%20Laws/Senate/5160-S.SL.pdf#page=3 + - title: "2025 c 200 ss 1, 3 (HB 1106) #page 3,5" + href: https://lawfilesext.leg.wa.gov/biennium/2025-26/Pdf/Bills/Session%20Laws/House/1106.SL.pdf#page=3 diff --git a/policyengine_us/parameters/gov/states/wa/dor/property_tax_exemption/senior_disabled/veteran/rating_requirement_in_effect.yaml b/policyengine_us/parameters/gov/states/wa/dor/property_tax_exemption/senior_disabled/veteran/rating_requirement_in_effect.yaml new file mode 100644 index 00000000000..b5ceb02ad3b --- /dev/null +++ b/policyengine_us/parameters/gov/states/wa/dor/property_tax_exemption/senior_disabled/veteran/rating_requirement_in_effect.yaml @@ -0,0 +1,18 @@ +description: Washington requires a veteran claiming the senior citizens and disabled persons property tax exemption to be entitled to and receiving VA compensation at a qualifying service-connected disability rating, if this is true. +values: + # 2008 c 6 s 706, RCW 84.36.381(3)(b): a veteran "with one hundred percent + # service-connected disability as provided in 42 U.S.C. Sec. 423(d)(1)(A)". + 2008-01-01: false + # 2015 3rd sp.s. c 30 s 2, for taxes levied for collection in 2016 and after. + 2016-01-01: true +metadata: + unit: bool + period: year + label: Washington senior and disabled property tax exemption veteran rating requirement in effect + reference: + - title: RCW 84.36.381(3)(a)(ii) + href: https://app.leg.wa.gov/RCW/default.aspx?cite=84.36.381 + - title: 2008 c 6 s 706 (2SHB 3104), RCW 84.36.381(3) + href: https://lawfilesext.leg.wa.gov/biennium/2007-08/Pdf/Bills/Session%20Laws/House/3104-S2.SL.pdf#page=85 + - title: RCW 84.36.381 as amended by 2015 3rd sp.s. c 30 s 2, with the s 4 application note + href: https://lawfilestestext.leg.wa.gov/LawTest/RCW%20Supplement/RCW%20%2084%20%20TITLE/RCW%20%2084%20.%2036%20%20CHAPTER/RCW%20%2084%20.%2036%20.381.htm diff --git a/policyengine_us/tests/code_health/test_source_conflicts.py b/policyengine_us/tests/code_health/test_source_conflicts.py index 8512cb59e88..1a6874dd81b 100644 --- a/policyengine_us/tests/code_health/test_source_conflicts.py +++ b/policyengine_us/tests/code_health/test_source_conflicts.py @@ -159,7 +159,6 @@ "policyengine_us/variables/gov/states/mn/tax/income/subtractions/mn_k12_education_subtraction.py": 1, "policyengine_us/variables/gov/states/mo/dese/ccs/eligibility/mo_ccs_income_eligible.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, "policyengine_us/variables/gov/territories/pr/tax/income/pr_agi.py": 1, } diff --git a/policyengine_us/tests/policy/baseline/gov/local/ny/nyc/tax/income/credits/income_tax_elimination/integration.yaml b/policyengine_us/tests/policy/baseline/gov/local/ny/nyc/tax/income/credits/income_tax_elimination/integration.yaml index 9a4d3d054f4..cdd4bea1425 100644 --- a/policyengine_us/tests/policy/baseline/gov/local/ny/nyc/tax/income/credits/income_tax_elimination/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/local/ny/nyc/tax/income/credits/income_tax_elimination/integration.yaml @@ -30,20 +30,12 @@ # - nyc_income_tax = line 54 - (NYC CDCC + NYC EIC + NYC school tax credit # + this credit), the model's NYC refundable credit list for 2025. # -# Set-aside assertions (pre-existing model component, not this credit): -# Tax Law § 606(ggg)(4-b) and the IT-201-I line 69a worksheets give the NYC -# school tax credit rate reduction amount as "$25 plus 0.228% of the excess -# over $14,400" (head of household), "$37 plus ... over $21,600" (joint) and -# "$21 plus ... over $12,000" (single/separate). The model's -# school/rate_reduction/amount parameters are plain marginal schedules, so the -# base is 0.171% x 14,400 = 24.624 (joint 36.936, single 20.52). Once city -# taxable income passes the first bracket, the model's school tax credit, and -# so nyc_income_tax, differ from the forms by 0.376 (head of household) or -# 0.064 (joint). In Cases 1, 2, 3, 5 and 6 the nyc_school_tax_credit and -# nyc_income_tax assertions are commented out with their form values. The -# elimination credit does not use the school tax credit (IT-270 lines 6-10), -# so every credit assertion stays active. Case 4 (city taxable income below -# $14,400) asserts both. +# NYC school tax credit (line 69 / 69a): Tax Law § 606(ggg)(4-b) and the +# IT-201-I line 69a worksheets give the rate reduction amount as "$25 plus +# 0.228% of the excess over $14,400" (head of household), "$37 plus ... over +# $21,600" (joint) and "$21 plus ... over $12,000" (single/separate). The +# model uses these statutory bases, so the nyc_school_tax_credit and +# nyc_income_tax assertions hold the form values in every case. - name: Case 1, head of household with two children below the threshold gets the full credit. period: 2025 @@ -105,12 +97,11 @@ # Line 69a: HOH, city taxable income 22,800 over 14,400: # $25 + 0.228% x 8,400 = 25 + 19.152 = 44.152 (Tax Law § 606(ggg)(4-b)(B)). # Total = 63 + 44.152 = 107.152. - # Set aside (see header; the model's base is 24.624, not $25): - # nyc_school_tax_credit: 107.152 + nyc_school_tax_credit: 107.152 # 759.24 - (0 + 673.1865 + 107.152 + 86.0535) = 759.24 - 866.392 # = -107.152: the credit zeroes the NYC tax, leaving only the school - # tax credit refund. Set aside with the school tax credit: - # nyc_income_tax: -107.152 + # tax credit refund. + nyc_income_tax: -107.152 - name: Case 2, head of household with two children inside the $5,000 band gets a partial credit. period: 2025 @@ -165,11 +156,10 @@ nyc_income_tax_elimination_credit: 165.8724408 # Line 69 fixed $63; line 69a HOH: 25 + 0.228% x 11,400 = 25 + 25.992 # = 50.992; total 113.992. - # Set aside (see header; the model's base is 24.624, not $25): - # nyc_school_tax_credit: 113.992 + nyc_school_tax_credit: 113.992 # 872.10 - (0 + 578.4165 + 113.992 + 165.8724408) = 872.10 - 858.2809408 - # = 13.8190592. Set aside with the school tax credit: - # nyc_income_tax: 13.8190592 + # = 13.8190592. + nyc_income_tax: 13.8190592 - name: Case 3, married couple with three children one dollar above the threshold plus $5,000 gets no credit. period: 2025 @@ -228,11 +218,9 @@ # Line 69 fixed $125 (MFJ); line 69a MFJ: $37 + 0.228% x 18,896 # = 37 + 43.08288 = 80.08288 (Tax Law § 606(ggg)(4-b)(A)); # total 205.08288. - # Set aside (see header; the model's base is 36.936, not $37): - # nyc_school_tax_credit: 205.08288 + nyc_school_tax_credit: 205.08288 # 1,375.71552 - (0 + 192.25944 + 205.08288 + 0) = 978.3732. - # Set aside with the school tax credit: - # nyc_income_tax: 978.3732 + nyc_income_tax: 978.3732 - name: Case 4, head of household with one child whose NYC EIC exceeds line 54 gets no credit. period: 2025 @@ -350,11 +338,9 @@ nyc_income_tax_elimination_credit: 2_361.852 # Line 69 fixed $63; line 69a HOH: 25 + 0.228% x (64,800 - 14,400 # = 50,400) = 25 + 114.912 = 139.912; total 202.912. - # Set aside (see header; the model's base is 24.624, not $25): - # nyc_school_tax_credit: 202.912 + nyc_school_tax_credit: 202.912 # 2,361.852 - (0 + 0 + 202.912 + 2,361.852) = -202.912. - # Set aside with the school tax credit: - # nyc_income_tax: -202.912 + nyc_income_tax: -202.912 - name: Case 6, head of household with $10,001 of interest income is ineligible despite positive line 10. period: 2025 @@ -410,8 +396,6 @@ nyc_income_tax_elimination_credit: 0 # Line 69 fixed $63; line 69a HOH: 25 + 0.228% x 7,401 = 25 + 16.87428 # = 41.87428; total 104.87428. - # Set aside (see header; the model's base is 24.624, not $25): - # nyc_school_tax_credit: 104.87428 + nyc_school_tax_credit: 104.87428 # 721.65762 - (0 + 704.74491 + 104.87428 + 0) = -87.96157. - # Set aside with the school tax credit: - # nyc_income_tax: -87.96157 + nyc_income_tax: -87.96157 diff --git a/policyengine_us/tests/policy/baseline/gov/local/ny/nyc/tax/income/credits/school/nyc_school_tax_credit.yaml b/policyengine_us/tests/policy/baseline/gov/local/ny/nyc/tax/income/credits/school/nyc_school_tax_credit.yaml index e012d75345e..ce11ac03dfc 100644 --- a/policyengine_us/tests/policy/baseline/gov/local/ny/nyc/tax/income/credits/school/nyc_school_tax_credit.yaml +++ b/policyengine_us/tests/policy/baseline/gov/local/ny/nyc/tax/income/credits/school/nyc_school_tax_credit.yaml @@ -30,9 +30,9 @@ nyc_taxable_income: 441_000 nyc_school_tax_credit_fixed_amount_eligible: false nyc_school_tax_credit_rate_reduction_amount_eligible: true - # 0.171% x 12,000 + 0.228% x (441,000 - 12,000) = 20.52 + 978.12 - nyc_school_tax_credit_rate_reduction_amount: 998.64 - nyc_school_tax_credit: 998.64 + # § 606(ggg)(4-b)(C): $21 + 0.228% x (441,000 - 12,000) = 21 + 978.12. + nyc_school_tax_credit_rate_reduction_amount: 999.12 + nyc_school_tax_credit: 999.12 - name: Income just over $500,000 denies the rate reduction amount although city taxable income is under $500,000. period: 2025 @@ -83,9 +83,9 @@ # deduction = 272,000. nyc_taxable_income: 272_000 nyc_school_tax_credit_fixed_amount: 63 - # 20.52 + 0.228% x (272,000 - 12,000) = 20.52 + 592.80 - nyc_school_tax_credit_rate_reduction_amount: 613.32 - nyc_school_tax_credit: 676.32 + # § 606(ggg)(4-b)(C): $21 + 0.228% x (272,000 - 12,000) = 21 + 592.80. + nyc_school_tax_credit_rate_reduction_amount: 613.80 + nyc_school_tax_credit: 676.80 - name: City taxable income over $500,000 denies the rate reduction amount although income is under $500,000. period: 2025 @@ -144,6 +144,6 @@ nyc_taxable_income: 482_950 nyc_school_tax_credit_fixed_amount_eligible: false nyc_school_tax_credit_rate_reduction_amount_eligible: true - # 0.171% x 21,600 + 0.228% x (482,950 - 21,600) = 36.936 + 1,051.878 - nyc_school_tax_credit_rate_reduction_amount: 1_088.81 - nyc_school_tax_credit: 1_088.81 + # § 606(ggg)(4-b)(A): $37 + 0.228% x (482,950 - 21,600) = 37 + 1,051.878. + nyc_school_tax_credit_rate_reduction_amount: 1_088.878 + nyc_school_tax_credit: 1_088.878 diff --git a/policyengine_us/tests/policy/baseline/gov/local/ny/nyc/tax/income/credits/school/nyc_school_tax_credit_rate_reduction_amount.yaml b/policyengine_us/tests/policy/baseline/gov/local/ny/nyc/tax/income/credits/school/nyc_school_tax_credit_rate_reduction_amount.yaml index 0a2ab880b66..484a63fc039 100644 --- a/policyengine_us/tests/policy/baseline/gov/local/ny/nyc/tax/income/credits/school/nyc_school_tax_credit_rate_reduction_amount.yaml +++ b/policyengine_us/tests/policy/baseline/gov/local/ny/nyc/tax/income/credits/school/nyc_school_tax_credit_rate_reduction_amount.yaml @@ -13,7 +13,7 @@ - name: Joint filing gets $37 plus .228% of taxable income above $21,600 for total income not over $500,000. period: 2022 - absolute_error_margin: 1 # The $37 amount is rounded in the instructions. + absolute_error_margin: 0.01 input: nyc_school_tax_credit_rate_reduction_amount_eligible: true nyc_taxable_income: 500_000 @@ -22,7 +22,8 @@ # NYC School Tax Instructions # See Page 27 for rate reduction amount # https://www.tax.ny.gov/pdf/2022/printable-pdfs/inc/it201i-2022.pdf#page=27 - nyc_school_tax_credit_rate_reduction_amount: 1_127.75 + # Tax Law § 606(ggg)(4-b)(A): 37 + 0.00228 * (500_000 - 21_600) = 1_127.752. + nyc_school_tax_credit_rate_reduction_amount: 1_127.752 - name: Joint filing gets no reduction amount if not eligible. period: 2022 @@ -52,7 +53,7 @@ - name: Single person gets $21 plus .228% of taxable income above $12,000 for total income not over $500,000. period: 2022 - absolute_error_margin: 1 # The $21 amount is rounded in the instructions. + absolute_error_margin: 0.01 input: nyc_school_tax_credit_rate_reduction_amount_eligible: true nyc_taxable_income: 500_000 @@ -61,6 +62,7 @@ # NYC School Tax Instructions # See Page 27 for rate reduction amount # https://www.tax.ny.gov/pdf/2022/printable-pdfs/inc/it201i-2022.pdf#page=27 + # Tax Law § 606(ggg)(4-b)(C): 21 + 0.00228 * (500_000 - 12_000) = 1_133.64. nyc_school_tax_credit_rate_reduction_amount: 1_133.64 - name: Household head gets .171% of taxable income for income not over $14,400. @@ -78,7 +80,7 @@ - name: Household head gets $25 plus .228% of taxable income above $14,400 for total income not over $500,000. period: 2022 - absolute_error_margin: 1 # The $25 amount is rounded in the instructions. + absolute_error_margin: 0.01 input: nyc_school_tax_credit_rate_reduction_amount_eligible: true nyc_taxable_income: 500_000 @@ -87,4 +89,134 @@ # NYC School Tax Instructions # See Page 27 for rate reduction amount # https://www.tax.ny.gov/pdf/2022/printable-pdfs/inc/it201i-2022.pdf#page=27 - nyc_school_tax_credit_rate_reduction_amount: 1_132.17 + # Tax Law § 606(ggg)(4-b)(B): 25 + 0.00228 * (500_000 - 14_400) = 1_132.168. + nyc_school_tax_credit_rate_reduction_amount: 1_132.168 + +# Tax Law § 606(ggg)(4-b), as amended by L.2017, ch. 59, Part C, § 2 for tax +# years beginning on and after January 1, 2017 (S.2009-C, PDF pages 8-9 and +# 14), sets the amount above each threshold as a statutory base plus 0.228% +# of the excess. The bases ($37 joint and surviving spouse, $25 head of +# household, $21 single and separate) are fixed in the statute; they are not +# 0.171% of the threshold (36.936, 24.624 and 20.52). City taxable income +# equal to the threshold is "not over" it and stays in the lower branch. +# 2025 IT-201-I line 69a tables (PDF page 21) give the same values. + +- name: 2017 head of household above the threshold gets the statutory $25 base. + period: 2017 + absolute_error_margin: 0.001 + input: + nyc_school_tax_credit_rate_reduction_amount_eligible: true + nyc_taxable_income: 20_000 + filing_status: HEAD_OF_HOUSEHOLD + output: + # 25 + 0.00228 * (20_000 - 14_400) = 25 + 12.768 = 37.768. + nyc_school_tax_credit_rate_reduction_amount: 37.768 + +- name: 2025 joint filers above the threshold get the statutory $37 base. + period: 2025 + absolute_error_margin: 0.001 + input: + nyc_school_tax_credit_rate_reduction_amount_eligible: true + nyc_taxable_income: 30_000 + filing_status: JOINT + output: + # 37 + 0.00228 * (30_000 - 21_600) = 37 + 19.152 = 56.152. + nyc_school_tax_credit_rate_reduction_amount: 56.152 + +- name: 2025 single filer above the threshold gets the statutory $21 base. + period: 2025 + absolute_error_margin: 0.001 + input: + nyc_school_tax_credit_rate_reduction_amount_eligible: true + nyc_taxable_income: 20_000 + filing_status: SINGLE + output: + # 21 + 0.00228 * (20_000 - 12_000) = 21 + 18.24 = 39.24. + nyc_school_tax_credit_rate_reduction_amount: 39.24 + +- name: 2017 surviving spouse one dollar above the threshold gets the $37 base. + period: 2017 + absolute_error_margin: 0.001 + input: + nyc_school_tax_credit_rate_reduction_amount_eligible: true + nyc_taxable_income: 21_601 + filing_status: SURVIVING_SPOUSE + output: + # 37 + 0.00228 * 1 = 37.00228. + nyc_school_tax_credit_rate_reduction_amount: 37.00228 + +- name: 2017 separate filer one dollar above the threshold gets the $21 base. + period: 2017 + absolute_error_margin: 0.001 + input: + nyc_school_tax_credit_rate_reduction_amount_eligible: true + nyc_taxable_income: 12_001 + filing_status: SEPARATE + output: + # 21 + 0.00228 * 1 = 21.00228. + nyc_school_tax_credit_rate_reduction_amount: 21.00228 + +- name: 2017 separate filer at the threshold stays in the lower branch. + period: 2017 + absolute_error_margin: 0.001 + input: + nyc_school_tax_credit_rate_reduction_amount_eligible: true + nyc_taxable_income: 12_000 + filing_status: SEPARATE + output: + # "Not over $12,000": 0.00171 * 12_000 = 20.52. + nyc_school_tax_credit_rate_reduction_amount: 20.52 + +- name: 2017 joint filers at the threshold stay in the lower branch. + period: 2017 + absolute_error_margin: 0.001 + input: + nyc_school_tax_credit_rate_reduction_amount_eligible: true + nyc_taxable_income: 21_600 + filing_status: JOINT + output: + # "Not over $21,600": 0.00171 * 21_600 = 36.936. + nyc_school_tax_credit_rate_reduction_amount: 36.936 + +- name: Negative city taxable income gives no rate reduction amount. + period: 2025 + absolute_error_margin: 0.001 + input: + nyc_school_tax_credit_rate_reduction_amount_eligible: true + nyc_taxable_income: -5_000 + filing_status: SINGLE + output: + nyc_school_tax_credit_rate_reduction_amount: 0 + +- name: Mixed filing statuses are computed together. + period: 2025 + absolute_error_margin: 0.001 + input: + people: + person1: {} + person2: {} + person3: {} + tax_units: + tax_unit1: + members: [person1] + nyc_school_tax_credit_rate_reduction_amount_eligible: true + nyc_taxable_income: 10_000 + filing_status: SINGLE + tax_unit2: + members: [person2] + nyc_school_tax_credit_rate_reduction_amount_eligible: true + nyc_taxable_income: 14_401 + filing_status: HEAD_OF_HOUSEHOLD + tax_unit3: + members: [person3] + nyc_school_tax_credit_rate_reduction_amount_eligible: true + nyc_taxable_income: 100_000 + filing_status: JOINT + households: + household: + members: [person1, person2, person3] + output: + # Single below its threshold: 0.00171 * 10_000 = 17.1. + # Head of household $1 above: 25 + 0.00228 = 25.00228. + # Joint: 37 + 0.00228 * (100_000 - 21_600) = 37 + 178.752 = 215.752. + nyc_school_tax_credit_rate_reduction_amount: [17.1, 25.00228, 215.752] diff --git a/policyengine_us/tests/policy/baseline/gov/local/ny/nyc/tax/income/credits/school/test_nyc_school_tax_credit_income_test_invariants.py b/policyengine_us/tests/policy/baseline/gov/local/ny/nyc/tax/income/credits/school/test_nyc_school_tax_credit_income_test_invariants.py index 453b15fdf9d..b34e4c5853f 100644 --- a/policyengine_us/tests/policy/baseline/gov/local/ny/nyc/tax/income/credits/school/test_nyc_school_tax_credit_income_test_invariants.py +++ b/policyengine_us/tests/policy/baseline/gov/local/ny/nyc/tax/income/credits/school/test_nyc_school_tax_credit_income_test_invariants.py @@ -12,7 +12,7 @@ other; 2. the rate reduction amount matches the statutory tables applied to city taxable income (a differential check against the text of § 606(ggg)(4-b), - whose second-band base amounts are rounded; see #8947) and is zero when + including its fixed second-band base amounts; see #8947) and is zero when ineligible; 3. school tax credit income equals federal AGI minus the head's and spouse's IRA and SEP distributions, is never above AGI, and ignores dependents' @@ -66,10 +66,10 @@ } LOW_RATE = 0.00171 EXCESS_RATE = 0.00228 -# The model carries the first band into the second at the marginal rate -# (e.g. 12,000 x 0.171% = 20.52) where the statute prints rounded base -# amounts (21), a gap of at most 0.48 (#8947). -TOLERANCE = 0.5 +# The second band starts from the statute's base amounts (e.g. $21), not the +# first band carried forward at 0.171% (12,000 x 0.171% = 20.52; #8947), so +# the model matches the tables up to float32 rounding. +TOLERANCE = 1e-3 def statutory_rate_reduction(taxable_income, filing_status): diff --git a/policyengine_us/tests/policy/baseline/gov/states/household/state_property_tax_credits/in_blind_disabled_property_tax_credit_in_aggregate.yaml b/policyengine_us/tests/policy/baseline/gov/states/household/state_property_tax_credits/in_blind_disabled_property_tax_credit_in_aggregate.yaml index d23edaeb11c..8371fadd14a 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/household/state_property_tax_credits/in_blind_disabled_property_tax_credit_in_aggregate.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/household/state_property_tax_credits/in_blind_disabled_property_tax_credit_in_aggregate.yaml @@ -21,6 +21,11 @@ adjusted_gross_income: 2024: 30_000 2026: 30_000 + in_supplemental_homestead_credit_eligible: true + # Homestead liability after the over-65 and blind/disabled credits, + # which DLGF's order of operations applies first (June 18, 2025 FAQ, + # questions 29 and 33): 2,000 - 150 - 125 = 1,725. + in_homestead_property_tax_liability: 1_725 households: household: members: [person1] @@ -28,12 +33,12 @@ output: # A disabled senior homeowner qualifies for all three SEA 1 credits, which # stack in the umbrella: over-65 $150 (senior, 2024 AGI 30,000 under the - # limit, homeowner) + blind/disabled $125 + supplemental homestead $200 - # (10% of 2,000, capped at $300) = $475. + # limit, homeowner) + blind/disabled $125 + supplemental homestead $172.50 + # (10% of 1,725, capped at $300) = $447.50. in_over_65_property_tax_credit: 150 in_blind_disabled_property_tax_credit: 125 - in_supplemental_homestead_credit: 200 - taxsim_state_property_tax_credit: 475 + in_supplemental_homestead_credit: 172.5 + taxsim_state_property_tax_credit: 447.5 - name: 2025 umbrella excludes the blind/disabled credit period: 2025 diff --git a/policyengine_us/tests/policy/baseline/gov/states/household/state_property_tax_credits/in_supplemental_homestead_credit_in_aggregate.yaml b/policyengine_us/tests/policy/baseline/gov/states/household/state_property_tax_credits/in_supplemental_homestead_credit_in_aggregate.yaml index 4d4f535544d..5fd67c8b6c0 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/household/state_property_tax_credits/in_supplemental_homestead_credit_in_aggregate.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/household/state_property_tax_credits/in_supplemental_homestead_credit_in_aggregate.yaml @@ -21,16 +21,21 @@ adjusted_gross_income: 2024: 30_000 2026: 30_000 + in_supplemental_homestead_credit_eligible: true + # Homestead liability after the $150 over-65 credit, which DLGF's + # order of operations applies first (June 18, 2025 FAQ, questions 29 + # and 33): 2,000 - 150 = 1,850. + in_homestead_property_tax_liability: 1_850 households: household: members: [person1] state_code: IN output: - # Supplemental: 10% of 2,000 = 200. Over-65: $150 (senior, 2024 AGI 30,000 - # under the limit, homeowner). Umbrella = 350. - in_supplemental_homestead_credit: 200 + # Supplemental: 10% of 1,850 = 185. Over-65: $150 (senior, 2024 AGI 30,000 + # under the limit, homeowner). Umbrella = 335. + in_supplemental_homestead_credit: 185 in_over_65_property_tax_credit: 150 - taxsim_state_property_tax_credit: 350 + taxsim_state_property_tax_credit: 335 - name: 2025 umbrella excludes the supplemental homestead credit period: 2025 diff --git a/policyengine_us/tests/policy/baseline/gov/states/in/tax/property/supplemental_homestead_credit/in_supplemental_homestead_credit.yaml b/policyengine_us/tests/policy/baseline/gov/states/in/tax/property/supplemental_homestead_credit/in_supplemental_homestead_credit.yaml index fb778e8a0d7..c214c32a066 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/in/tax/property/supplemental_homestead_credit/in_supplemental_homestead_credit.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/in/tax/property/supplemental_homestead_credit/in_supplemental_homestead_credit.yaml @@ -1,9 +1,18 @@ # Indiana supplemental homestead credit (Senate Enrolled Act 1, 2025; -# IC 6-1.1-20.6-7.7): the lesser of 10% of the homestead property tax liability -# or $300, for taxes first due and payable in 2026 and after. No age or income -# limit. +# IC 6-1.1-20.6-7.7), for property taxes first due and payable in 2026 and +# after: +# - (b): a person who qualifies for the homestead standard deduction under +# IC 6-1.1-12-37 for their homestead (or the surviving spouse of one who +# did) is entitled to the credit; +# - (c): the credit is the lesser of 10% of the property tax liability on that +# homestead or $300; +# - (d): taxes approved by referendum or local public question are not +# considered. +# DLGF June 18, 2025 FAQ, questions 26-30 (PDF pages 7-8), confirms all three. +# Generic real_estate_taxes neither establish qualification nor measure the +# homestead liability. -- name: Case 1, 2026 homeowner below the cap receives 10% of property tax. +- name: Case 1, 2026 qualifying homestead below the cap receives 10% of its liability. period: 2026 absolute_error_margin: 0.01 input: @@ -13,6 +22,8 @@ tax_units: tax_unit: members: [person1] + in_supplemental_homestead_credit_eligible: true + in_homestead_property_tax_liability: 2_000 households: household: members: [person1] @@ -20,7 +31,7 @@ output: in_supplemental_homestead_credit: 200 -- name: Case 2, 2026 homeowner at the $3,000 liability boundary receives the $300 cap. +- name: Case 2, 2026 qualifying homestead at the $3,000 liability boundary receives the $300 cap. period: 2026 absolute_error_margin: 0.01 input: @@ -30,6 +41,8 @@ tax_units: tax_unit: members: [person1] + in_supplemental_homestead_credit_eligible: true + in_homestead_property_tax_liability: 3_000 households: household: members: [person1] @@ -37,7 +50,7 @@ output: in_supplemental_homestead_credit: 300 -- name: Case 3, 2026 homeowner above the cap is limited to $300. +- name: Case 3, 2026 qualifying homestead above the cap is limited to $300. period: 2026 absolute_error_margin: 0.01 input: @@ -47,6 +60,8 @@ tax_units: tax_unit: members: [person1] + in_supplemental_homestead_credit_eligible: true + in_homestead_property_tax_liability: 5_000 households: household: members: [person1] @@ -54,7 +69,7 @@ output: in_supplemental_homestead_credit: 300 -- name: Case 4, 2026 renter with no real estate taxes receives no credit. +- name: Case 4, 2026 renter with no homestead receives no credit. period: 2026 absolute_error_margin: 0.01 input: @@ -64,6 +79,8 @@ tax_units: tax_unit: members: [person1] + in_supplemental_homestead_credit_eligible: false + in_homestead_property_tax_liability: 0 households: household: members: [person1] @@ -81,6 +98,8 @@ tax_units: tax_unit: members: [person1] + in_supplemental_homestead_credit_eligible: true + in_homestead_property_tax_liability: 2_000 households: household: members: [person1] @@ -100,10 +119,79 @@ tax_units: tax_unit: members: [person1, person2] + in_supplemental_homestead_credit_eligible: true + in_homestead_property_tax_liability: 4_000 households: household: members: [person1, person2] state_code: IN output: - # 10% of the combined $3,000 is $300, exactly the cap, for the tax unit. + # 10% of the $4,000 homestead liability is $400, capped once at $300. + in_supplemental_homestead_credit: 300 + +- name: Case 7, real estate taxes without homestead qualification produce no credit. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: IN + real_estate_taxes: 3_000 + in_supplemental_homestead_credit_eligible: false + in_homestead_property_tax_liability: 0 + in_homestead_referendum_property_tax: 0 + output: + # IC 6-1.1-20.6-7.7(b): no homestead deduction qualification, no credit. + # Before this fix the model gave min(10% x 3,000, 300) = 300. + in_supplemental_homestead_credit: 0 + +- name: Case 8, only the qualifying homestead's liability enters the credit. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: IN + real_estate_taxes: 5_000 + in_supplemental_homestead_credit_eligible: true + in_homestead_property_tax_liability: 2_000 + in_homestead_referendum_property_tax: 0 + output: + # IC 6-1.1-20.6-7.7(c): min(10% x 2,000, 300) = 200. The other $3,000 of + # real estate taxes is on other property. Before this fix: 300. + in_supplemental_homestead_credit: 200 + +- name: Case 9, referendum-approved homestead taxes are excluded. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: IN + real_estate_taxes: 2_000 + in_supplemental_homestead_credit_eligible: true + in_homestead_property_tax_liability: 2_000 + in_homestead_referendum_property_tax: 1_000 + output: + # IC 6-1.1-20.6-7.7(d): min(10% x (2,000 - 1,000), 300) = 100. Before this + # fix: 200. + in_supplemental_homestead_credit: 100 + +- name: Case 10, referendum taxes above the reported liability floor the base at zero. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: IN + real_estate_taxes: 1_000 + in_supplemental_homestead_credit_eligible: true + in_homestead_property_tax_liability: 1_000 + in_homestead_referendum_property_tax: 1_200 + output: + in_supplemental_homestead_credit: 0 + +- name: Case 11, the cap binds after the referendum exclusion. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: IN + real_estate_taxes: 6_000 + in_supplemental_homestead_credit_eligible: true + in_homestead_property_tax_liability: 6_000 + in_homestead_referendum_property_tax: 2_000 + output: + # min(10% x (6,000 - 2,000), 300) = min(400, 300) = 300. in_supplemental_homestead_credit: 300 diff --git a/policyengine_us/tests/policy/baseline/gov/states/va/tax/income/deductions/plan_529/va_529_plan_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/va/tax/income/deductions/plan_529/va_529_plan_deduction.yaml index 5cddd899160..5bb67803d10 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/va/tax/income/deductions/plan_529/va_529_plan_deduction.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/va/tax/income/deductions/plan_529/va_529_plan_deduction.yaml @@ -16,7 +16,7 @@ output: va_529_plan_deduction: 4_000 -- name: Two beneficiaries increases the cap +- name: Without account-level amounts, two accounts default to an even split of contributions period: 2024 input: people: @@ -31,6 +31,10 @@ members: [person1] state_code: VA output: + # va_529_plan_deduction_capped_amount is not supplied, so it defaults to + # min(7_000, 4_000 x 2) = 7_000, the per-account caps applied to 3_500 + # contributed to each of two accounts. + va_529_plan_deduction_capped_amount: 7_000 va_529_plan_deduction: 7_000 - name: Zero contributions @@ -163,3 +167,118 @@ output: va_529_plan_deduction_person: [0, 0] va_529_plan_deduction: 0 + +# Va. Code § 58.1-322.03(7)(a) limits the deduction to "$4,000 per prepaid +# tuition contract or college savings trust account" and carries forward +# contributions above that amount "until the purchase price or college savings +# trust contribution has been fully deducted". Subdivision 7(b) lets an owner +# aged 70 or older deduct "the full amount ... less any amounts previously +# deducted". The 2024 Form 760 instructions, code 104, agree: "the lesser of +# $4,000 or the amount contributed during the taxable year to each +# Commonwealth Savers account". + +- name: Uneven account contributions receive separate caps + period: 2024 + input: + state_code: VA + age: 45 + investment_in_529_plan_indv: 8_000 + count_529_contribution_beneficiaries: 2 + va_529_plan_deduction_capped_amount: 5_000 + va_529_plan_carryforward: 0 + output: + # Account records: $7,000 and $1,000, so min(7_000, 4_000) + # + min(1_000, 4_000) = 5_000. Before this fix the pooled cap + # min(8_000, 4_000 x 2) gave 8_000. + va_529_plan_deduction: 5_000 + +- name: Prior undeducted contributions remain deductible + period: 2024 + input: + state_code: VA + age: 45 + investment_in_529_plan_indv: 0 + count_529_contribution_beneficiaries: 1 + va_529_plan_deduction_capped_amount: 3_000 + va_529_plan_carryforward: 3_000 + output: + # One account with a $3,000 carryforward: min(0 + 3_000, 4_000) = 3_000. + # Before this fix the model allowed only current contributions, 0. + va_529_plan_deduction: 3_000 + +- name: Age 70 removes the annual cap on current and carried-forward contributions + period: 2024 + input: + state_code: VA + age: 70 + investment_in_529_plan_indv: 1_000 + va_529_plan_deduction_capped_amount: 4_000 + va_529_plan_carryforward: 6_000 + output: + # 1_000 current + 6_000 undeducted carryforward = 7_000, uncapped. + va_529_plan_deduction: 7_000 + +- name: Without account-level amounts, a carryforward into one account is capped with the current contribution + period: 2024 + input: + state_code: VA + age: 45 + investment_in_529_plan_indv: 3_000 + count_529_contribution_beneficiaries: 1 + va_529_plan_carryforward: 2_000 + output: + # Default capped amount: min(3_000 + 2_000, 4_000 x 1) = 4_000. + va_529_plan_deduction_capped_amount: 4_000 + va_529_plan_deduction: 4_000 + +- name: A dependent's account-level amount is not deducted on the parents' return + period: 2024 + input: + people: + person1: + age: 45 + person2: + age: 16 + is_tax_unit_dependent: true + investment_in_529_plan_indv: 1_000 + count_529_contribution_beneficiaries: 1 + va_529_plan_deduction_capped_amount: 1_000 + va_529_plan_carryforward: 500 + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: VA + output: + va_529_plan_deduction_person: [0, 0] + va_529_plan_deduction: 0 + +- name: Each spouse's account-level amounts and carryforwards stay with that owner + period: 2024 + input: + people: + person1: + age: 45 + investment_in_529_plan_indv: 9_000 + count_529_contribution_beneficiaries: 2 + va_529_plan_deduction_capped_amount: 7_000 + person2: + age: 72 + investment_in_529_plan_indv: 500 + count_529_contribution_beneficiaries: 1 + va_529_plan_carryforward: 2_500 + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: VA + output: + # Person 1 (under 70) contributed $6,000 and $3,000 to two accounts: + # min(6_000, 4_000) + min(3_000, 4_000) = 7_000. Person 2 (72): + # 500 + 2_500 = 3_000. + va_529_plan_deduction_person: [7_000, 3_000] + va_529_plan_deduction: 10_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/wa/dor/property_tax_exemption/senior_disabled/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/wa/dor/property_tax_exemption/senior_disabled/integration.yaml index 9b0df0249b2..a6ec0c265e4 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wa/dor/property_tax_exemption/senior_disabled/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wa/dor/property_tax_exemption/senior_disabled/integration.yaml @@ -2,7 +2,8 @@ # Property Tax Exemption (RCW 84.36.379-389; WAC 458-16A-100..150). # # Eligibility: someone who is the tax-unit head (or spouse in a joint return) -# satisfies the age threshold (62 pre-2020, 61 from 2020) OR is_disabled; +# satisfies the age threshold (62 pre-2020, 61 from 2020), retired from regular +# gainful employment by reason of disability, or the disabled veteran pathway; # the tax unit owns an occupied residence (real_estate_taxes > 0); # combined disposable income (annual) <= Tier 3 threshold for the household's county. # @@ -61,13 +62,14 @@ wa_pte_tier: 1 wa_senior_disabled_property_tax_exemption: 5_184 -- name: Case 2, eligible disabled person under age threshold qualifies for Tier 1. +- name: Case 2, person under age threshold retired by reason of disability qualifies for Tier 1. period: 2024 input: people: person1: age: 45 is_disabled: true + wa_pte_retired_due_to_disability: true real_estate_taxes: 4_800 assessed_property_value: 500_000 tax_units: diff --git a/policyengine_us/tests/policy/baseline/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_pte_categorical_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_pte_categorical_eligible.yaml index 88c89a8535b..e4e217cc62e 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_pte_categorical_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_pte_categorical_eligible.yaml @@ -18,13 +18,14 @@ output: wa_pte_categorical_eligible: true -- name: Case 2, person under age threshold who is disabled is categorically eligible by disability. +- name: Case 2, person under age threshold retired by reason of disability is categorically eligible. period: 2024 input: people: person1: age: 45 is_disabled: true + wa_pte_retired_due_to_disability: true tax_units: tax_unit: members: [person1] @@ -58,13 +59,14 @@ output: wa_pte_categorical_eligible: false -- name: Case 4, person aged 70 who is also disabled is categorically eligible (OR semantics). +- name: Case 4, person aged 70 who is also retired by reason of disability is categorically eligible (OR semantics). period: 2024 input: people: person1: age: 70 is_disabled: true + wa_pte_retired_due_to_disability: true tax_units: tax_unit: members: [person1] @@ -142,3 +144,241 @@ # ESHB 1105 lowered the age threshold to 61 effective 2020-01-01. # 60 < 61 -> not categorically eligible. wa_pte_categorical_eligible: false + +# RCW 84.36.381(3)(a): the claimant must be (i) 61 or older, or retired from +# regular gainful employment by reason of disability, or (ii) a veteran +# entitled to and receiving VA compensation at a qualifying service-connected +# rating. Generic disability (is_disabled) establishes neither pathway. +# Veteran rating tests by collection year (session laws, PDF page 3 each): +# - 2016-2019 (2015 3rd sp.s. c 30 s 2): a total disability rating; a 100% +# combined evaluation is a total rating (38 CFR 3.340(a)(2)). +# - 2020-2026 (2019 c 453 s 1): combined rating of 80% or more, or a total rating. +# - 2027 on (2025 c 200 s 1): combined rating of 40% or more, or a total rating. + +- name: Case 8, generic disability without disability retirement does not qualify. + period: 2024 + input: + state_code: WA + age: 45 + is_disabled: true + is_veteran: false + wa_pte_retired_due_to_disability: false + wa_pte_receives_va_disability_compensation: false + real_estate_taxes: 5_000 + assessed_property_value: 500_000 + wa_pte_income_eligible: true + wa_pte_tier: 1 + output: + # 45 < 61 and neither statutory disability pathway holds. Before this fix + # the model awarded 5,000 x 0.30 + 300,000 x (5,000 x 0.70 / 500,000) + # = 3,600. + wa_pte_categorical_eligible: false + wa_pte_eligible: false + wa_senior_disabled_property_tax_exemption: 0 + +- name: Case 9, retirement by reason of disability establishes the disability pathway. + period: 2024 + input: + state_code: WA + age: 45 + is_disabled: true + is_veteran: false + wa_pte_retired_due_to_disability: true + wa_pte_receives_va_disability_compensation: false + real_estate_taxes: 5_000 + assessed_property_value: 500_000 + wa_pte_income_eligible: true + wa_pte_tier: 1 + output: + # 5,000 x 0.30 + max(60,000, 500,000 x 0.60) x (5,000 x 0.70 / 500,000) + # = 1,500 + 300,000 x 0.007 = 3,600. + wa_pte_categorical_eligible: true + wa_pte_eligible: true + wa_senior_disabled_property_tax_exemption: 3_600 + +- name: Case 10, a compensated 40 percent veteran qualifies beginning in collection year 2027. + period: 2027 + input: + state_code: + 2026: WA + 2027: WA + age: + 2026: 45 + 2027: 46 + is_disabled: + 2026: false + 2027: false + is_veteran: + 2026: true + 2027: true + wa_pte_retired_due_to_disability: + 2026: false + 2027: false + wa_pte_receives_va_disability_compensation: + 2026: true + 2027: true + wa_pte_va_service_connected_rating: + 2026: 0.4 + 2027: 0.4 + wa_pte_va_total_disability_rating: + 2026: false + 2027: false + output: + # 0.40 < 0.80 in 2026; 0.40 >= 0.40 in 2027. + wa_pte_categorical_eligible: + 2026: false + 2027: true + +- name: Case 11, a compensated veteran rated 80 percent qualifies in 2024 without generic disability. + period: 2024 + input: + state_code: WA + age: 45 + is_disabled: false + is_veteran: true + wa_pte_receives_va_disability_compensation: true + wa_pte_va_service_connected_rating: 0.8 + output: + # 2019 c 453 s 1: a combined rating of 80% or higher. Before this fix the + # model required is_disabled and returned false. + wa_pte_categorical_eligible: true + +- name: Case 12, a compensated veteran rated 70 percent does not qualify in 2024. + period: 2024 + input: + state_code: WA + age: 45 + is_veteran: true + wa_pte_receives_va_disability_compensation: true + wa_pte_va_service_connected_rating: 0.7 + output: + wa_pte_categorical_eligible: false + +- name: Case 13, a total disability rating qualifies a compensated veteran regardless of the combined rating. + period: 2024 + input: + state_code: WA + age: 45 + is_veteran: true + wa_pte_receives_va_disability_compensation: true + wa_pte_va_service_connected_rating: 0.6 + wa_pte_va_total_disability_rating: true + output: + # RCW 84.36.381(3)(a)(ii)(B): a total disability rating "without regard to + # evaluation percent". + wa_pte_categorical_eligible: true + +- name: Case 14, a qualifying rating without receipt of VA compensation does not qualify. + period: 2024 + input: + state_code: WA + age: 45 + is_veteran: true + wa_pte_receives_va_disability_compensation: false + wa_pte_va_service_connected_rating: 1 + wa_pte_va_total_disability_rating: true + output: + # The veteran must be "entitled to and receiving compensation". + wa_pte_categorical_eligible: false + +- name: Case 15, a non-veteran's rating inputs do not establish the veteran pathway. + period: 2024 + input: + state_code: WA + age: 45 + is_veteran: false + wa_pte_receives_va_disability_compensation: true + wa_pte_va_service_connected_rating: 1 + wa_pte_va_total_disability_rating: true + output: + wa_pte_categorical_eligible: false + +- name: Case 16, in 2019 a compensated veteran rated 90 percent without a total rating does not qualify. + period: 2019 + input: + state_code: WA + age: 45 + is_veteran: true + wa_pte_receives_va_disability_compensation: true + wa_pte_va_service_connected_rating: 0.9 + wa_pte_va_total_disability_rating: false + output: + # Collection years 2016-2019 require a total disability rating. + wa_pte_categorical_eligible: false + +- name: Case 17, in 2019 a compensated veteran with a 100 percent combined rating qualifies. + period: 2019 + input: + state_code: WA + age: 45 + is_veteran: true + wa_pte_receives_va_disability_compensation: true + wa_pte_va_service_connected_rating: 1 + wa_pte_va_total_disability_rating: false + output: + # A 100% evaluation is a total rating (38 CFR 3.340(a)(2)). + wa_pte_categorical_eligible: true + +- name: Case 18, in 2019 a compensated veteran with a total rating below 100 percent qualifies. + period: 2019 + input: + state_code: WA + age: 45 + is_veteran: true + wa_pte_receives_va_disability_compensation: true + wa_pte_va_service_connected_rating: 0.7 + wa_pte_va_total_disability_rating: true + output: + wa_pte_categorical_eligible: true + +- name: Case 19, in 2015 generic disability without disability retirement does not qualify a non-veteran. + period: 2015 + input: + state_code: WA + age: 45 + is_disabled: true + is_veteran: false + wa_pte_retired_due_to_disability: false + output: + # 2008 c 6 s 706 (PDF page 85) already required retirement from regular + # gainful employment by reason of disability. + wa_pte_categorical_eligible: false + +- name: Case 20, in 2015 a disabled veteran keeps the generic disability treatment. + period: 2015 + input: + state_code: WA + age: 45 + is_disabled: true + is_veteran: true + wa_pte_retired_due_to_disability: false + output: + # Before collection year 2016 the veteran pathway was "one hundred percent + # service-connected disability as provided in 42 U.S.C. Sec. 423(d)(1)(A)", + # which admits more than one reading, so the model keeps generic disability + # for veterans in those years. + wa_pte_categorical_eligible: true + +- name: Case 21, mixed people are evaluated together. + period: 2024 + input: + people: + person1: + age: 61 + person2: + age: 45 + is_disabled: true + person3: + age: 45 + wa_pte_retired_due_to_disability: true + person4: + age: 45 + is_veteran: true + wa_pte_receives_va_disability_compensation: true + wa_pte_va_service_connected_rating: 0.8 + households: + household: + members: [person1, person2, person3, person4] + state_code: WA + output: + wa_pte_categorical_eligible: [true, false, true, true] diff --git a/policyengine_us/tests/policy/baseline/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_pte_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_pte_eligible.yaml index 6cece5021d7..084f6a4f5c4 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_pte_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_pte_eligible.yaml @@ -65,13 +65,14 @@ output: wa_pte_eligible: false -- name: Case 4, disabled owner-occupant is eligible. +- name: Case 4, owner-occupant retired by reason of disability is eligible. period: 2024 input: people: person1: age: 45 is_disabled: true + wa_pte_retired_due_to_disability: true real_estate_taxes: 6_000 tax_units: tax_unit: @@ -122,6 +123,7 @@ person2: age: 30 is_disabled: true + wa_pte_retired_due_to_disability: true tax_units: tax_unit: members: [person1, person2] diff --git a/policyengine_us/tests/policy/baseline/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_senior_disabled_property_tax_exemption.yaml b/policyengine_us/tests/policy/baseline/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_senior_disabled_property_tax_exemption.yaml index 63ea7dc5418..15ff18e8cc9 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_senior_disabled_property_tax_exemption.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_senior_disabled_property_tax_exemption.yaml @@ -204,13 +204,14 @@ # defined_for = StateCode.WA on wa_pte_eligible blocks the benefit wa_senior_disabled_property_tax_exemption: 0 -- name: Case 9, age 60 disabled is benefit-eligible via disability path. +- name: Case 9, age 60 retired by reason of disability is benefit-eligible via the disability path. period: 2024 input: people: person1: age: 60 is_disabled: true + wa_pte_retired_due_to_disability: true real_estate_taxes: 6_000 assessed_property_value: 700_000 tax_units: diff --git a/policyengine_us/tests/policy/baseline/household/income/spm_unit/spm_unit_local_tax.yaml b/policyengine_us/tests/policy/baseline/household/income/spm_unit/spm_unit_local_tax.yaml index 3333c3356e2..f2b189324ef 100644 --- a/policyengine_us/tests/policy/baseline/household/income/spm_unit/spm_unit_local_tax.yaml +++ b/policyengine_us/tests/policy/baseline/household/income/spm_unit/spm_unit_local_tax.yaml @@ -9,14 +9,16 @@ in_nyc: true employment_income: 100_000 output: - nyc_income_tax: 3_175.1702 - local_tax: 3_175.1702 - spm_unit_local_tax: 3_175.1702 + # The NYC school tax credit rate reduction amount on city taxable income + # of 92,000 is $21 + 0.228% x 80,000 = 203.40 (Tax Law § 606(ggg)(4-b)(C)). + nyc_income_tax: 3_174.6902 + local_tax: 3_174.6902 + spm_unit_local_tax: 3_174.6902 spm_unit_state_tax: 4_951.75 # Includes the 2024 New York Paid Family Leave contribution, # min(0.373% * 100,000, 333.25) = 333.25. - spm_unit_taxes: 29_982.37 - spm_unit_net_income: 62_901.633 + spm_unit_taxes: 29_981.889 + spm_unit_net_income: 62_902.109 - name: NYC refundable tax credits reduce SPM taxes and increase SPM net income period: 2024 diff --git a/policyengine_us/tests/policy/contrib/local/nyc/stc/adjust_income_limit_by_filing_status_and_eligibility_by_children.yaml b/policyengine_us/tests/policy/contrib/local/nyc/stc/adjust_income_limit_by_filing_status_and_eligibility_by_children.yaml index 06816174939..81a0637dd7a 100644 --- a/policyengine_us/tests/policy/contrib/local/nyc/stc/adjust_income_limit_by_filing_status_and_eligibility_by_children.yaml +++ b/policyengine_us/tests/policy/contrib/local/nyc/stc/adjust_income_limit_by_filing_status_and_eligibility_by_children.yaml @@ -5,10 +5,8 @@ # reform's filing-status income limit even when federal AGI is over it. # TY2025 rates (IT-201-I 2025, line 69 and 69a): fixed amount $63 single, $125 # joint; rate reduction 0.171% of city taxable income up to $12,000 (single) or -# $21,600 (joint), then 0.228% above it. Above the first band the form prints -# rounded base amounts ($21 single, $37 joint) while the model carries in the -# first band at the marginal rate (12,000 x 0.171% = $20.52; 21,600 x 0.171% = -# $36.936), and the expected values below follow the model; that gap is #8947. +# $21,600 (joint), and above it $21 (single) or $37 (joint) plus 0.228% of the +# excess (Tax Law § 606(ggg)(4-b)(A), (C)). - name: Case 1, single retiree whose IRA distribution puts AGI over the limit but school credit income under it. period: 2025 @@ -37,9 +35,9 @@ # 300,000 - 20,000 pension and annuity exclusion - 8,000 standard deduction. nyc_taxable_income: 272_000 nyc_school_tax_credit_fixed_amount: 63 - # 12,000 x 0.171% + (272,000 - 12,000) x 0.228% = 20.52 + 592.80. - nyc_school_tax_credit_rate_reduction_amount: 613.32 - nyc_school_tax_credit: 676.32 + # $21 + (272,000 - 12,000) x 0.228% = 21 + 592.80. + nyc_school_tax_credit_rate_reduction_amount: 613.80 + nyc_school_tax_credit: 676.80 - name: Case 2, IRA distribution of a filer under 59 1/2 brings school credit income under the limit. period: 2025 @@ -67,9 +65,9 @@ # No pension and annuity exclusion under age 59 1/2: 250,001 - 8,000. nyc_taxable_income: 242_001 nyc_school_tax_credit_fixed_amount: 63 - # 20.52 + (242,001 - 12,000) x 0.228% = 20.52 + 524.40. - nyc_school_tax_credit_rate_reduction_amount: 544.92 - nyc_school_tax_credit: 607.92 + # $21 + (242,001 - 12,000) x 0.228% = 21 + 524.40228. + nyc_school_tax_credit_rate_reduction_amount: 545.40 + nyc_school_tax_credit: 608.40 - name: Case 3, wages one dollar over the limit with no IRA distribution. period: 2025 @@ -151,9 +149,9 @@ # 300,000 - 20,000 pension and annuity exclusion - 16,050 standard deduction. nyc_taxable_income: 263_950 nyc_school_tax_credit_fixed_amount: 125 - # 21,600 x 0.171% + (263,950 - 21,600) x 0.228% = 36.936 + 552.558. - nyc_school_tax_credit_rate_reduction_amount: 589.49 - nyc_school_tax_credit: 714.49 + # $37 + (263,950 - 21,600) x 0.228% = 37 + 552.558. + nyc_school_tax_credit_rate_reduction_amount: 589.558 + nyc_school_tax_credit: 714.558 - name: Case 6, the same joint retirees fail a one-child minimum. period: 2025 @@ -217,9 +215,9 @@ nyc_school_tax_credit_eligible: true # 263,950 - 1,000 New York dependent exemption. nyc_taxable_income: 262_950 - # 36.936 + (262,950 - 21,600) x 0.228% = 36.936 + 550.278. - nyc_school_tax_credit_rate_reduction_amount: 587.21 - nyc_school_tax_credit: 712.21 + # $37 + (262,950 - 21,600) x 0.228% = 37 + 550.278. + nyc_school_tax_credit_rate_reduction_amount: 587.278 + nyc_school_tax_credit: 712.278 - name: Case 8, a filing-status limit equal to school credit income, not AGI, is met. period: 2025 @@ -244,7 +242,7 @@ output: nyc_school_credit_income: 100_000 nyc_school_tax_credit_eligible: true - nyc_school_tax_credit: 676.32 + nyc_school_tax_credit: 676.80 - name: Case 9, a filing-status limit one dollar under school credit income is not met. period: 2025 diff --git a/policyengine_us/tests/policy/contrib/local/nyc/stc/adjust_income_limit_by_filing_status_joint_override.yaml b/policyengine_us/tests/policy/contrib/local/nyc/stc/adjust_income_limit_by_filing_status_joint_override.yaml index 6da57e7e315..83e81457a24 100644 --- a/policyengine_us/tests/policy/contrib/local/nyc/stc/adjust_income_limit_by_filing_status_joint_override.yaml +++ b/policyengine_us/tests/policy/contrib/local/nyc/stc/adjust_income_limit_by_filing_status_joint_override.yaml @@ -6,10 +6,8 @@ # reform's filing-status income limit even when federal AGI is over it. # TY2025 rates (IT-201-I 2025, line 69 and 69a): fixed amount $63 single, $125 # joint; rate reduction 0.171% of city taxable income up to $12,000 (single) or -# $21,600 (joint), then 0.228% above it. Above the first band the form prints -# rounded base amounts ($21 single, $37 joint) while the model carries in the -# first band at the marginal rate (12,000 x 0.171% = $20.52; 21,600 x 0.171% = -# $36.936), and the expected values below follow the model; that gap is #8947. +# $21,600 (joint), and above it $21 (single) or $37 (joint) plus 0.228% of the +# excess (Tax Law § 606(ggg)(4-b)(A), (C)). - name: Case 10, the joint filing-status limit set to the joint retirees' school credit income is met. period: 2025 @@ -39,7 +37,7 @@ output: nyc_school_credit_income: 200_000 nyc_school_tax_credit_eligible: true - nyc_school_tax_credit: 714.49 + nyc_school_tax_credit: 714.558 - name: Case 11, the joint limit one dollar under school credit income is not met while the single limit stays at $250,000. period: 2025 diff --git a/policyengine_us/variables/gov/local/ny/nyc/tax/income/credits/school/nyc_school_tax_credit_rate_reduction_amount.py b/policyengine_us/variables/gov/local/ny/nyc/tax/income/credits/school/nyc_school_tax_credit_rate_reduction_amount.py index bf2a055fb20..4450f13b4ba 100644 --- a/policyengine_us/variables/gov/local/ny/nyc/tax/income/credits/school/nyc_school_tax_credit_rate_reduction_amount.py +++ b/policyengine_us/variables/gov/local/ny/nyc/tax/income/credits/school/nyc_school_tax_credit_rate_reduction_amount.py @@ -8,32 +8,28 @@ class nyc_school_tax_credit_rate_reduction_amount(Variable): unit = USD definition_period = YEAR defined_for = "nyc_school_tax_credit_rate_reduction_amount_eligible" + reference = ( + # NY Tax Law § 606(ggg)(4-b) + "https://www.nysenate.gov/legislation/laws/TAX/606", + # L.2017, ch. 59, Part C, § 2 (tables, PDF pages 8-9) and § 7 + # (applies to tax years beginning on and after January 1, 2017, + # PDF page 14) + "https://legislation.nysenate.gov/pdf/bills/2017/S2009C#page=8", + "https://www.tax.ny.gov/pdf/2025/inc/it201i_2025.pdf#page=21", + ) def formula(tax_unit, period, parameters): - # First get their NYC taxable income. - nyc_taxable_income = tax_unit("nyc_taxable_income", period) - - # Then get their filing status. + p = parameters( + period + ).gov.local.ny.nyc.tax.income.credits.school.rate_reduction.amount filing_status = tax_unit("filing_status", period) - - # Then get the School Tax Credit rate reduction amount part of the parameter tree. - p = parameters(period).gov.local.ny.nyc.tax.income.credits.school.rate_reduction - - # Calculate amount if eligible, which varies only with filing status. - filing_statuses = filing_status.possible_values - return select( - [ - filing_status == filing_statuses.SINGLE, - filing_status == filing_statuses.JOINT, - filing_status == filing_statuses.SEPARATE, - filing_status == filing_statuses.HEAD_OF_HOUSEHOLD, - filing_status == filing_statuses.SURVIVING_SPOUSE, - ], - [ - p.amount.single.calc(nyc_taxable_income), - p.amount.joint.calc(nyc_taxable_income), - p.amount.separate.calc(nyc_taxable_income), - p.amount.head_of_household.calc(nyc_taxable_income), - p.amount.surviving_spouse.calc(nyc_taxable_income), - ], + taxable_income = max_(tax_unit("nyc_taxable_income", period), 0) + threshold = p.threshold[filing_status] + # § 606(ggg)(4-b)(A)-(C): city taxable income not over the threshold + # gets the first band rate; above it, the amount is a fixed base for + # the filing status plus the excess rate on income over the threshold. + first_band = p.first_band_rate * taxable_income + above_threshold = p.base[filing_status] + p.excess_rate * ( + taxable_income - threshold ) + return where(taxable_income > threshold, above_threshold, first_band) diff --git a/policyengine_us/variables/gov/states/in/tax/property/supplemental_homestead_credit/in_homestead_property_tax_liability.py b/policyengine_us/variables/gov/states/in/tax/property/supplemental_homestead_credit/in_homestead_property_tax_liability.py new file mode 100644 index 00000000000..465301a7caa --- /dev/null +++ b/policyengine_us/variables/gov/states/in/tax/property/supplemental_homestead_credit/in_homestead_property_tax_liability.py @@ -0,0 +1,23 @@ +from policyengine_us.model_api import * + + +class in_homestead_property_tax_liability(Variable): + value_type = float + entity = TaxUnit + label = "Indiana property tax liability on the qualifying homestead" + documentation = ( + "Property tax first due and payable for the year on the homestead that " + "receives the IC 6-1.1-12-37 standard deduction, after the credits " + "applied before the supplemental homestead credit (including the " + "Over 65 and Blind/Disabled credits) and before the supplemental " + "homestead credit. Excludes tax on any other property." + ) + unit = USD + definition_period = YEAR + reference = ( + # IC 6-1.1-20.6-7.7(c)(1)(A), added by SEA 1 (2025), SECTION 74 + "https://iga.in.gov/pdf-documents/124/2025/senate/bills/SB0001/SB0001.05.ENRH.pdf#page=124", + # DLGF June 18, 2025 FAQ, questions 27, 29 and 33 (order of operations) + # PDF pages 7-9 + "https://www.in.gov/dlgf/files/2025-presentations/250618-FAQ-Webinar-Legislative-Update.pdf#page=7", + ) diff --git a/policyengine_us/variables/gov/states/in/tax/property/supplemental_homestead_credit/in_homestead_referendum_property_tax.py b/policyengine_us/variables/gov/states/in/tax/property/supplemental_homestead_credit/in_homestead_referendum_property_tax.py new file mode 100644 index 00000000000..08bd3a10039 --- /dev/null +++ b/policyengine_us/variables/gov/states/in/tax/property/supplemental_homestead_credit/in_homestead_referendum_property_tax.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * + + +class in_homestead_referendum_property_tax(Variable): + value_type = float + entity = TaxUnit + label = "Indiana referendum property tax on the qualifying homestead" + documentation = ( + "The part of in_homestead_property_tax_liability imposed after approval " + "by the voters in a referendum or local public question." + ) + unit = USD + definition_period = YEAR + reference = ( + # IC 6-1.1-20.6-7.7(d), added by SEA 1 (2025), SECTION 74 + "https://iga.in.gov/pdf-documents/124/2025/senate/bills/SB0001/SB0001.05.ENRH.pdf#page=124", + # DLGF June 18, 2025 FAQ, question 30 + "https://www.in.gov/dlgf/files/2025-presentations/250618-FAQ-Webinar-Legislative-Update.pdf#page=8", + ) diff --git a/policyengine_us/variables/gov/states/in/tax/property/supplemental_homestead_credit/in_supplemental_homestead_credit.py b/policyengine_us/variables/gov/states/in/tax/property/supplemental_homestead_credit/in_supplemental_homestead_credit.py index 50eef9305f2..f350bc3bb73 100644 --- a/policyengine_us/variables/gov/states/in/tax/property/supplemental_homestead_credit/in_supplemental_homestead_credit.py +++ b/policyengine_us/variables/gov/states/in/tax/property/supplemental_homestead_credit/in_supplemental_homestead_credit.py @@ -8,27 +8,31 @@ class in_supplemental_homestead_credit(Variable): unit = USD definition_period = YEAR reference = ( + # IC 6-1.1-20.6-7.7, added by SEA 1 (2025), SECTION 74 "https://iga.in.gov/pdf-documents/124/2025/senate/bills/SB0001/SB0001.05.ENRH.pdf#page=124", "https://www.in.gov/dlgf/files/2025-memos/250612-Cockerill-Memo-Legislation-Affecting-Deductions%2C-Exemptions%2C-and-Credits.pdf#page=9", + # DLGF June 18, 2025 FAQ, questions 26-30 and 33, PDF pages 7-9 + "https://www.in.gov/dlgf/files/2025-presentations/250618-FAQ-Webinar-Legislative-Update.pdf#page=7", ) defined_for = StateCode.IN def formula(tax_unit, period, parameters): - # Senate Enrolled Act 1 (2025) adds IC 6-1.1-20.6-7.7, a supplemental - # homestead credit equal to the lesser of 10% of the homestead property - # tax liability or $300, for taxes first due and payable in 2026 and - # after. No age or income limit; homeowners only, so renters (with no - # real estate taxes) receive zero. - # Modeling approximations, all bounded by the $300 cap: eligibility is - # proxied by real_estate_taxes > 0 rather than the IC 6-1.1-12-37 - # homestead standard deduction qualification; the base is total - # real_estate_taxes rather than the homestead-only liability (PE has no - # homestead-specific variable); and subsection (d)'s exclusion of - # referendum-approved taxes from the base is not modeled. + # IC 6-1.1-20.6-7.7 applies to property taxes first due and payable + # in 2026 and after. Subsection (b) limits the credit to a person who + # qualifies for the homestead standard deduction under IC 6-1.1-12-37 + # (or the surviving spouse of one who did), against the liability on + # that same homestead. Subsection (c) sets the credit at the lesser + # of 10% of that liability or $300, and subsection (d) leaves out + # taxes approved by referendum or local public question. Generic + # real_estate_taxes neither establish qualification nor measure the + # homestead liability, so all three are inputs. p = ( parameters(period) .gov.states["in"] .tax.property.supplemental_homestead_credit ) - property_tax = add(tax_unit, period, ["real_estate_taxes"]) - return min_(p.rate * property_tax, p.cap) + eligible = tax_unit("in_supplemental_homestead_credit_eligible", period) + liability = tax_unit("in_homestead_property_tax_liability", period) + referendum_tax = tax_unit("in_homestead_referendum_property_tax", period) + base = max_(liability - referendum_tax, 0) + return eligible * min_(p.rate * base, p.cap) diff --git a/policyengine_us/variables/gov/states/in/tax/property/supplemental_homestead_credit/in_supplemental_homestead_credit_eligible.py b/policyengine_us/variables/gov/states/in/tax/property/supplemental_homestead_credit/in_supplemental_homestead_credit_eligible.py new file mode 100644 index 00000000000..233a2aa600d --- /dev/null +++ b/policyengine_us/variables/gov/states/in/tax/property/supplemental_homestead_credit/in_supplemental_homestead_credit_eligible.py @@ -0,0 +1,20 @@ +from policyengine_us.model_api import * + + +class in_supplemental_homestead_credit_eligible(Variable): + value_type = bool + entity = TaxUnit + label = "Qualifies for the Indiana supplemental homestead credit" + documentation = ( + "Whether the filer qualifies for the homestead standard deduction under " + "IC 6-1.1-12-37 for their homestead, or is married at the time of death " + "to a deceased spouse who qualified for it, for the year the property " + "taxes are first due and payable." + ) + definition_period = YEAR + reference = ( + # IC 6-1.1-20.6-7.7(b), added by SEA 1 (2025), SECTION 74 + "https://iga.in.gov/pdf-documents/124/2025/senate/bills/SB0001/SB0001.05.ENRH.pdf#page=124", + # DLGF June 18, 2025 FAQ, questions 26 and 28 + "https://www.in.gov/dlgf/files/2025-presentations/250618-FAQ-Webinar-Legislative-Update.pdf#page=7", + ) diff --git a/policyengine_us/variables/gov/states/va/tax/income/deductions/plan_529/va_529_plan_carryforward.py b/policyengine_us/variables/gov/states/va/tax/income/deductions/plan_529/va_529_plan_carryforward.py new file mode 100644 index 00000000000..ee345487482 --- /dev/null +++ b/policyengine_us/variables/gov/states/va/tax/income/deductions/plan_529/va_529_plan_carryforward.py @@ -0,0 +1,20 @@ +from policyengine_us.model_api import * + + +class va_529_plan_carryforward(Variable): + value_type = float + entity = Person + label = "Virginia Commonwealth Savers contributions carried forward" + documentation = ( + "Contributions to Commonwealth Savers accounts this person owns, made " + "in prior taxable years and not yet deducted, including carryovers " + "succeeded to on a transfer of ownership." + ) + unit = USD + definition_period = YEAR + reference = ( + # Va. Code § 58.1-322.03(7)(a) + "https://law.lis.virginia.gov/vacode/title58.1/chapter3/section58.1-322.03/", + # 2024 Form 760 instructions, deduction code 104 + "https://www.tax.virginia.gov/sites/default/files/vatax-pdf/2024-760-instructions.pdf#page=28", + ) diff --git a/policyengine_us/variables/gov/states/va/tax/income/deductions/plan_529/va_529_plan_deduction_capped_amount.py b/policyengine_us/variables/gov/states/va/tax/income/deductions/plan_529/va_529_plan_deduction_capped_amount.py new file mode 100644 index 00000000000..f1c55455aae --- /dev/null +++ b/policyengine_us/variables/gov/states/va/tax/income/deductions/plan_529/va_529_plan_deduction_capped_amount.py @@ -0,0 +1,35 @@ +from policyengine_us.model_api import * + + +class va_529_plan_deduction_capped_amount(Variable): + value_type = float + entity = Person + label = "Virginia Commonwealth Savers deduction within the per-account cap" + documentation = ( + "Sum, across the Commonwealth Savers accounts this person owns, of the " + "lesser of the per-account cap or the account's contributions for the " + "year plus its undeducted carryforward. Supply it from account records; " + "otherwise it is computed as if contributions and carryforwards were " + "split evenly across count_529_contribution_beneficiaries accounts." + ) + unit = USD + definition_period = YEAR + reference = ( + # Va. Code § 58.1-322.03(7)(a) + "https://law.lis.virginia.gov/vacode/title58.1/chapter3/section58.1-322.03/", + # 2024 Form 760 instructions, deduction code 104 + "https://www.tax.virginia.gov/sites/default/files/vatax-pdf/2024-760-instructions.pdf#page=28", + ) + defined_for = StateCode.VA + + def formula(person, period, parameters): + p = parameters(period).gov.states.va.tax.income.subtractions.plan_529 + # § 58.1-322.03(7)(a) caps each contract or account separately, so the + # exact amount needs account-level records. Total contributions and + # an account count only bound it: with an even split, each of n + # accounts holds 1/n of the total, giving min(total, cap x n), the + # largest deduction any split of the same total allows. + contributions = person("investment_in_529_plan_indv", period) + carryforward = person("va_529_plan_carryforward", period) + accounts = person("count_529_contribution_beneficiaries", period) + return min_(contributions + carryforward, p.cap * accounts) diff --git a/policyengine_us/variables/gov/states/va/tax/income/deductions/plan_529/va_529_plan_deduction_person.py b/policyengine_us/variables/gov/states/va/tax/income/deductions/plan_529/va_529_plan_deduction_person.py index 7fce214f2e1..57111599459 100644 --- a/policyengine_us/variables/gov/states/va/tax/income/deductions/plan_529/va_529_plan_deduction_person.py +++ b/policyengine_us/variables/gov/states/va/tax/income/deductions/plan_529/va_529_plan_deduction_person.py @@ -23,10 +23,13 @@ def formula(person, period, parameters): # accounts. Dependents file their own returns, which this tax unit # does not model, so dependent-owned accounts are excluded. head_or_spouse = person("is_tax_unit_head_or_spouse", period) + # § 58.1-322.03(7)(a): up to $4,000 per contract or account each year, + # with any excess carried forward until fully deducted. + capped = person("va_529_plan_deduction_capped_amount", period) + # § 58.1-322.03(7)(b): an owner who has attained age 70 deducts the + # full amount contributed, less any amounts previously deducted, so + # this year's contributions and the undeducted carryforward. contributions = person("investment_in_529_plan_indv", period) - accounts = person("count_529_contribution_beneficiaries", period) - capped = min_(contributions, p.cap * accounts) - # An owner who has attained age 70 may deduct the full amount - # contributed during the year. + carryforward = person("va_529_plan_carryforward", period) age_exempt = person("age", period) >= p.age_threshold - return head_or_spouse * where(age_exempt, contributions, capped) + return head_or_spouse * where(age_exempt, contributions + carryforward, capped) diff --git a/policyengine_us/variables/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_pte_categorical_eligible.py b/policyengine_us/variables/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_pte_categorical_eligible.py index 0f83196fdaf..3e98f904b05 100644 --- a/policyengine_us/variables/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_pte_categorical_eligible.py +++ b/policyengine_us/variables/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_pte_categorical_eligible.py @@ -9,20 +9,39 @@ class wa_pte_categorical_eligible(Variable): defined_for = StateCode.WA reference = ( "https://app.leg.wa.gov/RCW/default.aspx?cite=84.36.381", + "https://app.leg.wa.gov/WAC/default.aspx?cite=458-16A-130", "https://dor.wa.gov/sites/default/files/2022-02/PTExemption_Senior.pdf#page=1", ) def formula(person, period, parameters): - age = person("age", period) - # The statute requires being "retired from regular gainful employment - # by reason of disability" (RCW 84.36.381(3)(a)(ii)). We use is_disabled - # as a proxy — it captures unable-to-work disability across SSDI, SSI, - # VA, and physician-certified pathways, but doesn't directly verify the - # "retired from gainful employment" condition. - # Disability eligibility is proxied via the federal `is_disabled` variable - # (SSDI/SSI/VA/physician-certified). Note: RCW 84.36.381(3)(a)(iii) also - # allows VA-rated 40%+ service-connected disability as a separate pathway; - # this is not modeled explicitly (subsumed under `is_disabled` in practice). - is_disabled = person("is_disabled", period) p = parameters(period).gov.states.wa.dor.property_tax_exemption.senior_disabled - return (age >= p.age_threshold) | is_disabled + # RCW 84.36.381(3)(a)(i): at or above the age threshold, or retired + # from regular gainful employment by reason of disability at the time + # of filing. Generic disability establishes neither. + senior = person("age", period) >= p.age_threshold + retired_due_to_disability = person("wa_pte_retired_due_to_disability", period) + # RCW 84.36.381(3)(a)(ii): a veteran entitled to and receiving VA + # compensation at a combined service-connected evaluation rating of at + # least the threshold, or at a total disability rating for a + # service-connected disability. A 100 percent evaluation is a total + # rating (38 CFR 3.340(a)(2)). + veteran = person("is_veteran", period) + compensated = person("wa_pte_receives_va_disability_compensation", period) + rating = person("wa_pte_va_service_connected_rating", period) + total_rating = person("wa_pte_va_total_disability_rating", period) | ( + rating >= 1 + ) + qualifying_rating = total_rating | ( + rating >= p.veteran.combined_rating_threshold + ) + rated_veteran = compensated & qualifying_rating + # Before collection year 2016 the veteran pathway was "one hundred + # percent service-connected disability as provided in 42 U.S.C. Sec. + # 423(d)(1)(A)", which can be read as a 100 percent VA rating or as a + # wholly service-connected disability meeting the Social Security + # definition; is_disabled stands in for it in those years. + earlier_veteran = person("is_disabled", period) + veteran_pathway = veteran & where( + p.veteran.rating_requirement_in_effect, rated_veteran, earlier_veteran + ) + return senior | retired_due_to_disability | veteran_pathway diff --git a/policyengine_us/variables/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_pte_receives_va_disability_compensation.py b/policyengine_us/variables/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_pte_receives_va_disability_compensation.py new file mode 100644 index 00000000000..3fd52804927 --- /dev/null +++ b/policyengine_us/variables/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_pte_receives_va_disability_compensation.py @@ -0,0 +1,14 @@ +from policyengine_us.model_api import * + + +class wa_pte_receives_va_disability_compensation(Variable): + value_type = bool + entity = Person + label = "Entitled to and receiving VA compensation for a service-connected disability for the Washington senior and disabled persons property tax exemption" + definition_period = YEAR + reference = ( + # RCW 84.36.381(3)(a)(ii) + "https://app.leg.wa.gov/RCW/default.aspx?cite=84.36.381", + # WAC 458-16A-130 + "https://app.leg.wa.gov/WAC/default.aspx?cite=458-16A-130", + ) diff --git a/policyengine_us/variables/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_pte_retired_due_to_disability.py b/policyengine_us/variables/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_pte_retired_due_to_disability.py new file mode 100644 index 00000000000..6b54ca5a669 --- /dev/null +++ b/policyengine_us/variables/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_pte_retired_due_to_disability.py @@ -0,0 +1,23 @@ +from policyengine_us.model_api import * + + +class wa_pte_retired_due_to_disability(Variable): + value_type = bool + entity = Person + label = "Retired from regular gainful employment by reason of disability for the Washington senior and disabled persons property tax exemption" + documentation = ( + "At the time of filing, retired from regular gainful employment by " + "reason of a disability as defined in RCW 84.36.383 (42 U.S.C. " + "423(d)(1)(A): unable to engage in any substantial gainful activity " + "because of a medically determinable impairment expected to result in " + "death or to last at least 12 months)." + ) + definition_period = YEAR + reference = ( + # RCW 84.36.381(3)(a)(i) + "https://app.leg.wa.gov/RCW/default.aspx?cite=84.36.381", + # RCW 84.36.383(6) + "https://app.leg.wa.gov/RCW/default.aspx?cite=84.36.383", + # WAC 458-16A-130 + "https://app.leg.wa.gov/WAC/default.aspx?cite=458-16A-130", + ) diff --git a/policyengine_us/variables/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_pte_va_service_connected_rating.py b/policyengine_us/variables/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_pte_va_service_connected_rating.py new file mode 100644 index 00000000000..c2accc52ea1 --- /dev/null +++ b/policyengine_us/variables/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_pte_va_service_connected_rating.py @@ -0,0 +1,14 @@ +from policyengine_us.model_api import * + + +class wa_pte_va_service_connected_rating(Variable): + value_type = float + entity = Person + label = "Combined VA service-connected evaluation rating for the Washington senior and disabled persons property tax exemption" + documentation = "The combined service-connected evaluation rating from the U.S. Department of Veterans Affairs, as a fraction (0.8 for 80 percent)." + unit = "/1" + definition_period = YEAR + reference = ( + # RCW 84.36.381(3)(a)(ii)(A) + "https://app.leg.wa.gov/RCW/default.aspx?cite=84.36.381", + ) diff --git a/policyengine_us/variables/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_pte_va_total_disability_rating.py b/policyengine_us/variables/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_pte_va_total_disability_rating.py new file mode 100644 index 00000000000..c8274eefa5c --- /dev/null +++ b/policyengine_us/variables/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_pte_va_total_disability_rating.py @@ -0,0 +1,15 @@ +from policyengine_us.model_api import * + + +class wa_pte_va_total_disability_rating(Variable): + value_type = bool + entity = Person + label = "Has a VA total disability rating for a service-connected disability for the Washington senior and disabled persons property tax exemption" + documentation = "A total disability rating from the U.S. Department of Veterans Affairs for a service-connected disability, without regard to evaluation percent (for example, individual unemployability)." + definition_period = YEAR + reference = ( + # RCW 84.36.381(3)(a)(ii)(B) + "https://app.leg.wa.gov/RCW/default.aspx?cite=84.36.381", + # 38 CFR 3.340(a)(2) + "https://www.law.cornell.edu/cfr/text/38/3.340", + )