From 6ff55d631b659195e9d8ee0886ebf65b27c54651 Mon Sep 17 00:00:00 2001 From: Ziming Date: Wed, 10 Dec 2025 15:28:23 -0500 Subject: [PATCH 1/6] Initial commit for Utah TANF implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Starting implementation of Utah Temporary Assistance for Needy Families (TANF) program. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- changelog_entry.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/changelog_entry.yaml b/changelog_entry.yaml index e69de29bb2d..d3170193321 100644 --- a/changelog_entry.yaml +++ b/changelog_entry.yaml @@ -0,0 +1,4 @@ +- bump: minor + changes: + added: + - Adds Utah Temporary Assistance for Needy Families (TANF) program. From 28def3112e5e38f6009187e323703e59c3c656df Mon Sep 17 00:00:00 2001 From: Ziming Date: Wed, 10 Dec 2025 16:51:46 -0500 Subject: [PATCH 2/6] Add Utah TANF (Family Employment Program) implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implements Utah's Temporary Assistance for Needy Families program under the Department of Workforce Services (DWF): Variables: - ut_tanf: Final benefit calculation - ut_tanf_payment_standard: Payment standard by family size (87.5% SNB) - ut_tanf_eligible: Overall eligibility (demographic + income + resources) - ut_tanf_income_eligible: Combined gross and net income tests - ut_tanf_gross_income_eligible: Gross income <= 185% SNB - ut_tanf_net_income_eligible: Countable income < 100% SNB - ut_tanf_resource_eligible: Resources <= $2,000 - ut_tanf_countable_income: Net countable income - ut_tanf_earned_income_deduction: Work expense + 50% disregard - ut_tanf_gross_income: Gross earned + unearned income Parameters: - Payment standards by family size (1-8+) - Gross income limits (185% SNB by family size) - Net income limits (100% SNB by family size) - Work expense allowance ($100/employed person) - Earned income disregard rate (50%) - Resource limit ($2,000) Reference: Utah Admin. Code R986-200 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../earned_income_disregard/rate.yaml | 12 + .../work_expense_allowance/amount.yaml | 12 + .../income/gross_income_limit/amount.yaml | 50 +++ .../tanf/income/net_income_limit/amount.yaml | 50 +++ .../ut/dwf/tanf/payment_standard/amount.yaml | 50 +++ .../tanf/payment_standard/max_unit_size.yaml | 12 + .../ut/dwf/tanf/resources/limit/amount.yaml | 12 + .../benefit/ut_tanf_payment_standard.yaml | 73 +++++ .../tanf/eligibility/ut_tanf_eligible.yaml | 56 ++++ .../ut_tanf_gross_income_eligible.yaml | 91 +++++ .../eligibility/ut_tanf_income_eligible.yaml | 41 +++ .../ut_tanf_net_income_eligible.yaml | 84 +++++ .../ut_tanf_resource_eligible.yaml | 47 +++ .../tanf/income/ut_tanf_countable_income.yaml | 69 ++++ .../ut_tanf_earned_income_deduction.yaml | 136 ++++++++ .../gov/states/ut/dwf/tanf/integration.yaml | 310 ++++++++++++++++++ .../gov/states/ut/dwf/tanf/ut_tanf.yaml | 96 ++++++ .../dwf/tanf/eligibility/ut_tanf_eligible.py | 19 ++ .../ut_tanf_gross_income_eligible.py | 23 ++ .../eligibility/ut_tanf_income_eligible.py | 18 + .../ut_tanf_net_income_eligible.py | 23 ++ .../eligibility/ut_tanf_resource_eligible.py | 18 + .../tanf/income/ut_tanf_countable_income.py | 22 ++ .../income/ut_tanf_earned_income_deduction.py | 40 +++ .../dwf/tanf/income/ut_tanf_gross_income.py | 18 + .../gov/states/ut/dwf/tanf/ut_tanf.py | 19 ++ .../ut/dwf/tanf/ut_tanf_payment_standard.py | 19 ++ 27 files changed, 1420 insertions(+) create mode 100644 policyengine_us/parameters/gov/states/ut/dwf/tanf/income/deductions/earned_income_disregard/rate.yaml create mode 100644 policyengine_us/parameters/gov/states/ut/dwf/tanf/income/deductions/work_expense_allowance/amount.yaml create mode 100644 policyengine_us/parameters/gov/states/ut/dwf/tanf/income/gross_income_limit/amount.yaml create mode 100644 policyengine_us/parameters/gov/states/ut/dwf/tanf/income/net_income_limit/amount.yaml create mode 100644 policyengine_us/parameters/gov/states/ut/dwf/tanf/payment_standard/amount.yaml create mode 100644 policyengine_us/parameters/gov/states/ut/dwf/tanf/payment_standard/max_unit_size.yaml create mode 100644 policyengine_us/parameters/gov/states/ut/dwf/tanf/resources/limit/amount.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/benefit/ut_tanf_payment_standard.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_eligible.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_gross_income_eligible.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_income_eligible.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_net_income_eligible.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_resource_eligible.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/income/ut_tanf_countable_income.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/income/ut_tanf_earned_income_deduction.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/integration.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/ut_tanf.yaml create mode 100644 policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_eligible.py create mode 100644 policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_gross_income_eligible.py create mode 100644 policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_income_eligible.py create mode 100644 policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_net_income_eligible.py create mode 100644 policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_resource_eligible.py create mode 100644 policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_countable_income.py create mode 100644 policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_earned_income_deduction.py create mode 100644 policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_gross_income.py create mode 100644 policyengine_us/variables/gov/states/ut/dwf/tanf/ut_tanf.py create mode 100644 policyengine_us/variables/gov/states/ut/dwf/tanf/ut_tanf_payment_standard.py diff --git a/policyengine_us/parameters/gov/states/ut/dwf/tanf/income/deductions/earned_income_disregard/rate.yaml b/policyengine_us/parameters/gov/states/ut/dwf/tanf/income/deductions/earned_income_disregard/rate.yaml new file mode 100644 index 00000000000..ecd824aa11a --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dwf/tanf/income/deductions/earned_income_disregard/rate.yaml @@ -0,0 +1,12 @@ +description: Utah disregards this share of remaining earned income after the work expense allowance under the Family Employment Program. + +metadata: + unit: /1 + period: month + label: Utah FEP earned income disregard rate + reference: + - title: Utah Admin Code R986-200-239 + href: https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules + +values: + 2022-10-01: 0.5 diff --git a/policyengine_us/parameters/gov/states/ut/dwf/tanf/income/deductions/work_expense_allowance/amount.yaml b/policyengine_us/parameters/gov/states/ut/dwf/tanf/income/deductions/work_expense_allowance/amount.yaml new file mode 100644 index 00000000000..55cc9ddb674 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dwf/tanf/income/deductions/work_expense_allowance/amount.yaml @@ -0,0 +1,12 @@ +description: Utah deducts this work expense allowance per employed person from earned income under the Family Employment Program. + +metadata: + unit: currency-USD + period: month + label: Utah FEP work expense allowance amount + reference: + - title: Utah Admin Code R986-200-239 + href: https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules + +values: + 2022-10-01: 100 diff --git a/policyengine_us/parameters/gov/states/ut/dwf/tanf/income/gross_income_limit/amount.yaml b/policyengine_us/parameters/gov/states/ut/dwf/tanf/income/gross_income_limit/amount.yaml new file mode 100644 index 00000000000..d5d50561496 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dwf/tanf/income/gross_income_limit/amount.yaml @@ -0,0 +1,50 @@ +description: Utah limits the Family Employment Program to households with gross income at or below this amount, based on household size. + +metadata: + unit: currency-USD + period: month + breakdown: + - range(1, 20) + label: Utah FEP gross income limit amount + reference: + - title: Utah Admin Code R986-200-238 + href: https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules + +1: + 2022-10-01: 608 +2: + 2022-10-01: 843 +3: + 2022-10-01: 1_050 +4: + 2022-10-01: 1_230 +5: + 2022-10-01: 1_400 +6: + 2022-10-01: 1_542 +7: + 2022-10-01: 1_615 +8: + 2022-10-01: 1_690 +9: + 2022-10-01: 1_765 +10: + 2022-10-01: 1_840 +11: + 2022-10-01: 1_915 +12: + 2022-10-01: 1_990 +13: + 2022-10-01: 2_065 +14: + 2022-10-01: 2_140 +15: + 2022-10-01: 2_215 +16: + 2022-10-01: 2_290 +17: + 2022-10-01: 2_365 +18: + 2022-10-01: 2_440 +19: + 2022-10-01: 2_515 diff --git a/policyengine_us/parameters/gov/states/ut/dwf/tanf/income/net_income_limit/amount.yaml b/policyengine_us/parameters/gov/states/ut/dwf/tanf/income/net_income_limit/amount.yaml new file mode 100644 index 00000000000..3a5aebdf670 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dwf/tanf/income/net_income_limit/amount.yaml @@ -0,0 +1,50 @@ +description: Utah limits the Family Employment Program to households with net countable income below this amount, based on household size. + +metadata: + unit: currency-USD + period: month + breakdown: + - range(1, 20) + label: Utah FEP net income limit amount + reference: + - title: Utah Admin Code R986-200-238 + href: https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules + +1: + 2022-10-01: 329 +2: + 2022-10-01: 456 +3: + 2022-10-01: 568 +4: + 2022-10-01: 665 +5: + 2022-10-01: 757 +6: + 2022-10-01: 834 +7: + 2022-10-01: 873 +8: + 2022-10-01: 914 +9: + 2022-10-01: 955 +10: + 2022-10-01: 996 +11: + 2022-10-01: 1_037 +12: + 2022-10-01: 1_078 +13: + 2022-10-01: 1_119 +14: + 2022-10-01: 1_160 +15: + 2022-10-01: 1_201 +16: + 2022-10-01: 1_242 +17: + 2022-10-01: 1_283 +18: + 2022-10-01: 1_324 +19: + 2022-10-01: 1_365 diff --git a/policyengine_us/parameters/gov/states/ut/dwf/tanf/payment_standard/amount.yaml b/policyengine_us/parameters/gov/states/ut/dwf/tanf/payment_standard/amount.yaml new file mode 100644 index 00000000000..e45dd03d46e --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dwf/tanf/payment_standard/amount.yaml @@ -0,0 +1,50 @@ +description: Utah provides up to this maximum benefit amount under the Family Employment Program, based on household size. + +metadata: + unit: currency-USD + period: month + breakdown: + - range(1, 20) + label: Utah FEP maximum benefit amount + reference: + - title: Utah Admin Code R986-200-246 + href: https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules + +1: + 2022-10-01: 383 +2: + 2022-10-01: 531 +3: + 2022-10-01: 662 +4: + 2022-10-01: 775 +5: + 2022-10-01: 882 +6: + 2022-10-01: 972 +7: + 2022-10-01: 1_017 +8: + 2022-10-01: 1_065 +9: + 2022-10-01: 1_113 +10: + 2022-10-01: 1_161 +11: + 2022-10-01: 1_209 +12: + 2022-10-01: 1_257 +13: + 2022-10-01: 1_305 +14: + 2022-10-01: 1_353 +15: + 2022-10-01: 1_401 +16: + 2022-10-01: 1_449 +17: + 2022-10-01: 1_497 +18: + 2022-10-01: 1_545 +19: + 2022-10-01: 1_593 diff --git a/policyengine_us/parameters/gov/states/ut/dwf/tanf/payment_standard/max_unit_size.yaml b/policyengine_us/parameters/gov/states/ut/dwf/tanf/payment_standard/max_unit_size.yaml new file mode 100644 index 00000000000..bff3776f0e9 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dwf/tanf/payment_standard/max_unit_size.yaml @@ -0,0 +1,12 @@ +description: Utah defines the Family Employment Program payment schedule up to this maximum household size. + +metadata: + unit: person + period: month + label: Utah FEP maximum unit size for payment schedule + reference: + - title: Utah Admin Code R986-200-246 + href: https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules + +values: + 2022-10-01: 19 diff --git a/policyengine_us/parameters/gov/states/ut/dwf/tanf/resources/limit/amount.yaml b/policyengine_us/parameters/gov/states/ut/dwf/tanf/resources/limit/amount.yaml new file mode 100644 index 00000000000..b95fa29919c --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dwf/tanf/resources/limit/amount.yaml @@ -0,0 +1,12 @@ +description: Utah limits the Family Employment Program to households with countable resources at or below this amount. + +metadata: + unit: currency-USD + period: month + label: Utah FEP resource limit amount + reference: + - title: Utah Admin Code R986-200-240 + href: https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules + +values: + 2022-10-01: 2_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/benefit/ut_tanf_payment_standard.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/benefit/ut_tanf_payment_standard.yaml new file mode 100644 index 00000000000..84ec5f48399 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/benefit/ut_tanf_payment_standard.yaml @@ -0,0 +1,73 @@ +# Unit tests for ut_tanf_payment_standard (maximum benefit by family size) +# Payment standard is 87.5% of Standard Needs Budget (SNB) +# Reference: Utah Admin. Code R986-200-239 +# Source: https://jobs.utah.gov/Infosource/eligibilitymanual/Tables +# +# 2022 Payment Standards (87.5% SNB): +# Size 1: $383, Size 2: $531, Size 3: $662 +# Size 4: $775, Size 5: $882, Size 6: $972 +# Size 7: $1,017, Size 8: $1,065 + +- name: Family size 1 - payment standard $383. + period: 2024-01 + input: + state_code: UT + spm_unit_size: 1 + output: + ut_tanf_payment_standard: 383 + +- name: Family size 2 - payment standard $531. + period: 2024-01 + input: + state_code: UT + spm_unit_size: 2 + output: + ut_tanf_payment_standard: 531 + +- name: Family size 3 - payment standard $662. + period: 2024-01 + input: + state_code: UT + spm_unit_size: 3 + output: + ut_tanf_payment_standard: 662 + +- name: Family size 4 - payment standard $775. + period: 2024-01 + input: + state_code: UT + spm_unit_size: 4 + output: + ut_tanf_payment_standard: 775 + +- name: Family size 5 - payment standard $882. + period: 2024-01 + input: + state_code: UT + spm_unit_size: 5 + output: + ut_tanf_payment_standard: 882 + +- name: Family size 6 - payment standard $972. + period: 2024-01 + input: + state_code: UT + spm_unit_size: 6 + output: + ut_tanf_payment_standard: 972 + +- name: Family size 7 - payment standard $1,017. + period: 2024-01 + input: + state_code: UT + spm_unit_size: 7 + output: + ut_tanf_payment_standard: 1_017 + +- name: Family size 8 - payment standard $1,065. + period: 2024-01 + input: + state_code: UT + spm_unit_size: 8 + output: + ut_tanf_payment_standard: 1_065 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_eligible.yaml new file mode 100644 index 00000000000..e467eda5594 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_eligible.yaml @@ -0,0 +1,56 @@ +# Unit tests for ut_tanf_eligible (final eligibility determination) +# Utah TANF eligibility requires: +# - Demographic eligibility (uses federal baseline) +# - Income eligibility (gross and net tests) +# - Resource eligibility +# Reference: Utah Admin. Code R986-200 + +- name: All eligibility criteria met - eligible. + period: 2024-01 + input: + state_code: UT + is_demographic_tanf_eligible: true + ut_tanf_income_eligible: true + ut_tanf_resource_eligible: true + output: + ut_tanf_eligible: true + +- name: Demographic ineligible - not eligible. + period: 2024-01 + input: + state_code: UT + is_demographic_tanf_eligible: false + ut_tanf_income_eligible: true + ut_tanf_resource_eligible: true + output: + ut_tanf_eligible: false + +- name: Income ineligible - not eligible. + period: 2024-01 + input: + state_code: UT + is_demographic_tanf_eligible: true + ut_tanf_income_eligible: false + ut_tanf_resource_eligible: true + output: + ut_tanf_eligible: false + +- name: Resource ineligible - not eligible. + period: 2024-01 + input: + state_code: UT + is_demographic_tanf_eligible: true + ut_tanf_income_eligible: true + ut_tanf_resource_eligible: false + output: + ut_tanf_eligible: false + +- name: All criteria not met - not eligible. + period: 2024-01 + input: + state_code: UT + is_demographic_tanf_eligible: false + ut_tanf_income_eligible: false + ut_tanf_resource_eligible: false + output: + ut_tanf_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_gross_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_gross_income_eligible.yaml new file mode 100644 index 00000000000..5c4e9ce608b --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_gross_income_eligible.yaml @@ -0,0 +1,91 @@ +# Unit tests for ut_tanf_gross_income_eligible (185% SNB gross income test) +# Gross income must be <= 185% of Standard Needs Budget +# Reference: Utah Admin. Code R986-200-239 +# +# 2022 Gross Income Limits (185% SNB): +# Size 1: $608, Size 2: $843, Size 3: $1,050 +# Size 4: $1,230, Size 5: $1,400, Size 6: $1,542 + +- name: Gross income zero - eligible (family size 3). + period: 2024-01 + input: + state_code: UT + spm_unit_size: 3 + tanf_gross_earned_income: 0 + tanf_gross_unearned_income: 0 + output: + # Gross limit for size 3 = $1,050 + # Gross income = 0 <= 1,050 - eligible + ut_tanf_gross_income_eligible: true + +- name: Gross income below limit - eligible (family size 3). + period: 2024-01 + input: + state_code: UT + spm_unit_size: 3 + tanf_gross_earned_income: 500 + tanf_gross_unearned_income: 200 + output: + # Gross limit for size 3 = $1,050 + # Gross income = 500 + 200 = 700 <= 1,050 - eligible + ut_tanf_gross_income_eligible: true + +- name: Gross income at limit - eligible (family size 3). + period: 2024-01 + input: + state_code: UT + spm_unit_size: 3 + tanf_gross_earned_income: 800 + tanf_gross_unearned_income: 250 + output: + # Gross limit for size 3 = $1,050 + # Gross income = 800 + 250 = 1,050 <= 1,050 - eligible + ut_tanf_gross_income_eligible: true + +- name: Gross income above limit - ineligible (family size 3). + period: 2024-01 + input: + state_code: UT + spm_unit_size: 3 + tanf_gross_earned_income: 900 + tanf_gross_unearned_income: 200 + output: + # Gross limit for size 3 = $1,050 + # Gross income = 900 + 200 = 1,100 > 1,050 - ineligible + ut_tanf_gross_income_eligible: false + +- name: Gross income at limit for family size 1. + period: 2024-01 + input: + state_code: UT + spm_unit_size: 1 + tanf_gross_earned_income: 608 + tanf_gross_unearned_income: 0 + output: + # Gross limit for size 1 = $608 + # Gross income = 608 <= 608 - eligible + ut_tanf_gross_income_eligible: true + +- name: Gross income above limit for family size 1. + period: 2024-01 + input: + state_code: UT + spm_unit_size: 1 + tanf_gross_earned_income: 609 + tanf_gross_unearned_income: 0 + output: + # Gross limit for size 1 = $608 + # Gross income = 609 > 608 - ineligible + ut_tanf_gross_income_eligible: false + +- name: Larger family size 5 with income at limit. + period: 2024-01 + input: + state_code: UT + spm_unit_size: 5 + tanf_gross_earned_income: 1_000 + tanf_gross_unearned_income: 400 + output: + # Gross limit for size 5 = $1,400 + # Gross income = 1,000 + 400 = 1,400 <= 1,400 - eligible + ut_tanf_gross_income_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_income_eligible.yaml new file mode 100644 index 00000000000..5ba7036997c --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_income_eligible.yaml @@ -0,0 +1,41 @@ +# Unit tests for ut_tanf_income_eligible (combined income eligibility) +# Utah uses a two-step income test: +# 1. Gross income must be <= 185% of SNB +# 2. Net income must be < 100% of SNB +# Reference: Utah Admin. Code R986-200-239 + +- name: Both gross and net income eligible - income eligible. + period: 2024-01 + input: + state_code: UT + ut_tanf_gross_income_eligible: true + ut_tanf_net_income_eligible: true + output: + ut_tanf_income_eligible: true + +- name: Gross income eligible but net income ineligible - not eligible. + period: 2024-01 + input: + state_code: UT + ut_tanf_gross_income_eligible: true + ut_tanf_net_income_eligible: false + output: + ut_tanf_income_eligible: false + +- name: Net income eligible but gross income ineligible - not eligible. + period: 2024-01 + input: + state_code: UT + ut_tanf_gross_income_eligible: false + ut_tanf_net_income_eligible: true + output: + ut_tanf_income_eligible: false + +- name: Both gross and net income ineligible - not eligible. + period: 2024-01 + input: + state_code: UT + ut_tanf_gross_income_eligible: false + ut_tanf_net_income_eligible: false + output: + ut_tanf_income_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_net_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_net_income_eligible.yaml new file mode 100644 index 00000000000..ce8c026300b --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_net_income_eligible.yaml @@ -0,0 +1,84 @@ +# Unit tests for ut_tanf_net_income_eligible (100% SNB net income test) +# Net income must be < 100% of Standard Needs Budget (strict less than) +# Reference: Utah Admin. Code R986-200-239 +# +# 2022 Net Income Limits (100% SNB): +# Size 1: $329, Size 2: $456, Size 3: $568 +# Size 4: $665, Size 5: $757, Size 6: $834 + +- name: Net income zero - eligible (family size 3). + period: 2024-01 + input: + state_code: UT + spm_unit_size: 3 + ut_tanf_countable_income: 0 + output: + # Net limit for size 3 = $568 + # Net income = 0 < 568 - eligible + ut_tanf_net_income_eligible: true + +- name: Net income below limit - eligible (family size 3). + period: 2024-01 + input: + state_code: UT + spm_unit_size: 3 + ut_tanf_countable_income: 400 + output: + # Net limit for size 3 = $568 + # Net income = 400 < 568 - eligible + ut_tanf_net_income_eligible: true + +- name: Net income at limit - ineligible (family size 3). + period: 2024-01 + input: + state_code: UT + spm_unit_size: 3 + ut_tanf_countable_income: 568 + output: + # Net limit for size 3 = $568 + # Net income = 568 NOT < 568 - ineligible (strict less than) + ut_tanf_net_income_eligible: false + +- name: Net income above limit - ineligible (family size 3). + period: 2024-01 + input: + state_code: UT + spm_unit_size: 3 + ut_tanf_countable_income: 600 + output: + # Net limit for size 3 = $568 + # Net income = 600 > 568 - ineligible + ut_tanf_net_income_eligible: false + +- name: Net income just below limit - eligible (family size 3). + period: 2024-01 + input: + state_code: UT + spm_unit_size: 3 + ut_tanf_countable_income: 567 + output: + # Net limit for size 3 = $568 + # Net income = 567 < 568 - eligible + ut_tanf_net_income_eligible: true + +- name: Net income at limit for family size 1. + period: 2024-01 + input: + state_code: UT + spm_unit_size: 1 + ut_tanf_countable_income: 329 + output: + # Net limit for size 1 = $329 + # Net income = 329 NOT < 329 - ineligible (strict less than) + ut_tanf_net_income_eligible: false + +- name: Net income below limit for family size 5. + period: 2024-01 + input: + state_code: UT + spm_unit_size: 5 + ut_tanf_countable_income: 500 + output: + # Net limit for size 5 = $757 + # Net income = 500 < 757 - eligible + ut_tanf_net_income_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_resource_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_resource_eligible.yaml new file mode 100644 index 00000000000..fc7e17d9a27 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_resource_eligible.yaml @@ -0,0 +1,47 @@ +# Unit tests for ut_tanf_resource_eligible (resource/asset test) +# Countable resources must not exceed $2,000 +# Reference: Utah Admin. Code R986-200-230 + +- name: No resources - eligible. + period: 2024-01 + input: + state_code: UT + spm_unit_assets: 0 + output: + ut_tanf_resource_eligible: true + +- name: Resources below limit - eligible. + period: 2024-01 + input: + state_code: UT + spm_unit_assets: 1_500 + output: + # Resources = 1,500 <= 2,000 - eligible + ut_tanf_resource_eligible: true + +- name: Resources at limit - eligible. + period: 2024-01 + input: + state_code: UT + spm_unit_assets: 2_000 + output: + # Resources = 2,000 <= 2,000 - eligible + ut_tanf_resource_eligible: true + +- name: Resources above limit - ineligible. + period: 2024-01 + input: + state_code: UT + spm_unit_assets: 2_001 + output: + # Resources = 2,001 > 2,000 - ineligible + ut_tanf_resource_eligible: false + +- name: Resources significantly above limit - ineligible. + period: 2024-01 + input: + state_code: UT + spm_unit_assets: 5_000 + output: + # Resources = 5,000 > 2,000 - ineligible + ut_tanf_resource_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/income/ut_tanf_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/income/ut_tanf_countable_income.yaml new file mode 100644 index 00000000000..4f35a52c3e8 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/income/ut_tanf_countable_income.yaml @@ -0,0 +1,69 @@ +# Unit tests for ut_tanf_countable_income (net countable income calculation) +# Countable income = earned income after deductions + unearned income +# Reference: Utah Admin. Code R986-200-239 + +- name: No income - zero countable income. + period: 2024-01 + input: + state_code: UT + ut_tanf_earned_income_deduction: 0 + tanf_gross_earned_income: 0 + tanf_gross_unearned_income: 0 + output: + # Countable = (0 - 0) + 0 = 0 + ut_tanf_countable_income: 0 + +- name: Earned income only with deductions. + period: 2024-01 + input: + state_code: UT + ut_tanf_earned_income_deduction: 350 + tanf_gross_earned_income: 600 + tanf_gross_unearned_income: 0 + output: + # Countable = max(600 - 350, 0) + 0 = 250 + ut_tanf_countable_income: 250 + +- name: Unearned income only. + period: 2024-01 + input: + state_code: UT + ut_tanf_earned_income_deduction: 0 + tanf_gross_earned_income: 0 + tanf_gross_unearned_income: 300 + output: + # Countable = 0 + 300 = 300 + ut_tanf_countable_income: 300 + +- name: Both earned and unearned income. + period: 2024-01 + input: + state_code: UT + ut_tanf_earned_income_deduction: 350 + tanf_gross_earned_income: 800 + tanf_gross_unearned_income: 150 + output: + # Countable = max(800 - 350, 0) + 150 = 450 + 150 = 600 + ut_tanf_countable_income: 600 + +- name: Earned income deduction exceeds earned income. + period: 2024-01 + input: + state_code: UT + ut_tanf_earned_income_deduction: 400 + tanf_gross_earned_income: 200 + tanf_gross_unearned_income: 100 + output: + # Countable = max(200 - 400, 0) + 100 = 0 + 100 = 100 + ut_tanf_countable_income: 100 + +- name: Large earned income with full deductions. + period: 2024-01 + input: + state_code: UT + ut_tanf_earned_income_deduction: 500 + tanf_gross_earned_income: 1_000 + tanf_gross_unearned_income: 200 + output: + # Countable = max(1,000 - 500, 0) + 200 = 500 + 200 = 700 + ut_tanf_countable_income: 700 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/income/ut_tanf_earned_income_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/income/ut_tanf_earned_income_deduction.yaml new file mode 100644 index 00000000000..1119d5815f5 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/income/ut_tanf_earned_income_deduction.yaml @@ -0,0 +1,136 @@ +# Unit tests for ut_tanf_earned_income_deduction (earned income deductions) +# Utah applies two earned income deductions: +# 1. Work expense allowance: $100 per employed person +# 2. 50% earned income disregard on remaining earned income +# Formula: work_expense + 0.50 * max(earned_income - work_expense, 0) +# Reference: Utah Admin. Code R986-200-239(2)(a) and R986-200-239(2)(b) + +- name: No earned income - zero deduction. + period: 2024-01 + input: + people: + person1: + tanf_gross_earned_income: 0 + person2: + tanf_gross_earned_income: 0 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + # No earnings = no deduction + ut_tanf_earned_income_deduction: 0 + +- name: Single employed person with $500 earnings. + period: 2024-01 + input: + people: + person1: + tanf_gross_earned_income: 500 + person2: + tanf_gross_earned_income: 0 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + # 1 employed person: work_expense = $100 + # After work expense = max(500 - 100, 0) = 400 + # 50% disregard = 400 * 0.50 = 200 + # Total deduction = 100 + 200 = 300 + ut_tanf_earned_income_deduction: 300 + +- name: Single employed person with $1,000 earnings. + period: 2024-01 + input: + people: + person1: + tanf_gross_earned_income: 1_000 + person2: + tanf_gross_earned_income: 0 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + # 1 employed person: work_expense = $100 + # After work expense = max(1,000 - 100, 0) = 900 + # 50% disregard = 900 * 0.50 = 450 + # Total deduction = 100 + 450 = 550 + ut_tanf_earned_income_deduction: 550 + +- name: Two employed persons with earnings. + period: 2024-01 + input: + people: + person1: + tanf_gross_earned_income: 600 + person2: + tanf_gross_earned_income: 400 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + # 2 employed persons: work_expense = $200 (100 * 2) + # Total earnings = 600 + 400 = 1,000 + # After work expense = max(1,000 - 200, 0) = 800 + # 50% disregard = 800 * 0.50 = 400 + # Total deduction = 200 + 400 = 600 + ut_tanf_earned_income_deduction: 600 + +- name: Earnings less than work expense deduction. + period: 2024-01 + input: + people: + person1: + tanf_gross_earned_income: 80 + person2: + tanf_gross_earned_income: 0 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + # 1 employed person: work_expense = $100 + # After work expense = max(80 - 100, 0) = 0 + # 50% disregard = 0 * 0.50 = 0 + # Total deduction = 80 (capped at earnings, cannot exceed earnings) + ut_tanf_earned_income_deduction: 80 + +- name: Earnings exactly equal to work expense. + period: 2024-01 + input: + people: + person1: + tanf_gross_earned_income: 100 + person2: + tanf_gross_earned_income: 0 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + # 1 employed person: work_expense = $100 + # After work expense = max(100 - 100, 0) = 0 + # 50% disregard = 0 * 0.50 = 0 + # Total deduction = 100 + ut_tanf_earned_income_deduction: 100 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/integration.yaml new file mode 100644 index 00000000000..a219f30a820 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/integration.yaml @@ -0,0 +1,310 @@ +# Integration tests for Utah TANF (Family Employment Program) +# Tests the complete benefit calculation pipeline from inputs to final benefit +# Reference: Utah Admin. Code R986-200 +# +# Key Program Parameters (October 2022): +# - Gross income limit: 185% of Standard Needs Budget (SNB) +# - Net income limit: 100% of SNB (strict less than) +# - Payment standard: 87.5% of SNB +# - Work expense deduction: $100 per employed person +# - Earned income disregard: 50% of remaining earned income +# - Resource limit: $2,000 + +- name: Case 1 - Single parent with one child, no income, receives maximum benefit. + period: 2024-01 + input: + people: + person1: + age: 30 + tanf_gross_earned_income: 0 + tanf_gross_unearned_income: 0 + person2: + age: 5 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 500 + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + # Family size = 2 + # Gross income = 0, Gross limit = $843 -> PASS + # No earnings, so no deductions + # Countable income = 0, Net limit = $456 -> PASS + # Resources = $500 <= $2,000 -> PASS + # Eligible = true + # Benefit = Payment standard ($531) - Countable income (0) = $531 + ut_tanf_payment_standard: 531 + ut_tanf_gross_income_eligible: true + ut_tanf_countable_income: 0 + ut_tanf_net_income_eligible: true + ut_tanf_resource_eligible: true + ut_tanf_income_eligible: true + ut_tanf_eligible: true + ut_tanf: 531 + +- name: Case 2 - Single parent with two children, moderate earnings, partial benefit. + period: 2024-01 + input: + people: + person1: + age: 28 + tanf_gross_earned_income: 600 + tanf_gross_unearned_income: 0 + person2: + age: 8 + is_tax_unit_dependent: true + person3: + age: 4 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2, person3] + spm_unit_assets: 1_000 + tax_units: + tax_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: UT + output: + # Family size = 3 + # Gross income = $600, Gross limit = $1,050 -> PASS + # Work expense = $100 (1 employed person) + # After work expense = $600 - $100 = $500 + # 50% disregard = $500 * 0.50 = $250 + # Total deduction = $100 + $250 = $350 + # Countable income = $600 - $350 = $250 + # Net limit = $568 (100% SNB), $250 < $568 -> PASS + # Resources = $1,000 <= $2,000 -> PASS + # Eligible = true + # Benefit = Payment standard ($662) - Countable income ($250) = $412 + ut_tanf_payment_standard: 662 + ut_tanf_earned_income_deduction: 350 + ut_tanf_gross_income_eligible: true + ut_tanf_countable_income: 250 + ut_tanf_net_income_eligible: true + ut_tanf_resource_eligible: true + ut_tanf_income_eligible: true + ut_tanf_eligible: true + ut_tanf: 412 + +- name: Case 3 - Two-parent family with three children, both employed. + period: 2024-01 + input: + people: + person1: + age: 35 + tanf_gross_earned_income: 400 + tanf_gross_unearned_income: 0 + person2: + age: 33 + tanf_gross_earned_income: 300 + tanf_gross_unearned_income: 0 + person3: + age: 10 + is_tax_unit_dependent: true + person4: + age: 7 + is_tax_unit_dependent: true + person5: + age: 3 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5] + spm_unit_assets: 1_500 + tax_units: + tax_unit: + members: [person1, person2, person3, person4, person5] + households: + household: + members: [person1, person2, person3, person4, person5] + state_code: UT + output: + # Family size = 5 + # Gross income = $400 + $300 = $700, Gross limit = $1,400 -> PASS + # Work expense = $200 (2 employed persons: $100 * 2) + # After work expense = $700 - $200 = $500 + # 50% disregard = $500 * 0.50 = $250 + # Total deduction = $200 + $250 = $450 + # Countable income = $700 - $450 = $250 + # Net limit = $757 (100% SNB), $250 < $757 -> PASS + # Resources = $1,500 <= $2,000 -> PASS + # Eligible = true + # Benefit = Payment standard ($882) - Countable income ($250) = $632 + ut_tanf_payment_standard: 882 + ut_tanf_earned_income_deduction: 450 + ut_tanf_gross_income_eligible: true + ut_tanf_countable_income: 250 + ut_tanf_net_income_eligible: true + ut_tanf_resource_eligible: true + ut_tanf_income_eligible: true + ut_tanf_eligible: true + ut_tanf: 632 + +- name: Case 4 - Ineligible due to gross income exceeding 185% SNB. + period: 2024-01 + input: + people: + person1: + age: 32 + tanf_gross_earned_income: 1_200 + tanf_gross_unearned_income: 0 + person2: + age: 6 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 500 + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + # Family size = 2 + # Gross income = $1,200, Gross limit = $843 (185% SNB) + # $1,200 > $843 -> FAIL gross income test + # Ineligible, benefit = $0 + ut_tanf_payment_standard: 531 + ut_tanf_gross_income_eligible: false + ut_tanf_income_eligible: false + ut_tanf_eligible: false + ut_tanf: 0 + +- name: Case 5 - Ineligible due to gross income with mixed income sources. + period: 2024-01 + input: + people: + person1: + age: 29 + tanf_gross_earned_income: 800 + tanf_gross_unearned_income: 200 + person2: + age: 3 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 800 + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + # Family size = 2 + # Gross income = $800 + $200 = $1,000 + # Gross limit = $843 (185% SNB for size 2) + # $1,000 > $843 -> FAIL gross income test + ut_tanf_payment_standard: 531 + ut_tanf_gross_income_eligible: false + ut_tanf_income_eligible: false + ut_tanf_eligible: false + ut_tanf: 0 + +- name: Case 6 - Ineligible due to excess resources. + period: 2024-01 + input: + people: + person1: + age: 27 + tanf_gross_earned_income: 400 + tanf_gross_unearned_income: 0 + person2: + age: 2 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 3_000 + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + # Family size = 2 + # Gross income = $400, Gross limit = $843 -> PASS + # Work expense = $100 + # After work expense = $400 - $100 = $300 + # 50% disregard = $300 * 0.50 = $150 + # Total deduction = $100 + $150 = $250 + # Countable income = $400 - $250 = $150 + # Net limit = $456, $150 < $456 -> PASS + # Resources = $3,000 > $2,000 -> FAIL + # Ineligible due to excess resources + ut_tanf_payment_standard: 531 + ut_tanf_earned_income_deduction: 250 + ut_tanf_gross_income_eligible: true + ut_tanf_countable_income: 150 + ut_tanf_net_income_eligible: true + ut_tanf_resource_eligible: false + ut_tanf_income_eligible: true + ut_tanf_eligible: false + ut_tanf: 0 + +- name: Case 7 - Large family with unearned income only. + period: 2024-01 + input: + people: + person1: + age: 40 + tanf_gross_earned_income: 0 + tanf_gross_unearned_income: 400 + person2: + age: 15 + is_tax_unit_dependent: true + person3: + age: 12 + is_tax_unit_dependent: true + person4: + age: 8 + is_tax_unit_dependent: true + person5: + age: 5 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5] + spm_unit_assets: 1_200 + tax_units: + tax_unit: + members: [person1, person2, person3, person4, person5] + households: + household: + members: [person1, person2, person3, person4, person5] + state_code: UT + output: + # Family size = 5 + # Gross income = $400 (unearned only), Gross limit = $1,400 -> PASS + # No earned income, so no deductions apply + # Countable income = $400 (unearned passes through) + # Net limit = $757, $400 < $757 -> PASS + # Resources = $1,200 <= $2,000 -> PASS + # Eligible = true + # Benefit = Payment standard ($882) - Countable income ($400) = $482 + ut_tanf_payment_standard: 882 + ut_tanf_earned_income_deduction: 0 + ut_tanf_gross_income_eligible: true + ut_tanf_countable_income: 400 + ut_tanf_net_income_eligible: true + ut_tanf_resource_eligible: true + ut_tanf_income_eligible: true + ut_tanf_eligible: true + ut_tanf: 482 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/ut_tanf.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/ut_tanf.yaml new file mode 100644 index 00000000000..f8cf671c2ce --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/ut_tanf.yaml @@ -0,0 +1,96 @@ +# Unit test for Utah Family Employment Program (TANF) +# Based on October 2022 payment standards +# +# Test case: Family of 3, single parent, $1,000/month earned income +# Gross income = $1,000/month (earned) +# Gross limit for 3 = $1,050 -> PASS gross test +# Work expense deduction = $100 (1 employed person) +# Remainder = $1,000 - $100 = $900 +# 50% disregard = $900 * 0.50 = $450 +# Countable earned = $900 - $450 = $450/month +# Net limit for 3 = $568 -> PASS net test (450 < 568) +# Payment standard for 3 = $662/month +# Benefit = $662 - $450 = $212/month +# Annual values = monthly * 12 + +- name: Utah TANF - eligible family of 3 + period: 2023 + input: + people: + parent: + age: 30 + employment_income_before_lsr: 12_000 # $1,000/month + child1: + age: 8 + child2: + age: 5 + spm_units: + spm_unit: + members: [parent, child1, child2] + spm_unit_assets: 1_000 + households: + household: + members: [parent, child1, child2] + state_code: UT + output: + ut_tanf_gross_income: 1_000 * 12 # $1,000/month * 12 + ut_tanf_earned_income_deduction: 550 * 12 # $550/month * 12 + ut_tanf_countable_income: 450 * 12 # $450/month * 12 + ut_tanf_income_eligible: true + ut_tanf_resource_eligible: true + ut_tanf_eligible: true + ut_tanf_payment_standard: 662 * 12 # $662/month * 12 + ut_tanf: 212 * 12 # $212/month * 12 + +# Test case: Family over gross income limit +# Gross income = $1,200/month (earned) +# Gross limit for 3 = $1,050/month -> FAIL gross test + +- name: Utah TANF - ineligible due to gross income + period: 2023 + input: + people: + parent: + age: 30 + employment_income_before_lsr: 14_400 # $1,200/month + child1: + age: 8 + child2: + age: 5 + spm_units: + spm_unit: + members: [parent, child1, child2] + spm_unit_assets: 500 + households: + household: + members: [parent, child1, child2] + state_code: UT + output: + ut_tanf_gross_income: 1_200 * 12 + ut_tanf_income_eligible: false + ut_tanf_eligible: false + ut_tanf: 0 + +# Test case: Family over resource limit + +- name: Utah TANF - ineligible due to resources + period: 2023 + input: + people: + parent: + age: 30 + employment_income_before_lsr: 6_000 # $500/month + child1: + age: 8 + spm_units: + spm_unit: + members: [parent, child1] + spm_unit_assets: 2_500 # Over $2,000 limit + households: + household: + members: [parent, child1] + state_code: UT + output: + ut_tanf_resource_eligible: false + ut_tanf_eligible: false + ut_tanf: 0 diff --git a/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_eligible.py b/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_eligible.py new file mode 100644 index 00000000000..d943d9d56a9 --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_eligible.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * + + +class ut_tanf_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Eligible for Utah Family Employment Program" + definition_period = MONTH + reference = ( + "https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules" + ) + defined_for = StateCode.UT + + def formula(spm_unit, period, parameters): + # Per R986-200: Must meet demographic, income, and resource tests + demographic_eligible = spm_unit("is_demographic_tanf_eligible", period) + income_eligible = spm_unit("ut_tanf_income_eligible", period) + resource_eligible = spm_unit("ut_tanf_resource_eligible", period) + return demographic_eligible & income_eligible & resource_eligible diff --git a/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_gross_income_eligible.py b/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_gross_income_eligible.py new file mode 100644 index 00000000000..e882d9d8227 --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_gross_income_eligible.py @@ -0,0 +1,23 @@ +from policyengine_us.model_api import * + + +class ut_tanf_gross_income_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Eligible for Utah TANF under gross income test" + definition_period = MONTH + reference = ( + "https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules" + ) + defined_for = StateCode.UT + + def formula(spm_unit, period, parameters): + # Utah gross income test: gross income <= 185% of SNB + p = parameters(period).gov.states.ut.dwf.tanf + + size = spm_unit("spm_unit_size", period) + size_capped = min_(size, p.payment_standard.max_unit_size) + + gross_income = spm_unit("ut_tanf_gross_income", period) + gross_limit = p.income.gross_income_limit.amount[size_capped] + return gross_income <= gross_limit diff --git a/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_income_eligible.py b/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_income_eligible.py new file mode 100644 index 00000000000..12176be8e73 --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_income_eligible.py @@ -0,0 +1,18 @@ +from policyengine_us.model_api import * + + +class ut_tanf_income_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Eligible for Utah Family Employment Program due to income" + definition_period = MONTH + reference = ( + "https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules" + ) + defined_for = StateCode.UT + + def formula(spm_unit, period, parameters): + # Utah uses two-tier income test per R986-200-238 + gross_test = spm_unit("ut_tanf_gross_income_eligible", period) + net_test = spm_unit("ut_tanf_net_income_eligible", period) + return gross_test & net_test diff --git a/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_net_income_eligible.py b/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_net_income_eligible.py new file mode 100644 index 00000000000..48862c39336 --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_net_income_eligible.py @@ -0,0 +1,23 @@ +from policyengine_us.model_api import * + + +class ut_tanf_net_income_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Eligible for Utah TANF under net income test" + definition_period = MONTH + reference = ( + "https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules" + ) + defined_for = StateCode.UT + + def formula(spm_unit, period, parameters): + # Utah net income test: countable income < 100% of SNB (strict less than) + p = parameters(period).gov.states.ut.dwf.tanf + + size = spm_unit("spm_unit_size", period) + size_capped = min_(size, p.payment_standard.max_unit_size) + + countable_income = spm_unit("ut_tanf_countable_income", period) + net_limit = p.income.net_income_limit.amount[size_capped] + return countable_income < net_limit diff --git a/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_resource_eligible.py b/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_resource_eligible.py new file mode 100644 index 00000000000..e926da8c115 --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_resource_eligible.py @@ -0,0 +1,18 @@ +from policyengine_us.model_api import * + + +class ut_tanf_resource_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Eligible for Utah Family Employment Program due to resources" + definition_period = MONTH + reference = ( + "https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules" + ) + defined_for = StateCode.UT + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.ut.dwf.tanf.resources.limit + # Use federal spm_unit_assets variable directly + assets = spm_unit("spm_unit_assets", period.this_year) + return assets <= p.amount diff --git a/policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_countable_income.py b/policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_countable_income.py new file mode 100644 index 00000000000..e8edb330b49 --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_countable_income.py @@ -0,0 +1,22 @@ +from policyengine_us.model_api import * + + +class ut_tanf_countable_income(Variable): + value_type = float + entity = SPMUnit + label = "Utah Family Employment Program countable income" + unit = USD + definition_period = MONTH + reference = ( + "https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules" + ) + defined_for = StateCode.UT + + def formula(spm_unit, period, parameters): + # Countable income = gross_earned - deductions + gross_unearned + person = spm_unit.members + gross_earned = spm_unit.sum(person("tanf_gross_earned_income", period)) + deduction = spm_unit("ut_tanf_earned_income_deduction", period) + countable_earned = max_(gross_earned - deduction, 0) + gross_unearned = add(spm_unit, period, ["tanf_gross_unearned_income"]) + return countable_earned + gross_unearned diff --git a/policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_earned_income_deduction.py b/policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_earned_income_deduction.py new file mode 100644 index 00000000000..db7010371b8 --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_earned_income_deduction.py @@ -0,0 +1,40 @@ +from policyengine_us.model_api import * + + +class ut_tanf_earned_income_deduction(Variable): + value_type = float + entity = SPMUnit + label = "Utah TANF earned income deduction" + unit = USD + definition_period = MONTH + reference = ( + "https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules" + ) + defined_for = StateCode.UT + + def formula(spm_unit, period, parameters): + # Utah earned income deductions per R986-200-239: + # 1. Work expense allowance: $100 per employed person + # 2. 50% earned income disregard on remaining earned income + p = parameters(period).gov.states.ut.dwf.tanf.income.deductions + + # Get gross earned income from household members + person = spm_unit.members + person_earned = person("tanf_gross_earned_income", period) + gross_earned = spm_unit.sum(person_earned) + + # Step 1: Work expense deduction ($100 per employed person) + has_earned_income = person_earned > 0 + employed_count = spm_unit.sum(has_earned_income) + work_expense_deduction = ( + employed_count * p.work_expense_allowance.amount + ) + + # Step 2: 50% disregard on remainder after work expense + remainder = max_(gross_earned - work_expense_deduction, 0) + disregard = remainder * p.earned_income_disregard.rate + + # Total deduction is work expense + 50% disregard + # But cannot exceed gross earned income + total_deduction = work_expense_deduction + disregard + return min_(total_deduction, gross_earned) diff --git a/policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_gross_income.py b/policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_gross_income.py new file mode 100644 index 00000000000..f7db4938717 --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_gross_income.py @@ -0,0 +1,18 @@ +from policyengine_us.model_api import * + + +class ut_tanf_gross_income(Variable): + value_type = float + entity = SPMUnit + label = "Utah Family Employment Program gross income" + unit = USD + definition_period = MONTH + reference = ( + "https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules" + ) + defined_for = StateCode.UT + + adds = [ + "tanf_gross_earned_income", + "tanf_gross_unearned_income", + ] diff --git a/policyengine_us/variables/gov/states/ut/dwf/tanf/ut_tanf.py b/policyengine_us/variables/gov/states/ut/dwf/tanf/ut_tanf.py new file mode 100644 index 00000000000..b6c1a9328a7 --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/dwf/tanf/ut_tanf.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * + + +class ut_tanf(Variable): + value_type = float + entity = SPMUnit + label = "Utah Family Employment Program benefit" + unit = USD + definition_period = MONTH + reference = ( + "https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules" + ) + defined_for = "ut_tanf_eligible" + + def formula(spm_unit, period, parameters): + # Per R986-200-246: Benefit = payment standard - countable income + payment_standard = spm_unit("ut_tanf_payment_standard", period) + countable_income = spm_unit("ut_tanf_countable_income", period) + return max_(payment_standard - countable_income, 0) diff --git a/policyengine_us/variables/gov/states/ut/dwf/tanf/ut_tanf_payment_standard.py b/policyengine_us/variables/gov/states/ut/dwf/tanf/ut_tanf_payment_standard.py new file mode 100644 index 00000000000..4f667ca14c1 --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/dwf/tanf/ut_tanf_payment_standard.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * + + +class ut_tanf_payment_standard(Variable): + value_type = float + entity = SPMUnit + label = "Utah Family Employment Program payment standard" + unit = USD + definition_period = MONTH + reference = ( + "https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules" + ) + defined_for = StateCode.UT + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.ut.dwf.tanf.payment_standard + size = spm_unit("spm_unit_size", period) + size_capped = min_(size, p.max_unit_size) + return p.amount[size_capped] From 1385e5fed3d579d808db7bc4d390a8377549be77 Mon Sep 17 00:00:00 2001 From: Ziming Date: Wed, 10 Dec 2025 18:09:54 -0500 Subject: [PATCH 3/6] adjustment --- ...l => ut_tanf_countable_earned_income.yaml} | 49 ++++++------- .../tanf/income/ut_tanf_countable_income.yaml | 69 ------------------- ...tanf_earned_income_after_work_expense.yaml | 59 ++++++++++++++++ .../gov/states/ut/dwf/tanf/integration.yaml | 32 ++++----- .../gov/states/ut/dwf/tanf/ut_tanf.yaml | 11 ++- .../ut_tanf_gross_income_eligible.py | 3 +- .../ut_tanf_net_income_eligible.py | 3 +- .../income/ut_tanf_countable_earned_income.py | 24 +++++++ .../tanf/income/ut_tanf_countable_income.py | 12 ++-- ...t_tanf_earned_income_after_work_expense.py | 19 +++++ .../income/ut_tanf_earned_income_deduction.py | 40 ----------- 11 files changed, 145 insertions(+), 176 deletions(-) rename policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/income/{ut_tanf_earned_income_deduction.yaml => ut_tanf_countable_earned_income.yaml} (65%) delete mode 100644 policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/income/ut_tanf_countable_income.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/income/ut_tanf_earned_income_after_work_expense.yaml create mode 100644 policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_countable_earned_income.py create mode 100644 policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_earned_income_after_work_expense.py delete mode 100644 policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_earned_income_deduction.py diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/income/ut_tanf_earned_income_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/income/ut_tanf_countable_earned_income.yaml similarity index 65% rename from policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/income/ut_tanf_earned_income_deduction.yaml rename to policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/income/ut_tanf_countable_earned_income.yaml index 1119d5815f5..aa5dce1787d 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/income/ut_tanf_earned_income_deduction.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/income/ut_tanf_countable_earned_income.yaml @@ -1,11 +1,11 @@ -# Unit tests for ut_tanf_earned_income_deduction (earned income deductions) -# Utah applies two earned income deductions: +# Unit tests for ut_tanf_countable_earned_income +# Utah applies earned income deductions then counts the remainder: # 1. Work expense allowance: $100 per employed person # 2. 50% earned income disregard on remaining earned income -# Formula: work_expense + 0.50 * max(earned_income - work_expense, 0) +# Formula: sum(max(person_earned - 100, 0)) * 0.5 # Reference: Utah Admin. Code R986-200-239(2)(a) and R986-200-239(2)(b) -- name: No earned income - zero deduction. +- name: No earned income - zero countable. period: 2024-01 input: people: @@ -21,8 +21,8 @@ members: [person1, person2] state_code: UT output: - # No earnings = no deduction - ut_tanf_earned_income_deduction: 0 + # No earnings = no countable earned income + ut_tanf_countable_earned_income: 0 - name: Single employed person with $500 earnings. period: 2024-01 @@ -40,11 +40,9 @@ members: [person1, person2] state_code: UT output: - # 1 employed person: work_expense = $100 # After work expense = max(500 - 100, 0) = 400 - # 50% disregard = 400 * 0.50 = 200 - # Total deduction = 100 + 200 = 300 - ut_tanf_earned_income_deduction: 300 + # Countable = 400 * 0.50 = 200 + ut_tanf_countable_earned_income: 200 - name: Single employed person with $1,000 earnings. period: 2024-01 @@ -62,11 +60,9 @@ members: [person1, person2] state_code: UT output: - # 1 employed person: work_expense = $100 - # After work expense = max(1,000 - 100, 0) = 900 - # 50% disregard = 900 * 0.50 = 450 - # Total deduction = 100 + 450 = 550 - ut_tanf_earned_income_deduction: 550 + # After work expense = max(1000 - 100, 0) = 900 + # Countable = 900 * 0.50 = 450 + ut_tanf_countable_earned_income: 450 - name: Two employed persons with earnings. period: 2024-01 @@ -84,12 +80,11 @@ members: [person1, person2] state_code: UT output: - # 2 employed persons: work_expense = $200 (100 * 2) - # Total earnings = 600 + 400 = 1,000 - # After work expense = max(1,000 - 200, 0) = 800 - # 50% disregard = 800 * 0.50 = 400 - # Total deduction = 200 + 400 = 600 - ut_tanf_earned_income_deduction: 600 + # Person1 after work expense = max(600 - 100, 0) = 500 + # Person2 after work expense = max(400 - 100, 0) = 300 + # Total after work expense = 800 + # Countable = 800 * 0.50 = 400 + ut_tanf_countable_earned_income: 400 - name: Earnings less than work expense deduction. period: 2024-01 @@ -107,11 +102,9 @@ members: [person1, person2] state_code: UT output: - # 1 employed person: work_expense = $100 # After work expense = max(80 - 100, 0) = 0 - # 50% disregard = 0 * 0.50 = 0 - # Total deduction = 80 (capped at earnings, cannot exceed earnings) - ut_tanf_earned_income_deduction: 80 + # Countable = 0 * 0.50 = 0 + ut_tanf_countable_earned_income: 0 - name: Earnings exactly equal to work expense. period: 2024-01 @@ -129,8 +122,6 @@ members: [person1, person2] state_code: UT output: - # 1 employed person: work_expense = $100 # After work expense = max(100 - 100, 0) = 0 - # 50% disregard = 0 * 0.50 = 0 - # Total deduction = 100 - ut_tanf_earned_income_deduction: 100 + # Countable = 0 * 0.50 = 0 + ut_tanf_countable_earned_income: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/income/ut_tanf_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/income/ut_tanf_countable_income.yaml deleted file mode 100644 index 4f35a52c3e8..00000000000 --- a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/income/ut_tanf_countable_income.yaml +++ /dev/null @@ -1,69 +0,0 @@ -# Unit tests for ut_tanf_countable_income (net countable income calculation) -# Countable income = earned income after deductions + unearned income -# Reference: Utah Admin. Code R986-200-239 - -- name: No income - zero countable income. - period: 2024-01 - input: - state_code: UT - ut_tanf_earned_income_deduction: 0 - tanf_gross_earned_income: 0 - tanf_gross_unearned_income: 0 - output: - # Countable = (0 - 0) + 0 = 0 - ut_tanf_countable_income: 0 - -- name: Earned income only with deductions. - period: 2024-01 - input: - state_code: UT - ut_tanf_earned_income_deduction: 350 - tanf_gross_earned_income: 600 - tanf_gross_unearned_income: 0 - output: - # Countable = max(600 - 350, 0) + 0 = 250 - ut_tanf_countable_income: 250 - -- name: Unearned income only. - period: 2024-01 - input: - state_code: UT - ut_tanf_earned_income_deduction: 0 - tanf_gross_earned_income: 0 - tanf_gross_unearned_income: 300 - output: - # Countable = 0 + 300 = 300 - ut_tanf_countable_income: 300 - -- name: Both earned and unearned income. - period: 2024-01 - input: - state_code: UT - ut_tanf_earned_income_deduction: 350 - tanf_gross_earned_income: 800 - tanf_gross_unearned_income: 150 - output: - # Countable = max(800 - 350, 0) + 150 = 450 + 150 = 600 - ut_tanf_countable_income: 600 - -- name: Earned income deduction exceeds earned income. - period: 2024-01 - input: - state_code: UT - ut_tanf_earned_income_deduction: 400 - tanf_gross_earned_income: 200 - tanf_gross_unearned_income: 100 - output: - # Countable = max(200 - 400, 0) + 100 = 0 + 100 = 100 - ut_tanf_countable_income: 100 - -- name: Large earned income with full deductions. - period: 2024-01 - input: - state_code: UT - ut_tanf_earned_income_deduction: 500 - tanf_gross_earned_income: 1_000 - tanf_gross_unearned_income: 200 - output: - # Countable = max(1,000 - 500, 0) + 200 = 500 + 200 = 700 - ut_tanf_countable_income: 700 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/income/ut_tanf_earned_income_after_work_expense.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/income/ut_tanf_earned_income_after_work_expense.yaml new file mode 100644 index 00000000000..6ff8222bc07 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/income/ut_tanf_earned_income_after_work_expense.yaml @@ -0,0 +1,59 @@ +# Unit tests for ut_tanf_earned_income_after_work_expense (Person-level) +# Earned income after $100 work expense deduction per person +# Formula: max(earned_income - 100, 0) +# Reference: Utah Admin. Code R986-200-239(2)(a) + +- name: No earned income. + period: 2024-01 + input: + people: + person1: + tanf_gross_earned_income: 0 + households: + household: + members: [person1] + state_code: UT + output: + ut_tanf_earned_income_after_work_expense: 0 + +- name: Earned income $500. + period: 2024-01 + input: + people: + person1: + tanf_gross_earned_income: 500 + households: + household: + members: [person1] + state_code: UT + output: + # max(500 - 100, 0) = 400 + ut_tanf_earned_income_after_work_expense: 400 + +- name: Earned income less than $100. + period: 2024-01 + input: + people: + person1: + tanf_gross_earned_income: 80 + households: + household: + members: [person1] + state_code: UT + output: + # max(80 - 100, 0) = 0 + ut_tanf_earned_income_after_work_expense: 0 + +- name: Earned income exactly $100. + period: 2024-01 + input: + people: + person1: + tanf_gross_earned_income: 100 + households: + household: + members: [person1] + state_code: UT + output: + # max(100 - 100, 0) = 0 + ut_tanf_earned_income_after_work_expense: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/integration.yaml index a219f30a820..b65c654c6dd 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/integration.yaml @@ -77,17 +77,15 @@ output: # Family size = 3 # Gross income = $600, Gross limit = $1,050 -> PASS - # Work expense = $100 (1 employed person) - # After work expense = $600 - $100 = $500 - # 50% disregard = $500 * 0.50 = $250 - # Total deduction = $100 + $250 = $350 - # Countable income = $600 - $350 = $250 + # After work expense = max(600 - 100, 0) = 500 + # Countable earned = 500 * 0.50 = 250 + # Countable income = 250 + 0 (unearned) = 250 # Net limit = $568 (100% SNB), $250 < $568 -> PASS # Resources = $1,000 <= $2,000 -> PASS # Eligible = true # Benefit = Payment standard ($662) - Countable income ($250) = $412 ut_tanf_payment_standard: 662 - ut_tanf_earned_income_deduction: 350 + ut_tanf_countable_earned_income: 250 ut_tanf_gross_income_eligible: true ut_tanf_countable_income: 250 ut_tanf_net_income_eligible: true @@ -131,17 +129,15 @@ output: # Family size = 5 # Gross income = $400 + $300 = $700, Gross limit = $1,400 -> PASS - # Work expense = $200 (2 employed persons: $100 * 2) - # After work expense = $700 - $200 = $500 - # 50% disregard = $500 * 0.50 = $250 - # Total deduction = $200 + $250 = $450 - # Countable income = $700 - $450 = $250 + # After work expense = max(400-100,0) + max(300-100,0) = 300 + 200 = 500 + # Countable earned = 500 * 0.50 = 250 + # Countable income = 250 + 0 (unearned) = 250 # Net limit = $757 (100% SNB), $250 < $757 -> PASS # Resources = $1,500 <= $2,000 -> PASS # Eligible = true # Benefit = Payment standard ($882) - Countable income ($250) = $632 ut_tanf_payment_standard: 882 - ut_tanf_earned_income_deduction: 450 + ut_tanf_countable_earned_income: 250 ut_tanf_gross_income_eligible: true ut_tanf_countable_income: 250 ut_tanf_net_income_eligible: true @@ -241,16 +237,14 @@ output: # Family size = 2 # Gross income = $400, Gross limit = $843 -> PASS - # Work expense = $100 - # After work expense = $400 - $100 = $300 - # 50% disregard = $300 * 0.50 = $150 - # Total deduction = $100 + $150 = $250 - # Countable income = $400 - $250 = $150 + # After work expense = max(400 - 100, 0) = 300 + # Countable earned = 300 * 0.50 = 150 + # Countable income = 150 + 0 (unearned) = 150 # Net limit = $456, $150 < $456 -> PASS # Resources = $3,000 > $2,000 -> FAIL # Ineligible due to excess resources ut_tanf_payment_standard: 531 - ut_tanf_earned_income_deduction: 250 + ut_tanf_countable_earned_income: 150 ut_tanf_gross_income_eligible: true ut_tanf_countable_income: 150 ut_tanf_net_income_eligible: true @@ -300,7 +294,7 @@ # Eligible = true # Benefit = Payment standard ($882) - Countable income ($400) = $482 ut_tanf_payment_standard: 882 - ut_tanf_earned_income_deduction: 0 + ut_tanf_countable_earned_income: 0 ut_tanf_gross_income_eligible: true ut_tanf_countable_income: 400 ut_tanf_net_income_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/ut_tanf.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/ut_tanf.yaml index f8cf671c2ce..b1ce9e95ef4 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/ut_tanf.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/ut_tanf.yaml @@ -4,10 +4,9 @@ # Test case: Family of 3, single parent, $1,000/month earned income # Gross income = $1,000/month (earned) # Gross limit for 3 = $1,050 -> PASS gross test -# Work expense deduction = $100 (1 employed person) -# Remainder = $1,000 - $100 = $900 -# 50% disregard = $900 * 0.50 = $450 -# Countable earned = $900 - $450 = $450/month +# After work expense = max(1000 - 100, 0) = 900 +# Countable earned = 900 * 0.50 = 450 +# Countable income = 450 + 0 (unearned) = 450 # Net limit for 3 = $568 -> PASS net test (450 < 568) # Payment standard for 3 = $662/month # Benefit = $662 - $450 = $212/month @@ -33,8 +32,7 @@ members: [parent, child1, child2] state_code: UT output: - ut_tanf_gross_income: 1_000 * 12 # $1,000/month * 12 - ut_tanf_earned_income_deduction: 550 * 12 # $550/month * 12 + ut_tanf_countable_earned_income: 450 * 12 # $450/month * 12 ut_tanf_countable_income: 450 * 12 # $450/month * 12 ut_tanf_income_eligible: true ut_tanf_resource_eligible: true @@ -66,7 +64,6 @@ members: [parent, child1, child2] state_code: UT output: - ut_tanf_gross_income: 1_200 * 12 ut_tanf_income_eligible: false ut_tanf_eligible: false ut_tanf: 0 diff --git a/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_gross_income_eligible.py b/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_gross_income_eligible.py index e882d9d8227..63e102fb64e 100644 --- a/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_gross_income_eligible.py +++ b/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_gross_income_eligible.py @@ -19,5 +19,4 @@ def formula(spm_unit, period, parameters): size_capped = min_(size, p.payment_standard.max_unit_size) gross_income = spm_unit("ut_tanf_gross_income", period) - gross_limit = p.income.gross_income_limit.amount[size_capped] - return gross_income <= gross_limit + return gross_income <= p.income.gross_income_limit.amount[size_capped] diff --git a/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_net_income_eligible.py b/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_net_income_eligible.py index 48862c39336..e6d71acaa53 100644 --- a/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_net_income_eligible.py +++ b/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_net_income_eligible.py @@ -19,5 +19,4 @@ def formula(spm_unit, period, parameters): size_capped = min_(size, p.payment_standard.max_unit_size) countable_income = spm_unit("ut_tanf_countable_income", period) - net_limit = p.income.net_income_limit.amount[size_capped] - return countable_income < net_limit + return countable_income < p.income.net_income_limit.amount[size_capped] diff --git a/policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_countable_earned_income.py b/policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_countable_earned_income.py new file mode 100644 index 00000000000..0bbda89e711 --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_countable_earned_income.py @@ -0,0 +1,24 @@ +from policyengine_us.model_api import * + + +class ut_tanf_countable_earned_income(Variable): + value_type = float + entity = SPMUnit + label = "Utah TANF countable earned income" + unit = USD + definition_period = MONTH + reference = ( + "https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules" + ) + defined_for = StateCode.UT + + def formula(spm_unit, period, parameters): + # Utah earned income after deductions per R986-200-239: + # 1. Work expense allowance: $100 per employed person + # 2. 50% earned income disregard on remaining earned income + p = parameters(period).gov.states.ut.dwf.tanf.income.deductions + after_work_expense = add( + spm_unit, period, ["ut_tanf_earned_income_after_work_expense"] + ) + # Countable = remainder * (1 - disregard_rate) = remainder * 0.5 + return after_work_expense * (1 - p.earned_income_disregard.rate) diff --git a/policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_countable_income.py b/policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_countable_income.py index e8edb330b49..7c90107e3cd 100644 --- a/policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_countable_income.py +++ b/policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_countable_income.py @@ -12,11 +12,7 @@ class ut_tanf_countable_income(Variable): ) defined_for = StateCode.UT - def formula(spm_unit, period, parameters): - # Countable income = gross_earned - deductions + gross_unearned - person = spm_unit.members - gross_earned = spm_unit.sum(person("tanf_gross_earned_income", period)) - deduction = spm_unit("ut_tanf_earned_income_deduction", period) - countable_earned = max_(gross_earned - deduction, 0) - gross_unearned = add(spm_unit, period, ["tanf_gross_unearned_income"]) - return countable_earned + gross_unearned + adds = [ + "ut_tanf_countable_earned_income", + "tanf_gross_unearned_income", + ] diff --git a/policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_earned_income_after_work_expense.py b/policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_earned_income_after_work_expense.py new file mode 100644 index 00000000000..b7759112c7f --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_earned_income_after_work_expense.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * + + +class ut_tanf_earned_income_after_work_expense(Variable): + value_type = float + entity = Person + label = "Utah TANF earned income after work expense deduction" + unit = USD + definition_period = MONTH + reference = ( + "https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules" + ) + defined_for = StateCode.UT + + def formula(person, period, parameters): + # $100 work expense deduction per employed person + p = parameters(period).gov.states.ut.dwf.tanf.income.deductions + earned_income = person("tanf_gross_earned_income", period) + return max_(earned_income - p.work_expense_allowance.amount, 0) diff --git a/policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_earned_income_deduction.py b/policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_earned_income_deduction.py deleted file mode 100644 index db7010371b8..00000000000 --- a/policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_earned_income_deduction.py +++ /dev/null @@ -1,40 +0,0 @@ -from policyengine_us.model_api import * - - -class ut_tanf_earned_income_deduction(Variable): - value_type = float - entity = SPMUnit - label = "Utah TANF earned income deduction" - unit = USD - definition_period = MONTH - reference = ( - "https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules" - ) - defined_for = StateCode.UT - - def formula(spm_unit, period, parameters): - # Utah earned income deductions per R986-200-239: - # 1. Work expense allowance: $100 per employed person - # 2. 50% earned income disregard on remaining earned income - p = parameters(period).gov.states.ut.dwf.tanf.income.deductions - - # Get gross earned income from household members - person = spm_unit.members - person_earned = person("tanf_gross_earned_income", period) - gross_earned = spm_unit.sum(person_earned) - - # Step 1: Work expense deduction ($100 per employed person) - has_earned_income = person_earned > 0 - employed_count = spm_unit.sum(has_earned_income) - work_expense_deduction = ( - employed_count * p.work_expense_allowance.amount - ) - - # Step 2: 50% disregard on remainder after work expense - remainder = max_(gross_earned - work_expense_deduction, 0) - disregard = remainder * p.earned_income_disregard.rate - - # Total deduction is work expense + 50% disregard - # But cannot exceed gross earned income - total_deduction = work_expense_deduction + disregard - return min_(total_deduction, gross_earned) From c732094291e4752fc62b12450aaa91721b226225 Mon Sep 17 00:00:00 2001 From: Ziming Date: Wed, 10 Dec 2025 19:25:57 -0500 Subject: [PATCH 4/6] adjustment --- .../earned_income_disregard/rate.yaml | 4 +- .../work_expense_allowance/amount.yaml | 4 +- .../fep/income/gross_income_limit/rate.yaml | 12 ++ .../payment_standard/amount.yaml | 6 +- .../fep/payment_standard/max_unit_size.yaml | 12 ++ .../{tanf => fep}/resources/limit/amount.yaml | 4 +- .../dwf/fep/standard_needs_budget/amount.yaml | 52 +++++++++ .../income/gross_income_limit/amount.yaml | 50 -------- .../tanf/income/net_income_limit/amount.yaml | 50 -------- .../tanf/payment_standard/max_unit_size.yaml | 12 -- .../benefit/ut_fep_payment_standard.yaml} | 18 +-- .../eligibility/ut_fep_eligible.yaml} | 32 +++--- .../ut_fep_gross_income_eligible.yaml} | 16 +-- .../eligibility/ut_fep_income_eligible.yaml} | 26 ++--- .../ut_fep_net_income_eligible.yaml} | 30 ++--- .../ut_fep_resources_eligible.yaml} | 12 +- .../ut_fep_countable_earned_income.yaml} | 14 +-- ...fep_earned_income_after_work_expense.yaml} | 10 +- .../ut/dwf/{tanf => fep}/integration.yaml | 108 +++++++++--------- .../{tanf/ut_tanf.yaml => fep/ut_fep.yaml} | 26 ++--- .../eligibility/ut_fep_eligible.py} | 10 +- .../ut_fep_gross_income_eligible.py | 26 +++++ .../eligibility/ut_fep_income_eligible.py} | 10 +- .../ut_fep_net_income_eligible.py} | 10 +- .../eligibility/ut_fep_resources_eligible.py} | 8 +- .../income/ut_fep_countable_earned_income.py} | 10 +- .../income/ut_fep_countable_income.py} | 8 +- ...t_fep_earned_income_after_work_expense.py} | 8 +- .../income/ut_fep_gross_income.py} | 6 +- .../ut/dwf/{tanf/ut_tanf.py => fep/ut_fep.py} | 12 +- .../ut_fep_payment_standard.py} | 8 +- .../ut_tanf_gross_income_eligible.py | 22 ---- 32 files changed, 293 insertions(+), 343 deletions(-) rename policyengine_us/parameters/gov/states/ut/dwf/{tanf => fep}/income/deductions/earned_income_disregard/rate.yaml (65%) rename policyengine_us/parameters/gov/states/ut/dwf/{tanf => fep}/income/deductions/work_expense_allowance/amount.yaml (66%) create mode 100644 policyengine_us/parameters/gov/states/ut/dwf/fep/income/gross_income_limit/rate.yaml rename policyengine_us/parameters/gov/states/ut/dwf/{tanf => fep}/payment_standard/amount.yaml (62%) create mode 100644 policyengine_us/parameters/gov/states/ut/dwf/fep/payment_standard/max_unit_size.yaml rename policyengine_us/parameters/gov/states/ut/dwf/{tanf => fep}/resources/limit/amount.yaml (65%) create mode 100644 policyengine_us/parameters/gov/states/ut/dwf/fep/standard_needs_budget/amount.yaml delete mode 100644 policyengine_us/parameters/gov/states/ut/dwf/tanf/income/gross_income_limit/amount.yaml delete mode 100644 policyengine_us/parameters/gov/states/ut/dwf/tanf/income/net_income_limit/amount.yaml delete mode 100644 policyengine_us/parameters/gov/states/ut/dwf/tanf/payment_standard/max_unit_size.yaml rename policyengine_us/tests/policy/baseline/gov/states/ut/dwf/{tanf/benefit/ut_tanf_payment_standard.yaml => fep/benefit/ut_fep_payment_standard.yaml} (79%) rename policyengine_us/tests/policy/baseline/gov/states/ut/dwf/{tanf/eligibility/ut_tanf_eligible.yaml => fep/eligibility/ut_fep_eligible.yaml} (61%) rename policyengine_us/tests/policy/baseline/gov/states/ut/dwf/{tanf/eligibility/ut_tanf_gross_income_eligible.yaml => fep/eligibility/ut_fep_gross_income_eligible.yaml} (86%) rename policyengine_us/tests/policy/baseline/gov/states/ut/dwf/{tanf/eligibility/ut_tanf_income_eligible.yaml => fep/eligibility/ut_fep_income_eligible.yaml} (55%) rename policyengine_us/tests/policy/baseline/gov/states/ut/dwf/{tanf/eligibility/ut_tanf_net_income_eligible.yaml => fep/eligibility/ut_fep_net_income_eligible.yaml} (75%) rename policyengine_us/tests/policy/baseline/gov/states/ut/dwf/{tanf/eligibility/ut_tanf_resource_eligible.yaml => fep/eligibility/ut_fep_resources_eligible.yaml} (78%) rename policyengine_us/tests/policy/baseline/gov/states/ut/dwf/{tanf/income/ut_tanf_countable_earned_income.yaml => fep/income/ut_fep_countable_earned_income.yaml} (91%) rename policyengine_us/tests/policy/baseline/gov/states/ut/dwf/{tanf/income/ut_tanf_earned_income_after_work_expense.yaml => fep/income/ut_fep_earned_income_after_work_expense.yaml} (80%) rename policyengine_us/tests/policy/baseline/gov/states/ut/dwf/{tanf => fep}/integration.yaml (80%) rename policyengine_us/tests/policy/baseline/gov/states/ut/dwf/{tanf/ut_tanf.yaml => fep/ut_fep.yaml} (80%) rename policyengine_us/variables/gov/states/ut/dwf/{tanf/eligibility/ut_tanf_eligible.py => fep/eligibility/ut_fep_eligible.py} (64%) create mode 100644 policyengine_us/variables/gov/states/ut/dwf/fep/eligibility/ut_fep_gross_income_eligible.py rename policyengine_us/variables/gov/states/ut/dwf/{tanf/eligibility/ut_tanf_income_eligible.py => fep/eligibility/ut_fep_income_eligible.py} (56%) rename policyengine_us/variables/gov/states/ut/dwf/{tanf/eligibility/ut_tanf_net_income_eligible.py => fep/eligibility/ut_fep_net_income_eligible.py} (63%) rename policyengine_us/variables/gov/states/ut/dwf/{tanf/eligibility/ut_tanf_resource_eligible.py => fep/eligibility/ut_fep_resources_eligible.py} (66%) rename policyengine_us/variables/gov/states/ut/dwf/{tanf/income/ut_tanf_countable_earned_income.py => fep/income/ut_fep_countable_earned_income.py} (68%) rename policyengine_us/variables/gov/states/ut/dwf/{tanf/income/ut_tanf_countable_income.py => fep/income/ut_fep_countable_income.py} (60%) rename policyengine_us/variables/gov/states/ut/dwf/{tanf/income/ut_tanf_earned_income_after_work_expense.py => fep/income/ut_fep_earned_income_after_work_expense.py} (67%) rename policyengine_us/variables/gov/states/ut/dwf/{tanf/income/ut_tanf_gross_income.py => fep/income/ut_fep_gross_income.py} (69%) rename policyengine_us/variables/gov/states/ut/dwf/{tanf/ut_tanf.py => fep/ut_fep.py} (54%) rename policyengine_us/variables/gov/states/ut/dwf/{tanf/ut_tanf_payment_standard.py => fep/ut_fep_payment_standard.py} (65%) delete mode 100644 policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_gross_income_eligible.py diff --git a/policyengine_us/parameters/gov/states/ut/dwf/tanf/income/deductions/earned_income_disregard/rate.yaml b/policyengine_us/parameters/gov/states/ut/dwf/fep/income/deductions/earned_income_disregard/rate.yaml similarity index 65% rename from policyengine_us/parameters/gov/states/ut/dwf/tanf/income/deductions/earned_income_disregard/rate.yaml rename to policyengine_us/parameters/gov/states/ut/dwf/fep/income/deductions/earned_income_disregard/rate.yaml index ecd824aa11a..030267cda36 100644 --- a/policyengine_us/parameters/gov/states/ut/dwf/tanf/income/deductions/earned_income_disregard/rate.yaml +++ b/policyengine_us/parameters/gov/states/ut/dwf/fep/income/deductions/earned_income_disregard/rate.yaml @@ -5,8 +5,8 @@ metadata: period: month label: Utah FEP earned income disregard rate reference: - - title: Utah Admin Code R986-200-239 - href: https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules + - title: Utah Admin. Code R986-200-239(2)(b) + href: https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R986-200-239 values: 2022-10-01: 0.5 diff --git a/policyengine_us/parameters/gov/states/ut/dwf/tanf/income/deductions/work_expense_allowance/amount.yaml b/policyengine_us/parameters/gov/states/ut/dwf/fep/income/deductions/work_expense_allowance/amount.yaml similarity index 66% rename from policyengine_us/parameters/gov/states/ut/dwf/tanf/income/deductions/work_expense_allowance/amount.yaml rename to policyengine_us/parameters/gov/states/ut/dwf/fep/income/deductions/work_expense_allowance/amount.yaml index 55cc9ddb674..867458ae12e 100644 --- a/policyengine_us/parameters/gov/states/ut/dwf/tanf/income/deductions/work_expense_allowance/amount.yaml +++ b/policyengine_us/parameters/gov/states/ut/dwf/fep/income/deductions/work_expense_allowance/amount.yaml @@ -5,8 +5,8 @@ metadata: period: month label: Utah FEP work expense allowance amount reference: - - title: Utah Admin Code R986-200-239 - href: https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules + - title: Utah Admin. Code R986-200-239(2)(a) + href: https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R986-200-239 values: 2022-10-01: 100 diff --git a/policyengine_us/parameters/gov/states/ut/dwf/fep/income/gross_income_limit/rate.yaml b/policyengine_us/parameters/gov/states/ut/dwf/fep/income/gross_income_limit/rate.yaml new file mode 100644 index 00000000000..30d82e55018 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dwf/fep/income/gross_income_limit/rate.yaml @@ -0,0 +1,12 @@ +description: Utah limits gross income to this share of the Standard Needs Budget under the Family Employment Program. + +metadata: + unit: /1 + period: month + label: Utah FEP gross income limit rate + reference: + - title: Utah Admin. Code R986-200-239(1) + href: https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R986-200-239 + +values: + 2022-10-01: 1.85 diff --git a/policyengine_us/parameters/gov/states/ut/dwf/tanf/payment_standard/amount.yaml b/policyengine_us/parameters/gov/states/ut/dwf/fep/payment_standard/amount.yaml similarity index 62% rename from policyengine_us/parameters/gov/states/ut/dwf/tanf/payment_standard/amount.yaml rename to policyengine_us/parameters/gov/states/ut/dwf/fep/payment_standard/amount.yaml index e45dd03d46e..0de622d246a 100644 --- a/policyengine_us/parameters/gov/states/ut/dwf/tanf/payment_standard/amount.yaml +++ b/policyengine_us/parameters/gov/states/ut/dwf/fep/payment_standard/amount.yaml @@ -7,8 +7,10 @@ metadata: - range(1, 20) label: Utah FEP maximum benefit amount reference: - - title: Utah Admin Code R986-200-246 - href: https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules + - title: Utah Admin. Code R986-200-239 + href: https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R986-200-239 + - title: Utah DWS Table 1 - Financial Monthly Income Limits and Assistance Amounts + href: https://jobs.utah.gov/Infosource/eligibilitymanual/Tables,_Appendicies,_and_Charts/Tables,_Appendicies,_and_Charts/Table_1_-_Financial_Monthly_Income_Limits_and_Assistance_Amounts.htm 1: 2022-10-01: 383 diff --git a/policyengine_us/parameters/gov/states/ut/dwf/fep/payment_standard/max_unit_size.yaml b/policyengine_us/parameters/gov/states/ut/dwf/fep/payment_standard/max_unit_size.yaml new file mode 100644 index 00000000000..301903ecb4a --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dwf/fep/payment_standard/max_unit_size.yaml @@ -0,0 +1,12 @@ +description: Utah defines the Family Employment Program payment schedule up to this maximum household size. + +metadata: + unit: person + period: month + label: Utah FEP maximum unit size for payment schedule + reference: + - title: Utah DWS Table 1 - Financial Monthly Income Limits and Assistance Amounts + href: https://jobs.utah.gov/Infosource/eligibilitymanual/Tables,_Appendicies,_and_Charts/Tables,_Appendicies,_and_Charts/Table_1_-_Financial_Monthly_Income_Limits_and_Assistance_Amounts.htm + +values: + 2022-10-01: 19 diff --git a/policyengine_us/parameters/gov/states/ut/dwf/tanf/resources/limit/amount.yaml b/policyengine_us/parameters/gov/states/ut/dwf/fep/resources/limit/amount.yaml similarity index 65% rename from policyengine_us/parameters/gov/states/ut/dwf/tanf/resources/limit/amount.yaml rename to policyengine_us/parameters/gov/states/ut/dwf/fep/resources/limit/amount.yaml index b95fa29919c..e4bc343296c 100644 --- a/policyengine_us/parameters/gov/states/ut/dwf/tanf/resources/limit/amount.yaml +++ b/policyengine_us/parameters/gov/states/ut/dwf/fep/resources/limit/amount.yaml @@ -5,8 +5,8 @@ metadata: period: month label: Utah FEP resource limit amount reference: - - title: Utah Admin Code R986-200-240 - href: https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules + - title: Utah Admin. Code R986-200-230(5) + href: https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R986-200-230 values: 2022-10-01: 2_000 diff --git a/policyengine_us/parameters/gov/states/ut/dwf/fep/standard_needs_budget/amount.yaml b/policyengine_us/parameters/gov/states/ut/dwf/fep/standard_needs_budget/amount.yaml new file mode 100644 index 00000000000..4dd96603dbb --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dwf/fep/standard_needs_budget/amount.yaml @@ -0,0 +1,52 @@ +description: Utah Standard Needs Budget (SNB) for the Family Employment Program, based on household size. The SNB is determined by the Department based on a survey of basic living expenses per R986-200-239(1). + +metadata: + unit: currency-USD + period: month + breakdown: + - range(1, 20) + label: Utah FEP Standard Needs Budget (SNB) + reference: + - title: Utah Admin. Code R986-200-239(1) + href: https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R986-200-239 + - title: Utah DWS Table 1 - Financial Monthly Income Limits and Assistance Amounts + href: https://jobs.utah.gov/Infosource/eligibilitymanual/Tables,_Appendicies,_and_Charts/Tables,_Appendicies,_and_Charts/Table_1_-_Financial_Monthly_Income_Limits_and_Assistance_Amounts.htm + +1: + 2022-10-01: 329 +2: + 2022-10-01: 456 +3: + 2022-10-01: 568 +4: + 2022-10-01: 665 +5: + 2022-10-01: 757 +6: + 2022-10-01: 834 +7: + 2022-10-01: 873 +8: + 2022-10-01: 914 +9: + 2022-10-01: 955 +10: + 2022-10-01: 996 +11: + 2022-10-01: 1_037 +12: + 2022-10-01: 1_078 +13: + 2022-10-01: 1_119 +14: + 2022-10-01: 1_160 +15: + 2022-10-01: 1_201 +16: + 2022-10-01: 1_242 +17: + 2022-10-01: 1_283 +18: + 2022-10-01: 1_324 +19: + 2022-10-01: 1_365 diff --git a/policyengine_us/parameters/gov/states/ut/dwf/tanf/income/gross_income_limit/amount.yaml b/policyengine_us/parameters/gov/states/ut/dwf/tanf/income/gross_income_limit/amount.yaml deleted file mode 100644 index d5d50561496..00000000000 --- a/policyengine_us/parameters/gov/states/ut/dwf/tanf/income/gross_income_limit/amount.yaml +++ /dev/null @@ -1,50 +0,0 @@ -description: Utah limits the Family Employment Program to households with gross income at or below this amount, based on household size. - -metadata: - unit: currency-USD - period: month - breakdown: - - range(1, 20) - label: Utah FEP gross income limit amount - reference: - - title: Utah Admin Code R986-200-238 - href: https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules - -1: - 2022-10-01: 608 -2: - 2022-10-01: 843 -3: - 2022-10-01: 1_050 -4: - 2022-10-01: 1_230 -5: - 2022-10-01: 1_400 -6: - 2022-10-01: 1_542 -7: - 2022-10-01: 1_615 -8: - 2022-10-01: 1_690 -9: - 2022-10-01: 1_765 -10: - 2022-10-01: 1_840 -11: - 2022-10-01: 1_915 -12: - 2022-10-01: 1_990 -13: - 2022-10-01: 2_065 -14: - 2022-10-01: 2_140 -15: - 2022-10-01: 2_215 -16: - 2022-10-01: 2_290 -17: - 2022-10-01: 2_365 -18: - 2022-10-01: 2_440 -19: - 2022-10-01: 2_515 diff --git a/policyengine_us/parameters/gov/states/ut/dwf/tanf/income/net_income_limit/amount.yaml b/policyengine_us/parameters/gov/states/ut/dwf/tanf/income/net_income_limit/amount.yaml deleted file mode 100644 index 3a5aebdf670..00000000000 --- a/policyengine_us/parameters/gov/states/ut/dwf/tanf/income/net_income_limit/amount.yaml +++ /dev/null @@ -1,50 +0,0 @@ -description: Utah limits the Family Employment Program to households with net countable income below this amount, based on household size. - -metadata: - unit: currency-USD - period: month - breakdown: - - range(1, 20) - label: Utah FEP net income limit amount - reference: - - title: Utah Admin Code R986-200-238 - href: https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules - -1: - 2022-10-01: 329 -2: - 2022-10-01: 456 -3: - 2022-10-01: 568 -4: - 2022-10-01: 665 -5: - 2022-10-01: 757 -6: - 2022-10-01: 834 -7: - 2022-10-01: 873 -8: - 2022-10-01: 914 -9: - 2022-10-01: 955 -10: - 2022-10-01: 996 -11: - 2022-10-01: 1_037 -12: - 2022-10-01: 1_078 -13: - 2022-10-01: 1_119 -14: - 2022-10-01: 1_160 -15: - 2022-10-01: 1_201 -16: - 2022-10-01: 1_242 -17: - 2022-10-01: 1_283 -18: - 2022-10-01: 1_324 -19: - 2022-10-01: 1_365 diff --git a/policyengine_us/parameters/gov/states/ut/dwf/tanf/payment_standard/max_unit_size.yaml b/policyengine_us/parameters/gov/states/ut/dwf/tanf/payment_standard/max_unit_size.yaml deleted file mode 100644 index bff3776f0e9..00000000000 --- a/policyengine_us/parameters/gov/states/ut/dwf/tanf/payment_standard/max_unit_size.yaml +++ /dev/null @@ -1,12 +0,0 @@ -description: Utah defines the Family Employment Program payment schedule up to this maximum household size. - -metadata: - unit: person - period: month - label: Utah FEP maximum unit size for payment schedule - reference: - - title: Utah Admin Code R986-200-246 - href: https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules - -values: - 2022-10-01: 19 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/benefit/ut_tanf_payment_standard.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/fep/benefit/ut_fep_payment_standard.yaml similarity index 79% rename from policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/benefit/ut_tanf_payment_standard.yaml rename to policyengine_us/tests/policy/baseline/gov/states/ut/dwf/fep/benefit/ut_fep_payment_standard.yaml index 84ec5f48399..b514ad54bd8 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/benefit/ut_tanf_payment_standard.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/fep/benefit/ut_fep_payment_standard.yaml @@ -1,4 +1,4 @@ -# Unit tests for ut_tanf_payment_standard (maximum benefit by family size) +# Unit tests for ut_fep_payment_standard (maximum benefit by family size) # Payment standard is 87.5% of Standard Needs Budget (SNB) # Reference: Utah Admin. Code R986-200-239 # Source: https://jobs.utah.gov/Infosource/eligibilitymanual/Tables @@ -14,7 +14,7 @@ state_code: UT spm_unit_size: 1 output: - ut_tanf_payment_standard: 383 + ut_fep_payment_standard: 383 - name: Family size 2 - payment standard $531. period: 2024-01 @@ -22,7 +22,7 @@ state_code: UT spm_unit_size: 2 output: - ut_tanf_payment_standard: 531 + ut_fep_payment_standard: 531 - name: Family size 3 - payment standard $662. period: 2024-01 @@ -30,7 +30,7 @@ state_code: UT spm_unit_size: 3 output: - ut_tanf_payment_standard: 662 + ut_fep_payment_standard: 662 - name: Family size 4 - payment standard $775. period: 2024-01 @@ -38,7 +38,7 @@ state_code: UT spm_unit_size: 4 output: - ut_tanf_payment_standard: 775 + ut_fep_payment_standard: 775 - name: Family size 5 - payment standard $882. period: 2024-01 @@ -46,7 +46,7 @@ state_code: UT spm_unit_size: 5 output: - ut_tanf_payment_standard: 882 + ut_fep_payment_standard: 882 - name: Family size 6 - payment standard $972. period: 2024-01 @@ -54,7 +54,7 @@ state_code: UT spm_unit_size: 6 output: - ut_tanf_payment_standard: 972 + ut_fep_payment_standard: 972 - name: Family size 7 - payment standard $1,017. period: 2024-01 @@ -62,7 +62,7 @@ state_code: UT spm_unit_size: 7 output: - ut_tanf_payment_standard: 1_017 + ut_fep_payment_standard: 1_017 - name: Family size 8 - payment standard $1,065. period: 2024-01 @@ -70,4 +70,4 @@ state_code: UT spm_unit_size: 8 output: - ut_tanf_payment_standard: 1_065 + ut_fep_payment_standard: 1_065 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/fep/eligibility/ut_fep_eligible.yaml similarity index 61% rename from policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_eligible.yaml rename to policyengine_us/tests/policy/baseline/gov/states/ut/dwf/fep/eligibility/ut_fep_eligible.yaml index e467eda5594..87aaab0efe4 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/fep/eligibility/ut_fep_eligible.yaml @@ -1,4 +1,4 @@ -# Unit tests for ut_tanf_eligible (final eligibility determination) +# Unit tests for ut_fep_eligible (final eligibility determination) # Utah TANF eligibility requires: # - Demographic eligibility (uses federal baseline) # - Income eligibility (gross and net tests) @@ -10,47 +10,47 @@ input: state_code: UT is_demographic_tanf_eligible: true - ut_tanf_income_eligible: true - ut_tanf_resource_eligible: true + ut_fep_income_eligible: true + ut_fep_resources_eligible: true output: - ut_tanf_eligible: true + ut_fep_eligible: true - name: Demographic ineligible - not eligible. period: 2024-01 input: state_code: UT is_demographic_tanf_eligible: false - ut_tanf_income_eligible: true - ut_tanf_resource_eligible: true + ut_fep_income_eligible: true + ut_fep_resources_eligible: true output: - ut_tanf_eligible: false + ut_fep_eligible: false - name: Income ineligible - not eligible. period: 2024-01 input: state_code: UT is_demographic_tanf_eligible: true - ut_tanf_income_eligible: false - ut_tanf_resource_eligible: true + ut_fep_income_eligible: false + ut_fep_resources_eligible: true output: - ut_tanf_eligible: false + ut_fep_eligible: false - name: Resource ineligible - not eligible. period: 2024-01 input: state_code: UT is_demographic_tanf_eligible: true - ut_tanf_income_eligible: true - ut_tanf_resource_eligible: false + ut_fep_income_eligible: true + ut_fep_resources_eligible: false output: - ut_tanf_eligible: false + ut_fep_eligible: false - name: All criteria not met - not eligible. period: 2024-01 input: state_code: UT is_demographic_tanf_eligible: false - ut_tanf_income_eligible: false - ut_tanf_resource_eligible: false + ut_fep_income_eligible: false + ut_fep_resources_eligible: false output: - ut_tanf_eligible: false + ut_fep_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_gross_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/fep/eligibility/ut_fep_gross_income_eligible.yaml similarity index 86% rename from policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_gross_income_eligible.yaml rename to policyengine_us/tests/policy/baseline/gov/states/ut/dwf/fep/eligibility/ut_fep_gross_income_eligible.yaml index 5c4e9ce608b..312c5c7de6c 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_gross_income_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/fep/eligibility/ut_fep_gross_income_eligible.yaml @@ -1,4 +1,4 @@ -# Unit tests for ut_tanf_gross_income_eligible (185% SNB gross income test) +# Unit tests for ut_fep_gross_income_eligible (185% SNB gross income test) # Gross income must be <= 185% of Standard Needs Budget # Reference: Utah Admin. Code R986-200-239 # @@ -16,7 +16,7 @@ output: # Gross limit for size 3 = $1,050 # Gross income = 0 <= 1,050 - eligible - ut_tanf_gross_income_eligible: true + ut_fep_gross_income_eligible: true - name: Gross income below limit - eligible (family size 3). period: 2024-01 @@ -28,7 +28,7 @@ output: # Gross limit for size 3 = $1,050 # Gross income = 500 + 200 = 700 <= 1,050 - eligible - ut_tanf_gross_income_eligible: true + ut_fep_gross_income_eligible: true - name: Gross income at limit - eligible (family size 3). period: 2024-01 @@ -40,7 +40,7 @@ output: # Gross limit for size 3 = $1,050 # Gross income = 800 + 250 = 1,050 <= 1,050 - eligible - ut_tanf_gross_income_eligible: true + ut_fep_gross_income_eligible: true - name: Gross income above limit - ineligible (family size 3). period: 2024-01 @@ -52,7 +52,7 @@ output: # Gross limit for size 3 = $1,050 # Gross income = 900 + 200 = 1,100 > 1,050 - ineligible - ut_tanf_gross_income_eligible: false + ut_fep_gross_income_eligible: false - name: Gross income at limit for family size 1. period: 2024-01 @@ -64,7 +64,7 @@ output: # Gross limit for size 1 = $608 # Gross income = 608 <= 608 - eligible - ut_tanf_gross_income_eligible: true + ut_fep_gross_income_eligible: true - name: Gross income above limit for family size 1. period: 2024-01 @@ -76,7 +76,7 @@ output: # Gross limit for size 1 = $608 # Gross income = 609 > 608 - ineligible - ut_tanf_gross_income_eligible: false + ut_fep_gross_income_eligible: false - name: Larger family size 5 with income at limit. period: 2024-01 @@ -88,4 +88,4 @@ output: # Gross limit for size 5 = $1,400 # Gross income = 1,000 + 400 = 1,400 <= 1,400 - eligible - ut_tanf_gross_income_eligible: true + ut_fep_gross_income_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/fep/eligibility/ut_fep_income_eligible.yaml similarity index 55% rename from policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_income_eligible.yaml rename to policyengine_us/tests/policy/baseline/gov/states/ut/dwf/fep/eligibility/ut_fep_income_eligible.yaml index 5ba7036997c..fbdaa459dbd 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_income_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/fep/eligibility/ut_fep_income_eligible.yaml @@ -1,4 +1,4 @@ -# Unit tests for ut_tanf_income_eligible (combined income eligibility) +# Unit tests for ut_fep_income_eligible (combined income eligibility) # Utah uses a two-step income test: # 1. Gross income must be <= 185% of SNB # 2. Net income must be < 100% of SNB @@ -8,34 +8,34 @@ period: 2024-01 input: state_code: UT - ut_tanf_gross_income_eligible: true - ut_tanf_net_income_eligible: true + ut_fep_gross_income_eligible: true + ut_fep_net_income_eligible: true output: - ut_tanf_income_eligible: true + ut_fep_income_eligible: true - name: Gross income eligible but net income ineligible - not eligible. period: 2024-01 input: state_code: UT - ut_tanf_gross_income_eligible: true - ut_tanf_net_income_eligible: false + ut_fep_gross_income_eligible: true + ut_fep_net_income_eligible: false output: - ut_tanf_income_eligible: false + ut_fep_income_eligible: false - name: Net income eligible but gross income ineligible - not eligible. period: 2024-01 input: state_code: UT - ut_tanf_gross_income_eligible: false - ut_tanf_net_income_eligible: true + ut_fep_gross_income_eligible: false + ut_fep_net_income_eligible: true output: - ut_tanf_income_eligible: false + ut_fep_income_eligible: false - name: Both gross and net income ineligible - not eligible. period: 2024-01 input: state_code: UT - ut_tanf_gross_income_eligible: false - ut_tanf_net_income_eligible: false + ut_fep_gross_income_eligible: false + ut_fep_net_income_eligible: false output: - ut_tanf_income_eligible: false + ut_fep_income_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_net_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/fep/eligibility/ut_fep_net_income_eligible.yaml similarity index 75% rename from policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_net_income_eligible.yaml rename to policyengine_us/tests/policy/baseline/gov/states/ut/dwf/fep/eligibility/ut_fep_net_income_eligible.yaml index ce8c026300b..e7ea6ac50fc 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_net_income_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/fep/eligibility/ut_fep_net_income_eligible.yaml @@ -1,4 +1,4 @@ -# Unit tests for ut_tanf_net_income_eligible (100% SNB net income test) +# Unit tests for ut_fep_net_income_eligible (100% SNB net income test) # Net income must be < 100% of Standard Needs Budget (strict less than) # Reference: Utah Admin. Code R986-200-239 # @@ -11,74 +11,74 @@ input: state_code: UT spm_unit_size: 3 - ut_tanf_countable_income: 0 + ut_fep_countable_income: 0 output: # Net limit for size 3 = $568 # Net income = 0 < 568 - eligible - ut_tanf_net_income_eligible: true + ut_fep_net_income_eligible: true - name: Net income below limit - eligible (family size 3). period: 2024-01 input: state_code: UT spm_unit_size: 3 - ut_tanf_countable_income: 400 + ut_fep_countable_income: 400 output: # Net limit for size 3 = $568 # Net income = 400 < 568 - eligible - ut_tanf_net_income_eligible: true + ut_fep_net_income_eligible: true - name: Net income at limit - ineligible (family size 3). period: 2024-01 input: state_code: UT spm_unit_size: 3 - ut_tanf_countable_income: 568 + ut_fep_countable_income: 568 output: # Net limit for size 3 = $568 # Net income = 568 NOT < 568 - ineligible (strict less than) - ut_tanf_net_income_eligible: false + ut_fep_net_income_eligible: false - name: Net income above limit - ineligible (family size 3). period: 2024-01 input: state_code: UT spm_unit_size: 3 - ut_tanf_countable_income: 600 + ut_fep_countable_income: 600 output: # Net limit for size 3 = $568 # Net income = 600 > 568 - ineligible - ut_tanf_net_income_eligible: false + ut_fep_net_income_eligible: false - name: Net income just below limit - eligible (family size 3). period: 2024-01 input: state_code: UT spm_unit_size: 3 - ut_tanf_countable_income: 567 + ut_fep_countable_income: 567 output: # Net limit for size 3 = $568 # Net income = 567 < 568 - eligible - ut_tanf_net_income_eligible: true + ut_fep_net_income_eligible: true - name: Net income at limit for family size 1. period: 2024-01 input: state_code: UT spm_unit_size: 1 - ut_tanf_countable_income: 329 + ut_fep_countable_income: 329 output: # Net limit for size 1 = $329 # Net income = 329 NOT < 329 - ineligible (strict less than) - ut_tanf_net_income_eligible: false + ut_fep_net_income_eligible: false - name: Net income below limit for family size 5. period: 2024-01 input: state_code: UT spm_unit_size: 5 - ut_tanf_countable_income: 500 + ut_fep_countable_income: 500 output: # Net limit for size 5 = $757 # Net income = 500 < 757 - eligible - ut_tanf_net_income_eligible: true + ut_fep_net_income_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_resource_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/fep/eligibility/ut_fep_resources_eligible.yaml similarity index 78% rename from policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_resource_eligible.yaml rename to policyengine_us/tests/policy/baseline/gov/states/ut/dwf/fep/eligibility/ut_fep_resources_eligible.yaml index fc7e17d9a27..8b3585d907a 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/eligibility/ut_tanf_resource_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/fep/eligibility/ut_fep_resources_eligible.yaml @@ -1,4 +1,4 @@ -# Unit tests for ut_tanf_resource_eligible (resource/asset test) +# Unit tests for ut_fep_resources_eligible (resource/asset test) # Countable resources must not exceed $2,000 # Reference: Utah Admin. Code R986-200-230 @@ -8,7 +8,7 @@ state_code: UT spm_unit_assets: 0 output: - ut_tanf_resource_eligible: true + ut_fep_resources_eligible: true - name: Resources below limit - eligible. period: 2024-01 @@ -17,7 +17,7 @@ spm_unit_assets: 1_500 output: # Resources = 1,500 <= 2,000 - eligible - ut_tanf_resource_eligible: true + ut_fep_resources_eligible: true - name: Resources at limit - eligible. period: 2024-01 @@ -26,7 +26,7 @@ spm_unit_assets: 2_000 output: # Resources = 2,000 <= 2,000 - eligible - ut_tanf_resource_eligible: true + ut_fep_resources_eligible: true - name: Resources above limit - ineligible. period: 2024-01 @@ -35,7 +35,7 @@ spm_unit_assets: 2_001 output: # Resources = 2,001 > 2,000 - ineligible - ut_tanf_resource_eligible: false + ut_fep_resources_eligible: false - name: Resources significantly above limit - ineligible. period: 2024-01 @@ -44,4 +44,4 @@ spm_unit_assets: 5_000 output: # Resources = 5,000 > 2,000 - ineligible - ut_tanf_resource_eligible: false + ut_fep_resources_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/income/ut_tanf_countable_earned_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/fep/income/ut_fep_countable_earned_income.yaml similarity index 91% rename from policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/income/ut_tanf_countable_earned_income.yaml rename to policyengine_us/tests/policy/baseline/gov/states/ut/dwf/fep/income/ut_fep_countable_earned_income.yaml index aa5dce1787d..300a9aeece9 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/income/ut_tanf_countable_earned_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/fep/income/ut_fep_countable_earned_income.yaml @@ -1,4 +1,4 @@ -# Unit tests for ut_tanf_countable_earned_income +# Unit tests for ut_fep_countable_earned_income # Utah applies earned income deductions then counts the remainder: # 1. Work expense allowance: $100 per employed person # 2. 50% earned income disregard on remaining earned income @@ -22,7 +22,7 @@ state_code: UT output: # No earnings = no countable earned income - ut_tanf_countable_earned_income: 0 + ut_fep_countable_earned_income: 0 - name: Single employed person with $500 earnings. period: 2024-01 @@ -42,7 +42,7 @@ output: # After work expense = max(500 - 100, 0) = 400 # Countable = 400 * 0.50 = 200 - ut_tanf_countable_earned_income: 200 + ut_fep_countable_earned_income: 200 - name: Single employed person with $1,000 earnings. period: 2024-01 @@ -62,7 +62,7 @@ output: # After work expense = max(1000 - 100, 0) = 900 # Countable = 900 * 0.50 = 450 - ut_tanf_countable_earned_income: 450 + ut_fep_countable_earned_income: 450 - name: Two employed persons with earnings. period: 2024-01 @@ -84,7 +84,7 @@ # Person2 after work expense = max(400 - 100, 0) = 300 # Total after work expense = 800 # Countable = 800 * 0.50 = 400 - ut_tanf_countable_earned_income: 400 + ut_fep_countable_earned_income: 400 - name: Earnings less than work expense deduction. period: 2024-01 @@ -104,7 +104,7 @@ output: # After work expense = max(80 - 100, 0) = 0 # Countable = 0 * 0.50 = 0 - ut_tanf_countable_earned_income: 0 + ut_fep_countable_earned_income: 0 - name: Earnings exactly equal to work expense. period: 2024-01 @@ -124,4 +124,4 @@ output: # After work expense = max(100 - 100, 0) = 0 # Countable = 0 * 0.50 = 0 - ut_tanf_countable_earned_income: 0 + ut_fep_countable_earned_income: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/income/ut_tanf_earned_income_after_work_expense.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/fep/income/ut_fep_earned_income_after_work_expense.yaml similarity index 80% rename from policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/income/ut_tanf_earned_income_after_work_expense.yaml rename to policyengine_us/tests/policy/baseline/gov/states/ut/dwf/fep/income/ut_fep_earned_income_after_work_expense.yaml index 6ff8222bc07..c81ce3e4aec 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/income/ut_tanf_earned_income_after_work_expense.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/fep/income/ut_fep_earned_income_after_work_expense.yaml @@ -1,4 +1,4 @@ -# Unit tests for ut_tanf_earned_income_after_work_expense (Person-level) +# Unit tests for ut_fep_earned_income_after_work_expense (Person-level) # Earned income after $100 work expense deduction per person # Formula: max(earned_income - 100, 0) # Reference: Utah Admin. Code R986-200-239(2)(a) @@ -14,7 +14,7 @@ members: [person1] state_code: UT output: - ut_tanf_earned_income_after_work_expense: 0 + ut_fep_earned_income_after_work_expense: 0 - name: Earned income $500. period: 2024-01 @@ -28,7 +28,7 @@ state_code: UT output: # max(500 - 100, 0) = 400 - ut_tanf_earned_income_after_work_expense: 400 + ut_fep_earned_income_after_work_expense: 400 - name: Earned income less than $100. period: 2024-01 @@ -42,7 +42,7 @@ state_code: UT output: # max(80 - 100, 0) = 0 - ut_tanf_earned_income_after_work_expense: 0 + ut_fep_earned_income_after_work_expense: 0 - name: Earned income exactly $100. period: 2024-01 @@ -56,4 +56,4 @@ state_code: UT output: # max(100 - 100, 0) = 0 - ut_tanf_earned_income_after_work_expense: 0 + ut_fep_earned_income_after_work_expense: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/fep/integration.yaml similarity index 80% rename from policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/integration.yaml rename to policyengine_us/tests/policy/baseline/gov/states/ut/dwf/fep/integration.yaml index b65c654c6dd..d79a711b1c3 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/fep/integration.yaml @@ -40,14 +40,14 @@ # Resources = $500 <= $2,000 -> PASS # Eligible = true # Benefit = Payment standard ($531) - Countable income (0) = $531 - ut_tanf_payment_standard: 531 - ut_tanf_gross_income_eligible: true - ut_tanf_countable_income: 0 - ut_tanf_net_income_eligible: true - ut_tanf_resource_eligible: true - ut_tanf_income_eligible: true - ut_tanf_eligible: true - ut_tanf: 531 + ut_fep_payment_standard: 531 + ut_fep_gross_income_eligible: true + ut_fep_countable_income: 0 + ut_fep_net_income_eligible: true + ut_fep_resources_eligible: true + ut_fep_income_eligible: true + ut_fep_eligible: true + ut_fep: 531 - name: Case 2 - Single parent with two children, moderate earnings, partial benefit. period: 2024-01 @@ -84,15 +84,15 @@ # Resources = $1,000 <= $2,000 -> PASS # Eligible = true # Benefit = Payment standard ($662) - Countable income ($250) = $412 - ut_tanf_payment_standard: 662 - ut_tanf_countable_earned_income: 250 - ut_tanf_gross_income_eligible: true - ut_tanf_countable_income: 250 - ut_tanf_net_income_eligible: true - ut_tanf_resource_eligible: true - ut_tanf_income_eligible: true - ut_tanf_eligible: true - ut_tanf: 412 + ut_fep_payment_standard: 662 + ut_fep_countable_earned_income: 250 + ut_fep_gross_income_eligible: true + ut_fep_countable_income: 250 + ut_fep_net_income_eligible: true + ut_fep_resources_eligible: true + ut_fep_income_eligible: true + ut_fep_eligible: true + ut_fep: 412 - name: Case 3 - Two-parent family with three children, both employed. period: 2024-01 @@ -136,15 +136,15 @@ # Resources = $1,500 <= $2,000 -> PASS # Eligible = true # Benefit = Payment standard ($882) - Countable income ($250) = $632 - ut_tanf_payment_standard: 882 - ut_tanf_countable_earned_income: 250 - ut_tanf_gross_income_eligible: true - ut_tanf_countable_income: 250 - ut_tanf_net_income_eligible: true - ut_tanf_resource_eligible: true - ut_tanf_income_eligible: true - ut_tanf_eligible: true - ut_tanf: 632 + ut_fep_payment_standard: 882 + ut_fep_countable_earned_income: 250 + ut_fep_gross_income_eligible: true + ut_fep_countable_income: 250 + ut_fep_net_income_eligible: true + ut_fep_resources_eligible: true + ut_fep_income_eligible: true + ut_fep_eligible: true + ut_fep: 632 - name: Case 4 - Ineligible due to gross income exceeding 185% SNB. period: 2024-01 @@ -173,11 +173,11 @@ # Gross income = $1,200, Gross limit = $843 (185% SNB) # $1,200 > $843 -> FAIL gross income test # Ineligible, benefit = $0 - ut_tanf_payment_standard: 531 - ut_tanf_gross_income_eligible: false - ut_tanf_income_eligible: false - ut_tanf_eligible: false - ut_tanf: 0 + ut_fep_payment_standard: 531 + ut_fep_gross_income_eligible: false + ut_fep_income_eligible: false + ut_fep_eligible: false + ut_fep: 0 - name: Case 5 - Ineligible due to gross income with mixed income sources. period: 2024-01 @@ -206,11 +206,11 @@ # Gross income = $800 + $200 = $1,000 # Gross limit = $843 (185% SNB for size 2) # $1,000 > $843 -> FAIL gross income test - ut_tanf_payment_standard: 531 - ut_tanf_gross_income_eligible: false - ut_tanf_income_eligible: false - ut_tanf_eligible: false - ut_tanf: 0 + ut_fep_payment_standard: 531 + ut_fep_gross_income_eligible: false + ut_fep_income_eligible: false + ut_fep_eligible: false + ut_fep: 0 - name: Case 6 - Ineligible due to excess resources. period: 2024-01 @@ -243,15 +243,15 @@ # Net limit = $456, $150 < $456 -> PASS # Resources = $3,000 > $2,000 -> FAIL # Ineligible due to excess resources - ut_tanf_payment_standard: 531 - ut_tanf_countable_earned_income: 150 - ut_tanf_gross_income_eligible: true - ut_tanf_countable_income: 150 - ut_tanf_net_income_eligible: true - ut_tanf_resource_eligible: false - ut_tanf_income_eligible: true - ut_tanf_eligible: false - ut_tanf: 0 + ut_fep_payment_standard: 531 + ut_fep_countable_earned_income: 150 + ut_fep_gross_income_eligible: true + ut_fep_countable_income: 150 + ut_fep_net_income_eligible: true + ut_fep_resources_eligible: false + ut_fep_income_eligible: true + ut_fep_eligible: false + ut_fep: 0 - name: Case 7 - Large family with unearned income only. period: 2024-01 @@ -293,12 +293,12 @@ # Resources = $1,200 <= $2,000 -> PASS # Eligible = true # Benefit = Payment standard ($882) - Countable income ($400) = $482 - ut_tanf_payment_standard: 882 - ut_tanf_countable_earned_income: 0 - ut_tanf_gross_income_eligible: true - ut_tanf_countable_income: 400 - ut_tanf_net_income_eligible: true - ut_tanf_resource_eligible: true - ut_tanf_income_eligible: true - ut_tanf_eligible: true - ut_tanf: 482 + ut_fep_payment_standard: 882 + ut_fep_countable_earned_income: 0 + ut_fep_gross_income_eligible: true + ut_fep_countable_income: 400 + ut_fep_net_income_eligible: true + ut_fep_resources_eligible: true + ut_fep_income_eligible: true + ut_fep_eligible: true + ut_fep: 482 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/ut_tanf.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/fep/ut_fep.yaml similarity index 80% rename from policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/ut_tanf.yaml rename to policyengine_us/tests/policy/baseline/gov/states/ut/dwf/fep/ut_fep.yaml index b1ce9e95ef4..6dd2be032bb 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/tanf/ut_tanf.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/fep/ut_fep.yaml @@ -32,13 +32,13 @@ members: [parent, child1, child2] state_code: UT output: - ut_tanf_countable_earned_income: 450 * 12 # $450/month * 12 - ut_tanf_countable_income: 450 * 12 # $450/month * 12 - ut_tanf_income_eligible: true - ut_tanf_resource_eligible: true - ut_tanf_eligible: true - ut_tanf_payment_standard: 662 * 12 # $662/month * 12 - ut_tanf: 212 * 12 # $212/month * 12 + ut_fep_countable_earned_income: 450 * 12 # $450/month * 12 + ut_fep_countable_income: 450 * 12 # $450/month * 12 + ut_fep_income_eligible: true + ut_fep_resources_eligible: true + ut_fep_eligible: true + ut_fep_payment_standard: 662 * 12 # $662/month * 12 + ut_fep: 212 * 12 # $212/month * 12 # Test case: Family over gross income limit # Gross income = $1,200/month (earned) @@ -64,9 +64,9 @@ members: [parent, child1, child2] state_code: UT output: - ut_tanf_income_eligible: false - ut_tanf_eligible: false - ut_tanf: 0 + ut_fep_income_eligible: false + ut_fep_eligible: false + ut_fep: 0 # Test case: Family over resource limit @@ -88,6 +88,6 @@ members: [parent, child1] state_code: UT output: - ut_tanf_resource_eligible: false - ut_tanf_eligible: false - ut_tanf: 0 + ut_fep_resources_eligible: false + ut_fep_eligible: false + ut_fep: 0 diff --git a/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_eligible.py b/policyengine_us/variables/gov/states/ut/dwf/fep/eligibility/ut_fep_eligible.py similarity index 64% rename from policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_eligible.py rename to policyengine_us/variables/gov/states/ut/dwf/fep/eligibility/ut_fep_eligible.py index d943d9d56a9..f2aba83ce90 100644 --- a/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_eligible.py +++ b/policyengine_us/variables/gov/states/ut/dwf/fep/eligibility/ut_fep_eligible.py @@ -1,19 +1,17 @@ from policyengine_us.model_api import * -class ut_tanf_eligible(Variable): +class ut_fep_eligible(Variable): value_type = bool entity = SPMUnit label = "Eligible for Utah Family Employment Program" definition_period = MONTH - reference = ( - "https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules" - ) + reference = "https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R986-200-202" defined_for = StateCode.UT def formula(spm_unit, period, parameters): # Per R986-200: Must meet demographic, income, and resource tests demographic_eligible = spm_unit("is_demographic_tanf_eligible", period) - income_eligible = spm_unit("ut_tanf_income_eligible", period) - resource_eligible = spm_unit("ut_tanf_resource_eligible", period) + income_eligible = spm_unit("ut_fep_income_eligible", period) + resource_eligible = spm_unit("ut_fep_resources_eligible", period) return demographic_eligible & income_eligible & resource_eligible diff --git a/policyengine_us/variables/gov/states/ut/dwf/fep/eligibility/ut_fep_gross_income_eligible.py b/policyengine_us/variables/gov/states/ut/dwf/fep/eligibility/ut_fep_gross_income_eligible.py new file mode 100644 index 00000000000..162608520fe --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/dwf/fep/eligibility/ut_fep_gross_income_eligible.py @@ -0,0 +1,26 @@ +from policyengine_us.model_api import * + + +class ut_fep_gross_income_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Eligible for Utah TANF under gross income test" + definition_period = MONTH + reference = "https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R986-200-239" + defined_for = StateCode.UT + + def formula(spm_unit, period, parameters): + # Utah gross income test: gross income <= 185% of SNB (Standard Needs Budget) + # Per R986-200-239(1), gross income must be <= 185% of SNB + # The net income limit equals the SNB + p = parameters(period).gov.states.ut.dwf.tanf + + size = spm_unit("spm_unit_size", period) + size_capped = min_(size, p.payment_standard.max_unit_size) + + # Standard Needs Budget (SNB) = net income limit + snb = p.standard_needs_budget.amount[size_capped] + gross_income_limit = snb * p.income.gross_income_limit.rate + + gross_income = spm_unit("ut_fep_gross_income", period) + return gross_income <= gross_income_limit diff --git a/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_income_eligible.py b/policyengine_us/variables/gov/states/ut/dwf/fep/eligibility/ut_fep_income_eligible.py similarity index 56% rename from policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_income_eligible.py rename to policyengine_us/variables/gov/states/ut/dwf/fep/eligibility/ut_fep_income_eligible.py index 12176be8e73..959f076315a 100644 --- a/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_income_eligible.py +++ b/policyengine_us/variables/gov/states/ut/dwf/fep/eligibility/ut_fep_income_eligible.py @@ -1,18 +1,16 @@ from policyengine_us.model_api import * -class ut_tanf_income_eligible(Variable): +class ut_fep_income_eligible(Variable): value_type = bool entity = SPMUnit label = "Eligible for Utah Family Employment Program due to income" definition_period = MONTH - reference = ( - "https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules" - ) + reference = "https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R986-200-239" defined_for = StateCode.UT def formula(spm_unit, period, parameters): # Utah uses two-tier income test per R986-200-238 - gross_test = spm_unit("ut_tanf_gross_income_eligible", period) - net_test = spm_unit("ut_tanf_net_income_eligible", period) + gross_test = spm_unit("ut_fep_gross_income_eligible", period) + net_test = spm_unit("ut_fep_net_income_eligible", period) return gross_test & net_test diff --git a/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_net_income_eligible.py b/policyengine_us/variables/gov/states/ut/dwf/fep/eligibility/ut_fep_net_income_eligible.py similarity index 63% rename from policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_net_income_eligible.py rename to policyengine_us/variables/gov/states/ut/dwf/fep/eligibility/ut_fep_net_income_eligible.py index e6d71acaa53..13f1c98e0bd 100644 --- a/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_net_income_eligible.py +++ b/policyengine_us/variables/gov/states/ut/dwf/fep/eligibility/ut_fep_net_income_eligible.py @@ -1,14 +1,12 @@ from policyengine_us.model_api import * -class ut_tanf_net_income_eligible(Variable): +class ut_fep_net_income_eligible(Variable): value_type = bool entity = SPMUnit label = "Eligible for Utah TANF under net income test" definition_period = MONTH - reference = ( - "https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules" - ) + reference = "https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R986-200-239" defined_for = StateCode.UT def formula(spm_unit, period, parameters): @@ -18,5 +16,5 @@ def formula(spm_unit, period, parameters): size = spm_unit("spm_unit_size", period) size_capped = min_(size, p.payment_standard.max_unit_size) - countable_income = spm_unit("ut_tanf_countable_income", period) - return countable_income < p.income.net_income_limit.amount[size_capped] + countable_income = spm_unit("ut_fep_countable_income", period) + return countable_income < p.standard_needs_budget.amount[size_capped] diff --git a/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_resource_eligible.py b/policyengine_us/variables/gov/states/ut/dwf/fep/eligibility/ut_fep_resources_eligible.py similarity index 66% rename from policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_resource_eligible.py rename to policyengine_us/variables/gov/states/ut/dwf/fep/eligibility/ut_fep_resources_eligible.py index e926da8c115..3b09ded7e1d 100644 --- a/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_resource_eligible.py +++ b/policyengine_us/variables/gov/states/ut/dwf/fep/eligibility/ut_fep_resources_eligible.py @@ -1,18 +1,16 @@ from policyengine_us.model_api import * -class ut_tanf_resource_eligible(Variable): +class ut_fep_resources_eligible(Variable): value_type = bool entity = SPMUnit label = "Eligible for Utah Family Employment Program due to resources" definition_period = MONTH - reference = ( - "https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules" - ) + reference = "https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R986-200-230" defined_for = StateCode.UT def formula(spm_unit, period, parameters): - p = parameters(period).gov.states.ut.dwf.tanf.resources.limit + p = parameters(period).gov.states.ut.dwf.fep.resources.limit # Use federal spm_unit_assets variable directly assets = spm_unit("spm_unit_assets", period.this_year) return assets <= p.amount diff --git a/policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_countable_earned_income.py b/policyengine_us/variables/gov/states/ut/dwf/fep/income/ut_fep_countable_earned_income.py similarity index 68% rename from policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_countable_earned_income.py rename to policyengine_us/variables/gov/states/ut/dwf/fep/income/ut_fep_countable_earned_income.py index 0bbda89e711..617d415f460 100644 --- a/policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_countable_earned_income.py +++ b/policyengine_us/variables/gov/states/ut/dwf/fep/income/ut_fep_countable_earned_income.py @@ -1,24 +1,22 @@ from policyengine_us.model_api import * -class ut_tanf_countable_earned_income(Variable): +class ut_fep_countable_earned_income(Variable): value_type = float entity = SPMUnit label = "Utah TANF countable earned income" unit = USD definition_period = MONTH - reference = ( - "https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules" - ) + reference = "https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R986-200-239" defined_for = StateCode.UT def formula(spm_unit, period, parameters): # Utah earned income after deductions per R986-200-239: # 1. Work expense allowance: $100 per employed person # 2. 50% earned income disregard on remaining earned income - p = parameters(period).gov.states.ut.dwf.tanf.income.deductions + p = parameters(period).gov.states.ut.dwf.fep.income.deductions after_work_expense = add( - spm_unit, period, ["ut_tanf_earned_income_after_work_expense"] + spm_unit, period, ["ut_fep_earned_income_after_work_expense"] ) # Countable = remainder * (1 - disregard_rate) = remainder * 0.5 return after_work_expense * (1 - p.earned_income_disregard.rate) diff --git a/policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_countable_income.py b/policyengine_us/variables/gov/states/ut/dwf/fep/income/ut_fep_countable_income.py similarity index 60% rename from policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_countable_income.py rename to policyengine_us/variables/gov/states/ut/dwf/fep/income/ut_fep_countable_income.py index 7c90107e3cd..7336c0aa8ba 100644 --- a/policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_countable_income.py +++ b/policyengine_us/variables/gov/states/ut/dwf/fep/income/ut_fep_countable_income.py @@ -1,18 +1,16 @@ from policyengine_us.model_api import * -class ut_tanf_countable_income(Variable): +class ut_fep_countable_income(Variable): value_type = float entity = SPMUnit label = "Utah Family Employment Program countable income" unit = USD definition_period = MONTH - reference = ( - "https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules" - ) + reference = "https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R986-200-239" defined_for = StateCode.UT adds = [ - "ut_tanf_countable_earned_income", + "ut_fep_countable_earned_income", "tanf_gross_unearned_income", ] diff --git a/policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_earned_income_after_work_expense.py b/policyengine_us/variables/gov/states/ut/dwf/fep/income/ut_fep_earned_income_after_work_expense.py similarity index 67% rename from policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_earned_income_after_work_expense.py rename to policyengine_us/variables/gov/states/ut/dwf/fep/income/ut_fep_earned_income_after_work_expense.py index b7759112c7f..8eb89ae20e5 100644 --- a/policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_earned_income_after_work_expense.py +++ b/policyengine_us/variables/gov/states/ut/dwf/fep/income/ut_fep_earned_income_after_work_expense.py @@ -1,19 +1,17 @@ from policyengine_us.model_api import * -class ut_tanf_earned_income_after_work_expense(Variable): +class ut_fep_earned_income_after_work_expense(Variable): value_type = float entity = Person label = "Utah TANF earned income after work expense deduction" unit = USD definition_period = MONTH - reference = ( - "https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules" - ) + reference = "https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R986-200-239" defined_for = StateCode.UT def formula(person, period, parameters): # $100 work expense deduction per employed person - p = parameters(period).gov.states.ut.dwf.tanf.income.deductions + p = parameters(period).gov.states.ut.dwf.fep.income.deductions earned_income = person("tanf_gross_earned_income", period) return max_(earned_income - p.work_expense_allowance.amount, 0) diff --git a/policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_gross_income.py b/policyengine_us/variables/gov/states/ut/dwf/fep/income/ut_fep_gross_income.py similarity index 69% rename from policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_gross_income.py rename to policyengine_us/variables/gov/states/ut/dwf/fep/income/ut_fep_gross_income.py index f7db4938717..e2c28ce89b2 100644 --- a/policyengine_us/variables/gov/states/ut/dwf/tanf/income/ut_tanf_gross_income.py +++ b/policyengine_us/variables/gov/states/ut/dwf/fep/income/ut_fep_gross_income.py @@ -1,15 +1,13 @@ from policyengine_us.model_api import * -class ut_tanf_gross_income(Variable): +class ut_fep_gross_income(Variable): value_type = float entity = SPMUnit label = "Utah Family Employment Program gross income" unit = USD definition_period = MONTH - reference = ( - "https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules" - ) + reference = "https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R986-200-239" defined_for = StateCode.UT adds = [ diff --git a/policyengine_us/variables/gov/states/ut/dwf/tanf/ut_tanf.py b/policyengine_us/variables/gov/states/ut/dwf/fep/ut_fep.py similarity index 54% rename from policyengine_us/variables/gov/states/ut/dwf/tanf/ut_tanf.py rename to policyengine_us/variables/gov/states/ut/dwf/fep/ut_fep.py index b6c1a9328a7..71a1761c2a5 100644 --- a/policyengine_us/variables/gov/states/ut/dwf/tanf/ut_tanf.py +++ b/policyengine_us/variables/gov/states/ut/dwf/fep/ut_fep.py @@ -1,19 +1,17 @@ from policyengine_us.model_api import * -class ut_tanf(Variable): +class ut_fep(Variable): value_type = float entity = SPMUnit label = "Utah Family Employment Program benefit" unit = USD definition_period = MONTH - reference = ( - "https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules" - ) - defined_for = "ut_tanf_eligible" + reference = "https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R986-200-239" + defined_for = "ut_fep_eligible" def formula(spm_unit, period, parameters): # Per R986-200-246: Benefit = payment standard - countable income - payment_standard = spm_unit("ut_tanf_payment_standard", period) - countable_income = spm_unit("ut_tanf_countable_income", period) + payment_standard = spm_unit("ut_fep_payment_standard", period) + countable_income = spm_unit("ut_fep_countable_income", period) return max_(payment_standard - countable_income, 0) diff --git a/policyengine_us/variables/gov/states/ut/dwf/tanf/ut_tanf_payment_standard.py b/policyengine_us/variables/gov/states/ut/dwf/fep/ut_fep_payment_standard.py similarity index 65% rename from policyengine_us/variables/gov/states/ut/dwf/tanf/ut_tanf_payment_standard.py rename to policyengine_us/variables/gov/states/ut/dwf/fep/ut_fep_payment_standard.py index 4f667ca14c1..9d66d20d7c2 100644 --- a/policyengine_us/variables/gov/states/ut/dwf/tanf/ut_tanf_payment_standard.py +++ b/policyengine_us/variables/gov/states/ut/dwf/fep/ut_fep_payment_standard.py @@ -1,19 +1,17 @@ from policyengine_us.model_api import * -class ut_tanf_payment_standard(Variable): +class ut_fep_payment_standard(Variable): value_type = float entity = SPMUnit label = "Utah Family Employment Program payment standard" unit = USD definition_period = MONTH - reference = ( - "https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules" - ) + reference = "https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R986-200-239" defined_for = StateCode.UT def formula(spm_unit, period, parameters): - p = parameters(period).gov.states.ut.dwf.tanf.payment_standard + p = parameters(period).gov.states.ut.dwf.fep.payment_standard size = spm_unit("spm_unit_size", period) size_capped = min_(size, p.max_unit_size) return p.amount[size_capped] diff --git a/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_gross_income_eligible.py b/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_gross_income_eligible.py deleted file mode 100644 index 63e102fb64e..00000000000 --- a/policyengine_us/variables/gov/states/ut/dwf/tanf/eligibility/ut_tanf_gross_income_eligible.py +++ /dev/null @@ -1,22 +0,0 @@ -from policyengine_us.model_api import * - - -class ut_tanf_gross_income_eligible(Variable): - value_type = bool - entity = SPMUnit - label = "Eligible for Utah TANF under gross income test" - definition_period = MONTH - reference = ( - "https://adminrules.utah.gov/public/rule/R986-200/Current%20Rules" - ) - defined_for = StateCode.UT - - def formula(spm_unit, period, parameters): - # Utah gross income test: gross income <= 185% of SNB - p = parameters(period).gov.states.ut.dwf.tanf - - size = spm_unit("spm_unit_size", period) - size_capped = min_(size, p.payment_standard.max_unit_size) - - gross_income = spm_unit("ut_tanf_gross_income", period) - return gross_income <= p.income.gross_income_limit.amount[size_capped] From c164e2f77ae11f88dcc11cde1eb8a14400459c25 Mon Sep 17 00:00:00 2001 From: Ziming Date: Wed, 10 Dec 2025 19:26:08 -0500 Subject: [PATCH 5/6] minor --- .../ut/dwf/fep/eligibility/ut_fep_gross_income_eligible.py | 2 +- .../states/ut/dwf/fep/eligibility/ut_fep_net_income_eligible.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/policyengine_us/variables/gov/states/ut/dwf/fep/eligibility/ut_fep_gross_income_eligible.py b/policyengine_us/variables/gov/states/ut/dwf/fep/eligibility/ut_fep_gross_income_eligible.py index 162608520fe..eaada2f06c0 100644 --- a/policyengine_us/variables/gov/states/ut/dwf/fep/eligibility/ut_fep_gross_income_eligible.py +++ b/policyengine_us/variables/gov/states/ut/dwf/fep/eligibility/ut_fep_gross_income_eligible.py @@ -13,7 +13,7 @@ def formula(spm_unit, period, parameters): # Utah gross income test: gross income <= 185% of SNB (Standard Needs Budget) # Per R986-200-239(1), gross income must be <= 185% of SNB # The net income limit equals the SNB - p = parameters(period).gov.states.ut.dwf.tanf + p = parameters(period).gov.states.ut.dwf.fep size = spm_unit("spm_unit_size", period) size_capped = min_(size, p.payment_standard.max_unit_size) diff --git a/policyengine_us/variables/gov/states/ut/dwf/fep/eligibility/ut_fep_net_income_eligible.py b/policyengine_us/variables/gov/states/ut/dwf/fep/eligibility/ut_fep_net_income_eligible.py index 13f1c98e0bd..303c125ebfe 100644 --- a/policyengine_us/variables/gov/states/ut/dwf/fep/eligibility/ut_fep_net_income_eligible.py +++ b/policyengine_us/variables/gov/states/ut/dwf/fep/eligibility/ut_fep_net_income_eligible.py @@ -11,7 +11,7 @@ class ut_fep_net_income_eligible(Variable): def formula(spm_unit, period, parameters): # Utah net income test: countable income < 100% of SNB (strict less than) - p = parameters(period).gov.states.ut.dwf.tanf + p = parameters(period).gov.states.ut.dwf.fep size = spm_unit("spm_unit_size", period) size_capped = min_(size, p.payment_standard.max_unit_size) From a14b7509f17760784d07b5046a5b53eecafaef6a Mon Sep 17 00:00:00 2001 From: Ziming Date: Sat, 13 Dec 2025 01:21:47 -0500 Subject: [PATCH 6/6] minor --- .../ut/dwf/fep/payment_standard/amount.yaml | 22 +++++++++---------- .../dwf/fep/standard_needs_budget/amount.yaml | 22 +++++++++---------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/policyengine_us/parameters/gov/states/ut/dwf/fep/payment_standard/amount.yaml b/policyengine_us/parameters/gov/states/ut/dwf/fep/payment_standard/amount.yaml index 0de622d246a..5620880b9e3 100644 --- a/policyengine_us/parameters/gov/states/ut/dwf/fep/payment_standard/amount.yaml +++ b/policyengine_us/parameters/gov/states/ut/dwf/fep/payment_standard/amount.yaml @@ -29,24 +29,24 @@ metadata: 8: 2022-10-01: 1_065 9: - 2022-10-01: 1_113 + 2022-10-01: 1_116 10: - 2022-10-01: 1_161 + 2022-10-01: 1_162 11: - 2022-10-01: 1_209 + 2022-10-01: 1_210 12: - 2022-10-01: 1_257 + 2022-10-01: 1_258 13: - 2022-10-01: 1_305 + 2022-10-01: 1_306 14: - 2022-10-01: 1_353 + 2022-10-01: 1_354 15: - 2022-10-01: 1_401 + 2022-10-01: 1_403 16: - 2022-10-01: 1_449 + 2022-10-01: 1_450 17: - 2022-10-01: 1_497 + 2022-10-01: 1_498 18: - 2022-10-01: 1_545 + 2022-10-01: 1_546 19: - 2022-10-01: 1_593 + 2022-10-01: 1_594 diff --git a/policyengine_us/parameters/gov/states/ut/dwf/fep/standard_needs_budget/amount.yaml b/policyengine_us/parameters/gov/states/ut/dwf/fep/standard_needs_budget/amount.yaml index 4dd96603dbb..714446e8f13 100644 --- a/policyengine_us/parameters/gov/states/ut/dwf/fep/standard_needs_budget/amount.yaml +++ b/policyengine_us/parameters/gov/states/ut/dwf/fep/standard_needs_budget/amount.yaml @@ -29,24 +29,24 @@ metadata: 8: 2022-10-01: 914 9: - 2022-10-01: 955 + 2022-10-01: 957 10: - 2022-10-01: 996 + 2022-10-01: 997 11: - 2022-10-01: 1_037 + 2022-10-01: 1_038 12: - 2022-10-01: 1_078 + 2022-10-01: 1_079 13: - 2022-10-01: 1_119 + 2022-10-01: 1_120 14: - 2022-10-01: 1_160 + 2022-10-01: 1_161 15: - 2022-10-01: 1_201 + 2022-10-01: 1_203 16: - 2022-10-01: 1_242 + 2022-10-01: 1_244 17: - 2022-10-01: 1_283 + 2022-10-01: 1_285 18: - 2022-10-01: 1_324 + 2022-10-01: 1_326 19: - 2022-10-01: 1_365 + 2022-10-01: 1_367