diff --git a/changelog_entry.yaml b/changelog_entry.yaml index e69de29bb2d..036a3b017cd 100644 --- a/changelog_entry.yaml +++ b/changelog_entry.yaml @@ -0,0 +1,6 @@ +- bump: patch + changes: + fixed: + - Fix IL HBWD earned income exemptions to apply only to disabled/blind persons. + added: + - Add is_blind to IL HBWD disability eligibility check. diff --git a/policyengine_us/parameters/gov/states/il/hfs/hbwd/eligibility/income/sources/earned.yaml b/policyengine_us/parameters/gov/states/il/hfs/hbwd/eligibility/income/sources/earned.yaml index c85701edad1..a37c739cbb5 100644 --- a/policyengine_us/parameters/gov/states/il/hfs/hbwd/eligibility/income/sources/earned.yaml +++ b/policyengine_us/parameters/gov/states/il/hfs/hbwd/eligibility/income/sources/earned.yaml @@ -3,6 +3,7 @@ values: 2022-04-01: - employment_income - self_employment_income + - rental_income metadata: unit: list diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/hfs/hbwd/eligibility/il_hbwd_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/hfs/hbwd/eligibility/il_hbwd_income_eligible.yaml index 15edc7cb0f2..8673cfe114a 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/il/hfs/hbwd/eligibility/il_hbwd_income_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/il/hfs/hbwd/eligibility/il_hbwd_income_eligible.yaml @@ -2,6 +2,7 @@ period: 2024-01 input: state_code: IL + is_disabled: true employment_income: 36_000 # $3,000/month social_security: 12_000 # $1,000/month output: @@ -11,6 +12,7 @@ period: 2024-01 input: state_code: IL + is_disabled: true employment_income: 52_716 # $4,393/month output: il_hbwd_income_eligible: true @@ -19,7 +21,31 @@ period: 2024-01 input: state_code: IL + is_disabled: true employment_income: 60_000 # $5,000/month output: il_hbwd_income_eligible: true # Gross $5,000, after expenses and exemptions becomes eligible + +- name: Case 4, income too high even with exemptions. + period: 2024-01 + input: + state_code: IL + is_disabled: true + employment_income: 72_000 # $6,000/month + output: + il_hbwd_income_eligible: false + # 350% FPL for single (2024) = ~$4,393/month + # Gross $6,000, even after exemptions exceeds limit + +- name: Case 5, not disabled so no exemptions and income too high. + period: 2024-01 + input: + state_code: IL + is_disabled: false + employment_income: 60_000 # $5,000/month + output: + il_hbwd_income_eligible: false + # Non-disabled person uses gross income (no exemptions) + # Gross $5,000 > limit $4,393 → NOT eligible + # (Same income as Case 3, but without exemptions) diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/hfs/hbwd/income/earned/il_hbwd_countable_earned_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/hfs/hbwd/income/earned/il_hbwd_countable_earned_income.yaml new file mode 100644 index 00000000000..d15cea7883e --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/il/hfs/hbwd/income/earned/il_hbwd_countable_earned_income.yaml @@ -0,0 +1,292 @@ +# Test HBWD earned income exemption handling +# Per § 120.510(i), exemptions apply only to disabled/blind persons. +# Non-disabled/non-blind persons use gross income (no exemptions). +# If spouse is disabled/blind, they also get exemptions. + +# Test 1: Disabled worker gets earned income exemptions +- name: Case 1, disabled worker gets earned income exemptions. + period: 2025-01 + absolute_error_margin: 0.5 + input: + age: 49 + is_disabled: true + is_blind: false + il_aabd_gross_earned_income: 125 + il_aabd_expense_exemption_person: 0 + il_aabd_gross_unearned_income: 0 + state_code: IL + output: + # Disabled worker gets exemptions: 125 - 25(flat) - 20 - 30(50% of 60) = 50 + il_hbwd_countable_earned_income: 50 + +# Test 2: Non-disabled, non-blind person uses gross income (no exemptions) +- name: Case 2, non-disabled person uses gross income. + period: 2025-01 + absolute_error_margin: 0.5 + input: + age: 47 + is_disabled: false + is_blind: false + il_aabd_gross_earned_income: 125 + il_aabd_expense_exemption_person: 0 + il_aabd_gross_unearned_income: 0 + state_code: IL + output: + # Non-disabled, non-blind person: uses il_hbwd_gross_earned_income (not set here, so 0) + # In real scenarios, employment_income flows to il_hbwd_gross_earned_income + il_hbwd_countable_earned_income: 0 + +# Test 3: Scenario 15 - Married couple over income limit correctly shows ineligible +# person1: Age 49, disabled, $4,500/month wages ($54,000/year) +# person2: Age 47, NOT disabled/blind, $2,500/month wages ($30,000/year) +# Combined gross income: $7,000/month +# 350% FPL for 2 people = $6,168.75/month +- name: Case 3, married couple over income limit correctly shows ineligible. + period: 2025-01 + absolute_error_margin: 0.3 + input: + people: + person1: + age: 49 + is_disabled: true + employment_income: 54_000 # $4,500/month * 12 + person2: + age: 47 + is_disabled: false + employment_income: 30_000 # $2,500/month * 12 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: IL + output: + # person1 (disabled): gets exemptions + # person2 (not disabled/blind): uses gross income (no exemptions) + # Combined countable $6,323 > limit $6,168.75 → NOT eligible + il_hbwd_countable_income: 6_323 + il_hbwd_income_eligible: [false, false] + il_hbwd_eligible: [false, false] + il_hbwd_person: [0, 0] + +# Test 4: Single disabled worker - eligible +- name: Case 4, single disabled worker eligible. + period: 2025-01 + absolute_error_margin: 0.3 + input: + people: + person1: + age: 35 + is_disabled: true + employment_income: 24_000 # $2,000/month * 12 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: IL + output: + # Single person: 350% FPL = $5,285/month (2025) + # Countable income after exemptions < limit → eligible + il_hbwd_income_eligible: [true] + il_hbwd_eligible: [true] + +# Test 5: Single disabled worker - over income limit +- name: Case 5, single disabled worker over income limit. + period: 2025-01 + absolute_error_margin: 0.3 + input: + people: + person1: + age: 40 + is_disabled: true + employment_income: 72_000 # $6,000/month * 12 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: IL + output: + # Single person: 350% FPL = $5,285/month + # Countable income > limit → NOT eligible + il_hbwd_income_eligible: [false] + il_hbwd_eligible: [false] + +# Test 6: Blind worker (not disabled) - gets blind exemptions +- name: Case 6, blind worker gets exemptions. + period: 2025-01 + absolute_error_margin: 0.3 + input: + people: + person1: + age: 45 + is_disabled: false + is_blind: true + employment_income: 36_000 # $3,000/month * 12 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: IL + output: + # Blind worker is disability eligible and gets more generous exemptions + il_hbwd_disability_eligible: [true] + il_hbwd_income_eligible: [true] + il_hbwd_eligible: [true] + +# Test 7: Married couple - both disabled - both get exemptions +- name: Case 7, married couple both disabled. + period: 2025-01 + absolute_error_margin: 0.3 + input: + people: + person1: + age: 50 + is_disabled: true + employment_income: 36_000 # $3,000/month * 12 + person2: + age: 48 + is_disabled: true + employment_income: 24_000 # $2,000/month * 12 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: IL + output: + # Both disabled, both get exemptions + # Combined gross $5,000/month, after exemptions < limit + il_hbwd_income_eligible: [true, true] + il_hbwd_eligible: [true, true] + +# Test 8: Disabled worker under age 16 - not age eligible +- name: Case 8, disabled worker under age 16. + period: 2025-01 + absolute_error_margin: 0.3 + input: + people: + person1: + age: 15 + is_disabled: true + employment_income: 12_000 # $1,000/month * 12 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: IL + output: + # Under 16 - not age eligible for HBWD + il_hbwd_age_eligible: [false] + il_hbwd_eligible: [false] + +# Test 9: Disabled worker over age 64 - not age eligible +- name: Case 9, disabled worker over age 64. + period: 2025-01 + absolute_error_margin: 0.3 + input: + people: + person1: + age: 65 + is_disabled: true + employment_income: 24_000 # $2,000/month * 12 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: IL + output: + # Over 64 - not age eligible for HBWD + il_hbwd_age_eligible: [false] + il_hbwd_eligible: [false] + +# Test 10: Family with disabled parent and children +- name: Case 10, disabled parent with two children. + period: 2025-01 + absolute_error_margin: 0.3 + input: + people: + person1: + age: 38 + is_disabled: true + employment_income: 48_000 # $4,000/month * 12 + person2: + age: 12 + is_disabled: false + person3: + age: 8 + is_disabled: false + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: IL + output: + # 3-person household: 350% FPL = $7,455/month + # Only person1 (disabled parent) can be HBWD eligible + # Children not disabled, not age eligible + il_hbwd_eligible: [true, false, false] + +# Test 11: Non-disabled, non-blind worker - not eligible +- name: Case 11, non-disabled worker not eligible. + period: 2025-01 + absolute_error_margin: 0.3 + input: + people: + person1: + age: 30 + is_disabled: false + is_blind: false + employment_income: 24_000 # $2,000/month * 12 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: IL + output: + # Not disabled or blind - not disability eligible + il_hbwd_disability_eligible: [false] + il_hbwd_eligible: [false] + +# Test 12: Married couple at income threshold +- name: Case 12, married couple at income threshold. + period: 2025-01 + absolute_error_margin: 0.3 + input: + people: + person1: + age: 55 + is_disabled: true + employment_income: 48_000 # $4,000/month * 12 + person2: + age: 52 + is_disabled: false + employment_income: 24_000 # $2,000/month * 12 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: IL + output: + # Combined gross $6,000/month + # person1 (disabled) gets exemptions, person2 (not disabled/blind) uses gross + # Combined countable should be just under limit + il_hbwd_income_eligible: [true, true] + il_hbwd_eligible: [true, false] # person2 not disabled/blind diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/hfs/hbwd/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/hfs/hbwd/integration.yaml index e5d4e970f5a..75ddb4826f1 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/il/hfs/hbwd/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/il/hfs/hbwd/integration.yaml @@ -143,13 +143,13 @@ input: state_code: IL age: 55 - is_disabled: false + is_disabled: true # SSDI recipients are disabled social_security_disability: 18_000 # $1,500/month SSDI employment_income: 12_000 # $1,000/month part-time spm_unit_cash_assets: 5_000 output: il_hbwd_age_eligible: true - il_hbwd_disability_eligible: true # Via SSDI receipt + il_hbwd_disability_eligible: true il_hbwd_employment_eligible: true il_hbwd_income_eligible: true il_hbwd_asset_eligible: true diff --git a/policyengine_us/variables/gov/states/il/hfs/hbwd/eligibility/il_hbwd_disability_eligible.py b/policyengine_us/variables/gov/states/il/hfs/hbwd/eligibility/il_hbwd_disability_eligible.py index b8be18389a0..414f98c4323 100644 --- a/policyengine_us/variables/gov/states/il/hfs/hbwd/eligibility/il_hbwd_disability_eligible.py +++ b/policyengine_us/variables/gov/states/il/hfs/hbwd/eligibility/il_hbwd_disability_eligible.py @@ -18,7 +18,9 @@ def formula(person, period, parameters): # rules related to earned income do not apply" - so we use is_disabled # (medical definition) instead of is_ssi_disabled (which includes SGA test). # See: https://il.db101.org/il/programs/health_coverage/how_health/program2b.htm + # SSA recognizes blindness as a category of disability (SSI has Aged, Blind, Disabled). is_disabled = person("is_disabled", period.this_year) + is_blind = person("is_blind", period) # Or currently receiving SSDI receives_ssdi = person("social_security_disability", period) > 0 - return is_disabled | receives_ssdi + return is_disabled | is_blind | receives_ssdi diff --git a/policyengine_us/variables/gov/states/il/hfs/hbwd/income/earned/il_hbwd_countable_earned_income.py b/policyengine_us/variables/gov/states/il/hfs/hbwd/income/earned/il_hbwd_countable_earned_income.py index f9d09085d13..d77cb248298 100644 --- a/policyengine_us/variables/gov/states/il/hfs/hbwd/income/earned/il_hbwd_countable_earned_income.py +++ b/policyengine_us/variables/gov/states/il/hfs/hbwd/income/earned/il_hbwd_countable_earned_income.py @@ -15,10 +15,19 @@ class il_hbwd_countable_earned_income(Variable): ) defined_for = StateCode.IL - adds = ["il_aabd_earned_income_after_exemption_person"] - # HBWD uses the same earned income calculation as AABD per - # 89 Ill. Admin. Code § 120.510(i) referencing § 120.362 and § 120.370 - # § 120.362 and § 113.120 have identical exemption amounts: - # - $25 flat exemption (§ 120.362(a) / § 113.120(a)) - # - $20 + 50% of next $60 for disabled workers (§ 120.362(b)(1) / § 113.120(b)) - # § 120.370 references AABD MANG work expense deductions + def formula(person, period, parameters): + # Per § 120.510(i), earned income exemptions apply only to the + # disabled/blind worker's earnings, not to the spouse's. + # Per § 120.510(f), the spouse's income is counted at gross. + is_disabled = person("is_disabled", period) + is_blind = person("is_blind", period) + is_hbwd_worker = is_disabled | is_blind + + earned_income_with_exemption = person( + "il_aabd_earned_income_after_exemption_person", period + ) + gross_earned_income = person("il_hbwd_gross_earned_income", period) + + return where( + is_hbwd_worker, earned_income_with_exemption, gross_earned_income + ) diff --git a/policyengine_us/variables/gov/states/il/hfs/hbwd/income/il_hbwd_countable_income.py b/policyengine_us/variables/gov/states/il/hfs/hbwd/income/il_hbwd_countable_income.py index 2f5c2b159d4..90710334448 100644 --- a/policyengine_us/variables/gov/states/il/hfs/hbwd/income/il_hbwd_countable_income.py +++ b/policyengine_us/variables/gov/states/il/hfs/hbwd/income/il_hbwd_countable_income.py @@ -14,8 +14,9 @@ class il_hbwd_countable_income(Variable): defined_for = "is_tax_unit_head_or_spouse" adds = [ - "il_aabd_earned_income_after_exemption_person", + "il_hbwd_countable_earned_income", "il_hbwd_countable_unearned_income", ] # Per § 120.510(f), count income of individual AND spouse + # Per § 120.510(i), earned income exemptions apply only to disabled worker # Adds automatically sums across SPM unit members