diff --git a/changelog_entry.yaml b/changelog_entry.yaml index e69de29bb2d..7ed32c6dfca 100644 --- a/changelog_entry.yaml +++ b/changelog_entry.yaml @@ -0,0 +1,4 @@ +- bump: minor + changes: + added: + - Add New Hampshire FANF (Financial Assistance to Needy Families) program with eligibility determination, payment standard (60% FPG), earned income disregards, and benefit calculation. diff --git a/policyengine_us/parameters/gov/states/nh/dhhs/fanf/income/child_care_deduction/full_time.yaml b/policyengine_us/parameters/gov/states/nh/dhhs/fanf/income/child_care_deduction/full_time.yaml new file mode 100644 index 00000000000..3038aea2d40 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nh/dhhs/fanf/income/child_care_deduction/full_time.yaml @@ -0,0 +1,24 @@ +description: New Hampshire deducts up to this amount of child care expenses per child from countable income for full-time employees under the Financial Assistance to Needy Families program, depending on child age. + +metadata: + period: month + label: New Hampshire FANF child care deduction full-time per child + type: single_amount + threshold_unit: year + amount_unit: currency-USD + reference: + - title: FAM 603.05 - Child/Dependent Care Deduction (SR 12-04) + href: https://www.dhhs.nh.gov/famar_htm/html/603_05_child_dependent_care_deduction_sr_12-04_07_12_fam_a.htm + - title: New Hampshire TANF State Plan - Policy Changes (BFA SR 22-18) + href: https://www.dhhs.nh.gov/sites/g/files/ehbemt476/files/documents2/tanf-state-plan.pdf#page=25 + +brackets: + - threshold: + 2012-07-01: 0 + amount: + 2012-07-01: 200 + - threshold: + 2012-07-01: 2 + 2022-07-01: 6 + amount: + 2012-07-01: 175 diff --git a/policyengine_us/parameters/gov/states/nh/dhhs/fanf/income/child_care_deduction/full_time_threshold.yaml b/policyengine_us/parameters/gov/states/nh/dhhs/fanf/income/child_care_deduction/full_time_threshold.yaml new file mode 100644 index 00000000000..6cd3bf4fb06 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nh/dhhs/fanf/income/child_care_deduction/full_time_threshold.yaml @@ -0,0 +1,12 @@ +description: New Hampshire sets this earnings threshold to distinguish full-time from part-time employment for the child care deduction under the Financial Assistance to Needy Families program. + +values: + 2012-07-01: 377 + +metadata: + unit: currency-USD + period: month + label: New Hampshire FANF child care deduction full-time earnings threshold + reference: + - title: FAM 603.05 - Child/Dependent Care Deduction + href: https://www.dhhs.nh.gov/famar_htm/index.htm#html/603_05_child_dependent_care_deduction_sr_12-04_07_12_fam_a.htm diff --git a/policyengine_us/parameters/gov/states/nh/dhhs/fanf/income/child_care_deduction/part_time.yaml b/policyengine_us/parameters/gov/states/nh/dhhs/fanf/income/child_care_deduction/part_time.yaml new file mode 100644 index 00000000000..719a685fa01 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nh/dhhs/fanf/income/child_care_deduction/part_time.yaml @@ -0,0 +1,24 @@ +description: New Hampshire deducts up to this amount of child care expenses per child from countable income for part-time employees under the Financial Assistance to Needy Families program, depending on child age. + +metadata: + period: month + label: New Hampshire FANF child care deduction part-time per child + type: single_amount + threshold_unit: year + amount_unit: currency-USD + reference: + - title: FAM 603.05 - Child/Dependent Care Deduction (SR 12-04) + href: https://www.dhhs.nh.gov/famar_htm/html/603_05_child_dependent_care_deduction_sr_12-04_07_12_fam_a.htm + - title: New Hampshire TANF State Plan - Policy Changes (BFA SR 22-18) + href: https://www.dhhs.nh.gov/sites/g/files/ehbemt476/files/documents2/tanf-state-plan.pdf#page=25 + +brackets: + - threshold: + 2012-07-01: 0 + amount: + 2012-07-01: 100 + - threshold: + 2012-07-01: 2 + 2022-07-01: 6 + amount: + 2012-07-01: 87.5 diff --git a/policyengine_us/parameters/gov/states/nh/dhhs/fanf/income/earned_income_disregard/applicant_rate.yaml b/policyengine_us/parameters/gov/states/nh/dhhs/fanf/income/earned_income_disregard/applicant_rate.yaml new file mode 100644 index 00000000000..675b88ffe21 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nh/dhhs/fanf/income/earned_income_disregard/applicant_rate.yaml @@ -0,0 +1,14 @@ +description: New Hampshire excludes this share of earnings from countable income for applicants under the Financial Assistance to Needy Families program. + +values: + 1997-02-01: 0.2 + +metadata: + unit: /1 + period: month + label: New Hampshire FANF applicant earned income disregard rate + reference: + - title: FAM 603.01 - Earned Income Disregards (EID) + href: https://www.dhhs.nh.gov/famar_htm/html/603_01_earned_income_disregards_eid_sr_97-03_02_97_fam_a.htm + - title: SR 97-03 Dated 02/97 - TANF Implementation + href: https://www.dhhs.nh.gov/sr_htm/html/sr_97-03_dated_02_97.htm diff --git a/policyengine_us/parameters/gov/states/nh/dhhs/fanf/income/earned_income_disregard/recipient_rate.yaml b/policyengine_us/parameters/gov/states/nh/dhhs/fanf/income/earned_income_disregard/recipient_rate.yaml new file mode 100644 index 00000000000..54a48f9b3aa --- /dev/null +++ b/policyengine_us/parameters/gov/states/nh/dhhs/fanf/income/earned_income_disregard/recipient_rate.yaml @@ -0,0 +1,17 @@ +description: New Hampshire excludes this share of earnings from countable income for recipients under the Financial Assistance to Needy Families program. + +values: + 1997-02-01: 0.5 + 2022-09-01: 0.75 + +metadata: + unit: /1 + period: month + label: New Hampshire FANF recipient earned income disregard rate + reference: + - title: FAM 603.01 - Earned Income Disregards (EID) + href: https://www.dhhs.nh.gov/famar_htm/html/603_01_earned_income_disregards_eid_sr_97-03_02_97_fam_a.htm + - title: SR 97-03 Dated 02/97 - TANF Implementation + href: https://www.dhhs.nh.gov/sr_htm/html/sr_97-03_dated_02_97.htm + - title: New Hampshire TANF State Plan - Cliff Effect Initiative + href: https://www.dhhs.nh.gov/sites/g/files/ehbemt476/files/documents2/tanf-state-plan.pdf#page=29 diff --git a/policyengine_us/parameters/gov/states/nh/dhhs/fanf/payment_standard/fpg_rate.yaml b/policyengine_us/parameters/gov/states/nh/dhhs/fanf/payment_standard/fpg_rate.yaml new file mode 100644 index 00000000000..14cbf979aee --- /dev/null +++ b/policyengine_us/parameters/gov/states/nh/dhhs/fanf/payment_standard/fpg_rate.yaml @@ -0,0 +1,12 @@ +description: New Hampshire uses this multiplier of the federal poverty guideline for the payment standard under the Financial Assistance to Needy Families program. + +values: + 2017-07-01: 0.6 + +metadata: + unit: /1 + period: month + label: New Hampshire FANF payment standard FPG rate + reference: + - title: RSA 167:77-g - Adjustment of TANF Financial Assistance + href: https://gc.nh.gov/rsa/html/xii/167/167-77-g.htm diff --git a/policyengine_us/parameters/gov/states/nh/dhhs/fanf/resources/applicant_limit.yaml b/policyengine_us/parameters/gov/states/nh/dhhs/fanf/resources/applicant_limit.yaml new file mode 100644 index 00000000000..42bb90698af --- /dev/null +++ b/policyengine_us/parameters/gov/states/nh/dhhs/fanf/resources/applicant_limit.yaml @@ -0,0 +1,14 @@ +description: New Hampshire limits resources to this amount for applicants under the Financial Assistance to Needy Families program. + +values: + 1997-02-01: 1_000 + +metadata: + unit: currency-USD + period: month + label: New Hampshire FANF applicant resource limit + reference: + - title: SR 97-03 Dated 02/97 - TANF Implementation + href: https://www.dhhs.nh.gov/sr_htm/html/sr_97-03_dated_02_97.htm + - title: New Hampshire TANF State Plan - Policy Changes (BFA SR 22-17) + href: https://www.dhhs.nh.gov/sites/g/files/ehbemt476/files/documents2/tanf-state-plan.pdf#page=25 diff --git a/policyengine_us/parameters/gov/states/nh/dhhs/fanf/resources/recipient_limit.yaml b/policyengine_us/parameters/gov/states/nh/dhhs/fanf/resources/recipient_limit.yaml new file mode 100644 index 00000000000..01672b4d163 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nh/dhhs/fanf/resources/recipient_limit.yaml @@ -0,0 +1,15 @@ +description: New Hampshire limits resources to this amount for recipients under the Financial Assistance to Needy Families program. + +values: + 1997-02-01: 2_000 + 2022-07-01: 5_000 + +metadata: + unit: currency-USD + period: month + label: New Hampshire FANF recipient resource limit + reference: + - title: SR 97-03 Dated 02/97 - TANF Implementation + href: https://www.dhhs.nh.gov/sr_htm/html/sr_97-03_dated_02_97.htm + - title: New Hampshire TANF State Plan - Policy Changes (BFA SR 22-17) + href: https://www.dhhs.nh.gov/sites/g/files/ehbemt476/files/documents2/tanf-state-plan.pdf#page=25 diff --git a/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/fanf/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/fanf/integration.yaml new file mode 100644 index 00000000000..be5a4b069f4 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/fanf/integration.yaml @@ -0,0 +1,418 @@ +# Integration tests for NH FANF (Financial Assistance to Needy Families) +# Tests the complete benefit calculation pipeline with real-world scenarios +# Note: Tests default to applicant status (20% earned income disregard) +# Recipients get 75% disregard per Cliff Effect Initiative (Sept 2022) +# Sources: RSA 167:77-g; FAM 601; FAM 603; SR 97-03; BFA SR 22-28 + +- name: Case 1, single parent with one child, no income, maximum benefit. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 500 + households: + household: + members: [person1, person2] + state_code: NH + output: + nh_fanf_payment_standard: 1_022 + nh_fanf_countable_earned_income: 0 + nh_fanf_countable_income: 0 + nh_fanf_income_eligible: true + nh_fanf_resources_eligible: true + nh_fanf_eligible: true + nh_fanf: 1_022 + +- name: Case 2, applicant with earnings, 20 percent disregard. + period: 2024-01 + input: + people: + person1: + age: 28 + employment_income_before_lsr: 12_000 # $1,000/month + person2: + age: 7 + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 200 + households: + household: + members: [person1, person2] + state_code: NH + output: + nh_fanf_payment_standard: 1_022 + # Applicant: 1,000 * 0.80 = 800 + nh_fanf_countable_earned_income: 800 + nh_fanf_countable_income: 800 + nh_fanf_income_eligible: true + nh_fanf_resources_eligible: true + nh_fanf_eligible: true + # 1,022 - 800 = 222 + nh_fanf: 222 + +- name: Case 3, income above threshold, ineligible. + period: 2024-01 + input: + people: + person1: + age: 35 + employment_income_before_lsr: 36_000 # $3,000/month + person2: + age: 8 + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 0 + households: + household: + members: [person1, person2] + state_code: NH + output: + nh_fanf_payment_standard: 1_022 + # Applicant: 3,000 * 0.80 = 2,400 > 1,022 + nh_fanf_countable_earned_income: 2_400 + nh_fanf_countable_income: 2_400 + nh_fanf_income_eligible: false + nh_fanf_eligible: false + nh_fanf: 0 + +- name: Case 4, resources over limit, ineligible. + period: 2024-01 + input: + people: + person1: + age: 29 + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 2_000 + households: + household: + members: [person1, person2] + state_code: NH + output: + nh_fanf_resources_eligible: false + nh_fanf_eligible: false + nh_fanf: 0 + +- name: Case 5, SSI recipient excluded from income. + period: 2024-01 + input: + people: + person1: + age: 40 + ssi: 10_000 + person2: + age: 12 + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 300 + households: + household: + members: [person1, person2] + state_code: NH + output: + # SSI excluded + nh_fanf_countable_income: 0 + nh_fanf_eligible: true + nh_fanf: 1_022 + +- name: Case 6, earned and unearned income combined. + period: 2024-01 + input: + people: + person1: + age: 38 + employment_income_before_lsr: 9_600 # $800/month + social_security: 2_400 # $200/month + person2: + age: 36 + person3: + age: 14 + person4: + age: 10 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + spm_unit_assets: 900 + households: + household: + members: [person1, person2, person3, person4] + state_code: NH + output: + nh_fanf_payment_standard: 1_560 + # Applicant: 800 * 0.80 = 640 earned + 200 unearned = 840 + nh_fanf_countable_earned_income: 640 + nh_fanf_countable_income: 840 + nh_fanf_eligible: true + # 1,560 - 840 = 720 + nh_fanf: 720 + +- name: Case 7, recipient with 75 percent earned income disregard. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 12_000 # $1,000/month + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 500 + is_tanf_enrolled: true + households: + household: + members: [person1, person2] + state_code: NH + output: + # Recipient: 1,000 * 0.25 = 250 + nh_fanf_countable_earned_income: 250 + nh_fanf_countable_income: 250 + nh_fanf_eligible: true + # 1,022 - 250 = 772 + nh_fanf: 772 + +- name: Case 8, recipient with higher resource limit. + period: 2024-01 + input: + people: + person1: + age: 35 + person2: + age: 8 + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 3_000 + is_tanf_enrolled: true + households: + household: + members: [person1, person2] + state_code: NH + output: + # Recipient limit: $5,000; assets $3,000 passes + nh_fanf_resources_eligible: true + nh_fanf_eligible: true + nh_fanf: 1_022 + +- name: Case 9, recipient with child care deduction. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 24_000 # $2,000/month + person2: + age: 3 + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 500 + is_tanf_enrolled: true + childcare_expenses: 3_600 + households: + household: + members: [person1, person2] + state_code: NH + output: + # Recipient: 2,000 * 0.25 = 500 + # Child care: $200 + # Countable: 500 - 200 = 300 + nh_fanf_child_care_deduction: 200 + nh_fanf_countable_earned_income: 300 + nh_fanf_countable_income: 300 + nh_fanf_eligible: true + # 1,022 - 300 = 722 + nh_fanf: 722 + +- name: Case 10, large 8-person household. + period: 2024-01 + input: + people: + person1: + age: 40 + person2: + age: 38 + person3: + age: 16 + person4: + age: 14 + person5: + age: 12 + person6: + age: 10 + person7: + age: 8 + person8: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + spm_unit_assets: 800 + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + state_code: NH + output: + # 8-person payment standard: 2,636 + nh_fanf_payment_standard: 2_636 + nh_fanf_eligible: true + nh_fanf: 2_636 + +- name: Case 11, applicant with child care deduction. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 24_000 # $2,000/month + person2: + age: 3 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + spm_unit_assets: 500 + is_tanf_enrolled: false + childcare_expenses: 6_000 + households: + household: + members: [person1, person2, person3] + state_code: NH + output: + nh_fanf_payment_standard: 1_291 + # Applicant: 2,000 * 0.80 = 1,600 + # Child care: $200 (age 3) + $175 (age 7) = $375 + # Countable: 1,600 - 375 = 1,225 + nh_fanf_child_care_deduction: 375 + nh_fanf_countable_earned_income: 1_225 + nh_fanf_countable_income: 1_225 + nh_fanf_eligible: true + # 1,291 - 1,225 = 66 + nh_fanf: 66 + +- name: Case 12, child care deduction brings countable to zero. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 2_400 # $200/month + person2: + age: 3 + person3: + age: 4 + spm_units: + spm_unit: + members: [person1, person2, person3] + spm_unit_assets: 500 + is_tanf_enrolled: true + childcare_expenses: 4_800 + households: + household: + members: [person1, person2, person3] + state_code: NH + output: + nh_fanf_payment_standard: 1_291 + # Recipient: 200 * 0.25 = 50 + # Child care (part-time): 2 * $100 = $200 + # Countable: max(50 - 200, 0) = 0 + nh_fanf_child_care_deduction: 200 + nh_fanf_countable_earned_income: 0 + nh_fanf_countable_income: 0 + nh_fanf_eligible: true + nh_fanf: 1_291 + +- name: Case 13, multiple earners in household. + period: 2024-01 + input: + people: + person1: + age: 35 + employment_income_before_lsr: 6_000 # $500/month + person2: + age: 33 + employment_income_before_lsr: 6_000 # $500/month + person3: + age: 8 + spm_units: + spm_unit: + members: [person1, person2, person3] + spm_unit_assets: 500 + households: + household: + members: [person1, person2, person3] + state_code: NH + output: + nh_fanf_payment_standard: 1_291 + # Applicant: (500 + 500) * 0.80 = 800 + nh_fanf_countable_earned_income: 800 + nh_fanf_countable_income: 800 + nh_fanf_eligible: true + # 1,291 - 800 = 491 + nh_fanf: 491 + +- name: Case 14, applicant with $1000 per month earnings. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 12_000 # $1,000/month + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 500 + is_tanf_enrolled: false + households: + household: + members: [person1, person2] + state_code: NH + output: + # Applicant: 1,000 * 0.80 = 800 + nh_fanf_countable_earned_income: 800 + nh_fanf_countable_income: 800 + nh_fanf_eligible: true + # 1,022 - 800 = 222 + nh_fanf: 222 + +- name: Case 15, recipient with same $1000 per month earnings. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 12_000 # $1,000/month + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 500 + is_tanf_enrolled: true + households: + household: + members: [person1, person2] + state_code: NH + output: + # Recipient: 1,000 * 0.25 = 250 (75% disregard) + nh_fanf_countable_earned_income: 250 + nh_fanf_countable_income: 250 + nh_fanf_eligible: true + # 1,022 - 250 = 772 (vs 222 for applicant - $550 more benefit!) + nh_fanf: 772 diff --git a/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/fanf/nh_fanf.yaml b/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/fanf/nh_fanf.yaml new file mode 100644 index 00000000000..36de82bba88 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/fanf/nh_fanf.yaml @@ -0,0 +1,58 @@ +# Tests for NH FANF benefit calculation +# Formula: Benefit = max(Payment Standard - Net Countable Income, 0) +# Benefit is 0 if not eligible (handled by defined_for) +# Source: SR 97-03 Dated 02/97; FAM 603 + +- name: Case 1, maximum benefit with zero income. + period: 2024-01 + input: + state_code: NH + nh_fanf_eligible: true + nh_fanf_payment_standard: 753 + nh_fanf_countable_income: 0 + output: + # 753 - 0 = 753 + nh_fanf: 753 + +- name: Case 2, partial benefit with some income. + period: 2024-01 + input: + state_code: NH + nh_fanf_eligible: true + nh_fanf_payment_standard: 1_022 + nh_fanf_countable_income: 400 + output: + # 1,022 - 400 = 622 + nh_fanf: 622 + +- name: Case 3, income at payment standard yields zero benefit. + period: 2024-01 + input: + state_code: NH + nh_fanf_eligible: true + nh_fanf_payment_standard: 753 + nh_fanf_countable_income: 753 + output: + # 753 - 753 = 0 + nh_fanf: 0 + +- name: Case 4, ineligible gets zero benefit. + period: 2024-01 + input: + state_code: NH + nh_fanf_eligible: false + nh_fanf_payment_standard: 753 + nh_fanf_countable_income: 0 + output: + nh_fanf: 0 + +- name: Case 5, income exceeds payment standard, capped at zero. + period: 2024-01 + input: + state_code: NH + nh_fanf_eligible: true + nh_fanf_payment_standard: 753 + nh_fanf_countable_income: 800 + output: + # max(753 - 800, 0) = 0 + nh_fanf: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/fanf/nh_fanf_child_care_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/fanf/nh_fanf_child_care_deduction.yaml new file mode 100644 index 00000000000..5774df75b1e --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/fanf/nh_fanf_child_care_deduction.yaml @@ -0,0 +1,258 @@ +# Tests for NH FANF child care deduction +# Age threshold changed from 2 to 6 per BFA SR 22-18 (Eff: 07/01/22) +# Under 6: $200 FT / $100 PT +# 6+: $175 FT / $87.50 PT +# Full-time threshold: $377/month earned income +# Source: FAM 603.05; BFA SR 22-18 + +- name: Case 1, no child care expenses. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 12_000 + person2: + age: 3 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NH + output: + nh_fanf_child_care_deduction: 0 + +- name: Case 2, full-time parent with child under 6. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 6_000 # $500/month, above $377 threshold + person2: + age: 3 + spm_units: + spm_unit: + members: [person1, person2] + childcare_expenses: 3_600 # $300/month + households: + household: + members: [person1, person2] + state_code: NH + output: + # Max for full-time, under 6: $200/month + nh_fanf_child_care_deduction: 200 + +- name: Case 3, full-time parent with child age 6 plus. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 6_000 + person2: + age: 7 + spm_units: + spm_unit: + members: [person1, person2] + childcare_expenses: 3_600 + households: + household: + members: [person1, person2] + state_code: NH + output: + # Max for full-time, age 6+: $175/month + nh_fanf_child_care_deduction: 175 + +- name: Case 4, part-time parent with child under 6. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 3_600 # $300/month, below $377 threshold + person2: + age: 3 + spm_units: + spm_unit: + members: [person1, person2] + childcare_expenses: 2_400 + households: + household: + members: [person1, person2] + state_code: NH + output: + # Max for part-time, under 6: $100/month + nh_fanf_child_care_deduction: 100 + +- name: Case 5, part-time parent with child age 6 plus. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 3_600 + person2: + age: 8 + spm_units: + spm_unit: + members: [person1, person2] + childcare_expenses: 2_400 + households: + household: + members: [person1, person2] + state_code: NH + output: + # Max for part-time, age 6+: $87.50/month + nh_fanf_child_care_deduction: 87.5 + +- name: Case 6, child exactly age 6 gets 6 plus rate. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 6_000 + person2: + age: 6 + spm_units: + spm_unit: + members: [person1, person2] + childcare_expenses: 3_600 + households: + household: + members: [person1, person2] + state_code: NH + output: + # Age 6 triggers age 6+ bracket: $175 + nh_fanf_child_care_deduction: 175 + +- name: Case 7, earnings exactly at 377 threshold is full-time. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 4_524 # $377/month exactly + person2: + age: 3 + spm_units: + spm_unit: + members: [person1, person2] + childcare_expenses: 3_600 + households: + household: + members: [person1, person2] + state_code: NH + output: + # $377 >= $377 threshold = full-time rate + nh_fanf_child_care_deduction: 200 + +- name: Case 8, two children with mixed ages. + period: 2024-01 + input: + people: + person1: + age: 35 + employment_income_before_lsr: 6_000 + person2: + age: 3 + person3: + age: 8 + spm_units: + spm_unit: + members: [person1, person2, person3] + childcare_expenses: 6_000 + households: + household: + members: [person1, person2, person3] + state_code: NH + output: + # Full-time: $200 (under 6) + $175 (6+) = $375 + nh_fanf_child_care_deduction: 375 + +- name: Case 9, expenses less than maximum. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 6_000 + person2: + age: 3 + spm_units: + spm_unit: + members: [person1, person2] + childcare_expenses: 1_200 # $100/month + households: + household: + members: [person1, person2] + state_code: NH + output: + # Actual expenses: $100, max: $200 -> $100 + nh_fanf_child_care_deduction: 100 + +- name: Case 10, no children in household. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 6_000 + person2: + age: 25 + spm_units: + spm_unit: + members: [person1, person2] + childcare_expenses: 2_400 + households: + household: + members: [person1, person2] + state_code: NH + output: + # No children - no deduction + nh_fanf_child_care_deduction: 0 + +- name: Case 11, earnings $376 per month is part-time. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 4_512 # $376/month, one dollar below $377 threshold + person2: + age: 3 + spm_units: + spm_unit: + members: [person1, person2] + childcare_expenses: 3_600 + households: + household: + members: [person1, person2] + state_code: NH + output: + # $376 < $377 threshold = part-time rate ($100 for under 6) + nh_fanf_child_care_deduction: 100 + +- name: Case 12, zero earnings with childcare expenses. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 0 + person2: + age: 3 + spm_units: + spm_unit: + members: [person1, person2] + childcare_expenses: 2_400 + households: + household: + members: [person1, person2] + state_code: NH + output: + # Zero earnings = part-time rate ($100 for under 6) + nh_fanf_child_care_deduction: 100 diff --git a/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/fanf/nh_fanf_countable_earned_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/fanf/nh_fanf_countable_earned_income.yaml new file mode 100644 index 00000000000..5fd10457415 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/fanf/nh_fanf_countable_earned_income.yaml @@ -0,0 +1,129 @@ +# Tests for NH FANF countable earned income +# NH applies different earned income disregard rates: +# - Applicants: 20% disregard (keep 80%) +# - Recipients: 75% disregard (keep 25%) as of Sept 2022 Cliff Effect Initiative +# Child care deduction is also applied to earned income +# Source: SR 97-03; FAM 603.01; BFA SR 22-28 + +- name: Case 1, zero earned income. + period: 2024-01 + input: + state_code: NH + output: + nh_fanf_countable_earned_income: 0 + +- name: Case 2, applicant with earned income, 20 percent disregard. + period: 2024-01 + input: + state_code: NH + is_tanf_enrolled: false + tanf_gross_earned_income: 1_000 + output: + # Applicant: 1,000 * (1 - 0.20) = 800 + nh_fanf_countable_earned_income: 800 + +- name: Case 3, recipient with earned income, 75 percent disregard. + period: 2024-01 + input: + state_code: NH + is_tanf_enrolled: true + tanf_gross_earned_income: 1_000 + output: + # Recipient: 1,000 * (1 - 0.75) = 250 + nh_fanf_countable_earned_income: 250 + +- name: Case 4, applicant with child care deduction. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 24_000 # $2,000/month gross + person2: + age: 3 + spm_units: + spm_unit: + members: [person1, person2] + is_tanf_enrolled: false + childcare_expenses: 3_600 # $300/month + households: + household: + members: [person1, person2] + state_code: NH + output: + # Applicant: 2,000 * (1 - 0.20) = 1,600 + # Child care max (under 6, full-time): $200 + # Countable: 1,600 - 200 = 1,400 + nh_fanf_countable_earned_income: 1_400 + +- name: Case 5, recipient with child care deduction. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 24_000 + person2: + age: 3 + spm_units: + spm_unit: + members: [person1, person2] + is_tanf_enrolled: true + childcare_expenses: 3_600 + households: + household: + members: [person1, person2] + state_code: NH + output: + # Recipient: 2,000 * (1 - 0.75) = 500 + # Child care: $200 + # Countable: 500 - 200 = 300 + nh_fanf_countable_earned_income: 300 + +- name: Case 6, child care deduction exceeds income, capped at zero. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 2_400 # $200/month gross + person2: + age: 3 + spm_units: + spm_unit: + members: [person1, person2] + is_tanf_enrolled: true + childcare_expenses: 2_400 + households: + household: + members: [person1, person2] + state_code: NH + output: + # Recipient: 200 * (1 - 0.75) = 50 + # Child care (part-time): $100 + # Countable: max(50 - 100, 0) = 0 + nh_fanf_countable_earned_income: 0 + +- name: Case 7, child care deduction exactly equals after-disregard income. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 9_600 # $800/month gross + person2: + age: 3 + spm_units: + spm_unit: + members: [person1, person2] + is_tanf_enrolled: true + childcare_expenses: 3_600 + households: + household: + members: [person1, person2] + state_code: NH + output: + # Recipient: 800 * (1 - 0.75) = 200 + # Child care (full-time, under 6): $200 + # Countable: 200 - 200 = 0 + nh_fanf_countable_earned_income: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/fanf/nh_fanf_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/fanf/nh_fanf_eligible.yaml new file mode 100644 index 00000000000..a1ceea052fd --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/fanf/nh_fanf_eligible.yaml @@ -0,0 +1,133 @@ +# Tests for NH FANF overall eligibility +# Eligibility requires: income eligible AND resources eligible AND demographic eligible +# Source: RSA 167:79; FAM 203 + +- name: Case 1, all criteria met is eligible. + period: 2024-01 + input: + state_code: NH + nh_fanf_income_eligible: true + nh_fanf_resources_eligible: true + is_demographic_tanf_eligible: true + output: + nh_fanf_eligible: true + +- name: Case 2, income ineligible. + period: 2024-01 + input: + state_code: NH + nh_fanf_income_eligible: false + nh_fanf_resources_eligible: true + is_demographic_tanf_eligible: true + output: + nh_fanf_eligible: false + +- name: Case 3, resources ineligible. + period: 2024-01 + input: + state_code: NH + nh_fanf_income_eligible: true + nh_fanf_resources_eligible: false + is_demographic_tanf_eligible: true + output: + nh_fanf_eligible: false + +- name: Case 4, demographic ineligible. + period: 2024-01 + input: + state_code: NH + nh_fanf_income_eligible: true + nh_fanf_resources_eligible: true + is_demographic_tanf_eligible: false + output: + nh_fanf_eligible: false + +- name: Case 5, adults only household, no children. + period: 2024-01 + input: + people: + person1: + age: 35 + immigration_status: CITIZEN + person2: + age: 30 + immigration_status: CITIZEN + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 500 + nh_fanf_countable_income: 0 + households: + household: + members: [person1, person2] + state_code: NH + output: + # No children - demographic ineligible + nh_fanf_eligible: false + +- name: Case 6, child exactly age 17 is still a child. + period: 2024-01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + person2: + age: 17 + immigration_status: CITIZEN + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 500 + nh_fanf_countable_income: 0 + households: + household: + members: [person1, person2] + state_code: NH + output: + # Age 17 < 18 is still a child + nh_fanf_eligible: true + +- name: Case 7, child exactly age 18 is no longer a child. + period: 2024-01 + input: + people: + person1: + age: 45 + immigration_status: CITIZEN + person2: + age: 18 + immigration_status: CITIZEN + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 500 + nh_fanf_countable_income: 0 + households: + household: + members: [person1, person2] + state_code: NH + output: + # Age 18 is an adult - no dependent children + nh_fanf_eligible: false + +- name: Case 8, pregnant woman with no children is eligible. + period: 2024-01 + input: + people: + person1: + age: 25 + is_pregnant: true + immigration_status: CITIZEN + spm_units: + spm_unit: + members: [person1] + spm_unit_assets: 500 + nh_fanf_countable_income: 0 + households: + household: + members: [person1] + state_code: NH + output: + # Pregnant woman qualifies for demographic eligibility + nh_fanf_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/fanf/nh_fanf_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/fanf/nh_fanf_income_eligible.yaml new file mode 100644 index 00000000000..45e9af82c3d --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/fanf/nh_fanf_income_eligible.yaml @@ -0,0 +1,39 @@ +# Tests for NH FANF income eligibility +# Formula: Net Countable Income <= Payment Standard (60% FPG) +# Source: RSA 167:77-g; FAM 601 Table B + +- name: Case 1, zero income is eligible. + period: 2024-01 + input: + state_code: NH + nh_fanf_countable_income: 0 + nh_fanf_payment_standard: 753 + output: + nh_fanf_income_eligible: true + +- name: Case 2, income below payment standard is eligible. + period: 2024-01 + input: + state_code: NH + nh_fanf_countable_income: 500 + nh_fanf_payment_standard: 753 + output: + nh_fanf_income_eligible: true + +- name: Case 3, income equal to payment standard is eligible. + period: 2024-01 + input: + state_code: NH + nh_fanf_countable_income: 753 + nh_fanf_payment_standard: 753 + output: + nh_fanf_income_eligible: true + +- name: Case 4, income above payment standard is ineligible. + period: 2024-01 + input: + state_code: NH + nh_fanf_countable_income: 754 + nh_fanf_payment_standard: 753 + output: + nh_fanf_income_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/fanf/nh_fanf_payment_standard.yaml b/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/fanf/nh_fanf_payment_standard.yaml new file mode 100644 index 00000000000..15239a9a9aa --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/fanf/nh_fanf_payment_standard.yaml @@ -0,0 +1,116 @@ +# Tests for NH FANF payment standard +# Per RSA 167:77-g, the payment standard equals 60% of FPG for household size +# Formula: Payment Standard = FPG * 0.60 / 12 (monthly) +# 2024 FPG: First person = $15,060, Each additional = $5,380 +# Source: RSA 167:77-g; SR 24-07 Dated 03/24 + +- 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: NH + output: + # 15,060 * 0.60 / 12 = 753 + nh_fanf_payment_standard: 753 + +- name: Case 2, two person household. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NH + output: + # (15,060 + 5,380) * 0.60 / 12 = 1,022 + nh_fanf_payment_standard: 1_022 + +- name: Case 3, three person household. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 8 + person3: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: NH + output: + # (15,060 + 5,380*2) * 0.60 / 12 = 1,291 + nh_fanf_payment_standard: 1_291 + +- name: Case 4, four person household. + period: 2024-01 + input: + people: + person1: + age: 35 + person2: + age: 33 + person3: + age: 10 + person4: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: NH + output: + # (15,060 + 5,380*3) * 0.60 / 12 = 1,560 + nh_fanf_payment_standard: 1_560 + +- name: Case 5, large 8-person household. + period: 2024-01 + input: + people: + person1: + age: 40 + person2: + age: 38 + person3: + age: 16 + person4: + age: 14 + person5: + age: 12 + person6: + age: 10 + person7: + age: 8 + person8: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + state_code: NH + output: + # (15,060 + 5,380*7) * 0.60 / 12 = 2,636 + nh_fanf_payment_standard: 2_636 diff --git a/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/fanf/nh_fanf_resources_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/fanf/nh_fanf_resources_eligible.yaml new file mode 100644 index 00000000000..07179837a73 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/fanf/nh_fanf_resources_eligible.yaml @@ -0,0 +1,86 @@ +# Tests for NH FANF resources eligibility +# Resource limits differ for applicants vs recipients: +# - Applicants: $1,000 (since 1997) +# - Recipients: $5,000 (since 07/01/22, was $2,000 before) +# Source: FAM 403; SR 97-03; BFA SR 22-17 + +- name: Case 1, zero resources is eligible. + period: 2024-01 + input: + state_code: NH + spm_unit_assets: 0 + output: + nh_fanf_resources_eligible: true + +- name: Case 2, applicant resources at limit is eligible. + period: 2024-01 + input: + state_code: NH + is_tanf_enrolled: false + spm_unit_assets: 1_000 + output: + nh_fanf_resources_eligible: true + +- name: Case 3, applicant resources above limit is ineligible. + period: 2024-01 + input: + state_code: NH + is_tanf_enrolled: false + spm_unit_assets: 1_001 + output: + nh_fanf_resources_eligible: false + +- name: Case 4, recipient resources at limit is eligible. + period: 2024-01 + input: + state_code: NH + is_tanf_enrolled: true + spm_unit_assets: 5_000 + output: + nh_fanf_resources_eligible: true + +- name: Case 5, recipient resources above limit is ineligible. + period: 2024-01 + input: + state_code: NH + is_tanf_enrolled: true + spm_unit_assets: 5_001 + output: + nh_fanf_resources_eligible: false + +- name: Case 6, resources between applicant and recipient limits, applicant fails. + period: 2024-01 + input: + state_code: NH + is_tanf_enrolled: false + spm_unit_assets: 3_000 + output: + nh_fanf_resources_eligible: false + +- name: Case 7, resources between applicant and recipient limits, recipient passes. + period: 2024-01 + input: + state_code: NH + is_tanf_enrolled: true + spm_unit_assets: 3_000 + output: + nh_fanf_resources_eligible: true + +- name: Case 8, recipient zero resources is eligible. + period: 2024-01 + input: + state_code: NH + is_tanf_enrolled: true + spm_unit_assets: 0 + output: + nh_fanf_resources_eligible: true + +- name: Case 9, applicant at $999 is eligible. + period: 2024-01 + input: + state_code: NH + is_tanf_enrolled: false + spm_unit_assets: 999 + output: + # $999 < $1,000 limit = eligible + nh_fanf_resources_eligible: true diff --git a/policyengine_us/variables/gov/states/nh/dhhs/fanf/eligibility/nh_fanf_eligible.py b/policyengine_us/variables/gov/states/nh/dhhs/fanf/eligibility/nh_fanf_eligible.py new file mode 100644 index 00000000000..23f82ebed19 --- /dev/null +++ b/policyengine_us/variables/gov/states/nh/dhhs/fanf/eligibility/nh_fanf_eligible.py @@ -0,0 +1,29 @@ +from policyengine_us.model_api import * + + +class nh_fanf_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "New Hampshire FANF eligible" + definition_period = MONTH + reference = ( + "https://gc.nh.gov/rsa/html/xii/167/167-79.htm", + "https://www.dhhs.nh.gov/sr_htm/html/sr_97-03_dated_02_97.htm", + ) + defined_for = StateCode.NH + + def formula(spm_unit, period, parameters): + demographic_eligible = spm_unit("is_demographic_tanf_eligible", period) + immigration_eligible = ( + add(spm_unit, period, ["is_citizen_or_legal_immigrant"]) > 0 + ) + income_eligible = spm_unit("nh_fanf_income_eligible", period) + resources_eligible = spm_unit( + "nh_fanf_resources_eligible", period.this_year + ) + return ( + demographic_eligible + & immigration_eligible + & income_eligible + & resources_eligible + ) diff --git a/policyengine_us/variables/gov/states/nh/dhhs/fanf/eligibility/nh_fanf_income_eligible.py b/policyengine_us/variables/gov/states/nh/dhhs/fanf/eligibility/nh_fanf_income_eligible.py new file mode 100644 index 00000000000..4d4e324f316 --- /dev/null +++ b/policyengine_us/variables/gov/states/nh/dhhs/fanf/eligibility/nh_fanf_income_eligible.py @@ -0,0 +1,18 @@ +from policyengine_us.model_api import * + + +class nh_fanf_income_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "New Hampshire FANF income eligible" + definition_period = MONTH + reference = ( + "https://gc.nh.gov/rsa/html/xii/167/167-77-g.htm", + "https://www.dhhs.nh.gov/fam_htm/newfam.htm", + ) + defined_for = StateCode.NH + + def formula(spm_unit, period, parameters): + countable_income = spm_unit("nh_fanf_countable_income", period) + payment_standard = spm_unit("nh_fanf_payment_standard", period) + return countable_income <= payment_standard diff --git a/policyengine_us/variables/gov/states/nh/dhhs/fanf/eligibility/nh_fanf_resources_eligible.py b/policyengine_us/variables/gov/states/nh/dhhs/fanf/eligibility/nh_fanf_resources_eligible.py new file mode 100644 index 00000000000..8f1a36146d2 --- /dev/null +++ b/policyengine_us/variables/gov/states/nh/dhhs/fanf/eligibility/nh_fanf_resources_eligible.py @@ -0,0 +1,23 @@ +from policyengine_us.model_api import * + + +class nh_fanf_resources_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "New Hampshire FANF resources eligible" + definition_period = YEAR + reference = ( + "https://www.dhhs.nh.gov/sr_htm/html/sr_97-03_dated_02_97.htm", + "https://www.dhhs.nh.gov/fam_htm/newfam.htm", + "https://www.dhhs.nh.gov/sites/g/files/ehbemt476/files/documents2/tanf-state-plan.pdf#page=25", + ) + defined_for = StateCode.NH + + def formula(spm_unit, period, parameters): + # NOTE: One vehicle per adult is excluded regardless of value. + # Resource limits differ for applicants ($1,000) vs recipients ($5,000 as of 07/01/22) + p = parameters(period).gov.states.nh.dhhs.fanf.resources + resources = spm_unit("spm_unit_assets", period) + is_enrolled = spm_unit("is_tanf_enrolled", period) + limit = where(is_enrolled, p.recipient_limit, p.applicant_limit) + return resources <= limit diff --git a/policyengine_us/variables/gov/states/nh/dhhs/fanf/income/nh_fanf_child_care_deduction.py b/policyengine_us/variables/gov/states/nh/dhhs/fanf/income/nh_fanf_child_care_deduction.py new file mode 100644 index 00000000000..cac87672be9 --- /dev/null +++ b/policyengine_us/variables/gov/states/nh/dhhs/fanf/income/nh_fanf_child_care_deduction.py @@ -0,0 +1,40 @@ +from policyengine_us.model_api import * + + +class nh_fanf_child_care_deduction(Variable): + value_type = float + entity = SPMUnit + label = "New Hampshire FANF child/dependent care deduction" + unit = USD + definition_period = MONTH + reference = "https://www.dhhs.nh.gov/famar_htm/index.htm#html/603_05_child_dependent_care_deduction_sr_12-04_07_12_fam_a.htm" + defined_for = StateCode.NH + + def formula(spm_unit, period, parameters): + p = parameters( + period + ).gov.states.nh.dhhs.fanf.income.child_care_deduction + person = spm_unit.members + + # Determine if any earner is full-time (≥$377/month) + earned_income = person("tanf_gross_earned_income", period) + is_full_time = earned_income >= p.full_time_threshold + any_full_time = spm_unit.any(is_full_time) + + # Get child age and status + age = person("age", period.this_year) + is_child = person("is_child", period) + + # Calculate max deduction per child based on employment status and age + full_time_max = p.full_time.calc(age) + part_time_max = p.part_time.calc(age) + max_per_child = where(any_full_time, full_time_max, part_time_max) + + # Only count children + max_deduction_per_child = max_per_child * is_child + total_max_deduction = spm_unit.sum(max_deduction_per_child) + + # Cap at actual childcare expenses + childcare_expenses = spm_unit("childcare_expenses", period) + + return min_(childcare_expenses, total_max_deduction) diff --git a/policyengine_us/variables/gov/states/nh/dhhs/fanf/income/nh_fanf_countable_earned_income.py b/policyengine_us/variables/gov/states/nh/dhhs/fanf/income/nh_fanf_countable_earned_income.py new file mode 100644 index 00000000000..1a06a44afa7 --- /dev/null +++ b/policyengine_us/variables/gov/states/nh/dhhs/fanf/income/nh_fanf_countable_earned_income.py @@ -0,0 +1,33 @@ +from policyengine_us.model_api import * + + +class nh_fanf_countable_earned_income(Variable): + value_type = float + entity = SPMUnit + label = "New Hampshire FANF countable earned income" + unit = USD + definition_period = MONTH + reference = ( + "https://www.dhhs.nh.gov/famar_htm/html/603_01_earned_income_disregards_eid_sr_97-03_02_97_fam_a.htm", + "https://www.dhhs.nh.gov/sr_htm/html/sr_97-03_dated_02_97.htm", + "https://www.dhhs.nh.gov/sites/g/files/ehbemt476/files/documents2/tanf-state-plan.pdf#page=29", + ) + defined_for = StateCode.NH + + def formula(spm_unit, period, parameters): + # NH has different disregard rates for applicants (20%) vs recipients + # Recipients: 50% (1997) → 75% (Sept 2022 Cliff Effect Initiative) + # Note: A 100% disregard exists for high-demand jobs (per NH Workforce + # Innovation Opportunities Act board) with medical benefits offered, + # but this is not implemented due to lack of job classification data. + p = parameters( + period + ).gov.states.nh.dhhs.fanf.income.earned_income_disregard + gross_earned = add(spm_unit, period, ["tanf_gross_earned_income"]) + is_enrolled = spm_unit("is_tanf_enrolled", period) + disregard_rate = where(is_enrolled, p.recipient_rate, p.applicant_rate) + after_disregard = gross_earned * (1 - disregard_rate) + + # Child care deduction applies to earned income (FAM 603.05) + child_care_deduction = spm_unit("nh_fanf_child_care_deduction", period) + return max_(after_disregard - child_care_deduction, 0) diff --git a/policyengine_us/variables/gov/states/nh/dhhs/fanf/income/nh_fanf_countable_income.py b/policyengine_us/variables/gov/states/nh/dhhs/fanf/income/nh_fanf_countable_income.py new file mode 100644 index 00000000000..d705529ae2f --- /dev/null +++ b/policyengine_us/variables/gov/states/nh/dhhs/fanf/income/nh_fanf_countable_income.py @@ -0,0 +1,16 @@ +from policyengine_us.model_api import * + + +class nh_fanf_countable_income(Variable): + value_type = float + entity = SPMUnit + label = "New Hampshire FANF countable income" + unit = USD + definition_period = MONTH + reference = ( + "https://www.dhhs.nh.gov/sr_htm/html/sr_97-03_dated_02_97.htm", + "https://www.dhhs.nh.gov/fam_htm/newfam.htm", + ) + defined_for = StateCode.NH + + adds = ["nh_fanf_countable_earned_income", "tanf_gross_unearned_income"] diff --git a/policyengine_us/variables/gov/states/nh/dhhs/fanf/nh_fanf.py b/policyengine_us/variables/gov/states/nh/dhhs/fanf/nh_fanf.py new file mode 100644 index 00000000000..6bc870bfdeb --- /dev/null +++ b/policyengine_us/variables/gov/states/nh/dhhs/fanf/nh_fanf.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * + + +class nh_fanf(Variable): + value_type = float + entity = SPMUnit + label = "New Hampshire Financial Assistance to Needy Families" + unit = USD + definition_period = MONTH + reference = ( + "https://gc.nh.gov/rsa/html/xii/167/167-77-g.htm", + "https://www.dhhs.nh.gov/sr_htm/html/sr_97-03_dated_02_97.htm", + ) + defined_for = "nh_fanf_eligible" + + def formula(spm_unit, period, parameters): + payment_standard = spm_unit("nh_fanf_payment_standard", period) + countable_income = spm_unit("nh_fanf_countable_income", period) + return max_(payment_standard - countable_income, 0) diff --git a/policyengine_us/variables/gov/states/nh/dhhs/fanf/nh_fanf_payment_standard.py b/policyengine_us/variables/gov/states/nh/dhhs/fanf/nh_fanf_payment_standard.py new file mode 100644 index 00000000000..3ab62c20f0f --- /dev/null +++ b/policyengine_us/variables/gov/states/nh/dhhs/fanf/nh_fanf_payment_standard.py @@ -0,0 +1,16 @@ +from policyengine_us.model_api import * + + +class nh_fanf_payment_standard(Variable): + value_type = float + entity = SPMUnit + label = "New Hampshire FANF payment standard" + unit = USD + definition_period = MONTH + reference = "https://gc.nh.gov/rsa/html/xii/167/167-77-g.htm" + defined_for = StateCode.NH + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.nh.dhhs.fanf.payment_standard + annual_fpg = spm_unit("spm_unit_fpg", period.this_year) + return annual_fpg * p.fpg_rate / MONTHS_IN_YEAR