diff --git a/changelog_entry.yaml b/changelog_entry.yaml index e69de29bb2d..1a7aa318281 100644 --- a/changelog_entry.yaml +++ b/changelog_entry.yaml @@ -0,0 +1,4 @@ +- bump: minor + changes: + added: + - Nebraska Aid to Dependent Children (ADC) program. diff --git a/policyengine_us/parameters/gov/states/ne/dhhs/adc/benefit/payment_standard_rate.yaml b/policyengine_us/parameters/gov/states/ne/dhhs/adc/benefit/payment_standard_rate.yaml new file mode 100644 index 00000000000..555ebd2abe9 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ne/dhhs/adc/benefit/payment_standard_rate.yaml @@ -0,0 +1,12 @@ +description: Nebraska provides this share of the standard of need as the payment standard under the Aid to Dependent Children program. + +values: + 2015-07-01: 0.55 + +metadata: + unit: /1 + period: month + label: Nebraska ADC payment standard rate + reference: + - title: Neb. Rev. Stat. 43-512(3) + href: https://nebraskalegislature.gov/laws/statutes.php?statute=43-512 diff --git a/policyengine_us/parameters/gov/states/ne/dhhs/adc/benefit/standard_of_need/additional_person.yaml b/policyengine_us/parameters/gov/states/ne/dhhs/adc/benefit/standard_of_need/additional_person.yaml new file mode 100644 index 00000000000..ba0a6327c0e --- /dev/null +++ b/policyengine_us/parameters/gov/states/ne/dhhs/adc/benefit/standard_of_need/additional_person.yaml @@ -0,0 +1,17 @@ +description: Nebraska adds this amount to the standard of need for each person beyond unit size 10 under the Aid to Dependent Children program. + +values: + 2021-07-01: 140 + 2025-07-01: 170 + +metadata: + unit: currency-USD + period: month + label: Nebraska ADC standard of need additional person increment + reference: + - title: Neb. Rev. Stat. 43-513(1) + href: https://nebraskalegislature.gov/laws/statutes.php?statute=43-513 + - title: 468-000-209 (2021) + href: https://dhhs.ne.gov/Documents/468-000-209.pdf + - title: Title 468 NAC Chapter 3 (2025) + href: https://dhhs.ne.gov/Guidance%20Docs/Title%20468%20-%20Aid%20to%20Dependent%20Children.pdf#page=9 diff --git a/policyengine_us/parameters/gov/states/ne/dhhs/adc/benefit/standard_of_need/amount.yaml b/policyengine_us/parameters/gov/states/ne/dhhs/adc/benefit/standard_of_need/amount.yaml new file mode 100644 index 00000000000..3ef597ae90f --- /dev/null +++ b/policyengine_us/parameters/gov/states/ne/dhhs/adc/benefit/standard_of_need/amount.yaml @@ -0,0 +1,46 @@ +description: Nebraska sets this amount as the standard of need under the Aid to Dependent Children program. + +metadata: + unit: currency-USD + period: month + breakdown: + - range(1, 11) + label: Nebraska ADC standard of need + reference: + - title: Neb. Rev. Stat. 43-513(1) + href: https://nebraskalegislature.gov/laws/statutes.php?statute=43-513 + - title: 468-000-209 (2021) + href: https://dhhs.ne.gov/Documents/468-000-209.pdf + - title: Title 468 NAC Chapter 3 (2025) + href: https://dhhs.ne.gov/Guidance%20Docs/Title%20468%20-%20Aid%20to%20Dependent%20Children.pdf#page=9 + +1: + 2021-07-01: 601 + 2025-07-01: 727 +2: + 2021-07-01: 741 + 2025-07-01: 897 +3: + 2021-07-01: 881 + 2025-07-01: 1_067 +4: + 2021-07-01: 1_021 + 2025-07-01: 1_237 +5: + 2021-07-01: 1_161 + 2025-07-01: 1_407 +6: + 2021-07-01: 1_301 + 2025-07-01: 1_577 +7: + 2021-07-01: 1_441 + 2025-07-01: 1_747 +8: + 2021-07-01: 1_581 + 2025-07-01: 1_917 +9: + 2021-07-01: 1_721 + 2025-07-01: 2_087 +10: + 2021-07-01: 1_861 + 2025-07-01: 2_257 diff --git a/policyengine_us/parameters/gov/states/ne/dhhs/adc/income/earned_income_disregard/initial.yaml b/policyengine_us/parameters/gov/states/ne/dhhs/adc/income/earned_income_disregard/initial.yaml new file mode 100644 index 00000000000..f80f0f0048c --- /dev/null +++ b/policyengine_us/parameters/gov/states/ne/dhhs/adc/income/earned_income_disregard/initial.yaml @@ -0,0 +1,12 @@ +description: Nebraska excludes this share of earnings from countable income for initial applicants under the Aid to Dependent Children program. + +values: + 2021-07-01: 0.2 + +metadata: + unit: /1 + period: month + label: Nebraska ADC initial earned income disregard rate + reference: + - title: Neb. Rev. Stat. 68-1726(3)(a)(i) + href: https://nebraskalegislature.gov/laws/statutes.php?statute=68-1726 diff --git a/policyengine_us/parameters/gov/states/ne/dhhs/adc/income/earned_income_disregard/ongoing.yaml b/policyengine_us/parameters/gov/states/ne/dhhs/adc/income/earned_income_disregard/ongoing.yaml new file mode 100644 index 00000000000..90388af8b53 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ne/dhhs/adc/income/earned_income_disregard/ongoing.yaml @@ -0,0 +1,12 @@ +description: Nebraska excludes this share of earnings from countable income for ongoing recipients under the Aid to Dependent Children program. + +values: + 2021-07-01: 0.5 + +metadata: + unit: /1 + period: month + label: Nebraska ADC ongoing earned income disregard rate + reference: + - title: Neb. Rev. Stat. 68-1726(3)(a)(ii) + href: https://nebraskalegislature.gov/laws/statutes.php?statute=68-1726 diff --git a/policyengine_us/parameters/gov/states/ne/dhhs/adc/max_unit_size.yaml b/policyengine_us/parameters/gov/states/ne/dhhs/adc/max_unit_size.yaml new file mode 100644 index 00000000000..fe917551b2d --- /dev/null +++ b/policyengine_us/parameters/gov/states/ne/dhhs/adc/max_unit_size.yaml @@ -0,0 +1,12 @@ +description: Nebraska sets this as the maximum unit size for benefit calculations under the Aid to Dependent Children program. + +values: + 2021-07-01: 10 + +metadata: + unit: /1 + period: year + label: Nebraska ADC maximum unit size + reference: + - title: Title 468 NAC Chapter 3 (2025) + href: https://dhhs.ne.gov/Guidance%20Docs/Title%20468%20-%20Aid%20to%20Dependent%20Children.pdf#page=9 diff --git a/policyengine_us/parameters/gov/states/ne/dhhs/adc/resources/limit.yaml b/policyengine_us/parameters/gov/states/ne/dhhs/adc/resources/limit.yaml new file mode 100644 index 00000000000..57ff15172ad --- /dev/null +++ b/policyengine_us/parameters/gov/states/ne/dhhs/adc/resources/limit.yaml @@ -0,0 +1,21 @@ +description: Nebraska limits countable resources to this amount under the Aid to Dependent Children program. + +metadata: + type: single_amount + threshold_unit: person + amount_unit: currency-USD + period: month + label: Nebraska ADC resource limit + reference: + - title: Neb. Rev. Stat. 68-1726(1) + href: https://nebraskalegislature.gov/laws/statutes.php?statute=68-1726 + +brackets: + - threshold: + 2021-07-01: 1 + amount: + 2021-07-01: 4_000 + - threshold: + 2021-07-01: 2 + amount: + 2021-07-01: 6_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/adc/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/adc/integration.yaml new file mode 100644 index 00000000000..718352d4698 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/adc/integration.yaml @@ -0,0 +1,258 @@ +# Nebraska ADC (Aid to Dependent Children) Integration Tests +# These tests verify the FULL calculation pipeline with all intermediate values. +# +# Gap Budgeting Methodology: +# Step 1: Net Earned Income = Gross Earned * (1 - disregard_rate) +# - Initial applicants: 20% disregard (countable = 80%) +# - Ongoing recipients: 50% disregard (countable = 50%) +# Step 2: Gap = Need Standard - Net Earned Income +# Step 3: Benefit = min(Gap, Payment Standard) +# Step 4: Final Benefit = Benefit - Unearned Income +# +# Income Standards (July 2021): +# Size 2: Need Standard = $741, Payment Standard = $408 +# Size 3: Need Standard = $881, Payment Standard = $485 +# Size 4: Need Standard = $1,021, Payment Standard = $562 +# +# NOTE: These tests model ONGOING recipients (is_tanf_enrolled: true) +# who receive the 50% earned income disregard. + +- name: Case 1, family of 3 with no income receives maximum benefit. + period: 2024-01 + absolute_error_margin: 0.5 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + employment_income_before_lsr: 0 + person2: + age: 10 + person3: + age: 8 + spm_units: + spm_unit: + members: [person1, person2, person3] + spm_unit_assets: 1_000 + is_tanf_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: NE + output: + spm_unit_size: 3 + ne_adc_need_standard: 881 + ne_adc_payment_standard: 485 + ne_adc_countable_earned_income: 0 + ne_adc_income_eligible: true + ne_adc_eligible: true + ne_adc: 485 + # Gap = $881 - $0 = $881 + # Benefit = min($881, $485) = $485 + +- name: Case 2, family of 3 with earned income receives partial benefit. + period: 2024-01 + absolute_error_margin: 0.5 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + employment_income_before_lsr: 12_000 # $1,000/month + person2: + age: 10 + person3: + age: 8 + spm_units: + spm_unit: + members: [person1, person2, person3] + spm_unit_assets: 2_000 + is_tanf_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: NE + output: + spm_unit_size: 3 + ne_adc_need_standard: 881 + ne_adc_payment_standard: 485 + ne_adc_countable_earned_income: 500 + # After 50% disregard: $1,000 * 0.50 = $500 + ne_adc_income_eligible: true + ne_adc_eligible: true + ne_adc: 381 + # Gap = $881 - $500 = $381 + # Benefit = min($381, $485) = $381 + +- name: Case 3, family of 4 with unearned income. + period: 2024-01 + absolute_error_margin: 0.5 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + employment_income_before_lsr: 0 + social_security: 6_000 # $500/month unearned + person2: + age: 29 + is_tax_unit_head_or_spouse: true + person3: + age: 10 + person4: + age: 8 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + spm_unit_assets: 3_000 + is_tanf_enrolled: true + households: + household: + members: [person1, person2, person3, person4] + state_code: NE + output: + spm_unit_size: 4 + ne_adc_need_standard: 1_021 + ne_adc_payment_standard: 562 + ne_adc_countable_earned_income: 0 + ne_adc_income_eligible: true + ne_adc_eligible: true + ne_adc: 62 + # Gap = $1,021 - $0 = $1,021 + # Benefit = min($1,021, $562) = $562 + # Final = $562 - $500 = $62 + +- name: Case 4, family above income limit is ineligible. + period: 2024-01 + absolute_error_margin: 0.5 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + employment_income_before_lsr: 24_000 # $2,000/month + person2: + age: 10 + person3: + age: 8 + spm_units: + spm_unit: + members: [person1, person2, person3] + spm_unit_assets: 1_000 + is_tanf_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: NE + output: + spm_unit_size: 3 + ne_adc_need_standard: 881 + ne_adc_payment_standard: 485 + ne_adc_countable_earned_income: 1_000 + # After 50% disregard: $2,000 * 0.50 = $1,000 + ne_adc_income_eligible: false + # Countable ($1,000) > Need Standard ($881) + ne_adc_eligible: false + ne_adc: 0 + +- name: Case 5, family of 2 near income threshold. + period: 2024-01 + absolute_error_margin: 0.5 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + employment_income_before_lsr: 16_800 # $1,400/month + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 1_000 + is_tanf_enrolled: true + households: + household: + members: [person1, person2] + state_code: NE + output: + spm_unit_size: 2 + ne_adc_need_standard: 741 + ne_adc_payment_standard: 408 + ne_adc_countable_earned_income: 700 + # After 50% disregard: $1,400 * 0.50 = $700 + ne_adc_income_eligible: true + ne_adc_eligible: true + ne_adc: 41 + # Gap = $741 - $700 = $41 + # Benefit = min($41, $408) = $41 + +- name: Case 6, family with both earned and unearned income. + period: 2024-01 + absolute_error_margin: 0.5 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + employment_income_before_lsr: 7_200 # $600/month earned + social_security: 2_400 # $200/month unearned + person2: + age: 10 + person3: + age: 8 + spm_units: + spm_unit: + members: [person1, person2, person3] + spm_unit_assets: 2_000 + is_tanf_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: NE + output: + spm_unit_size: 3 + ne_adc_need_standard: 881 + ne_adc_payment_standard: 485 + ne_adc_countable_earned_income: 300 + # After 50% disregard: $600 * 0.50 = $300 + ne_adc_income_eligible: true + ne_adc_eligible: true + ne_adc: 285 + # Gap = $881 - $300 = $581 + # Benefit = min($581, $485) = $485 + # Final = $485 - $200 = $285 + +- name: Case 7, small benefit after unearned income deduction. + period: 2024-01 + absolute_error_margin: 0.5 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + employment_income_before_lsr: 7_920 # $660/month earned + social_security: 4_800 # $400/month unearned + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 1_000 + is_tanf_enrolled: true + households: + household: + members: [person1, person2] + state_code: NE + output: + spm_unit_size: 2 + ne_adc_need_standard: 741 + ne_adc_payment_standard: 408 + ne_adc_countable_earned_income: 330 + # After 50% disregard: $660 * 0.50 = $330 + ne_adc_income_eligible: true + ne_adc_eligible: true + ne_adc: 8 + # Gap = $741 - $330 = $411 + # Benefit = min($411, $408) = $408 + # Final = $408 - $400 = $8 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/adc/ne_adc.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/adc/ne_adc.yaml new file mode 100644 index 00000000000..03e6d81b00e --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/adc/ne_adc.yaml @@ -0,0 +1,151 @@ +# Nebraska ADC Benefit Amount Edge Cases +# These test specific edge cases NOT covered in integration.yaml +# +# Gap Budgeting Methodology: +# Step 1: Net Earned Income = Gross Earned * (1 - disregard_rate) +# Step 2: Gap = Need Standard - Net Earned Income +# Step 3: Benefit = min(Gap, Payment Standard) +# Step 4: Final Benefit = Benefit - Unearned Income + +# ============================================================================= +# EDGE CASES - GAP BUDGETING +# ============================================================================= + +- name: Edge case, gap less than payment standard benefit equals gap. + period: 2024-01 + absolute_error_margin: 1 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 8_400 # $700/month -> $350 countable + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 1_000 + is_tanf_enrolled: true + households: + household: + members: [person1, person2] + state_code: NE + output: + ne_adc_need_standard: 741 + ne_adc_payment_standard: 408 + ne_adc_countable_earned_income: 350 + # Gross = $700, after 50% disregard = $350 + ne_adc_maximum_benefit: 391 + # Gap = $741 - $350 = $391 + # Benefit = min($391, $408) = $391 (gap < payment standard) + ne_adc: 391 + +- name: Edge case, gap greater than payment standard benefit equals payment standard. + period: 2024-01 + absolute_error_margin: 1 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 0 + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 1_000 + households: + household: + members: [person1, person2] + state_code: NE + output: + ne_adc_need_standard: 741 + ne_adc_payment_standard: 408 + ne_adc_countable_earned_income: 0 + ne_adc_maximum_benefit: 408 + # Gap = $741 - $0 = $741 + # Benefit = min($741, $408) = $408 (gap > payment standard) + ne_adc: 408 + +# ============================================================================= +# EDGE CASES - UNEARNED INCOME +# ============================================================================= + +- name: Edge case, unearned income exactly wipes out max benefit. + period: 2024-01 + absolute_error_margin: 1 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 0 + social_security: 4_896 # $408/month unearned = payment standard + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 1_000 + households: + household: + members: [person1, person2] + state_code: NE + output: + ne_adc_payment_standard: 408 + ne_adc_maximum_benefit: 408 + # Gap = $741 - $0 = $741 + # Benefit = min($741, $408) = $408 + ne_adc: 0 + # Final = $408 - $408 = $0 + +- name: Edge case, unearned income exceeds max benefit no negative. + period: 2024-01 + absolute_error_margin: 1 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 0 + social_security: 6_000 # $500/month unearned > payment standard + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 1_000 + households: + household: + members: [person1, person2] + state_code: NE + output: + ne_adc_payment_standard: 408 + ne_adc_maximum_benefit: 408 + ne_adc: 0 + # Final = $408 - $500 = -$92 -> $0 (no negative benefits) + +# ============================================================================= +# EDGE CASES - STATE RESIDENCY +# ============================================================================= + +- name: Edge case, non-Nebraska state returns zero benefit. + # Family in Texas should get zero Nebraska ADC benefit + period: 2024-01 + absolute_error_margin: 0.5 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 0 + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 1_000 + households: + household: + members: [person1, person2] + state_code: TX + output: + ne_adc: 0 + # Family in Texas, not Nebraska -> ne_adc benefit is $0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/adc/ne_adc_countable_earned_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/adc/ne_adc_countable_earned_income.yaml new file mode 100644 index 00000000000..a3398aaa3d3 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/adc/ne_adc_countable_earned_income.yaml @@ -0,0 +1,109 @@ +# Nebraska ADC Countable Earned Income Tests +# Per Neb. Rev. Stat. 68-1726(3)(a): +# - (i) Initial applicants: 20% disregard (countable = 80%) +# - (ii) Ongoing recipients: 50% disregard (countable = 50%) + +- name: Case 1, ongoing recipient 50 percent disregard. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 12_000 # $1,000/month + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + is_tanf_enrolled: true + households: + household: + members: [person1, person2] + state_code: NE + output: + ne_adc_countable_earned_income: 500 + # Gross: $1,000/month * 0.50 = $500 + +- name: Case 2, initial applicant 20 percent disregard. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 12_000 # $1,000/month + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + is_tanf_enrolled: false + households: + household: + members: [person1, person2] + state_code: NE + output: + ne_adc_countable_earned_income: 800 + # Gross: $1,000/month * 0.80 = $800 + +- name: Case 3, zero income. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 0 + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NE + output: + ne_adc_countable_earned_income: 0 + +- name: Edge case, ongoing recipient large income. + period: 2024-01 + absolute_error_margin: 0.5 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 60_000 # $5,000/month + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + is_tanf_enrolled: true + households: + household: + members: [person1, person2] + state_code: NE + output: + ne_adc_countable_earned_income: 2_500 + # Gross: $5,000/month * 0.50 = $2,500 + +- name: Edge case, initial applicant large income. + period: 2024-01 + absolute_error_margin: 0.5 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 60_000 # $5,000/month + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + is_tanf_enrolled: false + households: + household: + members: [person1, person2] + state_code: NE + output: + ne_adc_countable_earned_income: 4_000 + # Gross: $5,000/month * 0.80 = $4,000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/adc/ne_adc_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/adc/ne_adc_eligible.yaml new file mode 100644 index 00000000000..1fa4c4288de --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/adc/ne_adc_eligible.yaml @@ -0,0 +1,165 @@ +# Nebraska ADC Eligibility Tests +# Eligibility requires: +# 1. Demographic eligibility (children or pregnant) +# 2. Immigration eligibility (citizen or legal immigrant) +# 3. Income eligibility (countable income < need standard) +# 4. Resource eligibility ($4,000 for 1 person, $6,000 for 2+) +# +# NOTE: These tests focus on COMBINED eligibility checks. +# Individual component tests are in their respective files. + +- name: Case 1, no income is eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 0 + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_cash_assets: 1_000 + is_tanf_enrolled: true + households: + household: + members: [person1, person2] + state_code: NE + output: + ne_adc_income_eligible: true + ne_adc_resources_eligible: true + ne_adc_eligible: true + +- name: Case 2, income ineligible fails overall. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 24_000 # $2,000/month -> $1,000 countable + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_cash_assets: 1_000 + is_tanf_enrolled: true + households: + household: + members: [person1, person2] + state_code: NE + output: + ne_adc_income_eligible: false + ne_adc_resources_eligible: true + ne_adc_eligible: false + +- name: Case 3, resources ineligible fails overall. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 0 + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 7_000 # Above $6,000 limit + households: + household: + members: [person1, person2] + state_code: NE + output: + ne_adc_income_eligible: true + ne_adc_resources_eligible: false + ne_adc_eligible: false + +# ============================================================================= +# EDGE CASES - INITIAL VS ONGOING RECIPIENT DISREGARD +# ============================================================================= + +- name: Edge case, initial applicant fails but ongoing recipient would pass. + # Same income: initial applicant (80% countable) fails, ongoing (50% countable) passes + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 14_400 # $1,200/month gross + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_cash_assets: 1_000 + is_tanf_enrolled: false # Initial applicant + households: + household: + members: [person1, person2] + state_code: NE + output: + ne_adc_countable_earned_income: 960 + # After 20% disregard: $1,200 * 0.80 = $960 + ne_adc_income_eligible: false + # Countable ($960) > Need Standard ($741) -> FAILS + ne_adc_eligible: false + +- name: Edge case, ongoing recipient passes with same income as failing initial applicant. + # Same income as above: ongoing recipient (50% countable) passes + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 14_400 # $1,200/month gross + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_cash_assets: 1_000 + is_tanf_enrolled: true # Ongoing recipient + households: + household: + members: [person1, person2] + state_code: NE + output: + ne_adc_countable_earned_income: 600 + # After 50% disregard: $1,200 * 0.50 = $600 + ne_adc_income_eligible: true + # Countable ($600) < Need Standard ($741) -> PASSES + ne_adc_eligible: true + +# ============================================================================= +# EDGE CASES - DEMOGRAPHIC ELIGIBILITY +# ============================================================================= + +- name: Edge case, household with only adults fails demographic eligibility. + # Two adults (ages 30 and 35) with no children or pregnant persons + period: 2024-01 + absolute_error_margin: 0.5 + input: + people: + person1: + age: 30 + is_pregnant: false + employment_income_before_lsr: 0 + person2: + age: 35 + is_pregnant: false + employment_income_before_lsr: 0 + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 1_000 + households: + household: + members: [person1, person2] + state_code: NE + output: + is_demographic_tanf_eligible: false + # No eligible children (both adults over age limit) and no pregnant persons + ne_adc_eligible: false + ne_adc: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/adc/ne_adc_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/adc/ne_adc_income_eligible.yaml new file mode 100644 index 00000000000..8841e66a750 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/adc/ne_adc_income_eligible.yaml @@ -0,0 +1,120 @@ +# Nebraska ADC Income Eligibility Tests +# Per 468 NAC: countable income must be strictly less than need standard +# Countable income = countable earned + unearned income + +- name: Case 1, zero income is eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NE + output: + ne_adc_countable_income: 0 + ne_adc_need_standard: 741 + ne_adc_income_eligible: true + # Countable ($0) < Need Standard ($741) -> true + +- name: Case 2, income below threshold is eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 12_000 # $1,000/month -> $500 countable + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + is_tanf_enrolled: true + households: + household: + members: [person1, person2] + state_code: NE + output: + ne_adc_countable_income: 500 + ne_adc_need_standard: 741 + ne_adc_income_eligible: true + # Countable ($500) < Need Standard ($741) -> true + +- name: Case 3, income above threshold is ineligible. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 24_000 # $2,000/month -> $1,000 countable + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + is_tanf_enrolled: true + households: + household: + members: [person1, person2] + state_code: NE + output: + ne_adc_countable_income: 1_000 + ne_adc_need_standard: 741 + ne_adc_income_eligible: false + # Countable ($1,000) < Need Standard ($741) -> false + +- name: Case 4, income exactly at threshold is ineligible. + # Tests strict less-than comparison + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 17_784 # $1,482/month -> $741 countable + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + is_tanf_enrolled: true + households: + household: + members: [person1, person2] + state_code: NE + output: + ne_adc_countable_income: 741 + ne_adc_need_standard: 741 + ne_adc_income_eligible: false + # Countable ($741) < Need Standard ($741) -> false (not strictly less) + +- name: Case 5, mixed income at threshold is ineligible. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 6_000 # $500/month -> $250 countable earned + social_security: 5_892 # $491/month unearned + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + is_tanf_enrolled: true + households: + household: + members: [person1, person2] + state_code: NE + output: + ne_adc_countable_earned_income: 250 + ne_adc_countable_income: 741 + # Total = $250 + $491 = $741 + ne_adc_need_standard: 741 + ne_adc_income_eligible: false + # Countable ($741) < Need Standard ($741) -> false diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/adc/ne_adc_maximum_benefit.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/adc/ne_adc_maximum_benefit.yaml new file mode 100644 index 00000000000..da32ac8df4d --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/adc/ne_adc_maximum_benefit.yaml @@ -0,0 +1,110 @@ +# Nebraska ADC Maximum Benefit Tests +# Gap Budgeting Formula: +# Gap = max(Need Standard - Countable Earned Income, 0) +# Maximum Benefit = min(Gap, Payment Standard) +# +# NOTE: This is BEFORE unearned income deduction (final benefit subtracts unearned) + +- name: Case 1, zero income gap exceeds payment standard. + period: 2024-01 + absolute_error_margin: 1 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 0 + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NE + output: + ne_adc_need_standard: 741 + ne_adc_payment_standard: 408 + ne_adc_countable_earned_income: 0 + ne_adc_maximum_benefit: 408 + # Gap = $741 - $0 = $741 + # Benefit = min($741, $408) = $408 + +- name: Case 2, income reduces gap below payment standard. + period: 2024-01 + absolute_error_margin: 1 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 8_400 # $700/month -> $350 countable + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + is_tanf_enrolled: true + households: + household: + members: [person1, person2] + state_code: NE + output: + ne_adc_need_standard: 741 + ne_adc_payment_standard: 408 + ne_adc_countable_earned_income: 350 + ne_adc_maximum_benefit: 391 + # Gap = $741 - $350 = $391 + # Benefit = min($391, $408) = $391 + +- name: Case 3, high income negative gap becomes zero. + period: 2024-01 + absolute_error_margin: 1 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 24_000 # $2,000/month -> $1,000 countable + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + is_tanf_enrolled: true + households: + household: + members: [person1, person2] + state_code: NE + output: + ne_adc_need_standard: 741 + ne_adc_countable_earned_income: 1_000 + ne_adc_maximum_benefit: 0 + # Gap = $741 - $1,000 = -$259 -> max(-259, 0) = $0 + # Benefit = min($0, $408) = $0 + +- name: Case 4, larger family higher standards. + period: 2024-01 + absolute_error_margin: 1 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 12_000 # $1,000/month -> $500 countable + person2: + age: 10 + person3: + age: 8 + spm_units: + spm_unit: + members: [person1, person2, person3] + is_tanf_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: NE + output: + ne_adc_need_standard: 881 + ne_adc_payment_standard: 485 + ne_adc_countable_earned_income: 500 + ne_adc_maximum_benefit: 381 + # Gap = $881 - $500 = $381 + # Benefit = min($381, $485) = $381 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/adc/ne_adc_need_standard.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/adc/ne_adc_need_standard.yaml new file mode 100644 index 00000000000..f580e8d7c41 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/adc/ne_adc_need_standard.yaml @@ -0,0 +1,159 @@ +# Nebraska ADC Need Standard Tests +# The need standard is a lookup by family size +# Values effective July 1, 2021: +# Size 1: $601, Size 2: $741, Size 3: $881, Size 4: $1,021, etc. +# Formula: $601 + ($140 * (size - 1)) + +- name: Case 1, single person household. + period: 2024-01 + input: + people: + person1: + age: 30 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: NE + output: + ne_adc_need_standard: 601 + # Need standard for size 1 = $601 + +- name: Case 2, family of 2. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NE + output: + ne_adc_need_standard: 741 + # Need standard for size 2 = $741 + +- name: Case 3, family of 3. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 10 + person3: + age: 8 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: NE + output: + ne_adc_need_standard: 881 + # Need standard for size 3 = $881 + +- name: Case 4, family of 4. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 29 + person3: + age: 10 + person4: + age: 8 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: NE + output: + ne_adc_need_standard: 1_021 + # Need standard for size 4 = $1,021 + +- name: Case 5, large family of 7. + period: 2024-01 + input: + people: + person1: + age: 35 + person2: + age: 33 + person3: + age: 15 + person4: + age: 12 + person5: + age: 10 + person6: + age: 8 + person7: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7] + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7] + state_code: NE + output: + ne_adc_need_standard: 1_441 + # Need standard for size 7 = $1,441 + +- name: Edge case, family size 14 uses additional person increment. + period: 2024-01 + absolute_error_margin: 0.5 + input: + people: + person1: + age: 35 + person2: + age: 33 + person3: + age: 17 + person4: + age: 16 + person5: + age: 15 + person6: + age: 14 + person7: + age: 13 + person8: + age: 12 + person9: + age: 11 + person10: + age: 10 + person11: + age: 9 + person12: + age: 8 + person13: + age: 7 + person14: + age: 6 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14] + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14] + state_code: NE + output: + spm_unit_size: 14 + ne_adc_need_standard: 2_421 + # Need standard for size 14 = $1,861 + 4*$140 = $2,421 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/adc/ne_adc_payment_standard.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/adc/ne_adc_payment_standard.yaml new file mode 100644 index 00000000000..23c6f59c595 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/adc/ne_adc_payment_standard.yaml @@ -0,0 +1,88 @@ +# Nebraska ADC Payment Standard Tests +# Payment standard = Need Standard * 0.55 (55%) +# Values effective September 1, 2015: +# Size 1: $331, Size 2: $408, Size 3: $485, Size 4: $562, etc. + +- name: Case 1, single person household. + period: 2024-01 + absolute_error_margin: 1 + input: + people: + person1: + age: 30 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: NE + output: + ne_adc_payment_standard: 331 + # Need standard $601 * 0.55 = $330.55, rounded to $331 + +- name: Case 2, family of 2. + period: 2024-01 + absolute_error_margin: 1 + input: + people: + person1: + age: 30 + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NE + output: + ne_adc_payment_standard: 408 + # Need standard $741 * 0.55 = $407.55, rounded to $408 + +- name: Case 3, family of 3. + period: 2024-01 + absolute_error_margin: 1 + input: + people: + person1: + age: 30 + person2: + age: 10 + person3: + age: 8 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: NE + output: + ne_adc_payment_standard: 485 + # Need standard $881 * 0.55 = $484.55, rounded to $485 + +- name: Case 4, family of 4. + period: 2024-01 + absolute_error_margin: 1 + input: + people: + person1: + age: 30 + person2: + age: 29 + person3: + age: 10 + person4: + age: 8 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: NE + output: + ne_adc_payment_standard: 562 + # Need standard $1,021 * 0.55 = $561.55, rounded to $562 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/adc/ne_adc_resources_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/adc/ne_adc_resources_eligible.yaml new file mode 100644 index 00000000000..2d33d23ca33 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/adc/ne_adc_resources_eligible.yaml @@ -0,0 +1,86 @@ +# Nebraska ADC Resources Eligibility Tests +# Per Neb. Rev. Stat. 68-1726(1): +# - $4,000 limit for single person +# - $6,000 limit for 2+ persons + +- name: Case 1, single person at resource limit. + period: 2024-01 + input: + people: + person1: + age: 30 + is_pregnant: true + spm_units: + spm_unit: + members: [person1] + spm_unit_assets: 4_000 + households: + household: + members: [person1] + state_code: NE + output: + spm_unit_size: 1 + ne_adc_resources_eligible: true + # Resources ($4,000) <= Limit ($4,000) -> true + +- name: Case 2, single person above resource limit. + period: 2024-01 + input: + people: + person1: + age: 30 + is_pregnant: true + spm_units: + spm_unit: + members: [person1] + spm_unit_assets: 4_001 + households: + household: + members: [person1] + state_code: NE + output: + spm_unit_size: 1 + ne_adc_resources_eligible: false + # Resources ($4,001) > Limit ($4,000) -> false + +- name: Case 3, family at resource limit. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 6_000 + households: + household: + members: [person1, person2] + state_code: NE + output: + spm_unit_size: 2 + ne_adc_resources_eligible: true + # Resources ($6,000) <= Limit ($6,000) -> true + +- name: Case 4, family above resource limit. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 6_001 + households: + household: + members: [person1, person2] + state_code: NE + output: + spm_unit_size: 2 + ne_adc_resources_eligible: false + # Resources ($6,001) > Limit ($6,000) -> false diff --git a/policyengine_us/variables/gov/states/ne/dhhs/adc/benefit/ne_adc_maximum_benefit.py b/policyengine_us/variables/gov/states/ne/dhhs/adc/benefit/ne_adc_maximum_benefit.py new file mode 100644 index 00000000000..63d557068ab --- /dev/null +++ b/policyengine_us/variables/gov/states/ne/dhhs/adc/benefit/ne_adc_maximum_benefit.py @@ -0,0 +1,23 @@ +from policyengine_us.model_api import * + + +class ne_adc_maximum_benefit(Variable): + value_type = float + entity = SPMUnit + label = "Nebraska ADC maximum benefit before unearned income deduction" + unit = USD + definition_period = MONTH + reference = ( + "https://nebraskalegislature.gov/laws/statutes.php?statute=68-1713", + "https://dhhs.ne.gov/Pages/Title-468.aspx", + ) + defined_for = StateCode.NE + + def formula(spm_unit, period, parameters): + need_standard = spm_unit("ne_adc_need_standard", period) + countable_earned = spm_unit("ne_adc_countable_earned_income", period) + payment_standard = spm_unit("ne_adc_payment_standard", period) + # Gap budgeting: Gap = Standard of Need - Net Earned Income + gap = max_(need_standard - countable_earned, 0) + # Benefit = min(Gap, Payment Standard) + return min_(gap, payment_standard) diff --git a/policyengine_us/variables/gov/states/ne/dhhs/adc/benefit/ne_adc_need_standard.py b/policyengine_us/variables/gov/states/ne/dhhs/adc/benefit/ne_adc_need_standard.py new file mode 100644 index 00000000000..3afa90eb505 --- /dev/null +++ b/policyengine_us/variables/gov/states/ne/dhhs/adc/benefit/ne_adc_need_standard.py @@ -0,0 +1,27 @@ +from policyengine_us.model_api import * + + +class ne_adc_need_standard(Variable): + value_type = float + entity = SPMUnit + label = "Nebraska ADC standard of need" + unit = USD + definition_period = MONTH + reference = ( + "https://nebraskalegislature.gov/laws/statutes.php?statute=43-513", + "https://dhhs.ne.gov/Pages/Title-468.aspx", + ) + defined_for = StateCode.NE + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.ne.dhhs.adc + size = spm_unit("spm_unit_size", period.this_year) + # Parameter table defines sizes 1-10; for larger sizes, add increment per person + max_table_size = p.max_unit_size + capped_size = min_(size, max_table_size) + base_amount = p.benefit.standard_of_need.amount[capped_size] + additional_persons = max_(size - max_table_size, 0) + additional_amount = ( + additional_persons * p.benefit.standard_of_need.additional_person + ) + return base_amount + additional_amount diff --git a/policyengine_us/variables/gov/states/ne/dhhs/adc/benefit/ne_adc_payment_standard.py b/policyengine_us/variables/gov/states/ne/dhhs/adc/benefit/ne_adc_payment_standard.py new file mode 100644 index 00000000000..e56001a3b23 --- /dev/null +++ b/policyengine_us/variables/gov/states/ne/dhhs/adc/benefit/ne_adc_payment_standard.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * + + +class ne_adc_payment_standard(Variable): + value_type = float + entity = SPMUnit + label = "Nebraska ADC payment standard" + unit = USD + definition_period = MONTH + reference = ( + "https://nebraskalegislature.gov/laws/statutes.php?statute=43-512" + ) + defined_for = StateCode.NE + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.ne.dhhs.adc + need_standard = spm_unit("ne_adc_need_standard", period) + # Per Neb. Rev. Stat. 43-512: payment is 55% of standard of need + return need_standard * p.benefit.payment_standard_rate diff --git a/policyengine_us/variables/gov/states/ne/dhhs/adc/eligibility/ne_adc_eligible.py b/policyengine_us/variables/gov/states/ne/dhhs/adc/eligibility/ne_adc_eligible.py new file mode 100644 index 00000000000..3823d8fcd4f --- /dev/null +++ b/policyengine_us/variables/gov/states/ne/dhhs/adc/eligibility/ne_adc_eligible.py @@ -0,0 +1,33 @@ +from policyengine_us.model_api import * + + +class ne_adc_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Nebraska ADC eligible" + definition_period = MONTH + reference = ( + "https://dhhs.ne.gov/Pages/TANF.aspx", + "https://dhhs.ne.gov/Pages/Title-468.aspx", + ) + defined_for = StateCode.NE + + def formula(spm_unit, period, parameters): + # Use federal demographic eligibility baseline + demographic_eligible = spm_unit("is_demographic_tanf_eligible", period) + # Check immigration eligibility (at least one citizen/legal immigrant) + immigration_eligible = ( + add(spm_unit, period, ["is_citizen_or_legal_immigrant"]) > 0 + ) + # Income eligibility + income_eligible = spm_unit("ne_adc_income_eligible", period) + # Resource eligibility (YEAR variable) + resources_eligible = spm_unit( + "ne_adc_resources_eligible", period.this_year + ) + return ( + demographic_eligible + & immigration_eligible + & income_eligible + & resources_eligible + ) diff --git a/policyengine_us/variables/gov/states/ne/dhhs/adc/eligibility/ne_adc_income_eligible.py b/policyengine_us/variables/gov/states/ne/dhhs/adc/eligibility/ne_adc_income_eligible.py new file mode 100644 index 00000000000..da10b768533 --- /dev/null +++ b/policyengine_us/variables/gov/states/ne/dhhs/adc/eligibility/ne_adc_income_eligible.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * + + +class ne_adc_income_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Nebraska ADC income eligible" + definition_period = MONTH + reference = ( + "https://nebraskalegislature.gov/laws/statutes.php?statute=68-1726", + "https://dhhs.ne.gov/Pages/Title-468.aspx", + ) + defined_for = StateCode.NE + + def formula(spm_unit, period, parameters): + # Per 468 NAC: countable income must be below standard of need + countable_income = spm_unit("ne_adc_countable_income", period) + need_standard = spm_unit("ne_adc_need_standard", period) + return countable_income < need_standard diff --git a/policyengine_us/variables/gov/states/ne/dhhs/adc/eligibility/ne_adc_resources_eligible.py b/policyengine_us/variables/gov/states/ne/dhhs/adc/eligibility/ne_adc_resources_eligible.py new file mode 100644 index 00000000000..5556c4c8c75 --- /dev/null +++ b/policyengine_us/variables/gov/states/ne/dhhs/adc/eligibility/ne_adc_resources_eligible.py @@ -0,0 +1,22 @@ +from policyengine_us.model_api import * + + +class ne_adc_resources_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Nebraska ADC resources eligible" + definition_period = YEAR + reference = ( + "https://nebraskalegislature.gov/laws/statutes.php?statute=68-1726", + "https://nebraskalegislature.gov/laws/statutes.php?statute=68-1713", + ) + defined_for = StateCode.NE + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.ne.dhhs.adc + # spm_unit_assets is a YEAR variable + countable_resources = spm_unit("spm_unit_assets", period) + size = spm_unit("spm_unit_size", period) + # Resource limits: $4,000 for 1 person, $6,000 for 2+ persons + limit = p.resources.limit.calc(size) + return countable_resources <= limit diff --git a/policyengine_us/variables/gov/states/ne/dhhs/adc/income/ne_adc_countable_earned_income.py b/policyengine_us/variables/gov/states/ne/dhhs/adc/income/ne_adc_countable_earned_income.py new file mode 100644 index 00000000000..781454a5e02 --- /dev/null +++ b/policyengine_us/variables/gov/states/ne/dhhs/adc/income/ne_adc_countable_earned_income.py @@ -0,0 +1,25 @@ +from policyengine_us.model_api import * + + +class ne_adc_countable_earned_income(Variable): + value_type = float + entity = SPMUnit + label = "Nebraska ADC countable earned income" + unit = USD + definition_period = MONTH + reference = ( + "https://nebraskalegislature.gov/laws/statutes.php?statute=68-1726" + ) + defined_for = StateCode.NE + + def formula(spm_unit, period, parameters): + p = parameters( + period + ).gov.states.ne.dhhs.adc.income.earned_income_disregard + gross_earned = add(spm_unit, period, ["tanf_gross_earned_income"]) + is_enrolled = spm_unit("is_tanf_enrolled", period) + # Per Neb. Rev. Stat. 68-1726(3)(a): + # (i) 20% disregard for initial applicants + # (ii) 50% disregard for ongoing recipients + disregard_rate = where(is_enrolled, p.ongoing, p.initial) + return gross_earned * (1 - disregard_rate) diff --git a/policyengine_us/variables/gov/states/ne/dhhs/adc/income/ne_adc_countable_income.py b/policyengine_us/variables/gov/states/ne/dhhs/adc/income/ne_adc_countable_income.py new file mode 100644 index 00000000000..6344071ac7f --- /dev/null +++ b/policyengine_us/variables/gov/states/ne/dhhs/adc/income/ne_adc_countable_income.py @@ -0,0 +1,18 @@ +from policyengine_us.model_api import * + + +class ne_adc_countable_income(Variable): + value_type = float + entity = SPMUnit + label = "Nebraska ADC countable income" + unit = USD + definition_period = MONTH + reference = ( + "https://nebraskalegislature.gov/laws/statutes.php?statute=68-1726", + "https://nebraskalegislature.gov/laws/statutes.php?statute=68-1713", + ) + defined_for = StateCode.NE + adds = [ + "ne_adc_countable_earned_income", + "tanf_gross_unearned_income", + ] diff --git a/policyengine_us/variables/gov/states/ne/dhhs/adc/ne_adc.py b/policyengine_us/variables/gov/states/ne/dhhs/adc/ne_adc.py new file mode 100644 index 00000000000..0733ab3216e --- /dev/null +++ b/policyengine_us/variables/gov/states/ne/dhhs/adc/ne_adc.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * + + +class ne_adc(Variable): + value_type = float + entity = SPMUnit + label = "Nebraska Aid to Dependent Children (ADC)" + unit = USD + definition_period = MONTH + reference = ( + "https://nebraskalegislature.gov/laws/statutes.php?statute=43-512", + "https://nebraskalegislature.gov/laws/statutes.php?statute=68-1713", + ) + defined_for = "ne_adc_eligible" + + def formula(spm_unit, period, parameters): + maximum_benefit = spm_unit("ne_adc_maximum_benefit", period) + unearned = add(spm_unit, period, ["tanf_gross_unearned_income"]) + return max_(maximum_benefit - unearned, 0) diff --git a/uv.lock b/uv.lock index 03bbfcb2430..8092e2f4e8e 100644 --- a/uv.lock +++ b/uv.lock @@ -1534,7 +1534,7 @@ wheels = [ [[package]] name = "policyengine-us" -version = "1.475.0" +version = "1.477.0" source = { editable = "." } dependencies = [ { name = "microdf-python" },