diff --git a/changelog.d/hi-credit-start-dates.fixed.md b/changelog.d/hi-credit-start-dates.fixed.md new file mode 100644 index 00000000000..9e306adbc1b --- /dev/null +++ b/changelog.d/hi-credit-start-dates.fixed.md @@ -0,0 +1 @@ +Stop paying the Hawaii earned income tax credit before 2018 and the Act 115 refund outside 2021, and use each year's Hawaii military reserve pay exclusion cap for 2015-2025. diff --git a/policyengine_us/parameters/gov/states/hi/tax/income/credits/act_115_rebate/joint.yaml b/policyengine_us/parameters/gov/states/hi/tax/income/credits/act_115_rebate/joint.yaml index 7b320be909d..22ae1b468b4 100644 --- a/policyengine_us/parameters/gov/states/hi/tax/income/credits/act_115_rebate/joint.yaml +++ b/policyengine_us/parameters/gov/states/hi/tax/income/credits/act_115_rebate/joint.yaml @@ -15,8 +15,14 @@ brackets: - threshold: 2021-01-01: -.inf amount: + # Model years start in 2015. Act 115 paid a one-time refund to filers + # of a 2021 Form N-11. + 2000-01-01: 0 2021-01-01: 300 + 2022-01-01: 0 - threshold: 2021-01-01: 200_000 amount: + 2000-01-01: 0 2021-01-01: 100 + 2022-01-01: 0 diff --git a/policyengine_us/parameters/gov/states/hi/tax/income/credits/act_115_rebate/single.yaml b/policyengine_us/parameters/gov/states/hi/tax/income/credits/act_115_rebate/single.yaml index f002f2aff5b..089e4a1d9bc 100644 --- a/policyengine_us/parameters/gov/states/hi/tax/income/credits/act_115_rebate/single.yaml +++ b/policyengine_us/parameters/gov/states/hi/tax/income/credits/act_115_rebate/single.yaml @@ -15,8 +15,14 @@ brackets: - threshold: 2021-01-01: -.inf amount: + # Model years start in 2015. Act 115 paid a one-time refund to filers + # of a 2021 Form N-11. + 2000-01-01: 0 2021-01-01: 300 + 2022-01-01: 0 - threshold: 2021-01-01: 100_000 amount: + 2000-01-01: 0 2021-01-01: 100 + 2022-01-01: 0 diff --git a/policyengine_us/parameters/gov/states/hi/tax/income/credits/eitc/match.yaml b/policyengine_us/parameters/gov/states/hi/tax/income/credits/eitc/match.yaml index fb8d3cad97b..321364fe888 100644 --- a/policyengine_us/parameters/gov/states/hi/tax/income/credits/eitc/match.yaml +++ b/policyengine_us/parameters/gov/states/hi/tax/income/credits/eitc/match.yaml @@ -1,6 +1,9 @@ description: Hawaii matches this percent of the federal EITC. values: - 2017-01-01: 0.2 + # Model years start in 2015. The credit applies to taxable years beginning + # after December 31, 2017. + 2000-01-01: 0 + 2018-01-01: 0.2 2023-01-01: 0.4 2028-01-01: 0.2 metadata: @@ -9,6 +12,10 @@ metadata: reference: - title: Hawaii Income Tax Law, Chapter 235, Section 235-55.75 href: https://files.hawaii.gov/tax/legal/hrs/hrs_235.pdf#page=43 + - title: 2018 Hawaii N-11 Instructions, What's new (Act 107, SLH 2017) + href: https://files.hawaii.gov/tax/forms/2018/n11ins.pdf#page=2 + - title: Hawaii Tax Form N-356 2018 + href: https://web.archive.org/web/20190819110547/http://files.hawaii.gov/tax/forms/2018/n356_i.pdf#page=2 - title: Hawaii Tax Form N-356 2022 href: https://files.hawaii.gov/tax/forms/2022/n356_i.pdf - title: Hawaii Tax Form N-356 2023 diff --git a/policyengine_us/parameters/gov/states/hi/tax/income/credits/non_refundable.yaml b/policyengine_us/parameters/gov/states/hi/tax/income/credits/non_refundable.yaml index 0013368000a..e9c0f7f9ffb 100644 --- a/policyengine_us/parameters/gov/states/hi/tax/income/credits/non_refundable.yaml +++ b/policyengine_us/parameters/gov/states/hi/tax/income/credits/non_refundable.yaml @@ -1,6 +1,9 @@ description: Hawaii provides the following non-refundable tax credits. values: - 2021-01-01: + # Model years start in 2015. Hawaii had no earned income tax credit + # before 2018. + 2000-01-01: [] + 2018-01-01: - hi_eitc 2023-01-01: [] @@ -11,5 +14,9 @@ metadata: reference: - title: Hawaii Revised Statutes Title 14. Taxation 235. Income Tax Law, 235-55.75 Earned income tax credit. # repealed in 2023 href: https://law.justia.com/codes/hawaii/2022/title-14/chapter-235/section-235-55-75/ + - title: 2018 Hawaii N-11 Instructions, What's new (Act 107, SLH 2017) + href: https://files.hawaii.gov/tax/forms/2018/n11ins.pdf#page=2 + - title: 2018 Hawaii Form N-356 Instructions + href: https://web.archive.org/web/20190819110547/http://files.hawaii.gov/tax/forms/2018/n356_i.pdf#page=2 - title: 2025 Hawaii N-11 Instructions href: https://files.hawaii.gov/tax/forms/current/n11ins.pdf diff --git a/policyengine_us/parameters/gov/states/hi/tax/income/credits/refundable.yaml b/policyengine_us/parameters/gov/states/hi/tax/income/credits/refundable.yaml index 264449d0df2..f8b1648881d 100644 --- a/policyengine_us/parameters/gov/states/hi/tax/income/credits/refundable.yaml +++ b/policyengine_us/parameters/gov/states/hi/tax/income/credits/refundable.yaml @@ -1,5 +1,12 @@ description: Hawaii provides the following refundable tax credits. values: + # Model years start in 2015. The Act 115 refund went only to filers of a + # 2021 Form N-11. + 2000-01-01: + - hi_food_excise_credit + - hi_cdcc + - hi_tax_credit_for_low_income_household_renters + 2021-01-01: - hi_food_excise_credit - hi_cdcc @@ -22,6 +29,10 @@ metadata: period: year label: Hawaii refundable tax credits reference: + - title: 2018 Hawaii N-11 Tax Form + href: https://files.hawaii.gov/tax/forms/2018/n11_i.pdf#page=3 + - title: Hawaii Department of Taxation Announcement No. 2022-03, Act 115 Income Tax Refunds + href: https://files.hawaii.gov/tax/news/announce/ann22-03.pdf#page=2 - title: 2022 Hawaii N-11 Tax Form href: https://files.hawaii.gov/tax/forms/2022/n11_i.pdf#page=3 - title: 2021 Hawaii N-11 Tax Form diff --git a/policyengine_us/parameters/gov/states/hi/tax/income/subtractions/military_pay/cap.yaml b/policyengine_us/parameters/gov/states/hi/tax/income/subtractions/military_pay/cap.yaml index 019814a220c..bc3533ef2db 100644 --- a/policyengine_us/parameters/gov/states/hi/tax/income/subtractions/military_pay/cap.yaml +++ b/policyengine_us/parameters/gov/states/hi/tax/income/subtractions/military_pay/cap.yaml @@ -1,8 +1,16 @@ description: Hawaii caps the military reserve or Hawaii national guard duty pay exclusion at this amount. -values: - 2021-01-01: 7_345 +values: + 2015-01-01: 6_198 + 2016-01-01: 6_279 + 2017-01-01: 6_410 + 2018-01-01: 6_564 + 2019-01-01: 6_735 + 2020-01-01: 6_943 + 2021-01-01: 7_152 + 2022-01-01: 7_345 2023-01-01: 7_683 2024-01-01: 8_082 + 2025-01-01: 8_636 metadata: uprating: gov.irs.uprating @@ -10,21 +18,29 @@ metadata: period: year unit: currency-USD reference: - - title: Hawaii Resident Income Tax Instructions N-11 Rev.2022 - href: https://files.hawaii.gov/tax/forms/2022/n11ins.pdf#page=13 - - title: Hawaii 2022 Individual Income Tax Return N-11 From Rev.2022 - href: https://files.hawaii.gov/tax/forms/2022/n11_i.pdf#page=2 - - title: Hawaii Resident Income Tax Instructions N-11 Rev.2021 + # The value of the subtraction is derived from compensation for + # performance of duty, equivalent to pay received for forty-eight drills + - title: Hawaii Income Tax Law, Chapter 235, Section 235-7, (a) (7) + href: https://files.hawaii.gov/tax/legal/hrs/hrs_235.pdf#page=22 + - title: Hawaii Resident Income Tax Instructions N-11 Rev.2015, Line 15 + href: https://web.archive.org/web/20160207173809/http://files.hawaii.gov/tax/forms/2015/n11ins.pdf#page=14 + - title: Hawaii Resident Income Tax Instructions N-11 Rev.2016, Line 15 + href: https://web.archive.org/web/20170214234012/http://files.hawaii.gov/tax/forms/2016/n11ins.pdf#page=15 + - title: Hawaii Resident Income Tax Instructions N-11 Rev.2017, Line 15 + href: https://web.archive.org/web/20180417023253/http://files.hawaii.gov/tax/forms/2017/n11ins.pdf#page=15 + - title: Hawaii Resident Income Tax Instructions N-11 Rev.2018, Line 15 + href: https://files.hawaii.gov/tax/forms/2018/n11ins.pdf#page=15 + - title: Hawaii Resident Income Tax Instructions N-11 Rev.2019, Line 15 + href: https://files.hawaii.gov/tax/forms/2019/n11ins.pdf#page=15 + - title: Hawaii Resident Income Tax Instructions N-11 Rev.2020, Line 15 + href: https://files.hawaii.gov/tax/forms/2020/n11ins.pdf#page=15 + - title: Hawaii Resident Income Tax Instructions N-11 Rev.2021, Line 15 href: https://files.hawaii.gov/tax/forms/2021/n11ins.pdf#page=13 - - title: Hawaii 2021 Individual Income Tax Return N-11 From Rev.2021 - href: https://files.hawaii.gov/tax/forms/2021/n11_i.pdf#page=2 - # The value of the subtraction is derived from compensation for - # performance of duty, equivalent to pay received for forty-eight drills - - title: Hawaii Income Tax Law, Chapter 235, Section 235-7, (a) (7) - href: https://files.hawaii.gov/tax/legal/hrs/hrs_235.pdf#page=22 - - title: Hawaii Resident Income Tax Instructions N-11 Rev.2023 + - title: Hawaii Resident Income Tax Instructions N-11 Rev.2022, Line 15 + href: https://files.hawaii.gov/tax/forms/2022/n11ins.pdf#page=13 + - title: Hawaii Resident Income Tax Instructions N-11 Rev.2023, Line 15 href: https://files.hawaii.gov/tax/forms/2023/n11ins.pdf#page=13 - - title: Hawaii Resident Income Tax Instructions N-11 Rev.2024 + - title: Hawaii Resident Income Tax Instructions N-11 Rev.2024, Line 15 href: https://files.hawaii.gov/tax/forms/2024/n11ins.pdf#page=13 - - title: 2025 Hawaii N-11 Instructions Military Pay Exclusion - href: https://files.hawaii.gov/tax/forms/current/n11ins.pdf#page=13 + - title: Hawaii Resident Income Tax Instructions N-11 Rev.2025, Line 15 + href: https://files.hawaii.gov/tax/forms/2025/n11ins.pdf#page=13 diff --git a/policyengine_us/tests/policy/baseline/gov/states/hi/tax/income/credits/hi_act_115_rebate.yaml b/policyengine_us/tests/policy/baseline/gov/states/hi/tax/income/credits/hi_act_115_rebate.yaml index 13ebfd8d94a..6ca040f88c0 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/hi/tax/income/credits/hi_act_115_rebate.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/hi/tax/income/credits/hi_act_115_rebate.yaml @@ -162,3 +162,52 @@ state_code: HI output: hi_act_115_rebate: 0 + +# Act 115 refunds went only to filers of a 2021 Form N-11 (DOTAX +# Announcement 2022-03, p.2). +- name: No refund for 2017 + period: 2017 + input: + adjusted_gross_income: 50_000 + filing_status: SINGLE + state_code: HI + output: + hi_act_115_rebate: 0 + +- name: No refund for 2020 + period: 2020 + input: + adjusted_gross_income: 50_000 + filing_status: SINGLE + state_code: HI + output: + hi_act_115_rebate: 0 + +- name: No refund for 2022 + period: 2022 + input: + adjusted_gross_income: 50_000 + filing_status: SINGLE + state_code: HI + output: + hi_act_115_rebate: 0 + +- name: No refund for joint filers for 2020 + period: 2020 + input: + people: + head: + age: 40 + spouse: + age: 40 + tax_units: + tax_unit: + members: [head, spouse] + adjusted_gross_income: 60_000 + filing_status: JOINT + households: + household: + members: [head, spouse] + state_code: HI + output: + hi_act_115_rebate: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/hi/tax/income/credits/hi_credit_start_dates.yaml b/policyengine_us/tests/policy/baseline/gov/states/hi/tax/income/credits/hi_credit_start_dates.yaml new file mode 100644 index 00000000000..f1f3d725874 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/hi/tax/income/credits/hi_credit_start_dates.yaml @@ -0,0 +1,146 @@ +# A single filer, age 30, with $8,000 of wages in each year around the +# credits' start dates. The federal EITC is on its plateau in each year +# tested (single, no qualifying child), and the Hawaii food/excise credit is +# $100 for federal AGI of $5,000 to $10,000 (Form N-311, 2017-2022). +# Hawaii's EITC applies to taxable years beginning after December 31, 2017 +# (Act 107, SLH 2017; 2018 Form N-356 instructions, p.2). Act 115 (SLH 2022) +# refunds went only to filers of a 2021 Form N-11 (DOTAX Announcement +# 2022-03, p.2). +- name: Case 1, no Hawaii EITC or Act 115 refund in 2017. + period: 2017 + input: + people: + person1: + age: 30 + employment_income: 8_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: HI + output: + eitc: 510 + hi_eitc_potential: 0 + hi_non_refundable_credits: 0 + hi_act_115_rebate: 0 + hi_food_excise_credit: 100 + hi_refundable_credits: 100 + # Taxable income: 8,000 - 2,200 standard deduction - 1,144 exemption + # = 4,656. Tax: 1.4% * 2,400 + 3.2% * 2,256 = 105.792. + # 105.792 - 0 nonrefundable - 100 refundable = 5.792. + hi_income_tax: 5.792 + absolute_error_margin: 0.01 + +- name: Case 2, Hawaii EITC starts in 2018 and no Act 115 refund. + period: 2018 + input: + people: + person1: + age: 30 + employment_income: 8_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: HI + output: + eitc: 519 + # 20% * 519 + hi_eitc_potential: 103.8 + hi_act_115_rebate: 0 + hi_refundable_credits: 100 + absolute_error_margin: 0.01 + +- name: Case 3, Hawaii EITC and no Act 115 refund in 2020. + period: 2020 + input: + people: + person1: + age: 30 + employment_income: 8_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: HI + output: + eitc: 538 + # 20% * 538 + hi_eitc_potential: 107.6 + hi_act_115_rebate: 0 + hi_refundable_credits: 100 + absolute_error_margin: 0.01 + +- name: Case 4, Act 115 refund for 2021. + period: 2021 + input: + people: + person1: + age: 30 + employment_income: 8_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: HI + output: + # 15.3% * 8,000 under the 2021 phase-in. + eitc: 1_224 + # 20% * 1,224 + hi_eitc_potential: 244.8 + # One exemption * $300 for federal AGI under $100,000. + hi_act_115_rebate: 300 + # 100 food/excise + 300 Act 115 + hi_refundable_credits: 400 + absolute_error_margin: 0.01 + +- name: Case 5, no Act 115 refund for 2022. + period: 2022 + input: + people: + person1: + age: 30 + employment_income: 8_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: HI + output: + eitc: 560 + # 20% * 560 + hi_eitc_potential: 112 + hi_act_115_rebate: 0 + hi_refundable_credits: 100 + absolute_error_margin: 0.01 + +- name: Case 6, no Hawaii EITC or Act 115 refund in 2016. + period: 2016 + input: + people: + person1: + age: 30 + employment_income: 8_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: HI + output: + hi_eitc_potential: 0 + hi_non_refundable_credits: 0 + hi_act_115_rebate: 0 + hi_refundable_credits: 100 + absolute_error_margin: 0.01 diff --git a/policyengine_us/tests/policy/baseline/gov/states/hi/tax/income/credits/hi_eitc.yaml b/policyengine_us/tests/policy/baseline/gov/states/hi/tax/income/credits/hi_eitc.yaml index ad2cfec1980..918a84ddd9a 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/hi/tax/income/credits/hi_eitc.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/hi/tax/income/credits/hi_eitc.yaml @@ -43,3 +43,62 @@ state_code: HI output: hi_eitc: 400 + +# Act 107 (SLH 2017) created the credit for taxable years beginning after +# December 31, 2017 (2018 Form N-356 instructions, p.2). +- name: No Hawaii EITC in 2016 + period: 2016 + input: + eitc: 506 + state_code: HI + hi_income_tax_before_non_refundable_credits: 1_000_000 + output: + hi_eitc_potential: 0 + hi_eitc: 0 + hi_non_refundable_credits: 0 + +- name: No Hawaii EITC in 2017 + period: 2017 + input: + eitc: 510 + state_code: HI + hi_income_tax_before_non_refundable_credits: 1_000_000 + output: + hi_eitc_potential: 0 + hi_eitc: 0 + hi_non_refundable_credits: 0 + +- name: 20% nonrefundable match in 2018, the first year + period: 2018 + input: + eitc: 519 + state_code: HI + hi_income_tax_before_non_refundable_credits: 1_000_000 + output: + # 20% * 519 + hi_eitc_potential: 103.8 + hi_eitc: 103.8 + hi_non_refundable_credits: 103.8 + +- name: 20% nonrefundable match in 2020 + period: 2020 + input: + eitc: 538 + state_code: HI + hi_income_tax_before_non_refundable_credits: 1_000_000 + output: + # 20% * 538 + hi_eitc_potential: 107.6 + hi_eitc: 107.6 + hi_non_refundable_credits: 107.6 + +- name: 20% nonrefundable match in 2021 + period: 2021 + input: + eitc: 1_000 + state_code: HI + hi_income_tax_before_non_refundable_credits: 1_000_000 + output: + hi_eitc_potential: 200 + hi_eitc: 200 + hi_non_refundable_credits: 200 diff --git a/policyengine_us/tests/policy/baseline/gov/states/hi/tax/income/subtractions/hi_military_pay_exclusion.yaml b/policyengine_us/tests/policy/baseline/gov/states/hi/tax/income/subtractions/hi_military_pay_exclusion.yaml index 8da03d6eab8..413c9a24b50 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/hi/tax/income/subtractions/hi_military_pay_exclusion.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/hi/tax/income/subtractions/hi_military_pay_exclusion.yaml @@ -9,9 +9,55 @@ - name: Military reserve or national guard duty pay exceeds the max amount period: 2021 + input: + military_service_income: 8_000 + is_tax_unit_head_or_spouse: true + state_code: HI + output: + # 2021 N-11 instructions, line 15: $7,152. + hi_military_pay_exclusion: 7_152 + +- name: The 2015 cap is $6,198 + period: 2015 + input: + military_service_income: 8_000 + is_tax_unit_head_or_spouse: true + state_code: HI + output: + hi_military_pay_exclusion: 6_198 + +- name: The 2018 cap is $6,564 + period: 2018 + input: + military_service_income: 8_000 + is_tax_unit_head_or_spouse: true + state_code: HI + output: + hi_military_pay_exclusion: 6_564 + +- name: The 2020 cap is $6,943 + period: 2020 + input: + military_service_income: 8_000 + is_tax_unit_head_or_spouse: true + state_code: HI + output: + hi_military_pay_exclusion: 6_943 + +- name: The 2022 cap is $7,345 + period: 2022 input: military_service_income: 8_000 is_tax_unit_head_or_spouse: true state_code: HI output: hi_military_pay_exclusion: 7_345 + +- name: The 2025 cap is $8,636 + period: 2025 + input: + military_service_income: 9_000 + is_tax_unit_head_or_spouse: true + state_code: HI + output: + hi_military_pay_exclusion: 8_636 diff --git a/policyengine_us/tests/unit/test_hi_credit_start_dates_properties.py b/policyengine_us/tests/unit/test_hi_credit_start_dates_properties.py new file mode 100644 index 00000000000..a87bb838c00 --- /dev/null +++ b/policyengine_us/tests/unit/test_hi_credit_start_dates_properties.py @@ -0,0 +1,236 @@ +"""Properties of the years in which Hawaii's EITC and Act 115 refund apply. + +``backdate_parameters`` copies each parameter's first value back to 2015, so +these credits paid in years before they existed until their parameters were +dated. The law: + +- Hawaii's earned income tax credit applies to taxable years beginning after + December 31, 2017 (Act 107, SLH 2017; 2018 Form N-356 instructions, p.2): + 20% of the federal credit, nonrefundable, for 2018-2022, then 40% and + refundable from 2023 (Act 163, SLH 2023). +- Act 115 (SLH 2022) refunds went only to filers of a 2021 Form N-11: $300 + per exemption under the federal AGI threshold ($100,000; $200,000 for joint + filers and surviving spouses) and $100 at or above it (DOTAX Announcement + 2022-03, p.2). +- The military reserve or Hawaii National Guard duty pay exclusion is capped + at each year's N-11 instruction amount (line 15). + +For every grid point, and for Hypothesis-generated batches, in 2015-2026: + +- ``hi_act_115_rebate`` is zero outside 2021 and equals the announcement's + table times the number of people on the return in 2021; +- ``hi_eitc_potential`` is the year's match rate times the federal EITC, so + it is zero before 2018; +- ``hi_non_refundable_credits`` is zero before 2018 and from 2023, and never + exceeds the Hawaii EITC or the tax it offsets in 2018-2022; +- refundable credits beyond the food/excise, dependent care and renters' + credits are the Act 115 refund (2021 only) and the Hawaii EITC (from 2023); +- before 2018, Hawaii income tax is the tax before credits minus the + refundable credits, since no nonrefundable credit applies. +""" + +import itertools + +import numpy as np +import pytest +from hypothesis import given, settings, strategies as st + +from policyengine_us import Simulation + +YEARS = list(range(2015, 2027)) + +# Hawaii EITC match rate by year (HRS 235-55.75, Act 107 SLH 2017, Act 163 +# SLH 2023). +EITC_MATCH = { + year: 0.0 if year < 2018 else 0.2 if year < 2023 else 0.4 for year in YEARS +} +ACT_115_YEAR = 2021 +ACT_115_HIGH, ACT_115_LOW = 300, 100 +JOINT_STATUSES = {"JOINT", "SURVIVING_SPOUSE"} +ACT_115_THRESHOLD = {"joint": 200_000, "other": 100_000} + +# Military reserve or Hawaii National Guard duty pay exclusion cap, from each +# year's N-11 instructions, line 15. +MILITARY_PAY_CAP = { + 2015: 6_198, + 2016: 6_279, + 2017: 6_410, + 2018: 6_564, + 2019: 6_735, + 2020: 6_943, + 2021: 7_152, + 2022: 7_345, + 2023: 7_683, + 2024: 8_082, + 2025: 8_636, +} + +# (adults, children): single, head of household and joint returns. +HOUSEHOLDS = [(1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)] +WAGES = [0, 4_000, 8_000, 15_000, 40_000, 99_999, 100_000, 150_000, 200_000] +AGES = [30, 70] +GRID = list(itertools.product(HOUSEHOLDS, WAGES, AGES)) + + +def every_year(value): + return {year: value for year in YEARS} + + +def hawaii_simulation(points): + """One Hawaii tax unit per (household, wages, age) point.""" + people, tax_units, households = {}, {}, {} + for i, ((adults, children), wages, age) in enumerate(points): + members = [] + for a in range(adults): + name = f"u{i}_adult{a}" + people[name] = { + "age": every_year(age), + "employment_income": every_year(wages if a == 0 else 0), + } + members.append(name) + for c in range(children): + name = f"u{i}_child{c}" + people[name] = {"age": every_year(8 + c)} + members.append(name) + tax_units[f"u{i}"] = {"members": members} + households[f"u{i}"] = {"members": members, "state_code": every_year("HI")} + return Simulation( + situation={"people": people, "tax_units": tax_units, "households": households} + ) + + +def act_115_reference(sim, year): + """DOTAX Announcement 2022-03 table times exemptions, for 2021 only.""" + if year != ACT_115_YEAR: + return np.zeros(len(sim.calculate("tax_unit_id", year))) + statuses = sim.calculate("filing_status", year).decode_to_str() + agi = sim.calculate("adjusted_gross_income", year) + threshold = np.where( + np.isin(statuses, list(JOINT_STATUSES)), + ACT_115_THRESHOLD["joint"], + ACT_115_THRESHOLD["other"], + ) + per_exemption = np.where(agi < threshold, ACT_115_HIGH, ACT_115_LOW) + people = sim.calculate("tax_unit_size", year) + return per_exemption * people + + +def check_invariants(sim, year): + calc = lambda variable: sim.calculate(variable, year) # noqa: E731 + + rebate = calc("hi_act_115_rebate") + np.testing.assert_allclose(rebate, act_115_reference(sim, year), atol=0.01) + + eitc_potential = calc("hi_eitc_potential") + np.testing.assert_allclose( + eitc_potential, EITC_MATCH[year] * calc("eitc"), atol=0.01 + ) + + non_refundable = calc("hi_non_refundable_credits") + tax_before_credits = calc("hi_income_tax_before_non_refundable_credits") + if year < 2018 or year >= 2023: + assert np.all(non_refundable == 0) + else: + assert np.all(non_refundable >= 0) + assert np.all( + non_refundable <= np.minimum(eitc_potential, tax_before_credits) + 0.01 + ) + + base_refundable = ( + calc("hi_food_excise_credit") + + calc("hi_cdcc") + + calc("hi_tax_credit_for_low_income_household_renters") + ) + expected_extra = rebate if year == ACT_115_YEAR else 0 + if year >= 2023: + expected_extra = expected_extra + calc("hi_eitc") + np.testing.assert_allclose( + calc("hi_refundable_credits") - base_refundable, expected_extra, atol=0.01 + ) + + if year < 2018: + np.testing.assert_allclose( + calc("hi_income_tax"), + tax_before_credits - calc("hi_refundable_credits"), + atol=0.01, + ) + + +@pytest.fixture(scope="module") +def grid_sim(): + return hawaii_simulation(GRID) + + +def test_grid_premises(grid_sim): + # The grid reaches every filing status the Act 115 table distinguishes + # here, both sides of each AGI threshold, and a positive federal EITC. + statuses = set(grid_sim.calculate("filing_status", 2021).decode_to_str()) + assert {"SINGLE", "HEAD_OF_HOUSEHOLD", "JOINT"} <= statuses + agi = grid_sim.calculate("adjusted_gross_income", 2021) + assert (agi < 100_000).any() and (agi >= 200_000).any() + for year in YEARS: + assert (grid_sim.calculate("eitc", year) > 0).any() + + +@pytest.mark.parametrize("year", YEARS) +def test_grid_invariants(grid_sim, year): + check_invariants(grid_sim, year) + + +def test_act_115_refund_is_paid_only_for_2021(grid_sim): + paid = {year: grid_sim.calculate("hi_act_115_rebate", year).sum() for year in YEARS} + assert paid[ACT_115_YEAR] > 0 + assert all(paid[year] == 0 for year in YEARS if year != ACT_115_YEAR) + + +def test_hawaii_eitc_starts_in_2018(grid_sim): + for year in YEARS: + paid = grid_sim.calculate("hi_eitc_potential", year).sum() + assert (paid > 0) == (year >= 2018), year + + +GENERATED_POINTS = st.lists( + st.tuples( + st.sampled_from(HOUSEHOLDS), + st.integers(min_value=0, max_value=300_000), + st.sampled_from(AGES), + ), + min_size=1, + max_size=8, +) + + +@settings(max_examples=8, deadline=None) +@given(points=GENERATED_POINTS, year=st.sampled_from(YEARS)) +def test_generated_invariants(points, year): + # Witnesses on each side of the Act 115 thresholds and on the EITC + # plateau keep every batch from passing vacuously. + witnesses = [((1, 0), 8_000, 30), ((2, 1), 150_000, 30), ((2, 0), 250_000, 70)] + check_invariants(hawaii_simulation(points + witnesses), year) + + +def test_military_pay_exclusion_matches_published_caps(): + """Differential test: the exclusion against each year's N-11 cap.""" + pays = [0, 3_000, 6_000, 7_000, 8_000, 8_636, 9_000, 20_000] + people, tax_units, households = {}, {}, {} + for i, pay in enumerate(pays): + name = f"p{i}" + people[name] = { + "age": {year: 40 for year in MILITARY_PAY_CAP}, + "military_service_income": {year: pay for year in MILITARY_PAY_CAP}, + } + tax_units[name] = {"members": [name]} + households[name] = { + "members": [name], + "state_code": {year: "HI" for year in MILITARY_PAY_CAP}, + } + sim = Simulation( + situation={"people": people, "tax_units": tax_units, "households": households} + ) + for year, cap in MILITARY_PAY_CAP.items(): + np.testing.assert_allclose( + sim.calculate("hi_military_pay_exclusion", year), + np.minimum(pays, cap), + atol=0.01, + err_msg=str(year), + )