diff --git a/changelog_entry.yaml b/changelog_entry.yaml index e69de29bb2d..bf79e9338c6 100644 --- a/changelog_entry.yaml +++ b/changelog_entry.yaml @@ -0,0 +1,6 @@ +- bump: patch + changes: + added: + - Add historical TANF parameter data for DE, MO, RI, SD (pre-2018 values). + - Add PA TANF Work Expense Reimbursement (WER) for 2009-2020 era. + - Add PA TANF work expense mechanism toggle (uses_deduction parameter). diff --git a/policyengine_us/parameters/gov/states/de/dhss/tanf/benefit/deficit_rate.yaml b/policyengine_us/parameters/gov/states/de/dhss/tanf/benefit/deficit_rate.yaml index 955f70aa6c1..c0262a642a6 100644 --- a/policyengine_us/parameters/gov/states/de/dhss/tanf/benefit/deficit_rate.yaml +++ b/policyengine_us/parameters/gov/states/de/dhss/tanf/benefit/deficit_rate.yaml @@ -1,7 +1,7 @@ description: Delaware uses this share of the deficit to calculate the grant remainder under the Temporary Assistance for Needy Families program. values: - 2024-10-01: 0.5 + 2011-10-01: 0.5 metadata: unit: /1 @@ -10,5 +10,7 @@ metadata: reference: - title: 16 Del. Admin. Code SS 4000-4008.1.1 Step 3 TANF GRANT COMPUTATION href: https://www.law.cornell.edu/regulations/delaware/16-Del-Admin-Code-SS-4000-4008 + - title: Delaware TANF State Plan 2011 - Exhibit 1 and Exhibit 2 + href: https://dhss.delaware.gov/wp-content/uploads/sites/11/dss/pdf/tanf_ffy2012_stateplan.pdf#page=7 - title: Delaware TANF State Plan 2017 - Exhibit 1 and Exhibit 2 href: https://dhss.delaware.gov/wp-content/uploads/sites/11/dss/pdf/detanfstateplan2017.pdf#page=7 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 a37c739cbb5..c85701edad1 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,7 +3,6 @@ values: 2022-04-01: - employment_income - self_employment_income - - rental_income metadata: unit: list diff --git a/policyengine_us/parameters/gov/states/mo/dss/tanf/minimum_payment.yaml b/policyengine_us/parameters/gov/states/mo/dss/tanf/minimum_payment.yaml index 758787a62b2..546e356614e 100644 --- a/policyengine_us/parameters/gov/states/mo/dss/tanf/minimum_payment.yaml +++ b/policyengine_us/parameters/gov/states/mo/dss/tanf/minimum_payment.yaml @@ -1,7 +1,8 @@ description: Missouri does not issue TANF payments below this amount. values: - 2024-01-01: 10 + # Rule originated April 22, 1948 with AFDC; carried forward to TANF + 2002-01-01: 10 metadata: unit: currency-USD diff --git a/policyengine_us/parameters/gov/states/pa/dhs/tanf/income/deductions/work_expense/additional.yaml b/policyengine_us/parameters/gov/states/pa/dhs/tanf/income/deductions/work_expense/additional.yaml deleted file mode 100644 index 70ba7de905e..00000000000 --- a/policyengine_us/parameters/gov/states/pa/dhs/tanf/income/deductions/work_expense/additional.yaml +++ /dev/null @@ -1,15 +0,0 @@ -description: Pennsylvania deducts this additional amount for work expenses under the Temporary Assistance for Needy Families program. -# Administrative policy effective September 2020. Not codified in PA Code; documented in state plan and handbook. - -values: - 2020-09-26: 200 - -metadata: - unit: currency-USD - period: month - label: Pennsylvania TANF additional work expense deduction - reference: - - title: PA DHS TANF State Plan 2024 - href: https://www.pa.gov/content/dam/copapwp-pagov/en/dhs/documents/services/assistance/documents/tanf/tanf-state-plan-effective-october-1-2024.pdf#page=13 - - title: PA DHS Cash Assistance Handbook Section 168.22, Work Expense Deduction - href: http://services.dpw.state.pa.us/oimpolicymanuals/cash/index.htm#t=160_Income_Deductions%2F160_2_TANF_Earned_Income_Deductions.htm%23160.21_TANF_Earned_Income_Disregard diff --git a/policyengine_us/parameters/gov/states/pa/dhs/tanf/income/work_expense/deduction.yaml b/policyengine_us/parameters/gov/states/pa/dhs/tanf/income/work_expense/deduction.yaml new file mode 100644 index 00000000000..46c93b7f746 --- /dev/null +++ b/policyengine_us/parameters/gov/states/pa/dhs/tanf/income/work_expense/deduction.yaml @@ -0,0 +1,16 @@ +description: Pennsylvania deducts this amount from countable earned income for work expenses under the Temporary Assistance for Needy Families program. +# Work Expense Deduction (WED) - applied after 50% earned income disregard +# Replaced the Work Expense Reimbursement (WER) in September 2020 + +values: + 2020-10-01: 200 + +metadata: + unit: currency-USD + period: month + label: Pennsylvania TANF work expense deduction amount + reference: + - title: PA DHS TANF State Plan 2024 + href: https://www.pa.gov/content/dam/copapwp-pagov/en/dhs/documents/services/assistance/documents/tanf/tanf-state-plan-effective-october-1-2024.pdf#page=13 + - title: PA DHS Cash Assistance Handbook Section 160.22, Work Expense Deduction + href: http://services.dpw.state.pa.us/oimpolicymanuals/cash/index.htm#t=160_Income_Deductions%2F160_2_TANF_Earned_Income_Deductions.htm diff --git a/policyengine_us/parameters/gov/states/pa/dhs/tanf/income/work_expense/reimbursement.yaml b/policyengine_us/parameters/gov/states/pa/dhs/tanf/income/work_expense/reimbursement.yaml new file mode 100644 index 00000000000..c7ed5455ad3 --- /dev/null +++ b/policyengine_us/parameters/gov/states/pa/dhs/tanf/income/work_expense/reimbursement.yaml @@ -0,0 +1,14 @@ +description: Pennsylvania provides this amount as a work expense reimbursement under the Temporary Assistance for Needy Families program. +# Work Expense Reimbursement (WER) - flat bonus added to TANF grant +# Active March 2009 to September 2020, then replaced by Work Expense Deduction (WED) + +values: + 2009-04-01: 50 + +metadata: + unit: currency-USD + period: month + label: Pennsylvania TANF work expense reimbursement amount + reference: + - title: PA DHS Cash Assistance Handbook Section 137.4, Work Expense Reimbursement + href: http://services.dpw.state.pa.us/oimpolicymanuals/cash/137_Cash_Initiatives/137.4_Work_Expense_Reimbursement.htm diff --git a/policyengine_us/parameters/gov/states/pa/dhs/tanf/income/work_expense/uses_deduction.yaml b/policyengine_us/parameters/gov/states/pa/dhs/tanf/income/work_expense/uses_deduction.yaml new file mode 100644 index 00000000000..6a2ea22315e --- /dev/null +++ b/policyengine_us/parameters/gov/states/pa/dhs/tanf/income/work_expense/uses_deduction.yaml @@ -0,0 +1,17 @@ +description: Pennsylvania uses a work expense deduction (true) or reimbursement (false) under the Temporary Assistance for Needy Families program. +# Before 2020: Work Expense Reimbursement (WER) - $50/month added to benefit +# After 2020: Work Expense Deduction (WED) - $200/month deducted from income + +values: + 2009-04-01: false + 2020-10-01: true + +metadata: + unit: bool + period: month + label: Pennsylvania TANF uses work expense deduction + reference: + - title: PA DHS Cash Assistance Handbook Section 137.4, Work Expense Reimbursement + href: http://services.dpw.state.pa.us/oimpolicymanuals/cash/137_Cash_Initiatives/137.4_Work_Expense_Reimbursement.htm + - title: PA DHS TANF State Plan 2024, Work Expense Deduction + href: https://www.pa.gov/content/dam/copapwp-pagov/en/dhs/documents/services/assistance/documents/tanf/tanf-state-plan-effective-october-1-2024.pdf#page=13 diff --git a/policyengine_us/parameters/gov/states/ri/dhs/works/income/dependent_care/amount.yaml b/policyengine_us/parameters/gov/states/ri/dhs/works/income/dependent_care/amount.yaml index fdaaecf3968..4039add258c 100644 --- a/policyengine_us/parameters/gov/states/ri/dhs/works/income/dependent_care/amount.yaml +++ b/policyengine_us/parameters/gov/states/ri/dhs/works/income/dependent_care/amount.yaml @@ -9,15 +9,18 @@ metadata: reference: - title: 218-RICR-20-00-2.15.5(B)(2) Dependent Care Deduction href: https://www.law.cornell.edu/regulations/rhode-island/218-RICR-20-00-2.15 + - title: R.I. Gen. Laws Chapter 40-5.2 - Rhode Island Works Act of 2008 + href: http://webserver.rilin.state.ri.us/Statutes/TITLE40/40-5.2/INDEX.htm - title: Rhode Island Works Program Eligibility href: https://dhs.ri.gov/programs-and-services/ri-works-program/eligibility-how-apply brackets: + # Rhode Island Works established July 1, 2008; amounts based on federal SNAP limits - threshold: - 2019-01-01: 0 + 2008-07-01: 0 amount: - 2019-01-01: 200 + 2008-07-01: 200 - threshold: - 2019-01-01: 2 + 2008-07-01: 2 amount: - 2019-01-01: 175 + 2008-07-01: 175 diff --git a/policyengine_us/parameters/gov/states/sd/dss/tanf/payment_standard/max_table_size.yaml b/policyengine_us/parameters/gov/states/sd/dss/tanf/payment_standard/max_table_size.yaml index 483a8786b77..25a730106bc 100644 --- a/policyengine_us/parameters/gov/states/sd/dss/tanf/payment_standard/max_table_size.yaml +++ b/policyengine_us/parameters/gov/states/sd/dss/tanf/payment_standard/max_table_size.yaml @@ -1,12 +1,14 @@ description: South Dakota uses this amount as the maximum family size in the payment standard table under the Temporary Assistance for Needy Families program. values: - 2023-07-01: 12 + 2016-09-01: 12 metadata: unit: person period: month label: South Dakota TANF maximum table family size reference: + - title: ARSD 67:10:05:03 - Payment Standards (2016) + href: https://sdlegislature.gov/api/Rules/Archived/10994.pdf#page=1 - title: ARSD 67:10:05:03 - Payment Standards href: https://sdlegislature.gov/Rules/Administrative/67:10:05:03 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 8673cfe114a..15edc7cb0f2 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,7 +2,6 @@ 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: @@ -12,7 +11,6 @@ period: 2024-01 input: state_code: IL - is_disabled: true employment_income: 52_716 # $4,393/month output: il_hbwd_income_eligible: true @@ -21,31 +19,7 @@ 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 deleted file mode 100644 index d15cea7883e..00000000000 --- a/policyengine_us/tests/policy/baseline/gov/states/il/hfs/hbwd/income/earned/il_hbwd_countable_earned_income.yaml +++ /dev/null @@ -1,292 +0,0 @@ -# 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 75ddb4826f1..e5d4e970f5a 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: true # SSDI recipients are disabled + is_disabled: false 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 + il_hbwd_disability_eligible: true # Via SSDI receipt il_hbwd_employment_eligible: true il_hbwd_income_eligible: true il_hbwd_asset_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/pa/dhs/tanf/income/pa_tanf_earned_income_after_deductions_person.yaml b/policyengine_us/tests/policy/baseline/gov/states/pa/dhs/tanf/income/pa_tanf_earned_income_after_deductions_person.yaml index f390aa7555d..3f4cad77ca4 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/pa/dhs/tanf/income/pa_tanf_earned_income_after_deductions_person.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/pa/dhs/tanf/income/pa_tanf_earned_income_after_deductions_person.yaml @@ -79,3 +79,46 @@ # Step 1: $250 × 50% = $125 (EID: keep 50%) # Step 2: $125 - $200 = -$75, clipped to 0 (WED) pa_tanf_earned_income_after_deductions_person: 0 + +# Work Expense Reimbursement (WER) era tests - before Sept 2020 +# In WER era, no $200 WED deduction is applied + +- name: Case 8, WER era, low earnings, enrolled recipient, no WED. + period: 2019-01 + input: + employment_income_before_lsr: 12_000 + is_tanf_enrolled: true + state_code: PA + output: + # Monthly: $12,000/12 = $1,000 + # Step 1: $1,000 × 50% = $500 (EID: keep 50%) + # Step 2: No WED in WER era (pre-2020) + # Countable: $500 + pa_tanf_earned_income_after_deductions_person: 500 + +- name: Case 9, WER era, high earnings, enrolled recipient, no WED. + period: 2019-01 + input: + employment_income_before_lsr: 36_000 + is_tanf_enrolled: true + state_code: PA + output: + # Monthly: $36,000/12 = $3,000 + # Step 1: $3,000 × 50% = $1,500 (EID: keep 50%) + # Step 2: No WED in WER era (pre-2020) + # Countable: $1,500 + pa_tanf_earned_income_after_deductions_person: 1_500 + +- name: Case 10, WER era, deductions would have zeroed income in WED era. + period: 2019-01 + input: + employment_income_before_lsr: 2_400 + is_tanf_enrolled: true + state_code: PA + output: + # Monthly: $2,400/12 = $200 + # Step 1: $200 × 50% = $100 (EID: keep 50%) + # Step 2: No WED in WER era + # In WED era this would be: $100 - $200 = 0 + # In WER era: $100 (no deduction) + pa_tanf_earned_income_after_deductions_person: 100 diff --git a/policyengine_us/tests/policy/baseline/gov/states/pa/dhs/tanf/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/pa/dhs/tanf/integration.yaml index 0c77b4b143f..3104d91b042 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/pa/dhs/tanf/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/pa/dhs/tanf/integration.yaml @@ -384,3 +384,101 @@ pa_tanf_maximum_benefit: 403 pa_tanf_countable_income: 550 pa_tanf: 0 + +# Work Expense Reimbursement (WER) era integration tests - before Sept 2020 +# WER: $50 bonus added to benefit (not income deduction) +# WED: $200 deducted from income (not bonus) + +- name: Case 14, WER era, family with earned income gets $50 bonus. + period: 2019-01 + input: + people: + person1: + age: 35 + employment_income_before_lsr: 6_960 + person2: + age: 8 + person3: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + is_tanf_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: PA + output: + # Family of 3: FSA = $403/month (same as 2024) + # Person1 monthly: $6,960/12 = $580 + # WER era: Only 50% EID applied, no $200 WED + # $580 × 50% = $290 countable + # Base benefit: $403 - $290 = $113 + # WER bonus: +$50 (family has earned income) + # Total benefit: $113 + $50 = $163 + pa_tanf_maximum_benefit: 403 + pa_tanf_countable_income: 290 + pa_tanf: 163 + +- name: Case 15, WER era vs WED era comparison, same family. + period: 2024-01 + input: + people: + person1: + age: 35 + employment_income_before_lsr: 6_960 + person2: + age: 8 + person3: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + is_tanf_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: PA + output: + # Same family as Case 14 but in WED era (2024) + # Family of 3: FSA = $403/month + # Person1 monthly: $6,960/12 = $580 + # WED era: 50% EID + $200 WED deduction + # $580 × 50% = $290; $290 - $200 = $90 countable + # Benefit: $403 - $90 = $313 + # No WER bonus in WED era + # WED era benefit ($313) > WER era benefit ($163) by $150 + pa_tanf_maximum_benefit: 403 + pa_tanf_countable_income: 90 + pa_tanf: 313 + +- name: Case 16, WER era, no earned income, no bonus. + period: 2019-01 + input: + people: + person1: + age: 45 + employment_income_before_lsr: 0 + social_security: 2_400 + person2: + age: 10 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: PA + output: + # Family of 3: FSA = $403/month + # No earned income, only unearned (SS) + # Unearned monthly: $2,400/12 = $200 + # No EID/WED for unearned income + # Countable: $200 + # Benefit: $403 - $200 = $203 + # No WER bonus (no earned income) + pa_tanf_maximum_benefit: 403 + pa_tanf_countable_income: 200 + pa_tanf: 203 diff --git a/policyengine_us/tests/policy/baseline/gov/states/pa/dhs/tanf/pa_tanf.yaml b/policyengine_us/tests/policy/baseline/gov/states/pa/dhs/tanf/pa_tanf.yaml index ce2ed0f377a..9d40feb12d4 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/pa/dhs/tanf/pa_tanf.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/pa/dhs/tanf/pa_tanf.yaml @@ -51,3 +51,75 @@ pa_tanf_eligible: true output: pa_tanf: 636 + +# Work Expense Reimbursement (WER) era tests - before Sept 2020 +# WER adds $50 bonus to benefit for families with earned income + +- name: Case 7, WER era, family with earned income gets $50 bonus. + period: 2019-01 + input: + people: + person1: + age: 30 + tanf_gross_earned_income: 500 + spm_units: + spm_unit: + members: [person1] + pa_tanf_maximum_benefit: 316 + pa_tanf_countable_income: 100 + pa_tanf_eligible: true + households: + household: + members: [person1] + state_code: PA + output: + # Base grant: $316 - $100 = $216 + # WER bonus: $50 (family has earned income) + # Total: $216 + $50 = $266 + pa_tanf: 266 + +- name: Case 8, WER era, family without earned income, no bonus. + period: 2019-01 + input: + people: + person1: + age: 30 + tanf_gross_earned_income: 0 + spm_units: + spm_unit: + members: [person1] + pa_tanf_maximum_benefit: 316 + pa_tanf_countable_income: 100 + pa_tanf_eligible: true + households: + household: + members: [person1] + state_code: PA + output: + # Base grant: $316 - $100 = $216 + # No WER bonus (no earned income) + # Total: $216 + pa_tanf: 216 + +- name: Case 9, WED era, family with earned income, no bonus. + period: 2024-01 + input: + people: + person1: + age: 30 + tanf_gross_earned_income: 500 + spm_units: + spm_unit: + members: [person1] + pa_tanf_maximum_benefit: 316 + pa_tanf_countable_income: 100 + pa_tanf_eligible: true + households: + household: + members: [person1] + state_code: PA + output: + # Base grant: $316 - $100 = $216 + # No WER bonus in WED era (2024) + # Total: $216 + pa_tanf: 216 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 414f98c4323..b8be18389a0 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,9 +18,7 @@ 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 | is_blind | receives_ssdi + return is_disabled | 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 d77cb248298..f9d09085d13 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,19 +15,10 @@ class il_hbwd_countable_earned_income(Variable): ) defined_for = StateCode.IL - 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 - ) + 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 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 90710334448..2f5c2b159d4 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,9 +14,8 @@ class il_hbwd_countable_income(Variable): defined_for = "is_tax_unit_head_or_spouse" adds = [ - "il_hbwd_countable_earned_income", + "il_aabd_earned_income_after_exemption_person", "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 diff --git a/policyengine_us/variables/gov/states/pa/dhs/tanf/income/pa_tanf_earned_income_after_deductions_person.py b/policyengine_us/variables/gov/states/pa/dhs/tanf/income/pa_tanf_earned_income_after_deductions_person.py index 1814259ff44..82f22f30b1a 100644 --- a/policyengine_us/variables/gov/states/pa/dhs/tanf/income/pa_tanf_earned_income_after_deductions_person.py +++ b/policyengine_us/variables/gov/states/pa/dhs/tanf/income/pa_tanf_earned_income_after_deductions_person.py @@ -14,14 +14,25 @@ class pa_tanf_earned_income_after_deductions_person(Variable): ) def formula(person, period, parameters): - p = parameters(period).gov.states.pa.dhs.tanf.income.deductions + p = parameters(period).gov.states.pa.dhs.tanf.income gross_earned = person("tanf_gross_earned_income", period) disregard_eligible = person.spm_unit( "pa_tanf_disregard_eligible", period ) - after_eid = gross_earned * (1 - p.earned_income_disregard.percentage) - after_wed = max_(after_eid - p.work_expense.additional, 0) + # Apply 50% earned income disregard + after_eid = gross_earned * ( + 1 - p.deductions.earned_income_disregard.percentage + ) + + # Apply Work Expense Deduction (WED) only when in effect (post-2020) + # Before 2020, Work Expense Reimbursement (WER) was used instead (added to benefit) + wed_amount = where( + p.work_expense.uses_deduction, + p.work_expense.deduction, + 0, + ) + after_wed = max_(after_eid - wed_amount, 0) return where(disregard_eligible, after_wed, gross_earned) diff --git a/policyengine_us/variables/gov/states/pa/dhs/tanf/pa_tanf.py b/policyengine_us/variables/gov/states/pa/dhs/tanf/pa_tanf.py index 0b00b0aa03a..3ca14aa5904 100644 --- a/policyengine_us/variables/gov/states/pa/dhs/tanf/pa_tanf.py +++ b/policyengine_us/variables/gov/states/pa/dhs/tanf/pa_tanf.py @@ -9,11 +9,28 @@ class pa_tanf(Variable): definition_period = MONTH defined_for = "pa_tanf_eligible" reference = ( - "https://www.pa.gov/agencies/dhs/resources/cash-assistance/tanf" + "https://www.pa.gov/agencies/dhs/resources/cash-assistance/tanf", + "http://services.dpw.state.pa.us/oimpolicymanuals/cash/137_Cash_Initiatives/137.4_Work_Expense_Reimbursement.htm", ) def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.pa.dhs.tanf.income.work_expense + maximum_benefit = spm_unit("pa_tanf_maximum_benefit", period) countable_income = spm_unit("pa_tanf_countable_income", period) + base_grant = max_(maximum_benefit - countable_income, 0) + + # Work Expense Reimbursement (WER): $50/month bonus for families with earned income + # Active 2009-2020, before Work Expense Deduction (WED) replaced it + gross_earned_income = add( + spm_unit, period, ["tanf_gross_earned_income"] + ) + has_earned_income = gross_earned_income > 0 + uses_wer = p.uses_deduction == False + wer_amount = where( + uses_wer & has_earned_income, + p.reimbursement, + 0, + ) - return max_(maximum_benefit - countable_income, 0) + return base_grant + wer_amount