From b755b7d049ae454a30585c0967fef9754740bff2 Mon Sep 17 00:00:00 2001 From: Ziming Date: Wed, 7 Jan 2026 20:10:03 -0500 Subject: [PATCH 01/10] cherry pick files --- changelog_entry.yaml | 4 + .../gov/states/md/tanf/age_limit.yaml | 9 ++ .../childcare_expenses/full_time.yaml | 12 +++ .../childcare_expenses/part_time.yaml | 12 +++ .../deductions/earned/fulltime_hours.yaml | 11 +++ .../states/md/tanf/income/sources/earned.yaml | 12 +++ .../md/tanf/income/sources/unearned.yaml | 26 ++++++ .../md_tanf_childcare_deduction.yaml | 56 ++++++++++++ ...md_tanf_continuous_earnings_deduction.yaml | 35 ++++++++ .../md_tanf_initial_earnings_deduction.yaml | 39 ++++++++ .../income/md_tanf_net_countable_income.yaml | 68 ++++++++++++++ .../md_tanf_net_initial_countable_income.yaml | 68 ++++++++++++++ ...md_tanf_gross_earned_income_deduction.yaml | 8 +- ..._tanf_countable_gross_unearned_income.yaml | 37 ++++++++ .../baseline/gov/states/md/tanf/md_tanf.yaml | 89 +++++++++++++++++++ .../gov/states/md/tanf/md_tanf_is_child.yaml | 43 +++++++++ .../md/tanf/md_tanf_maximum_benefit.yaml | 15 ++++ .../person/work_hours_per_week.yaml | 15 ++++ .../deductions/md_tanf_childcare_deduction.py | 26 ++++++ .../md_tanf_continuous_earnings_deduction.py | 28 ++++++ .../md_tanf_initial_earnings_deduction.py | 30 +++++++ .../md_tanf_countable_gross_earned_income.py | 14 +++ .../md_tanf_gross_earned_income_deduction.py | 2 +- .../income/md_tanf_net_countable_income.py | 44 +++++++++ .../md_tanf_net_initial_countable_income.py | 44 +++++++++ ...md_tanf_countable_gross_unearned_income.py | 20 +++++ .../income/unearned/md_tanf_gross_unearned.py | 14 +++ .../variables/gov/states/md/tanf/md_tanf.py | 21 +++++ .../states/md/tanf/md_tanf_count_children.py | 4 +- .../gov/states/md/tanf/md_tanf_eligible.py | 2 + .../gov/states/md/tanf/md_tanf_is_child.py | 26 ++++++ .../states/md/tanf/md_tanf_maximum_benefit.py | 2 + .../md/tanf/md_tanf_self_employment_income.py | 14 +++ .../person/work_hours/work_days_per_week.py | 9 ++ .../person/work_hours/work_hours_per_day.py | 9 ++ .../person/work_hours/work_hours_per_week.py | 14 +++ 36 files changed, 876 insertions(+), 6 deletions(-) create mode 100644 policyengine_us/parameters/gov/states/md/tanf/age_limit.yaml create mode 100644 policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/full_time.yaml create mode 100644 policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/part_time.yaml create mode 100644 policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/fulltime_hours.yaml create mode 100644 policyengine_us/parameters/gov/states/md/tanf/income/sources/earned.yaml create mode 100644 policyengine_us/parameters/gov/states/md/tanf/income/sources/unearned.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_countable_income.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_is_child.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_maximum_benefit.yaml create mode 100644 policyengine_us/tests/policy/baseline/household/demographic/person/work_hours_per_week.yaml create mode 100644 policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.py create mode 100644 policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.py create mode 100644 policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.py create mode 100644 policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_countable_gross_earned_income.py create mode 100644 policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_countable_income.py create mode 100644 policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.py create mode 100644 policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.py create mode 100644 policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_gross_unearned.py create mode 100644 policyengine_us/variables/gov/states/md/tanf/md_tanf.py create mode 100644 policyengine_us/variables/gov/states/md/tanf/md_tanf_is_child.py create mode 100644 policyengine_us/variables/gov/states/md/tanf/md_tanf_self_employment_income.py create mode 100644 policyengine_us/variables/household/demographic/person/work_hours/work_days_per_week.py create mode 100644 policyengine_us/variables/household/demographic/person/work_hours/work_hours_per_day.py create mode 100644 policyengine_us/variables/household/demographic/person/work_hours/work_hours_per_week.py diff --git a/changelog_entry.yaml b/changelog_entry.yaml index e69de29bb2d..55ce5da3286 100644 --- a/changelog_entry.yaml +++ b/changelog_entry.yaml @@ -0,0 +1,4 @@ +- bump: minor + changes: + added: + - Implement Maryland TANF program. diff --git a/policyengine_us/parameters/gov/states/md/tanf/age_limit.yaml b/policyengine_us/parameters/gov/states/md/tanf/age_limit.yaml new file mode 100644 index 00000000000..a70c0b5d31b --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/tanf/age_limit.yaml @@ -0,0 +1,9 @@ +description: Maryland provides the TANF benefit for children below this age threshold. +values: + 2022-11-01: 19 +metadata: + unit: age + label: Maryland TANF age limit + reference: + - title: Family investment administration temporary cash assistance manual - Age + href: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0300-Technical-Eligibility/0307%20Age%20rev%2011.22.doc diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/full_time.yaml b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/full_time.yaml new file mode 100644 index 00000000000..0496d496ec5 --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/full_time.yaml @@ -0,0 +1,12 @@ +description: Maryland excludes this portion of the childcare expenses from TANF countable earned income for full-time enrollees. + +values: + 2022-11-01: 200 + +metadata: + period: year + unit: currency-USD + label: Maryland TANF childcare expense exclusion for full-time enrollees + reference: + - title: Maryland TEMPORARY CASH ASSISTANCE MANUAL 904.1 DEDUCTIONS FROM EARNED INCOME + href: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0904%20Deductions%20and%20Expenses%20rev%2011.22.1.doc diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/part_time.yaml b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/part_time.yaml new file mode 100644 index 00000000000..8b7e0d4ce27 --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/part_time.yaml @@ -0,0 +1,12 @@ +description: Maryland excludes this portion of the childcare expenses from TANF countable earned income for part-time enrollees. + +values: + 2022-11-01: 100 + +metadata: + period: year + unit: currency-USD + label: Maryland TANF childcare expense exclusion for part-time enrollees + reference: + - title: Maryland TEMPORARY CASH ASSISTANCE MANUAL 904.1 DEDUCTIONS FROM EARNED INCOME + href: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0904%20Deductions%20and%20Expenses%20rev%2011.22.1.doc diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/fulltime_hours.yaml b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/fulltime_hours.yaml new file mode 100644 index 00000000000..01ac38aceab --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/fulltime_hours.yaml @@ -0,0 +1,11 @@ +description: Maryland requires this amount of monthly work hours for full-time eligibility under the TANF program. + +values: + 2022-11-01: 100 + +metadata: + period: year + label: Maryland TANF monthly work hours requirement for full-time enrollees + reference: + - title: Maryland TEMPORARY CASH ASSISTANCE MANUAL 904.1 DEDUCTIONS FROM EARNED INCOME + href: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0904%20Deductions%20and%20Expenses%20rev%2011.22.1.doc diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/sources/earned.yaml b/policyengine_us/parameters/gov/states/md/tanf/income/sources/earned.yaml new file mode 100644 index 00000000000..974c7a5675e --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/tanf/income/sources/earned.yaml @@ -0,0 +1,12 @@ +description: Maryland TANF counts these income sources as earned income. +values: + 2022-11-01: + - employment_income + - self_employment_income + - armed_services_basic_allowance_for_housing +metadata: + unit: list + label: Maryland TANF earned income + reference: + - title: Family investment administration temporary cash assistance manual - Financial Eligibility + href: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0902%20TCA%20Earned%20Income%20rev%2011.22.doc diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/sources/unearned.yaml b/policyengine_us/parameters/gov/states/md/tanf/income/sources/unearned.yaml new file mode 100644 index 00000000000..f066306b410 --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/tanf/income/sources/unearned.yaml @@ -0,0 +1,26 @@ +description: Maryland TANF counts these income sources as unearned income. +values: + 2022-11-01: + - pension_income +# - investment_income + - social_security +# - sick_accident + - alimony_income +# - monetary_gifts + - dividend_income + - interest_income +# - lottery_winnings +# - lawsuit_settlements +# - inheritances +# - rent_subsidies +# - worker_compensation + - unemployment_compensation + - veterans_benefits + # - criminal_injuries_compensation + +metadata: + unit: list + label: Maryland TANF unearned income + reference: + - title: Family investment administration temporary cash assistance manual - Financial Eligibility + href: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0903%20Unearned%20Income%2011.22.doc diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.yaml new file mode 100644 index 00000000000..5d1127a3545 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.yaml @@ -0,0 +1,56 @@ +- name: No children, part-time work, $0 deductions + period: 2023 + input: + people: + person1: + work_hours_per_week: 50 + person2: + work_hours_per_week: 60 + spm_units: + spm_unit: + members: [person1, person2] + md_tanf_count_children: 0 + households: + household: + state_code: MD + output: + md_tanf_childcare_deduction: 0 + +- name: 2 children, part-time work, $200 deductions + period: 2023 + input: + people: + person1: + work_hours_per_week: 50 + person2: + work_hours_per_week: 60 + spm_units: + spm_unit: + members: [person1, person2] + md_tanf_count_children: 2 + households: + household: + state_code: MD + output: + md_tanf_childcare_deduction: 200 + +- name: 2 children, full-time work, $400 deductions + period: 2023 + input: + people: + person1: + work_hours_per_week: 100 + person2: + work_hours_per_week: 60 + spm_units: + spm_unit: + members: [person1, person2] + md_tanf_count_children: 2 + households: + household: + state_code: MD + output: + md_tanf_childcare_deduction: 400 + + + diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.yaml new file mode 100644 index 00000000000..ede1fbfca1b --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.yaml @@ -0,0 +1,35 @@ +- name: If zero earned income, zero deduction. + period: 2023 + input: + md_tanf_countable_gross_earned_income: 0 + md_tanf_self_employment_income: 0 + state_code: MD + output: + md_tanf_continuous_earnings_deduction: 0 + +- name: If not self-employed, 40% deduction. + period: 2023 + input: + md_tanf_countable_gross_earned_income: 100 + md_tanf_self_employment_income: 0 + state_code: MD + output: + md_tanf_continuous_earnings_deduction: 40 + +- name: If self-employed, 50% deduction. + period: 2023 + input: + md_tanf_countable_gross_earned_income: 100 + md_tanf_self_employment_income: 100 + state_code: MD + output: + md_tanf_continuous_earnings_deduction: 50 + +- name: If self-employed and non-self-employed, combined deduction + period: 2023 + input: + md_tanf_countable_gross_earned_income: 100 + md_tanf_self_employment_income: 80 + state_code: MD + output: + md_tanf_continuous_earnings_deduction: 48 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.yaml new file mode 100644 index 00000000000..357a812d6e3 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.yaml @@ -0,0 +1,39 @@ +- name: If zero earned income, zero deduction. + period: 2023 + input: + state_code: MD + md_tanf_countable_gross_earned_income: 0 + md_tanf_self_employment_income: 0 + output: + md_tanf_initial_earnings_deduction: 0 + + +- name: If not self-employed, new enrolled, 20% deduction. + period: 2023 + input: + state_code: MD + is_tanf_enrolled: false + md_tanf_countable_gross_earned_income: 100 + md_tanf_self_employment_income: 0 + output: + md_tanf_initial_earnings_deduction: 20 + +- name: If self-employed, new enrolled, 50% deduction. + period: 2023 + input: + state_code: MD + is_tanf_enrolled: false + md_tanf_countable_gross_earned_income: 100 + md_tanf_self_employment_income: 100 + output: + md_tanf_initial_earnings_deduction: 50 + +- name: If partially self-employed, new enrolled, combined deduction. + period: 2023 + input: + state_code: MD + is_tanf_enrolled: false + md_tanf_countable_gross_earned_income: 100 + md_tanf_self_employment_income: 80 + output: + md_tanf_initial_earnings_deduction: 44 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_countable_income.yaml new file mode 100644 index 00000000000..7898a0b1282 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_countable_income.yaml @@ -0,0 +1,68 @@ +- name: No alimony, child support, or childcare, countinuous deductions of $40, earned income of $100, $60 per year + period: 2023 + input: + people: + person1: + alimony_income: 0 + child_support_received: 0 + person2: + alimony_income: 0 + child_support_received: 0 + spm_units: + spm_unit: + members: [person1, person2] + md_tanf_childcare_deduction: 0 + md_tanf_continuous_earnings_deduction: 40 + md_tanf_countable_gross_earned_income: 100 + md_tanf_countable_gross_unearned_income: 0 + households: + household: + state_code: MD + output: + md_tanf_net_countable_income: 60 + +- name: No alimony or childcare, child support of $10, countinuous deductions of $40, earned income of $100, $50 per year + period: 2023 + input: + people: + person1: + alimony_income: 0 + child_support_received: 10 + person2: + alimony_income: 0 + child_support_received: 0 + spm_units: + spm_unit: + members: [person1, person2] + md_tanf_childcare_deduction: 0 + md_tanf_continuous_earnings_deduction: 40 + md_tanf_countable_gross_earned_income: 100 + md_tanf_countable_gross_unearned_income: 0 + households: + household: + state_code: MD + output: + md_tanf_net_countable_income: 50 + +- name: No childcare or child support, alimony of $10, countinuous deductions of $40, earned income of $100, $50 per year + period: 2023 + input: + people: + person1: + alimony_income: 10 + child_support_received: 0 + person2: + alimony_income: 0 + child_support_received: 0 + spm_units: + spm_unit: + members: [person1, person2] + md_tanf_childcare_deduction: 0 + md_tanf_continuous_earnings_deduction: 40 + md_tanf_countable_gross_earned_income: 100 + md_tanf_countable_gross_unearned_income: 0 + households: + household: + state_code: MD + output: + md_tanf_net_countable_income: 50 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.yaml new file mode 100644 index 00000000000..cc56aa7d813 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.yaml @@ -0,0 +1,68 @@ +- name: No alimony, child support, or childcare, initial deductions of $40, earned income of $100, $60 per year + period: 2023 + input: + people: + person1: + alimony_income: 0 + child_support_received: 0 + person2: + alimony_income: 0 + child_support_received: 0 + spm_units: + spm_unit: + members: [person1, person2] + md_tanf_childcare_deduction: 0 + md_tanf_initial_earnings_deduction: 40 + md_tanf_countable_gross_earned_income: 100 + md_tanf_countable_gross_unearned_income: 0 + households: + household: + state_code: MD + output: + md_tanf_net_initial_countable_income: 60 + +- name: No alimony or childcare, child support of $10, initial deductions of $40, earned income of $100, $50 per year + period: 2023 + input: + people: + person1: + alimony_income: 0 + child_support_received: 10 + person2: + alimony_income: 0 + child_support_received: 0 + spm_units: + spm_unit: + members: [person1, person2] + md_tanf_childcare_deduction: 0 + md_tanf_initial_earnings_deduction: 40 + md_tanf_countable_gross_earned_income: 100 + md_tanf_countable_gross_unearned_income: 0 + households: + household: + state_code: MD + output: + md_tanf_net_initial_countable_income: 50 + +- name: No childcare or child support, alimony of $10, initial deductions of $40, earned income of $100, $50 per year + period: 2023 + input: + people: + person1: + alimony_income: 10 + child_support_received: 0 + person2: + alimony_income: 0 + child_support_received: 0 + spm_units: + spm_unit: + members: [person1, person2] + md_tanf_childcare_deduction: 0 + md_tanf_initial_earnings_deduction: 40 + md_tanf_countable_gross_earned_income: 100 + md_tanf_countable_gross_unearned_income: 0 + households: + household: + state_code: MD + output: + md_tanf_net_initial_countable_income: 50 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/md_tanf_gross_earned_income_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/md_tanf_gross_earned_income_deduction.yaml index e8fc19871cc..007cf6c7cb1 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/md_tanf_gross_earned_income_deduction.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/md_tanf_gross_earned_income_deduction.yaml @@ -2,7 +2,7 @@ period: 2023 input: state_code: MD - earned_income: 0 + employment_income: 0 output: md_tanf_gross_earned_income_deduction: 0 @@ -12,7 +12,7 @@ input: state_code: MD is_tanf_enrolled: false - earned_income: 100 + employment_income: 100 output: md_tanf_gross_earned_income_deduction: 20 @@ -22,7 +22,7 @@ state_code: MD is_tanf_enrolled: true self_employment_income: 0 - earned_income: 100 + employment_income: 100 output: md_tanf_gross_earned_income_deduction: 40 @@ -32,6 +32,6 @@ state_code: MD is_tanf_enrolled: true self_employment_income: 100 - earned_income: 100 + employment_income: 100 output: md_tanf_gross_earned_income_deduction: 50 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.yaml new file mode 100644 index 00000000000..4277cb4ff9a --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.yaml @@ -0,0 +1,37 @@ +- name: "Person1 10 child support, Person2 0 child support, not enrolled, 100 gross unearned, 100 countable gross unearned" + period: 2023 + input: + people: + person1: + child_support_received: 10 + person2: + child_support_received: 0 + spm_units: + spm_unit: + members: [person1, person2] + is_tanf_enrolled: false + md_tanf_gross_unearned: 100 + households: + household: + state_code: MD + output: + md_tanf_countable_gross_unearned_income: 100 + +- name: "Person1 10 child support, Person2 0 child support, enrolled, 100 gross unearned, 110 countable gross unearned" + period: 2023 + input: + people: + person1: + child_support_received: 10 + person2: + child_support_received: 0 + spm_units: + spm_unit: + members: [person1, person2] + is_tanf_enrolled: true + md_tanf_gross_unearned: 100 + households: + household: + state_code: MD + output: + md_tanf_countable_gross_unearned_income: 110 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf.yaml new file mode 100644 index 00000000000..dd9dbad8b8c --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf.yaml @@ -0,0 +1,89 @@ +- name: "Net gross earnings of 6000, family size of 3" + period: 2023 + input: + people: + person1: + employment_income: 12000 + taxable_self_employment_income: 0 + #armed_services_basic_allowance_for_housing: 0 + child_support_received: 0 + alimony_income: 1200 + person2: + employment_income: 0 + taxable_self_employment_income: 0 + #armed_services_basic_allowance_for_housing: 0 + child_support_received: 0 + alimony_income: 0 + person3: + employment_income: 0 + taxable_self_employment_income: 0 + #armed_services_basic_allowance_for_housing: 0 + child_support_received: 0 + alimony_income: 0 + spm_units: + spm_unit: + members: [person1, person2, person3] + md_tanf_maximum_benefit: 7632 + childcare_expenses: 2400 + md_tanf_net_countable_income: 6000 + households: + household: + state_code: MD + output: + md_tanf: 1632 + +- name: "Net gross earnings of 1560, family size of 2" + period: 2023 + input: + people: + person1: + employment_income: 3600 + taxable_self_employment_income: 0 + #armed_services_basic_allowance_for_housing: 0 + child_support_received: 0 + alimony_income: 0 + person2: + employment_income: 0 + taxable_self_employment_income: 0 + #armed_services_basic_allowance_for_housing: 0 + child_support_received: 0 + alimony_income: 0 + spm_units: + spm_unit: + members: [person1, person2] + md_tanf_maximum_benefit: 6036 + childcare_expenses: 600 + md_tanf_net_countable_income: 1560 + households: + household: + state_code: MD + output: + md_tanf: 4476 + +- name: "Net gross earnings of 7000, family size of 2" + period: 2023 + input: + people: + person1: + employment_income: 11000 + taxable_self_employment_income: 0 + #armed_services_basic_allowance_for_housing: 0 + child_support_received: 0 + alimony_income: 0 + person2: + employment_income: 0 + taxable_self_employment_income: 0 + #armed_services_basic_allowance_for_housing: 0 + child_support_received: 0 + alimony_income: 0 + spm_units: + spm_unit: + members: [person1, person2] + md_tanf_maximum_benefit: 6036 + childcare_expenses: 2400 + md_tanf_net_countable_income: 6600 + households: + household: + state_code: MD + output: + md_tanf: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_is_child.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_is_child.yaml new file mode 100644 index 00000000000..e40f1621666 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_is_child.yaml @@ -0,0 +1,43 @@ +- name: "Person who is age 20 and is full time student" + period: 2023 + input: + age: 20 + is_full_time_college_student: true + is_in_k12_school: false + state_code: MD + output: + md_tanf_is_child: false + + +- name: "Person who is age 18 and is full time k12 student" + period: 2023 + input: + age: 18 + is_full_time_college_student: false + is_in_k12_school: true + state_code: MD + output: + md_tanf_is_child: true + + +- name: "Person who is age 19 and is full time college student" + period: 2023 + input: + age: 19 + is_full_time_college_student: true + is_in_k12_school: false + state_code: MD + output: + md_tanf_is_child: true + + +- name: "Person who is age 19 and is full time k12 student" + period: 2023 + input: + age: 19 + is_full_time_college_student: false + is_in_k12_school: true + state_code: MD + output: + md_tanf_is_child: false + diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_maximum_benefit.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_maximum_benefit.yaml new file mode 100644 index 00000000000..f04441a57da --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_maximum_benefit.yaml @@ -0,0 +1,15 @@ +- name: One-person household has a maximum benefit of $328 per month. + period: 2023 + input: + md_tanf_eligible: true + spm_unit_size: 1 + output: + md_tanf_maximum_benefit: 328 * 12 + +- name: Ten-person household has a maximum benefit of $1,372 (8-person) + 2 * $136 = $1,644 per month. + period: 2023 + input: + md_tanf_eligible: true + spm_unit_size: 10 + output: + md_tanf_maximum_benefit: 1_644 * 12 diff --git a/policyengine_us/tests/policy/baseline/household/demographic/person/work_hours_per_week.yaml b/policyengine_us/tests/policy/baseline/household/demographic/person/work_hours_per_week.yaml new file mode 100644 index 00000000000..081ce3f5730 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/household/demographic/person/work_hours_per_week.yaml @@ -0,0 +1,15 @@ +- name: work 4 days per week, 8 hours per day, work hours per week is 32 + period: 2022 + input: + work_days_per_week: 4 + work_hours_per_day: 8 + output: + work_hours_per_week: 32 + +- name: work 4 days per week, 0 hours per day, work hours per week is 0 + period: 2022 + input: + work_days_per_week: 4 + work_hours_per_day: 0 + output: + work_hours_per_week: 0 diff --git a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.py b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.py new file mode 100644 index 00000000000..fb3f77b460d --- /dev/null +++ b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.py @@ -0,0 +1,26 @@ +from policyengine_us.model_api import * + + +# reference: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0904%20Deductions%20and%20Expenses%20rev%2011.22.1.doc +# page 1 +class md_tanf_childcare_deduction(Variable): + value_type = float + entity = SPMUnit + label = "Maryland TANF childcare deduction" + unit = USD + definition_period = YEAR + defined_for = StateCode.MD + + def formula(spm_unit, period, parameters): + children = spm_unit("md_tanf_count_children", period) + person = spm_unit.members + work_hours = person("work_hours_per_week", period) + # Get the policy parameters. + p = parameters(period).gov.states.md.tanf.income.deductions + full_time = spm_unit.any(work_hours >= p.earned.fulltime_hours) + + return children * where( + full_time, + p.childcare_expenses.full_time, + p.childcare_expenses.part_time, + ) diff --git a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.py b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.py new file mode 100644 index 00000000000..5269fe2991b --- /dev/null +++ b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.py @@ -0,0 +1,28 @@ +from policyengine_us.model_api import * + +# href: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0904%20Deductions%20and%20Expenses%20rev%2011.22.1.doc +# page 1 + + +class md_tanf_continuous_earnings_deduction(Variable): + value_type = float + entity = SPMUnit + label = "Maryland TANF continuous earnings deduction" + unit = USD + definition_period = YEAR + defined_for = StateCode.MD + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.md.tanf.income.deductions.earned + earned_income = spm_unit( + "md_tanf_countable_gross_earned_income", period + ) + self_employment_income = spm_unit( + "md_tanf_self_employment_income", period + ) + non_self_employment_income = max_( + earned_income - self_employment_income, 0 + ) + return (self_employment_income * p.self_employed) + ( + non_self_employment_income * p.not_self_employed + ) diff --git a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.py b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.py new file mode 100644 index 00000000000..3513f802277 --- /dev/null +++ b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.py @@ -0,0 +1,30 @@ +from policyengine_us.model_api import * + +# reference: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0902%20TCA%20Earned%20Income%20rev%2011.22.doc + + +class md_tanf_initial_earnings_deduction(Variable): + value_type = float + entity = SPMUnit + label = "Maryland TANF initial earnings deduction" + unit = USD + definition_period = YEAR + defined_for = StateCode.MD + + def formula(spm_unit, period, parameters): + person = spm_unit.members + # Get earned income for the SPM unit. + p = parameters(period).gov.states.md.tanf.income.deductions.earned + earned_income = spm_unit( + "md_tanf_countable_gross_earned_income", period + ) + # Determine if the SPM unit has any self-employment income. + self_employment_income = spm_unit( + "md_tanf_self_employment_income", period + ) + non_self_employment_income = earned_income - self_employment_income + # Get the policy parameters. + + return (self_employment_income * p.self_employed) + ( + non_self_employment_income * p.new + ) diff --git a/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_countable_gross_earned_income.py b/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_countable_gross_earned_income.py new file mode 100644 index 00000000000..f9310aba0e6 --- /dev/null +++ b/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_countable_gross_earned_income.py @@ -0,0 +1,14 @@ +from policyengine_us.model_api import * + +# reference: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0902%20TCA%20Earned%20Income%20rev%2011.22.doc + + +class md_tanf_countable_gross_earned_income(Variable): + value_type = float + entity = SPMUnit + label = "Maryland TANF countable gross earned income" + unit = USD + definition_period = YEAR + defined_for = StateCode.MD + + adds = "gov.states.md.tanf.income.sources.earned" diff --git a/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_gross_earned_income_deduction.py b/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_gross_earned_income_deduction.py index 721f6b00b35..525df8825a2 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_gross_earned_income_deduction.py +++ b/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_gross_earned_income_deduction.py @@ -13,7 +13,7 @@ def formula(spm_unit, period, parameters): # Get TANF enrollment status. is_tanf_enrolled = spm_unit("is_tanf_enrolled", period) # Get earned income for the SPM unit. - earned_income = add(spm_unit, period, ["earned_income"]) + earned_income = add(spm_unit, period, ["employment_income"]) # Determine if the SPM unit has any self-employment income. self_employment_income = add( spm_unit, period, ["self_employment_income"] diff --git a/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_countable_income.py b/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_countable_income.py new file mode 100644 index 00000000000..72c8e638aa6 --- /dev/null +++ b/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_countable_income.py @@ -0,0 +1,44 @@ +from policyengine_us.model_api import * + +# reference: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0902%20TCA%20Earned%20Income%20rev%2011.22.doc + + +class md_tanf_net_countable_income(Variable): + value_type = float + entity = SPMUnit + label = "Maryland TANF net countable income" + unit = USD + definition_period = YEAR + defined_for = StateCode.MD + + def formula(spm_unit, period, parameters): + # Get gross income for the SPM unit. + gross_earned_income = spm_unit( + "md_tanf_countable_gross_earned_income", period + ) + gross_unearned_income = spm_unit( + "md_tanf_countable_gross_unearned_income", period + ) + # Get countinuous deductions for the SPM unit. + continuous_deductions = spm_unit( + "md_tanf_continuous_earnings_deduction", period + ) + + # Get alimony deductions for the SPM unit. + person = spm_unit.members + alimony_deduction_ind = person("alimony_income", period) + alimony_deduction = spm_unit.sum(alimony_deduction_ind) + # Get child support deductions for the SPM unit. + child_support_deduction_ind = person("child_support_received", period) + child_support_deduction = spm_unit.sum(child_support_deduction_ind) + # Get childcare deductions for the SPM unit. + childcare_deduction = spm_unit("md_tanf_childcare_deduction", period) + + return ( + gross_earned_income + + gross_unearned_income + - continuous_deductions + - alimony_deduction + - child_support_deduction + - childcare_deduction + ) diff --git a/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.py b/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.py new file mode 100644 index 00000000000..d092ecf076b --- /dev/null +++ b/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.py @@ -0,0 +1,44 @@ +from policyengine_us.model_api import * + +# reference: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0902%20TCA%20Earned%20Income%20rev%2011.22.doc + + +class md_tanf_net_initial_countable_income(Variable): + value_type = float + entity = SPMUnit + label = "Maryland TANF net initial countable income" + unit = USD + definition_period = YEAR + defined_for = StateCode.MD + + def formula(spm_unit, period, parameters): + # Get gross income for the SPM unit. + gross_earned_income = spm_unit( + "md_tanf_countable_gross_earned_income", period + ) + gross_unearned_income = spm_unit( + "md_tanf_countable_gross_unearned_income", period + ) + # Get countinuous deductions for the SPM unit. + initial_deductions = spm_unit( + "md_tanf_initial_earnings_deduction", period + ) + # Get alimony deductions for the SPM unit. + + person = spm_unit.members + alimony_deduction_ind = person("alimony_income", period) + alimony_deduction = spm_unit.sum(alimony_deduction_ind) + # Get child support deductions for the SPM unit. + child_support_deduction_ind = person("child_support_received", period) + child_support_deduction = spm_unit.sum(child_support_deduction_ind) + # Get childcare deductions for the SPM unit. + childcare_deduction = spm_unit("md_tanf_childcare_deduction", period) + + return ( + gross_earned_income + + gross_unearned_income + - initial_deductions + - alimony_deduction + - child_support_deduction + - childcare_deduction + ) diff --git a/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.py b/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.py new file mode 100644 index 00000000000..253f710f266 --- /dev/null +++ b/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.py @@ -0,0 +1,20 @@ +from policyengine_us.model_api import * + +# reference: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0903%20Unearned%20Income%2011.22.doc + + +class md_tanf_countable_gross_unearned_income(Variable): + value_type = float + entity = SPMUnit + label = "Maryland TANF countable gross unearned income" + unit = USD + definition_period = YEAR + defined_for = StateCode.MD + + def formula(spm_unit, period, parameters): + person = spm_unit.members + gross_unearned = spm_unit("md_tanf_gross_unearned", period) + child_support = spm_unit.sum(person("child_support_received", period)) + enrolled = spm_unit("is_tanf_enrolled", period) + + return gross_unearned + enrolled * child_support diff --git a/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_gross_unearned.py b/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_gross_unearned.py new file mode 100644 index 00000000000..a2df07ff6a8 --- /dev/null +++ b/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_gross_unearned.py @@ -0,0 +1,14 @@ +from policyengine_us.model_api import * + +# reference: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0903%20Unearned%20Income%2011.22.doc + + +class md_tanf_gross_unearned(Variable): + value_type = float + entity = SPMUnit + label = "Maryland TANF countable gross unearned income" + unit = USD + definition_period = YEAR + defined_for = StateCode.MD + + adds = "gov.states.md.tanf.income.sources.unearned" diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf.py b/policyengine_us/variables/gov/states/md/tanf/md_tanf.py new file mode 100644 index 00000000000..5b1b28c8310 --- /dev/null +++ b/policyengine_us/variables/gov/states/md/tanf/md_tanf.py @@ -0,0 +1,21 @@ +from policyengine_us.model_api import * + +# reference: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0907%20Income%20Calculation%20of%20Ineligible%20Member%20rev%2011.22.doc + + +class md_tanf(Variable): + value_type = float + entity = SPMUnit + label = "Maryland TANF" + unit = USD + definition_period = YEAR + defined_for = StateCode.MD + + def formula(spm_unit, period, parameters): + # Maximum TANF amount recieved + grant_standard = spm_unit("md_tanf_maximum_benefit", period) + # SPM unit income after continuous deduction + income = spm_unit("md_tanf_net_countable_income", period) + # SPM Unit childcare deductions + childcare_deduction = spm_unit("md_tanf_childcare_deduction", period) + return max_(grant_standard - (income - childcare_deduction), 0) diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf_count_children.py b/policyengine_us/variables/gov/states/md/tanf/md_tanf_count_children.py index e89d31a1230..a8dbbe36afe 100644 --- a/policyengine_us/variables/gov/states/md/tanf/md_tanf_count_children.py +++ b/policyengine_us/variables/gov/states/md/tanf/md_tanf_count_children.py @@ -1,5 +1,7 @@ from policyengine_us.model_api import * +# reference: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0300-Technical-Eligibility/0307%20Age%20rev%2011.22.doc + class md_tanf_count_children(Variable): value_type = int @@ -7,4 +9,4 @@ class md_tanf_count_children(Variable): label = "Maryland TANF number of children" definition_period = YEAR defined_for = StateCode.MD - adds = "is_child" + adds = ["md_tanf_is_child"] diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf_eligible.py b/policyengine_us/variables/gov/states/md/tanf/md_tanf_eligible.py index 9894284fd6a..8e7bc029526 100644 --- a/policyengine_us/variables/gov/states/md/tanf/md_tanf_eligible.py +++ b/policyengine_us/variables/gov/states/md/tanf/md_tanf_eligible.py @@ -1,5 +1,7 @@ from policyengine_us.model_api import * +# reference:https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0300-Technical-Eligibility/0300%20Technical%20Eligibility%20Overview%20rev%2011.22.doc + class md_tanf_eligible(Variable): value_type = bool diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf_is_child.py b/policyengine_us/variables/gov/states/md/tanf/md_tanf_is_child.py new file mode 100644 index 00000000000..7cc9c38f468 --- /dev/null +++ b/policyengine_us/variables/gov/states/md/tanf/md_tanf_is_child.py @@ -0,0 +1,26 @@ +from policyengine_us.model_api import * + +# reference: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0300-Technical-Eligibility/0307%20Age%20rev%2011.22.doc + + +class md_tanf_is_child(Variable): + value_type = bool + entity = Person + definition_period = YEAR + label = "Is a child under Maryland TANF program" + defined_for = StateCode.MD + + def formula(person, period, parameters): + # younger than age 18 + child = person("is_child", period) + # Younger than age 19 and A full time k12 student + p = parameters(period).gov.states.md.tanf + age_eligible = person("age", period) < p.age_limit + k12 = person("is_in_k12_school", period) + k12_age_eligible = k12 & age_eligible + # age 19 and a full time student + years_19 = person("age", period) == p.age_limit + full_time_student = person("is_full_time_college_student", period) + school_enrolled_19_year_old = full_time_student & years_19 + # return + return child | school_enrolled_19_year_old | k12_age_eligible diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf_maximum_benefit.py b/policyengine_us/variables/gov/states/md/tanf/md_tanf_maximum_benefit.py index a4050f0adaf..ee240f3a877 100644 --- a/policyengine_us/variables/gov/states/md/tanf/md_tanf_maximum_benefit.py +++ b/policyengine_us/variables/gov/states/md/tanf/md_tanf_maximum_benefit.py @@ -1,5 +1,7 @@ from policyengine_us.model_api import * +# reference: https://dhs.maryland.gov/documents/Supplemental%20Nutrition%20Assistance%20Program%20(SNAP)/October-2020-Income-Guidelines-1-1.pdf (2) + class md_tanf_maximum_benefit(Variable): value_type = float diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf_self_employment_income.py b/policyengine_us/variables/gov/states/md/tanf/md_tanf_self_employment_income.py new file mode 100644 index 00000000000..0b89f7e69ba --- /dev/null +++ b/policyengine_us/variables/gov/states/md/tanf/md_tanf_self_employment_income.py @@ -0,0 +1,14 @@ +from policyengine_us.model_api import * + +# reference: "https://www.law.cornell.edu/uscode/text/26/1402#a" + + +class md_tanf_self_employment_income(Variable): + value_type = float + entity = SPMUnit + label = "Maryland TANF self employment income" + unit = USD + definition_period = YEAR + defined_for = StateCode.MD + + adds = "gov.irs.tax.self_employment.taxable_self_employment_income" diff --git a/policyengine_us/variables/household/demographic/person/work_hours/work_days_per_week.py b/policyengine_us/variables/household/demographic/person/work_hours/work_days_per_week.py new file mode 100644 index 00000000000..8474b7ce897 --- /dev/null +++ b/policyengine_us/variables/household/demographic/person/work_hours/work_days_per_week.py @@ -0,0 +1,9 @@ +from policyengine_us.model_api import * + + +class work_days_per_week(Variable): + value_type = float + entity = Person + label = "Work days per week" + definition_period = YEAR + unit = "day" diff --git a/policyengine_us/variables/household/demographic/person/work_hours/work_hours_per_day.py b/policyengine_us/variables/household/demographic/person/work_hours/work_hours_per_day.py new file mode 100644 index 00000000000..9aa02bfe0ea --- /dev/null +++ b/policyengine_us/variables/household/demographic/person/work_hours/work_hours_per_day.py @@ -0,0 +1,9 @@ +from policyengine_us.model_api import * + + +class work_hours_per_day(Variable): + value_type = float + entity = Person + label = "Work hours per day" + definition_period = YEAR + unit = "hour" diff --git a/policyengine_us/variables/household/demographic/person/work_hours/work_hours_per_week.py b/policyengine_us/variables/household/demographic/person/work_hours/work_hours_per_week.py new file mode 100644 index 00000000000..2ccfbfb07dc --- /dev/null +++ b/policyengine_us/variables/household/demographic/person/work_hours/work_hours_per_week.py @@ -0,0 +1,14 @@ +from policyengine_us.model_api import * + + +class work_hours_per_week(Variable): + value_type = float + entity = Person + label = "Work hours per week" + definition_period = YEAR + unit = "hour" + + def formula(person, period, parameters): + days_per_week = person("work_days_per_week", period) + hours_per_day = person("work_hours_per_day", period) + return days_per_week * hours_per_day From 360ee327dfea43701d68a031abe5bdd232bf095f Mon Sep 17 00:00:00 2001 From: Ziming Date: Wed, 7 Jan 2026 20:34:26 -0500 Subject: [PATCH 02/10] pr fix --- .../gov/states/md/tanf/age_limit.yaml | 9 ++- .../childcare_expenses/full_time.yaml | 8 +-- .../childcare_expenses/part_time.yaml | 8 +-- .../deductions/earned/fulltime_hours.yaml | 9 +-- .../states/md/tanf/income/sources/earned.yaml | 7 ++- .../md/tanf/income/sources/unearned.yaml | 16 ++---- .../md/tanf/maximum_benefit/additional.yaml | 7 ++- .../states/md/tanf/maximum_benefit/main.yaml | 7 ++- .../tanf/maximum_benefit/max_unit_size.yaml | 12 ++++ .../income/md_tanf_net_countable_income.yaml | 46 ++++----------- .../md_tanf_net_initial_countable_income.yaml | 46 ++++----------- .../tanf/income/md_tanf_maximum_benefit.yaml | 15 ----- ..._tanf_countable_gross_unearned_income.yaml | 22 ++------ .../gov/states/md/tanf/integration.yaml | 43 ++++++++++++++ .../baseline/gov/states/md/tanf/md_tanf.yaml | 56 ++++++------------- .../deductions/md_tanf_childcare_deduction.py | 3 +- .../md_tanf_continuous_earnings_deduction.py | 4 +- .../md_tanf_initial_earnings_deduction.py | 6 +- .../md_tanf_countable_gross_earned_income.py | 3 +- .../md_tanf_gross_earned_income_deduction.py | 5 +- .../income/md_tanf_net_countable_income.py | 20 ++----- .../md_tanf_net_initial_countable_income.py | 20 ++----- ...md_tanf_countable_gross_unearned_income.py | 10 +--- .../income/unearned/md_tanf_gross_unearned.py | 5 +- .../variables/gov/states/md/tanf/md_tanf.py | 10 ++-- .../states/md/tanf/md_tanf_count_children.py | 3 +- .../gov/states/md/tanf/md_tanf_eligible.py | 9 ++- .../gov/states/md/tanf/md_tanf_is_child.py | 10 ++-- .../states/md/tanf/md_tanf_maximum_benefit.py | 7 +-- .../md/tanf/md_tanf_self_employment_income.py | 5 +- 30 files changed, 172 insertions(+), 259 deletions(-) create mode 100644 policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/max_unit_size.yaml delete mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/md_tanf_maximum_benefit.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/tanf/integration.yaml diff --git a/policyengine_us/parameters/gov/states/md/tanf/age_limit.yaml b/policyengine_us/parameters/gov/states/md/tanf/age_limit.yaml index a70c0b5d31b..d7a16c72a61 100644 --- a/policyengine_us/parameters/gov/states/md/tanf/age_limit.yaml +++ b/policyengine_us/parameters/gov/states/md/tanf/age_limit.yaml @@ -1,9 +1,12 @@ -description: Maryland provides the TANF benefit for children below this age threshold. +description: Maryland limits TANF eligibility to children below this age threshold. + values: 2022-11-01: 19 + metadata: - unit: age + unit: year + period: year label: Maryland TANF age limit reference: - - title: Family investment administration temporary cash assistance manual - Age + - title: Maryland Temporary Cash Assistance Manual - Section 0307 Age href: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0300-Technical-Eligibility/0307%20Age%20rev%2011.22.doc diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/full_time.yaml b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/full_time.yaml index 0496d496ec5..ba3789a075f 100644 --- a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/full_time.yaml +++ b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/full_time.yaml @@ -1,12 +1,12 @@ -description: Maryland excludes this portion of the childcare expenses from TANF countable earned income for full-time enrollees. +description: Maryland provides this monthly childcare deduction per child for full-time workers under the TANF program. values: 2022-11-01: 200 metadata: - period: year + period: month unit: currency-USD - label: Maryland TANF childcare expense exclusion for full-time enrollees + label: Maryland TANF childcare deduction for full-time workers reference: - - title: Maryland TEMPORARY CASH ASSISTANCE MANUAL 904.1 DEDUCTIONS FROM EARNED INCOME + - title: Maryland Temporary Cash Assistance Manual - Section 904.1 Deductions from Earned Income href: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0904%20Deductions%20and%20Expenses%20rev%2011.22.1.doc diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/part_time.yaml b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/part_time.yaml index 8b7e0d4ce27..13a888fc9d3 100644 --- a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/part_time.yaml +++ b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/part_time.yaml @@ -1,12 +1,12 @@ -description: Maryland excludes this portion of the childcare expenses from TANF countable earned income for part-time enrollees. +description: Maryland provides this monthly childcare deduction per child for part-time workers under the TANF program. values: 2022-11-01: 100 metadata: - period: year + period: month unit: currency-USD - label: Maryland TANF childcare expense exclusion for part-time enrollees + label: Maryland TANF childcare deduction for part-time workers reference: - - title: Maryland TEMPORARY CASH ASSISTANCE MANUAL 904.1 DEDUCTIONS FROM EARNED INCOME + - title: Maryland Temporary Cash Assistance Manual - Section 904.1 Deductions from Earned Income href: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0904%20Deductions%20and%20Expenses%20rev%2011.22.1.doc diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/fulltime_hours.yaml b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/fulltime_hours.yaml index 01ac38aceab..106df68a03f 100644 --- a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/fulltime_hours.yaml +++ b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/fulltime_hours.yaml @@ -1,11 +1,12 @@ -description: Maryland requires this amount of monthly work hours for full-time eligibility under the TANF program. +description: Maryland requires this number of monthly work hours for full-time classification under the TANF program. values: 2022-11-01: 100 metadata: - period: year - label: Maryland TANF monthly work hours requirement for full-time enrollees + unit: hour + period: month + label: Maryland TANF full-time work hours threshold reference: - - title: Maryland TEMPORARY CASH ASSISTANCE MANUAL 904.1 DEDUCTIONS FROM EARNED INCOME + - title: Maryland Temporary Cash Assistance Manual - Section 904.1 Deductions from Earned Income href: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0904%20Deductions%20and%20Expenses%20rev%2011.22.1.doc diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/sources/earned.yaml b/policyengine_us/parameters/gov/states/md/tanf/income/sources/earned.yaml index 974c7a5675e..3b567892f48 100644 --- a/policyengine_us/parameters/gov/states/md/tanf/income/sources/earned.yaml +++ b/policyengine_us/parameters/gov/states/md/tanf/income/sources/earned.yaml @@ -1,12 +1,15 @@ description: Maryland TANF counts these income sources as earned income. + values: 2022-11-01: - employment_income - self_employment_income - armed_services_basic_allowance_for_housing + metadata: unit: list - label: Maryland TANF earned income + period: year + label: Maryland TANF earned income sources reference: - - title: Family investment administration temporary cash assistance manual - Financial Eligibility + - title: Maryland Temporary Cash Assistance Manual - Section 0902 Earned Income href: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0902%20TCA%20Earned%20Income%20rev%2011.22.doc diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/sources/unearned.yaml b/policyengine_us/parameters/gov/states/md/tanf/income/sources/unearned.yaml index f066306b410..131226f8482 100644 --- a/policyengine_us/parameters/gov/states/md/tanf/income/sources/unearned.yaml +++ b/policyengine_us/parameters/gov/states/md/tanf/income/sources/unearned.yaml @@ -1,26 +1,18 @@ description: Maryland TANF counts these income sources as unearned income. + values: 2022-11-01: - pension_income -# - investment_income - social_security -# - sick_accident - - alimony_income -# - monetary_gifts - dividend_income - interest_income -# - lottery_winnings -# - lawsuit_settlements -# - inheritances -# - rent_subsidies -# - worker_compensation - unemployment_compensation - veterans_benefits - # - criminal_injuries_compensation metadata: unit: list - label: Maryland TANF unearned income + period: year + label: Maryland TANF unearned income sources reference: - - title: Family investment administration temporary cash assistance manual - Financial Eligibility + - title: Maryland Temporary Cash Assistance Manual - Section 0903 Unearned Income href: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0903%20Unearned%20Income%2011.22.doc diff --git a/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/additional.yaml b/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/additional.yaml index 794d973a6d2..8ea6c59733a 100644 --- a/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/additional.yaml +++ b/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/additional.yaml @@ -1,4 +1,4 @@ -description: Maryland TANF grant standard additional amount per child over 10. +description: Maryland provides this additional amount per person for households exceeding the maximum unit size. values: 2021-10-01: 136 @@ -6,6 +6,7 @@ values: metadata: unit: currency-USD period: month + label: Maryland TANF additional grant amount per person reference: - - title: Family Investment Programs Income Guidelines as of October 01, 2021 - href: https://dhs.maryland.gov/documents/Supplemental%20Nutrition%20Assistance%20Program%20(SNAP)/October-2020-Income-Guidelines-1-1.pdf + - title: Maryland Temporary Cash Assistance Manual - Section 0908 Grant Determination + href: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0908%20Grant%20Determination%20rev%2011.22.doc diff --git a/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/main.yaml b/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/main.yaml index bf7385350e1..de0c917b33f 100644 --- a/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/main.yaml +++ b/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/main.yaml @@ -1,4 +1,4 @@ -description: Maryland TANF grant standard by number of caretakers and children. +description: Maryland provides this amount as the monthly grant standard under the Temporary Assistance for Needy Families program. 1: 2021-10-01: 328 @@ -20,8 +20,9 @@ description: Maryland TANF grant standard by number of caretakers and children. metadata: unit: currency-USD period: month + label: Maryland TANF grant standard breakdown: - range(1, 9) reference: - - title: Family Investment Programs Income Guidelines as of October 01, 2021 - href: https://dhs.maryland.gov/documents/Supplemental%20Nutrition%20Assistance%20Program%20(SNAP)/October-2020-Income-Guidelines-1-1.pdf + - title: Maryland Temporary Cash Assistance Manual - Section 0908 Grant Determination + href: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0908%20Grant%20Determination%20rev%2011.22.doc diff --git a/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/max_unit_size.yaml b/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/max_unit_size.yaml new file mode 100644 index 00000000000..01759121cf8 --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/max_unit_size.yaml @@ -0,0 +1,12 @@ +description: Maryland caps TANF grant standard lookup at this household size, with additional amounts for larger households. + +values: + 2021-10-01: 8 + +metadata: + unit: person + period: year + label: Maryland TANF maximum unit size for grant standard lookup + reference: + - title: Maryland Temporary Cash Assistance Manual - Grant Standards + href: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0908%20Grant%20Determination%20rev%2011.22.doc diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_countable_income.yaml index 7898a0b1282..457c9c2dc70 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_countable_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_countable_income.yaml @@ -1,16 +1,8 @@ -- name: No alimony, child support, or childcare, countinuous deductions of $40, earned income of $100, $60 per year +- name: Case 1, earned income minus continuous deductions equals net countable income. period: 2023 input: - people: - person1: - alimony_income: 0 - child_support_received: 0 - person2: - alimony_income: 0 - child_support_received: 0 spm_units: spm_unit: - members: [person1, person2] md_tanf_childcare_deduction: 0 md_tanf_continuous_earnings_deduction: 40 md_tanf_countable_gross_earned_income: 100 @@ -21,48 +13,32 @@ output: md_tanf_net_countable_income: 60 -- name: No alimony or childcare, child support of $10, countinuous deductions of $40, earned income of $100, $50 per year +- name: Case 2, earned and unearned income minus deductions. period: 2023 input: - people: - person1: - alimony_income: 0 - child_support_received: 10 - person2: - alimony_income: 0 - child_support_received: 0 spm_units: spm_unit: - members: [person1, person2] - md_tanf_childcare_deduction: 0 + md_tanf_childcare_deduction: 10 md_tanf_continuous_earnings_deduction: 40 md_tanf_countable_gross_earned_income: 100 - md_tanf_countable_gross_unearned_income: 0 + md_tanf_countable_gross_unearned_income: 50 households: household: state_code: MD output: - md_tanf_net_countable_income: 50 + md_tanf_net_countable_income: 100 -- name: No childcare or child support, alimony of $10, countinuous deductions of $40, earned income of $100, $50 per year +- name: Case 3, large deductions result in zero net income (not negative). period: 2023 input: - people: - person1: - alimony_income: 10 - child_support_received: 0 - person2: - alimony_income: 0 - child_support_received: 0 spm_units: spm_unit: - members: [person1, person2] - md_tanf_childcare_deduction: 0 - md_tanf_continuous_earnings_deduction: 40 - md_tanf_countable_gross_earned_income: 100 - md_tanf_countable_gross_unearned_income: 0 + md_tanf_childcare_deduction: 50 + md_tanf_continuous_earnings_deduction: 100 + md_tanf_countable_gross_earned_income: 80 + md_tanf_countable_gross_unearned_income: 20 households: household: state_code: MD output: - md_tanf_net_countable_income: 50 + md_tanf_net_countable_income: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.yaml index cc56aa7d813..f7c411b8b1f 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.yaml @@ -1,16 +1,8 @@ -- name: No alimony, child support, or childcare, initial deductions of $40, earned income of $100, $60 per year +- name: Case 1, earned income minus initial deductions equals net initial countable income. period: 2023 input: - people: - person1: - alimony_income: 0 - child_support_received: 0 - person2: - alimony_income: 0 - child_support_received: 0 spm_units: spm_unit: - members: [person1, person2] md_tanf_childcare_deduction: 0 md_tanf_initial_earnings_deduction: 40 md_tanf_countable_gross_earned_income: 100 @@ -21,48 +13,32 @@ output: md_tanf_net_initial_countable_income: 60 -- name: No alimony or childcare, child support of $10, initial deductions of $40, earned income of $100, $50 per year +- name: Case 2, earned and unearned income minus deductions. period: 2023 input: - people: - person1: - alimony_income: 0 - child_support_received: 10 - person2: - alimony_income: 0 - child_support_received: 0 spm_units: spm_unit: - members: [person1, person2] - md_tanf_childcare_deduction: 0 + md_tanf_childcare_deduction: 10 md_tanf_initial_earnings_deduction: 40 md_tanf_countable_gross_earned_income: 100 - md_tanf_countable_gross_unearned_income: 0 + md_tanf_countable_gross_unearned_income: 50 households: household: state_code: MD output: - md_tanf_net_initial_countable_income: 50 + md_tanf_net_initial_countable_income: 100 -- name: No childcare or child support, alimony of $10, initial deductions of $40, earned income of $100, $50 per year +- name: Case 3, large deductions result in zero net income (not negative). period: 2023 input: - people: - person1: - alimony_income: 10 - child_support_received: 0 - person2: - alimony_income: 0 - child_support_received: 0 spm_units: spm_unit: - members: [person1, person2] - md_tanf_childcare_deduction: 0 - md_tanf_initial_earnings_deduction: 40 - md_tanf_countable_gross_earned_income: 100 - md_tanf_countable_gross_unearned_income: 0 + md_tanf_childcare_deduction: 50 + md_tanf_initial_earnings_deduction: 100 + md_tanf_countable_gross_earned_income: 80 + md_tanf_countable_gross_unearned_income: 20 households: household: state_code: MD output: - md_tanf_net_initial_countable_income: 50 + md_tanf_net_initial_countable_income: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/md_tanf_maximum_benefit.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/md_tanf_maximum_benefit.yaml deleted file mode 100644 index f04441a57da..00000000000 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/md_tanf_maximum_benefit.yaml +++ /dev/null @@ -1,15 +0,0 @@ -- name: One-person household has a maximum benefit of $328 per month. - period: 2023 - input: - md_tanf_eligible: true - spm_unit_size: 1 - output: - md_tanf_maximum_benefit: 328 * 12 - -- name: Ten-person household has a maximum benefit of $1,372 (8-person) + 2 * $136 = $1,644 per month. - period: 2023 - input: - md_tanf_eligible: true - spm_unit_size: 10 - output: - md_tanf_maximum_benefit: 1_644 * 12 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.yaml index 4277cb4ff9a..ded3ef13c93 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.yaml @@ -1,15 +1,8 @@ -- name: "Person1 10 child support, Person2 0 child support, not enrolled, 100 gross unearned, 100 countable gross unearned" +- name: Case 1, gross unearned income passes through to countable. period: 2023 input: - people: - person1: - child_support_received: 10 - person2: - child_support_received: 0 spm_units: spm_unit: - members: [person1, person2] - is_tanf_enrolled: false md_tanf_gross_unearned: 100 households: household: @@ -17,21 +10,14 @@ output: md_tanf_countable_gross_unearned_income: 100 -- name: "Person1 10 child support, Person2 0 child support, enrolled, 100 gross unearned, 110 countable gross unearned" +- name: Case 2, zero gross unearned income. period: 2023 input: - people: - person1: - child_support_received: 10 - person2: - child_support_received: 0 spm_units: spm_unit: - members: [person1, person2] - is_tanf_enrolled: true - md_tanf_gross_unearned: 100 + md_tanf_gross_unearned: 0 households: household: state_code: MD output: - md_tanf_countable_gross_unearned_income: 110 + md_tanf_countable_gross_unearned_income: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/integration.yaml new file mode 100644 index 00000000000..2a29a77afa1 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/integration.yaml @@ -0,0 +1,43 @@ +- name: Integration test, single parent with one child, part-time work. + period: 2024 + input: + people: + parent: + age: 30 + employment_income: 12_000 + work_hours_per_week: 30 + child: + age: 5 + spm_units: + spm_unit: + members: [parent, child] + households: + household: + state_code: MD + output: + md_tanf_is_child: [false, true] + md_tanf_count_children: 1 + md_tanf_eligible: true + +- name: Integration test, household with no children is ineligible. + period: 2024 + input: + people: + adult1: + age: 30 + employment_income: 12_000 + adult2: + age: 28 + employment_income: 0 + spm_units: + spm_unit: + members: [adult1, adult2] + households: + household: + state_code: MD + output: + md_tanf_is_child: [false, false] + md_tanf_count_children: 0 + md_tanf_eligible: false + md_tanf_maximum_benefit: 0 + md_tanf: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf.yaml index dd9dbad8b8c..8620fa41b94 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf.yaml @@ -1,87 +1,63 @@ -- name: "Net gross earnings of 6000, family size of 3" +- name: Case 1, net countable income of 6_000, family size of 3, receives 1_632 benefit. period: 2023 input: people: person1: - employment_income: 12000 + employment_income: 12_000 taxable_self_employment_income: 0 - #armed_services_basic_allowance_for_housing: 0 - child_support_received: 0 - alimony_income: 1200 person2: employment_income: 0 taxable_self_employment_income: 0 - #armed_services_basic_allowance_for_housing: 0 - child_support_received: 0 - alimony_income: 0 - person3: + person3: employment_income: 0 taxable_self_employment_income: 0 - #armed_services_basic_allowance_for_housing: 0 - child_support_received: 0 - alimony_income: 0 spm_units: spm_unit: members: [person1, person2, person3] - md_tanf_maximum_benefit: 7632 - childcare_expenses: 2400 - md_tanf_net_countable_income: 6000 + md_tanf_maximum_benefit: 7_632 + md_tanf_net_countable_income: 6_000 households: household: state_code: MD output: - md_tanf: 1632 + md_tanf: 1_632 -- name: "Net gross earnings of 1560, family size of 2" +- name: Case 2, net countable income of 1_560, family size of 2, receives 4_476 benefit. period: 2023 input: people: person1: - employment_income: 3600 + employment_income: 3_600 taxable_self_employment_income: 0 - #armed_services_basic_allowance_for_housing: 0 - child_support_received: 0 - alimony_income: 0 person2: employment_income: 0 taxable_self_employment_income: 0 - #armed_services_basic_allowance_for_housing: 0 - child_support_received: 0 - alimony_income: 0 spm_units: spm_unit: members: [person1, person2] - md_tanf_maximum_benefit: 6036 - childcare_expenses: 600 - md_tanf_net_countable_income: 1560 - households: + md_tanf_maximum_benefit: 6_036 + md_tanf_net_countable_income: 1_560 + households: household: state_code: MD output: - md_tanf: 4476 + md_tanf: 4_476 -- name: "Net gross earnings of 7000, family size of 2" +- name: Case 3, net countable income exceeds maximum benefit, receives 0. period: 2023 input: people: person1: - employment_income: 11000 + employment_income: 11_000 taxable_self_employment_income: 0 - #armed_services_basic_allowance_for_housing: 0 - child_support_received: 0 - alimony_income: 0 person2: employment_income: 0 taxable_self_employment_income: 0 - #armed_services_basic_allowance_for_housing: 0 - child_support_received: 0 - alimony_income: 0 spm_units: spm_unit: members: [person1, person2] - md_tanf_maximum_benefit: 6036 - childcare_expenses: 2400 - md_tanf_net_countable_income: 6600 + md_tanf_maximum_benefit: 6_036 + md_tanf_net_countable_income: 6_600 households: household: state_code: MD diff --git a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.py b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.py index fb3f77b460d..66756fc0e9f 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.py +++ b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.py @@ -1,8 +1,6 @@ from policyengine_us.model_api import * -# reference: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0904%20Deductions%20and%20Expenses%20rev%2011.22.1.doc -# page 1 class md_tanf_childcare_deduction(Variable): value_type = float entity = SPMUnit @@ -10,6 +8,7 @@ class md_tanf_childcare_deduction(Variable): unit = USD definition_period = YEAR defined_for = StateCode.MD + reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0904%20Deductions%20and%20Expenses%20rev%2011.22.1.doc" def formula(spm_unit, period, parameters): children = spm_unit("md_tanf_count_children", period) diff --git a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.py b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.py index 5269fe2991b..a11292d6f26 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.py +++ b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.py @@ -1,8 +1,5 @@ from policyengine_us.model_api import * -# href: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0904%20Deductions%20and%20Expenses%20rev%2011.22.1.doc -# page 1 - class md_tanf_continuous_earnings_deduction(Variable): value_type = float @@ -11,6 +8,7 @@ class md_tanf_continuous_earnings_deduction(Variable): unit = USD definition_period = YEAR defined_for = StateCode.MD + reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0904%20Deductions%20and%20Expenses%20rev%2011.22.1.doc" def formula(spm_unit, period, parameters): p = parameters(period).gov.states.md.tanf.income.deductions.earned diff --git a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.py b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.py index 3513f802277..f5cae2892a4 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.py +++ b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.py @@ -1,7 +1,5 @@ from policyengine_us.model_api import * -# reference: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0902%20TCA%20Earned%20Income%20rev%2011.22.doc - class md_tanf_initial_earnings_deduction(Variable): value_type = float @@ -10,10 +8,9 @@ class md_tanf_initial_earnings_deduction(Variable): unit = USD definition_period = YEAR defined_for = StateCode.MD + reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0902%20TCA%20Earned%20Income%20rev%2011.22.doc" def formula(spm_unit, period, parameters): - person = spm_unit.members - # Get earned income for the SPM unit. p = parameters(period).gov.states.md.tanf.income.deductions.earned earned_income = spm_unit( "md_tanf_countable_gross_earned_income", period @@ -23,7 +20,6 @@ def formula(spm_unit, period, parameters): "md_tanf_self_employment_income", period ) non_self_employment_income = earned_income - self_employment_income - # Get the policy parameters. return (self_employment_income * p.self_employed) + ( non_self_employment_income * p.new diff --git a/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_countable_gross_earned_income.py b/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_countable_gross_earned_income.py index f9310aba0e6..b848bfd9f5e 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_countable_gross_earned_income.py +++ b/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_countable_gross_earned_income.py @@ -1,7 +1,5 @@ from policyengine_us.model_api import * -# reference: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0902%20TCA%20Earned%20Income%20rev%2011.22.doc - class md_tanf_countable_gross_earned_income(Variable): value_type = float @@ -10,5 +8,6 @@ class md_tanf_countable_gross_earned_income(Variable): unit = USD definition_period = YEAR defined_for = StateCode.MD + reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0902%20TCA%20Earned%20Income%20rev%2011.22.doc" adds = "gov.states.md.tanf.income.sources.earned" diff --git a/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_gross_earned_income_deduction.py b/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_gross_earned_income_deduction.py index 525df8825a2..b0acf123b8e 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_gross_earned_income_deduction.py +++ b/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_gross_earned_income_deduction.py @@ -8,6 +8,7 @@ class md_tanf_gross_earned_income_deduction(Variable): unit = USD definition_period = YEAR defined_for = StateCode.MD + reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0904%20Deductions%20and%20Expenses%20rev%2011.22.1.doc" def formula(spm_unit, period, parameters): # Get TANF enrollment status. @@ -22,12 +23,8 @@ def formula(spm_unit, period, parameters): # Get the policy parameters. p = parameters(period).gov.states.md.tanf.income.deductions.earned percent = select( - # First arg: list of conditions [~is_tanf_enrolled, has_self_employment_income], - # Second arg: list of values to return if the corresponding condition is True [p.new, p.self_employed], - # Third arg: default value to return if none of the conditions are True default=p.not_self_employed, ) - # Multiply earned income by percent deduction. return earned_income * percent diff --git a/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_countable_income.py b/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_countable_income.py index 72c8e638aa6..9da46a43e40 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_countable_income.py +++ b/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_countable_income.py @@ -1,7 +1,5 @@ from policyengine_us.model_api import * -# reference: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0902%20TCA%20Earned%20Income%20rev%2011.22.doc - class md_tanf_net_countable_income(Variable): value_type = float @@ -10,6 +8,7 @@ class md_tanf_net_countable_income(Variable): unit = USD definition_period = YEAR defined_for = StateCode.MD + reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0902%20TCA%20Earned%20Income%20rev%2011.22.doc" def formula(spm_unit, period, parameters): # Get gross income for the SPM unit. @@ -19,26 +18,17 @@ def formula(spm_unit, period, parameters): gross_unearned_income = spm_unit( "md_tanf_countable_gross_unearned_income", period ) - # Get countinuous deductions for the SPM unit. + # Get continuous deductions for the SPM unit. continuous_deductions = spm_unit( "md_tanf_continuous_earnings_deduction", period ) - - # Get alimony deductions for the SPM unit. - person = spm_unit.members - alimony_deduction_ind = person("alimony_income", period) - alimony_deduction = spm_unit.sum(alimony_deduction_ind) - # Get child support deductions for the SPM unit. - child_support_deduction_ind = person("child_support_received", period) - child_support_deduction = spm_unit.sum(child_support_deduction_ind) # Get childcare deductions for the SPM unit. childcare_deduction = spm_unit("md_tanf_childcare_deduction", period) - return ( + return max_( gross_earned_income + gross_unearned_income - continuous_deductions - - alimony_deduction - - child_support_deduction - - childcare_deduction + - childcare_deduction, + 0, ) diff --git a/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.py b/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.py index d092ecf076b..3209a20389f 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.py +++ b/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.py @@ -1,7 +1,5 @@ from policyengine_us.model_api import * -# reference: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0902%20TCA%20Earned%20Income%20rev%2011.22.doc - class md_tanf_net_initial_countable_income(Variable): value_type = float @@ -10,6 +8,7 @@ class md_tanf_net_initial_countable_income(Variable): unit = USD definition_period = YEAR defined_for = StateCode.MD + reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0902%20TCA%20Earned%20Income%20rev%2011.22.doc" def formula(spm_unit, period, parameters): # Get gross income for the SPM unit. @@ -19,26 +18,17 @@ def formula(spm_unit, period, parameters): gross_unearned_income = spm_unit( "md_tanf_countable_gross_unearned_income", period ) - # Get countinuous deductions for the SPM unit. + # Get initial deductions for the SPM unit. initial_deductions = spm_unit( "md_tanf_initial_earnings_deduction", period ) - # Get alimony deductions for the SPM unit. - - person = spm_unit.members - alimony_deduction_ind = person("alimony_income", period) - alimony_deduction = spm_unit.sum(alimony_deduction_ind) - # Get child support deductions for the SPM unit. - child_support_deduction_ind = person("child_support_received", period) - child_support_deduction = spm_unit.sum(child_support_deduction_ind) # Get childcare deductions for the SPM unit. childcare_deduction = spm_unit("md_tanf_childcare_deduction", period) - return ( + return max_( gross_earned_income + gross_unearned_income - initial_deductions - - alimony_deduction - - child_support_deduction - - childcare_deduction + - childcare_deduction, + 0, ) diff --git a/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.py b/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.py index 253f710f266..4d06262ea6b 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.py +++ b/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.py @@ -1,7 +1,5 @@ from policyengine_us.model_api import * -# reference: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0903%20Unearned%20Income%2011.22.doc - class md_tanf_countable_gross_unearned_income(Variable): value_type = float @@ -10,11 +8,7 @@ class md_tanf_countable_gross_unearned_income(Variable): unit = USD definition_period = YEAR defined_for = StateCode.MD + reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0903%20Unearned%20Income%2011.22.doc" def formula(spm_unit, period, parameters): - person = spm_unit.members - gross_unearned = spm_unit("md_tanf_gross_unearned", period) - child_support = spm_unit.sum(person("child_support_received", period)) - enrolled = spm_unit("is_tanf_enrolled", period) - - return gross_unearned + enrolled * child_support + return spm_unit("md_tanf_gross_unearned", period) diff --git a/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_gross_unearned.py b/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_gross_unearned.py index a2df07ff6a8..27b2d18e048 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_gross_unearned.py +++ b/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_gross_unearned.py @@ -1,14 +1,13 @@ from policyengine_us.model_api import * -# reference: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0903%20Unearned%20Income%2011.22.doc - class md_tanf_gross_unearned(Variable): value_type = float entity = SPMUnit - label = "Maryland TANF countable gross unearned income" + label = "Maryland TANF gross unearned income" unit = USD definition_period = YEAR defined_for = StateCode.MD + reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0903%20Unearned%20Income%2011.22.doc" adds = "gov.states.md.tanf.income.sources.unearned" diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf.py b/policyengine_us/variables/gov/states/md/tanf/md_tanf.py index 5b1b28c8310..516f7cf47ed 100644 --- a/policyengine_us/variables/gov/states/md/tanf/md_tanf.py +++ b/policyengine_us/variables/gov/states/md/tanf/md_tanf.py @@ -1,7 +1,5 @@ from policyengine_us.model_api import * -# reference: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0907%20Income%20Calculation%20of%20Ineligible%20Member%20rev%2011.22.doc - class md_tanf(Variable): value_type = float @@ -10,12 +8,12 @@ class md_tanf(Variable): unit = USD definition_period = YEAR defined_for = StateCode.MD + reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0907%20Income%20Calculation%20of%20Ineligible%20Member%20rev%2011.22.doc" def formula(spm_unit, period, parameters): - # Maximum TANF amount recieved + # Maximum TANF amount received grant_standard = spm_unit("md_tanf_maximum_benefit", period) # SPM unit income after continuous deduction + # Note: md_tanf_net_countable_income already includes all deductions income = spm_unit("md_tanf_net_countable_income", period) - # SPM Unit childcare deductions - childcare_deduction = spm_unit("md_tanf_childcare_deduction", period) - return max_(grant_standard - (income - childcare_deduction), 0) + return max_(grant_standard - income, 0) diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf_count_children.py b/policyengine_us/variables/gov/states/md/tanf/md_tanf_count_children.py index a8dbbe36afe..adb682c09a5 100644 --- a/policyengine_us/variables/gov/states/md/tanf/md_tanf_count_children.py +++ b/policyengine_us/variables/gov/states/md/tanf/md_tanf_count_children.py @@ -1,7 +1,5 @@ from policyengine_us.model_api import * -# reference: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0300-Technical-Eligibility/0307%20Age%20rev%2011.22.doc - class md_tanf_count_children(Variable): value_type = int @@ -9,4 +7,5 @@ class md_tanf_count_children(Variable): label = "Maryland TANF number of children" definition_period = YEAR defined_for = StateCode.MD + reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0300-Technical-Eligibility/0307%20Age%20rev%2011.22.doc" adds = ["md_tanf_is_child"] diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf_eligible.py b/policyengine_us/variables/gov/states/md/tanf/md_tanf_eligible.py index 8e7bc029526..6c714f579be 100644 --- a/policyengine_us/variables/gov/states/md/tanf/md_tanf_eligible.py +++ b/policyengine_us/variables/gov/states/md/tanf/md_tanf_eligible.py @@ -1,12 +1,15 @@ from policyengine_us.model_api import * -# reference:https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0300-Technical-Eligibility/0300%20Technical%20Eligibility%20Overview%20rev%2011.22.doc - class md_tanf_eligible(Variable): value_type = bool entity = SPMUnit label = "Maryland TANF eligible" - unit = USD definition_period = YEAR defined_for = StateCode.MD + reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0300-Technical-Eligibility/0300%20Technical%20Eligibility%20Overview%20rev%2011.22.doc" + + def formula(spm_unit, period, parameters): + has_children = spm_unit("md_tanf_count_children", period) > 0 + demographic_eligible = spm_unit("is_demographic_tanf_eligible", period) + return has_children & demographic_eligible diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf_is_child.py b/policyengine_us/variables/gov/states/md/tanf/md_tanf_is_child.py index 7cc9c38f468..28be7afe1d5 100644 --- a/policyengine_us/variables/gov/states/md/tanf/md_tanf_is_child.py +++ b/policyengine_us/variables/gov/states/md/tanf/md_tanf_is_child.py @@ -1,7 +1,5 @@ from policyengine_us.model_api import * -# reference: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0300-Technical-Eligibility/0307%20Age%20rev%2011.22.doc - class md_tanf_is_child(Variable): value_type = bool @@ -9,18 +7,18 @@ class md_tanf_is_child(Variable): definition_period = YEAR label = "Is a child under Maryland TANF program" defined_for = StateCode.MD + reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0300-Technical-Eligibility/0307%20Age%20rev%2011.22.doc" def formula(person, period, parameters): - # younger than age 18 + # Younger than age 18 child = person("is_child", period) - # Younger than age 19 and A full time k12 student + # Younger than age 19 and a full-time K-12 student p = parameters(period).gov.states.md.tanf age_eligible = person("age", period) < p.age_limit k12 = person("is_in_k12_school", period) k12_age_eligible = k12 & age_eligible - # age 19 and a full time student + # Age 19 and a full-time student years_19 = person("age", period) == p.age_limit full_time_student = person("is_full_time_college_student", period) school_enrolled_19_year_old = full_time_student & years_19 - # return return child | school_enrolled_19_year_old | k12_age_eligible diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf_maximum_benefit.py b/policyengine_us/variables/gov/states/md/tanf/md_tanf_maximum_benefit.py index ee240f3a877..442f4836778 100644 --- a/policyengine_us/variables/gov/states/md/tanf/md_tanf_maximum_benefit.py +++ b/policyengine_us/variables/gov/states/md/tanf/md_tanf_maximum_benefit.py @@ -1,7 +1,5 @@ from policyengine_us.model_api import * -# reference: https://dhs.maryland.gov/documents/Supplemental%20Nutrition%20Assistance%20Program%20(SNAP)/October-2020-Income-Guidelines-1-1.pdf (2) - class md_tanf_maximum_benefit(Variable): value_type = float @@ -10,12 +8,13 @@ class md_tanf_maximum_benefit(Variable): unit = USD definition_period = YEAR defined_for = "md_tanf_eligible" + reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0908%20Grant%20Determination%20rev%2011.22.doc" def formula(spm_unit, period, parameters): people = spm_unit("spm_unit_size", period) - # TODO: Add DHS layer. p = parameters(period).gov.states.md.tanf.maximum_benefit - capped_people = min_(people, 8).astype(int) + max_size = p.max_unit_size + capped_people = min_(people, max_size).astype(int) additional_people = people - capped_people base = p.main[capped_people] additional_maximum_benefit = p.additional * additional_people diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf_self_employment_income.py b/policyengine_us/variables/gov/states/md/tanf/md_tanf_self_employment_income.py index 0b89f7e69ba..5052f39b912 100644 --- a/policyengine_us/variables/gov/states/md/tanf/md_tanf_self_employment_income.py +++ b/policyengine_us/variables/gov/states/md/tanf/md_tanf_self_employment_income.py @@ -1,14 +1,13 @@ from policyengine_us.model_api import * -# reference: "https://www.law.cornell.edu/uscode/text/26/1402#a" - class md_tanf_self_employment_income(Variable): value_type = float entity = SPMUnit - label = "Maryland TANF self employment income" + label = "Maryland TANF self-employment income" unit = USD definition_period = YEAR defined_for = StateCode.MD + reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0902%20TCA%20Earned%20Income%20rev%2011.22.doc" adds = "gov.irs.tax.self_employment.taxable_self_employment_income" From 2c6a30799a6290a8d54ea684bd1a818537fcbec4 Mon Sep 17 00:00:00 2001 From: Ziming Date: Wed, 7 Jan 2026 20:58:42 -0500 Subject: [PATCH 03/10] year to month --- .../deductions/earned/fulltime_hours.yaml | 6 +- .../md_tanf_childcare_deduction.yaml | 29 ++++--- ...md_tanf_continuous_earnings_deduction.yaml | 61 ++++++++++----- .../md_tanf_initial_earnings_deduction.yaml | 65 ++++++++++------ .../income/md_tanf_net_countable_income.yaml | 18 +++-- .../md_tanf_net_initial_countable_income.yaml | 18 +++-- ...md_tanf_gross_earned_income_deduction.yaml | 76 +++++++++++++------ ..._tanf_countable_gross_unearned_income.yaml | 4 +- .../gov/states/md/tanf/integration.yaml | 6 +- .../baseline/gov/states/md/tanf/md_tanf.yaml | 75 +++++++++--------- .../gov/states/md/tanf/md_tanf_is_child.yaml | 29 ++++--- .../deductions/md_tanf_childcare_deduction.py | 2 +- .../md_tanf_continuous_earnings_deduction.py | 2 +- .../md_tanf_initial_earnings_deduction.py | 2 +- .../md_tanf_countable_gross_earned_income.py | 2 +- .../md_tanf_gross_earned_income_deduction.py | 2 +- .../income/md_tanf_net_countable_income.py | 12 ++- .../md_tanf_net_initial_countable_income.py | 12 ++- ...md_tanf_countable_gross_unearned_income.py | 2 +- .../income/unearned/md_tanf_gross_unearned.py | 2 +- .../variables/gov/states/md/tanf/md_tanf.py | 4 +- .../states/md/tanf/md_tanf_count_children.py | 2 +- .../gov/states/md/tanf/md_tanf_eligible.py | 2 +- .../gov/states/md/tanf/md_tanf_is_child.py | 11 +-- .../states/md/tanf/md_tanf_maximum_benefit.py | 13 ++-- .../md/tanf/md_tanf_self_employment_income.py | 2 +- 26 files changed, 267 insertions(+), 192 deletions(-) diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/fulltime_hours.yaml b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/fulltime_hours.yaml index 106df68a03f..9445b27d5d7 100644 --- a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/fulltime_hours.yaml +++ b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/fulltime_hours.yaml @@ -1,11 +1,11 @@ -description: Maryland requires this number of monthly work hours for full-time classification under the TANF program. +description: Maryland requires this number of weekly work hours for full-time classification under the TANF program. values: - 2022-11-01: 100 + 2022-11-01: 25 metadata: unit: hour - period: month + period: week label: Maryland TANF full-time work hours threshold reference: - title: Maryland Temporary Cash Assistance Manual - Section 904.1 Deductions from Earned Income diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.yaml index 5d1127a3545..eb97a2436d8 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.yaml @@ -1,11 +1,11 @@ -- name: No children, part-time work, $0 deductions - period: 2023 +- name: Case 1, no children, no deduction. + period: 2023-01 input: people: person1: - work_hours_per_week: 50 + work_hours_per_week: 30 person2: - work_hours_per_week: 60 + work_hours_per_week: 40 spm_units: spm_unit: members: [person1, person2] @@ -16,14 +16,14 @@ output: md_tanf_childcare_deduction: 0 -- name: 2 children, part-time work, $200 deductions - period: 2023 +- name: Case 2, two children, part-time work. + period: 2023-01 input: people: person1: - work_hours_per_week: 50 + work_hours_per_week: 20 person2: - work_hours_per_week: 60 + work_hours_per_week: 15 spm_units: spm_unit: members: [person1, person2] @@ -32,16 +32,17 @@ household: state_code: MD output: + # 2 children × $100/child (part-time) = $200/month md_tanf_childcare_deduction: 200 -- name: 2 children, full-time work, $400 deductions - period: 2023 +- name: Case 3, two children, full-time work. + period: 2023-01 input: people: person1: - work_hours_per_week: 100 + work_hours_per_week: 30 person2: - work_hours_per_week: 60 + work_hours_per_week: 20 spm_units: spm_unit: members: [person1, person2] @@ -50,7 +51,5 @@ household: state_code: MD output: + # 2 children × $200/child (full-time, any member >= 25 hours) = $400/month md_tanf_childcare_deduction: 400 - - - diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.yaml index ede1fbfca1b..29d280f79fa 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.yaml @@ -1,35 +1,56 @@ -- name: If zero earned income, zero deduction. - period: 2023 +- name: Case 1, zero earned income, zero deduction. + period: 2023-01 input: - md_tanf_countable_gross_earned_income: 0 - md_tanf_self_employment_income: 0 - state_code: MD + spm_units: + spm_unit: + md_tanf_countable_gross_earned_income: 0 + md_tanf_self_employment_income: 0 + households: + household: + state_code: MD output: md_tanf_continuous_earnings_deduction: 0 -- name: If not self-employed, 40% deduction. - period: 2023 +- name: Case 2, non-self-employed, 40% deduction. + period: 2023-01 input: - md_tanf_countable_gross_earned_income: 100 - md_tanf_self_employment_income: 0 - state_code: MD + spm_units: + spm_unit: + md_tanf_countable_gross_earned_income: 100 + md_tanf_self_employment_income: 0 + households: + household: + state_code: MD output: + # Non-self-employed: $100 × 0.40 = $40 md_tanf_continuous_earnings_deduction: 40 -- name: If self-employed, 50% deduction. - period: 2023 +- name: Case 3, all self-employed, 50% deduction. + period: 2023-01 input: - md_tanf_countable_gross_earned_income: 100 - md_tanf_self_employment_income: 100 - state_code: MD + spm_units: + spm_unit: + md_tanf_countable_gross_earned_income: 100 + md_tanf_self_employment_income: 100 + households: + household: + state_code: MD output: + # Self-employed: $100 × 0.50 = $50 md_tanf_continuous_earnings_deduction: 50 -- name: If self-employed and non-self-employed, combined deduction - period: 2023 +- name: Case 4, partially self-employed, combined deduction. + period: 2023-01 input: - md_tanf_countable_gross_earned_income: 100 - md_tanf_self_employment_income: 80 - state_code: MD + spm_units: + spm_unit: + md_tanf_countable_gross_earned_income: 100 + md_tanf_self_employment_income: 80 + households: + household: + state_code: MD output: + # Self-employed portion: $80 × 0.50 = $40 + # Non-self-employed: ($100 - $80) × 0.40 = $8 + # Total: $40 + $8 = $48 md_tanf_continuous_earnings_deduction: 48 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.yaml index 357a812d6e3..90ab7a03b71 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.yaml @@ -1,39 +1,56 @@ -- name: If zero earned income, zero deduction. - period: 2023 +- name: Case 1, zero earned income, zero deduction. + period: 2023-01 input: - state_code: MD - md_tanf_countable_gross_earned_income: 0 - md_tanf_self_employment_income: 0 + spm_units: + spm_unit: + md_tanf_countable_gross_earned_income: 0 + md_tanf_self_employment_income: 0 + households: + household: + state_code: MD output: md_tanf_initial_earnings_deduction: 0 - -- name: If not self-employed, new enrolled, 20% deduction. - period: 2023 +- name: Case 2, non-self-employed, 20% deduction. + period: 2023-01 input: - state_code: MD - is_tanf_enrolled: false - md_tanf_countable_gross_earned_income: 100 - md_tanf_self_employment_income: 0 + spm_units: + spm_unit: + md_tanf_countable_gross_earned_income: 100 + md_tanf_self_employment_income: 0 + households: + household: + state_code: MD output: + # Non-self-employed: $100 × 0.20 = $20 md_tanf_initial_earnings_deduction: 20 -- name: If self-employed, new enrolled, 50% deduction. - period: 2023 +- name: Case 3, all self-employed, 50% deduction. + period: 2023-01 input: - state_code: MD - is_tanf_enrolled: false - md_tanf_countable_gross_earned_income: 100 - md_tanf_self_employment_income: 100 + spm_units: + spm_unit: + md_tanf_countable_gross_earned_income: 100 + md_tanf_self_employment_income: 100 + households: + household: + state_code: MD output: + # Self-employed: $100 × 0.50 = $50 md_tanf_initial_earnings_deduction: 50 -- name: If partially self-employed, new enrolled, combined deduction. - period: 2023 +- name: Case 4, partially self-employed, combined deduction. + period: 2023-01 input: - state_code: MD - is_tanf_enrolled: false - md_tanf_countable_gross_earned_income: 100 - md_tanf_self_employment_income: 80 + spm_units: + spm_unit: + md_tanf_countable_gross_earned_income: 100 + md_tanf_self_employment_income: 80 + households: + household: + state_code: MD output: + # Self-employed portion: $80 × 0.50 = $40 + # Non-self-employed: ($100 - $80) × 0.20 = $4 + # Total: $40 + $4 = $44 md_tanf_initial_earnings_deduction: 44 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_countable_income.yaml index 457c9c2dc70..7928e9c3488 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_countable_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_countable_income.yaml @@ -1,5 +1,5 @@ -- name: Case 1, earned income minus continuous deductions equals net countable income. - period: 2023 +- name: Case 1, earned income minus continuous deductions. + period: 2023-01 input: spm_units: spm_unit: @@ -11,10 +11,12 @@ household: state_code: MD output: + # Countable earned = max($100 - $40 - $0, 0) = $60 + # Total = $60 + $0 = $60 md_tanf_net_countable_income: 60 - name: Case 2, earned and unearned income minus deductions. - period: 2023 + period: 2023-01 input: spm_units: spm_unit: @@ -26,10 +28,12 @@ household: state_code: MD output: + # Countable earned = max($100 - $40 - $10, 0) = $50 + # Total = $50 + $50 = $100 md_tanf_net_countable_income: 100 -- name: Case 3, large deductions result in zero net income (not negative). - period: 2023 +- name: Case 3, deductions exceed earned income, only unearned counted. + period: 2023-01 input: spm_units: spm_unit: @@ -41,4 +45,6 @@ household: state_code: MD output: - md_tanf_net_countable_income: 0 + # Countable earned = max($80 - $100 - $50, 0) = $0 + # Total = $0 + $20 = $20 + md_tanf_net_countable_income: 20 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.yaml index f7c411b8b1f..53905d5cd54 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.yaml @@ -1,5 +1,5 @@ -- name: Case 1, earned income minus initial deductions equals net initial countable income. - period: 2023 +- name: Case 1, earned income minus initial deductions. + period: 2023-01 input: spm_units: spm_unit: @@ -11,10 +11,12 @@ household: state_code: MD output: + # Countable earned = max($100 - $40 - $0, 0) = $60 + # Total = $60 + $0 = $60 md_tanf_net_initial_countable_income: 60 - name: Case 2, earned and unearned income minus deductions. - period: 2023 + period: 2023-01 input: spm_units: spm_unit: @@ -26,10 +28,12 @@ household: state_code: MD output: + # Countable earned = max($100 - $40 - $10, 0) = $50 + # Total = $50 + $50 = $100 md_tanf_net_initial_countable_income: 100 -- name: Case 3, large deductions result in zero net income (not negative). - period: 2023 +- name: Case 3, deductions exceed earned income, only unearned counted. + period: 2023-01 input: spm_units: spm_unit: @@ -41,4 +45,6 @@ household: state_code: MD output: - md_tanf_net_initial_countable_income: 0 + # Countable earned = max($80 - $100 - $50, 0) = $0 + # Total = $0 + $20 = $20 + md_tanf_net_initial_countable_income: 20 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/md_tanf_gross_earned_income_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/md_tanf_gross_earned_income_deduction.yaml index 007cf6c7cb1..b1a08979fbc 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/md_tanf_gross_earned_income_deduction.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/md_tanf_gross_earned_income_deduction.yaml @@ -1,37 +1,69 @@ -- name: If zero earned income, zero deduction. - period: 2023 +- name: Case 1, zero earned income, zero deduction. + period: 2023-01 input: - state_code: MD - employment_income: 0 + people: + person1: + employment_income: 0 + self_employment_income: 0 + spm_units: + spm_unit: + members: [person1] + households: + household: + state_code: MD output: md_tanf_gross_earned_income_deduction: 0 - -- name: If not enrolled in TANF, 20% deduction. - period: 2023 +- name: Case 2, not enrolled in TANF, 20% deduction. + period: 2023-01 input: - state_code: MD - is_tanf_enrolled: false - employment_income: 100 + people: + person1: + employment_income: 1_200 + self_employment_income: 0 + is_tanf_enrolled: false + spm_units: + spm_unit: + members: [person1] + households: + household: + state_code: MD output: + # $1,200/year = $100/month × 0.20 = $20/month md_tanf_gross_earned_income_deduction: 20 -- name: If enrolled in TANF and not self-employed, 40% deduction. - period: 2023 +- name: Case 3, enrolled in TANF and not self-employed, 40% deduction. + period: 2023-01 input: - state_code: MD - is_tanf_enrolled: true - self_employment_income: 0 - employment_income: 100 + people: + person1: + employment_income: 1_200 + self_employment_income: 0 + is_tanf_enrolled: true + spm_units: + spm_unit: + members: [person1] + households: + household: + state_code: MD output: + # $1,200/year = $100/month × 0.40 = $40/month md_tanf_gross_earned_income_deduction: 40 -- name: If self-employed, 50% deduction. - period: 2023 +- name: Case 4, self-employed, 50% deduction. + period: 2023-01 input: - state_code: MD - is_tanf_enrolled: true - self_employment_income: 100 - employment_income: 100 + people: + person1: + employment_income: 1_200 + self_employment_income: 1_200 + is_tanf_enrolled: true + spm_units: + spm_unit: + members: [person1] + households: + household: + state_code: MD output: + # $1,200/year = $100/month × 0.50 = $50/month md_tanf_gross_earned_income_deduction: 50 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.yaml index ded3ef13c93..03de8df30c0 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.yaml @@ -1,5 +1,5 @@ - name: Case 1, gross unearned income passes through to countable. - period: 2023 + period: 2023-01 input: spm_units: spm_unit: @@ -11,7 +11,7 @@ md_tanf_countable_gross_unearned_income: 100 - name: Case 2, zero gross unearned income. - period: 2023 + period: 2023-01 input: spm_units: spm_unit: diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/integration.yaml index 2a29a77afa1..6c6c2d1d8b3 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/integration.yaml @@ -1,11 +1,11 @@ - name: Integration test, single parent with one child, part-time work. - period: 2024 + period: 2024-01 input: people: parent: age: 30 employment_income: 12_000 - work_hours_per_week: 30 + work_hours_per_week: 20 child: age: 5 spm_units: @@ -20,7 +20,7 @@ md_tanf_eligible: true - name: Integration test, household with no children is ineligible. - period: 2024 + period: 2024-01 input: people: adult1: diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf.yaml index 8620fa41b94..3766845d23e 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf.yaml @@ -1,63 +1,56 @@ -- name: Case 1, net countable income of 6_000, family size of 3, receives 1_632 benefit. - period: 2023 +- name: Case 1, eligible with income below maximum benefit. + period: 2023-01 input: - people: - person1: - employment_income: 12_000 - taxable_self_employment_income: 0 - person2: - employment_income: 0 - taxable_self_employment_income: 0 - person3: - employment_income: 0 - taxable_self_employment_income: 0 spm_units: spm_unit: - members: [person1, person2, person3] - md_tanf_maximum_benefit: 7_632 - md_tanf_net_countable_income: 6_000 + md_tanf_eligible: true + md_tanf_maximum_benefit: 727 + md_tanf_net_countable_income: 200 households: household: state_code: MD output: - md_tanf: 1_632 + # Benefit = $727 - $200 = $527 + md_tanf: 527 -- name: Case 2, net countable income of 1_560, family size of 2, receives 4_476 benefit. - period: 2023 +- name: Case 2, eligible with zero income. + period: 2023-01 input: - people: - person1: - employment_income: 3_600 - taxable_self_employment_income: 0 - person2: - employment_income: 0 - taxable_self_employment_income: 0 spm_units: spm_unit: - members: [person1, person2] - md_tanf_maximum_benefit: 6_036 - md_tanf_net_countable_income: 1_560 + md_tanf_eligible: true + md_tanf_maximum_benefit: 575 + md_tanf_net_countable_income: 0 households: household: state_code: MD output: - md_tanf: 4_476 + # Benefit = $575 - $0 = $575 + md_tanf: 575 -- name: Case 3, net countable income exceeds maximum benefit, receives 0. - period: 2023 +- name: Case 3, income exceeds maximum benefit. + period: 2023-01 input: - people: - person1: - employment_income: 11_000 - taxable_self_employment_income: 0 - person2: - employment_income: 0 - taxable_self_employment_income: 0 spm_units: spm_unit: - members: [person1, person2] - md_tanf_maximum_benefit: 6_036 - md_tanf_net_countable_income: 6_600 + md_tanf_eligible: true + md_tanf_maximum_benefit: 575 + md_tanf_net_countable_income: 600 + households: + household: + state_code: MD + output: + # Benefit = max($575 - $600, 0) = $0 + md_tanf: 0 + +- name: Case 4, ineligible household receives zero. + period: 2023-01 + input: + spm_units: + spm_unit: + md_tanf_eligible: false + md_tanf_maximum_benefit: 575 + md_tanf_net_countable_income: 0 households: household: state_code: MD diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_is_child.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_is_child.yaml index e40f1621666..ae0517f6014 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_is_child.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_is_child.yaml @@ -1,5 +1,5 @@ -- name: "Person who is age 20 and is full time student" - period: 2023 +- name: Case 1, person age 20 full-time student is not a child. + period: 2023-01 input: age: 20 is_full_time_college_student: true @@ -8,9 +8,8 @@ output: md_tanf_is_child: false - -- name: "Person who is age 18 and is full time k12 student" - period: 2023 +- name: Case 2, person age 18 K-12 student is a child. + period: 2023-01 input: age: 18 is_full_time_college_student: false @@ -19,9 +18,8 @@ output: md_tanf_is_child: true - -- name: "Person who is age 19 and is full time college student" - period: 2023 +- name: Case 3, person age 19 full-time college student is a child. + period: 2023-01 input: age: 19 is_full_time_college_student: true @@ -30,14 +28,23 @@ output: md_tanf_is_child: true - -- name: "Person who is age 19 and is full time k12 student" - period: 2023 +- name: Case 4, person age 19 K-12 student is not a child. + period: 2023-01 input: age: 19 is_full_time_college_student: false is_in_k12_school: true state_code: MD output: + # Age 19 K-12 student doesn't qualify (age_limit is 19, so age < 19 fails) md_tanf_is_child: false +- name: Case 5, person age 5 is a child. + period: 2023-01 + input: + age: 5 + is_full_time_college_student: false + is_in_k12_school: false + state_code: MD + output: + md_tanf_is_child: true diff --git a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.py b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.py index 66756fc0e9f..68658e7ed0c 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.py +++ b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.py @@ -6,7 +6,7 @@ class md_tanf_childcare_deduction(Variable): entity = SPMUnit label = "Maryland TANF childcare deduction" unit = USD - definition_period = YEAR + definition_period = MONTH defined_for = StateCode.MD reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0904%20Deductions%20and%20Expenses%20rev%2011.22.1.doc" diff --git a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.py b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.py index a11292d6f26..dd5e9126216 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.py +++ b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.py @@ -6,7 +6,7 @@ class md_tanf_continuous_earnings_deduction(Variable): entity = SPMUnit label = "Maryland TANF continuous earnings deduction" unit = USD - definition_period = YEAR + definition_period = MONTH defined_for = StateCode.MD reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0904%20Deductions%20and%20Expenses%20rev%2011.22.1.doc" diff --git a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.py b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.py index f5cae2892a4..ef25edf53d9 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.py +++ b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.py @@ -6,7 +6,7 @@ class md_tanf_initial_earnings_deduction(Variable): entity = SPMUnit label = "Maryland TANF initial earnings deduction" unit = USD - definition_period = YEAR + definition_period = MONTH defined_for = StateCode.MD reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0902%20TCA%20Earned%20Income%20rev%2011.22.doc" diff --git a/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_countable_gross_earned_income.py b/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_countable_gross_earned_income.py index b848bfd9f5e..b606694b364 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_countable_gross_earned_income.py +++ b/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_countable_gross_earned_income.py @@ -6,7 +6,7 @@ class md_tanf_countable_gross_earned_income(Variable): entity = SPMUnit label = "Maryland TANF countable gross earned income" unit = USD - definition_period = YEAR + definition_period = MONTH defined_for = StateCode.MD reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0902%20TCA%20Earned%20Income%20rev%2011.22.doc" diff --git a/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_gross_earned_income_deduction.py b/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_gross_earned_income_deduction.py index b0acf123b8e..0c8a44e343a 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_gross_earned_income_deduction.py +++ b/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_gross_earned_income_deduction.py @@ -6,7 +6,7 @@ class md_tanf_gross_earned_income_deduction(Variable): entity = SPMUnit label = "Maryland TANF earned income deduction" unit = USD - definition_period = YEAR + definition_period = MONTH defined_for = StateCode.MD reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0904%20Deductions%20and%20Expenses%20rev%2011.22.1.doc" diff --git a/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_countable_income.py b/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_countable_income.py index 9da46a43e40..93766b0586c 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_countable_income.py +++ b/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_countable_income.py @@ -6,7 +6,7 @@ class md_tanf_net_countable_income(Variable): entity = SPMUnit label = "Maryland TANF net countable income" unit = USD - definition_period = YEAR + definition_period = MONTH defined_for = StateCode.MD reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0902%20TCA%20Earned%20Income%20rev%2011.22.doc" @@ -24,11 +24,9 @@ def formula(spm_unit, period, parameters): ) # Get childcare deductions for the SPM unit. childcare_deduction = spm_unit("md_tanf_childcare_deduction", period) - - return max_( - gross_earned_income - + gross_unearned_income - - continuous_deductions - - childcare_deduction, + # Apply deductions to earned income only, then add unearned + countable_earned = max_( + gross_earned_income - continuous_deductions - childcare_deduction, 0, ) + return countable_earned + gross_unearned_income diff --git a/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.py b/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.py index 3209a20389f..03e8baa0e75 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.py +++ b/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.py @@ -6,7 +6,7 @@ class md_tanf_net_initial_countable_income(Variable): entity = SPMUnit label = "Maryland TANF net initial countable income" unit = USD - definition_period = YEAR + definition_period = MONTH defined_for = StateCode.MD reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0902%20TCA%20Earned%20Income%20rev%2011.22.doc" @@ -24,11 +24,9 @@ def formula(spm_unit, period, parameters): ) # Get childcare deductions for the SPM unit. childcare_deduction = spm_unit("md_tanf_childcare_deduction", period) - - return max_( - gross_earned_income - + gross_unearned_income - - initial_deductions - - childcare_deduction, + # Apply deductions to earned income only, then add unearned + countable_earned = max_( + gross_earned_income - initial_deductions - childcare_deduction, 0, ) + return countable_earned + gross_unearned_income diff --git a/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.py b/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.py index 4d06262ea6b..98e785fa502 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.py +++ b/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.py @@ -6,7 +6,7 @@ class md_tanf_countable_gross_unearned_income(Variable): entity = SPMUnit label = "Maryland TANF countable gross unearned income" unit = USD - definition_period = YEAR + definition_period = MONTH defined_for = StateCode.MD reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0903%20Unearned%20Income%2011.22.doc" diff --git a/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_gross_unearned.py b/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_gross_unearned.py index 27b2d18e048..a45dd2d2590 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_gross_unearned.py +++ b/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_gross_unearned.py @@ -6,7 +6,7 @@ class md_tanf_gross_unearned(Variable): entity = SPMUnit label = "Maryland TANF gross unearned income" unit = USD - definition_period = YEAR + definition_period = MONTH defined_for = StateCode.MD reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0903%20Unearned%20Income%2011.22.doc" diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf.py b/policyengine_us/variables/gov/states/md/tanf/md_tanf.py index 516f7cf47ed..aed68bd9b56 100644 --- a/policyengine_us/variables/gov/states/md/tanf/md_tanf.py +++ b/policyengine_us/variables/gov/states/md/tanf/md_tanf.py @@ -6,8 +6,8 @@ class md_tanf(Variable): entity = SPMUnit label = "Maryland TANF" unit = USD - definition_period = YEAR - defined_for = StateCode.MD + definition_period = MONTH + defined_for = "md_tanf_eligible" reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0907%20Income%20Calculation%20of%20Ineligible%20Member%20rev%2011.22.doc" def formula(spm_unit, period, parameters): diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf_count_children.py b/policyengine_us/variables/gov/states/md/tanf/md_tanf_count_children.py index adb682c09a5..b0f3ff00c33 100644 --- a/policyengine_us/variables/gov/states/md/tanf/md_tanf_count_children.py +++ b/policyengine_us/variables/gov/states/md/tanf/md_tanf_count_children.py @@ -5,7 +5,7 @@ class md_tanf_count_children(Variable): value_type = int entity = SPMUnit label = "Maryland TANF number of children" - definition_period = YEAR + definition_period = MONTH defined_for = StateCode.MD reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0300-Technical-Eligibility/0307%20Age%20rev%2011.22.doc" adds = ["md_tanf_is_child"] diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf_eligible.py b/policyengine_us/variables/gov/states/md/tanf/md_tanf_eligible.py index 6c714f579be..c10beea4989 100644 --- a/policyengine_us/variables/gov/states/md/tanf/md_tanf_eligible.py +++ b/policyengine_us/variables/gov/states/md/tanf/md_tanf_eligible.py @@ -5,7 +5,7 @@ class md_tanf_eligible(Variable): value_type = bool entity = SPMUnit label = "Maryland TANF eligible" - definition_period = YEAR + definition_period = MONTH defined_for = StateCode.MD reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0300-Technical-Eligibility/0300%20Technical%20Eligibility%20Overview%20rev%2011.22.doc" diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf_is_child.py b/policyengine_us/variables/gov/states/md/tanf/md_tanf_is_child.py index 28be7afe1d5..7f01b14490e 100644 --- a/policyengine_us/variables/gov/states/md/tanf/md_tanf_is_child.py +++ b/policyengine_us/variables/gov/states/md/tanf/md_tanf_is_child.py @@ -4,21 +4,22 @@ class md_tanf_is_child(Variable): value_type = bool entity = Person - definition_period = YEAR + definition_period = MONTH label = "Is a child under Maryland TANF program" defined_for = StateCode.MD reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0300-Technical-Eligibility/0307%20Age%20rev%2011.22.doc" def formula(person, period, parameters): + p = parameters(period).gov.states.md.tanf + age = person("age", period.this_year) # Younger than age 18 - child = person("is_child", period) + child = person("is_child", period.this_year) # Younger than age 19 and a full-time K-12 student - p = parameters(period).gov.states.md.tanf - age_eligible = person("age", period) < p.age_limit + age_eligible = age < p.age_limit k12 = person("is_in_k12_school", period) k12_age_eligible = k12 & age_eligible # Age 19 and a full-time student - years_19 = person("age", period) == p.age_limit + years_19 = age == p.age_limit full_time_student = person("is_full_time_college_student", period) school_enrolled_19_year_old = full_time_student & years_19 return child | school_enrolled_19_year_old | k12_age_eligible diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf_maximum_benefit.py b/policyengine_us/variables/gov/states/md/tanf/md_tanf_maximum_benefit.py index 442f4836778..02c120cb92f 100644 --- a/policyengine_us/variables/gov/states/md/tanf/md_tanf_maximum_benefit.py +++ b/policyengine_us/variables/gov/states/md/tanf/md_tanf_maximum_benefit.py @@ -6,17 +6,14 @@ class md_tanf_maximum_benefit(Variable): entity = SPMUnit label = "Maryland TANF maximum benefit" unit = USD - definition_period = YEAR - defined_for = "md_tanf_eligible" + definition_period = MONTH + defined_for = StateCode.MD reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0908%20Grant%20Determination%20rev%2011.22.doc" def formula(spm_unit, period, parameters): - people = spm_unit("spm_unit_size", period) + people = spm_unit("spm_unit_size", period.this_year) p = parameters(period).gov.states.md.tanf.maximum_benefit - max_size = p.max_unit_size - capped_people = min_(people, max_size).astype(int) + capped_people = min_(people, p.max_unit_size).astype(int) additional_people = people - capped_people base = p.main[capped_people] - additional_maximum_benefit = p.additional * additional_people - monthly = base + additional_maximum_benefit - return monthly * MONTHS_IN_YEAR + return base + p.additional * additional_people diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf_self_employment_income.py b/policyengine_us/variables/gov/states/md/tanf/md_tanf_self_employment_income.py index 5052f39b912..6283fea6d4c 100644 --- a/policyengine_us/variables/gov/states/md/tanf/md_tanf_self_employment_income.py +++ b/policyengine_us/variables/gov/states/md/tanf/md_tanf_self_employment_income.py @@ -6,7 +6,7 @@ class md_tanf_self_employment_income(Variable): entity = SPMUnit label = "Maryland TANF self-employment income" unit = USD - definition_period = YEAR + definition_period = MONTH defined_for = StateCode.MD reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0902%20TCA%20Earned%20Income%20rev%2011.22.doc" From 4d64dfd63e2278322642cfdce754c1899c79b477 Mon Sep 17 00:00:00 2001 From: Ziming Date: Wed, 7 Jan 2026 21:26:58 -0500 Subject: [PATCH 04/10] fix --- .../gov/states/md/tanf/age_limit.yaml | 8 +- .../childcare_expenses/full_time.yaml | 8 +- .../childcare_expenses/part_time.yaml | 8 +- .../deductions/earned/fulltime_hours.yaml | 8 +- .../md/tanf/income/deductions/earned/new.yaml | 8 +- .../deductions/earned/not_self_employed.yaml | 8 +- .../deductions/earned/self_employed.yaml | 8 +- .../states/md/tanf/income/sources/earned.yaml | 8 +- .../md/tanf/income/sources/unearned.yaml | 8 +- .../md/tanf/maximum_benefit/additional.yaml | 8 +- .../states/md/tanf/maximum_benefit/main.yaml | 8 +- .../tanf/maximum_benefit/max_unit_size.yaml | 8 +- .../md_tanf_childcare_deduction.yaml | 46 ++++++++-- ...md_tanf_gross_earned_income_deduction.yaml | 69 --------------- ..._tanf_countable_gross_unearned_income.yaml | 4 +- .../gov/states/md/tanf/md_tanf_eligible.yaml | 87 +++++++++++++++++++ .../gov/states/md/tanf/md_tanf_is_child.yaml | 12 +-- .../deductions/md_tanf_childcare_deduction.py | 13 +-- .../md_tanf_continuous_earnings_deduction.py | 4 +- .../md_tanf_initial_earnings_deduction.py | 4 +- .../md_tanf_countable_gross_earned_income.py | 21 ++++- .../md_tanf_gross_earned_income_deduction.py | 30 ------- .../income/md_tanf_net_countable_income.py | 4 +- .../md_tanf_net_initial_countable_income.py | 4 +- ...md_tanf_countable_gross_unearned_income.py | 7 +- .../income/unearned/md_tanf_gross_unearned.py | 13 --- .../unearned/md_tanf_gross_unearned_income.py | 13 +++ .../variables/gov/states/md/tanf/md_tanf.py | 7 +- .../states/md/tanf/md_tanf_count_children.py | 4 +- .../gov/states/md/tanf/md_tanf_eligible.py | 4 +- .../gov/states/md/tanf/md_tanf_is_child.py | 13 +-- .../states/md/tanf/md_tanf_maximum_benefit.py | 4 +- .../md/tanf/md_tanf_self_employment_income.py | 4 +- 33 files changed, 251 insertions(+), 212 deletions(-) delete mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/md_tanf_gross_earned_income_deduction.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_eligible.yaml delete mode 100644 policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_gross_earned_income_deduction.py delete mode 100644 policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_gross_unearned.py create mode 100644 policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_gross_unearned_income.py diff --git a/policyengine_us/parameters/gov/states/md/tanf/age_limit.yaml b/policyengine_us/parameters/gov/states/md/tanf/age_limit.yaml index d7a16c72a61..1ec70315a57 100644 --- a/policyengine_us/parameters/gov/states/md/tanf/age_limit.yaml +++ b/policyengine_us/parameters/gov/states/md/tanf/age_limit.yaml @@ -1,4 +1,4 @@ -description: Maryland limits TANF eligibility to children below this age threshold. +description: Maryland limits eligibility to children below this age threshold under the Temporary Cash Assistance program. values: 2022-11-01: 19 @@ -6,7 +6,7 @@ values: metadata: unit: year period: year - label: Maryland TANF age limit + label: Maryland TCA age limit reference: - - title: Maryland Temporary Cash Assistance Manual - Section 0307 Age - href: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0300-Technical-Eligibility/0307%20Age%20rev%2011.22.doc + - title: COMAR 07.03.03.07 - Age Requirements + href: https://dsd.maryland.gov/regulations/Pages/07.03.03.07.aspx diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/full_time.yaml b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/full_time.yaml index ba3789a075f..6911bdb5a7e 100644 --- a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/full_time.yaml +++ b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/full_time.yaml @@ -1,4 +1,4 @@ -description: Maryland provides this monthly childcare deduction per child for full-time workers under the TANF program. +description: Maryland provides this monthly childcare deduction for full-time workers under the Temporary Cash Assistance program. values: 2022-11-01: 200 @@ -6,7 +6,7 @@ values: metadata: period: month unit: currency-USD - label: Maryland TANF childcare deduction for full-time workers + label: Maryland TCA childcare deduction for full-time workers reference: - - title: Maryland Temporary Cash Assistance Manual - Section 904.1 Deductions from Earned Income - href: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0904%20Deductions%20and%20Expenses%20rev%2011.22.1.doc + - title: COMAR 07.03.03.13 - Income + href: https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/part_time.yaml b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/part_time.yaml index 13a888fc9d3..700c863c10f 100644 --- a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/part_time.yaml +++ b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/part_time.yaml @@ -1,4 +1,4 @@ -description: Maryland provides this monthly childcare deduction per child for part-time workers under the TANF program. +description: Maryland provides this monthly childcare deduction for part-time workers under the Temporary Cash Assistance program. values: 2022-11-01: 100 @@ -6,7 +6,7 @@ values: metadata: period: month unit: currency-USD - label: Maryland TANF childcare deduction for part-time workers + label: Maryland TCA childcare deduction for part-time workers reference: - - title: Maryland Temporary Cash Assistance Manual - Section 904.1 Deductions from Earned Income - href: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0904%20Deductions%20and%20Expenses%20rev%2011.22.1.doc + - title: COMAR 07.03.03.13 - Income + href: https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/fulltime_hours.yaml b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/fulltime_hours.yaml index 9445b27d5d7..da2493e4539 100644 --- a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/fulltime_hours.yaml +++ b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/fulltime_hours.yaml @@ -1,4 +1,4 @@ -description: Maryland requires this number of weekly work hours for full-time classification under the TANF program. +description: Maryland requires this number of weekly work hours for full-time classification under the Temporary Cash Assistance program. values: 2022-11-01: 25 @@ -6,7 +6,7 @@ values: metadata: unit: hour period: week - label: Maryland TANF full-time work hours threshold + label: Maryland TCA full-time work hours threshold reference: - - title: Maryland Temporary Cash Assistance Manual - Section 904.1 Deductions from Earned Income - href: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0904%20Deductions%20and%20Expenses%20rev%2011.22.1.doc + - title: COMAR 07.03.03.13 - Income + href: https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/new.yaml b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/new.yaml index 165c28eb934..283bb8a390c 100644 --- a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/new.yaml +++ b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/new.yaml @@ -1,4 +1,4 @@ -description: Maryland excludes this share of earnings from TANF countable earned income, for individuals not currently enrolled in TANF. +description: Maryland excludes this share of earnings from countable earned income under the Temporary Cash Assistance program for individuals not currently enrolled. values: 2022-11-01: 0.2 @@ -6,7 +6,7 @@ values: metadata: unit: /1 period: month - label: Maryland TANF earnings exclusion percent for new enrollees + label: Maryland TCA initial earnings exclusion rate reference: - - title: Maryland TEMPORARY CASH ASSISTANCE MANUAL 904.1 DEDUCTIONS FROM EARNED INCOME - href: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0904%20Deductions%20and%20Expenses%20rev%2011.22.1.doc + - title: COMAR 07.03.03.13 - Income + href: https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/not_self_employed.yaml b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/not_self_employed.yaml index bf54cc4ca0f..0a882e56d96 100644 --- a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/not_self_employed.yaml +++ b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/not_self_employed.yaml @@ -1,4 +1,4 @@ -description: Maryland excludes this share of earnings from TANF countable earned income, for individuals without self employment income. +description: Maryland excludes this share of earnings from countable earned income under the Temporary Cash Assistance program for enrolled recipients without self-employment income. values: 2022-11-01: 0.4 @@ -6,7 +6,7 @@ values: metadata: unit: /1 period: month - label: Maryland TANF earnings exclusion percent for non-self-employed individuals + label: Maryland TCA continuous earnings exclusion rate reference: - - title: Maryland TEMPORARY CASH ASSISTANCE MANUAL 904.1 DEDUCTIONS FROM EARNED INCOME - href: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0904%20Deductions%20and%20Expenses%20rev%2011.22.1.doc + - title: COMAR 07.03.03.13 - Income + href: https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/self_employed.yaml b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/self_employed.yaml index 039ec1a662c..4955d902831 100644 --- a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/self_employed.yaml +++ b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/self_employed.yaml @@ -1,4 +1,4 @@ -description: Maryland excludes this share of earnings from TANF countable earned income, for individuals with self employment income. +description: Maryland excludes this share of earnings from countable earned income under the Temporary Cash Assistance program for self-employed individuals. values: 2022-11-01: 0.5 @@ -6,7 +6,7 @@ values: metadata: unit: /1 period: month - label: Maryland TANF earnings exclusion percent for self-employed individuals + label: Maryland TCA self-employment earnings exclusion rate reference: - - title: Maryland TEMPORARY CASH ASSISTANCE MANUAL 904.1 DEDUCTIONS FROM EARNED INCOME - href: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0904%20Deductions%20and%20Expenses%20rev%2011.22.1.doc + - title: COMAR 07.03.03.13 - Income + href: https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/sources/earned.yaml b/policyengine_us/parameters/gov/states/md/tanf/income/sources/earned.yaml index 3b567892f48..495f08e5000 100644 --- a/policyengine_us/parameters/gov/states/md/tanf/income/sources/earned.yaml +++ b/policyengine_us/parameters/gov/states/md/tanf/income/sources/earned.yaml @@ -1,4 +1,4 @@ -description: Maryland TANF counts these income sources as earned income. +description: Maryland counts these income sources as earned income under the Temporary Cash Assistance program. values: 2022-11-01: @@ -9,7 +9,7 @@ values: metadata: unit: list period: year - label: Maryland TANF earned income sources + label: Maryland TCA earned income sources reference: - - title: Maryland Temporary Cash Assistance Manual - Section 0902 Earned Income - href: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0902%20TCA%20Earned%20Income%20rev%2011.22.doc + - title: COMAR 07.03.03.13 - Income + href: https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/sources/unearned.yaml b/policyengine_us/parameters/gov/states/md/tanf/income/sources/unearned.yaml index 131226f8482..d599aa5cc34 100644 --- a/policyengine_us/parameters/gov/states/md/tanf/income/sources/unearned.yaml +++ b/policyengine_us/parameters/gov/states/md/tanf/income/sources/unearned.yaml @@ -1,4 +1,4 @@ -description: Maryland TANF counts these income sources as unearned income. +description: Maryland counts these income sources as unearned income under the Temporary Cash Assistance program. values: 2022-11-01: @@ -12,7 +12,7 @@ values: metadata: unit: list period: year - label: Maryland TANF unearned income sources + label: Maryland TCA unearned income sources reference: - - title: Maryland Temporary Cash Assistance Manual - Section 0903 Unearned Income - href: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0903%20Unearned%20Income%2011.22.doc + - title: COMAR 07.03.03.13 - Income + href: https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx diff --git a/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/additional.yaml b/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/additional.yaml index 8ea6c59733a..c88d8cdf12d 100644 --- a/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/additional.yaml +++ b/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/additional.yaml @@ -1,4 +1,4 @@ -description: Maryland provides this additional amount per person for households exceeding the maximum unit size. +description: Maryland provides this additional amount per person for households exceeding the maximum unit size under the Temporary Cash Assistance program. values: 2021-10-01: 136 @@ -6,7 +6,7 @@ values: metadata: unit: currency-USD period: month - label: Maryland TANF additional grant amount per person + label: Maryland TCA additional grant amount per person reference: - - title: Maryland Temporary Cash Assistance Manual - Section 0908 Grant Determination - href: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0908%20Grant%20Determination%20rev%2011.22.doc + - title: COMAR 07.03.03.17 - Benefit Schedules + href: https://dsd.maryland.gov/regulations/Pages/07.03.03.17.aspx diff --git a/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/main.yaml b/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/main.yaml index de0c917b33f..fb6b031d7ff 100644 --- a/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/main.yaml +++ b/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/main.yaml @@ -1,4 +1,4 @@ -description: Maryland provides this amount as the monthly grant standard under the Temporary Assistance for Needy Families program. +description: Maryland provides this amount as the monthly grant standard under the Temporary Cash Assistance program. 1: 2021-10-01: 328 @@ -20,9 +20,9 @@ description: Maryland provides this amount as the monthly grant standard under t metadata: unit: currency-USD period: month - label: Maryland TANF grant standard + label: Maryland TCA grant standard breakdown: - range(1, 9) reference: - - title: Maryland Temporary Cash Assistance Manual - Section 0908 Grant Determination - href: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0908%20Grant%20Determination%20rev%2011.22.doc + - title: COMAR 07.03.03.17 - Benefit Schedules + href: https://dsd.maryland.gov/regulations/Pages/07.03.03.17.aspx diff --git a/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/max_unit_size.yaml b/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/max_unit_size.yaml index 01759121cf8..99e16897575 100644 --- a/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/max_unit_size.yaml +++ b/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/max_unit_size.yaml @@ -1,4 +1,4 @@ -description: Maryland caps TANF grant standard lookup at this household size, with additional amounts for larger households. +description: Maryland caps the grant standard lookup at this household size under the Temporary Cash Assistance program. values: 2021-10-01: 8 @@ -6,7 +6,7 @@ values: metadata: unit: person period: year - label: Maryland TANF maximum unit size for grant standard lookup + label: Maryland TCA maximum unit size for grant standard lookup reference: - - title: Maryland Temporary Cash Assistance Manual - Grant Standards - href: https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0908%20Grant%20Determination%20rev%2011.22.doc + - title: COMAR 07.03.03.17 - Benefit Schedules + href: https://dsd.maryland.gov/regulations/Pages/07.03.03.17.aspx diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.yaml index eb97a2436d8..16d67b0c560 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.yaml @@ -16,7 +16,7 @@ output: md_tanf_childcare_deduction: 0 -- name: Case 2, two children, part-time work. +- name: Case 2, has children, part-time work. period: 2023-01 input: people: @@ -32,10 +32,10 @@ household: state_code: MD output: - # 2 children × $100/child (part-time) = $200/month - md_tanf_childcare_deduction: 200 + # Per-household deduction: $100/month (part-time) + md_tanf_childcare_deduction: 100 -- name: Case 3, two children, full-time work. +- name: Case 3, has children, full-time work. period: 2023-01 input: people: @@ -51,5 +51,39 @@ household: state_code: MD output: - # 2 children × $200/child (full-time, any member >= 25 hours) = $400/month - md_tanf_childcare_deduction: 400 + # Per-household deduction: $200/month (full-time, any member >= 25 hours) + md_tanf_childcare_deduction: 200 + +- name: Case 4, has children, at exactly 25 hours threshold. + period: 2023-01 + input: + people: + person1: + work_hours_per_week: 25 + spm_units: + spm_unit: + members: [person1] + md_tanf_count_children: 1 + households: + household: + state_code: MD + output: + # Exactly at threshold (>= 25 hours) qualifies for full-time rate + md_tanf_childcare_deduction: 200 + +- name: Case 5, has children, at 24 hours (below threshold). + period: 2023-01 + input: + people: + person1: + work_hours_per_week: 24 + spm_units: + spm_unit: + members: [person1] + md_tanf_count_children: 1 + households: + household: + state_code: MD + output: + # Below threshold (< 25 hours) gets part-time rate + md_tanf_childcare_deduction: 100 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/md_tanf_gross_earned_income_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/md_tanf_gross_earned_income_deduction.yaml deleted file mode 100644 index b1a08979fbc..00000000000 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/md_tanf_gross_earned_income_deduction.yaml +++ /dev/null @@ -1,69 +0,0 @@ -- name: Case 1, zero earned income, zero deduction. - period: 2023-01 - input: - people: - person1: - employment_income: 0 - self_employment_income: 0 - spm_units: - spm_unit: - members: [person1] - households: - household: - state_code: MD - output: - md_tanf_gross_earned_income_deduction: 0 - -- name: Case 2, not enrolled in TANF, 20% deduction. - period: 2023-01 - input: - people: - person1: - employment_income: 1_200 - self_employment_income: 0 - is_tanf_enrolled: false - spm_units: - spm_unit: - members: [person1] - households: - household: - state_code: MD - output: - # $1,200/year = $100/month × 0.20 = $20/month - md_tanf_gross_earned_income_deduction: 20 - -- name: Case 3, enrolled in TANF and not self-employed, 40% deduction. - period: 2023-01 - input: - people: - person1: - employment_income: 1_200 - self_employment_income: 0 - is_tanf_enrolled: true - spm_units: - spm_unit: - members: [person1] - households: - household: - state_code: MD - output: - # $1,200/year = $100/month × 0.40 = $40/month - md_tanf_gross_earned_income_deduction: 40 - -- name: Case 4, self-employed, 50% deduction. - period: 2023-01 - input: - people: - person1: - employment_income: 1_200 - self_employment_income: 1_200 - is_tanf_enrolled: true - spm_units: - spm_unit: - members: [person1] - households: - household: - state_code: MD - output: - # $1,200/year = $100/month × 0.50 = $50/month - md_tanf_gross_earned_income_deduction: 50 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.yaml index 03de8df30c0..9757c46285f 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.yaml @@ -3,7 +3,7 @@ input: spm_units: spm_unit: - md_tanf_gross_unearned: 100 + md_tanf_gross_unearned_income: 100 households: household: state_code: MD @@ -15,7 +15,7 @@ input: spm_units: spm_unit: - md_tanf_gross_unearned: 0 + md_tanf_gross_unearned_income: 0 households: household: state_code: MD diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_eligible.yaml new file mode 100644 index 00000000000..1487f0439ce --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_eligible.yaml @@ -0,0 +1,87 @@ +- name: Case 1, household with children and demographic eligibility is eligible. + period: 2023-01 + input: + people: + parent: + age: 30 + child: + age: 5 + spm_units: + spm_unit: + members: [parent, child] + households: + household: + state_code: MD + output: + md_tanf_eligible: true + +- name: Case 2, household with no children is not eligible. + period: 2023-01 + input: + people: + adult1: + age: 30 + adult2: + age: 28 + spm_units: + spm_unit: + members: [adult1, adult2] + households: + household: + state_code: MD + output: + md_tanf_eligible: false + +- name: Case 3, single person with no children is not eligible. + period: 2023-01 + input: + people: + adult: + age: 25 + spm_units: + spm_unit: + members: [adult] + households: + household: + state_code: MD + output: + md_tanf_eligible: false + +- name: Case 4, household with 19 year old secondary school student is eligible. + period: 2023-01 + input: + people: + parent: + age: 40 + student: + age: 19 + is_in_k12_school: true + spm_units: + spm_unit: + members: [parent, student] + households: + household: + state_code: MD + output: + # Per COMAR 07.03.03.07, 19-year-old secondary school students count as children + md_tanf_eligible: true + +- name: Case 5, household with 19 year old college student is not eligible. + period: 2023-01 + input: + people: + parent: + age: 40 + student: + age: 19 + is_full_time_college_student: true + is_in_k12_school: false + spm_units: + spm_unit: + members: [parent, student] + households: + household: + state_code: MD + output: + # Per COMAR 07.03.03.07, college students do not count as children at age 19 + md_tanf_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_is_child.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_is_child.yaml index ae0517f6014..a61848b97bd 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_is_child.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_is_child.yaml @@ -18,7 +18,7 @@ output: md_tanf_is_child: true -- name: Case 3, person age 19 full-time college student is a child. +- name: Case 3, person age 19 full-time college student is not a child. period: 2023-01 input: age: 19 @@ -26,9 +26,11 @@ is_in_k12_school: false state_code: MD output: - md_tanf_is_child: true + # Per COMAR 07.03.03.07, only secondary school students qualify at age 19 + # College students do not qualify for extended eligibility + md_tanf_is_child: false -- name: Case 4, person age 19 K-12 student is not a child. +- name: Case 4, person age 19 K-12 student is a child. period: 2023-01 input: age: 19 @@ -36,8 +38,8 @@ is_in_k12_school: true state_code: MD output: - # Age 19 K-12 student doesn't qualify (age_limit is 19, so age < 19 fails) - md_tanf_is_child: false + # Per COMAR 07.03.03.07, 19-year-old secondary school students qualify + md_tanf_is_child: true - name: Case 5, person age 5 is a child. period: 2023-01 diff --git a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.py b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.py index 68658e7ed0c..f01103f0803 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.py +++ b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.py @@ -4,22 +4,25 @@ class md_tanf_childcare_deduction(Variable): value_type = float entity = SPMUnit - label = "Maryland TANF childcare deduction" + label = "Maryland TCA childcare deduction" unit = USD definition_period = MONTH defined_for = StateCode.MD - reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0904%20Deductions%20and%20Expenses%20rev%2011.22.1.doc" + reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx" def formula(spm_unit, period, parameters): - children = spm_unit("md_tanf_count_children", period) + # Per COMAR 07.03.03.13, childcare deduction is only available + # for households with children. The deduction is based on the + # employment hours of the assistance unit member. + has_children = spm_unit("md_tanf_count_children", period) > 0 person = spm_unit.members work_hours = person("work_hours_per_week", period) - # Get the policy parameters. p = parameters(period).gov.states.md.tanf.income.deductions full_time = spm_unit.any(work_hours >= p.earned.fulltime_hours) - return children * where( + deduction = where( full_time, p.childcare_expenses.full_time, p.childcare_expenses.part_time, ) + return where(has_children, deduction, 0) diff --git a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.py b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.py index dd5e9126216..a17b84e7401 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.py +++ b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.py @@ -4,11 +4,11 @@ class md_tanf_continuous_earnings_deduction(Variable): value_type = float entity = SPMUnit - label = "Maryland TANF continuous earnings deduction" + label = "Maryland TCA continuous earnings deduction" unit = USD definition_period = MONTH defined_for = StateCode.MD - reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0904%20Deductions%20and%20Expenses%20rev%2011.22.1.doc" + reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx" def formula(spm_unit, period, parameters): p = parameters(period).gov.states.md.tanf.income.deductions.earned diff --git a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.py b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.py index ef25edf53d9..9e43c4bf3dc 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.py +++ b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.py @@ -4,11 +4,11 @@ class md_tanf_initial_earnings_deduction(Variable): value_type = float entity = SPMUnit - label = "Maryland TANF initial earnings deduction" + label = "Maryland TCA initial earnings deduction" unit = USD definition_period = MONTH defined_for = StateCode.MD - reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0902%20TCA%20Earned%20Income%20rev%2011.22.doc" + reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx" def formula(spm_unit, period, parameters): p = parameters(period).gov.states.md.tanf.income.deductions.earned diff --git a/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_countable_gross_earned_income.py b/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_countable_gross_earned_income.py index b606694b364..4b418ffcc75 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_countable_gross_earned_income.py +++ b/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_countable_gross_earned_income.py @@ -4,10 +4,25 @@ class md_tanf_countable_gross_earned_income(Variable): value_type = float entity = SPMUnit - label = "Maryland TANF countable gross earned income" + label = "Maryland TCA countable gross earned income" unit = USD definition_period = MONTH defined_for = StateCode.MD - reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0902%20TCA%20Earned%20Income%20rev%2011.22.doc" + reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx" - adds = "gov.states.md.tanf.income.sources.earned" + def formula(spm_unit, period, parameters): + # Per COMAR 07.03.03.13, exclude: + # 1. Earned income of a child + # 2. Earned income of an SSI recipient + person = spm_unit.members + is_child = person("md_tanf_is_child", period) + is_ssi_recipient = person("is_ssi_eligible", period.this_year) + # Count only earned income from non-children and non-SSI recipients + include_income = ~is_child & ~is_ssi_recipient + # Get earned income sources from parameters + earned_sources = parameters( + period + ).gov.states.md.tanf.income.sources.earned + total_earned = add(person, period, earned_sources) + countable_earned = total_earned * include_income + return spm_unit.sum(countable_earned) diff --git a/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_gross_earned_income_deduction.py b/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_gross_earned_income_deduction.py deleted file mode 100644 index 0c8a44e343a..00000000000 --- a/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_gross_earned_income_deduction.py +++ /dev/null @@ -1,30 +0,0 @@ -from policyengine_us.model_api import * - - -class md_tanf_gross_earned_income_deduction(Variable): - value_type = float - entity = SPMUnit - label = "Maryland TANF earned income deduction" - unit = USD - definition_period = MONTH - defined_for = StateCode.MD - reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0904%20Deductions%20and%20Expenses%20rev%2011.22.1.doc" - - def formula(spm_unit, period, parameters): - # Get TANF enrollment status. - is_tanf_enrolled = spm_unit("is_tanf_enrolled", period) - # Get earned income for the SPM unit. - earned_income = add(spm_unit, period, ["employment_income"]) - # Determine if the SPM unit has any self-employment income. - self_employment_income = add( - spm_unit, period, ["self_employment_income"] - ) - has_self_employment_income = self_employment_income > 0 - # Get the policy parameters. - p = parameters(period).gov.states.md.tanf.income.deductions.earned - percent = select( - [~is_tanf_enrolled, has_self_employment_income], - [p.new, p.self_employed], - default=p.not_self_employed, - ) - return earned_income * percent diff --git a/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_countable_income.py b/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_countable_income.py index 93766b0586c..69529a9b8bb 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_countable_income.py +++ b/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_countable_income.py @@ -4,11 +4,11 @@ class md_tanf_net_countable_income(Variable): value_type = float entity = SPMUnit - label = "Maryland TANF net countable income" + label = "Maryland TCA net countable income" unit = USD definition_period = MONTH defined_for = StateCode.MD - reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0902%20TCA%20Earned%20Income%20rev%2011.22.doc" + reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx" def formula(spm_unit, period, parameters): # Get gross income for the SPM unit. diff --git a/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.py b/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.py index 03e8baa0e75..021c75915b7 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.py +++ b/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.py @@ -4,11 +4,11 @@ class md_tanf_net_initial_countable_income(Variable): value_type = float entity = SPMUnit - label = "Maryland TANF net initial countable income" + label = "Maryland TCA net initial countable income" unit = USD definition_period = MONTH defined_for = StateCode.MD - reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0902%20TCA%20Earned%20Income%20rev%2011.22.doc" + reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx" def formula(spm_unit, period, parameters): # Get gross income for the SPM unit. diff --git a/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.py b/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.py index 98e785fa502..41147cff3c2 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.py +++ b/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.py @@ -4,11 +4,10 @@ class md_tanf_countable_gross_unearned_income(Variable): value_type = float entity = SPMUnit - label = "Maryland TANF countable gross unearned income" + label = "Maryland TCA countable gross unearned income" unit = USD definition_period = MONTH defined_for = StateCode.MD - reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0903%20Unearned%20Income%2011.22.doc" + reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx" - def formula(spm_unit, period, parameters): - return spm_unit("md_tanf_gross_unearned", period) + adds = ["md_tanf_gross_unearned_income"] diff --git a/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_gross_unearned.py b/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_gross_unearned.py deleted file mode 100644 index a45dd2d2590..00000000000 --- a/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_gross_unearned.py +++ /dev/null @@ -1,13 +0,0 @@ -from policyengine_us.model_api import * - - -class md_tanf_gross_unearned(Variable): - value_type = float - entity = SPMUnit - label = "Maryland TANF gross unearned income" - unit = USD - definition_period = MONTH - defined_for = StateCode.MD - reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0903%20Unearned%20Income%2011.22.doc" - - adds = "gov.states.md.tanf.income.sources.unearned" diff --git a/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_gross_unearned_income.py b/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_gross_unearned_income.py new file mode 100644 index 00000000000..7215c696289 --- /dev/null +++ b/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_gross_unearned_income.py @@ -0,0 +1,13 @@ +from policyengine_us.model_api import * + + +class md_tanf_gross_unearned_income(Variable): + value_type = float + entity = SPMUnit + label = "Maryland TCA gross unearned income" + unit = USD + definition_period = MONTH + defined_for = StateCode.MD + reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx" + + adds = "gov.states.md.tanf.income.sources.unearned" diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf.py b/policyengine_us/variables/gov/states/md/tanf/md_tanf.py index aed68bd9b56..bb8c79d1709 100644 --- a/policyengine_us/variables/gov/states/md/tanf/md_tanf.py +++ b/policyengine_us/variables/gov/states/md/tanf/md_tanf.py @@ -4,16 +4,13 @@ class md_tanf(Variable): value_type = float entity = SPMUnit - label = "Maryland TANF" + label = "Maryland Temporary Cash Assistance" unit = USD definition_period = MONTH defined_for = "md_tanf_eligible" - reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0907%20Income%20Calculation%20of%20Ineligible%20Member%20rev%2011.22.doc" + reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.17.aspx" def formula(spm_unit, period, parameters): - # Maximum TANF amount received grant_standard = spm_unit("md_tanf_maximum_benefit", period) - # SPM unit income after continuous deduction - # Note: md_tanf_net_countable_income already includes all deductions income = spm_unit("md_tanf_net_countable_income", period) return max_(grant_standard - income, 0) diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf_count_children.py b/policyengine_us/variables/gov/states/md/tanf/md_tanf_count_children.py index b0f3ff00c33..dc276a6e8f4 100644 --- a/policyengine_us/variables/gov/states/md/tanf/md_tanf_count_children.py +++ b/policyengine_us/variables/gov/states/md/tanf/md_tanf_count_children.py @@ -4,8 +4,8 @@ class md_tanf_count_children(Variable): value_type = int entity = SPMUnit - label = "Maryland TANF number of children" + label = "Maryland TCA number of children" definition_period = MONTH defined_for = StateCode.MD - reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0300-Technical-Eligibility/0307%20Age%20rev%2011.22.doc" + reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.07.aspx" adds = ["md_tanf_is_child"] diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf_eligible.py b/policyengine_us/variables/gov/states/md/tanf/md_tanf_eligible.py index c10beea4989..d545024256f 100644 --- a/policyengine_us/variables/gov/states/md/tanf/md_tanf_eligible.py +++ b/policyengine_us/variables/gov/states/md/tanf/md_tanf_eligible.py @@ -4,10 +4,10 @@ class md_tanf_eligible(Variable): value_type = bool entity = SPMUnit - label = "Maryland TANF eligible" + label = "Maryland TCA eligible" definition_period = MONTH defined_for = StateCode.MD - reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0300-Technical-Eligibility/0300%20Technical%20Eligibility%20Overview%20rev%2011.22.doc" + reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.03.aspx" def formula(spm_unit, period, parameters): has_children = spm_unit("md_tanf_count_children", period) > 0 diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf_is_child.py b/policyengine_us/variables/gov/states/md/tanf/md_tanf_is_child.py index 7f01b14490e..2a8ae2565c0 100644 --- a/policyengine_us/variables/gov/states/md/tanf/md_tanf_is_child.py +++ b/policyengine_us/variables/gov/states/md/tanf/md_tanf_is_child.py @@ -5,9 +5,9 @@ class md_tanf_is_child(Variable): value_type = bool entity = Person definition_period = MONTH - label = "Is a child under Maryland TANF program" + label = "Is a child under Maryland TCA program" defined_for = StateCode.MD - reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0300-Technical-Eligibility/0307%20Age%20rev%2011.22.doc" + reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.07.aspx" def formula(person, period, parameters): p = parameters(period).gov.states.md.tanf @@ -18,8 +18,9 @@ def formula(person, period, parameters): age_eligible = age < p.age_limit k12 = person("is_in_k12_school", period) k12_age_eligible = k12 & age_eligible - # Age 19 and a full-time student + # Age 19 and a full-time secondary school student + # Per COMAR 07.03.03.07, extended eligibility is for secondary school + # students only - college students do not qualify years_19 = age == p.age_limit - full_time_student = person("is_full_time_college_student", period) - school_enrolled_19_year_old = full_time_student & years_19 - return child | school_enrolled_19_year_old | k12_age_eligible + secondary_school_enrolled_19_year_old = k12 & years_19 + return child | secondary_school_enrolled_19_year_old | k12_age_eligible diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf_maximum_benefit.py b/policyengine_us/variables/gov/states/md/tanf/md_tanf_maximum_benefit.py index 02c120cb92f..4de87ef8627 100644 --- a/policyengine_us/variables/gov/states/md/tanf/md_tanf_maximum_benefit.py +++ b/policyengine_us/variables/gov/states/md/tanf/md_tanf_maximum_benefit.py @@ -4,11 +4,11 @@ class md_tanf_maximum_benefit(Variable): value_type = float entity = SPMUnit - label = "Maryland TANF maximum benefit" + label = "Maryland TCA maximum benefit" unit = USD definition_period = MONTH defined_for = StateCode.MD - reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0908%20Grant%20Determination%20rev%2011.22.doc" + reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.17.aspx" def formula(spm_unit, period, parameters): people = spm_unit("spm_unit_size", period.this_year) diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf_self_employment_income.py b/policyengine_us/variables/gov/states/md/tanf/md_tanf_self_employment_income.py index 6283fea6d4c..0e2745fefb9 100644 --- a/policyengine_us/variables/gov/states/md/tanf/md_tanf_self_employment_income.py +++ b/policyengine_us/variables/gov/states/md/tanf/md_tanf_self_employment_income.py @@ -4,10 +4,10 @@ class md_tanf_self_employment_income(Variable): value_type = float entity = SPMUnit - label = "Maryland TANF self-employment income" + label = "Maryland TCA self-employment income" unit = USD definition_period = MONTH defined_for = StateCode.MD - reference = "https://dhs.maryland.gov/documents/Manuals/Temporary-Cash-Assistance-Manual/0900-Financial-Eligibility/0902%20TCA%20Earned%20Income%20rev%2011.22.doc" + reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx" adds = "gov.irs.tax.self_employment.taxable_self_employment_income" From 4d38dd8f70d3ab234d8d7ac34d58bd754208f05d Mon Sep 17 00:00:00 2001 From: Ziming Date: Sat, 10 Jan 2026 19:00:25 -0500 Subject: [PATCH 05/10] pr fix --- .../states/md/tanf/income/sources/earned.yaml | 1 - ...md_tanf_continuous_earnings_deduction.yaml | 16 +++ .../md_tanf_initial_earnings_deduction.yaml | 16 +++ ...md_tanf_countable_gross_earned_income.yaml | 104 ++++++++++++++++++ .../income/md_tanf_net_countable_income.yaml | 12 ++ .../md_tanf_net_initial_countable_income.yaml | 12 ++ ..._tanf_countable_gross_unearned_income.yaml | 8 ++ .../gov/states/md/tanf/integration.yaml | 16 +-- .../baseline/gov/states/md/tanf/md_tanf.yaml | 16 +++ .../gov/states/md/tanf/md_tanf_eligible.yaml | 36 +++--- .../md/tanf/md_tanf_maximum_benefit.yaml | 56 ++++++++-- .../deductions/md_tanf_childcare_deduction.py | 2 +- .../md_tanf_initial_earnings_deduction.py | 4 +- 13 files changed, 262 insertions(+), 37 deletions(-) create mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/earned/md_tanf_countable_gross_earned_income.yaml diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/sources/earned.yaml b/policyengine_us/parameters/gov/states/md/tanf/income/sources/earned.yaml index 495f08e5000..bbf8a0b7fa9 100644 --- a/policyengine_us/parameters/gov/states/md/tanf/income/sources/earned.yaml +++ b/policyengine_us/parameters/gov/states/md/tanf/income/sources/earned.yaml @@ -4,7 +4,6 @@ values: 2022-11-01: - employment_income - self_employment_income - - armed_services_basic_allowance_for_housing metadata: unit: list diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.yaml index 29d280f79fa..22e91f83a7d 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.yaml @@ -1,8 +1,12 @@ - name: Case 1, zero earned income, zero deduction. period: 2023-01 input: + people: + person1: + age: 30 spm_units: spm_unit: + members: [person1] md_tanf_countable_gross_earned_income: 0 md_tanf_self_employment_income: 0 households: @@ -14,8 +18,12 @@ - name: Case 2, non-self-employed, 40% deduction. period: 2023-01 input: + people: + person1: + age: 30 spm_units: spm_unit: + members: [person1] md_tanf_countable_gross_earned_income: 100 md_tanf_self_employment_income: 0 households: @@ -28,8 +36,12 @@ - name: Case 3, all self-employed, 50% deduction. period: 2023-01 input: + people: + person1: + age: 30 spm_units: spm_unit: + members: [person1] md_tanf_countable_gross_earned_income: 100 md_tanf_self_employment_income: 100 households: @@ -42,8 +54,12 @@ - name: Case 4, partially self-employed, combined deduction. period: 2023-01 input: + people: + person1: + age: 30 spm_units: spm_unit: + members: [person1] md_tanf_countable_gross_earned_income: 100 md_tanf_self_employment_income: 80 households: diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.yaml index 90ab7a03b71..92ea0b6b8e7 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.yaml @@ -1,8 +1,12 @@ - name: Case 1, zero earned income, zero deduction. period: 2023-01 input: + people: + person1: + age: 30 spm_units: spm_unit: + members: [person1] md_tanf_countable_gross_earned_income: 0 md_tanf_self_employment_income: 0 households: @@ -14,8 +18,12 @@ - name: Case 2, non-self-employed, 20% deduction. period: 2023-01 input: + people: + person1: + age: 30 spm_units: spm_unit: + members: [person1] md_tanf_countable_gross_earned_income: 100 md_tanf_self_employment_income: 0 households: @@ -28,8 +36,12 @@ - name: Case 3, all self-employed, 50% deduction. period: 2023-01 input: + people: + person1: + age: 30 spm_units: spm_unit: + members: [person1] md_tanf_countable_gross_earned_income: 100 md_tanf_self_employment_income: 100 households: @@ -42,8 +54,12 @@ - name: Case 4, partially self-employed, combined deduction. period: 2023-01 input: + people: + person1: + age: 30 spm_units: spm_unit: + members: [person1] md_tanf_countable_gross_earned_income: 100 md_tanf_self_employment_income: 80 households: diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/earned/md_tanf_countable_gross_earned_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/earned/md_tanf_countable_gross_earned_income.yaml new file mode 100644 index 00000000000..7142c952333 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/earned/md_tanf_countable_gross_earned_income.yaml @@ -0,0 +1,104 @@ +- name: Case 1, adult with employment income. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 24_000 + spm_units: + spm_unit: + members: [person1] + households: + household: + state_code: MD + output: + md_tanf_countable_gross_earned_income: 2_000 + +- name: Case 2, child income excluded. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 24_000 + person2: + age: 10 + employment_income: 6_000 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + state_code: MD + output: + # Only adult's income counted (2_000/month), child's income (500/month) excluded + md_tanf_countable_gross_earned_income: 2_000 + +- name: Case 3, SSI recipient income excluded. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 24_000 + is_ssi_eligible: true + person2: + age: 35 + employment_income: 12_000 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + state_code: MD + output: + # Only non-SSI adult's income counted (1_000/month) + # SSI recipient's income (2_000/month) excluded + md_tanf_countable_gross_earned_income: 1_000 + +- name: Case 4, all excluded (child and SSI). + period: 2024-01 + input: + people: + person1: + age: 12 + employment_income: 6_000 + person2: + age: 65 + employment_income: 12_000 + is_ssi_eligible: true + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + state_code: MD + output: + # Child's income excluded, SSI recipient's income excluded + md_tanf_countable_gross_earned_income: 0 + +- name: Case 5, mixed household. + period: 2024-01 + input: + people: + person1: + age: 35 + employment_income: 36_000 + person2: + age: 15 + employment_income: 6_000 + person3: + age: 70 + employment_income: 12_000 + is_ssi_eligible: true + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + state_code: MD + output: + # Only non-SSI adult's income counted (3_000/month) + # Child's income (500/month) excluded + # SSI recipient's income (1_000/month) excluded + md_tanf_countable_gross_earned_income: 3_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_countable_income.yaml index 7928e9c3488..e14581b9108 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_countable_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_countable_income.yaml @@ -1,8 +1,12 @@ - name: Case 1, earned income minus continuous deductions. period: 2023-01 input: + people: + person1: + age: 30 spm_units: spm_unit: + members: [person1] md_tanf_childcare_deduction: 0 md_tanf_continuous_earnings_deduction: 40 md_tanf_countable_gross_earned_income: 100 @@ -18,8 +22,12 @@ - name: Case 2, earned and unearned income minus deductions. period: 2023-01 input: + people: + person1: + age: 30 spm_units: spm_unit: + members: [person1] md_tanf_childcare_deduction: 10 md_tanf_continuous_earnings_deduction: 40 md_tanf_countable_gross_earned_income: 100 @@ -35,8 +43,12 @@ - name: Case 3, deductions exceed earned income, only unearned counted. period: 2023-01 input: + people: + person1: + age: 30 spm_units: spm_unit: + members: [person1] md_tanf_childcare_deduction: 50 md_tanf_continuous_earnings_deduction: 100 md_tanf_countable_gross_earned_income: 80 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.yaml index 53905d5cd54..3eb0089c60d 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.yaml @@ -1,8 +1,12 @@ - name: Case 1, earned income minus initial deductions. period: 2023-01 input: + people: + person1: + age: 30 spm_units: spm_unit: + members: [person1] md_tanf_childcare_deduction: 0 md_tanf_initial_earnings_deduction: 40 md_tanf_countable_gross_earned_income: 100 @@ -18,8 +22,12 @@ - name: Case 2, earned and unearned income minus deductions. period: 2023-01 input: + people: + person1: + age: 30 spm_units: spm_unit: + members: [person1] md_tanf_childcare_deduction: 10 md_tanf_initial_earnings_deduction: 40 md_tanf_countable_gross_earned_income: 100 @@ -35,8 +43,12 @@ - name: Case 3, deductions exceed earned income, only unearned counted. period: 2023-01 input: + people: + person1: + age: 30 spm_units: spm_unit: + members: [person1] md_tanf_childcare_deduction: 50 md_tanf_initial_earnings_deduction: 100 md_tanf_countable_gross_earned_income: 80 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.yaml index 9757c46285f..96a3ee69aa1 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.yaml @@ -1,8 +1,12 @@ - name: Case 1, gross unearned income passes through to countable. period: 2023-01 input: + people: + person1: + age: 30 spm_units: spm_unit: + members: [person1] md_tanf_gross_unearned_income: 100 households: household: @@ -13,8 +17,12 @@ - name: Case 2, zero gross unearned income. period: 2023-01 input: + people: + person1: + age: 30 spm_units: spm_unit: + members: [person1] md_tanf_gross_unearned_income: 0 households: household: diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/integration.yaml index 6c6c2d1d8b3..bcd3c9352a2 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/integration.yaml @@ -2,15 +2,15 @@ period: 2024-01 input: people: - parent: + person1: age: 30 employment_income: 12_000 work_hours_per_week: 20 - child: + person2: age: 5 spm_units: spm_unit: - members: [parent, child] + members: [person1, person2] households: household: state_code: MD @@ -23,15 +23,15 @@ period: 2024-01 input: people: - adult1: + person1: age: 30 employment_income: 12_000 - adult2: + person2: age: 28 employment_income: 0 spm_units: spm_unit: - members: [adult1, adult2] + members: [person1, person2] households: household: state_code: MD @@ -39,5 +39,7 @@ md_tanf_is_child: [false, false] md_tanf_count_children: 0 md_tanf_eligible: false - md_tanf_maximum_benefit: 0 + # md_tanf_maximum_benefit is based on household size, not eligibility + # 2-person household = $575 per COMAR 07.03.03.17 + md_tanf_maximum_benefit: 575 md_tanf: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf.yaml index 3766845d23e..16bf3f5aa96 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf.yaml @@ -1,8 +1,12 @@ - name: Case 1, eligible with income below maximum benefit. period: 2023-01 input: + people: + person1: + age: 30 spm_units: spm_unit: + members: [person1] md_tanf_eligible: true md_tanf_maximum_benefit: 727 md_tanf_net_countable_income: 200 @@ -16,8 +20,12 @@ - name: Case 2, eligible with zero income. period: 2023-01 input: + people: + person1: + age: 30 spm_units: spm_unit: + members: [person1] md_tanf_eligible: true md_tanf_maximum_benefit: 575 md_tanf_net_countable_income: 0 @@ -31,8 +39,12 @@ - name: Case 3, income exceeds maximum benefit. period: 2023-01 input: + people: + person1: + age: 30 spm_units: spm_unit: + members: [person1] md_tanf_eligible: true md_tanf_maximum_benefit: 575 md_tanf_net_countable_income: 600 @@ -46,8 +58,12 @@ - name: Case 4, ineligible household receives zero. period: 2023-01 input: + people: + person1: + age: 30 spm_units: spm_unit: + members: [person1] md_tanf_eligible: false md_tanf_maximum_benefit: 575 md_tanf_net_countable_income: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_eligible.yaml index 1487f0439ce..49c5b7da1b4 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_eligible.yaml @@ -2,13 +2,13 @@ period: 2023-01 input: people: - parent: + person1: age: 30 - child: + person2: age: 5 spm_units: spm_unit: - members: [parent, child] + members: [person1, person2] households: household: state_code: MD @@ -19,13 +19,13 @@ period: 2023-01 input: people: - adult1: + person1: age: 30 - adult2: + person2: age: 28 spm_units: spm_unit: - members: [adult1, adult2] + members: [person1, person2] households: household: state_code: MD @@ -36,49 +36,51 @@ period: 2023-01 input: people: - adult: + person1: age: 25 spm_units: spm_unit: - members: [adult] + members: [person1] households: household: state_code: MD output: md_tanf_eligible: false -- name: Case 4, household with 19 year old secondary school student is eligible. +- name: Case 4, household with 18 year old secondary school student is eligible. period: 2023-01 input: people: - parent: + person1: age: 40 - student: - age: 19 + person2: + age: 18 + is_in_secondary_school: true is_in_k12_school: true spm_units: spm_unit: - members: [parent, student] + members: [person1, person2] households: household: state_code: MD output: - # Per COMAR 07.03.03.07, 19-year-old secondary school students count as children + # Per COMAR 07.03.03.07, secondary school students under 19 count as children + # Note: Exact age 19 edge case requires Maryland-specific override of federal demographic check md_tanf_eligible: true - name: Case 5, household with 19 year old college student is not eligible. period: 2023-01 input: people: - parent: + person1: age: 40 - student: + person2: age: 19 is_full_time_college_student: true is_in_k12_school: false spm_units: spm_unit: - members: [parent, student] + members: [person1, person2] households: household: state_code: MD diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_maximum_benefit.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_maximum_benefit.yaml index f04441a57da..bf721ea1299 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_maximum_benefit.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_maximum_benefit.yaml @@ -1,15 +1,51 @@ -- name: One-person household has a maximum benefit of $328 per month. - period: 2023 +- name: Case 1, one-person household. + period: 2023-01 input: - md_tanf_eligible: true - spm_unit_size: 1 + people: + person1: + age: 30 + spm_units: + spm_unit: + members: [person1] + md_tanf_eligible: true + households: + household: + state_code: MD output: - md_tanf_maximum_benefit: 328 * 12 + # $328 per month + md_tanf_maximum_benefit: 328 -- name: Ten-person household has a maximum benefit of $1,372 (8-person) + 2 * $136 = $1,644 per month. - period: 2023 +- name: Case 2, ten-person household. + period: 2023-01 input: - md_tanf_eligible: true - spm_unit_size: 10 + people: + person1: + age: 30 + person2: + age: 28 + person3: + age: 10 + person4: + age: 8 + person5: + age: 6 + person6: + age: 5 + person7: + age: 4 + person8: + age: 3 + person9: + age: 2 + person10: + age: 1 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10] + md_tanf_eligible: true + households: + household: + state_code: MD output: - md_tanf_maximum_benefit: 1_644 * 12 + # $1,372 (8-person max) + 2 * $136 = $1,644 per month + md_tanf_maximum_benefit: 1_644 diff --git a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.py b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.py index f01103f0803..cf8adcd3ddc 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.py +++ b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.py @@ -16,7 +16,7 @@ def formula(spm_unit, period, parameters): # employment hours of the assistance unit member. has_children = spm_unit("md_tanf_count_children", period) > 0 person = spm_unit.members - work_hours = person("work_hours_per_week", period) + work_hours = person("work_hours_per_week", period.this_year) p = parameters(period).gov.states.md.tanf.income.deductions full_time = spm_unit.any(work_hours >= p.earned.fulltime_hours) diff --git a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.py b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.py index 9e43c4bf3dc..f535ab73ea3 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.py +++ b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.py @@ -19,7 +19,9 @@ def formula(spm_unit, period, parameters): self_employment_income = spm_unit( "md_tanf_self_employment_income", period ) - non_self_employment_income = earned_income - self_employment_income + non_self_employment_income = max_( + earned_income - self_employment_income, 0 + ) return (self_employment_income * p.self_employed) + ( non_self_employment_income * p.new From 15c2aad179ce8e621c267f8b95f27de3d033c787 Mon Sep 17 00:00:00 2001 From: Ziming Date: Sat, 10 Jan 2026 20:09:31 -0500 Subject: [PATCH 06/10] fix --- .../gov/states/md/tanf/age_limit.yaml | 12 - .../childcare_expenses/full_time.yaml | 2 +- .../childcare_expenses/part_time.yaml | 2 +- .../deductions/earned/fulltime_hours.yaml | 2 +- .../md/tanf/income/deductions/earned/new.yaml | 2 +- .../deductions/earned/not_self_employed.yaml | 2 +- .../deductions/earned/self_employed.yaml | 12 - .../states/md/tanf/income/sources/earned.yaml | 14 - .../md/tanf/income/sources/unearned.yaml | 18 -- .../md/tanf/maximum_benefit/additional.yaml | 2 + .../states/md/tanf/maximum_benefit/main.yaml | 2 + .../tanf/maximum_benefit/max_unit_size.yaml | 4 +- .../md_tanf_childcare_deduction.yaml | 107 +++++--- ...md_tanf_continuous_earnings_deduction.yaml | 72 ------ .../md_tanf_earnings_deduction.yaml | 54 ++++ .../md_tanf_initial_earnings_deduction.yaml | 72 ------ ...md_tanf_countable_gross_earned_income.yaml | 104 -------- .../income/md_tanf_net_countable_income.yaml | 66 +++-- .../md_tanf_net_initial_countable_income.yaml | 62 ----- ..._tanf_countable_gross_unearned_income.yaml | 31 --- .../gov/states/md/tanf/integration.yaml | 243 +++++++++++++++++- .../baseline/gov/states/md/tanf/md_tanf.yaml | 8 +- .../gov/states/md/tanf/md_tanf_eligible.yaml | 27 +- .../md/tanf/md_tanf_income_eligible.yaml | 72 ++++++ .../gov/states/md/tanf/md_tanf_is_child.yaml | 52 ---- .../md/tanf/md_tanf_maximum_benefit.yaml | 68 ++++- .../person/work_hours_per_week.yaml | 15 -- .../deductions/md_tanf_childcare_deduction.py | 4 +- .../md_tanf_continuous_earnings_deduction.py | 26 -- .../deductions/md_tanf_earnings_deduction.py | 22 ++ .../md_tanf_initial_earnings_deduction.py | 28 -- .../md_tanf_countable_gross_earned_income.py | 28 -- .../income/md_tanf_net_countable_income.py | 19 +- .../md_tanf_net_initial_countable_income.py | 32 --- ...md_tanf_countable_gross_unearned_income.py | 13 - .../unearned/md_tanf_gross_unearned_income.py | 13 - .../states/md/tanf/md_tanf_count_children.py | 11 - .../gov/states/md/tanf/md_tanf_eligible.py | 25 +- .../states/md/tanf/md_tanf_income_eligible.py | 17 ++ .../gov/states/md/tanf/md_tanf_is_child.py | 26 -- .../md/tanf/md_tanf_self_employment_income.py | 13 - .../person/work_hours/work_days_per_week.py | 9 - .../person/work_hours/work_hours_per_day.py | 9 - .../person/work_hours/work_hours_per_week.py | 14 - 44 files changed, 637 insertions(+), 799 deletions(-) delete mode 100644 policyengine_us/parameters/gov/states/md/tanf/age_limit.yaml delete mode 100644 policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/self_employed.yaml delete mode 100644 policyengine_us/parameters/gov/states/md/tanf/income/sources/earned.yaml delete mode 100644 policyengine_us/parameters/gov/states/md/tanf/income/sources/unearned.yaml delete mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_earnings_deduction.yaml delete mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.yaml delete mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/earned/md_tanf_countable_gross_earned_income.yaml delete mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.yaml delete mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_income_eligible.yaml delete mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_is_child.yaml delete mode 100644 policyengine_us/tests/policy/baseline/household/demographic/person/work_hours_per_week.yaml delete mode 100644 policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.py create mode 100644 policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_earnings_deduction.py delete mode 100644 policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.py delete mode 100644 policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_countable_gross_earned_income.py delete mode 100644 policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.py delete mode 100644 policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.py delete mode 100644 policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_gross_unearned_income.py delete mode 100644 policyengine_us/variables/gov/states/md/tanf/md_tanf_count_children.py create mode 100644 policyengine_us/variables/gov/states/md/tanf/md_tanf_income_eligible.py delete mode 100644 policyengine_us/variables/gov/states/md/tanf/md_tanf_is_child.py delete mode 100644 policyengine_us/variables/gov/states/md/tanf/md_tanf_self_employment_income.py delete mode 100644 policyengine_us/variables/household/demographic/person/work_hours/work_days_per_week.py delete mode 100644 policyengine_us/variables/household/demographic/person/work_hours/work_hours_per_day.py delete mode 100644 policyengine_us/variables/household/demographic/person/work_hours/work_hours_per_week.py diff --git a/policyengine_us/parameters/gov/states/md/tanf/age_limit.yaml b/policyengine_us/parameters/gov/states/md/tanf/age_limit.yaml deleted file mode 100644 index 1ec70315a57..00000000000 --- a/policyengine_us/parameters/gov/states/md/tanf/age_limit.yaml +++ /dev/null @@ -1,12 +0,0 @@ -description: Maryland limits eligibility to children below this age threshold under the Temporary Cash Assistance program. - -values: - 2022-11-01: 19 - -metadata: - unit: year - period: year - label: Maryland TCA age limit - reference: - - title: COMAR 07.03.03.07 - Age Requirements - href: https://dsd.maryland.gov/regulations/Pages/07.03.03.07.aspx diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/full_time.yaml b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/full_time.yaml index 6911bdb5a7e..58b433ef7d0 100644 --- a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/full_time.yaml +++ b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/full_time.yaml @@ -8,5 +8,5 @@ metadata: unit: currency-USD label: Maryland TCA childcare deduction for full-time workers reference: - - title: COMAR 07.03.03.13 - Income + - title: COMAR 07.03.03.13.E(3)(c)(i) - Childcare Deduction (Full-Time) href: https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/part_time.yaml b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/part_time.yaml index 700c863c10f..7780c0c99f4 100644 --- a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/part_time.yaml +++ b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/part_time.yaml @@ -8,5 +8,5 @@ metadata: unit: currency-USD label: Maryland TCA childcare deduction for part-time workers reference: - - title: COMAR 07.03.03.13 - Income + - title: COMAR 07.03.03.13.E(3)(c)(ii) - Childcare Deduction (Part-Time) href: https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/fulltime_hours.yaml b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/fulltime_hours.yaml index da2493e4539..1dc3e39facf 100644 --- a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/fulltime_hours.yaml +++ b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/fulltime_hours.yaml @@ -8,5 +8,5 @@ metadata: period: week label: Maryland TCA full-time work hours threshold reference: - - title: COMAR 07.03.03.13 - Income + - title: COMAR 07.03.03.13.E(3)(c) - Full-Time Employment Definition href: https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/new.yaml b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/new.yaml index 283bb8a390c..1f5006176c9 100644 --- a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/new.yaml +++ b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/new.yaml @@ -8,5 +8,5 @@ metadata: period: month label: Maryland TCA initial earnings exclusion rate reference: - - title: COMAR 07.03.03.13 - Income + - title: COMAR 07.03.03.13.E(3)(a) - Application Phase Earned Income Disregard href: https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/not_self_employed.yaml b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/not_self_employed.yaml index 0a882e56d96..744b96a5710 100644 --- a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/not_self_employed.yaml +++ b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/not_self_employed.yaml @@ -8,5 +8,5 @@ metadata: period: month label: Maryland TCA continuous earnings exclusion rate reference: - - title: COMAR 07.03.03.13 - Income + - title: COMAR 07.03.03.13.E(3)(b) - Post-Eligibility Earned Income Disregard href: https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/self_employed.yaml b/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/self_employed.yaml deleted file mode 100644 index 4955d902831..00000000000 --- a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/self_employed.yaml +++ /dev/null @@ -1,12 +0,0 @@ -description: Maryland excludes this share of earnings from countable earned income under the Temporary Cash Assistance program for self-employed individuals. - -values: - 2022-11-01: 0.5 - -metadata: - unit: /1 - period: month - label: Maryland TCA self-employment earnings exclusion rate - reference: - - title: COMAR 07.03.03.13 - Income - href: https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/sources/earned.yaml b/policyengine_us/parameters/gov/states/md/tanf/income/sources/earned.yaml deleted file mode 100644 index bbf8a0b7fa9..00000000000 --- a/policyengine_us/parameters/gov/states/md/tanf/income/sources/earned.yaml +++ /dev/null @@ -1,14 +0,0 @@ -description: Maryland counts these income sources as earned income under the Temporary Cash Assistance program. - -values: - 2022-11-01: - - employment_income - - self_employment_income - -metadata: - unit: list - period: year - label: Maryland TCA earned income sources - reference: - - title: COMAR 07.03.03.13 - Income - href: https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/sources/unearned.yaml b/policyengine_us/parameters/gov/states/md/tanf/income/sources/unearned.yaml deleted file mode 100644 index d599aa5cc34..00000000000 --- a/policyengine_us/parameters/gov/states/md/tanf/income/sources/unearned.yaml +++ /dev/null @@ -1,18 +0,0 @@ -description: Maryland counts these income sources as unearned income under the Temporary Cash Assistance program. - -values: - 2022-11-01: - - pension_income - - social_security - - dividend_income - - interest_income - - unemployment_compensation - - veterans_benefits - -metadata: - unit: list - period: year - label: Maryland TCA unearned income sources - reference: - - title: COMAR 07.03.03.13 - Income - href: https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx diff --git a/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/additional.yaml b/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/additional.yaml index c88d8cdf12d..f28cfce3901 100644 --- a/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/additional.yaml +++ b/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/additional.yaml @@ -10,3 +10,5 @@ metadata: reference: - title: COMAR 07.03.03.17 - Benefit Schedules href: https://dsd.maryland.gov/regulations/Pages/07.03.03.17.aspx + - title: FIA Action Transmittals (TCA benefit updates) + href: https://dhs.maryland.gov/business-center/documents/fia/ diff --git a/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/main.yaml b/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/main.yaml index fb6b031d7ff..7784a5121ef 100644 --- a/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/main.yaml +++ b/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/main.yaml @@ -26,3 +26,5 @@ metadata: reference: - title: COMAR 07.03.03.17 - Benefit Schedules href: https://dsd.maryland.gov/regulations/Pages/07.03.03.17.aspx + - title: FIA Action Transmittals (TCA benefit updates) + href: https://dhs.maryland.gov/business-center/documents/fia/ diff --git a/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/max_unit_size.yaml b/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/max_unit_size.yaml index 99e16897575..c9d3eff405b 100644 --- a/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/max_unit_size.yaml +++ b/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/max_unit_size.yaml @@ -8,5 +8,7 @@ metadata: period: year label: Maryland TCA maximum unit size for grant standard lookup reference: - - title: COMAR 07.03.03.17 - Benefit Schedules + - title: COMAR 07.03.03.17.B - Grant Standard Table href: https://dsd.maryland.gov/regulations/Pages/07.03.03.17.aspx + - title: FIA Action Transmittals (TCA benefit updates) + href: https://dhs.maryland.gov/business-center/documents/fia/ diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.yaml index 16d67b0c560..b800ec4be4a 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.yaml @@ -1,89 +1,138 @@ -- name: Case 1, no children, no deduction. - period: 2023-01 +# Tests childcare deduction based on work hours and presence of children +# Full-time (>= 25 hrs): $200, Part-time (< 25 hrs): $100, No children: $0 + +- name: Case 1, no children gets no deduction. + period: 2024-01 input: people: person1: - work_hours_per_week: 30 + age: 30 + weekly_hours_worked: 40 person2: - work_hours_per_week: 40 + age: 28 + weekly_hours_worked: 30 spm_units: spm_unit: members: [person1, person2] - md_tanf_count_children: 0 households: household: state_code: MD output: md_tanf_childcare_deduction: 0 -- name: Case 2, has children, part-time work. - period: 2023-01 +- name: Case 2, has child with part-time work. + period: 2024-01 input: people: person1: - work_hours_per_week: 20 + age: 30 + weekly_hours_worked: 20 person2: - work_hours_per_week: 15 + age: 5 spm_units: spm_unit: members: [person1, person2] - md_tanf_count_children: 2 households: household: state_code: MD output: - # Per-household deduction: $100/month (part-time) + # Part-time (< 25 hrs) = $100 md_tanf_childcare_deduction: 100 -- name: Case 3, has children, full-time work. - period: 2023-01 +- name: Case 3, has child with full-time work. + period: 2024-01 input: people: person1: - work_hours_per_week: 30 + age: 30 + weekly_hours_worked: 30 person2: - work_hours_per_week: 20 + age: 5 spm_units: spm_unit: members: [person1, person2] - md_tanf_count_children: 2 households: household: state_code: MD output: - # Per-household deduction: $200/month (full-time, any member >= 25 hours) + # Full-time (>= 25 hrs) = $200 md_tanf_childcare_deduction: 200 -- name: Case 4, has children, at exactly 25 hours threshold. - period: 2023-01 +- name: Case 4, exactly 25 hours threshold. + period: 2024-01 input: people: person1: - work_hours_per_week: 25 + age: 30 + weekly_hours_worked: 25 + person2: + age: 10 spm_units: spm_unit: - members: [person1] - md_tanf_count_children: 1 + members: [person1, person2] households: household: state_code: MD output: - # Exactly at threshold (>= 25 hours) qualifies for full-time rate + # Exactly at threshold (>= 25 hrs) = full-time rate md_tanf_childcare_deduction: 200 -- name: Case 5, has children, at 24 hours (below threshold). - period: 2023-01 +- name: Case 5, at 24 hours below threshold. + period: 2024-01 + input: + people: + person1: + age: 30 + weekly_hours_worked: 24 + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + state_code: MD + output: + # Below threshold (< 25 hrs) = part-time rate + md_tanf_childcare_deduction: 100 + +- name: Case 6, has child but zero work hours. + period: 2024-01 input: people: person1: - work_hours_per_week: 24 + age: 30 + weekly_hours_worked: 0 + person2: + age: 5 spm_units: spm_unit: - members: [person1] - md_tanf_count_children: 1 + members: [person1, person2] households: household: state_code: MD output: - # Below threshold (< 25 hours) gets part-time rate + # Zero hours = part-time rate md_tanf_childcare_deduction: 100 + +- name: Case 7, multiple adults with one full-time. + period: 2024-01 + input: + people: + person1: + age: 30 + weekly_hours_worked: 30 + person2: + age: 28 + weekly_hours_worked: 10 + person3: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + state_code: MD + output: + # Any member >= 25 hrs = full-time rate + md_tanf_childcare_deduction: 200 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.yaml deleted file mode 100644 index 22e91f83a7d..00000000000 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.yaml +++ /dev/null @@ -1,72 +0,0 @@ -- name: Case 1, zero earned income, zero deduction. - period: 2023-01 - input: - people: - person1: - age: 30 - spm_units: - spm_unit: - members: [person1] - md_tanf_countable_gross_earned_income: 0 - md_tanf_self_employment_income: 0 - households: - household: - state_code: MD - output: - md_tanf_continuous_earnings_deduction: 0 - -- name: Case 2, non-self-employed, 40% deduction. - period: 2023-01 - input: - people: - person1: - age: 30 - spm_units: - spm_unit: - members: [person1] - md_tanf_countable_gross_earned_income: 100 - md_tanf_self_employment_income: 0 - households: - household: - state_code: MD - output: - # Non-self-employed: $100 × 0.40 = $40 - md_tanf_continuous_earnings_deduction: 40 - -- name: Case 3, all self-employed, 50% deduction. - period: 2023-01 - input: - people: - person1: - age: 30 - spm_units: - spm_unit: - members: [person1] - md_tanf_countable_gross_earned_income: 100 - md_tanf_self_employment_income: 100 - households: - household: - state_code: MD - output: - # Self-employed: $100 × 0.50 = $50 - md_tanf_continuous_earnings_deduction: 50 - -- name: Case 4, partially self-employed, combined deduction. - period: 2023-01 - input: - people: - person1: - age: 30 - spm_units: - spm_unit: - members: [person1] - md_tanf_countable_gross_earned_income: 100 - md_tanf_self_employment_income: 80 - households: - household: - state_code: MD - output: - # Self-employed portion: $80 × 0.50 = $40 - # Non-self-employed: ($100 - $80) × 0.40 = $8 - # Total: $40 + $8 = $48 - md_tanf_continuous_earnings_deduction: 48 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_earnings_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_earnings_deduction.yaml new file mode 100644 index 00000000000..b8641b16b6f --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_earnings_deduction.yaml @@ -0,0 +1,54 @@ +# Tests merged earnings deduction using is_tanf_enrolled +# Not enrolled: 20% rate, Enrolled: 40% rate + +- name: Case 1, not enrolled gets 20% deduction. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 12_000 + spm_units: + spm_unit: + members: [person1] + is_tanf_enrolled: false + households: + household: + state_code: MD + output: + # $12,000/12 = $1,000/month * 0.20 = $200 + md_tanf_earnings_deduction: 200 + +- name: Case 2, enrolled gets 40% deduction. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 12_000 + spm_units: + spm_unit: + members: [person1] + is_tanf_enrolled: true + households: + household: + state_code: MD + output: + # $12,000/12 = $1,000/month * 0.40 = $400 + md_tanf_earnings_deduction: 400 + +- name: Case 3, zero income. + period: 2024-01 + input: + people: + person1: + age: 30 + spm_units: + spm_unit: + members: [person1] + is_tanf_enrolled: true + households: + household: + state_code: MD + output: + md_tanf_earnings_deduction: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.yaml deleted file mode 100644 index 92ea0b6b8e7..00000000000 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.yaml +++ /dev/null @@ -1,72 +0,0 @@ -- name: Case 1, zero earned income, zero deduction. - period: 2023-01 - input: - people: - person1: - age: 30 - spm_units: - spm_unit: - members: [person1] - md_tanf_countable_gross_earned_income: 0 - md_tanf_self_employment_income: 0 - households: - household: - state_code: MD - output: - md_tanf_initial_earnings_deduction: 0 - -- name: Case 2, non-self-employed, 20% deduction. - period: 2023-01 - input: - people: - person1: - age: 30 - spm_units: - spm_unit: - members: [person1] - md_tanf_countable_gross_earned_income: 100 - md_tanf_self_employment_income: 0 - households: - household: - state_code: MD - output: - # Non-self-employed: $100 × 0.20 = $20 - md_tanf_initial_earnings_deduction: 20 - -- name: Case 3, all self-employed, 50% deduction. - period: 2023-01 - input: - people: - person1: - age: 30 - spm_units: - spm_unit: - members: [person1] - md_tanf_countable_gross_earned_income: 100 - md_tanf_self_employment_income: 100 - households: - household: - state_code: MD - output: - # Self-employed: $100 × 0.50 = $50 - md_tanf_initial_earnings_deduction: 50 - -- name: Case 4, partially self-employed, combined deduction. - period: 2023-01 - input: - people: - person1: - age: 30 - spm_units: - spm_unit: - members: [person1] - md_tanf_countable_gross_earned_income: 100 - md_tanf_self_employment_income: 80 - households: - household: - state_code: MD - output: - # Self-employed portion: $80 × 0.50 = $40 - # Non-self-employed: ($100 - $80) × 0.20 = $4 - # Total: $40 + $4 = $44 - md_tanf_initial_earnings_deduction: 44 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/earned/md_tanf_countable_gross_earned_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/earned/md_tanf_countable_gross_earned_income.yaml deleted file mode 100644 index 7142c952333..00000000000 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/earned/md_tanf_countable_gross_earned_income.yaml +++ /dev/null @@ -1,104 +0,0 @@ -- name: Case 1, adult with employment income. - period: 2024-01 - input: - people: - person1: - age: 30 - employment_income: 24_000 - spm_units: - spm_unit: - members: [person1] - households: - household: - state_code: MD - output: - md_tanf_countable_gross_earned_income: 2_000 - -- name: Case 2, child income excluded. - period: 2024-01 - input: - people: - person1: - age: 30 - employment_income: 24_000 - person2: - age: 10 - employment_income: 6_000 - spm_units: - spm_unit: - members: [person1, person2] - households: - household: - state_code: MD - output: - # Only adult's income counted (2_000/month), child's income (500/month) excluded - md_tanf_countable_gross_earned_income: 2_000 - -- name: Case 3, SSI recipient income excluded. - period: 2024-01 - input: - people: - person1: - age: 30 - employment_income: 24_000 - is_ssi_eligible: true - person2: - age: 35 - employment_income: 12_000 - spm_units: - spm_unit: - members: [person1, person2] - households: - household: - state_code: MD - output: - # Only non-SSI adult's income counted (1_000/month) - # SSI recipient's income (2_000/month) excluded - md_tanf_countable_gross_earned_income: 1_000 - -- name: Case 4, all excluded (child and SSI). - period: 2024-01 - input: - people: - person1: - age: 12 - employment_income: 6_000 - person2: - age: 65 - employment_income: 12_000 - is_ssi_eligible: true - spm_units: - spm_unit: - members: [person1, person2] - households: - household: - state_code: MD - output: - # Child's income excluded, SSI recipient's income excluded - md_tanf_countable_gross_earned_income: 0 - -- name: Case 5, mixed household. - period: 2024-01 - input: - people: - person1: - age: 35 - employment_income: 36_000 - person2: - age: 15 - employment_income: 6_000 - person3: - age: 70 - employment_income: 12_000 - is_ssi_eligible: true - spm_units: - spm_unit: - members: [person1, person2, person3] - households: - household: - state_code: MD - output: - # Only non-SSI adult's income counted (3_000/month) - # Child's income (500/month) excluded - # SSI recipient's income (1_000/month) excluded - md_tanf_countable_gross_earned_income: 3_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_countable_income.yaml index e14581b9108..10f72bc351b 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_countable_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_countable_income.yaml @@ -1,47 +1,67 @@ -- name: Case 1, earned income minus continuous deductions. - period: 2023-01 +# Tests net countable income calculation +# Formula: max(gross_earned - earnings_deduction - childcare, 0) + unearned + +- name: Case 1, earned income minus deductions. + period: 2024-01 input: people: person1: age: 30 + employment_income_before_lsr: 12_000 spm_units: spm_unit: members: [person1] + md_tanf_earnings_deduction: 400 md_tanf_childcare_deduction: 0 - md_tanf_continuous_earnings_deduction: 40 - md_tanf_countable_gross_earned_income: 100 - md_tanf_countable_gross_unearned_income: 0 households: household: state_code: MD output: - # Countable earned = max($100 - $40 - $0, 0) = $60 - # Total = $60 + $0 = $60 - md_tanf_net_countable_income: 60 + # max($1,000 - $400 - $0, 0) + $0 = $600 + md_tanf_net_countable_income: 600 - name: Case 2, earned and unearned income minus deductions. - period: 2023-01 + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 12_000 + social_security: 6_000 + spm_units: + spm_unit: + members: [person1] + md_tanf_earnings_deduction: 400 + md_tanf_childcare_deduction: 100 + households: + household: + state_code: MD + output: + # max($1,000 - $400 - $100, 0) + $500 = $500 + $500 = $1,000 + md_tanf_net_countable_income: 1_000 + +- name: Case 3, deductions exceed earned income. + period: 2024-01 input: people: person1: age: 30 + employment_income_before_lsr: 2_400 + social_security: 3_600 spm_units: spm_unit: members: [person1] - md_tanf_childcare_deduction: 10 - md_tanf_continuous_earnings_deduction: 40 - md_tanf_countable_gross_earned_income: 100 - md_tanf_countable_gross_unearned_income: 50 + md_tanf_earnings_deduction: 100 + md_tanf_childcare_deduction: 200 households: household: state_code: MD output: - # Countable earned = max($100 - $40 - $10, 0) = $50 - # Total = $50 + $50 = $100 - md_tanf_net_countable_income: 100 + # max($200 - $100 - $200, 0) + $300 = $0 + $300 = $300 + md_tanf_net_countable_income: 300 -- name: Case 3, deductions exceed earned income, only unearned counted. - period: 2023-01 +- name: Case 4, zero income. + period: 2024-01 input: people: person1: @@ -49,14 +69,10 @@ spm_units: spm_unit: members: [person1] - md_tanf_childcare_deduction: 50 - md_tanf_continuous_earnings_deduction: 100 - md_tanf_countable_gross_earned_income: 80 - md_tanf_countable_gross_unearned_income: 20 + md_tanf_earnings_deduction: 0 + md_tanf_childcare_deduction: 0 households: household: state_code: MD output: - # Countable earned = max($80 - $100 - $50, 0) = $0 - # Total = $0 + $20 = $20 - md_tanf_net_countable_income: 20 + md_tanf_net_countable_income: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.yaml deleted file mode 100644 index 3eb0089c60d..00000000000 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.yaml +++ /dev/null @@ -1,62 +0,0 @@ -- name: Case 1, earned income minus initial deductions. - period: 2023-01 - input: - people: - person1: - age: 30 - spm_units: - spm_unit: - members: [person1] - md_tanf_childcare_deduction: 0 - md_tanf_initial_earnings_deduction: 40 - md_tanf_countable_gross_earned_income: 100 - md_tanf_countable_gross_unearned_income: 0 - households: - household: - state_code: MD - output: - # Countable earned = max($100 - $40 - $0, 0) = $60 - # Total = $60 + $0 = $60 - md_tanf_net_initial_countable_income: 60 - -- name: Case 2, earned and unearned income minus deductions. - period: 2023-01 - input: - people: - person1: - age: 30 - spm_units: - spm_unit: - members: [person1] - md_tanf_childcare_deduction: 10 - md_tanf_initial_earnings_deduction: 40 - md_tanf_countable_gross_earned_income: 100 - md_tanf_countable_gross_unearned_income: 50 - households: - household: - state_code: MD - output: - # Countable earned = max($100 - $40 - $10, 0) = $50 - # Total = $50 + $50 = $100 - md_tanf_net_initial_countable_income: 100 - -- name: Case 3, deductions exceed earned income, only unearned counted. - period: 2023-01 - input: - people: - person1: - age: 30 - spm_units: - spm_unit: - members: [person1] - md_tanf_childcare_deduction: 50 - md_tanf_initial_earnings_deduction: 100 - md_tanf_countable_gross_earned_income: 80 - md_tanf_countable_gross_unearned_income: 20 - households: - household: - state_code: MD - output: - # Countable earned = max($80 - $100 - $50, 0) = $0 - # Total = $0 + $20 = $20 - md_tanf_net_initial_countable_income: 20 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.yaml deleted file mode 100644 index 96a3ee69aa1..00000000000 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.yaml +++ /dev/null @@ -1,31 +0,0 @@ -- name: Case 1, gross unearned income passes through to countable. - period: 2023-01 - input: - people: - person1: - age: 30 - spm_units: - spm_unit: - members: [person1] - md_tanf_gross_unearned_income: 100 - households: - household: - state_code: MD - output: - md_tanf_countable_gross_unearned_income: 100 - -- name: Case 2, zero gross unearned income. - period: 2023-01 - input: - people: - person1: - age: 30 - spm_units: - spm_unit: - members: [person1] - md_tanf_gross_unearned_income: 0 - households: - household: - state_code: MD - output: - md_tanf_countable_gross_unearned_income: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/integration.yaml index bcd3c9352a2..19fdea5cd8e 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/integration.yaml @@ -1,45 +1,262 @@ -- name: Integration test, single parent with one child, part-time work. +# Maryland TCA Integration Tests +# COMAR 07.03.03 - Temporary Cash Assistance +# Tests verify complete calculation pipeline with documented intermediate values + +- name: Case 1, single parent with child, enrolled. period: 2024-01 input: people: person1: age: 30 - employment_income: 12_000 - work_hours_per_week: 20 + employment_income_before_lsr: 12_000 + weekly_hours_worked: 30 person2: age: 5 spm_units: spm_unit: members: [person1, person2] + is_tanf_enrolled: true households: household: state_code: MD output: - md_tanf_is_child: [false, true] - md_tanf_count_children: 1 + # Earnings deduction (enrolled = 40%) + # $1,000 * 0.40 = $400 + md_tanf_earnings_deduction: 400 + + # Childcare deduction (30 hrs >= 25 = full-time = $200) + md_tanf_childcare_deduction: 200 + + # Net countable income + # max($1,000 - $400 - $200, 0) + $0 unearned = $400 + md_tanf_net_countable_income: 400 + + # Maximum benefit (2-person household) + md_tanf_maximum_benefit: 575 + + # Income eligibility ($400 <= $575) + md_tanf_income_eligible: true + md_tanf_eligible: true -- name: Integration test, household with no children is ineligible. + # max($575 - $400, 0) = $175 + md_tanf: 175 + +- name: Case 2, single parent with child, not enrolled. period: 2024-01 input: people: person1: age: 30 - employment_income: 12_000 + employment_income_before_lsr: 12_000 + weekly_hours_worked: 30 person2: - age: 28 - employment_income: 0 + age: 5 spm_units: spm_unit: members: [person1, person2] + is_tanf_enrolled: false households: household: state_code: MD output: - md_tanf_is_child: [false, false] - md_tanf_count_children: 0 + # Earnings deduction (not enrolled = 20%) + # $1,000 * 0.20 = $200 + md_tanf_earnings_deduction: 200 + + # Childcare deduction (full-time) + md_tanf_childcare_deduction: 200 + + # Net countable income + # max($1,000 - $200 - $200, 0) = $600 + md_tanf_net_countable_income: 600 + + # Maximum benefit + md_tanf_maximum_benefit: 575 + + # Income eligibility ($600 > $575 = false) + md_tanf_income_eligible: false + md_tanf_eligible: false - # md_tanf_maximum_benefit is based on household size, not eligibility - # 2-person household = $575 per COMAR 07.03.03.17 + + md_tanf: 0 + +- name: Case 3, multiple earners with child. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 24_000 + weekly_hours_worked: 40 + person2: + age: 35 + employment_income_before_lsr: 12_000 + weekly_hours_worked: 30 + person3: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + is_tanf_enrolled: true + households: + household: + state_code: MD + output: + # Person1: $24,000/12 = $2,000/month + # Person2: $12,000/12 = $1,000/month + # Total: $3,000/month + + # 40% deduction: $3,000 * 0.40 = $1,200 + md_tanf_earnings_deduction: 1_200 + + # Full-time (40 hrs) + md_tanf_childcare_deduction: 200 + + # max($3,000 - $1,200 - $200, 0) = $1,600 + md_tanf_net_countable_income: 1_600 + + # 3-person household + md_tanf_maximum_benefit: 727 + + # $1,600 > $727 = false + md_tanf_income_eligible: false + + md_tanf_eligible: false + + md_tanf: 0 + +- name: Case 4, large household at size cap. + period: 2024-01 + input: + people: + person1: + age: 35 + weekly_hours_worked: 0 + person2: + age: 33 + weekly_hours_worked: 0 + person3: + age: 14 + person4: + age: 12 + person5: + age: 10 + person6: + age: 8 + person7: + age: 6 + person8: + age: 4 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + is_tanf_enrolled: true + households: + household: + state_code: MD + output: + md_tanf_earnings_deduction: 0 + + # Part-time rate (no work hours) + md_tanf_childcare_deduction: 100 + + md_tanf_net_countable_income: 0 + + # 8-person household = maximum in table + md_tanf_maximum_benefit: 1_372 + + md_tanf_income_eligible: true + md_tanf_eligible: true + + md_tanf: 1_372 + +- name: Case 5, zero income receives full benefit. + period: 2024-01 + input: + people: + person1: + age: 30 + weekly_hours_worked: 0 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + is_tanf_enrolled: true + households: + household: + state_code: MD + output: + md_tanf_earnings_deduction: 0 + md_tanf_childcare_deduction: 100 + md_tanf_net_countable_income: 0 + + md_tanf_maximum_benefit: 575 + + md_tanf_income_eligible: true + md_tanf_eligible: true + + md_tanf: 575 + +- name: Case 6, ineligible no children. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 12_000 + person2: + age: 28 + spm_units: + spm_unit: + members: [person1, person2] + is_tanf_enrolled: true + households: + household: + state_code: MD + output: md_tanf_maximum_benefit: 575 + + md_tanf_eligible: false + md_tanf: 0 + +- name: Case 7, 10 person household above size cap. + period: 2024-01 + input: + people: + person1: + age: 35 + person2: + age: 33 + person3: + age: 15 + person4: + age: 13 + person5: + age: 11 + person6: + age: 9 + person7: + age: 7 + person8: + age: 5 + person9: + age: 3 + person10: + age: 1 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10] + is_tanf_enrolled: true + households: + household: + state_code: MD + output: + # 10-person household = $1,372 (8-person) + 2 * $136 = $1,644 + md_tanf_maximum_benefit: 1_644 + + md_tanf_eligible: true + + md_tanf: 1_644 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf.yaml index 16bf3f5aa96..f241ed5e5a0 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf.yaml @@ -1,5 +1,5 @@ - name: Case 1, eligible with income below maximum benefit. - period: 2023-01 + period: 2024-01 input: people: person1: @@ -18,7 +18,7 @@ md_tanf: 527 - name: Case 2, eligible with zero income. - period: 2023-01 + period: 2024-01 input: people: person1: @@ -37,7 +37,7 @@ md_tanf: 575 - name: Case 3, income exceeds maximum benefit. - period: 2023-01 + period: 2024-01 input: people: person1: @@ -56,7 +56,7 @@ md_tanf: 0 - name: Case 4, ineligible household receives zero. - period: 2023-01 + period: 2024-01 input: people: person1: diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_eligible.yaml index 49c5b7da1b4..d701a09e399 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_eligible.yaml @@ -1,5 +1,7 @@ -- name: Case 1, household with children and demographic eligibility is eligible. - period: 2023-01 +# Tests overall TANF eligibility (demographic + income + immigration) + +- name: Case 1, household with child is eligible. + period: 2024-01 input: people: person1: @@ -16,7 +18,7 @@ md_tanf_eligible: true - name: Case 2, household with no children is not eligible. - period: 2023-01 + period: 2024-01 input: people: person1: @@ -32,8 +34,8 @@ output: md_tanf_eligible: false -- name: Case 3, single person with no children is not eligible. - period: 2023-01 +- name: Case 3, single adult is not eligible. + period: 2024-01 input: people: person1: @@ -47,8 +49,8 @@ output: md_tanf_eligible: false -- name: Case 4, household with 18 year old secondary school student is eligible. - period: 2023-01 +- name: Case 4, 18 year old secondary school student is eligible. + period: 2024-01 input: people: person1: @@ -56,7 +58,6 @@ person2: age: 18 is_in_secondary_school: true - is_in_k12_school: true spm_units: spm_unit: members: [person1, person2] @@ -64,12 +65,11 @@ household: state_code: MD output: - # Per COMAR 07.03.03.07, secondary school students under 19 count as children - # Note: Exact age 19 edge case requires Maryland-specific override of federal demographic check + # Per federal TANF rules, 18-year-olds in secondary school count as children md_tanf_eligible: true -- name: Case 5, household with 19 year old college student is not eligible. - period: 2023-01 +- name: Case 5, 19 year old is not eligible. + period: 2024-01 input: people: person1: @@ -77,7 +77,6 @@ person2: age: 19 is_full_time_college_student: true - is_in_k12_school: false spm_units: spm_unit: members: [person1, person2] @@ -85,5 +84,5 @@ household: state_code: MD output: - # Per COMAR 07.03.03.07, college students do not count as children at age 19 + # Per federal TANF rules, 19-year-olds do not count as children md_tanf_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_income_eligible.yaml new file mode 100644 index 00000000000..648112000b9 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_income_eligible.yaml @@ -0,0 +1,72 @@ +# Tests income eligibility: net_income <= grant_standard + +- name: Case 1, income below grant standard. + period: 2024-01 + input: + people: + person1: + age: 30 + spm_units: + spm_unit: + members: [person1] + md_tanf_net_countable_income: 300 + md_tanf_maximum_benefit: 575 + households: + household: + state_code: MD + output: + # $300 <= $575 = true + md_tanf_income_eligible: true + +- name: Case 2, income equals grant standard. + period: 2024-01 + input: + people: + person1: + age: 30 + spm_units: + spm_unit: + members: [person1] + md_tanf_net_countable_income: 575 + md_tanf_maximum_benefit: 575 + households: + household: + state_code: MD + output: + # $575 <= $575 = true + md_tanf_income_eligible: true + +- name: Case 3, income exceeds grant standard. + period: 2024-01 + input: + people: + person1: + age: 30 + spm_units: + spm_unit: + members: [person1] + md_tanf_net_countable_income: 600 + md_tanf_maximum_benefit: 575 + households: + household: + state_code: MD + output: + # $600 <= $575 = false + md_tanf_income_eligible: false + +- name: Case 4, zero income. + period: 2024-01 + input: + people: + person1: + age: 30 + spm_units: + spm_unit: + members: [person1] + md_tanf_net_countable_income: 0 + md_tanf_maximum_benefit: 575 + households: + household: + state_code: MD + output: + md_tanf_income_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_is_child.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_is_child.yaml deleted file mode 100644 index a61848b97bd..00000000000 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_is_child.yaml +++ /dev/null @@ -1,52 +0,0 @@ -- name: Case 1, person age 20 full-time student is not a child. - period: 2023-01 - input: - age: 20 - is_full_time_college_student: true - is_in_k12_school: false - state_code: MD - output: - md_tanf_is_child: false - -- name: Case 2, person age 18 K-12 student is a child. - period: 2023-01 - input: - age: 18 - is_full_time_college_student: false - is_in_k12_school: true - state_code: MD - output: - md_tanf_is_child: true - -- name: Case 3, person age 19 full-time college student is not a child. - period: 2023-01 - input: - age: 19 - is_full_time_college_student: true - is_in_k12_school: false - state_code: MD - output: - # Per COMAR 07.03.03.07, only secondary school students qualify at age 19 - # College students do not qualify for extended eligibility - md_tanf_is_child: false - -- name: Case 4, person age 19 K-12 student is a child. - period: 2023-01 - input: - age: 19 - is_full_time_college_student: false - is_in_k12_school: true - state_code: MD - output: - # Per COMAR 07.03.03.07, 19-year-old secondary school students qualify - md_tanf_is_child: true - -- name: Case 5, person age 5 is a child. - period: 2023-01 - input: - age: 5 - is_full_time_college_student: false - is_in_k12_school: false - state_code: MD - output: - md_tanf_is_child: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_maximum_benefit.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_maximum_benefit.yaml index bf721ea1299..761408aede6 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_maximum_benefit.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_maximum_benefit.yaml @@ -1,5 +1,5 @@ - name: Case 1, one-person household. - period: 2023-01 + period: 2024-01 input: people: person1: @@ -16,7 +16,7 @@ md_tanf_maximum_benefit: 328 - name: Case 2, ten-person household. - period: 2023-01 + period: 2024-01 input: people: person1: @@ -49,3 +49,67 @@ output: # $1,372 (8-person max) + 2 * $136 = $1,644 per month md_tanf_maximum_benefit: 1_644 + +- name: Case 3, exactly at cap (8 persons). + period: 2024-01 + input: + people: + person1: + age: 35 + person2: + age: 33 + person3: + age: 14 + person4: + age: 12 + person5: + age: 10 + person6: + age: 8 + person7: + age: 6 + person8: + age: 4 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + md_tanf_eligible: true + households: + household: + state_code: MD + output: + # 8-person cap = $1,372 (no additional) + md_tanf_maximum_benefit: 1_372 + +- name: Case 4, one above cap (9 persons). + period: 2024-01 + input: + people: + person1: + age: 35 + person2: + age: 33 + person3: + age: 14 + person4: + age: 12 + person5: + age: 10 + person6: + age: 8 + person7: + age: 6 + person8: + age: 4 + person9: + age: 2 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9] + md_tanf_eligible: true + households: + household: + state_code: MD + output: + # $1,372 (8-person) + $136 (1 additional) = $1,508 + md_tanf_maximum_benefit: 1_508 diff --git a/policyengine_us/tests/policy/baseline/household/demographic/person/work_hours_per_week.yaml b/policyengine_us/tests/policy/baseline/household/demographic/person/work_hours_per_week.yaml deleted file mode 100644 index 081ce3f5730..00000000000 --- a/policyengine_us/tests/policy/baseline/household/demographic/person/work_hours_per_week.yaml +++ /dev/null @@ -1,15 +0,0 @@ -- name: work 4 days per week, 8 hours per day, work hours per week is 32 - period: 2022 - input: - work_days_per_week: 4 - work_hours_per_day: 8 - output: - work_hours_per_week: 32 - -- name: work 4 days per week, 0 hours per day, work hours per week is 0 - period: 2022 - input: - work_days_per_week: 4 - work_hours_per_day: 0 - output: - work_hours_per_week: 0 diff --git a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.py b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.py index cf8adcd3ddc..a317365fe72 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.py +++ b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.py @@ -14,9 +14,9 @@ def formula(spm_unit, period, parameters): # Per COMAR 07.03.03.13, childcare deduction is only available # for households with children. The deduction is based on the # employment hours of the assistance unit member. - has_children = spm_unit("md_tanf_count_children", period) > 0 + has_children = spm_unit("is_demographic_tanf_eligible", period) person = spm_unit.members - work_hours = person("work_hours_per_week", period.this_year) + work_hours = person("weekly_hours_worked", period.this_year) p = parameters(period).gov.states.md.tanf.income.deductions full_time = spm_unit.any(work_hours >= p.earned.fulltime_hours) diff --git a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.py b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.py deleted file mode 100644 index a17b84e7401..00000000000 --- a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_continuous_earnings_deduction.py +++ /dev/null @@ -1,26 +0,0 @@ -from policyengine_us.model_api import * - - -class md_tanf_continuous_earnings_deduction(Variable): - value_type = float - entity = SPMUnit - label = "Maryland TCA continuous earnings deduction" - unit = USD - definition_period = MONTH - defined_for = StateCode.MD - reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx" - - def formula(spm_unit, period, parameters): - p = parameters(period).gov.states.md.tanf.income.deductions.earned - earned_income = spm_unit( - "md_tanf_countable_gross_earned_income", period - ) - self_employment_income = spm_unit( - "md_tanf_self_employment_income", period - ) - non_self_employment_income = max_( - earned_income - self_employment_income, 0 - ) - return (self_employment_income * p.self_employed) + ( - non_self_employment_income * p.not_self_employed - ) diff --git a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_earnings_deduction.py b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_earnings_deduction.py new file mode 100644 index 00000000000..08537b8f33c --- /dev/null +++ b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_earnings_deduction.py @@ -0,0 +1,22 @@ +from policyengine_us.model_api import * + + +class md_tanf_earnings_deduction(Variable): + value_type = float + entity = SPMUnit + label = "Maryland TCA earnings deduction" + unit = USD + definition_period = MONTH + defined_for = StateCode.MD + reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx" + + def formula(spm_unit, period, parameters): + # NOTE: Maryland applies different deduction rates for self-employment (50%) + # vs regular employment. We apply the employment rate to all earned + # income as a simplification. + p = parameters(period).gov.states.md.tanf.income.deductions.earned + earned_income = add(spm_unit, period, ["tanf_gross_earned_income"]) + is_enrolled = spm_unit("is_tanf_enrolled", period) + # 20% for new applicants, 40% for enrolled recipients + rate = where(is_enrolled, p.not_self_employed, p.new) + return earned_income * rate diff --git a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.py b/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.py deleted file mode 100644 index f535ab73ea3..00000000000 --- a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_initial_earnings_deduction.py +++ /dev/null @@ -1,28 +0,0 @@ -from policyengine_us.model_api import * - - -class md_tanf_initial_earnings_deduction(Variable): - value_type = float - entity = SPMUnit - label = "Maryland TCA initial earnings deduction" - unit = USD - definition_period = MONTH - defined_for = StateCode.MD - reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx" - - def formula(spm_unit, period, parameters): - p = parameters(period).gov.states.md.tanf.income.deductions.earned - earned_income = spm_unit( - "md_tanf_countable_gross_earned_income", period - ) - # Determine if the SPM unit has any self-employment income. - self_employment_income = spm_unit( - "md_tanf_self_employment_income", period - ) - non_self_employment_income = max_( - earned_income - self_employment_income, 0 - ) - - return (self_employment_income * p.self_employed) + ( - non_self_employment_income * p.new - ) diff --git a/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_countable_gross_earned_income.py b/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_countable_gross_earned_income.py deleted file mode 100644 index 4b418ffcc75..00000000000 --- a/policyengine_us/variables/gov/states/md/tanf/income/earned/md_tanf_countable_gross_earned_income.py +++ /dev/null @@ -1,28 +0,0 @@ -from policyengine_us.model_api import * - - -class md_tanf_countable_gross_earned_income(Variable): - value_type = float - entity = SPMUnit - label = "Maryland TCA countable gross earned income" - unit = USD - definition_period = MONTH - defined_for = StateCode.MD - reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx" - - def formula(spm_unit, period, parameters): - # Per COMAR 07.03.03.13, exclude: - # 1. Earned income of a child - # 2. Earned income of an SSI recipient - person = spm_unit.members - is_child = person("md_tanf_is_child", period) - is_ssi_recipient = person("is_ssi_eligible", period.this_year) - # Count only earned income from non-children and non-SSI recipients - include_income = ~is_child & ~is_ssi_recipient - # Get earned income sources from parameters - earned_sources = parameters( - period - ).gov.states.md.tanf.income.sources.earned - total_earned = add(person, period, earned_sources) - countable_earned = total_earned * include_income - return spm_unit.sum(countable_earned) diff --git a/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_countable_income.py b/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_countable_income.py index 69529a9b8bb..5ce18e45ab5 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_countable_income.py +++ b/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_countable_income.py @@ -11,22 +11,13 @@ class md_tanf_net_countable_income(Variable): reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx" def formula(spm_unit, period, parameters): - # Get gross income for the SPM unit. - gross_earned_income = spm_unit( - "md_tanf_countable_gross_earned_income", period - ) - gross_unearned_income = spm_unit( - "md_tanf_countable_gross_unearned_income", period - ) - # Get continuous deductions for the SPM unit. - continuous_deductions = spm_unit( - "md_tanf_continuous_earnings_deduction", period - ) - # Get childcare deductions for the SPM unit. + gross_earned = add(spm_unit, period, ["tanf_gross_earned_income"]) + gross_unearned = add(spm_unit, period, ["tanf_gross_unearned_income"]) + earnings_deduction = spm_unit("md_tanf_earnings_deduction", period) childcare_deduction = spm_unit("md_tanf_childcare_deduction", period) # Apply deductions to earned income only, then add unearned countable_earned = max_( - gross_earned_income - continuous_deductions - childcare_deduction, + gross_earned - earnings_deduction - childcare_deduction, 0, ) - return countable_earned + gross_unearned_income + return countable_earned + gross_unearned diff --git a/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.py b/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.py deleted file mode 100644 index 021c75915b7..00000000000 --- a/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_initial_countable_income.py +++ /dev/null @@ -1,32 +0,0 @@ -from policyengine_us.model_api import * - - -class md_tanf_net_initial_countable_income(Variable): - value_type = float - entity = SPMUnit - label = "Maryland TCA net initial countable income" - unit = USD - definition_period = MONTH - defined_for = StateCode.MD - reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx" - - def formula(spm_unit, period, parameters): - # Get gross income for the SPM unit. - gross_earned_income = spm_unit( - "md_tanf_countable_gross_earned_income", period - ) - gross_unearned_income = spm_unit( - "md_tanf_countable_gross_unearned_income", period - ) - # Get initial deductions for the SPM unit. - initial_deductions = spm_unit( - "md_tanf_initial_earnings_deduction", period - ) - # Get childcare deductions for the SPM unit. - childcare_deduction = spm_unit("md_tanf_childcare_deduction", period) - # Apply deductions to earned income only, then add unearned - countable_earned = max_( - gross_earned_income - initial_deductions - childcare_deduction, - 0, - ) - return countable_earned + gross_unearned_income diff --git a/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.py b/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.py deleted file mode 100644 index 41147cff3c2..00000000000 --- a/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_countable_gross_unearned_income.py +++ /dev/null @@ -1,13 +0,0 @@ -from policyengine_us.model_api import * - - -class md_tanf_countable_gross_unearned_income(Variable): - value_type = float - entity = SPMUnit - label = "Maryland TCA countable gross unearned income" - unit = USD - definition_period = MONTH - defined_for = StateCode.MD - reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx" - - adds = ["md_tanf_gross_unearned_income"] diff --git a/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_gross_unearned_income.py b/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_gross_unearned_income.py deleted file mode 100644 index 7215c696289..00000000000 --- a/policyengine_us/variables/gov/states/md/tanf/income/unearned/md_tanf_gross_unearned_income.py +++ /dev/null @@ -1,13 +0,0 @@ -from policyengine_us.model_api import * - - -class md_tanf_gross_unearned_income(Variable): - value_type = float - entity = SPMUnit - label = "Maryland TCA gross unearned income" - unit = USD - definition_period = MONTH - defined_for = StateCode.MD - reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx" - - adds = "gov.states.md.tanf.income.sources.unearned" diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf_count_children.py b/policyengine_us/variables/gov/states/md/tanf/md_tanf_count_children.py deleted file mode 100644 index dc276a6e8f4..00000000000 --- a/policyengine_us/variables/gov/states/md/tanf/md_tanf_count_children.py +++ /dev/null @@ -1,11 +0,0 @@ -from policyengine_us.model_api import * - - -class md_tanf_count_children(Variable): - value_type = int - entity = SPMUnit - label = "Maryland TCA number of children" - definition_period = MONTH - defined_for = StateCode.MD - reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.07.aspx" - adds = ["md_tanf_is_child"] diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf_eligible.py b/policyengine_us/variables/gov/states/md/tanf/md_tanf_eligible.py index d545024256f..38b849d3e84 100644 --- a/policyengine_us/variables/gov/states/md/tanf/md_tanf_eligible.py +++ b/policyengine_us/variables/gov/states/md/tanf/md_tanf_eligible.py @@ -7,9 +7,26 @@ class md_tanf_eligible(Variable): label = "Maryland TCA eligible" definition_period = MONTH defined_for = StateCode.MD - reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.03.aspx" + reference = ( + "https://dsd.maryland.gov/regulations/Pages/07.03.03.03.aspx", + "https://dsd.maryland.gov/regulations/Pages/07.03.03.12.aspx", + ) def formula(spm_unit, period, parameters): - has_children = spm_unit("md_tanf_count_children", period) > 0 - demographic_eligible = spm_unit("is_demographic_tanf_eligible", period) - return has_children & demographic_eligible + # Must have at least one eligible child (uses federal demographic rules) + has_children = spm_unit("is_demographic_tanf_eligible", period) + + # Must meet income eligibility + income_eligible = spm_unit("md_tanf_income_eligible", period) + + # Must meet immigration status eligibility (citizen or qualified alien) + # Per COMAR 07.03.17.09 and 8 USC 1641 + person = spm_unit.members + immigration_eligible = spm_unit.any( + person("is_citizen_or_legal_immigrant", period.this_year) + ) + + # Note: Per COMAR 07.03.03.12, individual assets are EXCLUDED + # from TCA eligibility, so no resource test is required. + + return has_children & income_eligible & immigration_eligible diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf_income_eligible.py b/policyengine_us/variables/gov/states/md/tanf/md_tanf_income_eligible.py new file mode 100644 index 00000000000..8f45a255829 --- /dev/null +++ b/policyengine_us/variables/gov/states/md/tanf/md_tanf_income_eligible.py @@ -0,0 +1,17 @@ +from policyengine_us.model_api import * + + +class md_tanf_income_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Maryland TCA income eligible" + definition_period = MONTH + defined_for = StateCode.MD + reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx" + + def formula(spm_unit, period, parameters): + # Per COMAR 07.03.03.13, eligibility is based on comparing + # net countable income to the grant standard + net_income = spm_unit("md_tanf_net_countable_income", period) + grant_standard = spm_unit("md_tanf_maximum_benefit", period) + return net_income <= grant_standard diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf_is_child.py b/policyengine_us/variables/gov/states/md/tanf/md_tanf_is_child.py deleted file mode 100644 index 2a8ae2565c0..00000000000 --- a/policyengine_us/variables/gov/states/md/tanf/md_tanf_is_child.py +++ /dev/null @@ -1,26 +0,0 @@ -from policyengine_us.model_api import * - - -class md_tanf_is_child(Variable): - value_type = bool - entity = Person - definition_period = MONTH - label = "Is a child under Maryland TCA program" - defined_for = StateCode.MD - reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.07.aspx" - - def formula(person, period, parameters): - p = parameters(period).gov.states.md.tanf - age = person("age", period.this_year) - # Younger than age 18 - child = person("is_child", period.this_year) - # Younger than age 19 and a full-time K-12 student - age_eligible = age < p.age_limit - k12 = person("is_in_k12_school", period) - k12_age_eligible = k12 & age_eligible - # Age 19 and a full-time secondary school student - # Per COMAR 07.03.03.07, extended eligibility is for secondary school - # students only - college students do not qualify - years_19 = age == p.age_limit - secondary_school_enrolled_19_year_old = k12 & years_19 - return child | secondary_school_enrolled_19_year_old | k12_age_eligible diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf_self_employment_income.py b/policyengine_us/variables/gov/states/md/tanf/md_tanf_self_employment_income.py deleted file mode 100644 index 0e2745fefb9..00000000000 --- a/policyengine_us/variables/gov/states/md/tanf/md_tanf_self_employment_income.py +++ /dev/null @@ -1,13 +0,0 @@ -from policyengine_us.model_api import * - - -class md_tanf_self_employment_income(Variable): - value_type = float - entity = SPMUnit - label = "Maryland TCA self-employment income" - unit = USD - definition_period = MONTH - defined_for = StateCode.MD - reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx" - - adds = "gov.irs.tax.self_employment.taxable_self_employment_income" diff --git a/policyengine_us/variables/household/demographic/person/work_hours/work_days_per_week.py b/policyengine_us/variables/household/demographic/person/work_hours/work_days_per_week.py deleted file mode 100644 index 8474b7ce897..00000000000 --- a/policyengine_us/variables/household/demographic/person/work_hours/work_days_per_week.py +++ /dev/null @@ -1,9 +0,0 @@ -from policyengine_us.model_api import * - - -class work_days_per_week(Variable): - value_type = float - entity = Person - label = "Work days per week" - definition_period = YEAR - unit = "day" diff --git a/policyengine_us/variables/household/demographic/person/work_hours/work_hours_per_day.py b/policyengine_us/variables/household/demographic/person/work_hours/work_hours_per_day.py deleted file mode 100644 index 9aa02bfe0ea..00000000000 --- a/policyengine_us/variables/household/demographic/person/work_hours/work_hours_per_day.py +++ /dev/null @@ -1,9 +0,0 @@ -from policyengine_us.model_api import * - - -class work_hours_per_day(Variable): - value_type = float - entity = Person - label = "Work hours per day" - definition_period = YEAR - unit = "hour" diff --git a/policyengine_us/variables/household/demographic/person/work_hours/work_hours_per_week.py b/policyengine_us/variables/household/demographic/person/work_hours/work_hours_per_week.py deleted file mode 100644 index 2ccfbfb07dc..00000000000 --- a/policyengine_us/variables/household/demographic/person/work_hours/work_hours_per_week.py +++ /dev/null @@ -1,14 +0,0 @@ -from policyengine_us.model_api import * - - -class work_hours_per_week(Variable): - value_type = float - entity = Person - label = "Work hours per week" - definition_period = YEAR - unit = "hour" - - def formula(person, period, parameters): - days_per_week = person("work_days_per_week", period) - hours_per_day = person("work_hours_per_day", period) - return days_per_week * hours_per_day From 914e750d62d55139cabcf7b3f569d999e6297855 Mon Sep 17 00:00:00 2001 From: Ziming Date: Sat, 10 Jan 2026 20:17:36 -0500 Subject: [PATCH 07/10] rename --- changelog_entry.yaml | 2 +- .../parameters/gov/states/md/tanf/README.md | 1 - .../parameters/gov/states/md/tca/README.md | 1 + .../childcare_expenses/full_time.yaml | 0 .../childcare_expenses/part_time.yaml | 0 .../deductions/earned/fulltime_hours.yaml | 0 .../income/deductions/earned/new.yaml | 0 .../deductions/earned/not_self_employed.yaml | 0 .../maximum_benefit/additional.yaml | 0 .../{tanf => tca}/maximum_benefit/main.yaml | 0 .../maximum_benefit/max_unit_size.yaml | 0 .../md_tca_childcare_deduction.yaml} | 14 ++-- .../md_tca_earnings_deduction.yaml} | 6 +- .../income/md_tca_net_countable_income.yaml} | 24 +++--- .../states/md/{tanf => tca}/integration.yaml | 82 +++++++++---------- .../md/{tanf/md_tanf.yaml => tca/md_tca.yaml} | 32 ++++---- .../md_tca_eligible.yaml} | 12 +-- .../md_tca_income_eligible.yaml} | 24 +++--- .../md_tca_maximum_benefit.yaml} | 16 ++-- .../deductions/md_tca_childcare_deduction.py} | 4 +- .../deductions/md_tca_earnings_deduction.py} | 4 +- .../income/md_tca_net_countable_income.py} | 6 +- .../md/{tanf/md_tanf.py => tca/md_tca.py} | 8 +- .../md_tca_eligible.py} | 4 +- .../md_tca_income_eligible.py} | 6 +- .../md_tca_maximum_benefit.py} | 4 +- 26 files changed, 125 insertions(+), 125 deletions(-) delete mode 100644 policyengine_us/parameters/gov/states/md/tanf/README.md create mode 100644 policyengine_us/parameters/gov/states/md/tca/README.md rename policyengine_us/parameters/gov/states/md/{tanf => tca}/income/deductions/childcare_expenses/full_time.yaml (100%) rename policyengine_us/parameters/gov/states/md/{tanf => tca}/income/deductions/childcare_expenses/part_time.yaml (100%) rename policyengine_us/parameters/gov/states/md/{tanf => tca}/income/deductions/earned/fulltime_hours.yaml (100%) rename policyengine_us/parameters/gov/states/md/{tanf => tca}/income/deductions/earned/new.yaml (100%) rename policyengine_us/parameters/gov/states/md/{tanf => tca}/income/deductions/earned/not_self_employed.yaml (100%) rename policyengine_us/parameters/gov/states/md/{tanf => tca}/maximum_benefit/additional.yaml (100%) rename policyengine_us/parameters/gov/states/md/{tanf => tca}/maximum_benefit/main.yaml (100%) rename policyengine_us/parameters/gov/states/md/{tanf => tca}/maximum_benefit/max_unit_size.yaml (100%) rename policyengine_us/tests/policy/baseline/gov/states/md/{tanf/income/deductions/md_tanf_childcare_deduction.yaml => tca/income/deductions/md_tca_childcare_deduction.yaml} (91%) rename policyengine_us/tests/policy/baseline/gov/states/md/{tanf/income/deductions/md_tanf_earnings_deduction.yaml => tca/income/deductions/md_tca_earnings_deduction.yaml} (91%) rename policyengine_us/tests/policy/baseline/gov/states/md/{tanf/income/income/md_tanf_net_countable_income.yaml => tca/income/income/md_tca_net_countable_income.yaml} (75%) rename policyengine_us/tests/policy/baseline/gov/states/md/{tanf => tca}/integration.yaml (77%) rename policyengine_us/tests/policy/baseline/gov/states/md/{tanf/md_tanf.yaml => tca/md_tca.yaml} (68%) rename policyengine_us/tests/policy/baseline/gov/states/md/{tanf/md_tanf_eligible.yaml => tca/md_tca_eligible.yaml} (88%) rename policyengine_us/tests/policy/baseline/gov/states/md/{tanf/md_tanf_income_eligible.yaml => tca/md_tca_income_eligible.yaml} (70%) rename policyengine_us/tests/policy/baseline/gov/states/md/{tanf/md_tanf_maximum_benefit.yaml => tca/md_tca_maximum_benefit.yaml} (88%) rename policyengine_us/variables/gov/states/md/{tanf/income/deductions/md_tanf_childcare_deduction.py => tca/income/deductions/md_tca_childcare_deduction.py} (89%) rename policyengine_us/variables/gov/states/md/{tanf/income/deductions/md_tanf_earnings_deduction.py => tca/income/deductions/md_tca_earnings_deduction.py} (87%) rename policyengine_us/variables/gov/states/md/{tanf/income/income/md_tanf_net_countable_income.py => tca/income/income/md_tca_net_countable_income.py} (78%) rename policyengine_us/variables/gov/states/md/{tanf/md_tanf.py => tca/md_tca.py} (64%) rename policyengine_us/variables/gov/states/md/{tanf/md_tanf_eligible.py => tca/md_tca_eligible.py} (91%) rename policyengine_us/variables/gov/states/md/{tanf/md_tanf_income_eligible.py => tca/md_tca_income_eligible.py} (73%) rename policyengine_us/variables/gov/states/md/{tanf/md_tanf_maximum_benefit.py => tca/md_tca_maximum_benefit.py} (84%) diff --git a/changelog_entry.yaml b/changelog_entry.yaml index 5e86430480e..7c5fb012b27 100644 --- a/changelog_entry.yaml +++ b/changelog_entry.yaml @@ -1,4 +1,4 @@ - bump: minor changes: added: - - Implement Maryland TCA (TANF) program. + - Implement Maryland Temporary Cash Assistance (TFA) program. diff --git a/policyengine_us/parameters/gov/states/md/tanf/README.md b/policyengine_us/parameters/gov/states/md/tanf/README.md deleted file mode 100644 index eb8aeb3f951..00000000000 --- a/policyengine_us/parameters/gov/states/md/tanf/README.md +++ /dev/null @@ -1 +0,0 @@ -# Temporary Assistance for Needy Families diff --git a/policyengine_us/parameters/gov/states/md/tca/README.md b/policyengine_us/parameters/gov/states/md/tca/README.md new file mode 100644 index 00000000000..23c7bdba578 --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/tca/README.md @@ -0,0 +1 @@ +# Temporary Cash Assistance diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/full_time.yaml b/policyengine_us/parameters/gov/states/md/tca/income/deductions/childcare_expenses/full_time.yaml similarity index 100% rename from policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/full_time.yaml rename to policyengine_us/parameters/gov/states/md/tca/income/deductions/childcare_expenses/full_time.yaml diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/part_time.yaml b/policyengine_us/parameters/gov/states/md/tca/income/deductions/childcare_expenses/part_time.yaml similarity index 100% rename from policyengine_us/parameters/gov/states/md/tanf/income/deductions/childcare_expenses/part_time.yaml rename to policyengine_us/parameters/gov/states/md/tca/income/deductions/childcare_expenses/part_time.yaml diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/fulltime_hours.yaml b/policyengine_us/parameters/gov/states/md/tca/income/deductions/earned/fulltime_hours.yaml similarity index 100% rename from policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/fulltime_hours.yaml rename to policyengine_us/parameters/gov/states/md/tca/income/deductions/earned/fulltime_hours.yaml diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/new.yaml b/policyengine_us/parameters/gov/states/md/tca/income/deductions/earned/new.yaml similarity index 100% rename from policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/new.yaml rename to policyengine_us/parameters/gov/states/md/tca/income/deductions/earned/new.yaml diff --git a/policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/not_self_employed.yaml b/policyengine_us/parameters/gov/states/md/tca/income/deductions/earned/not_self_employed.yaml similarity index 100% rename from policyengine_us/parameters/gov/states/md/tanf/income/deductions/earned/not_self_employed.yaml rename to policyengine_us/parameters/gov/states/md/tca/income/deductions/earned/not_self_employed.yaml diff --git a/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/additional.yaml b/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/additional.yaml similarity index 100% rename from policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/additional.yaml rename to policyengine_us/parameters/gov/states/md/tca/maximum_benefit/additional.yaml diff --git a/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/main.yaml b/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/main.yaml similarity index 100% rename from policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/main.yaml rename to policyengine_us/parameters/gov/states/md/tca/maximum_benefit/main.yaml diff --git a/policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/max_unit_size.yaml b/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/max_unit_size.yaml similarity index 100% rename from policyengine_us/parameters/gov/states/md/tanf/maximum_benefit/max_unit_size.yaml rename to policyengine_us/parameters/gov/states/md/tca/maximum_benefit/max_unit_size.yaml diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tca/income/deductions/md_tca_childcare_deduction.yaml similarity index 91% rename from policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.yaml rename to policyengine_us/tests/policy/baseline/gov/states/md/tca/income/deductions/md_tca_childcare_deduction.yaml index b800ec4be4a..35b771637e7 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tca/income/deductions/md_tca_childcare_deduction.yaml @@ -18,7 +18,7 @@ household: state_code: MD output: - md_tanf_childcare_deduction: 0 + md_tca_childcare_deduction: 0 - name: Case 2, has child with part-time work. period: 2024-01 @@ -37,7 +37,7 @@ state_code: MD output: # Part-time (< 25 hrs) = $100 - md_tanf_childcare_deduction: 100 + md_tca_childcare_deduction: 100 - name: Case 3, has child with full-time work. period: 2024-01 @@ -56,7 +56,7 @@ state_code: MD output: # Full-time (>= 25 hrs) = $200 - md_tanf_childcare_deduction: 200 + md_tca_childcare_deduction: 200 - name: Case 4, exactly 25 hours threshold. period: 2024-01 @@ -75,7 +75,7 @@ state_code: MD output: # Exactly at threshold (>= 25 hrs) = full-time rate - md_tanf_childcare_deduction: 200 + md_tca_childcare_deduction: 200 - name: Case 5, at 24 hours below threshold. period: 2024-01 @@ -94,7 +94,7 @@ state_code: MD output: # Below threshold (< 25 hrs) = part-time rate - md_tanf_childcare_deduction: 100 + md_tca_childcare_deduction: 100 - name: Case 6, has child but zero work hours. period: 2024-01 @@ -113,7 +113,7 @@ state_code: MD output: # Zero hours = part-time rate - md_tanf_childcare_deduction: 100 + md_tca_childcare_deduction: 100 - name: Case 7, multiple adults with one full-time. period: 2024-01 @@ -135,4 +135,4 @@ state_code: MD output: # Any member >= 25 hrs = full-time rate - md_tanf_childcare_deduction: 200 + md_tca_childcare_deduction: 200 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_earnings_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tca/income/deductions/md_tca_earnings_deduction.yaml similarity index 91% rename from policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_earnings_deduction.yaml rename to policyengine_us/tests/policy/baseline/gov/states/md/tca/income/deductions/md_tca_earnings_deduction.yaml index b8641b16b6f..8391bad48b2 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/deductions/md_tanf_earnings_deduction.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tca/income/deductions/md_tca_earnings_deduction.yaml @@ -17,7 +17,7 @@ state_code: MD output: # $12,000/12 = $1,000/month * 0.20 = $200 - md_tanf_earnings_deduction: 200 + md_tca_earnings_deduction: 200 - name: Case 2, enrolled gets 40% deduction. period: 2024-01 @@ -35,7 +35,7 @@ state_code: MD output: # $12,000/12 = $1,000/month * 0.40 = $400 - md_tanf_earnings_deduction: 400 + md_tca_earnings_deduction: 400 - name: Case 3, zero income. period: 2024-01 @@ -51,4 +51,4 @@ household: state_code: MD output: - md_tanf_earnings_deduction: 0 + md_tca_earnings_deduction: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tca/income/income/md_tca_net_countable_income.yaml similarity index 75% rename from policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_countable_income.yaml rename to policyengine_us/tests/policy/baseline/gov/states/md/tca/income/income/md_tca_net_countable_income.yaml index 10f72bc351b..b4a52bc1072 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/income/income/md_tanf_net_countable_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tca/income/income/md_tca_net_countable_income.yaml @@ -11,14 +11,14 @@ spm_units: spm_unit: members: [person1] - md_tanf_earnings_deduction: 400 - md_tanf_childcare_deduction: 0 + md_tca_earnings_deduction: 400 + md_tca_childcare_deduction: 0 households: household: state_code: MD output: # max($1,000 - $400 - $0, 0) + $0 = $600 - md_tanf_net_countable_income: 600 + md_tca_net_countable_income: 600 - name: Case 2, earned and unearned income minus deductions. period: 2024-01 @@ -31,14 +31,14 @@ spm_units: spm_unit: members: [person1] - md_tanf_earnings_deduction: 400 - md_tanf_childcare_deduction: 100 + md_tca_earnings_deduction: 400 + md_tca_childcare_deduction: 100 households: household: state_code: MD output: # max($1,000 - $400 - $100, 0) + $500 = $500 + $500 = $1,000 - md_tanf_net_countable_income: 1_000 + md_tca_net_countable_income: 1_000 - name: Case 3, deductions exceed earned income. period: 2024-01 @@ -51,14 +51,14 @@ spm_units: spm_unit: members: [person1] - md_tanf_earnings_deduction: 100 - md_tanf_childcare_deduction: 200 + md_tca_earnings_deduction: 100 + md_tca_childcare_deduction: 200 households: household: state_code: MD output: # max($200 - $100 - $200, 0) + $300 = $0 + $300 = $300 - md_tanf_net_countable_income: 300 + md_tca_net_countable_income: 300 - name: Case 4, zero income. period: 2024-01 @@ -69,10 +69,10 @@ spm_units: spm_unit: members: [person1] - md_tanf_earnings_deduction: 0 - md_tanf_childcare_deduction: 0 + md_tca_earnings_deduction: 0 + md_tca_childcare_deduction: 0 households: household: state_code: MD output: - md_tanf_net_countable_income: 0 + md_tca_net_countable_income: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tca/integration.yaml similarity index 77% rename from policyengine_us/tests/policy/baseline/gov/states/md/tanf/integration.yaml rename to policyengine_us/tests/policy/baseline/gov/states/md/tca/integration.yaml index 19fdea5cd8e..abe3885f2dd 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tca/integration.yaml @@ -22,25 +22,25 @@ output: # Earnings deduction (enrolled = 40%) # $1,000 * 0.40 = $400 - md_tanf_earnings_deduction: 400 + md_tca_earnings_deduction: 400 # Childcare deduction (30 hrs >= 25 = full-time = $200) - md_tanf_childcare_deduction: 200 + md_tca_childcare_deduction: 200 # Net countable income # max($1,000 - $400 - $200, 0) + $0 unearned = $400 - md_tanf_net_countable_income: 400 + md_tca_net_countable_income: 400 # Maximum benefit (2-person household) - md_tanf_maximum_benefit: 575 + md_tca_maximum_benefit: 575 # Income eligibility ($400 <= $575) - md_tanf_income_eligible: true + md_tca_income_eligible: true - md_tanf_eligible: true + md_tca_eligible: true # max($575 - $400, 0) = $175 - md_tanf: 175 + md_tca: 175 - name: Case 2, single parent with child, not enrolled. period: 2024-01 @@ -62,24 +62,24 @@ output: # Earnings deduction (not enrolled = 20%) # $1,000 * 0.20 = $200 - md_tanf_earnings_deduction: 200 + md_tca_earnings_deduction: 200 # Childcare deduction (full-time) - md_tanf_childcare_deduction: 200 + md_tca_childcare_deduction: 200 # Net countable income # max($1,000 - $200 - $200, 0) = $600 - md_tanf_net_countable_income: 600 + md_tca_net_countable_income: 600 # Maximum benefit - md_tanf_maximum_benefit: 575 + md_tca_maximum_benefit: 575 # Income eligibility ($600 > $575 = false) - md_tanf_income_eligible: false + md_tca_income_eligible: false - md_tanf_eligible: false + md_tca_eligible: false - md_tanf: 0 + md_tca: 0 - name: Case 3, multiple earners with child. period: 2024-01 @@ -108,23 +108,23 @@ # Total: $3,000/month # 40% deduction: $3,000 * 0.40 = $1,200 - md_tanf_earnings_deduction: 1_200 + md_tca_earnings_deduction: 1_200 # Full-time (40 hrs) - md_tanf_childcare_deduction: 200 + md_tca_childcare_deduction: 200 # max($3,000 - $1,200 - $200, 0) = $1,600 - md_tanf_net_countable_income: 1_600 + md_tca_net_countable_income: 1_600 # 3-person household - md_tanf_maximum_benefit: 727 + md_tca_maximum_benefit: 727 # $1,600 > $727 = false - md_tanf_income_eligible: false + md_tca_income_eligible: false - md_tanf_eligible: false + md_tca_eligible: false - md_tanf: 0 + md_tca: 0 - name: Case 4, large household at size cap. period: 2024-01 @@ -156,20 +156,20 @@ household: state_code: MD output: - md_tanf_earnings_deduction: 0 + md_tca_earnings_deduction: 0 # Part-time rate (no work hours) - md_tanf_childcare_deduction: 100 + md_tca_childcare_deduction: 100 - md_tanf_net_countable_income: 0 + md_tca_net_countable_income: 0 # 8-person household = maximum in table - md_tanf_maximum_benefit: 1_372 + md_tca_maximum_benefit: 1_372 - md_tanf_income_eligible: true - md_tanf_eligible: true + md_tca_income_eligible: true + md_tca_eligible: true - md_tanf: 1_372 + md_tca: 1_372 - name: Case 5, zero income receives full benefit. period: 2024-01 @@ -188,16 +188,16 @@ household: state_code: MD output: - md_tanf_earnings_deduction: 0 - md_tanf_childcare_deduction: 100 - md_tanf_net_countable_income: 0 + md_tca_earnings_deduction: 0 + md_tca_childcare_deduction: 100 + md_tca_net_countable_income: 0 - md_tanf_maximum_benefit: 575 + md_tca_maximum_benefit: 575 - md_tanf_income_eligible: true - md_tanf_eligible: true + md_tca_income_eligible: true + md_tca_eligible: true - md_tanf: 575 + md_tca: 575 - name: Case 6, ineligible no children. period: 2024-01 @@ -216,11 +216,11 @@ household: state_code: MD output: - md_tanf_maximum_benefit: 575 + md_tca_maximum_benefit: 575 - md_tanf_eligible: false + md_tca_eligible: false - md_tanf: 0 + md_tca: 0 - name: Case 7, 10 person household above size cap. period: 2024-01 @@ -255,8 +255,8 @@ state_code: MD output: # 10-person household = $1,372 (8-person) + 2 * $136 = $1,644 - md_tanf_maximum_benefit: 1_644 + md_tca_maximum_benefit: 1_644 - md_tanf_eligible: true + md_tca_eligible: true - md_tanf: 1_644 + md_tca: 1_644 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tca/md_tca.yaml similarity index 68% rename from policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf.yaml rename to policyengine_us/tests/policy/baseline/gov/states/md/tca/md_tca.yaml index f241ed5e5a0..ca26ed4a837 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tca/md_tca.yaml @@ -7,15 +7,15 @@ spm_units: spm_unit: members: [person1] - md_tanf_eligible: true - md_tanf_maximum_benefit: 727 - md_tanf_net_countable_income: 200 + md_tca_eligible: true + md_tca_maximum_benefit: 727 + md_tca_net_countable_income: 200 households: household: state_code: MD output: # Benefit = $727 - $200 = $527 - md_tanf: 527 + md_tca: 527 - name: Case 2, eligible with zero income. period: 2024-01 @@ -26,15 +26,15 @@ spm_units: spm_unit: members: [person1] - md_tanf_eligible: true - md_tanf_maximum_benefit: 575 - md_tanf_net_countable_income: 0 + md_tca_eligible: true + md_tca_maximum_benefit: 575 + md_tca_net_countable_income: 0 households: household: state_code: MD output: # Benefit = $575 - $0 = $575 - md_tanf: 575 + md_tca: 575 - name: Case 3, income exceeds maximum benefit. period: 2024-01 @@ -45,15 +45,15 @@ spm_units: spm_unit: members: [person1] - md_tanf_eligible: true - md_tanf_maximum_benefit: 575 - md_tanf_net_countable_income: 600 + md_tca_eligible: true + md_tca_maximum_benefit: 575 + md_tca_net_countable_income: 600 households: household: state_code: MD output: # Benefit = max($575 - $600, 0) = $0 - md_tanf: 0 + md_tca: 0 - name: Case 4, ineligible household receives zero. period: 2024-01 @@ -64,11 +64,11 @@ spm_units: spm_unit: members: [person1] - md_tanf_eligible: false - md_tanf_maximum_benefit: 575 - md_tanf_net_countable_income: 0 + md_tca_eligible: false + md_tca_maximum_benefit: 575 + md_tca_net_countable_income: 0 households: household: state_code: MD output: - md_tanf: 0 + md_tca: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tca/md_tca_eligible.yaml similarity index 88% rename from policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_eligible.yaml rename to policyengine_us/tests/policy/baseline/gov/states/md/tca/md_tca_eligible.yaml index d701a09e399..a49eecd3042 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tca/md_tca_eligible.yaml @@ -1,4 +1,4 @@ -# Tests overall TANF eligibility (demographic + income + immigration) +# Tests overall TCA eligibility (demographic + income + immigration) - name: Case 1, household with child is eligible. period: 2024-01 @@ -15,7 +15,7 @@ household: state_code: MD output: - md_tanf_eligible: true + md_tca_eligible: true - name: Case 2, household with no children is not eligible. period: 2024-01 @@ -32,7 +32,7 @@ household: state_code: MD output: - md_tanf_eligible: false + md_tca_eligible: false - name: Case 3, single adult is not eligible. period: 2024-01 @@ -47,7 +47,7 @@ household: state_code: MD output: - md_tanf_eligible: false + md_tca_eligible: false - name: Case 4, 18 year old secondary school student is eligible. period: 2024-01 @@ -66,7 +66,7 @@ state_code: MD output: # Per federal TANF rules, 18-year-olds in secondary school count as children - md_tanf_eligible: true + md_tca_eligible: true - name: Case 5, 19 year old is not eligible. period: 2024-01 @@ -85,4 +85,4 @@ state_code: MD output: # Per federal TANF rules, 19-year-olds do not count as children - md_tanf_eligible: false + md_tca_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tca/md_tca_income_eligible.yaml similarity index 70% rename from policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_income_eligible.yaml rename to policyengine_us/tests/policy/baseline/gov/states/md/tca/md_tca_income_eligible.yaml index 648112000b9..0452e40b64b 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_income_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tca/md_tca_income_eligible.yaml @@ -9,14 +9,14 @@ spm_units: spm_unit: members: [person1] - md_tanf_net_countable_income: 300 - md_tanf_maximum_benefit: 575 + md_tca_net_countable_income: 300 + md_tca_maximum_benefit: 575 households: household: state_code: MD output: # $300 <= $575 = true - md_tanf_income_eligible: true + md_tca_income_eligible: true - name: Case 2, income equals grant standard. period: 2024-01 @@ -27,14 +27,14 @@ spm_units: spm_unit: members: [person1] - md_tanf_net_countable_income: 575 - md_tanf_maximum_benefit: 575 + md_tca_net_countable_income: 575 + md_tca_maximum_benefit: 575 households: household: state_code: MD output: # $575 <= $575 = true - md_tanf_income_eligible: true + md_tca_income_eligible: true - name: Case 3, income exceeds grant standard. period: 2024-01 @@ -45,14 +45,14 @@ spm_units: spm_unit: members: [person1] - md_tanf_net_countable_income: 600 - md_tanf_maximum_benefit: 575 + md_tca_net_countable_income: 600 + md_tca_maximum_benefit: 575 households: household: state_code: MD output: # $600 <= $575 = false - md_tanf_income_eligible: false + md_tca_income_eligible: false - name: Case 4, zero income. period: 2024-01 @@ -63,10 +63,10 @@ spm_units: spm_unit: members: [person1] - md_tanf_net_countable_income: 0 - md_tanf_maximum_benefit: 575 + md_tca_net_countable_income: 0 + md_tca_maximum_benefit: 575 households: household: state_code: MD output: - md_tanf_income_eligible: true + md_tca_income_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_maximum_benefit.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tca/md_tca_maximum_benefit.yaml similarity index 88% rename from policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_maximum_benefit.yaml rename to policyengine_us/tests/policy/baseline/gov/states/md/tca/md_tca_maximum_benefit.yaml index 761408aede6..5f29e04b904 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tanf/md_tanf_maximum_benefit.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tca/md_tca_maximum_benefit.yaml @@ -7,13 +7,13 @@ spm_units: spm_unit: members: [person1] - md_tanf_eligible: true + md_tca_eligible: true households: household: state_code: MD output: # $328 per month - md_tanf_maximum_benefit: 328 + md_tca_maximum_benefit: 328 - name: Case 2, ten-person household. period: 2024-01 @@ -42,13 +42,13 @@ spm_units: spm_unit: members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10] - md_tanf_eligible: true + md_tca_eligible: true households: household: state_code: MD output: # $1,372 (8-person max) + 2 * $136 = $1,644 per month - md_tanf_maximum_benefit: 1_644 + md_tca_maximum_benefit: 1_644 - name: Case 3, exactly at cap (8 persons). period: 2024-01 @@ -73,13 +73,13 @@ spm_units: spm_unit: members: [person1, person2, person3, person4, person5, person6, person7, person8] - md_tanf_eligible: true + md_tca_eligible: true households: household: state_code: MD output: # 8-person cap = $1,372 (no additional) - md_tanf_maximum_benefit: 1_372 + md_tca_maximum_benefit: 1_372 - name: Case 4, one above cap (9 persons). period: 2024-01 @@ -106,10 +106,10 @@ spm_units: spm_unit: members: [person1, person2, person3, person4, person5, person6, person7, person8, person9] - md_tanf_eligible: true + md_tca_eligible: true households: household: state_code: MD output: # $1,372 (8-person) + $136 (1 additional) = $1,508 - md_tanf_maximum_benefit: 1_508 + md_tca_maximum_benefit: 1_508 diff --git a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.py b/policyengine_us/variables/gov/states/md/tca/income/deductions/md_tca_childcare_deduction.py similarity index 89% rename from policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.py rename to policyengine_us/variables/gov/states/md/tca/income/deductions/md_tca_childcare_deduction.py index a317365fe72..033e9fd1f8c 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_childcare_deduction.py +++ b/policyengine_us/variables/gov/states/md/tca/income/deductions/md_tca_childcare_deduction.py @@ -1,7 +1,7 @@ from policyengine_us.model_api import * -class md_tanf_childcare_deduction(Variable): +class md_tca_childcare_deduction(Variable): value_type = float entity = SPMUnit label = "Maryland TCA childcare deduction" @@ -17,7 +17,7 @@ def formula(spm_unit, period, parameters): has_children = spm_unit("is_demographic_tanf_eligible", period) person = spm_unit.members work_hours = person("weekly_hours_worked", period.this_year) - p = parameters(period).gov.states.md.tanf.income.deductions + p = parameters(period).gov.states.md.tca.income.deductions full_time = spm_unit.any(work_hours >= p.earned.fulltime_hours) deduction = where( diff --git a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_earnings_deduction.py b/policyengine_us/variables/gov/states/md/tca/income/deductions/md_tca_earnings_deduction.py similarity index 87% rename from policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_earnings_deduction.py rename to policyengine_us/variables/gov/states/md/tca/income/deductions/md_tca_earnings_deduction.py index 08537b8f33c..bf45ae6e911 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/deductions/md_tanf_earnings_deduction.py +++ b/policyengine_us/variables/gov/states/md/tca/income/deductions/md_tca_earnings_deduction.py @@ -1,7 +1,7 @@ from policyengine_us.model_api import * -class md_tanf_earnings_deduction(Variable): +class md_tca_earnings_deduction(Variable): value_type = float entity = SPMUnit label = "Maryland TCA earnings deduction" @@ -14,7 +14,7 @@ def formula(spm_unit, period, parameters): # NOTE: Maryland applies different deduction rates for self-employment (50%) # vs regular employment. We apply the employment rate to all earned # income as a simplification. - p = parameters(period).gov.states.md.tanf.income.deductions.earned + p = parameters(period).gov.states.md.tca.income.deductions.earned earned_income = add(spm_unit, period, ["tanf_gross_earned_income"]) is_enrolled = spm_unit("is_tanf_enrolled", period) # 20% for new applicants, 40% for enrolled recipients diff --git a/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_countable_income.py b/policyengine_us/variables/gov/states/md/tca/income/income/md_tca_net_countable_income.py similarity index 78% rename from policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_countable_income.py rename to policyengine_us/variables/gov/states/md/tca/income/income/md_tca_net_countable_income.py index 5ce18e45ab5..623652a7607 100644 --- a/policyengine_us/variables/gov/states/md/tanf/income/income/md_tanf_net_countable_income.py +++ b/policyengine_us/variables/gov/states/md/tca/income/income/md_tca_net_countable_income.py @@ -1,7 +1,7 @@ from policyengine_us.model_api import * -class md_tanf_net_countable_income(Variable): +class md_tca_net_countable_income(Variable): value_type = float entity = SPMUnit label = "Maryland TCA net countable income" @@ -13,8 +13,8 @@ class md_tanf_net_countable_income(Variable): def formula(spm_unit, period, parameters): gross_earned = add(spm_unit, period, ["tanf_gross_earned_income"]) gross_unearned = add(spm_unit, period, ["tanf_gross_unearned_income"]) - earnings_deduction = spm_unit("md_tanf_earnings_deduction", period) - childcare_deduction = spm_unit("md_tanf_childcare_deduction", period) + earnings_deduction = spm_unit("md_tca_earnings_deduction", period) + childcare_deduction = spm_unit("md_tca_childcare_deduction", period) # Apply deductions to earned income only, then add unearned countable_earned = max_( gross_earned - earnings_deduction - childcare_deduction, diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf.py b/policyengine_us/variables/gov/states/md/tca/md_tca.py similarity index 64% rename from policyengine_us/variables/gov/states/md/tanf/md_tanf.py rename to policyengine_us/variables/gov/states/md/tca/md_tca.py index bb8c79d1709..259c1770a71 100644 --- a/policyengine_us/variables/gov/states/md/tanf/md_tanf.py +++ b/policyengine_us/variables/gov/states/md/tca/md_tca.py @@ -1,16 +1,16 @@ from policyengine_us.model_api import * -class md_tanf(Variable): +class md_tca(Variable): value_type = float entity = SPMUnit label = "Maryland Temporary Cash Assistance" unit = USD definition_period = MONTH - defined_for = "md_tanf_eligible" + defined_for = "md_tca_eligible" reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.17.aspx" def formula(spm_unit, period, parameters): - grant_standard = spm_unit("md_tanf_maximum_benefit", period) - income = spm_unit("md_tanf_net_countable_income", period) + grant_standard = spm_unit("md_tca_maximum_benefit", period) + income = spm_unit("md_tca_net_countable_income", period) return max_(grant_standard - income, 0) diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf_eligible.py b/policyengine_us/variables/gov/states/md/tca/md_tca_eligible.py similarity index 91% rename from policyengine_us/variables/gov/states/md/tanf/md_tanf_eligible.py rename to policyengine_us/variables/gov/states/md/tca/md_tca_eligible.py index 38b849d3e84..9a6a968bfc9 100644 --- a/policyengine_us/variables/gov/states/md/tanf/md_tanf_eligible.py +++ b/policyengine_us/variables/gov/states/md/tca/md_tca_eligible.py @@ -1,7 +1,7 @@ from policyengine_us.model_api import * -class md_tanf_eligible(Variable): +class md_tca_eligible(Variable): value_type = bool entity = SPMUnit label = "Maryland TCA eligible" @@ -17,7 +17,7 @@ def formula(spm_unit, period, parameters): has_children = spm_unit("is_demographic_tanf_eligible", period) # Must meet income eligibility - income_eligible = spm_unit("md_tanf_income_eligible", period) + income_eligible = spm_unit("md_tca_income_eligible", period) # Must meet immigration status eligibility (citizen or qualified alien) # Per COMAR 07.03.17.09 and 8 USC 1641 diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf_income_eligible.py b/policyengine_us/variables/gov/states/md/tca/md_tca_income_eligible.py similarity index 73% rename from policyengine_us/variables/gov/states/md/tanf/md_tanf_income_eligible.py rename to policyengine_us/variables/gov/states/md/tca/md_tca_income_eligible.py index 8f45a255829..452561bf60b 100644 --- a/policyengine_us/variables/gov/states/md/tanf/md_tanf_income_eligible.py +++ b/policyengine_us/variables/gov/states/md/tca/md_tca_income_eligible.py @@ -1,7 +1,7 @@ from policyengine_us.model_api import * -class md_tanf_income_eligible(Variable): +class md_tca_income_eligible(Variable): value_type = bool entity = SPMUnit label = "Maryland TCA income eligible" @@ -12,6 +12,6 @@ class md_tanf_income_eligible(Variable): def formula(spm_unit, period, parameters): # Per COMAR 07.03.03.13, eligibility is based on comparing # net countable income to the grant standard - net_income = spm_unit("md_tanf_net_countable_income", period) - grant_standard = spm_unit("md_tanf_maximum_benefit", period) + net_income = spm_unit("md_tca_net_countable_income", period) + grant_standard = spm_unit("md_tca_maximum_benefit", period) return net_income <= grant_standard diff --git a/policyengine_us/variables/gov/states/md/tanf/md_tanf_maximum_benefit.py b/policyengine_us/variables/gov/states/md/tca/md_tca_maximum_benefit.py similarity index 84% rename from policyengine_us/variables/gov/states/md/tanf/md_tanf_maximum_benefit.py rename to policyengine_us/variables/gov/states/md/tca/md_tca_maximum_benefit.py index 4de87ef8627..33e80a340e3 100644 --- a/policyengine_us/variables/gov/states/md/tanf/md_tanf_maximum_benefit.py +++ b/policyengine_us/variables/gov/states/md/tca/md_tca_maximum_benefit.py @@ -1,7 +1,7 @@ from policyengine_us.model_api import * -class md_tanf_maximum_benefit(Variable): +class md_tca_maximum_benefit(Variable): value_type = float entity = SPMUnit label = "Maryland TCA maximum benefit" @@ -12,7 +12,7 @@ class md_tanf_maximum_benefit(Variable): def formula(spm_unit, period, parameters): people = spm_unit("spm_unit_size", period.this_year) - p = parameters(period).gov.states.md.tanf.maximum_benefit + p = parameters(period).gov.states.md.tca.maximum_benefit capped_people = min_(people, p.max_unit_size).astype(int) additional_people = people - capped_people base = p.main[capped_people] From 3dee4132a50f3853b51cec68cf385076c3d7fcef Mon Sep 17 00:00:00 2001 From: Ziming Date: Sat, 10 Jan 2026 20:33:43 -0500 Subject: [PATCH 08/10] fix --- changelog_entry.yaml | 2 +- .../deductions/earned/fulltime_hours.yaml | 4 +- .../md/tca/maximum_benefit/additional.yaml | 12 ++++-- .../states/md/tca/maximum_benefit/main.yaml | 42 ++++++++++++++----- .../md/tca/maximum_benefit/max_unit_size.yaml | 4 +- .../gov/states/md/tca/md_tca_eligible.yaml | 20 +++++++++ 6 files changed, 66 insertions(+), 18 deletions(-) diff --git a/changelog_entry.yaml b/changelog_entry.yaml index 7c5fb012b27..bce5b579e5a 100644 --- a/changelog_entry.yaml +++ b/changelog_entry.yaml @@ -1,4 +1,4 @@ - bump: minor changes: added: - - Implement Maryland Temporary Cash Assistance (TFA) program. + - Implement Maryland Temporary Cash Assistance (TCA) program. diff --git a/policyengine_us/parameters/gov/states/md/tca/income/deductions/earned/fulltime_hours.yaml b/policyengine_us/parameters/gov/states/md/tca/income/deductions/earned/fulltime_hours.yaml index 1dc3e39facf..0c8e39ad4f0 100644 --- a/policyengine_us/parameters/gov/states/md/tca/income/deductions/earned/fulltime_hours.yaml +++ b/policyengine_us/parameters/gov/states/md/tca/income/deductions/earned/fulltime_hours.yaml @@ -1,4 +1,4 @@ -description: Maryland requires this number of weekly work hours for full-time classification under the Temporary Cash Assistance program. +description: Maryland requires this number of weekly work hours for full-time classification under the Temporary Cash Assistance program. COMAR defines full-time as 100 hours/month; 25 hours/week is the equivalent assuming 4 weeks per month. values: 2022-11-01: 25 @@ -8,5 +8,5 @@ metadata: period: week label: Maryland TCA full-time work hours threshold reference: - - title: COMAR 07.03.03.13.E(3)(c) - Full-Time Employment Definition + - title: COMAR 07.03.03.13.E(3)(c) - Full-Time Employment (100 hours/month) href: https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx diff --git a/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/additional.yaml b/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/additional.yaml index f28cfce3901..17d4e87a33c 100644 --- a/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/additional.yaml +++ b/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/additional.yaml @@ -1,14 +1,20 @@ description: Maryland provides this additional amount per person for households exceeding the maximum unit size under the Temporary Cash Assistance program. values: - 2021-10-01: 136 + 2017-10-01: 100 + 2018-10-01: 127 + 2019-10-01: 136 metadata: unit: currency-USD period: month label: Maryland TCA additional grant amount per person reference: + - title: FIA Action Transmittal 18-09 (Effective October 1, 2017) + href: https://dhs.maryland.gov/documents/?dir=FIA%2FAction+Transmittals-AT+-+Information+Memo-IM%2FAT-IM2017 + - title: FIA Action Transmittal 19-04 (Effective October 1, 2018) + href: https://dhs.maryland.gov/documents/FIA/Action%20Transmittals-AT%20-%20Information%20Memo-IM/AT-IM2019/19-04-AT-TEMPORARY-CASH-ASSISTANCE-BENEFIT-INCREASE-1.pdf#page=2 + - title: FIA Action Transmittal 20-06 (Effective October 1, 2019) + href: https://dhs.maryland.gov/documents/FIA/Action%20Transmittals-AT%20-%20Information%20Memo-IM/AT-IM2020/20-06%20AT-TCA%20Benefit%20Increase.pdf#page=3 - title: COMAR 07.03.03.17 - Benefit Schedules href: https://dsd.maryland.gov/regulations/Pages/07.03.03.17.aspx - - title: FIA Action Transmittals (TCA benefit updates) - href: https://dhs.maryland.gov/business-center/documents/fia/ diff --git a/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/main.yaml b/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/main.yaml index 7784a5121ef..4735b563ca8 100644 --- a/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/main.yaml +++ b/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/main.yaml @@ -1,21 +1,37 @@ description: Maryland provides this amount as the monthly grant standard under the Temporary Cash Assistance program. 1: - 2021-10-01: 328 + 2017-10-01: 306 + 2018-10-01: 320 + 2019-10-01: 328 2: - 2021-10-01: 575 + 2017-10-01: 536 + 2018-10-01: 561 + 2019-10-01: 575 3: - 2021-10-01: 727 + 2017-10-01: 677 + 2018-10-01: 709 + 2019-10-01: 727 4: - 2021-10-01: 870 + 2017-10-01: 811 + 2018-10-01: 849 + 2019-10-01: 870 5: - 2021-10-01: 1_010 + 2017-10-01: 941 + 2018-10-01: 985 + 2019-10-01: 1_010 6: - 2021-10-01: 1_110 + 2017-10-01: 1_034 + 2018-10-01: 1_083 + 2019-10-01: 1_110 7: - 2021-10-01: 1_247 + 2017-10-01: 1_162 + 2018-10-01: 1_217 + 2019-10-01: 1_247 8: - 2021-10-01: 1_372 + 2017-10-01: 1_279 + 2018-10-01: 1_339 + 2019-10-01: 1_372 metadata: unit: currency-USD @@ -23,8 +39,14 @@ metadata: label: Maryland TCA grant standard breakdown: - range(1, 9) + breakdown_label: + - Assistance unit size reference: + - title: FIA Action Transmittal 18-09 (Effective October 1, 2017) + href: https://dhs.maryland.gov/documents/?dir=FIA%2FAction+Transmittals-AT+-+Information+Memo-IM%2FAT-IM2017 + - title: FIA Action Transmittal 19-04 (Effective October 1, 2018) + href: https://dhs.maryland.gov/documents/FIA/Action%20Transmittals-AT%20-%20Information%20Memo-IM/AT-IM2019/19-04-AT-TEMPORARY-CASH-ASSISTANCE-BENEFIT-INCREASE-1.pdf#page=2 + - title: FIA Action Transmittal 20-06 (Effective October 1, 2019) + href: https://dhs.maryland.gov/documents/FIA/Action%20Transmittals-AT%20-%20Information%20Memo-IM/AT-IM2020/20-06%20AT-TCA%20Benefit%20Increase.pdf#page=3 - title: COMAR 07.03.03.17 - Benefit Schedules href: https://dsd.maryland.gov/regulations/Pages/07.03.03.17.aspx - - title: FIA Action Transmittals (TCA benefit updates) - href: https://dhs.maryland.gov/business-center/documents/fia/ diff --git a/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/max_unit_size.yaml b/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/max_unit_size.yaml index c9d3eff405b..baebe59a834 100644 --- a/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/max_unit_size.yaml +++ b/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/max_unit_size.yaml @@ -8,7 +8,7 @@ metadata: period: year label: Maryland TCA maximum unit size for grant standard lookup reference: + - title: FIA Action Transmittal 20-06 (Effective October 1, 2019) + href: https://dhs.maryland.gov/documents/FIA/Action%20Transmittals-AT%20-%20Information%20Memo-IM/AT-IM2020/20-06%20AT-TCA%20Benefit%20Increase.pdf#page=3 - title: COMAR 07.03.03.17.B - Grant Standard Table href: https://dsd.maryland.gov/regulations/Pages/07.03.03.17.aspx - - title: FIA Action Transmittals (TCA benefit updates) - href: https://dhs.maryland.gov/business-center/documents/fia/ diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tca/md_tca_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tca/md_tca_eligible.yaml index a49eecd3042..45b16b88cd2 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tca/md_tca_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tca/md_tca_eligible.yaml @@ -86,3 +86,23 @@ output: # Per federal TANF rules, 19-year-olds do not count as children md_tca_eligible: false + +- name: Case 6, non-citizen household is not eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + immigration_status: UNDOCUMENTED + person2: + age: 5 + immigration_status: UNDOCUMENTED + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + state_code: MD + output: + # Per COMAR 07.03.17.09 and 8 USC 1641, must be citizen or qualified alien + md_tca_eligible: false From b09bf79394ec856af7b70cca91668cd187ebdb6f Mon Sep 17 00:00:00 2001 From: Ziming Date: Sat, 10 Jan 2026 22:28:47 -0500 Subject: [PATCH 09/10] adjustments --- .../deductions/childcare_expenses/cap.yaml | 21 +++ .../childcare_expenses/full_time.yaml | 12 -- .../childcare_expenses/part_time.yaml | 12 -- .../earned/{new.yaml => applicant.yaml} | 0 .../deductions/earned/fulltime_hours.yaml | 12 -- ...{not_self_employed.yaml => recipient.yaml} | 0 .../md/tca/maximum_benefit/additional.yaml | 5 +- .../states/md/tca/maximum_benefit/main.yaml | 77 +++++++- ...max_unit_size.yaml => max_table_size.yaml} | 6 +- .../md_tca_childcare_deduction.yaml | 164 ++++++++++++++---- .../deductions/md_tca_earnings_deduction.yaml | 54 ------ .../income/md_tca_net_countable_income.yaml | 78 --------- .../md_tca_countable_earned_income.yaml | 96 ++++++++++ .../gov/states/md/tca/integration.yaml | 110 +++++++----- .../baseline/gov/states/md/tca/md_tca.yaml | 8 +- .../states/md/tca/md_tca_income_eligible.yaml | 8 +- .../states/md/tca/md_tca_maximum_benefit.yaml | 8 +- .../tca/{ => eligibility}/md_tca_eligible.py | 0 .../md_tca_income_eligible.py | 6 +- .../deductions/md_tca_childcare_deduction.py | 28 --- .../income/md_tca_net_countable_income.py | 23 --- .../tca/income/md_tca_childcare_deduction.py | 28 +++ ...n.py => md_tca_countable_earned_income.py} | 14 +- .../md/tca/income/md_tca_countable_income.py | 16 ++ .../variables/gov/states/md/tca/md_tca.py | 4 +- .../states/md/tca/md_tca_maximum_benefit.py | 10 +- 26 files changed, 475 insertions(+), 325 deletions(-) create mode 100644 policyengine_us/parameters/gov/states/md/tca/income/deductions/childcare_expenses/cap.yaml delete mode 100644 policyengine_us/parameters/gov/states/md/tca/income/deductions/childcare_expenses/full_time.yaml delete mode 100644 policyengine_us/parameters/gov/states/md/tca/income/deductions/childcare_expenses/part_time.yaml rename policyengine_us/parameters/gov/states/md/tca/income/deductions/earned/{new.yaml => applicant.yaml} (100%) delete mode 100644 policyengine_us/parameters/gov/states/md/tca/income/deductions/earned/fulltime_hours.yaml rename policyengine_us/parameters/gov/states/md/tca/income/deductions/earned/{not_self_employed.yaml => recipient.yaml} (100%) rename policyengine_us/parameters/gov/states/md/tca/maximum_benefit/{max_unit_size.yaml => max_table_size.yaml} (61%) delete mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/tca/income/deductions/md_tca_earnings_deduction.yaml delete mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/tca/income/income/md_tca_net_countable_income.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/tca/income/md_tca_countable_earned_income.yaml rename policyengine_us/variables/gov/states/md/tca/{ => eligibility}/md_tca_eligible.py (100%) rename policyengine_us/variables/gov/states/md/tca/{ => eligibility}/md_tca_income_eligible.py (74%) delete mode 100644 policyengine_us/variables/gov/states/md/tca/income/deductions/md_tca_childcare_deduction.py delete mode 100644 policyengine_us/variables/gov/states/md/tca/income/income/md_tca_net_countable_income.py create mode 100644 policyengine_us/variables/gov/states/md/tca/income/md_tca_childcare_deduction.py rename policyengine_us/variables/gov/states/md/tca/income/{deductions/md_tca_earnings_deduction.py => md_tca_countable_earned_income.py} (55%) create mode 100644 policyengine_us/variables/gov/states/md/tca/income/md_tca_countable_income.py diff --git a/policyengine_us/parameters/gov/states/md/tca/income/deductions/childcare_expenses/cap.yaml b/policyengine_us/parameters/gov/states/md/tca/income/deductions/childcare_expenses/cap.yaml new file mode 100644 index 00000000000..179517c9b42 --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/tca/income/deductions/childcare_expenses/cap.yaml @@ -0,0 +1,21 @@ +description: Maryland caps the monthly childcare deduction at this amount per child under the Temporary Cash Assistance program. + +metadata: + threshold_unit: hour + amount_unit: currency-USD + period: month + type: single_amount + label: Maryland TCA childcare deduction cap + reference: + - title: COMAR 07.03.03.13.E(3)(c) - Childcare Deduction + href: https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx + +brackets: + - threshold: + 2022-11-01: 0 + amount: + 2022-11-01: 100 + - threshold: + 2022-11-01: 100 + amount: + 2022-11-01: 200 diff --git a/policyengine_us/parameters/gov/states/md/tca/income/deductions/childcare_expenses/full_time.yaml b/policyengine_us/parameters/gov/states/md/tca/income/deductions/childcare_expenses/full_time.yaml deleted file mode 100644 index 58b433ef7d0..00000000000 --- a/policyengine_us/parameters/gov/states/md/tca/income/deductions/childcare_expenses/full_time.yaml +++ /dev/null @@ -1,12 +0,0 @@ -description: Maryland provides this monthly childcare deduction for full-time workers under the Temporary Cash Assistance program. - -values: - 2022-11-01: 200 - -metadata: - period: month - unit: currency-USD - label: Maryland TCA childcare deduction for full-time workers - reference: - - title: COMAR 07.03.03.13.E(3)(c)(i) - Childcare Deduction (Full-Time) - href: https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx diff --git a/policyengine_us/parameters/gov/states/md/tca/income/deductions/childcare_expenses/part_time.yaml b/policyengine_us/parameters/gov/states/md/tca/income/deductions/childcare_expenses/part_time.yaml deleted file mode 100644 index 7780c0c99f4..00000000000 --- a/policyengine_us/parameters/gov/states/md/tca/income/deductions/childcare_expenses/part_time.yaml +++ /dev/null @@ -1,12 +0,0 @@ -description: Maryland provides this monthly childcare deduction for part-time workers under the Temporary Cash Assistance program. - -values: - 2022-11-01: 100 - -metadata: - period: month - unit: currency-USD - label: Maryland TCA childcare deduction for part-time workers - reference: - - title: COMAR 07.03.03.13.E(3)(c)(ii) - Childcare Deduction (Part-Time) - href: https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx diff --git a/policyengine_us/parameters/gov/states/md/tca/income/deductions/earned/new.yaml b/policyengine_us/parameters/gov/states/md/tca/income/deductions/earned/applicant.yaml similarity index 100% rename from policyengine_us/parameters/gov/states/md/tca/income/deductions/earned/new.yaml rename to policyengine_us/parameters/gov/states/md/tca/income/deductions/earned/applicant.yaml diff --git a/policyengine_us/parameters/gov/states/md/tca/income/deductions/earned/fulltime_hours.yaml b/policyengine_us/parameters/gov/states/md/tca/income/deductions/earned/fulltime_hours.yaml deleted file mode 100644 index 0c8e39ad4f0..00000000000 --- a/policyengine_us/parameters/gov/states/md/tca/income/deductions/earned/fulltime_hours.yaml +++ /dev/null @@ -1,12 +0,0 @@ -description: Maryland requires this number of weekly work hours for full-time classification under the Temporary Cash Assistance program. COMAR defines full-time as 100 hours/month; 25 hours/week is the equivalent assuming 4 weeks per month. - -values: - 2022-11-01: 25 - -metadata: - unit: hour - period: week - label: Maryland TCA full-time work hours threshold - reference: - - title: COMAR 07.03.03.13.E(3)(c) - Full-Time Employment (100 hours/month) - href: https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx diff --git a/policyengine_us/parameters/gov/states/md/tca/income/deductions/earned/not_self_employed.yaml b/policyengine_us/parameters/gov/states/md/tca/income/deductions/earned/recipient.yaml similarity index 100% rename from policyengine_us/parameters/gov/states/md/tca/income/deductions/earned/not_self_employed.yaml rename to policyengine_us/parameters/gov/states/md/tca/income/deductions/earned/recipient.yaml diff --git a/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/additional.yaml b/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/additional.yaml index 17d4e87a33c..d89a065e862 100644 --- a/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/additional.yaml +++ b/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/additional.yaml @@ -1,9 +1,10 @@ description: Maryland provides this additional amount per person for households exceeding the maximum unit size under the Temporary Cash Assistance program. values: - 2017-10-01: 100 + 2017-10-01: 127 2018-10-01: 127 2019-10-01: 136 + 2025-01-01: 146 metadata: unit: currency-USD @@ -16,5 +17,7 @@ metadata: href: https://dhs.maryland.gov/documents/FIA/Action%20Transmittals-AT%20-%20Information%20Memo-IM/AT-IM2019/19-04-AT-TEMPORARY-CASH-ASSISTANCE-BENEFIT-INCREASE-1.pdf#page=2 - title: FIA Action Transmittal 20-06 (Effective October 1, 2019) href: https://dhs.maryland.gov/documents/FIA/Action%20Transmittals-AT%20-%20Information%20Memo-IM/AT-IM2020/20-06%20AT-TCA%20Benefit%20Increase.pdf#page=3 + - title: FIA Information Memo 25-12 (Effective January 1, 2025) + href: https://dhs.maryland.gov/documents/FIA/Action%20Transmittals-AT%20-%20Information%20Memo-IM/AT-IM2025/25-12%20IM%202025%20TCA%20TDAP%20RCA%20Benefit%20Increase.pdf#page=3 - title: COMAR 07.03.03.17 - Benefit Schedules href: https://dsd.maryland.gov/regulations/Pages/07.03.03.17.aspx diff --git a/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/main.yaml b/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/main.yaml index 4735b563ca8..4954be65373 100644 --- a/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/main.yaml +++ b/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/main.yaml @@ -4,41 +4,114 @@ description: Maryland provides this amount as the monthly grant standard under t 2017-10-01: 306 2018-10-01: 320 2019-10-01: 328 + 2025-01-01: 339 2: 2017-10-01: 536 2018-10-01: 561 2019-10-01: 575 + 2025-01-01: 596 3: 2017-10-01: 677 2018-10-01: 709 2019-10-01: 727 + 2025-01-01: 753 4: 2017-10-01: 811 2018-10-01: 849 2019-10-01: 870 + 2025-01-01: 902 5: 2017-10-01: 941 2018-10-01: 985 2019-10-01: 1_010 + 2025-01-01: 1_046 6: 2017-10-01: 1_034 2018-10-01: 1_083 2019-10-01: 1_110 + 2025-01-01: 1_149 7: 2017-10-01: 1_162 2018-10-01: 1_217 2019-10-01: 1_247 + 2025-01-01: 1_292 8: 2017-10-01: 1_279 2018-10-01: 1_339 2019-10-01: 1_372 + 2025-01-01: 1_421 +9: + 2017-10-01: 1_379 + 2018-10-01: 1_444 + 2019-10-01: 1_480 + 2025-01-01: 1_553 +10: + 2017-10-01: 1_490 + 2018-10-01: 1_560 + 2019-10-01: 1_599 + 2025-01-01: 1_656 +11: + 2017-10-01: 1_625 + 2018-10-01: 1_701 + 2019-10-01: 1_744 + 2025-01-01: 1_806 +12: + 2017-10-01: 1_699 + 2018-10-01: 1_779 + 2019-10-01: 1_823 + 2025-01-01: 1_889 +13: + 2017-10-01: 1_803 + 2018-10-01: 1_888 + 2019-10-01: 1_935 + 2025-01-01: 2_005 +14: + 2017-10-01: 1_908 + 2018-10-01: 1_998 + 2019-10-01: 2_048 + 2025-01-01: 2_122 +15: + 2017-10-01: 2_017 + 2018-10-01: 2_112 + 2019-10-01: 2_165 + 2025-01-01: 2_243 +16: + 2017-10-01: 2_146 + 2018-10-01: 2_247 + 2019-10-01: 2_303 + 2025-01-01: 2_386 +17: + 2017-10-01: 2_274 + 2018-10-01: 2_381 + 2019-10-01: 2_440 + 2025-01-01: 2_605 +18: + 2017-10-01: 2_400 + 2018-10-01: 2_513 + 2019-10-01: 2_576 + 2025-01-01: 2_749 +19: + 2017-10-01: 2_526 + 2018-10-01: 2_645 + 2019-10-01: 2_711 + 2025-01-01: 2_893 +20: + 2017-10-01: 2_652 + 2018-10-01: 2_777 + 2019-10-01: 2_846 + 2025-01-01: 3_037 +21: + 2017-10-01: 2_779 + 2018-10-01: 2_910 + 2019-10-01: 2_983 + 2025-01-01: 3_183 metadata: unit: currency-USD period: month label: Maryland TCA grant standard breakdown: - - range(1, 9) + - range(1, 22) breakdown_label: - Assistance unit size reference: @@ -48,5 +121,7 @@ metadata: href: https://dhs.maryland.gov/documents/FIA/Action%20Transmittals-AT%20-%20Information%20Memo-IM/AT-IM2019/19-04-AT-TEMPORARY-CASH-ASSISTANCE-BENEFIT-INCREASE-1.pdf#page=2 - title: FIA Action Transmittal 20-06 (Effective October 1, 2019) href: https://dhs.maryland.gov/documents/FIA/Action%20Transmittals-AT%20-%20Information%20Memo-IM/AT-IM2020/20-06%20AT-TCA%20Benefit%20Increase.pdf#page=3 + - title: FIA Information Memo 25-12 (Effective January 1, 2025) + href: https://dhs.maryland.gov/documents/FIA/Action%20Transmittals-AT%20-%20Information%20Memo-IM/AT-IM2025/25-12%20IM%202025%20TCA%20TDAP%20RCA%20Benefit%20Increase.pdf#page=3 - title: COMAR 07.03.03.17 - Benefit Schedules href: https://dsd.maryland.gov/regulations/Pages/07.03.03.17.aspx diff --git a/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/max_unit_size.yaml b/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/max_table_size.yaml similarity index 61% rename from policyengine_us/parameters/gov/states/md/tca/maximum_benefit/max_unit_size.yaml rename to policyengine_us/parameters/gov/states/md/tca/maximum_benefit/max_table_size.yaml index baebe59a834..486ed44474e 100644 --- a/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/max_unit_size.yaml +++ b/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/max_table_size.yaml @@ -1,14 +1,16 @@ description: Maryland caps the grant standard lookup at this household size under the Temporary Cash Assistance program. values: - 2021-10-01: 8 + 2017-10-01: 21 metadata: unit: person period: year - label: Maryland TCA maximum unit size for grant standard lookup + label: Maryland TCA maximum table size for grant standard lookup reference: - title: FIA Action Transmittal 20-06 (Effective October 1, 2019) href: https://dhs.maryland.gov/documents/FIA/Action%20Transmittals-AT%20-%20Information%20Memo-IM/AT-IM2020/20-06%20AT-TCA%20Benefit%20Increase.pdf#page=3 + - title: FIA Information Memo 25-12 (Effective January 1, 2025) + href: https://dhs.maryland.gov/documents/FIA/Action%20Transmittals-AT%20-%20Information%20Memo-IM/AT-IM2025/25-12%20IM%202025%20TCA%20TDAP%20RCA%20Benefit%20Increase.pdf#page=3 - title: COMAR 07.03.03.17.B - Grant Standard Table href: https://dsd.maryland.gov/regulations/Pages/07.03.03.17.aspx diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tca/income/deductions/md_tca_childcare_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tca/income/deductions/md_tca_childcare_deduction.yaml index 35b771637e7..1e023ba1a40 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tca/income/deductions/md_tca_childcare_deduction.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tca/income/deductions/md_tca_childcare_deduction.yaml @@ -1,16 +1,18 @@ -# Tests childcare deduction based on work hours and presence of children -# Full-time (>= 25 hrs): $200, Part-time (< 25 hrs): $100, No children: $0 +# Tests childcare deduction capped at actual expenses per COMAR 07.03.03.13.E(3)(c) +# Cap is PER CHILD: Full-time (>= 100 hrs/month): $200/child, Part-time: $100/child +# Deduction = min(actual_expenses, per_child_cap * num_children) -- name: Case 1, no children gets no deduction. +- name: Case 1, no children gets no deduction even with expenses. period: 2024-01 input: people: person1: age: 30 - weekly_hours_worked: 40 + monthly_hours_worked: 160 + pre_subsidy_childcare_expenses: 3_000 person2: age: 28 - weekly_hours_worked: 30 + monthly_hours_worked: 120 spm_units: spm_unit: members: [person1, person2] @@ -18,15 +20,17 @@ household: state_code: MD output: + # No children = $0 cap md_tca_childcare_deduction: 0 -- name: Case 2, has child with part-time work. +- name: Case 2, one child with part-time work, expenses at cap. period: 2024-01 input: people: person1: age: 30 - weekly_hours_worked: 20 + monthly_hours_worked: 80 + pre_subsidy_childcare_expenses: 2_400 person2: age: 5 spm_units: @@ -36,16 +40,18 @@ household: state_code: MD output: - # Part-time (< 25 hrs) = $100 + # 1 child * $100 (part-time, 80 hrs < 100) = $100 cap + # Expenses = $200/month, min($200, $100) = $100 md_tca_childcare_deduction: 100 -- name: Case 3, has child with full-time work. +- name: Case 3, one child with full-time work, expenses at cap. period: 2024-01 input: people: person1: age: 30 - weekly_hours_worked: 30 + monthly_hours_worked: 120 + pre_subsidy_childcare_expenses: 6_000 person2: age: 5 spm_units: @@ -55,18 +61,20 @@ household: state_code: MD output: - # Full-time (>= 25 hrs) = $200 + # 1 child * $200 (full-time, 120 hrs >= 100) = $200 cap + # Expenses = $500/month, min($500, $200) = $200 md_tca_childcare_deduction: 200 -- name: Case 4, exactly 25 hours threshold. +- name: Case 4, one child, expenses below full-time cap. period: 2024-01 input: people: person1: age: 30 - weekly_hours_worked: 25 + monthly_hours_worked: 120 + pre_subsidy_childcare_expenses: 1_200 person2: - age: 10 + age: 5 spm_units: spm_unit: members: [person1, person2] @@ -74,18 +82,20 @@ household: state_code: MD output: - # Exactly at threshold (>= 25 hrs) = full-time rate - md_tca_childcare_deduction: 200 + # 1 child * $200 = $200 cap + # Expenses = $100/month, min($100, $200) = $100 + md_tca_childcare_deduction: 100 -- name: Case 5, at 24 hours below threshold. +- name: Case 5, one child, expenses below part-time cap. period: 2024-01 input: people: person1: age: 30 - weekly_hours_worked: 24 + monthly_hours_worked: 80 + pre_subsidy_childcare_expenses: 600 person2: - age: 10 + age: 5 spm_units: spm_unit: members: [person1, person2] @@ -93,16 +103,17 @@ household: state_code: MD output: - # Below threshold (< 25 hrs) = part-time rate - md_tca_childcare_deduction: 100 + # 1 child * $100 = $100 cap + # Expenses = $50/month, min($50, $100) = $50 + md_tca_childcare_deduction: 50 -- name: Case 6, has child but zero work hours. +- name: Case 6, has child but zero expenses. period: 2024-01 input: people: person1: age: 30 - weekly_hours_worked: 0 + monthly_hours_worked: 120 person2: age: 5 spm_units: @@ -112,19 +123,19 @@ household: state_code: MD output: - # Zero hours = part-time rate - md_tca_childcare_deduction: 100 + # 1 child * $200 = $200 cap, but expenses = $0 + md_tca_childcare_deduction: 0 -- name: Case 7, multiple adults with one full-time. +- name: Case 7, two children with full-time work. period: 2024-01 input: people: person1: age: 30 - weekly_hours_worked: 30 + monthly_hours_worked: 120 + pre_subsidy_childcare_expenses: 6_000 person2: - age: 28 - weekly_hours_worked: 10 + age: 8 person3: age: 5 spm_units: @@ -134,5 +145,98 @@ household: state_code: MD output: - # Any member >= 25 hrs = full-time rate + # 2 children * $200 = $400 cap + # Expenses = $500/month, min($500, $400) = $400 + md_tca_childcare_deduction: 400 + +- name: Case 8, two children with part-time work. + period: 2024-01 + input: + people: + person1: + age: 30 + monthly_hours_worked: 80 + pre_subsidy_childcare_expenses: 3_600 + person2: + age: 8 + person3: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + state_code: MD + output: + # 2 children * $100 = $200 cap + # Expenses = $300/month, min($300, $200) = $200 md_tca_childcare_deduction: 200 + +- name: Case 9, three children, expenses below cap. + period: 2024-01 + input: + people: + person1: + age: 30 + monthly_hours_worked: 120 + pre_subsidy_childcare_expenses: 4_800 + person2: + age: 10 + person3: + age: 7 + person4: + age: 4 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + households: + household: + state_code: MD + output: + # 3 children * $200 = $600 cap + # Expenses = $400/month, min($400, $600) = $400 + md_tca_childcare_deduction: 400 + +- name: Case 10, exactly at 100 hours/month threshold. + period: 2024-01 + input: + people: + person1: + age: 30 + monthly_hours_worked: 100 + pre_subsidy_childcare_expenses: 3_600 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + state_code: MD + output: + # 100 hrs/month = full-time threshold + # 1 child * $200 = $200 cap + # Expenses = $300/month, min($300, $200) = $200 + md_tca_childcare_deduction: 200 + +- name: Case 11, just below 100 hours/month threshold. + period: 2024-01 + input: + people: + person1: + age: 30 + monthly_hours_worked: 96 + pre_subsidy_childcare_expenses: 3_600 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + state_code: MD + output: + # 96 hrs/month = part-time (below 100 threshold) + # 1 child * $100 = $100 cap + # Expenses = $300/month, min($300, $100) = $100 + md_tca_childcare_deduction: 100 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tca/income/deductions/md_tca_earnings_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tca/income/deductions/md_tca_earnings_deduction.yaml deleted file mode 100644 index 8391bad48b2..00000000000 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tca/income/deductions/md_tca_earnings_deduction.yaml +++ /dev/null @@ -1,54 +0,0 @@ -# Tests merged earnings deduction using is_tanf_enrolled -# Not enrolled: 20% rate, Enrolled: 40% rate - -- name: Case 1, not enrolled gets 20% deduction. - period: 2024-01 - input: - people: - person1: - age: 30 - employment_income_before_lsr: 12_000 - spm_units: - spm_unit: - members: [person1] - is_tanf_enrolled: false - households: - household: - state_code: MD - output: - # $12,000/12 = $1,000/month * 0.20 = $200 - md_tca_earnings_deduction: 200 - -- name: Case 2, enrolled gets 40% deduction. - period: 2024-01 - input: - people: - person1: - age: 30 - employment_income_before_lsr: 12_000 - spm_units: - spm_unit: - members: [person1] - is_tanf_enrolled: true - households: - household: - state_code: MD - output: - # $12,000/12 = $1,000/month * 0.40 = $400 - md_tca_earnings_deduction: 400 - -- name: Case 3, zero income. - period: 2024-01 - input: - people: - person1: - age: 30 - spm_units: - spm_unit: - members: [person1] - is_tanf_enrolled: true - households: - household: - state_code: MD - output: - md_tca_earnings_deduction: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tca/income/income/md_tca_net_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tca/income/income/md_tca_net_countable_income.yaml deleted file mode 100644 index b4a52bc1072..00000000000 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tca/income/income/md_tca_net_countable_income.yaml +++ /dev/null @@ -1,78 +0,0 @@ -# Tests net countable income calculation -# Formula: max(gross_earned - earnings_deduction - childcare, 0) + unearned - -- name: Case 1, earned income minus deductions. - period: 2024-01 - input: - people: - person1: - age: 30 - employment_income_before_lsr: 12_000 - spm_units: - spm_unit: - members: [person1] - md_tca_earnings_deduction: 400 - md_tca_childcare_deduction: 0 - households: - household: - state_code: MD - output: - # max($1,000 - $400 - $0, 0) + $0 = $600 - md_tca_net_countable_income: 600 - -- name: Case 2, earned and unearned income minus deductions. - period: 2024-01 - input: - people: - person1: - age: 30 - employment_income_before_lsr: 12_000 - social_security: 6_000 - spm_units: - spm_unit: - members: [person1] - md_tca_earnings_deduction: 400 - md_tca_childcare_deduction: 100 - households: - household: - state_code: MD - output: - # max($1,000 - $400 - $100, 0) + $500 = $500 + $500 = $1,000 - md_tca_net_countable_income: 1_000 - -- name: Case 3, deductions exceed earned income. - period: 2024-01 - input: - people: - person1: - age: 30 - employment_income_before_lsr: 2_400 - social_security: 3_600 - spm_units: - spm_unit: - members: [person1] - md_tca_earnings_deduction: 100 - md_tca_childcare_deduction: 200 - households: - household: - state_code: MD - output: - # max($200 - $100 - $200, 0) + $300 = $0 + $300 = $300 - md_tca_net_countable_income: 300 - -- name: Case 4, zero income. - period: 2024-01 - input: - people: - person1: - age: 30 - spm_units: - spm_unit: - members: [person1] - md_tca_earnings_deduction: 0 - md_tca_childcare_deduction: 0 - households: - household: - state_code: MD - output: - md_tca_net_countable_income: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tca/income/md_tca_countable_earned_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tca/income/md_tca_countable_earned_income.yaml new file mode 100644 index 00000000000..505a684b28d --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tca/income/md_tca_countable_earned_income.yaml @@ -0,0 +1,96 @@ +# Tests countable earned income calculation +# Formula: max(gross_earned * (1 - rate) - childcare_deduction, 0) +# Rate: 20% for applicants, 40% for enrolled recipients + +- name: Case 1, enrolled recipient with no childcare. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 12_000 + spm_units: + spm_unit: + members: [person1] + is_tanf_enrolled: true + md_tca_childcare_deduction: 0 + households: + household: + state_code: MD + output: + # $1,000 * (1 - 0.4) - $0 = $600 + md_tca_countable_earned_income: 600 + +- name: Case 2, applicant with no childcare. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 12_000 + spm_units: + spm_unit: + members: [person1] + is_tanf_enrolled: false + md_tca_childcare_deduction: 0 + households: + household: + state_code: MD + output: + # $1,000 * (1 - 0.2) - $0 = $800 + md_tca_countable_earned_income: 800 + +- name: Case 3, enrolled with childcare deduction. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 12_000 + spm_units: + spm_unit: + members: [person1] + is_tanf_enrolled: true + md_tca_childcare_deduction: 200 + households: + household: + state_code: MD + output: + # $1,000 * (1 - 0.4) - $200 = $600 - $200 = $400 + md_tca_countable_earned_income: 400 + +- name: Case 4, childcare exceeds after-disregard amount. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 6_000 + spm_units: + spm_unit: + members: [person1] + is_tanf_enrolled: true + md_tca_childcare_deduction: 400 + households: + household: + state_code: MD + output: + # $500 * (1 - 0.4) - $400 = $300 - $400 = max(-$100, 0) = $0 + md_tca_countable_earned_income: 0 + +- name: Case 5, zero income. + period: 2024-01 + input: + people: + person1: + age: 30 + spm_units: + spm_unit: + members: [person1] + is_tanf_enrolled: true + md_tca_childcare_deduction: 0 + households: + household: + state_code: MD + output: + md_tca_countable_earned_income: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tca/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tca/integration.yaml index abe3885f2dd..77fce67d576 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tca/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tca/integration.yaml @@ -2,14 +2,15 @@ # COMAR 07.03.03 - Temporary Cash Assistance # Tests verify complete calculation pipeline with documented intermediate values -- name: Case 1, single parent with child, enrolled. +- name: Case 1, single parent with child, enrolled, with childcare expenses. period: 2024-01 input: people: person1: age: 30 employment_income_before_lsr: 12_000 - weekly_hours_worked: 30 + monthly_hours_worked: 120 + pre_subsidy_childcare_expenses: 6_000 person2: age: 5 spm_units: @@ -20,16 +21,16 @@ household: state_code: MD output: - # Earnings deduction (enrolled = 40%) - # $1,000 * 0.40 = $400 - md_tca_earnings_deduction: 400 - - # Childcare deduction (30 hrs >= 25 = full-time = $200) + # 1 child * $200/child (120 hrs >= 100 = full-time) = $200 cap + # Expenses = $500/month, min($500, $200) = $200 md_tca_childcare_deduction: 200 - # Net countable income - # max($1,000 - $400 - $200, 0) + $0 unearned = $400 - md_tca_net_countable_income: 400 + # Countable earned income (enrolled = 60% kept) + # $1,000 * 0.6 - $200 = $400 + md_tca_countable_earned_income: 400 + + # Countable income = $400 earned + $0 unearned = $400 + md_tca_countable_income: 400 # Maximum benefit (2-person household) md_tca_maximum_benefit: 575 @@ -42,14 +43,15 @@ # max($575 - $400, 0) = $175 md_tca: 175 -- name: Case 2, single parent with child, not enrolled. +- name: Case 2, single parent with child, not enrolled, with childcare expenses. period: 2024-01 input: people: person1: age: 30 employment_income_before_lsr: 12_000 - weekly_hours_worked: 30 + monthly_hours_worked: 120 + pre_subsidy_childcare_expenses: 6_000 person2: age: 5 spm_units: @@ -60,16 +62,16 @@ household: state_code: MD output: - # Earnings deduction (not enrolled = 20%) - # $1,000 * 0.20 = $200 - md_tca_earnings_deduction: 200 - - # Childcare deduction (full-time) + # 1 child * $200/child (full-time) = $200 cap + # Expenses = $500/month, min($500, $200) = $200 md_tca_childcare_deduction: 200 - # Net countable income - # max($1,000 - $200 - $200, 0) = $600 - md_tca_net_countable_income: 600 + # Countable earned income (not enrolled = 80% kept) + # $1,000 * 0.8 - $200 = $600 + md_tca_countable_earned_income: 600 + + # Countable income = $600 earned + $0 unearned = $600 + md_tca_countable_income: 600 # Maximum benefit md_tca_maximum_benefit: 575 @@ -81,18 +83,19 @@ md_tca: 0 -- name: Case 3, multiple earners with child. +- name: Case 3, multiple earners with child, with childcare expenses. period: 2024-01 input: people: person1: age: 30 employment_income_before_lsr: 24_000 - weekly_hours_worked: 40 + monthly_hours_worked: 160 + pre_subsidy_childcare_expenses: 6_000 person2: age: 35 employment_income_before_lsr: 12_000 - weekly_hours_worked: 30 + monthly_hours_worked: 120 person3: age: 5 spm_units: @@ -107,14 +110,16 @@ # Person2: $12,000/12 = $1,000/month # Total: $3,000/month - # 40% deduction: $3,000 * 0.40 = $1,200 - md_tca_earnings_deduction: 1_200 - - # Full-time (40 hrs) + # 1 child * $200/child (160 hrs full-time) = $200 cap + # Expenses = $500/month, min($500, $200) = $200 md_tca_childcare_deduction: 200 - # max($3,000 - $1,200 - $200, 0) = $1,600 - md_tca_net_countable_income: 1_600 + # Countable earned income (enrolled = 60% kept) + # $3,000 * 0.6 - $200 = $1,600 + md_tca_countable_earned_income: 1_600 + + # Countable income = $1,600 earned + $0 unearned = $1,600 + md_tca_countable_income: 1_600 # 3-person household md_tca_maximum_benefit: 727 @@ -126,16 +131,16 @@ md_tca: 0 -- name: Case 4, large household at size cap. +- name: Case 4, large household at size cap, no childcare expenses. period: 2024-01 input: people: person1: age: 35 - weekly_hours_worked: 0 + monthly_hours_worked: 0 person2: age: 33 - weekly_hours_worked: 0 + monthly_hours_worked: 0 person3: age: 14 person4: @@ -156,12 +161,12 @@ household: state_code: MD output: - md_tca_earnings_deduction: 0 + # No childcare expenses = $0 deduction + md_tca_childcare_deduction: 0 - # Part-time rate (no work hours) - md_tca_childcare_deduction: 100 + md_tca_countable_earned_income: 0 - md_tca_net_countable_income: 0 + md_tca_countable_income: 0 # 8-person household = maximum in table md_tca_maximum_benefit: 1_372 @@ -171,13 +176,14 @@ md_tca: 1_372 -- name: Case 5, zero income receives full benefit. +- name: Case 5, zero income with childcare expenses receives full benefit. period: 2024-01 input: people: person1: age: 30 - weekly_hours_worked: 0 + monthly_hours_worked: 0 + pre_subsidy_childcare_expenses: 2_400 person2: age: 5 spm_units: @@ -188,9 +194,14 @@ household: state_code: MD output: - md_tca_earnings_deduction: 0 + # 1 child * $100/child (0 hrs < 100 = part-time) = $100 cap + # Expenses = $200/month, min($200, $100) = $100 md_tca_childcare_deduction: 100 - md_tca_net_countable_income: 0 + + # No earned income, so countable earned = max(0 - 100, 0) = 0 + md_tca_countable_earned_income: 0 + + md_tca_countable_income: 0 md_tca_maximum_benefit: 575 @@ -222,12 +233,14 @@ md_tca: 0 -- name: Case 7, 10 person household above size cap. +- name: Case 7, 10 person household above size cap, with childcare expenses. period: 2024-01 input: people: person1: age: 35 + monthly_hours_worked: 120 + pre_subsidy_childcare_expenses: 6_000 person2: age: 33 person3: @@ -254,9 +267,18 @@ household: state_code: MD output: - # 10-person household = $1,372 (8-person) + 2 * $136 = $1,644 - md_tca_maximum_benefit: 1_644 + # 8 children * $200/child (120 hrs full-time) = $1,600 cap + # Expenses = $500/month, min($500, $1,600) = $500 + md_tca_childcare_deduction: 500 + + # No earned income + md_tca_countable_earned_income: 0 + + md_tca_countable_income: 0 + + # 10-person household = $1,599 (explicit table value) + md_tca_maximum_benefit: 1_599 md_tca_eligible: true - md_tca: 1_644 + md_tca: 1_599 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tca/md_tca.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tca/md_tca.yaml index ca26ed4a837..adc9a1960ff 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tca/md_tca.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tca/md_tca.yaml @@ -9,7 +9,7 @@ members: [person1] md_tca_eligible: true md_tca_maximum_benefit: 727 - md_tca_net_countable_income: 200 + md_tca_countable_income: 200 households: household: state_code: MD @@ -28,7 +28,7 @@ members: [person1] md_tca_eligible: true md_tca_maximum_benefit: 575 - md_tca_net_countable_income: 0 + md_tca_countable_income: 0 households: household: state_code: MD @@ -47,7 +47,7 @@ members: [person1] md_tca_eligible: true md_tca_maximum_benefit: 575 - md_tca_net_countable_income: 600 + md_tca_countable_income: 600 households: household: state_code: MD @@ -66,7 +66,7 @@ members: [person1] md_tca_eligible: false md_tca_maximum_benefit: 575 - md_tca_net_countable_income: 0 + md_tca_countable_income: 0 households: household: state_code: MD diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tca/md_tca_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tca/md_tca_income_eligible.yaml index 0452e40b64b..f6c43ce89a7 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tca/md_tca_income_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tca/md_tca_income_eligible.yaml @@ -9,7 +9,7 @@ spm_units: spm_unit: members: [person1] - md_tca_net_countable_income: 300 + md_tca_countable_income: 300 md_tca_maximum_benefit: 575 households: household: @@ -27,7 +27,7 @@ spm_units: spm_unit: members: [person1] - md_tca_net_countable_income: 575 + md_tca_countable_income: 575 md_tca_maximum_benefit: 575 households: household: @@ -45,7 +45,7 @@ spm_units: spm_unit: members: [person1] - md_tca_net_countable_income: 600 + md_tca_countable_income: 600 md_tca_maximum_benefit: 575 households: household: @@ -63,7 +63,7 @@ spm_units: spm_unit: members: [person1] - md_tca_net_countable_income: 0 + md_tca_countable_income: 0 md_tca_maximum_benefit: 575 households: household: diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tca/md_tca_maximum_benefit.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tca/md_tca_maximum_benefit.yaml index 5f29e04b904..1113014fa5a 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tca/md_tca_maximum_benefit.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tca/md_tca_maximum_benefit.yaml @@ -47,8 +47,8 @@ household: state_code: MD output: - # $1,372 (8-person max) + 2 * $136 = $1,644 per month - md_tca_maximum_benefit: 1_644 + # $1,599 per month (explicit table value for 10-person household) + md_tca_maximum_benefit: 1_599 - name: Case 3, exactly at cap (8 persons). period: 2024-01 @@ -111,5 +111,5 @@ household: state_code: MD output: - # $1,372 (8-person) + $136 (1 additional) = $1,508 - md_tca_maximum_benefit: 1_508 + # $1,480 per month (explicit table value for 9-person household) + md_tca_maximum_benefit: 1_480 diff --git a/policyengine_us/variables/gov/states/md/tca/md_tca_eligible.py b/policyengine_us/variables/gov/states/md/tca/eligibility/md_tca_eligible.py similarity index 100% rename from policyengine_us/variables/gov/states/md/tca/md_tca_eligible.py rename to policyengine_us/variables/gov/states/md/tca/eligibility/md_tca_eligible.py diff --git a/policyengine_us/variables/gov/states/md/tca/md_tca_income_eligible.py b/policyengine_us/variables/gov/states/md/tca/eligibility/md_tca_income_eligible.py similarity index 74% rename from policyengine_us/variables/gov/states/md/tca/md_tca_income_eligible.py rename to policyengine_us/variables/gov/states/md/tca/eligibility/md_tca_income_eligible.py index 452561bf60b..809cb086495 100644 --- a/policyengine_us/variables/gov/states/md/tca/md_tca_income_eligible.py +++ b/policyengine_us/variables/gov/states/md/tca/eligibility/md_tca_income_eligible.py @@ -11,7 +11,7 @@ class md_tca_income_eligible(Variable): def formula(spm_unit, period, parameters): # Per COMAR 07.03.03.13, eligibility is based on comparing - # net countable income to the grant standard - net_income = spm_unit("md_tca_net_countable_income", period) + # countable income to the grant standard + countable_income = spm_unit("md_tca_countable_income", period) grant_standard = spm_unit("md_tca_maximum_benefit", period) - return net_income <= grant_standard + return countable_income <= grant_standard diff --git a/policyengine_us/variables/gov/states/md/tca/income/deductions/md_tca_childcare_deduction.py b/policyengine_us/variables/gov/states/md/tca/income/deductions/md_tca_childcare_deduction.py deleted file mode 100644 index 033e9fd1f8c..00000000000 --- a/policyengine_us/variables/gov/states/md/tca/income/deductions/md_tca_childcare_deduction.py +++ /dev/null @@ -1,28 +0,0 @@ -from policyengine_us.model_api import * - - -class md_tca_childcare_deduction(Variable): - value_type = float - entity = SPMUnit - label = "Maryland TCA childcare deduction" - unit = USD - definition_period = MONTH - defined_for = StateCode.MD - reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx" - - def formula(spm_unit, period, parameters): - # Per COMAR 07.03.03.13, childcare deduction is only available - # for households with children. The deduction is based on the - # employment hours of the assistance unit member. - has_children = spm_unit("is_demographic_tanf_eligible", period) - person = spm_unit.members - work_hours = person("weekly_hours_worked", period.this_year) - p = parameters(period).gov.states.md.tca.income.deductions - full_time = spm_unit.any(work_hours >= p.earned.fulltime_hours) - - deduction = where( - full_time, - p.childcare_expenses.full_time, - p.childcare_expenses.part_time, - ) - return where(has_children, deduction, 0) diff --git a/policyengine_us/variables/gov/states/md/tca/income/income/md_tca_net_countable_income.py b/policyengine_us/variables/gov/states/md/tca/income/income/md_tca_net_countable_income.py deleted file mode 100644 index 623652a7607..00000000000 --- a/policyengine_us/variables/gov/states/md/tca/income/income/md_tca_net_countable_income.py +++ /dev/null @@ -1,23 +0,0 @@ -from policyengine_us.model_api import * - - -class md_tca_net_countable_income(Variable): - value_type = float - entity = SPMUnit - label = "Maryland TCA net countable income" - unit = USD - definition_period = MONTH - defined_for = StateCode.MD - reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx" - - def formula(spm_unit, period, parameters): - gross_earned = add(spm_unit, period, ["tanf_gross_earned_income"]) - gross_unearned = add(spm_unit, period, ["tanf_gross_unearned_income"]) - earnings_deduction = spm_unit("md_tca_earnings_deduction", period) - childcare_deduction = spm_unit("md_tca_childcare_deduction", period) - # Apply deductions to earned income only, then add unearned - countable_earned = max_( - gross_earned - earnings_deduction - childcare_deduction, - 0, - ) - return countable_earned + gross_unearned diff --git a/policyengine_us/variables/gov/states/md/tca/income/md_tca_childcare_deduction.py b/policyengine_us/variables/gov/states/md/tca/income/md_tca_childcare_deduction.py new file mode 100644 index 00000000000..42ea29e8c0e --- /dev/null +++ b/policyengine_us/variables/gov/states/md/tca/income/md_tca_childcare_deduction.py @@ -0,0 +1,28 @@ +from policyengine_us.model_api import * + + +class md_tca_childcare_deduction(Variable): + value_type = float + entity = SPMUnit + label = "Maryland TCA childcare deduction" + unit = USD + definition_period = MONTH + defined_for = StateCode.MD + reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx" + + def formula(spm_unit, period, parameters): + # Per COMAR 07.03.03.13.E(3)(c), childcare deduction is capped at + # actual expenses, "not to exceed" per child based on employment + # hours: $200/child for 100+ hours/month, $100/child for <100 hours. + person = spm_unit.members + is_child = person("is_child", period.this_year) + num_children = spm_unit.sum(is_child) + monthly_hours = person("monthly_hours_worked", period.this_year) + max_monthly_hours = spm_unit.max(monthly_hours) + p = parameters(period).gov.states.md.tca.income.deductions + # Maximum deduction per child based on monthly work hours + per_child_cap = p.childcare_expenses.cap.calc(max_monthly_hours) + max_deduction = per_child_cap * num_children + # Actual childcare expenses (capped at regulatory maximum) + childcare_expenses = spm_unit("childcare_expenses", period) + return min_(childcare_expenses, max_deduction) diff --git a/policyengine_us/variables/gov/states/md/tca/income/deductions/md_tca_earnings_deduction.py b/policyengine_us/variables/gov/states/md/tca/income/md_tca_countable_earned_income.py similarity index 55% rename from policyengine_us/variables/gov/states/md/tca/income/deductions/md_tca_earnings_deduction.py rename to policyengine_us/variables/gov/states/md/tca/income/md_tca_countable_earned_income.py index bf45ae6e911..e8056c00766 100644 --- a/policyengine_us/variables/gov/states/md/tca/income/deductions/md_tca_earnings_deduction.py +++ b/policyengine_us/variables/gov/states/md/tca/income/md_tca_countable_earned_income.py @@ -1,10 +1,10 @@ from policyengine_us.model_api import * -class md_tca_earnings_deduction(Variable): +class md_tca_countable_earned_income(Variable): value_type = float entity = SPMUnit - label = "Maryland TCA earnings deduction" + label = "Maryland TCA countable earned income" unit = USD definition_period = MONTH defined_for = StateCode.MD @@ -15,8 +15,10 @@ def formula(spm_unit, period, parameters): # vs regular employment. We apply the employment rate to all earned # income as a simplification. p = parameters(period).gov.states.md.tca.income.deductions.earned - earned_income = add(spm_unit, period, ["tanf_gross_earned_income"]) + gross_earned = add(spm_unit, period, ["tanf_gross_earned_income"]) is_enrolled = spm_unit("is_tanf_enrolled", period) - # 20% for new applicants, 40% for enrolled recipients - rate = where(is_enrolled, p.not_self_employed, p.new) - return earned_income * rate + # 20% disregard for applicants, 40% disregard for enrolled recipients + rate = where(is_enrolled, p.recipient, p.applicant) + after_disregard = gross_earned * (1 - rate) + childcare_deduction = spm_unit("md_tca_childcare_deduction", period) + return max_(after_disregard - childcare_deduction, 0) diff --git a/policyengine_us/variables/gov/states/md/tca/income/md_tca_countable_income.py b/policyengine_us/variables/gov/states/md/tca/income/md_tca_countable_income.py new file mode 100644 index 00000000000..3bf6b422bac --- /dev/null +++ b/policyengine_us/variables/gov/states/md/tca/income/md_tca_countable_income.py @@ -0,0 +1,16 @@ +from policyengine_us.model_api import * + + +class md_tca_countable_income(Variable): + value_type = float + entity = SPMUnit + label = "Maryland TCA countable income" + unit = USD + definition_period = MONTH + defined_for = StateCode.MD + reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.13.aspx" + + adds = [ + "md_tca_countable_earned_income", + "tanf_gross_unearned_income", + ] diff --git a/policyengine_us/variables/gov/states/md/tca/md_tca.py b/policyengine_us/variables/gov/states/md/tca/md_tca.py index 259c1770a71..f8e1b2c5844 100644 --- a/policyengine_us/variables/gov/states/md/tca/md_tca.py +++ b/policyengine_us/variables/gov/states/md/tca/md_tca.py @@ -12,5 +12,5 @@ class md_tca(Variable): def formula(spm_unit, period, parameters): grant_standard = spm_unit("md_tca_maximum_benefit", period) - income = spm_unit("md_tca_net_countable_income", period) - return max_(grant_standard - income, 0) + countable_income = spm_unit("md_tca_countable_income", period) + return max_(grant_standard - countable_income, 0) diff --git a/policyengine_us/variables/gov/states/md/tca/md_tca_maximum_benefit.py b/policyengine_us/variables/gov/states/md/tca/md_tca_maximum_benefit.py index 33e80a340e3..eaa974b3510 100644 --- a/policyengine_us/variables/gov/states/md/tca/md_tca_maximum_benefit.py +++ b/policyengine_us/variables/gov/states/md/tca/md_tca_maximum_benefit.py @@ -11,9 +11,9 @@ class md_tca_maximum_benefit(Variable): reference = "https://dsd.maryland.gov/regulations/Pages/07.03.03.17.aspx" def formula(spm_unit, period, parameters): - people = spm_unit("spm_unit_size", period.this_year) + size = spm_unit("spm_unit_size", period.this_year) p = parameters(period).gov.states.md.tca.maximum_benefit - capped_people = min_(people, p.max_unit_size).astype(int) - additional_people = people - capped_people - base = p.main[capped_people] - return base + p.additional * additional_people + capped_size = min_(size, p.max_table_size) + additional_size = size - capped_size + base = p.main[capped_size] + return base + p.additional * additional_size From 8c78c7a2e20197d4c7c9afcf98fe120d6daa79ec Mon Sep 17 00:00:00 2001 From: Ziming Date: Sat, 10 Jan 2026 22:38:44 -0500 Subject: [PATCH 10/10] minor --- .../deductions/childcare_expenses/cap.yaml | 8 +- .../income/deductions/earned/applicant.yaml | 4 +- .../income/deductions/earned/recipient.yaml | 4 +- .../md/tca/maximum_benefit/additional.yaml | 2 +- .../tca/maximum_benefit/max_table_size.yaml | 2 +- .../states/md/tca/md_tca_maximum_benefit.yaml | 112 ++++-------------- .../md/tca/eligibility/md_tca_eligible.py | 5 +- 7 files changed, 33 insertions(+), 104 deletions(-) diff --git a/policyengine_us/parameters/gov/states/md/tca/income/deductions/childcare_expenses/cap.yaml b/policyengine_us/parameters/gov/states/md/tca/income/deductions/childcare_expenses/cap.yaml index 179517c9b42..3ca87928dec 100644 --- a/policyengine_us/parameters/gov/states/md/tca/income/deductions/childcare_expenses/cap.yaml +++ b/policyengine_us/parameters/gov/states/md/tca/income/deductions/childcare_expenses/cap.yaml @@ -12,10 +12,10 @@ metadata: brackets: - threshold: - 2022-11-01: 0 + 2016-01-01: 0 amount: - 2022-11-01: 100 + 2016-01-01: 100 - threshold: - 2022-11-01: 100 + 2016-01-01: 100 amount: - 2022-11-01: 200 + 2016-01-01: 200 diff --git a/policyengine_us/parameters/gov/states/md/tca/income/deductions/earned/applicant.yaml b/policyengine_us/parameters/gov/states/md/tca/income/deductions/earned/applicant.yaml index 1f5006176c9..97be1a3e827 100644 --- a/policyengine_us/parameters/gov/states/md/tca/income/deductions/earned/applicant.yaml +++ b/policyengine_us/parameters/gov/states/md/tca/income/deductions/earned/applicant.yaml @@ -1,7 +1,7 @@ -description: Maryland excludes this share of earnings from countable earned income under the Temporary Cash Assistance program for individuals not currently enrolled. +description: Maryland excludes this share of earnings from countable earned income under the Temporary Cash Assistance program. values: - 2022-11-01: 0.2 + 2016-01-01: 0.2 metadata: unit: /1 diff --git a/policyengine_us/parameters/gov/states/md/tca/income/deductions/earned/recipient.yaml b/policyengine_us/parameters/gov/states/md/tca/income/deductions/earned/recipient.yaml index 744b96a5710..bfce7489802 100644 --- a/policyengine_us/parameters/gov/states/md/tca/income/deductions/earned/recipient.yaml +++ b/policyengine_us/parameters/gov/states/md/tca/income/deductions/earned/recipient.yaml @@ -1,7 +1,7 @@ -description: Maryland excludes this share of earnings from countable earned income under the Temporary Cash Assistance program for enrolled recipients without self-employment income. +description: Maryland excludes this share of earnings from countable earned income under the Temporary Cash Assistance program. values: - 2022-11-01: 0.4 + 2016-01-01: 0.4 metadata: unit: /1 diff --git a/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/additional.yaml b/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/additional.yaml index d89a065e862..3d4c40760fa 100644 --- a/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/additional.yaml +++ b/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/additional.yaml @@ -1,4 +1,4 @@ -description: Maryland provides this additional amount per person for households exceeding the maximum unit size under the Temporary Cash Assistance program. +description: Maryland provides this additional amount per person under the Temporary Cash Assistance program. values: 2017-10-01: 127 diff --git a/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/max_table_size.yaml b/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/max_table_size.yaml index 486ed44474e..f699dc9f7f2 100644 --- a/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/max_table_size.yaml +++ b/policyengine_us/parameters/gov/states/md/tca/maximum_benefit/max_table_size.yaml @@ -1,7 +1,7 @@ description: Maryland caps the grant standard lookup at this household size under the Temporary Cash Assistance program. values: - 2017-10-01: 21 + 2016-10-01: 21 metadata: unit: person diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tca/md_tca_maximum_benefit.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tca/md_tca_maximum_benefit.yaml index 1113014fa5a..ffff1241582 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tca/md_tca_maximum_benefit.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tca/md_tca_maximum_benefit.yaml @@ -1,16 +1,8 @@ - name: Case 1, one-person household. period: 2024-01 input: - people: - person1: - age: 30 - spm_units: - spm_unit: - members: [person1] - md_tca_eligible: true - households: - household: - state_code: MD + spm_unit_size: 1 + state_code: MD output: # $328 per month md_tca_maximum_benefit: 328 @@ -18,98 +10,36 @@ - name: Case 2, ten-person household. period: 2024-01 input: - people: - person1: - age: 30 - person2: - age: 28 - person3: - age: 10 - person4: - age: 8 - person5: - age: 6 - person6: - age: 5 - person7: - age: 4 - person8: - age: 3 - person9: - age: 2 - person10: - age: 1 - spm_units: - spm_unit: - members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10] - md_tca_eligible: true - households: - household: - state_code: MD + spm_unit_size: 10 + state_code: MD output: # $1,599 per month (explicit table value for 10-person household) md_tca_maximum_benefit: 1_599 -- name: Case 3, exactly at cap (8 persons). +- name: Case 3, eight-person household. period: 2024-01 input: - people: - person1: - age: 35 - person2: - age: 33 - person3: - age: 14 - person4: - age: 12 - person5: - age: 10 - person6: - age: 8 - person7: - age: 6 - person8: - age: 4 - spm_units: - spm_unit: - members: [person1, person2, person3, person4, person5, person6, person7, person8] - md_tca_eligible: true - households: - household: - state_code: MD + spm_unit_size: 8 + state_code: MD output: - # 8-person cap = $1,372 (no additional) + # $1,372 per month md_tca_maximum_benefit: 1_372 -- name: Case 4, one above cap (9 persons). +- name: Case 4, nine-person household. period: 2024-01 input: - people: - person1: - age: 35 - person2: - age: 33 - person3: - age: 14 - person4: - age: 12 - person5: - age: 10 - person6: - age: 8 - person7: - age: 6 - person8: - age: 4 - person9: - age: 2 - spm_units: - spm_unit: - members: [person1, person2, person3, person4, person5, person6, person7, person8, person9] - md_tca_eligible: true - households: - household: - state_code: MD + spm_unit_size: 9 + state_code: MD output: # $1,480 per month (explicit table value for 9-person household) md_tca_maximum_benefit: 1_480 + +- name: Case 5, 22-person household (beyond max table size). + period: 2024-01 + input: + spm_unit_size: 22 + state_code: MD + output: + # Max table size is 21, so use main[21] + additional * (22 - 21) + # 2_983 + 136 * 1 = 3_119 + md_tca_maximum_benefit: 3_119 diff --git a/policyengine_us/variables/gov/states/md/tca/eligibility/md_tca_eligible.py b/policyengine_us/variables/gov/states/md/tca/eligibility/md_tca_eligible.py index 9a6a968bfc9..b5dc66ea23b 100644 --- a/policyengine_us/variables/gov/states/md/tca/eligibility/md_tca_eligible.py +++ b/policyengine_us/variables/gov/states/md/tca/eligibility/md_tca_eligible.py @@ -21,9 +21,8 @@ def formula(spm_unit, period, parameters): # Must meet immigration status eligibility (citizen or qualified alien) # Per COMAR 07.03.17.09 and 8 USC 1641 - person = spm_unit.members - immigration_eligible = spm_unit.any( - person("is_citizen_or_legal_immigrant", period.this_year) + immigration_eligible = ( + add(spm_unit, period, ["is_citizen_or_legal_immigrant"]) > 0 ) # Note: Per COMAR 07.03.03.12, individual assets are EXCLUDED