From cb96faab5fc6aacc1aa53a3f848101d53679c51b Mon Sep 17 00:00:00 2001 From: Ziming Date: Fri, 10 Jul 2026 12:47:50 -0400 Subject: [PATCH 1/7] Implement Oregon ERDC --- changelog.d/or-ccap.added.md | 1 + .../hhs/ccdf/child_care_subsidy_programs.yaml | 1 + .../license_exempt_infant_max_months.yaml | 11 + .../age_group/licensed_infant_max_months.yaml | 11 + .../erdc/age_group/preschool_max_years.yaml | 11 + .../erdc/age_group/toddler_max_months.yaml | 11 + .../or/delc/erdc/age_threshold/child.yaml | 11 + .../special_circumstances_child.yaml | 11 + .../gov/states/or/delc/erdc/copay/size_2.yaml | 33 ++ .../gov/states/or/delc/erdc/copay/size_3.yaml | 37 ++ .../gov/states/or/delc/erdc/copay/size_4.yaml | 37 ++ .../gov/states/or/delc/erdc/copay/size_5.yaml | 37 ++ .../gov/states/or/delc/erdc/copay/size_6.yaml | 37 ++ .../gov/states/or/delc/erdc/copay/size_7.yaml | 37 ++ .../gov/states/or/delc/erdc/copay/size_8.yaml | 37 ++ .../or/delc/erdc/hours/max_monthly.yaml | 11 + .../or/delc/erdc/hours/standard_tier.yaml | 20 + .../gov/states/or/delc/erdc/hours/tiered.yaml | 24 ++ .../erdc/income/countable_income/sources.yaml | 39 ++ .../or/delc/erdc/income/fpl_rate/initial.yaml | 11 + .../or/delc/erdc/income/fpl_rate/ongoing.yaml | 11 + .../or/delc/erdc/income/smi_rate/ongoing.yaml | 11 + .../states/or/delc/erdc/max_group_size.yaml | 11 + .../gov/states/or/delc/erdc/rates/hourly.yaml | 247 +++++++++++++ .../states/or/delc/erdc/rates/monthly.yaml | 247 +++++++++++++ .../states/or/delc/erdc/rates/part_time.yaml | 181 +++++++++ policyengine_us/programs.yaml | 9 +- .../gov/states/or/delc/erdc/integration.yaml | 241 ++++++++++++ .../delc/erdc/or_erdc_activity_eligible.yaml | 141 +++++++ .../states/or/delc/erdc/or_erdc_copay.yaml | 18 + .../or/delc/erdc/or_erdc_eligible_child.yaml | 33 ++ .../erdc/or_erdc_maximum_monthly_rate.yaml | 349 ++++++++++++++++++ .../or/delc/erdc/copay/or_erdc_copay.py | 43 +++ .../eligibility/or_erdc_activity_eligible.py | 41 ++ .../or_erdc_categorically_eligible.py | 17 + .../delc/erdc/eligibility/or_erdc_eligible.py | 25 ++ .../eligibility/or_erdc_eligible_child.py | 23 ++ .../eligibility/or_erdc_income_eligible.py | 34 ++ .../erdc/income/or_erdc_countable_income.py | 12 + .../or/delc/erdc/or_child_care_subsidies.py | 11 + .../gov/states/or/delc/erdc/or_erdc.py | 16 + .../states/or/delc/erdc/or_erdc_age_group.py | 55 +++ .../erdc/or_erdc_allowable_child_care_cost.py | 18 + .../or/delc/erdc/or_erdc_billing_tier.py | 32 ++ ...or_erdc_expanded_child_welfare_eligible.py | 10 + .../delc/erdc/or_erdc_maximum_monthly_rate.py | 37 ++ .../delc/erdc/or_erdc_monthly_care_hours.py | 19 + .../or/delc/erdc/or_erdc_on_medical_leave.py | 10 + .../or/delc/erdc/or_erdc_provider_area.py | 19 + .../or/delc/erdc/or_erdc_provider_type.py | 22 ++ .../or_erdc_special_circumstances_child.py | 10 + .../or_erdc_special_needs_rate_eligible.py | 10 + .../or_erdc_supervised_contact_required.py | 10 + .../delc/erdc/or_erdc_tiered_provider_type.py | 41 ++ .../erdc/or_erdc_unable_to_provide_care.py | 10 + sources/working_references.md | 53 +++ 56 files changed, 2504 insertions(+), 1 deletion(-) create mode 100644 changelog.d/or-ccap.added.md create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/age_group/license_exempt_infant_max_months.yaml create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/age_group/licensed_infant_max_months.yaml create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/age_group/preschool_max_years.yaml create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/age_group/toddler_max_months.yaml create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/age_threshold/child.yaml create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/age_threshold/special_circumstances_child.yaml create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_2.yaml create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_3.yaml create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_4.yaml create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_5.yaml create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_6.yaml create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_7.yaml create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_8.yaml create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/hours/max_monthly.yaml create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/hours/standard_tier.yaml create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/hours/tiered.yaml create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/income/countable_income/sources.yaml create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/income/fpl_rate/initial.yaml create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/income/fpl_rate/ongoing.yaml create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/income/smi_rate/ongoing.yaml create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/max_group_size.yaml create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/rates/hourly.yaml create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/rates/monthly.yaml create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/rates/part_time.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/integration.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_activity_eligible.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_copay.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_eligible_child.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_maximum_monthly_rate.yaml create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/copay/or_erdc_copay.py create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_activity_eligible.py create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_categorically_eligible.py create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_eligible.py create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_eligible_child.py create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_income_eligible.py create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/income/or_erdc_countable_income.py create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_child_care_subsidies.py create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc.py create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_age_group.py create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_allowable_child_care_cost.py create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_billing_tier.py create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_expanded_child_welfare_eligible.py create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_maximum_monthly_rate.py create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_monthly_care_hours.py create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_on_medical_leave.py create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_provider_area.py create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_provider_type.py create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_special_circumstances_child.py create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_special_needs_rate_eligible.py create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_supervised_contact_required.py create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_tiered_provider_type.py create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_unable_to_provide_care.py create mode 100644 sources/working_references.md diff --git a/changelog.d/or-ccap.added.md b/changelog.d/or-ccap.added.md new file mode 100644 index 00000000000..52bcd5272b2 --- /dev/null +++ b/changelog.d/or-ccap.added.md @@ -0,0 +1 @@ +Add Oregon Employment Related Day Care eligibility, copays, and 2026 provider reimbursement rates. diff --git a/policyengine_us/parameters/gov/hhs/ccdf/child_care_subsidy_programs.yaml b/policyengine_us/parameters/gov/hhs/ccdf/child_care_subsidy_programs.yaml index acd03170470..2d26696aee2 100644 --- a/policyengine_us/parameters/gov/hhs/ccdf/child_care_subsidy_programs.yaml +++ b/policyengine_us/parameters/gov/hhs/ccdf/child_care_subsidy_programs.yaml @@ -33,6 +33,7 @@ values: - pa_child_care_subsidies # Pennsylvania Child Care Works - nj_child_care_subsidies # New Jersey Child Care Assistance Program - nv_child_care_subsidies # Nevada Child Care and Development Program (CCDP) + - or_child_care_subsidies # Oregon Employment Related Day Care - ri_child_care_subsidies # Rhode Island Child Care Assistance Program - sc_child_care_subsidies # South Carolina Child Care Scholarship Program - va_child_care_subsidies # Virginia Child Care Subsidy Program diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/age_group/license_exempt_infant_max_months.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/age_group/license_exempt_infant_max_months.yaml new file mode 100644 index 00000000000..c802a9f72d9 --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/age_group/license_exempt_infant_max_months.yaml @@ -0,0 +1,11 @@ +description: Oregon limits the license-exempt infant rate category to children under this age under the Employment Related Day Care program. +values: + 2026-03-01: 12 + +metadata: + unit: month + period: year + label: Oregon ERDC license-exempt infant maximum age + reference: + - title: ERDC Provider Guide Insert, child age categories + href: https://www.oregon.gov/delc/providers/Documents/Provider%20Rate%20Increase%20For%20Jan%202026_Phase%202_ENG.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/age_group/licensed_infant_max_months.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/age_group/licensed_infant_max_months.yaml new file mode 100644 index 00000000000..d9367b99edb --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/age_group/licensed_infant_max_months.yaml @@ -0,0 +1,11 @@ +description: Oregon limits the licensed infant rate category to children under this age under the Employment Related Day Care program. +values: + 2026-01-01: 24 + +metadata: + unit: month + period: year + label: Oregon ERDC licensed infant maximum age + reference: + - title: ERDC Provider Guide Insert, child age categories + href: https://www.oregon.gov/delc/providers/Documents/Provider%20Rate%20Increase%20For%20Jan%202026_Phase%202_ENG.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/age_group/preschool_max_years.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/age_group/preschool_max_years.yaml new file mode 100644 index 00000000000..231a7de6164 --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/age_group/preschool_max_years.yaml @@ -0,0 +1,11 @@ +description: Oregon limits the preschool rate category to children under this age under the Employment Related Day Care program. +values: + 2026-01-01: 6 + +metadata: + unit: year + period: year + label: Oregon ERDC preschool maximum age + reference: + - title: ERDC Provider Guide Insert, child age categories + href: https://www.oregon.gov/delc/providers/Documents/Provider%20Rate%20Increase%20For%20Jan%202026_Phase%202_ENG.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/age_group/toddler_max_months.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/age_group/toddler_max_months.yaml new file mode 100644 index 00000000000..3fd351c13a6 --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/age_group/toddler_max_months.yaml @@ -0,0 +1,11 @@ +description: Oregon limits the toddler rate category to children under this age under the Employment Related Day Care program. +values: + 2026-01-01: 36 + +metadata: + unit: month + period: year + label: Oregon ERDC toddler maximum age + reference: + - title: ERDC Provider Guide Insert, child age categories + href: https://www.oregon.gov/delc/providers/Documents/Provider%20Rate%20Increase%20For%20Jan%202026_Phase%202_ENG.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/age_threshold/child.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/age_threshold/child.yaml new file mode 100644 index 00000000000..bf19365c6e8 --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/age_threshold/child.yaml @@ -0,0 +1,11 @@ +description: Oregon limits standard child eligibility to children under this age under the Employment Related Day Care program. +values: + 2023-07-01: 13 + +metadata: + unit: year + period: year + label: Oregon ERDC child age threshold + reference: + - title: OAR 414-175-0022(2)(a) + href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/age_threshold/special_circumstances_child.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/age_threshold/special_circumstances_child.yaml new file mode 100644 index 00000000000..6c86cbbc17d --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/age_threshold/special_circumstances_child.yaml @@ -0,0 +1,11 @@ +description: Oregon limits special-circumstances child eligibility to children under this age under the Employment Related Day Care program. +values: + 2023-07-01: 18 + +metadata: + unit: year + period: year + label: Oregon ERDC special circumstances child age threshold + reference: + - title: OAR 414-175-0022(2)(b) + href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_2.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_2.yaml new file mode 100644 index 00000000000..1cbefce623e --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_2.yaml @@ -0,0 +1,33 @@ +description: Oregon provides these monthly copay amounts for a group of 2 under the Employment Related Day Care program. +metadata: + type: single_amount + threshold_unit: currency-USD + amount_unit: currency-USD + period: month + label: Oregon ERDC group size 2 monthly copay + reference: + - title: OAR 414-175-0050(3)(b), Need group size 2 + href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 + +brackets: + - threshold: + 2026-03-01: -.inf + amount: + 2026-03-01: 0 + - threshold: + 2026-03-01: 1_804 + amount: + 2026-03-01: 5 + - threshold: + 2026-03-01: 2_705 + amount: + 2026-03-01: 10 + - threshold: + 2026-03-01: 3_607 + amount: + 2026-03-01: 40 + - threshold: + 2026-03-01: 4_058 + amount: + 2026-03-01: 100 + diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_3.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_3.yaml new file mode 100644 index 00000000000..aded32c09c4 --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_3.yaml @@ -0,0 +1,37 @@ +description: Oregon provides these monthly copay amounts for a group of 3 under the Employment Related Day Care program. +metadata: + type: single_amount + threshold_unit: currency-USD + amount_unit: currency-USD + period: month + label: Oregon ERDC group size 3 monthly copay + reference: + - title: OAR 414-175-0050(3)(b), Need group size 3 + href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 + +brackets: + - threshold: + 2026-03-01: -.inf + amount: + 2026-03-01: 0 + - threshold: + 2026-03-01: 2_277 + amount: + 2026-03-01: 5 + - threshold: + 2026-03-01: 3_415 + amount: + 2026-03-01: 10 + - threshold: + 2026-03-01: 3_985 + amount: + 2026-03-01: 15 + - threshold: + 2026-03-01: 4_554 + amount: + 2026-03-01: 50 + - threshold: + 2026-03-01: 5_123 + amount: + 2026-03-01: 110 + diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_4.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_4.yaml new file mode 100644 index 00000000000..42fb737ee1c --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_4.yaml @@ -0,0 +1,37 @@ +description: Oregon provides these monthly copay amounts for a group of 4 under the Employment Related Day Care program. +metadata: + type: single_amount + threshold_unit: currency-USD + amount_unit: currency-USD + period: month + label: Oregon ERDC group size 4 monthly copay + reference: + - title: OAR 414-175-0050(3)(b), Need group size 4 + href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 + +brackets: + - threshold: + 2026-03-01: -.inf + amount: + 2026-03-01: 0 + - threshold: + 2026-03-01: 2_750 + amount: + 2026-03-01: 5 + - threshold: + 2026-03-01: 4_125 + amount: + 2026-03-01: 10 + - threshold: + 2026-03-01: 4_813 + amount: + 2026-03-01: 20 + - threshold: + 2026-03-01: 5_500 + amount: + 2026-03-01: 60 + - threshold: + 2026-03-01: 6_188 + amount: + 2026-03-01: 120 + diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_5.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_5.yaml new file mode 100644 index 00000000000..5084fb49123 --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_5.yaml @@ -0,0 +1,37 @@ +description: Oregon provides these monthly copay amounts for a group of 5 under the Employment Related Day Care program. +metadata: + type: single_amount + threshold_unit: currency-USD + amount_unit: currency-USD + period: month + label: Oregon ERDC group size 5 monthly copay + reference: + - title: OAR 414-175-0050(3)(b), Need group size 5 + href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 + +brackets: + - threshold: + 2026-03-01: -.inf + amount: + 2026-03-01: 0 + - threshold: + 2026-03-01: 3_224 + amount: + 2026-03-01: 5 + - threshold: + 2026-03-01: 4_835 + amount: + 2026-03-01: 10 + - threshold: + 2026-03-01: 5_641 + amount: + 2026-03-01: 25 + - threshold: + 2026-03-01: 6_447 + amount: + 2026-03-01: 70 + - threshold: + 2026-03-01: 7_253 + amount: + 2026-03-01: 130 + diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_6.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_6.yaml new file mode 100644 index 00000000000..7749325cba0 --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_6.yaml @@ -0,0 +1,37 @@ +description: Oregon provides these monthly copay amounts for a group of 6 under the Employment Related Day Care program. +metadata: + type: single_amount + threshold_unit: currency-USD + amount_unit: currency-USD + period: month + label: Oregon ERDC group size 6 monthly copay + reference: + - title: OAR 414-175-0050(3)(b), Need group size 6 + href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 + +brackets: + - threshold: + 2026-03-01: -.inf + amount: + 2026-03-01: 0 + - threshold: + 2026-03-01: 3_697 + amount: + 2026-03-01: 5 + - threshold: + 2026-03-01: 5_545 + amount: + 2026-03-01: 10 + - threshold: + 2026-03-01: 6_470 + amount: + 2026-03-01: 25 + - threshold: + 2026-03-01: 7_394 + amount: + 2026-03-01: 70 + - threshold: + 2026-03-01: 8_318 + amount: + 2026-03-01: 130 + diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_7.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_7.yaml new file mode 100644 index 00000000000..9871bf24b71 --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_7.yaml @@ -0,0 +1,37 @@ +description: Oregon provides these monthly copay amounts for a group of 7 under the Employment Related Day Care program. +metadata: + type: single_amount + threshold_unit: currency-USD + amount_unit: currency-USD + period: month + label: Oregon ERDC group size 7 monthly copay + reference: + - title: OAR 414-175-0050(3)(b), Need group size 7 + href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 + +brackets: + - threshold: + 2026-03-01: -.inf + amount: + 2026-03-01: 0 + - threshold: + 2026-03-01: 4_170 + amount: + 2026-03-01: 5 + - threshold: + 2026-03-01: 6_255 + amount: + 2026-03-01: 10 + - threshold: + 2026-03-01: 7_298 + amount: + 2026-03-01: 25 + - threshold: + 2026-03-01: 8_340 + amount: + 2026-03-01: 70 + - threshold: + 2026-03-01: 9_383 + amount: + 2026-03-01: 130 + diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_8.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_8.yaml new file mode 100644 index 00000000000..8289f8337ee --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_8.yaml @@ -0,0 +1,37 @@ +description: Oregon provides these monthly copay amounts for a group of 8 or more under the Employment Related Day Care program. +metadata: + type: single_amount + threshold_unit: currency-USD + amount_unit: currency-USD + period: month + label: Oregon ERDC group size 8 or more monthly copay + reference: + - title: OAR 414-175-0050(3)(b), Need group size 8 or more + href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 + +brackets: + - threshold: + 2026-03-01: -.inf + amount: + 2026-03-01: 0 + - threshold: + 2026-03-01: 4_644 + amount: + 2026-03-01: 5 + - threshold: + 2026-03-01: 6_965 + amount: + 2026-03-01: 10 + - threshold: + 2026-03-01: 8_126 + amount: + 2026-03-01: 25 + - threshold: + 2026-03-01: 9_287 + amount: + 2026-03-01: 70 + - threshold: + 2026-03-01: 10_448 + amount: + 2026-03-01: 130 + diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/hours/max_monthly.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/hours/max_monthly.yaml new file mode 100644 index 00000000000..f8a5d16f581 --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/hours/max_monthly.yaml @@ -0,0 +1,11 @@ +description: Oregon limits standard monthly payable child care to this number of hours under the Employment Related Day Care program. +values: + 2026-01-01: 215 + +metadata: + unit: hour + period: month + label: Oregon ERDC maximum standard monthly hours + reference: + - title: OAR 414-175-0075(6)-(8) + href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/hours/standard_tier.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/hours/standard_tier.yaml new file mode 100644 index 00000000000..85c5e990448 --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/hours/standard_tier.yaml @@ -0,0 +1,20 @@ +description: Oregon sets these billing tiers for standard providers under the Employment Related Day Care program. +metadata: + type: single_amount + threshold_unit: hour + amount_unit: /1 + period: month + label: Oregon ERDC standard provider billing tiers + reference: + - title: ERDC Provider Guide Insert, 2026 standard rate maximums + href: https://www.oregon.gov/delc/providers/Documents/Provider%20Rate%20Increase%20For%20Jan%202026_Phase%202_ENG.pdf#page=2 + +brackets: + - threshold: + 2026-01-01: 0 + amount: + 2026-01-01: 0 + - threshold: + 2026-01-01: 158 + amount: + 2026-01-01: 2 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/hours/tiered.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/hours/tiered.yaml new file mode 100644 index 00000000000..56ef5a127da --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/hours/tiered.yaml @@ -0,0 +1,24 @@ +description: Oregon sets these billing tiers for enhanced and licensed providers under the Employment Related Day Care program. +metadata: + type: single_amount + threshold_unit: hour + amount_unit: /1 + period: month + label: Oregon ERDC tiered provider billing tiers + reference: + - title: ERDC Provider Guide Insert, 2026 enhanced and licensed rate maximums + href: https://www.oregon.gov/delc/providers/Documents/Provider%20Rate%20Increase%20For%20Jan%202026_Phase%202_ENG.pdf#page=2 + +brackets: + - threshold: + 2026-01-01: 0 + amount: + 2026-01-01: 0 + - threshold: + 2026-01-01: 63 + amount: + 2026-01-01: 1 + - threshold: + 2026-01-01: 136 + amount: + 2026-01-01: 2 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/income/countable_income/sources.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/income/countable_income/sources.yaml new file mode 100644 index 00000000000..1bb0463bc24 --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/income/countable_income/sources.yaml @@ -0,0 +1,39 @@ +description: Oregon counts these income sources under the Employment Related Day Care program. +values: + 2026-03-01: + - employment_income + - self_employment_income + - sstb_self_employment_income + - farm_operations_income + - military_basic_pay + - disability_benefits + - social_security + - ssi + - pension_income + - retirement_distributions + - military_retirement_pay + - unemployment_compensation + - workers_compensation + - alimony_income + - child_support_received + - interest_income + - dividend_income + - rental_income + - veterans_benefits + # TANF is countable under OAR 414-175-0035(56)(g), but including the + # calculated tanf variable would create a circular dependency through + # TANF child care deductions, child care expenses, and ERDC. + # - tanf + # The following countable sources do not have exact PolicyEngine variables: + # Paid Leave Oregon, striker benefits, Job Corps allowances, WIOA stipends, + # vocational rehabilitation maintenance, and other narrow payment types. + +metadata: + unit: list + period: year + label: Oregon ERDC countable income sources + reference: + - title: OAR 414-175-0030(1), General Financial Eligibility Provisions + href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 + - title: OAR 414-175-0035, Specific Financial Requirements + href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/income/fpl_rate/initial.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/income/fpl_rate/initial.yaml new file mode 100644 index 00000000000..df01ee5333f --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/income/fpl_rate/initial.yaml @@ -0,0 +1,11 @@ +description: Oregon limits initial income to this share of the federal poverty guideline under the Employment Related Day Care program. +values: + 2026-03-01: 2 + +metadata: + unit: /1 + period: year + label: Oregon ERDC initial income FPL rate + reference: + - title: OAR 414-175-0050(1)(b)(A) + href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/income/fpl_rate/ongoing.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/income/fpl_rate/ongoing.yaml new file mode 100644 index 00000000000..46f0ea8a910 --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/income/fpl_rate/ongoing.yaml @@ -0,0 +1,11 @@ +description: Oregon limits ongoing income to this share of the federal poverty guideline under the Employment Related Day Care program. +values: + 2026-03-01: 2.5 + +metadata: + unit: /1 + period: year + label: Oregon ERDC ongoing income FPL rate + reference: + - title: OAR 414-175-0050(1)(b)(B) + href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/income/smi_rate/ongoing.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/income/smi_rate/ongoing.yaml new file mode 100644 index 00000000000..8531a12affa --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/income/smi_rate/ongoing.yaml @@ -0,0 +1,11 @@ +description: Oregon limits ongoing income to this share of state median income under the Employment Related Day Care program. +values: + 2026-03-01: 0.85 + +metadata: + unit: /1 + period: year + label: Oregon ERDC ongoing income SMI rate + reference: + - title: OAR 414-175-0050(1)(b)(B) + href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/max_group_size.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/max_group_size.yaml new file mode 100644 index 00000000000..09cd96d468e --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/max_group_size.yaml @@ -0,0 +1,11 @@ +description: Oregon limits the group size used for income and copay calculations to this threshold under the Employment Related Day Care program. +values: + 2026-03-01: 8 + +metadata: + unit: person + period: year + label: Oregon ERDC maximum group size + reference: + - title: OAR 414-175-0050(1)(b) + href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/rates/hourly.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/rates/hourly.yaml new file mode 100644 index 00000000000..a4913d9283e --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/rates/hourly.yaml @@ -0,0 +1,247 @@ +description: Oregon provides these hourly maximum provider reimbursement rates under the Employment Related Day Care program. +metadata: + period: hour + unit: currency-USD + label: Oregon ERDC hourly maximum provider rates + breakdown: + - or_erdc_provider_area + - or_erdc_provider_type + - or_erdc_age_group + reference: + - title: Oregon DELC ERDC Child Care Maximum Rates, Group Areas A-C + href: https://www.oregon.gov/delc/providers/Documents/Provider%20Rate%20Increase%20For%20Jan%202026_Phase%202_ENG.pdf#page=2 + +AREA_A: + STANDARD_FAMILY: + INFANT: + 2026-03-01: 6.5 + TODDLER: + 2026-03-01: 5.9 + PRESCHOOL: + 2026-03-01: 5.4 + SCHOOL: + 2026-03-01: 5.7 + SPECIAL_NEEDS: + 2026-03-01: 6.5 + STANDARD_CENTER: + INFANT: + 2026-01-01: 9 + TODDLER: + 2026-01-01: 11 + PRESCHOOL: + 2026-01-01: 8.25 + SCHOOL: + 2026-01-01: 8 + SPECIAL_NEEDS: + 2026-01-01: 9 + ENHANCED_FAMILY: + INFANT: + 2026-03-01: 6.86 + TODDLER: + 2026-03-01: 6.22 + PRESCHOOL: + 2026-03-01: 5.7 + SCHOOL: + 2026-03-01: 6.01 + SPECIAL_NEEDS: + 2026-03-01: 6.86 + ENHANCED_CENTER: + INFANT: + 2026-01-01: 10.2 + TODDLER: + 2026-01-01: 12.47 + PRESCHOOL: + 2026-01-01: 9.35 + SCHOOL: + 2026-01-01: 9.07 + SPECIAL_NEEDS: + 2026-01-01: 10.2 + REGISTERED_FAMILY: + INFANT: + 2026-01-01: 7.22 + TODDLER: + 2026-01-01: 6.55 + PRESCHOOL: + 2026-01-01: 6 + SCHOOL: + 2026-01-01: 6.33 + SPECIAL_NEEDS: + 2026-01-01: 7.22 + CERTIFIED_FAMILY: + INFANT: + 2026-01-01: 9.33 + TODDLER: + 2026-01-01: 8.58 + PRESCHOOL: + 2026-01-01: 8.5 + SCHOOL: + 2026-01-01: 7.67 + SPECIAL_NEEDS: + 2026-01-01: 9.33 + CERTIFIED_CENTER: + INFANT: + 2026-01-01: 12 + TODDLER: + 2026-01-01: 14.67 + PRESCHOOL: + 2026-01-01: 11 + SCHOOL: + 2026-01-01: 10.67 + SPECIAL_NEEDS: + 2026-01-01: 12 +AREA_B: + STANDARD_FAMILY: + INFANT: + 2026-03-01: 4.95 + TODDLER: + 2026-03-01: 4.73 + PRESCHOOL: + 2026-03-01: 4.5 + SCHOOL: + 2026-03-01: 5.4 + SPECIAL_NEEDS: + 2026-03-01: 4.95 + STANDARD_CENTER: + INFANT: + 2026-01-01: 6.56 + TODDLER: + 2026-01-01: 4.94 + PRESCHOOL: + 2026-01-01: 7.13 + SCHOOL: + 2026-01-01: 4.31 + SPECIAL_NEEDS: + 2026-01-01: 6.56 + ENHANCED_FAMILY: + INFANT: + 2026-03-01: 5.23 + TODDLER: + 2026-03-01: 4.99 + PRESCHOOL: + 2026-03-01: 4.75 + SCHOOL: + 2026-03-01: 5.7 + SPECIAL_NEEDS: + 2026-03-01: 5.23 + ENHANCED_CENTER: + INFANT: + 2026-01-01: 7.44 + TODDLER: + 2026-01-01: 5.59 + PRESCHOOL: + 2026-01-01: 8.08 + SCHOOL: + 2026-01-01: 4.48 + SPECIAL_NEEDS: + 2026-01-01: 7.44 + REGISTERED_FAMILY: + INFANT: + 2026-01-01: 5.5 + TODDLER: + 2026-01-01: 5.25 + PRESCHOOL: + 2026-01-01: 5 + SCHOOL: + 2026-01-01: 6 + SPECIAL_NEEDS: + 2026-01-01: 5.5 + CERTIFIED_FAMILY: + INFANT: + 2026-01-01: 6 + TODDLER: + 2026-01-01: 5.5 + PRESCHOOL: + 2026-01-01: 6 + SCHOOL: + 2026-01-01: 5.83 + SPECIAL_NEEDS: + 2026-01-01: 6 + CERTIFIED_CENTER: + INFANT: + 2026-01-01: 7.75 + TODDLER: + 2026-01-01: 6.58 + PRESCHOOL: + 2026-01-01: 9.5 + SCHOOL: + 2026-01-01: 5.75 + SPECIAL_NEEDS: + 2026-01-01: 7.75 +AREA_C: + STANDARD_FAMILY: + INFANT: + 2026-03-01: 4.95 + TODDLER: + 2026-03-01: 4.73 + PRESCHOOL: + 2026-03-01: 4.5 + SCHOOL: + 2026-03-01: 5.4 + SPECIAL_NEEDS: + 2026-03-01: 4.95 + STANDARD_CENTER: + INFANT: + 2026-01-01: 6.56 + TODDLER: + 2026-01-01: 4.94 + PRESCHOOL: + 2026-01-01: 7.13 + SCHOOL: + 2026-01-01: 4.31 + SPECIAL_NEEDS: + 2026-01-01: 6.56 + ENHANCED_FAMILY: + INFANT: + 2026-03-01: 5.23 + TODDLER: + 2026-03-01: 4.99 + PRESCHOOL: + 2026-03-01: 4.75 + SCHOOL: + 2026-03-01: 5.7 + SPECIAL_NEEDS: + 2026-03-01: 5.23 + ENHANCED_CENTER: + INFANT: + 2026-01-01: 7.44 + TODDLER: + 2026-01-01: 5.59 + PRESCHOOL: + 2026-01-01: 8.08 + SCHOOL: + 2026-01-01: 4.48 + SPECIAL_NEEDS: + 2026-01-01: 7.44 + REGISTERED_FAMILY: + INFANT: + 2026-01-01: 5.5 + TODDLER: + 2026-01-01: 5.25 + PRESCHOOL: + 2026-01-01: 5 + SCHOOL: + 2026-01-01: 6 + SPECIAL_NEEDS: + 2026-01-01: 5.5 + CERTIFIED_FAMILY: + INFANT: + 2026-01-01: 6 + TODDLER: + 2026-01-01: 5.5 + PRESCHOOL: + 2026-01-01: 6 + SCHOOL: + 2026-01-01: 5.83 + SPECIAL_NEEDS: + 2026-01-01: 6 + CERTIFIED_CENTER: + INFANT: + 2026-01-01: 7.75 + TODDLER: + 2026-01-01: 6.58 + PRESCHOOL: + 2026-01-01: 9.5 + SCHOOL: + 2026-01-01: 5.75 + SPECIAL_NEEDS: + 2026-01-01: 7.75 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/rates/monthly.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/rates/monthly.yaml new file mode 100644 index 00000000000..76632cace86 --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/rates/monthly.yaml @@ -0,0 +1,247 @@ +description: Oregon provides these monthly maximum provider reimbursement rates under the Employment Related Day Care program. +metadata: + period: month + unit: currency-USD + label: Oregon ERDC monthly maximum provider rates + breakdown: + - or_erdc_provider_area + - or_erdc_provider_type + - or_erdc_age_group + reference: + - title: Oregon DELC ERDC Child Care Maximum Rates, Group Areas A-C + href: https://www.oregon.gov/delc/providers/Documents/Provider%20Rate%20Increase%20For%20Jan%202026_Phase%202_ENG.pdf#page=2 + +AREA_A: + STANDARD_FAMILY: + INFANT: + 2026-03-01: 1_110 + TODDLER: + 2026-03-01: 1_020 + PRESCHOOL: + 2026-03-01: 930 + SCHOOL: + 2026-03-01: 840 + SPECIAL_NEEDS: + 2026-03-01: 1_110 + STANDARD_CENTER: + INFANT: + 2026-01-01: 1_562 + TODDLER: + 2026-01-01: 1_490 + PRESCHOOL: + 2026-01-01: 1_173 + SCHOOL: + 2026-01-01: 1_189 + SPECIAL_NEEDS: + 2026-01-01: 1_562 + ENHANCED_FAMILY: + INFANT: + 2026-03-01: 1_172 + TODDLER: + 2026-03-01: 1_077 + PRESCHOOL: + 2026-03-01: 982 + SCHOOL: + 2026-03-01: 887 + SPECIAL_NEEDS: + 2026-03-01: 1_172 + ENHANCED_CENTER: + INFANT: + 2026-01-01: 1_770 + TODDLER: + 2026-01-01: 1_689 + PRESCHOOL: + 2026-01-01: 1_329 + SCHOOL: + 2026-01-01: 1_347 + SPECIAL_NEEDS: + 2026-01-01: 1_770 + REGISTERED_FAMILY: + INFANT: + 2026-01-01: 1233.33 + TODDLER: + 2026-01-01: 1133.33 + PRESCHOOL: + 2026-01-01: 1033.33 + SCHOOL: + 2026-01-01: 933.33 + SPECIAL_NEEDS: + 2026-01-01: 1233.33 + CERTIFIED_FAMILY: + INFANT: + 2026-01-01: 1_831 + TODDLER: + 2026-01-01: 1_675 + PRESCHOOL: + 2026-01-01: 1477.33 + SCHOOL: + 2026-01-01: 1_150 + SPECIAL_NEEDS: + 2026-01-01: 1_831 + CERTIFIED_CENTER: + INFANT: + 2026-01-01: 2_083 + TODDLER: + 2026-01-01: 1_987 + PRESCHOOL: + 2026-01-01: 1_563 + SCHOOL: + 2026-01-01: 1_585 + SPECIAL_NEEDS: + 2026-01-01: 2_083 +AREA_B: + STANDARD_FAMILY: + INFANT: + 2026-03-01: 855 + TODDLER: + 2026-03-01: 788 + PRESCHOOL: + 2026-03-01: 750 + SCHOOL: + 2026-03-01: 720 + SPECIAL_NEEDS: + 2026-03-01: 855 + STANDARD_CENTER: + INFANT: + 2026-01-01: 1_125 + TODDLER: + 2026-01-01: 994 + PRESCHOOL: + 2026-01-01: 782 + SCHOOL: + 2026-01-01: 600 + SPECIAL_NEEDS: + 2026-01-01: 1_125 + ENHANCED_FAMILY: + INFANT: + 2026-03-01: 903 + TODDLER: + 2026-03-01: 831 + PRESCHOOL: + 2026-03-01: 791 + SCHOOL: + 2026-03-01: 760 + SPECIAL_NEEDS: + 2026-03-01: 903 + ENHANCED_CENTER: + INFANT: + 2026-01-01: 1_275 + TODDLER: + 2026-01-01: 1_126 + PRESCHOOL: + 2026-01-01: 887 + SCHOOL: + 2026-01-01: 680 + SPECIAL_NEEDS: + 2026-01-01: 1_275 + REGISTERED_FAMILY: + INFANT: + 2026-01-01: 950 + TODDLER: + 2026-01-01: 875 + PRESCHOOL: + 2026-01-01: 833 + SCHOOL: + 2026-01-01: 800 + SPECIAL_NEEDS: + 2026-01-01: 950 + CERTIFIED_FAMILY: + INFANT: + 2026-01-01: 1_275 + TODDLER: + 2026-01-01: 1_110 + PRESCHOOL: + 2026-01-01: 1_050 + SCHOOL: + 2026-01-01: 900 + SPECIAL_NEEDS: + 2026-01-01: 1_275 + CERTIFIED_CENTER: + INFANT: + 2026-01-01: 1_500 + TODDLER: + 2026-01-01: 1_325 + PRESCHOOL: + 2026-01-01: 1_043 + SCHOOL: + 2026-01-01: 800 + SPECIAL_NEEDS: + 2026-01-01: 1_500 +AREA_C: + STANDARD_FAMILY: + INFANT: + 2026-03-01: 855 + TODDLER: + 2026-03-01: 788 + PRESCHOOL: + 2026-03-01: 750 + SCHOOL: + 2026-03-01: 720 + SPECIAL_NEEDS: + 2026-03-01: 855 + STANDARD_CENTER: + INFANT: + 2026-01-01: 1_125 + TODDLER: + 2026-01-01: 994 + PRESCHOOL: + 2026-01-01: 782 + SCHOOL: + 2026-01-01: 600 + SPECIAL_NEEDS: + 2026-01-01: 1_125 + ENHANCED_FAMILY: + INFANT: + 2026-03-01: 903 + TODDLER: + 2026-03-01: 831 + PRESCHOOL: + 2026-03-01: 791 + SCHOOL: + 2026-03-01: 760 + SPECIAL_NEEDS: + 2026-03-01: 903 + ENHANCED_CENTER: + INFANT: + 2026-01-01: 1_275 + TODDLER: + 2026-01-01: 1_126 + PRESCHOOL: + 2026-01-01: 887 + SCHOOL: + 2026-01-01: 680 + SPECIAL_NEEDS: + 2026-01-01: 1_275 + REGISTERED_FAMILY: + INFANT: + 2026-01-01: 950 + TODDLER: + 2026-01-01: 875 + PRESCHOOL: + 2026-01-01: 833 + SCHOOL: + 2026-01-01: 800 + SPECIAL_NEEDS: + 2026-01-01: 950 + CERTIFIED_FAMILY: + INFANT: + 2026-01-01: 1_275 + TODDLER: + 2026-01-01: 1_110 + PRESCHOOL: + 2026-01-01: 1_050 + SCHOOL: + 2026-01-01: 900 + SPECIAL_NEEDS: + 2026-01-01: 1_275 + CERTIFIED_CENTER: + INFANT: + 2026-01-01: 1_500 + TODDLER: + 2026-01-01: 1_325 + PRESCHOOL: + 2026-01-01: 1_043 + SCHOOL: + 2026-01-01: 800 + SPECIAL_NEEDS: + 2026-01-01: 1_500 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/rates/part_time.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/rates/part_time.yaml new file mode 100644 index 00000000000..1f2c6b96649 --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/rates/part_time.yaml @@ -0,0 +1,181 @@ +description: Oregon provides these part-time monthly maximum provider reimbursement rates under the Employment Related Day Care program. +metadata: + period: month + unit: currency-USD + label: Oregon ERDC part-time monthly maximum provider rates + breakdown: + - or_erdc_provider_area + - or_erdc_tiered_provider_type + - or_erdc_age_group + reference: + - title: Oregon DELC ERDC Child Care Maximum Rates, Group Areas A-C + href: https://www.oregon.gov/delc/providers/Documents/Provider%20Rate%20Increase%20For%20Jan%202026_Phase%202_ENG.pdf#page=2 + +AREA_A: + ENHANCED_FAMILY: + INFANT: + 2026-03-01: 879 + TODDLER: + 2026-03-01: 808 + PRESCHOOL: + 2026-03-01: 737 + SCHOOL: + 2026-03-01: 665 + SPECIAL_NEEDS: + 2026-03-01: 879 + ENHANCED_CENTER: + INFANT: + 2026-01-01: 1_328 + TODDLER: + 2026-01-01: 1_267 + PRESCHOOL: + 2026-01-01: 997 + SCHOOL: + 2026-01-01: 1_010 + SPECIAL_NEEDS: + 2026-01-01: 1_328 + REGISTERED_FAMILY: + INFANT: + 2026-01-01: 925 + TODDLER: + 2026-01-01: 850 + PRESCHOOL: + 2026-01-01: 775 + SCHOOL: + 2026-01-01: 700 + SPECIAL_NEEDS: + 2026-01-01: 925 + CERTIFIED_FAMILY: + INFANT: + 2026-01-01: 1_373 + TODDLER: + 2026-01-01: 1_256 + PRESCHOOL: + 2026-01-01: 1_108 + SCHOOL: + 2026-01-01: 863 + SPECIAL_NEEDS: + 2026-01-01: 1_373 + CERTIFIED_CENTER: + INFANT: + 2026-01-01: 1_562 + TODDLER: + 2026-01-01: 1_490 + PRESCHOOL: + 2026-01-01: 1_172 + SCHOOL: + 2026-01-01: 1_189 + SPECIAL_NEEDS: + 2026-01-01: 1_562 +AREA_B: + ENHANCED_FAMILY: + INFANT: + 2026-03-01: 677 + TODDLER: + 2026-03-01: 623 + PRESCHOOL: + 2026-03-01: 593 + SCHOOL: + 2026-03-01: 570 + SPECIAL_NEEDS: + 2026-03-01: 677 + ENHANCED_CENTER: + INFANT: + 2026-01-01: 956 + TODDLER: + 2026-01-01: 845 + PRESCHOOL: + 2026-01-01: 665 + SCHOOL: + 2026-01-01: 510 + SPECIAL_NEEDS: + 2026-01-01: 956 + REGISTERED_FAMILY: + INFANT: + 2026-01-01: 713 + TODDLER: + 2026-01-01: 656 + PRESCHOOL: + 2026-01-01: 625 + SCHOOL: + 2026-01-01: 600 + SPECIAL_NEEDS: + 2026-01-01: 713 + CERTIFIED_FAMILY: + INFANT: + 2026-01-01: 956 + TODDLER: + 2026-01-01: 833 + PRESCHOOL: + 2026-01-01: 788 + SCHOOL: + 2026-01-01: 675 + SPECIAL_NEEDS: + 2026-01-01: 956 + CERTIFIED_CENTER: + INFANT: + 2026-01-01: 1_125 + TODDLER: + 2026-01-01: 994 + PRESCHOOL: + 2026-01-01: 782 + SCHOOL: + 2026-01-01: 600 + SPECIAL_NEEDS: + 2026-01-01: 1_125 +AREA_C: + ENHANCED_FAMILY: + INFANT: + 2026-03-01: 677 + TODDLER: + 2026-03-01: 623 + PRESCHOOL: + 2026-03-01: 593 + SCHOOL: + 2026-03-01: 570 + SPECIAL_NEEDS: + 2026-03-01: 677 + ENHANCED_CENTER: + INFANT: + 2026-01-01: 956 + TODDLER: + 2026-01-01: 845 + PRESCHOOL: + 2026-01-01: 665 + SCHOOL: + 2026-01-01: 510 + SPECIAL_NEEDS: + 2026-01-01: 956 + REGISTERED_FAMILY: + INFANT: + 2026-01-01: 713 + TODDLER: + 2026-01-01: 656 + PRESCHOOL: + 2026-01-01: 625 + SCHOOL: + 2026-01-01: 600 + SPECIAL_NEEDS: + 2026-01-01: 713 + CERTIFIED_FAMILY: + INFANT: + 2026-01-01: 956 + TODDLER: + 2026-01-01: 833 + PRESCHOOL: + 2026-01-01: 788 + SCHOOL: + 2026-01-01: 675 + SPECIAL_NEEDS: + 2026-01-01: 956 + CERTIFIED_CENTER: + INFANT: + 2026-01-01: 1_125 + TODDLER: + 2026-01-01: 994 + PRESCHOOL: + 2026-01-01: 782 + SCHOOL: + 2026-01-01: 600 + SPECIAL_NEEDS: + 2026-01-01: 1_125 diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index a5114d95d5e..340b53201f3 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -460,7 +460,7 @@ programs: category: Benefits agency: HHS status: partial - coverage: AK, AR, AL, AZ, CA, CO, CT, DE, DC, FL, GA, HI, IA, ID, IL, IN, KS, KY, LA, MA, MD, ME, MI, MN, MO, MS, MT, NC, ND, NE, NH, NJ, NM, NV, PA, RI, SC, TX, VA, VT, WA, WV + coverage: AK, AR, AL, AZ, CA, CO, CT, DE, DC, FL, GA, HI, IA, ID, IL, IN, KS, KY, LA, MA, MD, ME, MI, MN, MO, MS, MT, NC, ND, NE, NH, NJ, NM, NV, OR, PA, RI, SC, TX, VA, VT, WA, WV state_implementations: - state: AK status: complete @@ -626,6 +626,13 @@ programs: full_name: Nevada Child Care and Development Program variable: nv_ccdp parameter_prefix: gov.states.nv.dwss.ccdp + - state: OR + status: complete + name: Oregon ERDC + full_name: Oregon Employment Related Day Care + variable: or_erdc + parameter_prefix: gov.states.or.delc.erdc + notes: Provider rate area is an input; automatic provider ZIP mapping is deferred - state: DC status: complete name: DC CCSP diff --git a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/integration.yaml new file mode 100644 index 00000000000..8979db42e48 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/integration.yaml @@ -0,0 +1,241 @@ +# End-to-end tests for Oregon Employment Related Day Care (ERDC). +# Provider rate areas are supplied directly until a later PR maps ZIP codes. + +- name: Case 1, initial applicant with a preschooler in certified center care. + period: 2027-01 + absolute_error_margin: 0.1 + input: + people: + parent: + age: 30 + employment_income: 36_000 + weekly_hours_worked_before_lsr: 40 + child: + age: 4 + childcare_hours_per_week: 40 + or_erdc_provider_area: AREA_A + or_erdc_provider_type: CERTIFIED_CENTER + pre_subsidy_childcare_expenses: 18_000 + spm_units: + spm_unit: + members: [parent, child] + households: + household: + members: [parent, child] + state_code: OR + output: + or_erdc_eligible_child: [false, true] + or_erdc_age_group: [SCHOOL, PRESCHOOL] + or_erdc_countable_income: 3_000 + or_erdc_activity_eligible: true + or_erdc_income_eligible: true + or_erdc_copay: 10 + or_erdc_maximum_monthly_rate: [0, 1_563] + or_erdc_allowable_child_care_cost: 1_500 + or_erdc_eligible: true + or_erdc: 1_490 + +- name: Case 2, initial applicant at the strict income limit is ineligible. + period: 2027-01 + absolute_error_margin: 0.1 + input: + people: + parent: + age: 30 + weekly_hours_worked_before_lsr: 40 + child: + age: 4 + childcare_hours_per_week: 40 + or_erdc_provider_area: AREA_A + or_erdc_provider_type: CERTIFIED_CENTER + pre_subsidy_childcare_expenses: 18_000 + spm_units: + spm_unit: + members: [parent, child] + or_erdc_countable_income: 3_692 + households: + household: + members: [parent, child] + state_code: OR + output: + or_erdc_countable_income: 3_692 + or_erdc_income_eligible: false + or_erdc_eligible: false + or_erdc: 0 + +- name: Case 3, continuing family uses the ongoing income limit and part-time rate. + period: 2027-01 + absolute_error_margin: 0.1 + input: + people: + parent: + age: 32 + employment_income: 80_000 + weekly_hours_worked_before_lsr: 40 + is_enrolled_in_ccdf: true + child: + age: 2 + childcare_hours_per_week: 30 + or_erdc_provider_area: AREA_B + or_erdc_provider_type: ENHANCED_FAMILY + pre_subsidy_childcare_expenses: 9_600 + sibling: + age: 10 + spm_units: + spm_unit: + members: [parent, child, sibling] + households: + household: + members: [parent, child, sibling] + state_code: OR + output: + or_erdc_countable_income: 6_666.67 + or_erdc_income_eligible: true + or_erdc_billing_tier: [HOURLY, PART_TIME, HOURLY] + or_erdc_maximum_monthly_rate: [0, 623, 0] + or_erdc_copay: 110 + or_erdc: 513 + +- name: Case 4, Expanded Child Welfare bypasses income and activity tests. + period: 2027-01 + absolute_error_margin: 0.1 + input: + people: + parent: + age: 28 + employment_income: 100_000 + weekly_hours_worked_before_lsr: 0 + child: + age: 0.5 + childcare_hours_per_week: 20 + or_erdc_provider_area: AREA_C + or_erdc_provider_type: STANDARD_FAMILY + pre_subsidy_childcare_expenses: 7_200 + spm_units: + spm_unit: + members: [parent, child] + or_erdc_expanded_child_welfare_eligible: true + households: + household: + members: [parent, child] + state_code: OR + output: + or_erdc_categorically_eligible: true + or_erdc_activity_eligible: true + or_erdc_income_eligible: true + or_erdc_copay: 0 + or_erdc_maximum_monthly_rate: [0, 429] + or_erdc: 429 + +- name: Case 5, assets above the CCDF limit make the family ineligible. + period: 2027-01 + input: + people: + parent: + age: 30 + employment_income: 30_000 + weekly_hours_worked_before_lsr: 40 + child: + age: 4 + childcare_hours_per_week: 40 + or_erdc_provider_area: AREA_A + or_erdc_provider_type: CERTIFIED_CENTER + pre_subsidy_childcare_expenses: 18_000 + spm_units: + spm_unit: + members: [parent, child] + spm_unit_assets: 1_000_001 + households: + household: + members: [parent, child] + state_code: OR + output: + is_ccdf_asset_eligible: false + or_erdc_eligible: false + or_erdc: 0 + +- name: Case 6, teenager with special circumstances receives the special-needs rate. + period: 2027-01 + absolute_error_margin: 0.1 + input: + people: + parent: + age: 40 + employment_income: 30_000 + weekly_hours_worked_before_lsr: 40 + child: + age: 15 + is_incapable_of_self_care: true + or_erdc_special_needs_rate_eligible: true + childcare_hours_per_week: 40 + or_erdc_provider_area: AREA_A + or_erdc_provider_type: CERTIFIED_FAMILY + pre_subsidy_childcare_expenses: 24_000 + spm_units: + spm_unit: + members: [parent, child] + households: + household: + members: [parent, child] + state_code: OR + output: + or_erdc_eligible_child: [false, true] + or_erdc_age_group: [SCHOOL, SPECIAL_NEEDS] + or_erdc_maximum_monthly_rate: [0, 1_831] + or_erdc_copay: 5 + or_erdc: 1_826 + +- name: Case 7, negative self-employment income reduces countable income. + period: 2027-01 + absolute_error_margin: 0.1 + input: + people: + parent: + age: 30 + employment_income: 24_000 + self_employment_income: -12_000 + weekly_hours_worked_before_lsr: 40 + child: + age: 4 + childcare_hours_per_week: 10 + or_erdc_provider_area: AREA_B + or_erdc_provider_type: STANDARD_CENTER + pre_subsidy_childcare_expenses: 6_000 + spm_units: + spm_unit: + members: [parent, child] + households: + household: + members: [parent, child] + state_code: OR + output: + or_erdc_countable_income: 1_000 + or_erdc_copay: 0 + or_erdc_maximum_monthly_rate: [0, 308.97] + or_erdc: 308.97 + +- name: Case 8, annual state and federal aggregators include ERDC. + period: 2027 + absolute_error_margin: 0.1 + input: + people: + parent: + age: 30 + employment_income: 36_000 + weekly_hours_worked_before_lsr: 40 + child: + age: 4 + childcare_hours_per_week: 40 + or_erdc_provider_area: AREA_A + or_erdc_provider_type: CERTIFIED_CENTER + pre_subsidy_childcare_expenses: 18_000 + spm_units: + spm_unit: + members: [parent, child] + households: + household: + members: [parent, child] + state_code: OR + output: + or_child_care_subsidies: 17_880 + child_care_subsidies: 17_880 diff --git a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_activity_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_activity_eligible.yaml new file mode 100644 index 00000000000..7e26782e5e3 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_activity_eligible.yaml @@ -0,0 +1,141 @@ +- name: A working single caretaker is activity eligible. + period: 2027-01 + input: + people: + parent: + age: 30 + weekly_hours_worked_before_lsr: 1 + child: + age: 4 + tax_units: + tax_unit: + members: [parent, child] + spm_units: + spm_unit: + members: [parent, child] + households: + household: + members: [parent, child] + state_code: OR + output: + or_erdc_activity_eligible: true + +- name: Both caretakers must have an eligible activity. + period: 2027-01 + input: + people: + parent_1: + age: 32 + weekly_hours_worked_before_lsr: 40 + parent_2: + age: 30 + weekly_hours_worked_before_lsr: 0 + child: + age: 4 + tax_units: + tax_unit: + members: [parent_1, parent_2, child] + spm_units: + spm_unit: + members: [parent_1, parent_2, child] + households: + household: + members: [parent_1, parent_2, child] + state_code: OR + output: + or_erdc_activity_eligible: false + +- name: A second caretaker unable to provide care satisfies the exception. + period: 2027-01 + input: + people: + parent_1: + age: 32 + weekly_hours_worked_before_lsr: 40 + parent_2: + age: 30 + weekly_hours_worked_before_lsr: 0 + or_erdc_unable_to_provide_care: true + child: + age: 4 + tax_units: + tax_unit: + members: [parent_1, parent_2, child] + spm_units: + spm_unit: + members: [parent_1, parent_2, child] + households: + household: + members: [parent_1, parent_2, child] + state_code: OR + output: + or_erdc_activity_eligible: true + +- name: A college student caretaker is activity eligible. + period: 2027-01 + input: + people: + parent: + age: 22 + weekly_hours_worked_before_lsr: 0 + is_full_time_college_student: true + child: + age: 4 + tax_units: + tax_unit: + members: [parent, child] + spm_units: + spm_unit: + members: [parent, child] + households: + household: + members: [parent, child] + state_code: OR + output: + or_erdc_activity_eligible: true + +- name: A caretaker on verified medical leave is activity eligible. + period: 2027-01 + input: + people: + parent: + age: 30 + weekly_hours_worked_before_lsr: 0 + or_erdc_on_medical_leave: true + child: + age: 4 + tax_units: + tax_unit: + members: [parent, child] + spm_units: + spm_unit: + members: [parent, child] + households: + household: + members: [parent, child] + state_code: OR + output: + or_erdc_activity_eligible: true + +- name: Supervised contact waives the ordinary caretaker activity test. + period: 2027-01 + input: + people: + parent: + age: 30 + weekly_hours_worked_before_lsr: 0 + child: + age: 4 + tax_units: + tax_unit: + members: [parent, child] + spm_units: + spm_unit: + members: [parent, child] + or_erdc_supervised_contact_required: true + households: + household: + members: [parent, child] + state_code: OR + output: + or_erdc_activity_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_copay.yaml b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_copay.yaml new file mode 100644 index 00000000000..e2b37df2575 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_copay.yaml @@ -0,0 +1,18 @@ +- name: Household sizes above eight use the size-eight copay schedule. + period: 2027-01 + input: + or_erdc_countable_income: 5_000 + spm_unit_size: 9 + state_code: OR + output: + or_erdc_copay: 5 + +- name: Categorically eligible families have no copay. + period: 2027-01 + input: + or_erdc_countable_income: 10_000 + or_erdc_categorically_eligible: true + spm_unit_size: 2 + state_code: OR + output: + or_erdc_copay: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_eligible_child.yaml b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_eligible_child.yaml new file mode 100644 index 00000000000..a699e75bc5e --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_eligible_child.yaml @@ -0,0 +1,33 @@ +- name: Child younger than 13 is eligible. + period: 2027-01 + input: + age: 12 + state_code: OR + output: + or_erdc_eligible_child: true + +- name: Child age 13 without special circumstances is ineligible. + period: 2027-01 + input: + age: 13 + state_code: OR + output: + or_erdc_eligible_child: false + +- name: Child younger than 18 with special circumstances is eligible. + period: 2027-01 + input: + age: 17 + or_erdc_special_circumstances_child: true + state_code: OR + output: + or_erdc_eligible_child: true + +- name: Person age 18 is ineligible even with special circumstances. + period: 2027-01 + input: + age: 18 + or_erdc_special_circumstances_child: true + state_code: OR + output: + or_erdc_eligible_child: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_maximum_monthly_rate.yaml b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_maximum_monthly_rate.yaml new file mode 100644 index 00000000000..44bb3ceddd8 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_maximum_monthly_rate.yaml @@ -0,0 +1,349 @@ +# Every provider type, rate area, age group, and billing tier is covered. + +- name: Case 1, Area A standard family infant hourly. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_A + or_erdc_provider_type: STANDARD_FAMILY + or_erdc_age_group: INFANT + or_erdc_monthly_care_hours: 10 + state_code: OR + output: + or_erdc_maximum_monthly_rate: 65 + +- name: Case 2, Area A standard center toddler monthly. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_A + or_erdc_provider_type: STANDARD_CENTER + or_erdc_age_group: TODDLER + or_erdc_monthly_care_hours: 200 + state_code: OR + output: + or_erdc_maximum_monthly_rate: 1490 + +- name: Case 3, Area A enhanced family preschool part-time. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_A + or_erdc_provider_type: ENHANCED_FAMILY + or_erdc_age_group: PRESCHOOL + or_erdc_monthly_care_hours: 100 + state_code: OR + output: + or_erdc_maximum_monthly_rate: 737 + +- name: Case 4, Area A enhanced center school hourly. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_A + or_erdc_provider_type: ENHANCED_CENTER + or_erdc_age_group: SCHOOL + or_erdc_monthly_care_hours: 10 + state_code: OR + output: + or_erdc_maximum_monthly_rate: 90.7 + +- name: Case 5, Area A registered family special needs monthly. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_A + or_erdc_provider_type: REGISTERED_FAMILY + or_erdc_age_group: SPECIAL_NEEDS + or_erdc_monthly_care_hours: 200 + state_code: OR + output: + or_erdc_maximum_monthly_rate: 1233.33 + +- name: Case 6, Area A certified family infant part-time. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_A + or_erdc_provider_type: CERTIFIED_FAMILY + or_erdc_age_group: INFANT + or_erdc_monthly_care_hours: 100 + state_code: OR + output: + or_erdc_maximum_monthly_rate: 1373 + +- name: Case 7, Area A certified center toddler hourly. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_A + or_erdc_provider_type: CERTIFIED_CENTER + or_erdc_age_group: TODDLER + or_erdc_monthly_care_hours: 10 + state_code: OR + output: + or_erdc_maximum_monthly_rate: 146.7 + +- name: Case 8, Area B standard family preschool monthly. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_B + or_erdc_provider_type: STANDARD_FAMILY + or_erdc_age_group: PRESCHOOL + or_erdc_monthly_care_hours: 200 + state_code: OR + output: + or_erdc_maximum_monthly_rate: 750 + +- name: Case 9, Area B standard center school hourly. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_B + or_erdc_provider_type: STANDARD_CENTER + or_erdc_age_group: SCHOOL + or_erdc_monthly_care_hours: 10 + state_code: OR + output: + or_erdc_maximum_monthly_rate: 43.1 + +- name: Case 10, Area B enhanced family special needs part-time. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_B + or_erdc_provider_type: ENHANCED_FAMILY + or_erdc_age_group: SPECIAL_NEEDS + or_erdc_monthly_care_hours: 100 + state_code: OR + output: + or_erdc_maximum_monthly_rate: 677 + +- name: Case 11, Area B enhanced center infant monthly. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_B + or_erdc_provider_type: ENHANCED_CENTER + or_erdc_age_group: INFANT + or_erdc_monthly_care_hours: 200 + state_code: OR + output: + or_erdc_maximum_monthly_rate: 1275 + +- name: Case 12, Area B registered family toddler hourly. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_B + or_erdc_provider_type: REGISTERED_FAMILY + or_erdc_age_group: TODDLER + or_erdc_monthly_care_hours: 10 + state_code: OR + output: + or_erdc_maximum_monthly_rate: 52.5 + +- name: Case 13, Area B certified family preschool part-time. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_B + or_erdc_provider_type: CERTIFIED_FAMILY + or_erdc_age_group: PRESCHOOL + or_erdc_monthly_care_hours: 100 + state_code: OR + output: + or_erdc_maximum_monthly_rate: 788 + +- name: Case 14, Area B certified center school monthly. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_B + or_erdc_provider_type: CERTIFIED_CENTER + or_erdc_age_group: SCHOOL + or_erdc_monthly_care_hours: 200 + state_code: OR + output: + or_erdc_maximum_monthly_rate: 800 + +- name: Case 15, Area C standard family special needs hourly. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_C + or_erdc_provider_type: STANDARD_FAMILY + or_erdc_age_group: SPECIAL_NEEDS + or_erdc_monthly_care_hours: 10 + state_code: OR + output: + or_erdc_maximum_monthly_rate: 49.5 + +- name: Case 16, Area C standard center infant monthly. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_C + or_erdc_provider_type: STANDARD_CENTER + or_erdc_age_group: INFANT + or_erdc_monthly_care_hours: 200 + state_code: OR + output: + or_erdc_maximum_monthly_rate: 1125 + +- name: Case 17, Area C enhanced family toddler part-time. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_C + or_erdc_provider_type: ENHANCED_FAMILY + or_erdc_age_group: TODDLER + or_erdc_monthly_care_hours: 100 + state_code: OR + output: + or_erdc_maximum_monthly_rate: 623 + +- name: Case 18, Area C enhanced center preschool hourly. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_C + or_erdc_provider_type: ENHANCED_CENTER + or_erdc_age_group: PRESCHOOL + or_erdc_monthly_care_hours: 10 + state_code: OR + output: + or_erdc_maximum_monthly_rate: 80.8 + +- name: Case 19, Area C registered family school monthly. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_C + or_erdc_provider_type: REGISTERED_FAMILY + or_erdc_age_group: SCHOOL + or_erdc_monthly_care_hours: 200 + state_code: OR + output: + or_erdc_maximum_monthly_rate: 800 + +- name: Case 20, Area C certified family special needs part-time. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_C + or_erdc_provider_type: CERTIFIED_FAMILY + or_erdc_age_group: SPECIAL_NEEDS + or_erdc_monthly_care_hours: 100 + state_code: OR + output: + or_erdc_maximum_monthly_rate: 956 + +- name: Case 21, Area C certified center infant hourly. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_C + or_erdc_provider_type: CERTIFIED_CENTER + or_erdc_age_group: INFANT + or_erdc_monthly_care_hours: 10 + state_code: OR + output: + or_erdc_maximum_monthly_rate: 77.5 + +- name: Tier boundary, enhanced provider at 62 hours is hourly. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_A + or_erdc_provider_type: ENHANCED_FAMILY + or_erdc_age_group: INFANT + or_erdc_monthly_care_hours: 62 + state_code: OR + output: + or_erdc_maximum_monthly_rate: 425.32 + +- name: Tier boundary, enhanced provider at 63 hours is part-time. + period: 2027-01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_A + or_erdc_provider_type: ENHANCED_FAMILY + or_erdc_age_group: INFANT + or_erdc_monthly_care_hours: 63 + state_code: OR + output: + or_erdc_maximum_monthly_rate: 879 + +- name: Tier boundary, enhanced provider at 135 hours remains part-time. + period: 2027-01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_A + or_erdc_provider_type: ENHANCED_FAMILY + or_erdc_age_group: INFANT + or_erdc_monthly_care_hours: 135 + state_code: OR + output: + or_erdc_maximum_monthly_rate: 879 + +- name: Tier boundary, enhanced provider at 136 hours is monthly. + period: 2027-01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_A + or_erdc_provider_type: ENHANCED_FAMILY + or_erdc_age_group: INFANT + or_erdc_monthly_care_hours: 136 + state_code: OR + output: + or_erdc_maximum_monthly_rate: 1_172 + +- name: Tier boundary, standard provider at 157 hours is hourly. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_A + or_erdc_provider_type: STANDARD_FAMILY + or_erdc_age_group: INFANT + or_erdc_monthly_care_hours: 157 + state_code: OR + output: + or_erdc_maximum_monthly_rate: 1_020.5 + +- name: Tier boundary, standard provider at 158 hours is monthly. + period: 2027-01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_A + or_erdc_provider_type: STANDARD_FAMILY + or_erdc_age_group: INFANT + or_erdc_monthly_care_hours: 158 + state_code: OR + output: + or_erdc_maximum_monthly_rate: 1_110 + diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/copay/or_erdc_copay.py b/policyengine_us/variables/gov/states/or/delc/erdc/copay/or_erdc_copay.py new file mode 100644 index 00000000000..17db106829e --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/copay/or_erdc_copay.py @@ -0,0 +1,43 @@ +from policyengine_us.model_api import * + + +class or_erdc_copay(Variable): + value_type = float + entity = SPMUnit + definition_period = MONTH + unit = USD + label = "Oregon ERDC monthly copay" + defined_for = StateCode.OR + reference = "https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871" + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states["or"].delc.erdc + income = spm_unit("or_erdc_countable_income", period) + size = clip( + spm_unit("spm_unit_size", period.this_year), + 2, + p.max_group_size, + ) + amount = select( + [ + size == 2, + size == 3, + size == 4, + size == 5, + size == 6, + size == 7, + size == 8, + ], + [ + p.copay.size_2.calc(income), + p.copay.size_3.calc(income), + p.copay.size_4.calc(income), + p.copay.size_5.calc(income), + p.copay.size_6.calc(income), + p.copay.size_7.calc(income), + p.copay.size_8.calc(income), + ], + default=p.copay.size_8.calc(income), + ) + categorical = spm_unit("or_erdc_categorically_eligible", period) + return where(categorical, 0, amount) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_activity_eligible.py b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_activity_eligible.py new file mode 100644 index 00000000000..e12e0675e51 --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_activity_eligible.py @@ -0,0 +1,41 @@ +from policyengine_us.model_api import * + + +class or_erdc_activity_eligible(Variable): + value_type = bool + entity = SPMUnit + definition_period = MONTH + label = "Eligible for Oregon ERDC based on caretaker activity" + defined_for = StateCode.OR + reference = "https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871" + + def formula(spm_unit, period, parameters): + categorical = spm_unit("or_erdc_categorically_eligible", period) + supervised_contact = spm_unit( + "or_erdc_supervised_contact_required", period.this_year + ) + person = spm_unit.members + caretaker = person("is_tax_unit_head_or_spouse", period.this_year) + caretaker_count = spm_unit.sum(caretaker) + working = person("weekly_hours_worked_before_lsr", period.this_year) > 0 + postsecondary_student = person( + "is_full_time_college_student", period.this_year + ) | person("is_part_time_college_student", period.this_year) + secondary_student = person("is_in_secondary_school", period.this_year) & ( + person("age", period.this_year) <= 20 + ) + medical_leave = person("or_erdc_on_medical_leave", period.this_year) + unable_to_care = person("or_erdc_unable_to_provide_care", period.this_year) + multiple_caretakers = spm_unit.project(caretaker_count > 1) + caretaker_eligible = ( + working + | postsecondary_student + | secondary_student + | medical_leave + | (multiple_caretakers & unable_to_care) + ) + has_caretaker = caretaker_count > 0 + all_caretakers_eligible = spm_unit.sum(caretaker & ~caretaker_eligible) == 0 + return ( + categorical | supervised_contact | (has_caretaker & all_caretakers_eligible) + ) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_categorically_eligible.py b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_categorically_eligible.py new file mode 100644 index 00000000000..4a36c6f8180 --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_categorically_eligible.py @@ -0,0 +1,17 @@ +from policyengine_us.model_api import * + + +class or_erdc_categorically_eligible(Variable): + value_type = bool + entity = SPMUnit + definition_period = MONTH + label = "Categorically eligible for Oregon ERDC" + defined_for = StateCode.OR + reference = "https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871" + + def formula(spm_unit, period, parameters): + tanf_enrolled = spm_unit("is_tanf_enrolled", period) + expanded_child_welfare = spm_unit( + "or_erdc_expanded_child_welfare_eligible", period.this_year + ) + return tanf_enrolled | expanded_child_welfare diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_eligible.py b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_eligible.py new file mode 100644 index 00000000000..3be9a73b7f3 --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_eligible.py @@ -0,0 +1,25 @@ +from policyengine_us.model_api import * + + +class or_erdc_eligible(Variable): + value_type = bool + entity = SPMUnit + definition_period = MONTH + label = "Eligible for Oregon ERDC" + defined_for = StateCode.OR + reference = "https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871" + + def formula(spm_unit, period, parameters): + has_eligible_child = add(spm_unit, period, ["or_erdc_eligible_child"]) > 0 + activity_eligible = spm_unit("or_erdc_activity_eligible", period) + income_eligible = spm_unit("or_erdc_income_eligible", period) + resource_eligible = spm_unit("is_ccdf_asset_eligible", period.this_year) + copay = spm_unit("or_erdc_copay", period) + allowable_cost = spm_unit("or_erdc_allowable_child_care_cost", period) + return ( + has_eligible_child + & activity_eligible + & income_eligible + & resource_eligible + & (copay < allowable_cost) + ) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_eligible_child.py b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_eligible_child.py new file mode 100644 index 00000000000..ceaef24c4c0 --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_eligible_child.py @@ -0,0 +1,23 @@ +from policyengine_us.model_api import * + + +class or_erdc_eligible_child(Variable): + value_type = bool + entity = Person + definition_period = MONTH + label = "Eligible child for Oregon ERDC" + defined_for = StateCode.OR + reference = "https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871" + + def formula(person, period, parameters): + p = parameters(period).gov.states["or"].delc.erdc.age_threshold + age = person("age", period.this_year) + special_circumstances = ( + person("is_incapable_of_self_care", period.this_year) + | person("is_in_foster_care", period.this_year) + | person("or_erdc_special_needs_rate_eligible", period.this_year) + | person("or_erdc_special_circumstances_child", period.this_year) + ) + return (age < p.child) | ( + (age < p.special_circumstances_child) & special_circumstances + ) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_income_eligible.py b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_income_eligible.py new file mode 100644 index 00000000000..63c5e008e82 --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_income_eligible.py @@ -0,0 +1,34 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.hhs.hhs_smi import smi +from policyengine_us.variables.gov.hhs.tax_unit_fpg import fpg + + +class or_erdc_income_eligible(Variable): + value_type = bool + entity = SPMUnit + definition_period = MONTH + label = "Eligible for Oregon ERDC based on income" + defined_for = StateCode.OR + reference = "https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871" + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states["or"].delc.erdc + expanded_child_welfare = spm_unit( + "or_erdc_expanded_child_welfare_eligible", period.this_year + ) + countable_income = spm_unit("or_erdc_countable_income", period) + size = spm_unit("spm_unit_size", period.this_year) + capped_size = clip(size, 2, p.max_group_size) + state_group = spm_unit.household("state_group_str", period.this_year) + state = spm_unit.household("state_code_str", period.this_year) + monthly_fpg = fpg(capped_size, state_group, period, parameters) / MONTHS_IN_YEAR + monthly_smi = smi(capped_size, state, period, parameters) / MONTHS_IN_YEAR + enrolled = add(spm_unit, period.this_year, ["is_enrolled_in_ccdf"]) > 0 + initial_limit = np.ceil(monthly_fpg * p.income.fpl_rate.initial) + ongoing_limit = max_( + np.ceil(monthly_fpg * p.income.fpl_rate.ongoing), + np.ceil(monthly_smi * p.income.smi_rate.ongoing), + ) + return expanded_child_welfare | ( + countable_income < where(enrolled, ongoing_limit, initial_limit) + ) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/income/or_erdc_countable_income.py b/policyengine_us/variables/gov/states/or/delc/erdc/income/or_erdc_countable_income.py new file mode 100644 index 00000000000..7ab57014360 --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/income/or_erdc_countable_income.py @@ -0,0 +1,12 @@ +from policyengine_us.model_api import * + + +class or_erdc_countable_income(Variable): + value_type = float + entity = SPMUnit + definition_period = MONTH + unit = USD + label = "Oregon ERDC countable income" + defined_for = StateCode.OR + reference = "https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871" + adds = "gov.states.or.delc.erdc.income.countable_income.sources" diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_child_care_subsidies.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_child_care_subsidies.py new file mode 100644 index 00000000000..5177d2551c7 --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_child_care_subsidies.py @@ -0,0 +1,11 @@ +from policyengine_us.model_api import * + + +class or_child_care_subsidies(Variable): + value_type = float + entity = SPMUnit + definition_period = YEAR + unit = USD + label = "Oregon child care subsidies" + defined_for = StateCode.OR + adds = ["or_erdc"] diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc.py new file mode 100644 index 00000000000..daa4e3b355f --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc.py @@ -0,0 +1,16 @@ +from policyengine_us.model_api import * + + +class or_erdc(Variable): + value_type = float + entity = SPMUnit + definition_period = MONTH + unit = USD + label = "Oregon Employment Related Day Care benefit amount" + defined_for = "or_erdc_eligible" + reference = "https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871" + + def formula(spm_unit, period, parameters): + allowable_cost = spm_unit("or_erdc_allowable_child_care_cost", period) + copay = spm_unit("or_erdc_copay", period) + return max_(allowable_cost - copay, 0) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_age_group.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_age_group.py new file mode 100644 index 00000000000..189e287582c --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_age_group.py @@ -0,0 +1,55 @@ +from policyengine_us.model_api import * + + +class ORERDCAgeGroup(Enum): + INFANT = "Infant" + TODDLER = "Toddler" + PRESCHOOL = "Preschool" + SCHOOL = "School" + SPECIAL_NEEDS = "Special needs" + + +class or_erdc_age_group(Variable): + value_type = Enum + entity = Person + possible_values = ORERDCAgeGroup + default_value = ORERDCAgeGroup.SCHOOL + definition_period = MONTH + label = "Oregon ERDC child age group" + defined_for = "or_erdc_eligible_child" + reference = "https://www.oregon.gov/delc/providers/Documents/Provider%20Rate%20Increase%20For%20Jan%202026_Phase%202_ENG.pdf#page=1" + + def formula(person, period, parameters): + p = parameters(period).gov.states["or"].delc.erdc.age_group + provider_type = person("or_erdc_provider_type", period) + types = provider_type.possible_values + licensed = ( + (provider_type == types.REGISTERED_FAMILY) + | (provider_type == types.CERTIFIED_FAMILY) + | (provider_type == types.CERTIFIED_CENTER) + ) + infant_max_months = where( + licensed, + p.licensed_infant_max_months, + p.license_exempt_infant_max_months, + ) + age = person("age", period.this_year) + age_months = age * MONTHS_IN_YEAR + special_needs = person("or_erdc_special_needs_rate_eligible", period.this_year) + return select( + [ + special_needs, + age_months < infant_max_months, + age_months < p.toddler_max_months, + age < p.preschool_max_years, + age >= p.preschool_max_years, + ], + [ + ORERDCAgeGroup.SPECIAL_NEEDS, + ORERDCAgeGroup.INFANT, + ORERDCAgeGroup.TODDLER, + ORERDCAgeGroup.PRESCHOOL, + ORERDCAgeGroup.SCHOOL, + ], + default=ORERDCAgeGroup.SCHOOL, + ) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_allowable_child_care_cost.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_allowable_child_care_cost.py new file mode 100644 index 00000000000..dd181916578 --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_allowable_child_care_cost.py @@ -0,0 +1,18 @@ +from policyengine_us.model_api import * + + +class or_erdc_allowable_child_care_cost(Variable): + value_type = float + entity = SPMUnit + definition_period = MONTH + unit = USD + label = "Oregon ERDC allowable child care cost" + defined_for = StateCode.OR + reference = "https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871" + + def formula(spm_unit, period, parameters): + person = spm_unit.members + eligible_child = person("or_erdc_eligible_child", period) + expenses = person("pre_subsidy_childcare_expenses", period) + maximum_rate = person("or_erdc_maximum_monthly_rate", period) + return spm_unit.sum(where(eligible_child, min_(expenses, maximum_rate), 0)) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_billing_tier.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_billing_tier.py new file mode 100644 index 00000000000..e82ed92916e --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_billing_tier.py @@ -0,0 +1,32 @@ +from policyengine_us.model_api import * + + +class ORERDCBillingTier(Enum): + HOURLY = "Hourly" + PART_TIME = "Part-time" + MONTHLY = "Monthly" + + +class or_erdc_billing_tier(Variable): + value_type = Enum + entity = Person + possible_values = ORERDCBillingTier + default_value = ORERDCBillingTier.HOURLY + definition_period = MONTH + label = "Oregon ERDC provider billing tier" + defined_for = "or_erdc_eligible_child" + reference = "https://www.oregon.gov/delc/programs/pages/rates.aspx" + + def formula(person, period, parameters): + p = parameters(period).gov.states["or"].delc.erdc.hours + hours = person("or_erdc_monthly_care_hours", period) + provider_type = person("or_erdc_provider_type", period) + types = provider_type.possible_values + standard_provider = (provider_type == types.STANDARD_FAMILY) | ( + provider_type == types.STANDARD_CENTER + ) + return where( + standard_provider, + p.standard_tier.calc(hours), + p.tiered.calc(hours), + ) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_expanded_child_welfare_eligible.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_expanded_child_welfare_eligible.py new file mode 100644 index 00000000000..59039a92960 --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_expanded_child_welfare_eligible.py @@ -0,0 +1,10 @@ +from policyengine_us.model_api import * + + +class or_erdc_expanded_child_welfare_eligible(Variable): + value_type = bool + entity = SPMUnit + definition_period = YEAR + label = "Eligible for Oregon ERDC through Expanded Child Welfare" + defined_for = StateCode.OR + reference = "https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871" diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_maximum_monthly_rate.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_maximum_monthly_rate.py new file mode 100644 index 00000000000..ce97fdec599 --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_maximum_monthly_rate.py @@ -0,0 +1,37 @@ +from policyengine_us.model_api import * + + +class or_erdc_maximum_monthly_rate(Variable): + value_type = float + entity = Person + definition_period = MONTH + unit = USD + label = "Oregon ERDC maximum monthly provider reimbursement" + defined_for = "or_erdc_eligible_child" + reference = "https://www.oregon.gov/delc/programs/pages/rates.aspx" + + def formula(person, period, parameters): + p = parameters(period).gov.states["or"].delc.erdc.rates + provider_type = person("or_erdc_provider_type", period) + tiered_provider_type = person("or_erdc_tiered_provider_type", period) + area = person("or_erdc_provider_area", period) + age_group = person("or_erdc_age_group", period) + hourly_rate = p.hourly[area][provider_type][age_group] + part_time_rate = p.part_time[area][tiered_provider_type][age_group] + monthly_rate = p.monthly[area][provider_type][age_group] + hours = person("or_erdc_monthly_care_hours", period) + tier = person("or_erdc_billing_tier", period) + tiers = tier.possible_values + return where( + hours > 0, + select( + [ + tier == tiers.HOURLY, + tier == tiers.PART_TIME, + tier == tiers.MONTHLY, + ], + [hourly_rate * hours, part_time_rate, monthly_rate], + default=0, + ), + 0, + ) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_monthly_care_hours.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_monthly_care_hours.py new file mode 100644 index 00000000000..8a7e061ba9c --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_monthly_care_hours.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * + + +class or_erdc_monthly_care_hours(Variable): + value_type = float + entity = Person + definition_period = MONTH + unit = "hour" + label = "Oregon ERDC monthly child care hours" + defined_for = "or_erdc_eligible_child" + reference = "https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871" + + def formula(person, period, parameters): + p = parameters(period).gov.states["or"].delc.erdc.hours + weekly_hours = person("childcare_hours_per_week", period.this_year) + return min_( + max_(weekly_hours, 0) * (WEEKS_IN_YEAR / MONTHS_IN_YEAR), + p.max_monthly, + ) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_on_medical_leave.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_on_medical_leave.py new file mode 100644 index 00000000000..f19d73afe52 --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_on_medical_leave.py @@ -0,0 +1,10 @@ +from policyengine_us.model_api import * + + +class or_erdc_on_medical_leave(Variable): + value_type = bool + entity = Person + definition_period = YEAR + label = "Oregon ERDC caretaker on verified medical leave" + defined_for = StateCode.OR + reference = "https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871" diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_provider_area.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_provider_area.py new file mode 100644 index 00000000000..a326f7ab24f --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_provider_area.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * + + +class ORERDCProviderArea(Enum): + AREA_A = "Area A" + AREA_B = "Area B" + AREA_C = "Area C" + + +class or_erdc_provider_area(Variable): + value_type = Enum + entity = Person + possible_values = ORERDCProviderArea + default_value = ORERDCProviderArea.AREA_C + definition_period = MONTH + label = "Oregon ERDC provider rate area" + documentation = "Area C is the conservative default until provider ZIP code mapping is implemented." + defined_for = StateCode.OR + reference = "https://www.oregon.gov/delc/programs/pages/rates.aspx" diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_provider_type.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_provider_type.py new file mode 100644 index 00000000000..df0b4da641a --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_provider_type.py @@ -0,0 +1,22 @@ +from policyengine_us.model_api import * + + +class ORERDCProviderType(Enum): + STANDARD_FAMILY = "Standard Family (FAM)" + STANDARD_CENTER = "Standard Center (NQC)" + ENHANCED_FAMILY = "Enhanced Family (QFM)" + ENHANCED_CENTER = "Enhanced Center (QEC)" + REGISTERED_FAMILY = "Registered Family (RFM)" + CERTIFIED_FAMILY = "Certified Family (CFM)" + CERTIFIED_CENTER = "Certified Center (CNT)" + + +class or_erdc_provider_type(Variable): + value_type = Enum + entity = Person + possible_values = ORERDCProviderType + default_value = ORERDCProviderType.CERTIFIED_CENTER + definition_period = MONTH + label = "Oregon ERDC provider type" + defined_for = StateCode.OR + reference = "https://www.oregon.gov/delc/programs/pages/rates.aspx" diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_special_circumstances_child.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_special_circumstances_child.py new file mode 100644 index 00000000000..8367e6166ef --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_special_circumstances_child.py @@ -0,0 +1,10 @@ +from policyengine_us.model_api import * + + +class or_erdc_special_circumstances_child(Variable): + value_type = bool + entity = Person + definition_period = YEAR + label = "Oregon ERDC child with verified special circumstances" + defined_for = StateCode.OR + reference = "https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871" diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_special_needs_rate_eligible.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_special_needs_rate_eligible.py new file mode 100644 index 00000000000..aa52b50ab83 --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_special_needs_rate_eligible.py @@ -0,0 +1,10 @@ +from policyengine_us.model_api import * + + +class or_erdc_special_needs_rate_eligible(Variable): + value_type = bool + entity = Person + definition_period = YEAR + label = "Eligible for the Oregon ERDC special needs rate" + defined_for = StateCode.OR + reference = "https://www.oregon.gov/delc/providers/Documents/Provider%20Rate%20Increase%20For%20Jan%202026_Phase%202_ENG.pdf#page=1" diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_supervised_contact_required.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_supervised_contact_required.py new file mode 100644 index 00000000000..ee4cec3ede3 --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_supervised_contact_required.py @@ -0,0 +1,10 @@ +from policyengine_us.model_api import * + + +class or_erdc_supervised_contact_required(Variable): + value_type = bool + entity = SPMUnit + definition_period = YEAR + label = "Oregon ERDC supervised contact required" + defined_for = StateCode.OR + reference = "https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871" diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_tiered_provider_type.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_tiered_provider_type.py new file mode 100644 index 00000000000..198d04cd710 --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_tiered_provider_type.py @@ -0,0 +1,41 @@ +from policyengine_us.model_api import * + + +class ORERDCTieredProviderType(Enum): + ENHANCED_FAMILY = "Enhanced Family (QFM)" + ENHANCED_CENTER = "Enhanced Center (QEC)" + REGISTERED_FAMILY = "Registered Family (RFM)" + CERTIFIED_FAMILY = "Certified Family (CFM)" + CERTIFIED_CENTER = "Certified Center (CNT)" + + +class or_erdc_tiered_provider_type(Variable): + value_type = Enum + entity = Person + possible_values = ORERDCTieredProviderType + default_value = ORERDCTieredProviderType.ENHANCED_FAMILY + definition_period = MONTH + label = "Oregon ERDC enhanced or licensed provider type" + defined_for = "or_erdc_eligible_child" + reference = "https://www.oregon.gov/delc/programs/pages/rates.aspx" + + def formula(person, period, parameters): + provider_type = person("or_erdc_provider_type", period) + types = provider_type.possible_values + return select( + [ + provider_type == types.ENHANCED_FAMILY, + provider_type == types.ENHANCED_CENTER, + provider_type == types.REGISTERED_FAMILY, + provider_type == types.CERTIFIED_FAMILY, + provider_type == types.CERTIFIED_CENTER, + ], + [ + ORERDCTieredProviderType.ENHANCED_FAMILY, + ORERDCTieredProviderType.ENHANCED_CENTER, + ORERDCTieredProviderType.REGISTERED_FAMILY, + ORERDCTieredProviderType.CERTIFIED_FAMILY, + ORERDCTieredProviderType.CERTIFIED_CENTER, + ], + default=ORERDCTieredProviderType.ENHANCED_FAMILY, + ) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_unable_to_provide_care.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_unable_to_provide_care.py new file mode 100644 index 00000000000..9b6f1edf605 --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_unable_to_provide_care.py @@ -0,0 +1,10 @@ +from policyengine_us.model_api import * + + +class or_erdc_unable_to_provide_care(Variable): + value_type = bool + entity = Person + definition_period = YEAR + label = "Oregon ERDC caretaker unable to provide care" + defined_for = StateCode.OR + reference = "https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871" diff --git a/sources/working_references.md b/sources/working_references.md new file mode 100644 index 00000000000..9ac806e1a97 --- /dev/null +++ b/sources/working_references.md @@ -0,0 +1,53 @@ +# Oregon Employment Related Day Care (ERDC) working references + +## Official Program Name + +**Federal Program**: Child Care and Development Fund (CCDF) +**State's Official Name**: Employment Related Day Care (ERDC) +**Abbreviation**: ERDC +**Agency**: Oregon Department of Early Learning and Care (DELC) +**Source**: OAR 414-175-0001 and Oregon DELC ERDC program page + +**Variable Prefix**: `or_erdc` + +## Primary sources + +1. [OAR Chapter 414, Division 175](https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871) — current ERDC administrative rules, including June 1, 2026 amendments. +2. [Oregon DELC ERDC program page](https://www.oregon.gov/delc/programs/pages/erdc.aspx) — public eligibility summary, current waitlist, and March 2026 income standards. +3. [Oregon DELC ERDC copays and billing](https://www.oregon.gov/delc/programs/pages/copays-billing.aspx) — copay and allowable-cost overview. +4. [Oregon DELC ERDC maximum rates](https://www.oregon.gov/delc/programs/pages/rates.aspx) — current 2026 rate tables and ZIP-code areas. +5. [Oregon Programs Eligibility Notebook (OPEN), July 2026](https://sharedsystems.dhsoha.state.or.us/DHSForms/Served/de2818.pdf#page=215) — operational guidance on categorical ERDC; PDF file pages 215-217. + +## Verified rule map + +- OAR 414-175-0015: ERDC filing, financial, need, and benefit groups; the PolicyEngine SPM unit is the closest available entity but is an approximation. +- OAR 414-175-0020: Oregon residency and immunization requirements. State scoping models residency; immunization verification is administrative. +- OAR 414-175-0021: child citizenship/noncitizen requirements applied only until May 1, 2024, so current ERDC does not require an immigration test. +- OAR 414-175-0022: eligible children are under age 13, or under age 18 with specified special circumstances. +- OAR 414-175-0023: every caretaker must work, attend qualifying education, or be on medical leave; exceptions cover a second caretaker unable to provide care and supervised contact. Categorically eligible families bypass the ordinary activity test and copay. +- OAR 414-175-0025: TANF and Expanded Child Welfare are categorical pathways. TANF waives child-care need; Expanded Child Welfare also excludes income. Both retain the resource ceiling and other federal requirements. +- OAR 414-175-0030: available assets are countable unless specifically excluded; gross income is used, with enumerated unavailable-income rules. +- OAR 414-175-0035: income-source treatment. Relevant modeled sources include wages, self-employment net of permitted costs, interest, dividends, rent, pensions, Social Security, SSI, unemployment, workers compensation, spousal support, veterans benefits, and TANF. Many narrow statutory payments lack exact PolicyEngine variables. +- OAR 414-175-0040: prospective monthly budgeting; Expanded Child Welfare income is not countable. +- OAR 414-175-0050(1): resources above $1,000,000 are ineligible. Initial monthly income must be strictly below 200% FPL. Ongoing/recertification income must be strictly below the greater of 250% FPL or 85% SMI. Group size is capped at eight. +- OAR 414-175-0050(3): March 2026 monthly copays are schedules for group sizes two through eight or more; categorical and specified transition/leave circumstances can waive them. +- OAR 414-175-0050(2): allowable cost is the lesser of billed cost and the applicable provider-rate cap; the subsidy is allowable cost less copay. +- OAR 414-175-0075: 2026 provider rates vary by Area A/B/C, provider category, child age, and hourly/part-time/monthly billing. Payable hours and special circumstances add further caps. +- OAR 414-175-0076: high-needs supplements require an administratively assessed score and supporting documentation. + +## 2026 standards + +- Initial monthly limits at 200% FPL, sizes 2-8+: $3,607; $4,554; $5,500; $6,447; $7,394; $8,340; $9,287. +- Ongoing monthly 85% SMI values, sizes 2-8+: $5,926; $7,321; $8,715; $10,109; $11,504; $11,765; $12,026. +- Ongoing monthly 250% FPL values, sizes 2-8+: $4,509; $5,692; $6,875; $8,059; $9,242; $10,425; $11,609. +- The copay schedule is effective March 1, 2026 and ranges from $0 to $130 depending on size and countable monthly income. +- Licensed, NQC, and QEC rate tables are effective January 1, 2026; license-exempt FAM and QFM rates are effective March 1, 2026. + +## Known source and modeling issues + +- OAR 414-175-0050(3)(b)(A)(v) contains an apparent typo (`$34,057.99`); the contiguous schedule and next bracket show that the intended upper boundary is $4,057.99. The implementation should encode bracket starts, avoiding reliance on the typo. +- The OPEN PDF initially failed through the web fetcher but was successfully downloaded directly, text-extracted, and relevant pages rendered at 300 DPI under `/tmp/or-ccap-sources/`. +- The waitlist, provider approval, immunization verification, unpaid-copay history, certification-period protections, and administratively assessed special circumstances are not inferable from survey inputs. +- Exact self-employment gross receipts and separately permitted business costs are not both available. The closest modeled amount is net self-employment income. +- ERDC includes TANF as countable income, but the calculated `tanf` variable is commented out of the source list because adding it would create a child care/TANF circular dependency. +- Provider rate area is a direct Area A/B/C Enum input in this PR; automatic ZIP-code mapping is deferred to a follow-up PR. From 31de34278bf17343f3edeac8378771e9575bb0b0 Mon Sep 17 00:00:00 2001 From: Ziming Date: Sat, 11 Jul 2026 14:24:21 -0400 Subject: [PATCH 2/7] Fix review findings: income, hours, billing gates, waivers, high-needs - Floor self-employment losses at zero per OAR 414-175-0035(81)(e) - Authorized care hours: 20/40/75 weekly bands, 20h categorical default, 25% travel allowance, 4.3 weekly-to-monthly conversion per OAR 414-175-0023(5) - Part-time billing tier now requires provider part-time billing input per OAR 414-175-0075(3)(b),(c),(e) - Cap hourly billing at the monthly maximum per OAR 414-175-0075 - Add job-loss and at-application copay waivers per OAR 414-175-0023(3)(d),(f) - Restrict supervised-contact exception to multiple-caretaker units - Parameterize education activity age limit; add GED pathway input - Age-13-17 pathway now requires OAR 414-175-0076 high-needs eligibility; add high-needs supplemental payment ($5 hourly / $840 monthly per factor) - Point variable/parameter references at controlling OAR subsections - Document microsim default bias and CNT infant-boundary ambiguity - Untrack sources/working_references.md; fix trailing whitespace - Update/add tests: 88 cases passing Co-Authored-By: Claude Fable 5 --- .../or/delc/erdc/age_threshold/education.yaml | 11 ++ .../gov/states/or/delc/erdc/copay/size_2.yaml | 1 - .../gov/states/or/delc/erdc/copay/size_3.yaml | 1 - .../gov/states/or/delc/erdc/copay/size_4.yaml | 1 - .../gov/states/or/delc/erdc/copay/size_5.yaml | 1 - .../gov/states/or/delc/erdc/copay/size_6.yaml | 1 - .../gov/states/or/delc/erdc/copay/size_7.yaml | 1 - .../gov/states/or/delc/erdc/copay/size_8.yaml | 1 - .../hours/authorized/categorical_default.yaml | 11 ++ .../hours/authorized/travel_allowance.yaml | 11 ++ .../or/delc/erdc/hours/authorized/weekly.yaml | 29 ++++ .../hours/authorized/weekly_to_monthly.yaml | 11 ++ .../erdc/income/countable_income/sources.yaml | 6 +- .../rates/high_needs_supplement/hourly.yaml | 11 ++ .../rates/high_needs_supplement/monthly.yaml | 11 ++ .../gov/states/or/delc/erdc/integration.yaml | 151 ++++++++++++++++-- .../delc/erdc/or_erdc_activity_eligible.yaml | 122 +++++++++++++- .../or/delc/erdc/or_erdc_age_group.yaml | 73 +++++++++ .../states/or/delc/erdc/or_erdc_copay.yaml | 92 +++++++++++ .../or/delc/erdc/or_erdc_eligible_child.yaml | 18 +++ .../or/delc/erdc/or_erdc_income_eligible.yaml | 83 ++++++++++ .../erdc/or_erdc_maximum_monthly_rate.yaml | 103 ++++++++++++ .../delc/erdc/or_erdc_monthly_care_hours.yaml | 100 ++++++++++++ .../or/delc/erdc/copay/or_erdc_copay.py | 11 +- .../eligibility/or_erdc_activity_eligible.py | 21 +-- .../eligibility/or_erdc_eligible_child.py | 2 +- .../eligibility/or_erdc_income_eligible.py | 4 +- ...r_erdc_countable_self_employment_income.py | 25 +++ .../gov/states/or/delc/erdc/or_erdc.py | 4 +- .../states/or/delc/erdc/or_erdc_age_group.py | 5 + .../or/delc/erdc/or_erdc_billing_tier.py | 19 ++- .../or_erdc_caretaker_weekly_need_hours.py | 28 ++++ .../delc/erdc/or_erdc_high_needs_factors.py | 15 ++ .../erdc/or_erdc_high_needs_rate_eligible.py | 12 ++ .../or/delc/erdc/or_erdc_in_ged_program.py | 12 ++ .../delc/erdc/or_erdc_maximum_monthly_rate.py | 25 ++- .../or_erdc_medical_leave_at_application.py | 12 ++ .../delc/erdc/or_erdc_monthly_care_hours.py | 24 ++- .../delc/erdc/or_erdc_permanent_job_loss.py | 12 ++ .../or/delc/erdc/or_erdc_provider_area.py | 6 +- .../erdc/or_erdc_provider_bills_part_time.py | 13 ++ .../or/delc/erdc/or_erdc_provider_type.py | 4 + .../or_erdc_supervised_contact_required.py | 8 +- sources/working_references.md | 53 ------ 44 files changed, 1062 insertions(+), 103 deletions(-) create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/age_threshold/education.yaml create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/hours/authorized/categorical_default.yaml create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/hours/authorized/travel_allowance.yaml create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/hours/authorized/weekly.yaml create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/hours/authorized/weekly_to_monthly.yaml create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/rates/high_needs_supplement/hourly.yaml create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/rates/high_needs_supplement/monthly.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_age_group.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_income_eligible.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_monthly_care_hours.yaml create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/income/or_erdc_countable_self_employment_income.py create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_caretaker_weekly_need_hours.py create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_high_needs_factors.py create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_high_needs_rate_eligible.py create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_in_ged_program.py create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_medical_leave_at_application.py create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_permanent_job_loss.py create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_provider_bills_part_time.py delete mode 100644 sources/working_references.md diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/age_threshold/education.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/age_threshold/education.yaml new file mode 100644 index 00000000000..7282883cf9d --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/age_threshold/education.yaml @@ -0,0 +1,11 @@ +description: Oregon limits the secondary education activity pathway to caretakers of this age or younger under the Employment Related Day Care program. +values: + 2023-07-01: 20 + +metadata: + unit: year + period: year + label: Oregon ERDC education activity age threshold + reference: + - title: OAR 414-175-0023(1)(a)(B)(ii) + href: https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0023 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_2.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_2.yaml index 1cbefce623e..b4466679536 100644 --- a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_2.yaml +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_2.yaml @@ -30,4 +30,3 @@ brackets: 2026-03-01: 4_058 amount: 2026-03-01: 100 - diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_3.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_3.yaml index aded32c09c4..cf4f74d59d2 100644 --- a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_3.yaml +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_3.yaml @@ -34,4 +34,3 @@ brackets: 2026-03-01: 5_123 amount: 2026-03-01: 110 - diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_4.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_4.yaml index 42fb737ee1c..b0da5bbff3a 100644 --- a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_4.yaml +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_4.yaml @@ -34,4 +34,3 @@ brackets: 2026-03-01: 6_188 amount: 2026-03-01: 120 - diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_5.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_5.yaml index 5084fb49123..0437f10158f 100644 --- a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_5.yaml +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_5.yaml @@ -34,4 +34,3 @@ brackets: 2026-03-01: 7_253 amount: 2026-03-01: 130 - diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_6.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_6.yaml index 7749325cba0..df3ef386bfb 100644 --- a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_6.yaml +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_6.yaml @@ -34,4 +34,3 @@ brackets: 2026-03-01: 8_318 amount: 2026-03-01: 130 - diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_7.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_7.yaml index 9871bf24b71..e150064ab6c 100644 --- a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_7.yaml +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_7.yaml @@ -34,4 +34,3 @@ brackets: 2026-03-01: 9_383 amount: 2026-03-01: 130 - diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_8.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_8.yaml index 8289f8337ee..0a6b451d466 100644 --- a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_8.yaml +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_8.yaml @@ -34,4 +34,3 @@ brackets: 2026-03-01: 10_448 amount: 2026-03-01: 130 - diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/hours/authorized/categorical_default.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/hours/authorized/categorical_default.yaml new file mode 100644 index 00000000000..556e121e178 --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/hours/authorized/categorical_default.yaml @@ -0,0 +1,11 @@ +description: Oregon allows this number of weekly child care hours for categorically eligible caretakers under the Employment Related Day Care program. +values: + 2023-07-01: 20 + +metadata: + unit: hour + period: week + label: Oregon ERDC categorical default weekly hours + reference: + - title: OAR 414-175-0023(5)(b) + href: https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0023 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/hours/authorized/travel_allowance.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/hours/authorized/travel_allowance.yaml new file mode 100644 index 00000000000..7336071b15a --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/hours/authorized/travel_allowance.yaml @@ -0,0 +1,11 @@ +description: Oregon adds this share of the weekly hours allowance for travel or commuting under the Employment Related Day Care program. +values: + 2023-07-01: 0.25 + +metadata: + unit: /1 + period: year + label: Oregon ERDC travel hours allowance share + reference: + - title: OAR 414-175-0023(5)(c) + href: https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0023 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/hours/authorized/weekly.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/hours/authorized/weekly.yaml new file mode 100644 index 00000000000..9959b8720ec --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/hours/authorized/weekly.yaml @@ -0,0 +1,29 @@ +description: Oregon allows these weekly child care hours based on the caretaker's allowable child care need under the Employment Related Day Care program. +metadata: + type: single_amount + threshold_unit: hour + amount_unit: hour + period: week + label: Oregon ERDC weekly authorized hours + reference: + - title: OAR 414-175-0023(5)(a) + href: https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0023 + +brackets: + # 20 or fewer need hours -> 20; more than 20 up to 40 -> 40; more than 40 -> up to 75 + - threshold: + 2023-07-01: 0 + amount: + 2023-07-01: 0 + - threshold: + 2023-07-01: 0.0001 + amount: + 2023-07-01: 20 + - threshold: + 2023-07-01: 20.0001 + amount: + 2023-07-01: 40 + - threshold: + 2023-07-01: 40.0001 + amount: + 2023-07-01: 75 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/hours/authorized/weekly_to_monthly.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/hours/authorized/weekly_to_monthly.yaml new file mode 100644 index 00000000000..bd411538f60 --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/hours/authorized/weekly_to_monthly.yaml @@ -0,0 +1,11 @@ +description: Oregon multiplies the weekly hours allowance by this factor to convert it to monthly authorized hours under the Employment Related Day Care program. +values: + 2023-07-01: 4.3 + +metadata: + unit: /1 + period: year + label: Oregon ERDC weekly to monthly hours conversion factor + reference: + - title: OAR 414-175-0023(5)(d) + href: https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0023 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/income/countable_income/sources.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/income/countable_income/sources.yaml index 1bb0463bc24..2e45dce09eb 100644 --- a/policyengine_us/parameters/gov/states/or/delc/erdc/income/countable_income/sources.yaml +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/income/countable_income/sources.yaml @@ -2,9 +2,9 @@ description: Oregon counts these income sources under the Employment Related Day values: 2026-03-01: - employment_income - - self_employment_income - - sstb_self_employment_income - - farm_operations_income + # Self-employment sources are floored at zero per business so a loss cannot + # offset other countable income, per OAR 414-175-0035(81)(a) and (81)(e). + - or_erdc_countable_self_employment_income - military_basic_pay - disability_benefits - social_security diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/rates/high_needs_supplement/hourly.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/rates/high_needs_supplement/hourly.yaml new file mode 100644 index 00000000000..f7472b04b8d --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/rates/high_needs_supplement/hourly.yaml @@ -0,0 +1,11 @@ +description: Oregon adds this amount per assessed factor to the hourly provider rate for children eligible for the high needs rate under the Employment Related Day Care program. +values: + 2026-01-01: 5 + +metadata: + unit: currency-USD + period: hour + label: Oregon ERDC high needs hourly rate supplement + reference: + - title: OAR 414-175-0076(2)(a) + href: https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0076 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/rates/high_needs_supplement/monthly.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/rates/high_needs_supplement/monthly.yaml new file mode 100644 index 00000000000..0e55912bea5 --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/rates/high_needs_supplement/monthly.yaml @@ -0,0 +1,11 @@ +description: Oregon adds this amount per assessed factor to the monthly provider rate for children eligible for the high needs rate under the Employment Related Day Care program. +values: + 2026-01-01: 840 + +metadata: + unit: currency-USD + period: month + label: Oregon ERDC high needs monthly rate supplement + reference: + - title: OAR 414-175-0076(2)(b) + href: https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0076 diff --git a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/integration.yaml index 8979db42e48..f522a1282af 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/integration.yaml @@ -63,7 +63,7 @@ or_erdc_eligible: false or_erdc: 0 -- name: Case 3, continuing family uses the ongoing income limit and part-time rate. +- name: Case 3, continuing family uses the ongoing income limit and monthly rate. period: 2027-01 absolute_error_margin: 0.1 input: @@ -89,12 +89,17 @@ members: [parent, child, sibling] state_code: OR output: + # Banded from the caretaker's 40 work hours: 40 -> 40 weekly, +25% travel, + # x4.3, capped at 215 monthly, so both children bill monthly. or_erdc_countable_income: 6_666.67 or_erdc_income_eligible: true - or_erdc_billing_tier: [HOURLY, PART_TIME, HOURLY] - or_erdc_maximum_monthly_rate: [0, 623, 0] + or_erdc_billing_tier: [HOURLY, MONTHLY, MONTHLY] + # Child: Area B enhanced family toddler monthly 831. + # Sibling (age 10, default certified center Area C school): monthly 800. + or_erdc_maximum_monthly_rate: [0, 831, 800] or_erdc_copay: 110 - or_erdc: 513 + # Allowable = min(800 expenses, 831) + min(0, 800) = 800; 800 - 110 = 690. + or_erdc: 690 - name: Case 4, Expanded Child Welfare bypasses income and activity tests. period: 2027-01 @@ -124,8 +129,10 @@ or_erdc_activity_eligible: true or_erdc_income_eligible: true or_erdc_copay: 0 - or_erdc_maximum_monthly_rate: [0, 429] - or_erdc: 429 + # Categorical 20-hour floor: 20 weekly, +25% travel, x4.3 = 107.5 monthly. + # Standard family infant hourly: min(4.95 * 107.5, 855) = 532.13. + or_erdc_maximum_monthly_rate: [0, 532.13] + or_erdc: 532.13 - name: Case 5, assets above the CCDF limit make the family ineligible. period: 2027-01 @@ -185,7 +192,7 @@ or_erdc_copay: 5 or_erdc: 1_826 -- name: Case 7, negative self-employment income reduces countable income. +- name: Case 7, self-employment loss does not offset other countable income. period: 2027-01 absolute_error_margin: 0.1 input: @@ -209,10 +216,14 @@ members: [parent, child] state_code: OR output: - or_erdc_countable_income: 1_000 - or_erdc_copay: 0 - or_erdc_maximum_monthly_rate: [0, 308.97] - or_erdc: 308.97 + # Self-employment loss is floored at 0 per business, so it no longer offsets + # wages: countable = 24,000 employment / 12 = 2,000. + or_erdc_countable_income: 2_000 + or_erdc_copay: 5 + # 40 work hours band to 215 monthly hours, so the standard center bills + # monthly: rate 782. Allowable = min(500 expenses, 782) = 500; 500 - 5 = 495. + or_erdc_maximum_monthly_rate: [0, 782] + or_erdc: 495 - name: Case 8, annual state and federal aggregators include ERDC. period: 2027 @@ -239,3 +250,121 @@ output: or_child_care_subsidies: 17_880 child_care_subsidies: 17_880 + +- name: Case 9, TANF enrollment bypasses the activity test and waives the copay. + period: 2027-01 + absolute_error_margin: 0.1 + input: + people: + parent: + age: 30 + employment_income: 20_000 + weekly_hours_worked_before_lsr: 0 + child: + age: 4 + or_erdc_provider_area: AREA_A + or_erdc_provider_type: CERTIFIED_CENTER + pre_subsidy_childcare_expenses: 18_000 + spm_units: + spm_unit: + members: [parent, child] + is_tanf_enrolled: true + households: + household: + members: [parent, child] + state_code: OR + output: + or_erdc_categorically_eligible: true + # Parent does not work, so only the TANF categorical path grants activity. + or_erdc_activity_eligible: true + or_erdc_income_eligible: true + or_erdc_copay: 0 + # Categorical 20-hour floor -> 107.5 monthly hours; certified center part-time + # band collapses to hourly (provider does not bill part-time): + # min(11 * 107.5, 1563) = 1182.5. + or_erdc_maximum_monthly_rate: [0, 1_182.5] + or_erdc: 1_182.5 + +- name: Case 10, two paying children sum their allowable costs. + period: 2027-01 + absolute_error_margin: 0.1 + input: + people: + parent: + age: 35 + employment_income: 40_000 + weekly_hours_worked_before_lsr: 40 + child1: + age: 4 + or_erdc_provider_area: AREA_A + or_erdc_provider_type: CERTIFIED_CENTER + pre_subsidy_childcare_expenses: 12_000 + child2: + age: 3 + or_erdc_provider_area: AREA_A + or_erdc_provider_type: CERTIFIED_CENTER + pre_subsidy_childcare_expenses: 12_000 + spm_units: + spm_unit: + members: [parent, child1, child2] + households: + household: + members: [parent, child1, child2] + state_code: OR + output: + # Both preschoolers bill monthly at the Area A certified center rate 1563. + or_erdc_maximum_monthly_rate: [0, 1_563, 1_563] + # min(1000, 1563) + min(1000, 1563) = 2000. + or_erdc_allowable_child_care_cost: 2_000 + or_erdc_copay: 5 + or_erdc: 1_995 + +- name: Case 11, copay meeting the allowable cost makes the family ineligible. + period: 2027-01 + absolute_error_margin: 0.1 + input: + people: + parent: + age: 40 + employment_income: 30_000 + weekly_hours_worked_before_lsr: 40 + child: + age: 4 + or_erdc_provider_area: AREA_A + or_erdc_provider_type: CERTIFIED_CENTER + pre_subsidy_childcare_expenses: 60 + spm_units: + spm_unit: + members: [parent, child] + households: + household: + members: [parent, child] + state_code: OR + output: + or_erdc_income_eligible: true + or_erdc_activity_eligible: true + # Allowable = min(60/12, 1563) = 5, which equals the copay, so the strict + # copay < allowable gate fails and the family receives nothing. + or_erdc_allowable_child_care_cost: 5 + or_erdc_copay: 5 + or_erdc_eligible: false + or_erdc: 0 + +- name: Case 12, a household with no eligible child receives no benefit. + period: 2027-01 + input: + people: + parent: + age: 30 + employment_income: 20_000 + weekly_hours_worked_before_lsr: 40 + spm_units: + spm_unit: + members: [parent] + households: + household: + members: [parent] + state_code: OR + output: + or_erdc_eligible: false + or_erdc: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_activity_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_activity_eligible.yaml index 7e26782e5e3..cfb20d970bd 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_activity_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_activity_eligible.yaml @@ -117,13 +117,14 @@ output: or_erdc_activity_eligible: true -- name: Supervised contact waives the ordinary caretaker activity test. +- name: A single caretaker with supervised contact required is not activity eligible. period: 2027-01 input: people: parent: age: 30 weekly_hours_worked_before_lsr: 0 + or_erdc_supervised_contact_required: true child: age: 4 tax_units: @@ -132,10 +133,127 @@ spm_units: spm_unit: members: [parent, child] - or_erdc_supervised_contact_required: true households: household: members: [parent, child] state_code: OR + output: + or_erdc_activity_eligible: false + +- name: A part-time college student caretaker is activity eligible. + period: 2027-01 + input: + people: + parent: + age: 25 + weekly_hours_worked_before_lsr: 0 + is_part_time_college_student: true + child: + age: 4 + tax_units: + tax_unit: + members: [parent, child] + spm_units: + spm_unit: + members: [parent, child] + households: + household: + members: [parent, child] + state_code: OR + output: + or_erdc_activity_eligible: true + +- name: A secondary school student caretaker at the education age limit is activity eligible. + period: 2027-01 + input: + people: + parent: + age: 20 + weekly_hours_worked_before_lsr: 0 + is_in_secondary_school: true + child: + age: 1 + tax_units: + tax_unit: + members: [parent, child] + spm_units: + spm_unit: + members: [parent, child] + households: + household: + members: [parent, child] + state_code: OR + output: + or_erdc_activity_eligible: true + +- name: A secondary school student caretaker above the education age limit is ineligible. + period: 2027-01 + input: + people: + parent: + age: 21 + weekly_hours_worked_before_lsr: 0 + is_in_secondary_school: true + child: + age: 1 + tax_units: + tax_unit: + members: [parent, child] + spm_units: + spm_unit: + members: [parent, child] + households: + household: + members: [parent, child] + state_code: OR + output: + or_erdc_activity_eligible: false + +- name: A caretaker in a GED program at the education age limit is activity eligible. + period: 2027-01 + input: + people: + parent: + age: 20 + weekly_hours_worked_before_lsr: 0 + or_erdc_in_ged_program: true + child: + age: 1 + tax_units: + tax_unit: + members: [parent, child] + spm_units: + spm_unit: + members: [parent, child] + households: + household: + members: [parent, child] + state_code: OR + output: + or_erdc_activity_eligible: true + +- name: A second caretaker requiring supervised contact satisfies the exception. + period: 2027-01 + input: + people: + parent_1: + age: 32 + weekly_hours_worked_before_lsr: 40 + parent_2: + age: 30 + weekly_hours_worked_before_lsr: 0 + or_erdc_supervised_contact_required: true + child: + age: 4 + tax_units: + tax_unit: + members: [parent_1, parent_2, child] + spm_units: + spm_unit: + members: [parent_1, parent_2, child] + households: + household: + members: [parent_1, parent_2, child] + state_code: OR output: or_erdc_activity_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_age_group.yaml b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_age_group.yaml new file mode 100644 index 00000000000..9616945d5a6 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_age_group.yaml @@ -0,0 +1,73 @@ +# The infant cutoff depends on provider licensure (24 months licensed, +# 12 months license-exempt); other age boundaries are shared. + +- name: An 18-month-old at a licensed certified center is an infant. + period: 2027-01 + input: + or_erdc_eligible_child: true + age: 1.5 + or_erdc_provider_type: CERTIFIED_CENTER + state_code: OR + output: + or_erdc_age_group: INFANT + +- name: An 18-month-old at a license-exempt standard family provider is a toddler. + period: 2027-01 + input: + or_erdc_eligible_child: true + age: 1.5 + or_erdc_provider_type: STANDARD_FAMILY + state_code: OR + output: + or_erdc_age_group: TODDLER + +- name: A child just under three years old is a toddler. + period: 2027-01 + input: + or_erdc_eligible_child: true + age: 2.9 + or_erdc_provider_type: CERTIFIED_CENTER + state_code: OR + output: + or_erdc_age_group: TODDLER + +- name: A child age three is a preschooler. + period: 2027-01 + input: + or_erdc_eligible_child: true + age: 3 + or_erdc_provider_type: CERTIFIED_CENTER + state_code: OR + output: + or_erdc_age_group: PRESCHOOL + +- name: A child age five is a preschooler. + period: 2027-01 + input: + or_erdc_eligible_child: true + age: 5 + or_erdc_provider_type: CERTIFIED_CENTER + state_code: OR + output: + or_erdc_age_group: PRESCHOOL + +- name: A child age six is school age. + period: 2027-01 + input: + or_erdc_eligible_child: true + age: 6 + or_erdc_provider_type: CERTIFIED_CENTER + state_code: OR + output: + or_erdc_age_group: SCHOOL + +- name: A special needs child uses the special needs group regardless of age. + period: 2027-01 + input: + or_erdc_eligible_child: true + age: 10 + or_erdc_special_needs_rate_eligible: true + or_erdc_provider_type: CERTIFIED_CENTER + state_code: OR + output: + or_erdc_age_group: SPECIAL_NEEDS diff --git a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_copay.yaml b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_copay.yaml index e2b37df2575..15f7bd6e95e 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_copay.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_copay.yaml @@ -16,3 +16,95 @@ state_code: OR output: or_erdc_copay: 0 + +- name: Group size 2 copay just below the second bracket boundary. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_countable_income: 2_704 + spm_unit_size: 2 + state_code: OR + output: + or_erdc_copay: 5 + +- name: Group size 2 copay at the second bracket boundary. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_countable_income: 2_705 + spm_unit_size: 2 + state_code: OR + output: + or_erdc_copay: 10 + +- name: Group size 4 copay in the twenty-dollar bracket. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_countable_income: 5_000 + spm_unit_size: 4 + state_code: OR + output: + or_erdc_copay: 20 + +- name: Group size 5 copay in the ten-dollar bracket. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_countable_income: 5_000 + spm_unit_size: 5 + state_code: OR + output: + or_erdc_copay: 10 + +- name: Group size 6 copay in the twenty-five-dollar bracket. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_countable_income: 6_500 + spm_unit_size: 6 + state_code: OR + output: + or_erdc_copay: 25 + +- name: Group size 7 copay in the seventy-dollar bracket. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_countable_income: 9_000 + spm_unit_size: 7 + state_code: OR + output: + or_erdc_copay: 70 + +- name: Group size 8 copay in the highest bracket. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_countable_income: 11_000 + spm_unit_size: 8 + state_code: OR + output: + or_erdc_copay: 130 + +- name: A permanent job loss waives the copay. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_countable_income: 5_000 + or_erdc_permanent_job_loss: true + spm_unit_size: 2 + state_code: OR + output: + or_erdc_copay: 0 + +- name: Medical leave at application waives the copay. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_countable_income: 5_000 + or_erdc_medical_leave_at_application: true + spm_unit_size: 2 + state_code: OR + output: + or_erdc_copay: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_eligible_child.yaml b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_eligible_child.yaml index a699e75bc5e..8ce8a4d4082 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_eligible_child.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_eligible_child.yaml @@ -31,3 +31,21 @@ state_code: OR output: or_erdc_eligible_child: false + +- name: Child age 15 eligible for the high needs rate is an eligible child. + period: 2027-01 + input: + age: 15 + or_erdc_high_needs_rate_eligible: true + state_code: OR + output: + or_erdc_eligible_child: true + +- name: Child age 15 with only the special needs rate is not an eligible child. + period: 2027-01 + input: + age: 15 + or_erdc_special_needs_rate_eligible: true + state_code: OR + output: + or_erdc_eligible_child: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_income_eligible.yaml new file mode 100644 index 00000000000..94956ecf957 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_income_eligible.yaml @@ -0,0 +1,83 @@ +# Tested at 2026-01, where the FPG (size 2 contiguous: 21,640/yr) and Oregon SMI +# (123,027 four-person base) are the published values, so limits are exact. +# Initial limit (size 2) = ceil(21,640 / 12 * 2) = 3,607. +# Ongoing limit (size 2) = max(ceil(1,803.33 * 2.5), ceil(6,971.53 * 0.85)) +# = max(4,509, 5,926) = 5,926, so the 85% SMI term binds. + +- name: Initial applicant just below the 200% FPL limit is income eligible. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 28 + spm_units: + spm_unit: + members: [person1, person2] + or_erdc_countable_income: 3_606 + households: + household: + members: [person1, person2] + state_code: OR + output: + or_erdc_income_eligible: true + +- name: Initial applicant at the 200% FPL limit is income ineligible. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 28 + spm_units: + spm_unit: + members: [person1, person2] + or_erdc_countable_income: 3_607 + households: + household: + members: [person1, person2] + state_code: OR + output: + or_erdc_income_eligible: false + +- name: Enrolled family just below the binding 85% SMI limit is income eligible. + period: 2026-01 + input: + people: + person1: + age: 30 + is_enrolled_in_ccdf: true + person2: + age: 28 + spm_units: + spm_unit: + members: [person1, person2] + or_erdc_countable_income: 5_925 + households: + household: + members: [person1, person2] + state_code: OR + output: + or_erdc_income_eligible: true + +- name: Enrolled family at the binding 85% SMI limit is income ineligible. + period: 2026-01 + input: + people: + person1: + age: 30 + is_enrolled_in_ccdf: true + person2: + age: 28 + spm_units: + spm_unit: + members: [person1, person2] + or_erdc_countable_income: 5_926 + households: + household: + members: [person1, person2] + state_code: OR + output: + or_erdc_income_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_maximum_monthly_rate.yaml b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_maximum_monthly_rate.yaml index 44bb3ceddd8..aa0d6e72715 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_maximum_monthly_rate.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_maximum_monthly_rate.yaml @@ -35,6 +35,7 @@ or_erdc_provider_type: ENHANCED_FAMILY or_erdc_age_group: PRESCHOOL or_erdc_monthly_care_hours: 100 + or_erdc_provider_bills_part_time: true state_code: OR output: or_erdc_maximum_monthly_rate: 737 @@ -74,6 +75,7 @@ or_erdc_provider_type: CERTIFIED_FAMILY or_erdc_age_group: INFANT or_erdc_monthly_care_hours: 100 + or_erdc_provider_bills_part_time: true state_code: OR output: or_erdc_maximum_monthly_rate: 1373 @@ -126,6 +128,7 @@ or_erdc_provider_type: ENHANCED_FAMILY or_erdc_age_group: SPECIAL_NEEDS or_erdc_monthly_care_hours: 100 + or_erdc_provider_bills_part_time: true state_code: OR output: or_erdc_maximum_monthly_rate: 677 @@ -165,6 +168,7 @@ or_erdc_provider_type: CERTIFIED_FAMILY or_erdc_age_group: PRESCHOOL or_erdc_monthly_care_hours: 100 + or_erdc_provider_bills_part_time: true state_code: OR output: or_erdc_maximum_monthly_rate: 788 @@ -217,6 +221,7 @@ or_erdc_provider_type: ENHANCED_FAMILY or_erdc_age_group: TODDLER or_erdc_monthly_care_hours: 100 + or_erdc_provider_bills_part_time: true state_code: OR output: or_erdc_maximum_monthly_rate: 623 @@ -256,6 +261,7 @@ or_erdc_provider_type: CERTIFIED_FAMILY or_erdc_age_group: SPECIAL_NEEDS or_erdc_monthly_care_hours: 100 + or_erdc_provider_bills_part_time: true state_code: OR output: or_erdc_maximum_monthly_rate: 956 @@ -294,6 +300,7 @@ or_erdc_provider_type: ENHANCED_FAMILY or_erdc_age_group: INFANT or_erdc_monthly_care_hours: 63 + or_erdc_provider_bills_part_time: true state_code: OR output: or_erdc_maximum_monthly_rate: 879 @@ -306,6 +313,7 @@ or_erdc_provider_type: ENHANCED_FAMILY or_erdc_age_group: INFANT or_erdc_monthly_care_hours: 135 + or_erdc_provider_bills_part_time: true state_code: OR output: or_erdc_maximum_monthly_rate: 879 @@ -347,3 +355,98 @@ output: or_erdc_maximum_monthly_rate: 1_110 +- name: Enhanced provider part-time band bills hourly when it does not bill part-time. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_A + or_erdc_provider_type: ENHANCED_FAMILY + or_erdc_age_group: PRESCHOOL + or_erdc_monthly_care_hours: 100 + or_erdc_provider_bills_part_time: false + state_code: OR + output: + # 100 hours falls in the enhanced part-time band, but the provider does not + # bill part-time, so the tier collapses to hourly: min(5.7 * 100, 982) = 570. + or_erdc_maximum_monthly_rate: 570 + +- name: High needs adds five dollars per factor per hour on hourly billing. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_A + or_erdc_provider_type: CERTIFIED_CENTER + or_erdc_age_group: INFANT + or_erdc_monthly_care_hours: 10 + or_erdc_high_needs_rate_eligible: true + or_erdc_high_needs_factors: 2 + state_code: OR + output: + # min(12 * 10, 2083) + 2 factors * $5 * 10 hours = 120 + 100 = 220. + or_erdc_maximum_monthly_rate: 220 + +- name: High needs adds eight hundred forty dollars per factor on monthly billing. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_A + or_erdc_provider_type: CERTIFIED_CENTER + or_erdc_age_group: INFANT + or_erdc_monthly_care_hours: 200 + or_erdc_high_needs_rate_eligible: true + or_erdc_high_needs_factors: 2 + state_code: OR + output: + # Monthly rate 2083 + 2 factors * $840 = 2083 + 1680 = 3763. + or_erdc_maximum_monthly_rate: 3_763 + +- name: High needs adds the monthly supplement on part-time billing. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_A + or_erdc_provider_type: CERTIFIED_CENTER + or_erdc_age_group: INFANT + or_erdc_monthly_care_hours: 100 + or_erdc_provider_bills_part_time: true + or_erdc_high_needs_rate_eligible: true + or_erdc_high_needs_factors: 1 + state_code: OR + output: + # Part-time rate 1562 + 1 factor * $840 = 2402. + or_erdc_maximum_monthly_rate: 2_402 + +- name: High needs supplement requires the high needs rate eligibility flag. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_A + or_erdc_provider_type: CERTIFIED_CENTER + or_erdc_age_group: INFANT + or_erdc_monthly_care_hours: 10 + or_erdc_high_needs_rate_eligible: false + or_erdc_high_needs_factors: 2 + state_code: OR + output: + # Factors present but not high-needs eligible, so no supplement: 12 * 10 = 120. + or_erdc_maximum_monthly_rate: 120 + +- name: Hourly billing is capped at the monthly rate near the monthly threshold. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_eligible_child: true + or_erdc_provider_area: AREA_B + or_erdc_provider_type: STANDARD_CENTER + or_erdc_age_group: PRESCHOOL + or_erdc_monthly_care_hours: 157 + state_code: OR + output: + # 7.13 * 157 = 1119.41 exceeds the 782 monthly rate, so hourly billing is + # capped at 782, keeping reimbursement monotonic across the 158-hour tier. + or_erdc_maximum_monthly_rate: 782 diff --git a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_monthly_care_hours.yaml b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_monthly_care_hours.yaml new file mode 100644 index 00000000000..2658d3478a3 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_monthly_care_hours.yaml @@ -0,0 +1,100 @@ +# Weekly need is banded (20 / 40 / 75), a 25% travel allowance is added, and the +# result is converted to monthly hours (x4.3) and capped at 215. + +- name: Twenty or fewer weekly work hours authorize the 20-hour band. + period: 2027-01 + absolute_error_margin: 0.01 + input: + people: + parent: + age: 30 + weekly_hours_worked_before_lsr: 15 + child: + age: 4 + tax_units: + tax_unit: + members: [parent, child] + spm_units: + spm_unit: + members: [parent, child] + households: + household: + members: [parent, child] + state_code: OR + output: + # 20 weekly hours * 1.25 travel * 4.3 = 107.5 monthly hours. + or_erdc_monthly_care_hours: [0, 107.5] + +- name: Twenty to forty weekly work hours authorize the 40-hour band. + period: 2027-01 + absolute_error_margin: 0.01 + input: + people: + parent: + age: 30 + weekly_hours_worked_before_lsr: 30 + child: + age: 4 + tax_units: + tax_unit: + members: [parent, child] + spm_units: + spm_unit: + members: [parent, child] + households: + household: + members: [parent, child] + state_code: OR + output: + # 40 weekly hours * 1.25 travel * 4.3 = 215 monthly hours. + or_erdc_monthly_care_hours: [0, 215] + +- name: High weekly work hours are capped at 215 monthly hours. + period: 2027-01 + absolute_error_margin: 0.01 + input: + people: + parent: + age: 30 + weekly_hours_worked_before_lsr: 60 + child: + age: 4 + tax_units: + tax_unit: + members: [parent, child] + spm_units: + spm_unit: + members: [parent, child] + households: + household: + members: [parent, child] + state_code: OR + output: + # 75 weekly hours * 1.25 * 4.3 = 403.125, capped at 215 monthly hours. + or_erdc_monthly_care_hours: [0, 215] + +- name: A categorically eligible caretaker receives the 20-hour weekly floor. + period: 2027-01 + absolute_error_margin: 0.01 + input: + people: + parent: + age: 30 + weekly_hours_worked_before_lsr: 0 + child: + age: 4 + tax_units: + tax_unit: + members: [parent, child] + spm_units: + spm_unit: + members: [parent, child] + or_erdc_expanded_child_welfare_eligible: true + households: + household: + members: [parent, child] + state_code: OR + output: + # No work hours, but the categorical 20-hour floor applies: + # 20 * 1.25 * 4.3 = 107.5 monthly hours. + or_erdc_monthly_care_hours: [0, 107.5] diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/copay/or_erdc_copay.py b/policyengine_us/variables/gov/states/or/delc/erdc/copay/or_erdc_copay.py index 17db106829e..6be5c0ef129 100644 --- a/policyengine_us/variables/gov/states/or/delc/erdc/copay/or_erdc_copay.py +++ b/policyengine_us/variables/gov/states/or/delc/erdc/copay/or_erdc_copay.py @@ -8,7 +8,9 @@ class or_erdc_copay(Variable): unit = USD label = "Oregon ERDC monthly copay" defined_for = StateCode.OR - reference = "https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871" + reference = ( + "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0050" + ) def formula(spm_unit, period, parameters): p = parameters(period).gov.states["or"].delc.erdc @@ -40,4 +42,9 @@ def formula(spm_unit, period, parameters): default=p.copay.size_8.calc(income), ) categorical = spm_unit("or_erdc_categorically_eligible", period) - return where(categorical, 0, amount) + job_loss_waiver = spm_unit("or_erdc_permanent_job_loss", period.this_year) + medical_leave_waiver = spm_unit( + "or_erdc_medical_leave_at_application", period.this_year + ) + copay_waived = categorical | job_loss_waiver | medical_leave_waiver + return where(copay_waived, 0, amount) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_activity_eligible.py b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_activity_eligible.py index e12e0675e51..ac79c64664b 100644 --- a/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_activity_eligible.py +++ b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_activity_eligible.py @@ -10,10 +10,8 @@ class or_erdc_activity_eligible(Variable): reference = "https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871" def formula(spm_unit, period, parameters): + p = parameters(period).gov.states["or"].delc.erdc categorical = spm_unit("or_erdc_categorically_eligible", period) - supervised_contact = spm_unit( - "or_erdc_supervised_contact_required", period.this_year - ) person = spm_unit.members caretaker = person("is_tax_unit_head_or_spouse", period.this_year) caretaker_count = spm_unit.sum(caretaker) @@ -21,21 +19,26 @@ def formula(spm_unit, period, parameters): postsecondary_student = person( "is_full_time_college_student", period.this_year ) | person("is_part_time_college_student", period.this_year) - secondary_student = person("is_in_secondary_school", period.this_year) & ( - person("age", period.this_year) <= 20 + education_age_eligible = ( + person("age", period.this_year) <= p.age_threshold.education ) + secondary_student = ( + person("is_in_secondary_school", period.this_year) + | person("or_erdc_in_ged_program", period.this_year) + ) & education_age_eligible medical_leave = person("or_erdc_on_medical_leave", period.this_year) unable_to_care = person("or_erdc_unable_to_provide_care", period.this_year) + supervised_contact = person( + "or_erdc_supervised_contact_required", period.this_year + ) multiple_caretakers = spm_unit.project(caretaker_count > 1) caretaker_eligible = ( working | postsecondary_student | secondary_student | medical_leave - | (multiple_caretakers & unable_to_care) + | (multiple_caretakers & (unable_to_care | supervised_contact)) ) has_caretaker = caretaker_count > 0 all_caretakers_eligible = spm_unit.sum(caretaker & ~caretaker_eligible) == 0 - return ( - categorical | supervised_contact | (has_caretaker & all_caretakers_eligible) - ) + return categorical | (has_caretaker & all_caretakers_eligible) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_eligible_child.py b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_eligible_child.py index ceaef24c4c0..e22a4592267 100644 --- a/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_eligible_child.py +++ b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_eligible_child.py @@ -15,7 +15,7 @@ def formula(person, period, parameters): special_circumstances = ( person("is_incapable_of_self_care", period.this_year) | person("is_in_foster_care", period.this_year) - | person("or_erdc_special_needs_rate_eligible", period.this_year) + | person("or_erdc_high_needs_rate_eligible", period.this_year) | person("or_erdc_special_circumstances_child", period.this_year) ) return (age < p.child) | ( diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_income_eligible.py b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_income_eligible.py index 63c5e008e82..1a21f49f2ca 100644 --- a/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_income_eligible.py +++ b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_income_eligible.py @@ -9,7 +9,9 @@ class or_erdc_income_eligible(Variable): definition_period = MONTH label = "Eligible for Oregon ERDC based on income" defined_for = StateCode.OR - reference = "https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871" + reference = ( + "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0050" + ) def formula(spm_unit, period, parameters): p = parameters(period).gov.states["or"].delc.erdc diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/income/or_erdc_countable_self_employment_income.py b/policyengine_us/variables/gov/states/or/delc/erdc/income/or_erdc_countable_self_employment_income.py new file mode 100644 index 00000000000..d5a20ac06d4 --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/income/or_erdc_countable_self_employment_income.py @@ -0,0 +1,25 @@ +from policyengine_us.model_api import * + + +class or_erdc_countable_self_employment_income(Variable): + value_type = float + entity = Person + definition_period = YEAR + unit = USD + label = "Oregon ERDC countable self-employment income" + defined_for = StateCode.OR + reference = ( + "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0035" + ) + + def formula(person, period, parameters): + # OAR 414-175-0035(81)(e) counts gross self-employment receipts before + # costs, and (81)(a) determines each business separately. PolicyEngine + # only tracks tax-net self-employment earnings, so each source is + # floored at zero to keep a business loss from offsetting other income; + # this still understates income by netting out business costs. + return ( + max_(person("self_employment_income", period), 0) + + max_(person("sstb_self_employment_income", period), 0) + + max_(person("farm_operations_income", period), 0) + ) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc.py index daa4e3b355f..4ac00e109c5 100644 --- a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc.py +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc.py @@ -8,7 +8,9 @@ class or_erdc(Variable): unit = USD label = "Oregon Employment Related Day Care benefit amount" defined_for = "or_erdc_eligible" - reference = "https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871" + reference = ( + "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0075" + ) def formula(spm_unit, period, parameters): allowable_cost = spm_unit("or_erdc_allowable_child_care_cost", period) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_age_group.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_age_group.py index 189e287582c..c7d7dc68f51 100644 --- a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_age_group.py +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_age_group.py @@ -23,6 +23,11 @@ def formula(person, period, parameters): p = parameters(period).gov.states["or"].delc.erdc.age_group provider_type = person("or_erdc_provider_type", period) types = provider_type.possible_values + # The Provider Guide Insert grants the infant window of 6 weeks through + # 23 months only to "Registered or Certified Family care" (RFM, CFM); + # it states no infant boundary for certified centers (CNT). We apply + # the same 24-month cutoff to CNT pending DELC confirmation (a ~$96/mo + # difference for children aged 12-23 months at certified centers). licensed = ( (provider_type == types.REGISTERED_FAMILY) | (provider_type == types.CERTIFIED_FAMILY) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_billing_tier.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_billing_tier.py index e82ed92916e..9bf611272e1 100644 --- a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_billing_tier.py +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_billing_tier.py @@ -15,7 +15,9 @@ class or_erdc_billing_tier(Variable): definition_period = MONTH label = "Oregon ERDC provider billing tier" defined_for = "or_erdc_eligible_child" - reference = "https://www.oregon.gov/delc/programs/pages/rates.aspx" + reference = ( + "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0075" + ) def formula(person, period, parameters): p = parameters(period).gov.states["or"].delc.erdc.hours @@ -25,8 +27,21 @@ def formula(person, period, parameters): standard_provider = (provider_type == types.STANDARD_FAMILY) | ( provider_type == types.STANDARD_CENTER ) + # OAR 414-175-0075(3)(b),(c),(e): an enhanced or licensed provider is + # paid the part-time monthly rate below the full-time threshold only + # when it customarily bills all families part-time and is the primary + # provider; otherwise that care is paid hourly. When the provider does + # not bill part-time, collapse the part-time band into the hourly tier. + bills_part_time = person("or_erdc_provider_bills_part_time", period) + tiered = p.tiered.calc(hours) + tiered_without_part_time = where( + tiered == ORERDCBillingTier.PART_TIME.index, + ORERDCBillingTier.HOURLY.index, + tiered, + ) + enhanced_tier = where(bills_part_time, tiered, tiered_without_part_time) return where( standard_provider, p.standard_tier.calc(hours), - p.tiered.calc(hours), + enhanced_tier, ) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_caretaker_weekly_need_hours.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_caretaker_weekly_need_hours.py new file mode 100644 index 00000000000..dc89b470f9b --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_caretaker_weekly_need_hours.py @@ -0,0 +1,28 @@ +from policyengine_us.model_api import * + + +class or_erdc_caretaker_weekly_need_hours(Variable): + value_type = float + entity = SPMUnit + definition_period = MONTH + unit = "hour" + label = "Oregon ERDC caretaker weekly child care need hours" + defined_for = StateCode.OR + reference = ( + "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0023" + ) + + def formula(spm_unit, period, parameters): + person = spm_unit.members + is_caretaker = person("is_tax_unit_head_or_spouse", period.this_year) + # OAR 414-175-0023(5) sets hours from the caretaker's allowable child + # care need. We proxy that need with work hours before labor supply + # responses (avoiding a circular dependency); education, training, and + # study hours are not separately tracked. OAR 0023(5) is silent on + # multi-caretaker units, so we authorize on the lowest-need caretaker, + # the more conservative reading. Non-caretakers get infinity so they + # never lower the need. + weekly_hours = person("weekly_hours_worked_before_lsr", period.this_year) + has_caretaker = spm_unit.sum(is_caretaker) > 0 + lowest_caretaker_hours = spm_unit.min(where(is_caretaker, weekly_hours, np.inf)) + return where(has_caretaker, lowest_caretaker_hours, 0) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_high_needs_factors.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_high_needs_factors.py new file mode 100644 index 00000000000..6661f88ed70 --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_high_needs_factors.py @@ -0,0 +1,15 @@ +from policyengine_us.model_api import * + + +class or_erdc_high_needs_factors(Variable): + value_type = int + entity = Person + definition_period = YEAR + default_value = 0 + label = "Oregon ERDC high needs assessed factor count" + # OAR 414-175-0076(2)-(4): the assessed high needs factor ranges from 0 to + # 2 and multiplies the hourly or monthly supplement. + defined_for = StateCode.OR + reference = ( + "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0076" + ) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_high_needs_rate_eligible.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_high_needs_rate_eligible.py new file mode 100644 index 00000000000..ef7eba145cd --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_high_needs_rate_eligible.py @@ -0,0 +1,12 @@ +from policyengine_us.model_api import * + + +class or_erdc_high_needs_rate_eligible(Variable): + value_type = bool + entity = Person + definition_period = YEAR + label = "Eligible for the Oregon ERDC high need rate" + defined_for = StateCode.OR + reference = ( + "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0076" + ) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_in_ged_program.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_in_ged_program.py new file mode 100644 index 00000000000..a70e8eaf3e6 --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_in_ged_program.py @@ -0,0 +1,12 @@ +from policyengine_us.model_api import * + + +class or_erdc_in_ged_program(Variable): + value_type = bool + entity = Person + definition_period = YEAR + label = "Oregon ERDC caretaker participating in a GED program" + defined_for = StateCode.OR + reference = ( + "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0023" + ) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_maximum_monthly_rate.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_maximum_monthly_rate.py index ce97fdec599..b4ac23f4eab 100644 --- a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_maximum_monthly_rate.py +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_maximum_monthly_rate.py @@ -8,7 +8,9 @@ class or_erdc_maximum_monthly_rate(Variable): unit = USD label = "Oregon ERDC maximum monthly provider reimbursement" defined_for = "or_erdc_eligible_child" - reference = "https://www.oregon.gov/delc/programs/pages/rates.aspx" + reference = ( + "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0075" + ) def formula(person, period, parameters): p = parameters(period).gov.states["or"].delc.erdc.rates @@ -20,6 +22,21 @@ def formula(person, period, parameters): part_time_rate = p.part_time[area][tiered_provider_type][age_group] monthly_rate = p.monthly[area][provider_type][age_group] hours = person("or_erdc_monthly_care_hours", period) + + # OAR 414-175-0076(2): for children eligible for the high needs rate, + # an assessed factor (0-2) adds $5 per hour on hourly billing or $840 + # on monthly billing, in addition to the base provider rate. + factors = person("or_erdc_high_needs_factors", period.this_year) + high_needs = person("or_erdc_high_needs_rate_eligible", period.this_year) + supplement = p.high_needs_supplement + hourly_supplement = where(high_needs, factors * supplement.hourly * hours, 0) + monthly_supplement = where(high_needs, factors * supplement.monthly, 0) + + # OAR 414-175-0075(3),(6): hourly billing is the lesser of hours times + # the hourly rate and the full-time monthly rate, which also keeps the + # reimbursement monotonic across the monthly-billing threshold. + hourly_payment = min_(hourly_rate * hours, monthly_rate) + hourly_supplement + tier = person("or_erdc_billing_tier", period) tiers = tier.possible_values return where( @@ -30,7 +47,11 @@ def formula(person, period, parameters): tier == tiers.PART_TIME, tier == tiers.MONTHLY, ], - [hourly_rate * hours, part_time_rate, monthly_rate], + [ + hourly_payment, + part_time_rate + monthly_supplement, + monthly_rate + monthly_supplement, + ], default=0, ), 0, diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_medical_leave_at_application.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_medical_leave_at_application.py new file mode 100644 index 00000000000..7f1c947a7b2 --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_medical_leave_at_application.py @@ -0,0 +1,12 @@ +from policyengine_us.model_api import * + + +class or_erdc_medical_leave_at_application(Variable): + value_type = bool + entity = SPMUnit + definition_period = YEAR + label = "Oregon ERDC caretaker on medical leave at initial application" + defined_for = StateCode.OR + reference = ( + "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0023" + ) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_monthly_care_hours.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_monthly_care_hours.py index 8a7e061ba9c..57bf710ca0d 100644 --- a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_monthly_care_hours.py +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_monthly_care_hours.py @@ -8,12 +8,26 @@ class or_erdc_monthly_care_hours(Variable): unit = "hour" label = "Oregon ERDC monthly child care hours" defined_for = "or_erdc_eligible_child" - reference = "https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871" + reference = ( + "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0023" + ) def formula(person, period, parameters): p = parameters(period).gov.states["or"].delc.erdc.hours - weekly_hours = person("childcare_hours_per_week", period.this_year) - return min_( - max_(weekly_hours, 0) * (WEEKS_IN_YEAR / MONTHS_IN_YEAR), - p.max_monthly, + need_hours = person.spm_unit("or_erdc_caretaker_weekly_need_hours", period) + # OAR 414-175-0023(5)(a): band the weekly need into 20 / 40 / up to 75 + # allowed weekly hours. + banded_weekly = p.authorized.weekly.calc(need_hours) + # OAR 414-175-0023(5)(b): categorically eligible caretakers receive a + # 20-hour weekly baseline even when the activity test is waived. + categorical = person.spm_unit("or_erdc_categorically_eligible", period) + weekly_allowance = where( + categorical, + max_(banded_weekly, p.authorized.categorical_default), + banded_weekly, ) + # OAR 414-175-0023(5)(c)-(d): add a travel allowance, then convert the + # weekly allowance to monthly hours, capped at the monthly maximum. + weekly_with_travel = weekly_allowance * (1 + p.authorized.travel_allowance) + monthly = weekly_with_travel * p.authorized.weekly_to_monthly + return min_(monthly, p.max_monthly) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_permanent_job_loss.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_permanent_job_loss.py new file mode 100644 index 00000000000..5878d636b96 --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_permanent_job_loss.py @@ -0,0 +1,12 @@ +from policyengine_us.model_api import * + + +class or_erdc_permanent_job_loss(Variable): + value_type = bool + entity = SPMUnit + definition_period = YEAR + label = "Oregon ERDC caretaker with a permanent job loss from all employment" + defined_for = StateCode.OR + reference = ( + "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0023" + ) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_provider_area.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_provider_area.py index a326f7ab24f..73dc5c2bffa 100644 --- a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_provider_area.py +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_provider_area.py @@ -11,9 +11,13 @@ class or_erdc_provider_area(Variable): value_type = Enum entity = Person possible_values = ORERDCProviderArea + # Area C is the conservative (lowest-rate) default until provider ZIP code + # mapping is implemented. In population runs this understates rates on its + # own, partly offsetting the highest-rate CERTIFIED_CENTER provider-type + # default; the remedy is populating provider area from data, not changing + # this default. default_value = ORERDCProviderArea.AREA_C definition_period = MONTH label = "Oregon ERDC provider rate area" - documentation = "Area C is the conservative default until provider ZIP code mapping is implemented." defined_for = StateCode.OR reference = "https://www.oregon.gov/delc/programs/pages/rates.aspx" diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_provider_bills_part_time.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_provider_bills_part_time.py new file mode 100644 index 00000000000..e98f53fcf4f --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_provider_bills_part_time.py @@ -0,0 +1,13 @@ +from policyengine_us.model_api import * + + +class or_erdc_provider_bills_part_time(Variable): + value_type = bool + entity = Person + definition_period = MONTH + default_value = False + label = "Oregon ERDC provider customarily bills part-time monthly" + defined_for = StateCode.OR + reference = ( + "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0075" + ) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_provider_type.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_provider_type.py index df0b4da641a..ddf805f0130 100644 --- a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_provider_type.py +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_provider_type.py @@ -15,6 +15,10 @@ class or_erdc_provider_type(Variable): value_type = Enum entity = Person possible_values = ORERDCProviderType + # CERTIFIED_CENTER (CNT) is the highest-rate provider type, so as a + # population default it biases modeled rates upward; it partly offsets the + # lowest-rate AREA_C area default. The remedy is populating provider type + # from data, not changing this default. default_value = ORERDCProviderType.CERTIFIED_CENTER definition_period = MONTH label = "Oregon ERDC provider type" diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_supervised_contact_required.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_supervised_contact_required.py index ee4cec3ede3..df6147686e5 100644 --- a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_supervised_contact_required.py +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_supervised_contact_required.py @@ -3,8 +3,10 @@ class or_erdc_supervised_contact_required(Variable): value_type = bool - entity = SPMUnit + entity = Person definition_period = YEAR - label = "Oregon ERDC supervised contact required" + label = "Oregon ERDC supervised contact required with a caretaker" defined_for = StateCode.OR - reference = "https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871" + reference = ( + "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0023" + ) diff --git a/sources/working_references.md b/sources/working_references.md deleted file mode 100644 index 9ac806e1a97..00000000000 --- a/sources/working_references.md +++ /dev/null @@ -1,53 +0,0 @@ -# Oregon Employment Related Day Care (ERDC) working references - -## Official Program Name - -**Federal Program**: Child Care and Development Fund (CCDF) -**State's Official Name**: Employment Related Day Care (ERDC) -**Abbreviation**: ERDC -**Agency**: Oregon Department of Early Learning and Care (DELC) -**Source**: OAR 414-175-0001 and Oregon DELC ERDC program page - -**Variable Prefix**: `or_erdc` - -## Primary sources - -1. [OAR Chapter 414, Division 175](https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871) — current ERDC administrative rules, including June 1, 2026 amendments. -2. [Oregon DELC ERDC program page](https://www.oregon.gov/delc/programs/pages/erdc.aspx) — public eligibility summary, current waitlist, and March 2026 income standards. -3. [Oregon DELC ERDC copays and billing](https://www.oregon.gov/delc/programs/pages/copays-billing.aspx) — copay and allowable-cost overview. -4. [Oregon DELC ERDC maximum rates](https://www.oregon.gov/delc/programs/pages/rates.aspx) — current 2026 rate tables and ZIP-code areas. -5. [Oregon Programs Eligibility Notebook (OPEN), July 2026](https://sharedsystems.dhsoha.state.or.us/DHSForms/Served/de2818.pdf#page=215) — operational guidance on categorical ERDC; PDF file pages 215-217. - -## Verified rule map - -- OAR 414-175-0015: ERDC filing, financial, need, and benefit groups; the PolicyEngine SPM unit is the closest available entity but is an approximation. -- OAR 414-175-0020: Oregon residency and immunization requirements. State scoping models residency; immunization verification is administrative. -- OAR 414-175-0021: child citizenship/noncitizen requirements applied only until May 1, 2024, so current ERDC does not require an immigration test. -- OAR 414-175-0022: eligible children are under age 13, or under age 18 with specified special circumstances. -- OAR 414-175-0023: every caretaker must work, attend qualifying education, or be on medical leave; exceptions cover a second caretaker unable to provide care and supervised contact. Categorically eligible families bypass the ordinary activity test and copay. -- OAR 414-175-0025: TANF and Expanded Child Welfare are categorical pathways. TANF waives child-care need; Expanded Child Welfare also excludes income. Both retain the resource ceiling and other federal requirements. -- OAR 414-175-0030: available assets are countable unless specifically excluded; gross income is used, with enumerated unavailable-income rules. -- OAR 414-175-0035: income-source treatment. Relevant modeled sources include wages, self-employment net of permitted costs, interest, dividends, rent, pensions, Social Security, SSI, unemployment, workers compensation, spousal support, veterans benefits, and TANF. Many narrow statutory payments lack exact PolicyEngine variables. -- OAR 414-175-0040: prospective monthly budgeting; Expanded Child Welfare income is not countable. -- OAR 414-175-0050(1): resources above $1,000,000 are ineligible. Initial monthly income must be strictly below 200% FPL. Ongoing/recertification income must be strictly below the greater of 250% FPL or 85% SMI. Group size is capped at eight. -- OAR 414-175-0050(3): March 2026 monthly copays are schedules for group sizes two through eight or more; categorical and specified transition/leave circumstances can waive them. -- OAR 414-175-0050(2): allowable cost is the lesser of billed cost and the applicable provider-rate cap; the subsidy is allowable cost less copay. -- OAR 414-175-0075: 2026 provider rates vary by Area A/B/C, provider category, child age, and hourly/part-time/monthly billing. Payable hours and special circumstances add further caps. -- OAR 414-175-0076: high-needs supplements require an administratively assessed score and supporting documentation. - -## 2026 standards - -- Initial monthly limits at 200% FPL, sizes 2-8+: $3,607; $4,554; $5,500; $6,447; $7,394; $8,340; $9,287. -- Ongoing monthly 85% SMI values, sizes 2-8+: $5,926; $7,321; $8,715; $10,109; $11,504; $11,765; $12,026. -- Ongoing monthly 250% FPL values, sizes 2-8+: $4,509; $5,692; $6,875; $8,059; $9,242; $10,425; $11,609. -- The copay schedule is effective March 1, 2026 and ranges from $0 to $130 depending on size and countable monthly income. -- Licensed, NQC, and QEC rate tables are effective January 1, 2026; license-exempt FAM and QFM rates are effective March 1, 2026. - -## Known source and modeling issues - -- OAR 414-175-0050(3)(b)(A)(v) contains an apparent typo (`$34,057.99`); the contiguous schedule and next bracket show that the intended upper boundary is $4,057.99. The implementation should encode bracket starts, avoiding reliance on the typo. -- The OPEN PDF initially failed through the web fetcher but was successfully downloaded directly, text-extracted, and relevant pages rendered at 300 DPI under `/tmp/or-ccap-sources/`. -- The waitlist, provider approval, immunization verification, unpaid-copay history, certification-period protections, and administratively assessed special circumstances are not inferable from survey inputs. -- Exact self-employment gross receipts and separately permitted business costs are not both available. The closest modeled amount is net self-employment income. -- ERDC includes TANF as countable income, but the calculated `tanf` variable is commented out of the source list because adding it would create a child care/TANF circular dependency. -- Provider rate area is a direct Area A/B/C Enum input in this PR; automatic ZIP-code mapping is deferred to a follow-up PR. From d32f4ae1e7fa90d57c5d19b71b51cc9c6219bdd3 Mon Sep 17 00:00:00 2001 From: Ziming Date: Mon, 13 Jul 2026 15:12:08 -0400 Subject: [PATCH 3/7] Fix high-needs rate category, round authorized hours up, document overlap rule Per OAR 414-175-0076(1) and the OPEN manual (07/2026, pp. 428, 448-449): - High-needs eligibility implies the special-needs rate category, so the supplement adds to the special-needs base rate rather than the ordinary age-based rate. - Monthly authorized hours round up before the 215-hour cap (the worker guide publishes the 20-hour band as 108 hours, not 107.5). - Two-caretaker units count only overlapping work or school hours; the lowest caretaker's hours remain as the maximum-possible-overlap proxy since schedules are not tracked, now documented with the OPEN citation. Co-Authored-By: Claude Fable 5 --- .../gov/states/or/delc/erdc/integration.yaml | 17 +++++++++-------- .../states/or/delc/erdc/or_erdc_age_group.yaml | 13 +++++++++++++ .../delc/erdc/or_erdc_monthly_care_hours.yaml | 10 +++++----- .../states/or/delc/erdc/or_erdc_age_group.py | 6 +++++- .../erdc/or_erdc_caretaker_weekly_need_hours.py | 13 ++++++++----- .../or/delc/erdc/or_erdc_monthly_care_hours.py | 8 ++++++-- 6 files changed, 46 insertions(+), 21 deletions(-) diff --git a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/integration.yaml index f522a1282af..2c448aeaf7d 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/integration.yaml @@ -129,10 +129,11 @@ or_erdc_activity_eligible: true or_erdc_income_eligible: true or_erdc_copay: 0 - # Categorical 20-hour floor: 20 weekly, +25% travel, x4.3 = 107.5 monthly. - # Standard family infant hourly: min(4.95 * 107.5, 855) = 532.13. - or_erdc_maximum_monthly_rate: [0, 532.13] - or_erdc: 532.13 + # Categorical 20-hour floor: 20 weekly, +25% travel, x4.3 = 107.5, + # rounded up to 108 monthly hours. + # Standard family infant hourly: min(4.95 * 108, 855) = 534.6. + or_erdc_maximum_monthly_rate: [0, 534.6] + or_erdc: 534.6 - name: Case 5, assets above the CCDF limit make the family ineligible. period: 2027-01 @@ -279,11 +280,11 @@ or_erdc_activity_eligible: true or_erdc_income_eligible: true or_erdc_copay: 0 - # Categorical 20-hour floor -> 107.5 monthly hours; certified center part-time + # Categorical 20-hour floor -> 108 monthly hours; certified center part-time # band collapses to hourly (provider does not bill part-time): - # min(11 * 107.5, 1563) = 1182.5. - or_erdc_maximum_monthly_rate: [0, 1_182.5] - or_erdc: 1_182.5 + # min(11 * 108, 1563) = 1188. + or_erdc_maximum_monthly_rate: [0, 1_188] + or_erdc: 1_188 - name: Case 10, two paying children sum their allowable costs. period: 2027-01 diff --git a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_age_group.yaml b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_age_group.yaml index 9616945d5a6..8df507e82bf 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_age_group.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_age_group.yaml @@ -71,3 +71,16 @@ state_code: OR output: or_erdc_age_group: SPECIAL_NEEDS + +- name: A high-needs child uses the special needs group without the rate flag. + period: 2027-01 + input: + or_erdc_eligible_child: true + age: 10 + or_erdc_high_needs_rate_eligible: true + or_erdc_provider_type: CERTIFIED_CENTER + state_code: OR + output: + # OAR 414-175-0076(1): high-needs children must qualify for the special + # needs rate, so the high-needs flag alone selects the special needs group. + or_erdc_age_group: SPECIAL_NEEDS diff --git a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_monthly_care_hours.yaml b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_monthly_care_hours.yaml index 2658d3478a3..5c5d0d336ae 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_monthly_care_hours.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_monthly_care_hours.yaml @@ -1,5 +1,5 @@ # Weekly need is banded (20 / 40 / 75), a 25% travel allowance is added, and the -# result is converted to monthly hours (x4.3) and capped at 215. +# result is converted to monthly hours (x4.3), rounded up, and capped at 215. - name: Twenty or fewer weekly work hours authorize the 20-hour band. period: 2027-01 @@ -22,8 +22,8 @@ members: [parent, child] state_code: OR output: - # 20 weekly hours * 1.25 travel * 4.3 = 107.5 monthly hours. - or_erdc_monthly_care_hours: [0, 107.5] + # 20 weekly hours * 1.25 travel * 4.3 = 107.5, rounded up to 108. + or_erdc_monthly_care_hours: [0, 108] - name: Twenty to forty weekly work hours authorize the 40-hour band. period: 2027-01 @@ -96,5 +96,5 @@ state_code: OR output: # No work hours, but the categorical 20-hour floor applies: - # 20 * 1.25 * 4.3 = 107.5 monthly hours. - or_erdc_monthly_care_hours: [0, 107.5] + # 20 * 1.25 * 4.3 = 107.5, rounded up to 108. + or_erdc_monthly_care_hours: [0, 108] diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_age_group.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_age_group.py index c7d7dc68f51..7b5ad0a15da 100644 --- a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_age_group.py +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_age_group.py @@ -41,9 +41,13 @@ def formula(person, period, parameters): age = person("age", period.this_year) age_months = age * MONTHS_IN_YEAR special_needs = person("or_erdc_special_needs_rate_eligible", period.this_year) + # OAR 414-175-0076(1) grants the high needs supplement only to + # children eligible for the special needs rate, so high-needs + # eligibility implies the special-needs rate category. + high_needs = person("or_erdc_high_needs_rate_eligible", period.this_year) return select( [ - special_needs, + special_needs | high_needs, age_months < infant_max_months, age_months < p.toddler_max_months, age < p.preschool_max_years, diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_caretaker_weekly_need_hours.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_caretaker_weekly_need_hours.py index dc89b470f9b..29e3da4fc80 100644 --- a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_caretaker_weekly_need_hours.py +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_caretaker_weekly_need_hours.py @@ -9,7 +9,8 @@ class or_erdc_caretaker_weekly_need_hours(Variable): label = "Oregon ERDC caretaker weekly child care need hours" defined_for = StateCode.OR reference = ( - "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0023" + "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0023", + "https://sharedsystems.dhsoha.state.or.us/DHSForms/Served/de2818.pdf#page=428", ) def formula(spm_unit, period, parameters): @@ -18,10 +19,12 @@ def formula(spm_unit, period, parameters): # OAR 414-175-0023(5) sets hours from the caretaker's allowable child # care need. We proxy that need with work hours before labor supply # responses (avoiding a circular dependency); education, training, and - # study hours are not separately tracked. OAR 0023(5) is silent on - # multi-caretaker units, so we authorize on the lowest-need caretaker, - # the more conservative reading. Non-caretakers get infinity so they - # never lower the need. + # study hours are not separately tracked. For two-caretaker units the + # OPEN worker guide (p. 428) counts only hours when both caretakers' + # work or school schedules overlap; we do not track schedules, so we + # use the lowest caretaker's hours, the maximum possible overlap. + # Set this variable directly when actual overlapping hours are known. + # Non-caretakers get infinity so they never lower the need. weekly_hours = person("weekly_hours_worked_before_lsr", period.this_year) has_caretaker = spm_unit.sum(is_caretaker) > 0 lowest_caretaker_hours = spm_unit.min(where(is_caretaker, weekly_hours, np.inf)) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_monthly_care_hours.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_monthly_care_hours.py index 57bf710ca0d..eae8c946399 100644 --- a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_monthly_care_hours.py +++ b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_monthly_care_hours.py @@ -9,7 +9,8 @@ class or_erdc_monthly_care_hours(Variable): label = "Oregon ERDC monthly child care hours" defined_for = "or_erdc_eligible_child" reference = ( - "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0023" + "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0023", + "https://sharedsystems.dhsoha.state.or.us/DHSForms/Served/de2818.pdf#page=428", ) def formula(person, period, parameters): @@ -30,4 +31,7 @@ def formula(person, period, parameters): # weekly allowance to monthly hours, capped at the monthly maximum. weekly_with_travel = weekly_allowance * (1 + p.authorized.travel_allowance) monthly = weekly_with_travel * p.authorized.weekly_to_monthly - return min_(monthly, p.max_monthly) + # The OPEN worker guide (p. 428) publishes the 20-hour band as 108 + # monthly hours (20 * 1.25 * 4.3 = 107.5), so fractional monthly + # hours round up before the cap. + return min_(np.ceil(monthly), p.max_monthly) From 08ebfc1cce0cd460d226e0449cd4a1cac6deb563 Mon Sep 17 00:00:00 2001 From: Ziming Date: Mon, 13 Jul 2026 17:30:26 -0400 Subject: [PATCH 4/7] Exclude child earned income from ERDC countable income OAR 414-175-0035(21)(a) excludes the earned income of a child, and the OAR 414-175-0015(2)(d) filing group counts earned income only from caretakers. Sum earned sources per person and zero them out for non-caretakers (tax unit heads and spouses). Co-Authored-By: Claude Fable 5 --- .../or/delc/erdc/hours/standard_tier.yaml | 20 -- .../gov/states/or/delc/erdc/hours/tiered.yaml | 24 --- .../countable_income/earned_sources.yaml | 18 ++ .../erdc/income/countable_income/sources.yaml | 8 +- .../rates/high_needs_supplement/hourly.yaml | 11 -- .../rates/high_needs_supplement/monthly.yaml | 11 -- .../states/or/delc/erdc/rates/part_time.yaml | 181 ------------------ .../erdc/or_erdc_countable_earned_income.yaml | 128 +++++++++++++ .../or_erdc_caretaker_weekly_need_hours.py | 0 .../{ => hours}/or_erdc_monthly_care_hours.py | 0 .../income/or_erdc_countable_earned_income.py | 22 +++ .../or/delc/erdc/or_erdc_billing_tier.py | 47 ----- ...or_erdc_expanded_child_welfare_eligible.py | 10 - .../delc/erdc/or_erdc_high_needs_factors.py | 15 -- .../erdc/or_erdc_high_needs_rate_eligible.py | 12 -- .../or/delc/erdc/or_erdc_in_ged_program.py | 12 -- .../or_erdc_medical_leave_at_application.py | 12 -- .../or/delc/erdc/or_erdc_on_medical_leave.py | 10 - .../delc/erdc/or_erdc_permanent_job_loss.py | 12 -- .../erdc/or_erdc_provider_bills_part_time.py | 13 -- .../or_erdc_special_circumstances_child.py | 10 - .../or_erdc_special_needs_rate_eligible.py | 10 - .../or_erdc_supervised_contact_required.py | 12 -- .../delc/erdc/or_erdc_tiered_provider_type.py | 41 ---- .../erdc/or_erdc_unable_to_provide_care.py | 10 - .../erdc/{ => rates}/or_erdc_age_group.py | 0 .../or_erdc_allowable_child_care_cost.py | 0 .../or_erdc_maximum_monthly_rate.py | 0 .../erdc/{ => rates}/or_erdc_provider_area.py | 0 .../erdc/{ => rates}/or_erdc_provider_type.py | 0 30 files changed, 171 insertions(+), 478 deletions(-) delete mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/hours/standard_tier.yaml delete mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/hours/tiered.yaml create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/income/countable_income/earned_sources.yaml delete mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/rates/high_needs_supplement/hourly.yaml delete mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/rates/high_needs_supplement/monthly.yaml delete mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/rates/part_time.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_countable_earned_income.yaml rename policyengine_us/variables/gov/states/or/delc/erdc/{ => hours}/or_erdc_caretaker_weekly_need_hours.py (100%) rename policyengine_us/variables/gov/states/or/delc/erdc/{ => hours}/or_erdc_monthly_care_hours.py (100%) create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/income/or_erdc_countable_earned_income.py delete mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_billing_tier.py delete mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_expanded_child_welfare_eligible.py delete mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_high_needs_factors.py delete mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_high_needs_rate_eligible.py delete mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_in_ged_program.py delete mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_medical_leave_at_application.py delete mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_on_medical_leave.py delete mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_permanent_job_loss.py delete mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_provider_bills_part_time.py delete mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_special_circumstances_child.py delete mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_special_needs_rate_eligible.py delete mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_supervised_contact_required.py delete mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_tiered_provider_type.py delete mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_unable_to_provide_care.py rename policyengine_us/variables/gov/states/or/delc/erdc/{ => rates}/or_erdc_age_group.py (100%) rename policyengine_us/variables/gov/states/or/delc/erdc/{ => rates}/or_erdc_allowable_child_care_cost.py (100%) rename policyengine_us/variables/gov/states/or/delc/erdc/{ => rates}/or_erdc_maximum_monthly_rate.py (100%) rename policyengine_us/variables/gov/states/or/delc/erdc/{ => rates}/or_erdc_provider_area.py (100%) rename policyengine_us/variables/gov/states/or/delc/erdc/{ => rates}/or_erdc_provider_type.py (100%) diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/hours/standard_tier.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/hours/standard_tier.yaml deleted file mode 100644 index 85c5e990448..00000000000 --- a/policyengine_us/parameters/gov/states/or/delc/erdc/hours/standard_tier.yaml +++ /dev/null @@ -1,20 +0,0 @@ -description: Oregon sets these billing tiers for standard providers under the Employment Related Day Care program. -metadata: - type: single_amount - threshold_unit: hour - amount_unit: /1 - period: month - label: Oregon ERDC standard provider billing tiers - reference: - - title: ERDC Provider Guide Insert, 2026 standard rate maximums - href: https://www.oregon.gov/delc/providers/Documents/Provider%20Rate%20Increase%20For%20Jan%202026_Phase%202_ENG.pdf#page=2 - -brackets: - - threshold: - 2026-01-01: 0 - amount: - 2026-01-01: 0 - - threshold: - 2026-01-01: 158 - amount: - 2026-01-01: 2 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/hours/tiered.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/hours/tiered.yaml deleted file mode 100644 index 56ef5a127da..00000000000 --- a/policyengine_us/parameters/gov/states/or/delc/erdc/hours/tiered.yaml +++ /dev/null @@ -1,24 +0,0 @@ -description: Oregon sets these billing tiers for enhanced and licensed providers under the Employment Related Day Care program. -metadata: - type: single_amount - threshold_unit: hour - amount_unit: /1 - period: month - label: Oregon ERDC tiered provider billing tiers - reference: - - title: ERDC Provider Guide Insert, 2026 enhanced and licensed rate maximums - href: https://www.oregon.gov/delc/providers/Documents/Provider%20Rate%20Increase%20For%20Jan%202026_Phase%202_ENG.pdf#page=2 - -brackets: - - threshold: - 2026-01-01: 0 - amount: - 2026-01-01: 0 - - threshold: - 2026-01-01: 63 - amount: - 2026-01-01: 1 - - threshold: - 2026-01-01: 136 - amount: - 2026-01-01: 2 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/income/countable_income/earned_sources.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/income/countable_income/earned_sources.yaml new file mode 100644 index 00000000000..31ac3b8e4cf --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/income/countable_income/earned_sources.yaml @@ -0,0 +1,18 @@ +description: Oregon counts these earned income sources under the Employment Related Day Care program. +values: + 2026-03-01: + - employment_income + # Self-employment sources are floored at zero per business so a loss cannot + # offset other countable income, per OAR 414-175-0035(81)(a) and (81)(e). + - or_erdc_countable_self_employment_income + - military_basic_pay + +metadata: + unit: list + period: year + label: Oregon ERDC countable earned income sources + reference: + - title: OAR 414-175-0030(1), General Financial Eligibility Provisions + href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 + - title: OAR 414-175-0035, Specific Financial Requirements + href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/income/countable_income/sources.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/income/countable_income/sources.yaml index 2e45dce09eb..61523b0854b 100644 --- a/policyengine_us/parameters/gov/states/or/delc/erdc/income/countable_income/sources.yaml +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/income/countable_income/sources.yaml @@ -1,11 +1,9 @@ description: Oregon counts these income sources under the Employment Related Day Care program. values: 2026-03-01: - - employment_income - # Self-employment sources are floored at zero per business so a loss cannot - # offset other countable income, per OAR 414-175-0035(81)(a) and (81)(e). - - or_erdc_countable_self_employment_income - - military_basic_pay + # Earned sources are aggregated per person so the earned income of a + # child can be excluded, per OAR 414-175-0035(21)(a). + - or_erdc_countable_earned_income - disability_benefits - social_security - ssi diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/rates/high_needs_supplement/hourly.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/rates/high_needs_supplement/hourly.yaml deleted file mode 100644 index f7472b04b8d..00000000000 --- a/policyengine_us/parameters/gov/states/or/delc/erdc/rates/high_needs_supplement/hourly.yaml +++ /dev/null @@ -1,11 +0,0 @@ -description: Oregon adds this amount per assessed factor to the hourly provider rate for children eligible for the high needs rate under the Employment Related Day Care program. -values: - 2026-01-01: 5 - -metadata: - unit: currency-USD - period: hour - label: Oregon ERDC high needs hourly rate supplement - reference: - - title: OAR 414-175-0076(2)(a) - href: https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0076 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/rates/high_needs_supplement/monthly.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/rates/high_needs_supplement/monthly.yaml deleted file mode 100644 index 0e55912bea5..00000000000 --- a/policyengine_us/parameters/gov/states/or/delc/erdc/rates/high_needs_supplement/monthly.yaml +++ /dev/null @@ -1,11 +0,0 @@ -description: Oregon adds this amount per assessed factor to the monthly provider rate for children eligible for the high needs rate under the Employment Related Day Care program. -values: - 2026-01-01: 840 - -metadata: - unit: currency-USD - period: month - label: Oregon ERDC high needs monthly rate supplement - reference: - - title: OAR 414-175-0076(2)(b) - href: https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0076 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/rates/part_time.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/rates/part_time.yaml deleted file mode 100644 index 1f2c6b96649..00000000000 --- a/policyengine_us/parameters/gov/states/or/delc/erdc/rates/part_time.yaml +++ /dev/null @@ -1,181 +0,0 @@ -description: Oregon provides these part-time monthly maximum provider reimbursement rates under the Employment Related Day Care program. -metadata: - period: month - unit: currency-USD - label: Oregon ERDC part-time monthly maximum provider rates - breakdown: - - or_erdc_provider_area - - or_erdc_tiered_provider_type - - or_erdc_age_group - reference: - - title: Oregon DELC ERDC Child Care Maximum Rates, Group Areas A-C - href: https://www.oregon.gov/delc/providers/Documents/Provider%20Rate%20Increase%20For%20Jan%202026_Phase%202_ENG.pdf#page=2 - -AREA_A: - ENHANCED_FAMILY: - INFANT: - 2026-03-01: 879 - TODDLER: - 2026-03-01: 808 - PRESCHOOL: - 2026-03-01: 737 - SCHOOL: - 2026-03-01: 665 - SPECIAL_NEEDS: - 2026-03-01: 879 - ENHANCED_CENTER: - INFANT: - 2026-01-01: 1_328 - TODDLER: - 2026-01-01: 1_267 - PRESCHOOL: - 2026-01-01: 997 - SCHOOL: - 2026-01-01: 1_010 - SPECIAL_NEEDS: - 2026-01-01: 1_328 - REGISTERED_FAMILY: - INFANT: - 2026-01-01: 925 - TODDLER: - 2026-01-01: 850 - PRESCHOOL: - 2026-01-01: 775 - SCHOOL: - 2026-01-01: 700 - SPECIAL_NEEDS: - 2026-01-01: 925 - CERTIFIED_FAMILY: - INFANT: - 2026-01-01: 1_373 - TODDLER: - 2026-01-01: 1_256 - PRESCHOOL: - 2026-01-01: 1_108 - SCHOOL: - 2026-01-01: 863 - SPECIAL_NEEDS: - 2026-01-01: 1_373 - CERTIFIED_CENTER: - INFANT: - 2026-01-01: 1_562 - TODDLER: - 2026-01-01: 1_490 - PRESCHOOL: - 2026-01-01: 1_172 - SCHOOL: - 2026-01-01: 1_189 - SPECIAL_NEEDS: - 2026-01-01: 1_562 -AREA_B: - ENHANCED_FAMILY: - INFANT: - 2026-03-01: 677 - TODDLER: - 2026-03-01: 623 - PRESCHOOL: - 2026-03-01: 593 - SCHOOL: - 2026-03-01: 570 - SPECIAL_NEEDS: - 2026-03-01: 677 - ENHANCED_CENTER: - INFANT: - 2026-01-01: 956 - TODDLER: - 2026-01-01: 845 - PRESCHOOL: - 2026-01-01: 665 - SCHOOL: - 2026-01-01: 510 - SPECIAL_NEEDS: - 2026-01-01: 956 - REGISTERED_FAMILY: - INFANT: - 2026-01-01: 713 - TODDLER: - 2026-01-01: 656 - PRESCHOOL: - 2026-01-01: 625 - SCHOOL: - 2026-01-01: 600 - SPECIAL_NEEDS: - 2026-01-01: 713 - CERTIFIED_FAMILY: - INFANT: - 2026-01-01: 956 - TODDLER: - 2026-01-01: 833 - PRESCHOOL: - 2026-01-01: 788 - SCHOOL: - 2026-01-01: 675 - SPECIAL_NEEDS: - 2026-01-01: 956 - CERTIFIED_CENTER: - INFANT: - 2026-01-01: 1_125 - TODDLER: - 2026-01-01: 994 - PRESCHOOL: - 2026-01-01: 782 - SCHOOL: - 2026-01-01: 600 - SPECIAL_NEEDS: - 2026-01-01: 1_125 -AREA_C: - ENHANCED_FAMILY: - INFANT: - 2026-03-01: 677 - TODDLER: - 2026-03-01: 623 - PRESCHOOL: - 2026-03-01: 593 - SCHOOL: - 2026-03-01: 570 - SPECIAL_NEEDS: - 2026-03-01: 677 - ENHANCED_CENTER: - INFANT: - 2026-01-01: 956 - TODDLER: - 2026-01-01: 845 - PRESCHOOL: - 2026-01-01: 665 - SCHOOL: - 2026-01-01: 510 - SPECIAL_NEEDS: - 2026-01-01: 956 - REGISTERED_FAMILY: - INFANT: - 2026-01-01: 713 - TODDLER: - 2026-01-01: 656 - PRESCHOOL: - 2026-01-01: 625 - SCHOOL: - 2026-01-01: 600 - SPECIAL_NEEDS: - 2026-01-01: 713 - CERTIFIED_FAMILY: - INFANT: - 2026-01-01: 956 - TODDLER: - 2026-01-01: 833 - PRESCHOOL: - 2026-01-01: 788 - SCHOOL: - 2026-01-01: 675 - SPECIAL_NEEDS: - 2026-01-01: 956 - CERTIFIED_CENTER: - INFANT: - 2026-01-01: 1_125 - TODDLER: - 2026-01-01: 994 - PRESCHOOL: - 2026-01-01: 782 - SCHOOL: - 2026-01-01: 600 - SPECIAL_NEEDS: - 2026-01-01: 1_125 diff --git a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_countable_earned_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_countable_earned_income.yaml new file mode 100644 index 00000000000..d8a459ab590 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_countable_earned_income.yaml @@ -0,0 +1,128 @@ +# OAR 414-175-0035(21)(a) excludes the earned income of a child; only +# caretakers (tax unit heads and spouses) contribute earned income. + +- name: Case 1, a working single caretaker's wages are counted. + period: 2027-01 + absolute_error_margin: 0.1 + input: + people: + parent: + age: 30 + employment_income: 24_000 + child: + age: 4 + tax_units: + tax_unit: + members: [parent, child] + spm_units: + spm_unit: + members: [parent, child] + households: + household: + members: [parent, child] + state_code: OR + output: + or_erdc_countable_earned_income: [2_000, 0] + +- name: Case 2, a working 16-year-old child's wages are excluded. + period: 2027-01 + absolute_error_margin: 0.1 + input: + people: + parent: + age: 40 + employment_income: 36_000 + teen: + age: 16 + employment_income: 24_000 + child: + age: 4 + tax_units: + tax_unit: + members: [parent, teen, child] + spm_units: + spm_unit: + members: [parent, teen, child] + households: + household: + members: [parent, teen, child] + state_code: OR + output: + or_erdc_countable_earned_income: [3_000, 0, 0] + +- name: Case 3, an 18-year-old in secondary school remains a child with excluded wages. + period: 2027-01 + absolute_error_margin: 0.1 + input: + people: + parent: + age: 45 + employment_income: 36_000 + teen: + age: 18 + is_in_secondary_school: true + employment_income: 24_000 + child: + age: 4 + tax_units: + tax_unit: + members: [parent, teen, child] + spm_units: + spm_unit: + members: [parent, teen, child] + households: + household: + members: [parent, teen, child] + state_code: OR + output: + or_erdc_countable_earned_income: [3_000, 0, 0] + +- name: Case 4, both spouses' earnings are counted. + period: 2027-01 + absolute_error_margin: 0.1 + input: + people: + parent_1: + age: 32 + employment_income: 24_000 + parent_2: + age: 30 + employment_income: 12_000 + child: + age: 4 + tax_units: + tax_unit: + members: [parent_1, parent_2, child] + spm_units: + spm_unit: + members: [parent_1, parent_2, child] + households: + household: + members: [parent_1, parent_2, child] + state_code: OR + output: + or_erdc_countable_earned_income: [2_000, 1_000, 0] + +- name: Case 5, a caretaker's self-employment loss cannot offset wages. + period: 2027-01 + absolute_error_margin: 0.1 + input: + people: + parent: + age: 30 + employment_income: 24_000 + self_employment_income: -12_000 + child: + age: 4 + tax_units: + tax_unit: + members: [parent, child] + spm_units: + spm_unit: + members: [parent, child] + households: + household: + members: [parent, child] + state_code: OR + output: + or_erdc_countable_earned_income: [2_000, 0] diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_caretaker_weekly_need_hours.py b/policyengine_us/variables/gov/states/or/delc/erdc/hours/or_erdc_caretaker_weekly_need_hours.py similarity index 100% rename from policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_caretaker_weekly_need_hours.py rename to policyengine_us/variables/gov/states/or/delc/erdc/hours/or_erdc_caretaker_weekly_need_hours.py diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_monthly_care_hours.py b/policyengine_us/variables/gov/states/or/delc/erdc/hours/or_erdc_monthly_care_hours.py similarity index 100% rename from policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_monthly_care_hours.py rename to policyengine_us/variables/gov/states/or/delc/erdc/hours/or_erdc_monthly_care_hours.py diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/income/or_erdc_countable_earned_income.py b/policyengine_us/variables/gov/states/or/delc/erdc/income/or_erdc_countable_earned_income.py new file mode 100644 index 00000000000..b800092fbef --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/income/or_erdc_countable_earned_income.py @@ -0,0 +1,22 @@ +from policyengine_us.model_api import * + + +class or_erdc_countable_earned_income(Variable): + value_type = float + entity = Person + definition_period = MONTH + unit = USD + label = "Oregon ERDC countable earned income" + defined_for = StateCode.OR + reference = ( + "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0035" + ) + + def formula(person, period, parameters): + p = parameters(period).gov.states["or"].delc.erdc + earned = add(person, period, p.income.countable_income.earned_sources) + # OAR 414-175-0035(21)(a) excludes the earned income of a child; the + # OAR 414-175-0015(2)(d) filing group counts earned income only from + # caretakers, proxied program-wide by tax unit heads and spouses. + caretaker = person("is_tax_unit_head_or_spouse", period.this_year) + return earned * caretaker diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_billing_tier.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_billing_tier.py deleted file mode 100644 index 9bf611272e1..00000000000 --- a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_billing_tier.py +++ /dev/null @@ -1,47 +0,0 @@ -from policyengine_us.model_api import * - - -class ORERDCBillingTier(Enum): - HOURLY = "Hourly" - PART_TIME = "Part-time" - MONTHLY = "Monthly" - - -class or_erdc_billing_tier(Variable): - value_type = Enum - entity = Person - possible_values = ORERDCBillingTier - default_value = ORERDCBillingTier.HOURLY - definition_period = MONTH - label = "Oregon ERDC provider billing tier" - defined_for = "or_erdc_eligible_child" - reference = ( - "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0075" - ) - - def formula(person, period, parameters): - p = parameters(period).gov.states["or"].delc.erdc.hours - hours = person("or_erdc_monthly_care_hours", period) - provider_type = person("or_erdc_provider_type", period) - types = provider_type.possible_values - standard_provider = (provider_type == types.STANDARD_FAMILY) | ( - provider_type == types.STANDARD_CENTER - ) - # OAR 414-175-0075(3)(b),(c),(e): an enhanced or licensed provider is - # paid the part-time monthly rate below the full-time threshold only - # when it customarily bills all families part-time and is the primary - # provider; otherwise that care is paid hourly. When the provider does - # not bill part-time, collapse the part-time band into the hourly tier. - bills_part_time = person("or_erdc_provider_bills_part_time", period) - tiered = p.tiered.calc(hours) - tiered_without_part_time = where( - tiered == ORERDCBillingTier.PART_TIME.index, - ORERDCBillingTier.HOURLY.index, - tiered, - ) - enhanced_tier = where(bills_part_time, tiered, tiered_without_part_time) - return where( - standard_provider, - p.standard_tier.calc(hours), - enhanced_tier, - ) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_expanded_child_welfare_eligible.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_expanded_child_welfare_eligible.py deleted file mode 100644 index 59039a92960..00000000000 --- a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_expanded_child_welfare_eligible.py +++ /dev/null @@ -1,10 +0,0 @@ -from policyengine_us.model_api import * - - -class or_erdc_expanded_child_welfare_eligible(Variable): - value_type = bool - entity = SPMUnit - definition_period = YEAR - label = "Eligible for Oregon ERDC through Expanded Child Welfare" - defined_for = StateCode.OR - reference = "https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871" diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_high_needs_factors.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_high_needs_factors.py deleted file mode 100644 index 6661f88ed70..00000000000 --- a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_high_needs_factors.py +++ /dev/null @@ -1,15 +0,0 @@ -from policyengine_us.model_api import * - - -class or_erdc_high_needs_factors(Variable): - value_type = int - entity = Person - definition_period = YEAR - default_value = 0 - label = "Oregon ERDC high needs assessed factor count" - # OAR 414-175-0076(2)-(4): the assessed high needs factor ranges from 0 to - # 2 and multiplies the hourly or monthly supplement. - defined_for = StateCode.OR - reference = ( - "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0076" - ) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_high_needs_rate_eligible.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_high_needs_rate_eligible.py deleted file mode 100644 index ef7eba145cd..00000000000 --- a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_high_needs_rate_eligible.py +++ /dev/null @@ -1,12 +0,0 @@ -from policyengine_us.model_api import * - - -class or_erdc_high_needs_rate_eligible(Variable): - value_type = bool - entity = Person - definition_period = YEAR - label = "Eligible for the Oregon ERDC high need rate" - defined_for = StateCode.OR - reference = ( - "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0076" - ) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_in_ged_program.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_in_ged_program.py deleted file mode 100644 index a70e8eaf3e6..00000000000 --- a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_in_ged_program.py +++ /dev/null @@ -1,12 +0,0 @@ -from policyengine_us.model_api import * - - -class or_erdc_in_ged_program(Variable): - value_type = bool - entity = Person - definition_period = YEAR - label = "Oregon ERDC caretaker participating in a GED program" - defined_for = StateCode.OR - reference = ( - "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0023" - ) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_medical_leave_at_application.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_medical_leave_at_application.py deleted file mode 100644 index 7f1c947a7b2..00000000000 --- a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_medical_leave_at_application.py +++ /dev/null @@ -1,12 +0,0 @@ -from policyengine_us.model_api import * - - -class or_erdc_medical_leave_at_application(Variable): - value_type = bool - entity = SPMUnit - definition_period = YEAR - label = "Oregon ERDC caretaker on medical leave at initial application" - defined_for = StateCode.OR - reference = ( - "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0023" - ) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_on_medical_leave.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_on_medical_leave.py deleted file mode 100644 index f19d73afe52..00000000000 --- a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_on_medical_leave.py +++ /dev/null @@ -1,10 +0,0 @@ -from policyengine_us.model_api import * - - -class or_erdc_on_medical_leave(Variable): - value_type = bool - entity = Person - definition_period = YEAR - label = "Oregon ERDC caretaker on verified medical leave" - defined_for = StateCode.OR - reference = "https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871" diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_permanent_job_loss.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_permanent_job_loss.py deleted file mode 100644 index 5878d636b96..00000000000 --- a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_permanent_job_loss.py +++ /dev/null @@ -1,12 +0,0 @@ -from policyengine_us.model_api import * - - -class or_erdc_permanent_job_loss(Variable): - value_type = bool - entity = SPMUnit - definition_period = YEAR - label = "Oregon ERDC caretaker with a permanent job loss from all employment" - defined_for = StateCode.OR - reference = ( - "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0023" - ) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_provider_bills_part_time.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_provider_bills_part_time.py deleted file mode 100644 index e98f53fcf4f..00000000000 --- a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_provider_bills_part_time.py +++ /dev/null @@ -1,13 +0,0 @@ -from policyengine_us.model_api import * - - -class or_erdc_provider_bills_part_time(Variable): - value_type = bool - entity = Person - definition_period = MONTH - default_value = False - label = "Oregon ERDC provider customarily bills part-time monthly" - defined_for = StateCode.OR - reference = ( - "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0075" - ) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_special_circumstances_child.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_special_circumstances_child.py deleted file mode 100644 index 8367e6166ef..00000000000 --- a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_special_circumstances_child.py +++ /dev/null @@ -1,10 +0,0 @@ -from policyengine_us.model_api import * - - -class or_erdc_special_circumstances_child(Variable): - value_type = bool - entity = Person - definition_period = YEAR - label = "Oregon ERDC child with verified special circumstances" - defined_for = StateCode.OR - reference = "https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871" diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_special_needs_rate_eligible.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_special_needs_rate_eligible.py deleted file mode 100644 index aa52b50ab83..00000000000 --- a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_special_needs_rate_eligible.py +++ /dev/null @@ -1,10 +0,0 @@ -from policyengine_us.model_api import * - - -class or_erdc_special_needs_rate_eligible(Variable): - value_type = bool - entity = Person - definition_period = YEAR - label = "Eligible for the Oregon ERDC special needs rate" - defined_for = StateCode.OR - reference = "https://www.oregon.gov/delc/providers/Documents/Provider%20Rate%20Increase%20For%20Jan%202026_Phase%202_ENG.pdf#page=1" diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_supervised_contact_required.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_supervised_contact_required.py deleted file mode 100644 index df6147686e5..00000000000 --- a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_supervised_contact_required.py +++ /dev/null @@ -1,12 +0,0 @@ -from policyengine_us.model_api import * - - -class or_erdc_supervised_contact_required(Variable): - value_type = bool - entity = Person - definition_period = YEAR - label = "Oregon ERDC supervised contact required with a caretaker" - defined_for = StateCode.OR - reference = ( - "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0023" - ) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_tiered_provider_type.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_tiered_provider_type.py deleted file mode 100644 index 198d04cd710..00000000000 --- a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_tiered_provider_type.py +++ /dev/null @@ -1,41 +0,0 @@ -from policyengine_us.model_api import * - - -class ORERDCTieredProviderType(Enum): - ENHANCED_FAMILY = "Enhanced Family (QFM)" - ENHANCED_CENTER = "Enhanced Center (QEC)" - REGISTERED_FAMILY = "Registered Family (RFM)" - CERTIFIED_FAMILY = "Certified Family (CFM)" - CERTIFIED_CENTER = "Certified Center (CNT)" - - -class or_erdc_tiered_provider_type(Variable): - value_type = Enum - entity = Person - possible_values = ORERDCTieredProviderType - default_value = ORERDCTieredProviderType.ENHANCED_FAMILY - definition_period = MONTH - label = "Oregon ERDC enhanced or licensed provider type" - defined_for = "or_erdc_eligible_child" - reference = "https://www.oregon.gov/delc/programs/pages/rates.aspx" - - def formula(person, period, parameters): - provider_type = person("or_erdc_provider_type", period) - types = provider_type.possible_values - return select( - [ - provider_type == types.ENHANCED_FAMILY, - provider_type == types.ENHANCED_CENTER, - provider_type == types.REGISTERED_FAMILY, - provider_type == types.CERTIFIED_FAMILY, - provider_type == types.CERTIFIED_CENTER, - ], - [ - ORERDCTieredProviderType.ENHANCED_FAMILY, - ORERDCTieredProviderType.ENHANCED_CENTER, - ORERDCTieredProviderType.REGISTERED_FAMILY, - ORERDCTieredProviderType.CERTIFIED_FAMILY, - ORERDCTieredProviderType.CERTIFIED_CENTER, - ], - default=ORERDCTieredProviderType.ENHANCED_FAMILY, - ) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_unable_to_provide_care.py b/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_unable_to_provide_care.py deleted file mode 100644 index 9b6f1edf605..00000000000 --- a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_unable_to_provide_care.py +++ /dev/null @@ -1,10 +0,0 @@ -from policyengine_us.model_api import * - - -class or_erdc_unable_to_provide_care(Variable): - value_type = bool - entity = Person - definition_period = YEAR - label = "Oregon ERDC caretaker unable to provide care" - defined_for = StateCode.OR - reference = "https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871" diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_age_group.py b/policyengine_us/variables/gov/states/or/delc/erdc/rates/or_erdc_age_group.py similarity index 100% rename from policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_age_group.py rename to policyengine_us/variables/gov/states/or/delc/erdc/rates/or_erdc_age_group.py diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_allowable_child_care_cost.py b/policyengine_us/variables/gov/states/or/delc/erdc/rates/or_erdc_allowable_child_care_cost.py similarity index 100% rename from policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_allowable_child_care_cost.py rename to policyengine_us/variables/gov/states/or/delc/erdc/rates/or_erdc_allowable_child_care_cost.py diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_maximum_monthly_rate.py b/policyengine_us/variables/gov/states/or/delc/erdc/rates/or_erdc_maximum_monthly_rate.py similarity index 100% rename from policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_maximum_monthly_rate.py rename to policyengine_us/variables/gov/states/or/delc/erdc/rates/or_erdc_maximum_monthly_rate.py diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_provider_area.py b/policyengine_us/variables/gov/states/or/delc/erdc/rates/or_erdc_provider_area.py similarity index 100% rename from policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_provider_area.py rename to policyengine_us/variables/gov/states/or/delc/erdc/rates/or_erdc_provider_area.py diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_provider_type.py b/policyengine_us/variables/gov/states/or/delc/erdc/rates/or_erdc_provider_type.py similarity index 100% rename from policyengine_us/variables/gov/states/or/delc/erdc/or_erdc_provider_type.py rename to policyengine_us/variables/gov/states/or/delc/erdc/rates/or_erdc_provider_type.py From 6b221abaf5d9492b83abf4190c7cbac82d65bc13 Mon Sep 17 00:00:00 2001 From: Ziming Date: Mon, 13 Jul 2026 17:30:36 -0400 Subject: [PATCH 5/7] Model ERDC provisions with existing variables instead of bespoke inputs Replace 14 program-specific input variables with existing repo variables or documented simplifications: - Special needs rate, 13-17 child eligibility, and the second-caretaker exception key on is_disabled, is_incapable_of_self_care, and is_in_foster_care; Expanded Child Welfare is now a formula over is_in_foster_care. - GED study is covered by is_in_secondary_school. - Part-time billing, the high needs supplement, copay waivers, medical leave, and supervised contact are unmodeled, each noted in a formula comment; billing collapses to hourly-vs-monthly full-time thresholds (158 standard, 136 enhanced/licensed). - Reorganize variables into eligibility, income, rates, hours, and copay folders. Co-Authored-By: Claude Fable 5 --- .../hours/full_time_threshold/licensed.yaml | 13 ++ .../hours/full_time_threshold/standard.yaml | 13 ++ .../gov/states/or/delc/erdc/integration.yaml | 44 ++++- .../delc/erdc/or_erdc_activity_eligible.yaml | 97 +---------- .../or/delc/erdc/or_erdc_age_group.yaml | 17 +- .../states/or/delc/erdc/or_erdc_copay.yaml | 22 --- .../or/delc/erdc/or_erdc_eligible_child.yaml | 16 +- .../erdc/or_erdc_maximum_monthly_rate.yaml | 151 +++--------------- .../delc/erdc/or_erdc_monthly_care_hours.yaml | 2 +- .../or/delc/erdc/copay/or_erdc_copay.py | 10 +- .../eligibility/or_erdc_activity_eligible.py | 19 +-- .../or_erdc_categorically_eligible.py | 2 +- .../eligibility/or_erdc_eligible_child.py | 9 +- ...or_erdc_expanded_child_welfare_eligible.py | 19 +++ .../or/delc/erdc/rates/or_erdc_age_group.py | 11 +- .../rates/or_erdc_maximum_monthly_rate.py | 58 +++---- 16 files changed, 166 insertions(+), 337 deletions(-) create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/hours/full_time_threshold/licensed.yaml create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/hours/full_time_threshold/standard.yaml create mode 100644 policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_expanded_child_welfare_eligible.py diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/hours/full_time_threshold/licensed.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/hours/full_time_threshold/licensed.yaml new file mode 100644 index 00000000000..21d5641a7fe --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/hours/full_time_threshold/licensed.yaml @@ -0,0 +1,13 @@ +description: Oregon pays enhanced and licensed providers the full-time monthly rate when a child is in care for at least this many hours per month under the Employment Related Day Care program. +values: + 2026-01-01: 136 + +metadata: + unit: hour + period: month + label: Oregon ERDC enhanced and licensed provider full-time hours threshold + reference: + - title: OAR 414-175-0075(3)(b) + href: https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0075 + - title: ERDC Provider Guide Insert, 2026 enhanced and licensed rate maximums + href: https://www.oregon.gov/delc/providers/Documents/Provider%20Rate%20Increase%20For%20Jan%202026_Phase%202_ENG.pdf#page=2 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/hours/full_time_threshold/standard.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/hours/full_time_threshold/standard.yaml new file mode 100644 index 00000000000..b2d213f8096 --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/hours/full_time_threshold/standard.yaml @@ -0,0 +1,13 @@ +description: Oregon pays standard providers the full-time monthly rate when a child is in care for at least this many hours per month under the Employment Related Day Care program. +values: + 2026-01-01: 158 + +metadata: + unit: hour + period: month + label: Oregon ERDC standard provider full-time hours threshold + reference: + - title: OAR 414-175-0075(3)(a) + href: https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0075 + - title: ERDC Provider Guide Insert, 2026 standard rate maximums + href: https://www.oregon.gov/delc/providers/Documents/Provider%20Rate%20Increase%20For%20Jan%202026_Phase%202_ENG.pdf#page=2 diff --git a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/integration.yaml index 2c448aeaf7d..d6f149f48b2 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/integration.yaml @@ -93,7 +93,6 @@ # x4.3, capped at 215 monthly, so both children bill monthly. or_erdc_countable_income: 6_666.67 or_erdc_income_eligible: true - or_erdc_billing_tier: [HOURLY, MONTHLY, MONTHLY] # Child: Area B enhanced family toddler monthly 831. # Sibling (age 10, default certified center Area C school): monthly 800. or_erdc_maximum_monthly_rate: [0, 831, 800] @@ -112,6 +111,7 @@ weekly_hours_worked_before_lsr: 0 child: age: 0.5 + is_in_foster_care: true childcare_hours_per_week: 20 or_erdc_provider_area: AREA_C or_erdc_provider_type: STANDARD_FAMILY @@ -119,7 +119,6 @@ spm_units: spm_unit: members: [parent, child] - or_erdc_expanded_child_welfare_eligible: true households: household: members: [parent, child] @@ -173,8 +172,7 @@ weekly_hours_worked_before_lsr: 40 child: age: 15 - is_incapable_of_self_care: true - or_erdc_special_needs_rate_eligible: true + is_disabled: true childcare_hours_per_week: 40 or_erdc_provider_area: AREA_A or_erdc_provider_type: CERTIFIED_FAMILY @@ -369,3 +367,41 @@ output: or_erdc_eligible: false or_erdc: 0 + +- name: Case 13, a working teenager's wages do not count toward the income test. + period: 2027-01 + absolute_error_margin: 0.1 + input: + people: + parent: + age: 40 + employment_income: 36_000 + weekly_hours_worked_before_lsr: 40 + teen: + age: 16 + employment_income: 24_000 + child: + age: 4 + childcare_hours_per_week: 40 + or_erdc_provider_area: AREA_A + or_erdc_provider_type: CERTIFIED_CENTER + pre_subsidy_childcare_expenses: 18_000 + spm_units: + spm_unit: + members: [parent, teen, child] + households: + household: + members: [parent, teen, child] + state_code: OR + output: + # Earned income of a child is excluded per OAR 414-175-0035(21)(a), so the + # teen's 2,000 monthly wages do not count: countable = 36,000 / 12 = 3,000. + # Counting them (5,000) would exceed the size-3 initial limit of 4,554. + or_erdc_countable_earned_income: [3_000, 0, 0] + or_erdc_countable_income: 3_000 + or_erdc_income_eligible: true + # Size-3 copay bracket at 3,000: 5. + or_erdc_copay: 5 + or_erdc_maximum_monthly_rate: [0, 0, 1_563] + or_erdc_allowable_child_care_cost: 1_500 + or_erdc: 1_495 diff --git a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_activity_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_activity_eligible.yaml index cfb20d970bd..e5ca3757928 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_activity_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_activity_eligible.yaml @@ -55,7 +55,7 @@ parent_2: age: 30 weekly_hours_worked_before_lsr: 0 - or_erdc_unable_to_provide_care: true + is_disabled: true child: age: 4 tax_units: @@ -94,52 +94,6 @@ output: or_erdc_activity_eligible: true -- name: A caretaker on verified medical leave is activity eligible. - period: 2027-01 - input: - people: - parent: - age: 30 - weekly_hours_worked_before_lsr: 0 - or_erdc_on_medical_leave: true - child: - age: 4 - tax_units: - tax_unit: - members: [parent, child] - spm_units: - spm_unit: - members: [parent, child] - households: - household: - members: [parent, child] - state_code: OR - output: - or_erdc_activity_eligible: true - -- name: A single caretaker with supervised contact required is not activity eligible. - period: 2027-01 - input: - people: - parent: - age: 30 - weekly_hours_worked_before_lsr: 0 - or_erdc_supervised_contact_required: true - child: - age: 4 - tax_units: - tax_unit: - members: [parent, child] - spm_units: - spm_unit: - members: [parent, child] - households: - household: - members: [parent, child] - state_code: OR - output: - or_erdc_activity_eligible: false - - name: A part-time college student caretaker is activity eligible. period: 2027-01 input: @@ -208,52 +162,3 @@ state_code: OR output: or_erdc_activity_eligible: false - -- name: A caretaker in a GED program at the education age limit is activity eligible. - period: 2027-01 - input: - people: - parent: - age: 20 - weekly_hours_worked_before_lsr: 0 - or_erdc_in_ged_program: true - child: - age: 1 - tax_units: - tax_unit: - members: [parent, child] - spm_units: - spm_unit: - members: [parent, child] - households: - household: - members: [parent, child] - state_code: OR - output: - or_erdc_activity_eligible: true - -- name: A second caretaker requiring supervised contact satisfies the exception. - period: 2027-01 - input: - people: - parent_1: - age: 32 - weekly_hours_worked_before_lsr: 40 - parent_2: - age: 30 - weekly_hours_worked_before_lsr: 0 - or_erdc_supervised_contact_required: true - child: - age: 4 - tax_units: - tax_unit: - members: [parent_1, parent_2, child] - spm_units: - spm_unit: - members: [parent_1, parent_2, child] - households: - household: - members: [parent_1, parent_2, child] - state_code: OR - output: - or_erdc_activity_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_age_group.yaml b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_age_group.yaml index 8df507e82bf..f49859ced2c 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_age_group.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_age_group.yaml @@ -61,26 +61,13 @@ output: or_erdc_age_group: SCHOOL -- name: A special needs child uses the special needs group regardless of age. +- name: A disabled child uses the special needs group regardless of age. period: 2027-01 input: or_erdc_eligible_child: true age: 10 - or_erdc_special_needs_rate_eligible: true + is_disabled: true or_erdc_provider_type: CERTIFIED_CENTER state_code: OR output: or_erdc_age_group: SPECIAL_NEEDS - -- name: A high-needs child uses the special needs group without the rate flag. - period: 2027-01 - input: - or_erdc_eligible_child: true - age: 10 - or_erdc_high_needs_rate_eligible: true - or_erdc_provider_type: CERTIFIED_CENTER - state_code: OR - output: - # OAR 414-175-0076(1): high-needs children must qualify for the special - # needs rate, so the high-needs flag alone selects the special needs group. - or_erdc_age_group: SPECIAL_NEEDS diff --git a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_copay.yaml b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_copay.yaml index 15f7bd6e95e..e991d35eebf 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_copay.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_copay.yaml @@ -86,25 +86,3 @@ state_code: OR output: or_erdc_copay: 130 - -- name: A permanent job loss waives the copay. - period: 2027-01 - absolute_error_margin: 0.01 - input: - or_erdc_countable_income: 5_000 - or_erdc_permanent_job_loss: true - spm_unit_size: 2 - state_code: OR - output: - or_erdc_copay: 0 - -- name: Medical leave at application waives the copay. - period: 2027-01 - absolute_error_margin: 0.01 - input: - or_erdc_countable_income: 5_000 - or_erdc_medical_leave_at_application: true - spm_unit_size: 2 - state_code: OR - output: - or_erdc_copay: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_eligible_child.yaml b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_eligible_child.yaml index 8ce8a4d4082..1668ea5505e 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_eligible_child.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_eligible_child.yaml @@ -14,11 +14,11 @@ output: or_erdc_eligible_child: false -- name: Child younger than 18 with special circumstances is eligible. +- name: Child younger than 18 incapable of self-care is eligible. period: 2027-01 input: age: 17 - or_erdc_special_circumstances_child: true + is_incapable_of_self_care: true state_code: OR output: or_erdc_eligible_child: true @@ -27,25 +27,25 @@ period: 2027-01 input: age: 18 - or_erdc_special_circumstances_child: true + is_incapable_of_self_care: true state_code: OR output: or_erdc_eligible_child: false -- name: Child age 15 eligible for the high needs rate is an eligible child. +- name: Child age 15 with a disability is an eligible child. period: 2027-01 input: age: 15 - or_erdc_high_needs_rate_eligible: true + is_disabled: true state_code: OR output: or_erdc_eligible_child: true -- name: Child age 15 with only the special needs rate is not an eligible child. +- name: Child age 15 receiving foster care is an eligible child. period: 2027-01 input: age: 15 - or_erdc_special_needs_rate_eligible: true + is_in_foster_care: true state_code: OR output: - or_erdc_eligible_child: false + or_erdc_eligible_child: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_maximum_monthly_rate.yaml b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_maximum_monthly_rate.yaml index aa0d6e72715..dacf0ba6040 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_maximum_monthly_rate.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_maximum_monthly_rate.yaml @@ -1,4 +1,5 @@ -# Every provider type, rate area, age group, and billing tier is covered. +# Every provider type, rate area, and age group is covered across hourly and +# monthly billing. - name: Case 1, Area A standard family infant hourly. period: 2027-01 @@ -26,7 +27,7 @@ output: or_erdc_maximum_monthly_rate: 1490 -- name: Case 3, Area A enhanced family preschool part-time. +- name: Case 3, Area A enhanced family preschool hourly. period: 2027-01 absolute_error_margin: 0.01 input: @@ -35,10 +36,10 @@ or_erdc_provider_type: ENHANCED_FAMILY or_erdc_age_group: PRESCHOOL or_erdc_monthly_care_hours: 100 - or_erdc_provider_bills_part_time: true state_code: OR output: - or_erdc_maximum_monthly_rate: 737 + # 5.7 * 100 = 570, below the 982 monthly rate. + or_erdc_maximum_monthly_rate: 570 - name: Case 4, Area A enhanced center school hourly. period: 2027-01 @@ -66,7 +67,7 @@ output: or_erdc_maximum_monthly_rate: 1233.33 -- name: Case 6, Area A certified family infant part-time. +- name: Case 6, Area A certified family infant hourly. period: 2027-01 absolute_error_margin: 0.01 input: @@ -75,10 +76,10 @@ or_erdc_provider_type: CERTIFIED_FAMILY or_erdc_age_group: INFANT or_erdc_monthly_care_hours: 100 - or_erdc_provider_bills_part_time: true state_code: OR output: - or_erdc_maximum_monthly_rate: 1373 + # 9.33 * 100 = 933, below the 1,831 monthly rate. + or_erdc_maximum_monthly_rate: 933 - name: Case 7, Area A certified center toddler hourly. period: 2027-01 @@ -119,7 +120,7 @@ output: or_erdc_maximum_monthly_rate: 43.1 -- name: Case 10, Area B enhanced family special needs part-time. +- name: Case 10, Area B enhanced family special needs hourly. period: 2027-01 absolute_error_margin: 0.01 input: @@ -128,10 +129,10 @@ or_erdc_provider_type: ENHANCED_FAMILY or_erdc_age_group: SPECIAL_NEEDS or_erdc_monthly_care_hours: 100 - or_erdc_provider_bills_part_time: true state_code: OR output: - or_erdc_maximum_monthly_rate: 677 + # 5.23 * 100 = 523, below the 903 monthly rate. + or_erdc_maximum_monthly_rate: 523 - name: Case 11, Area B enhanced center infant monthly. period: 2027-01 @@ -159,7 +160,7 @@ output: or_erdc_maximum_monthly_rate: 52.5 -- name: Case 13, Area B certified family preschool part-time. +- name: Case 13, Area B certified family preschool hourly. period: 2027-01 absolute_error_margin: 0.01 input: @@ -168,10 +169,10 @@ or_erdc_provider_type: CERTIFIED_FAMILY or_erdc_age_group: PRESCHOOL or_erdc_monthly_care_hours: 100 - or_erdc_provider_bills_part_time: true state_code: OR output: - or_erdc_maximum_monthly_rate: 788 + # 6 * 100 = 600, below the 1,050 monthly rate. + or_erdc_maximum_monthly_rate: 600 - name: Case 14, Area B certified center school monthly. period: 2027-01 @@ -212,7 +213,7 @@ output: or_erdc_maximum_monthly_rate: 1125 -- name: Case 17, Area C enhanced family toddler part-time. +- name: Case 17, Area C enhanced family toddler hourly. period: 2027-01 absolute_error_margin: 0.01 input: @@ -221,10 +222,10 @@ or_erdc_provider_type: ENHANCED_FAMILY or_erdc_age_group: TODDLER or_erdc_monthly_care_hours: 100 - or_erdc_provider_bills_part_time: true state_code: OR output: - or_erdc_maximum_monthly_rate: 623 + # 4.99 * 100 = 499, below the 831 monthly rate. + or_erdc_maximum_monthly_rate: 499 - name: Case 18, Area C enhanced center preschool hourly. period: 2027-01 @@ -252,7 +253,7 @@ output: or_erdc_maximum_monthly_rate: 800 -- name: Case 20, Area C certified family special needs part-time. +- name: Case 20, Area C certified family special needs hourly. period: 2027-01 absolute_error_margin: 0.01 input: @@ -261,10 +262,10 @@ or_erdc_provider_type: CERTIFIED_FAMILY or_erdc_age_group: SPECIAL_NEEDS or_erdc_monthly_care_hours: 100 - or_erdc_provider_bills_part_time: true state_code: OR output: - or_erdc_maximum_monthly_rate: 956 + # 6 * 100 = 600, below the 1,275 monthly rate. + or_erdc_maximum_monthly_rate: 600 - name: Case 21, Area C certified center infant hourly. period: 2027-01 @@ -279,44 +280,19 @@ output: or_erdc_maximum_monthly_rate: 77.5 -- name: Tier boundary, enhanced provider at 62 hours is hourly. +- name: Tier boundary, enhanced provider at 135 hours bills hourly. period: 2027-01 absolute_error_margin: 0.01 - input: - or_erdc_eligible_child: true - or_erdc_provider_area: AREA_A - or_erdc_provider_type: ENHANCED_FAMILY - or_erdc_age_group: INFANT - or_erdc_monthly_care_hours: 62 - state_code: OR - output: - or_erdc_maximum_monthly_rate: 425.32 - -- name: Tier boundary, enhanced provider at 63 hours is part-time. - period: 2027-01 - input: - or_erdc_eligible_child: true - or_erdc_provider_area: AREA_A - or_erdc_provider_type: ENHANCED_FAMILY - or_erdc_age_group: INFANT - or_erdc_monthly_care_hours: 63 - or_erdc_provider_bills_part_time: true - state_code: OR - output: - or_erdc_maximum_monthly_rate: 879 - -- name: Tier boundary, enhanced provider at 135 hours remains part-time. - period: 2027-01 input: or_erdc_eligible_child: true or_erdc_provider_area: AREA_A or_erdc_provider_type: ENHANCED_FAMILY or_erdc_age_group: INFANT or_erdc_monthly_care_hours: 135 - or_erdc_provider_bills_part_time: true state_code: OR output: - or_erdc_maximum_monthly_rate: 879 + # 6.86 * 135 = 926.1, below the 1,172 monthly rate. + or_erdc_maximum_monthly_rate: 926.1 - name: Tier boundary, enhanced provider at 136 hours is monthly. period: 2027-01 @@ -355,87 +331,6 @@ output: or_erdc_maximum_monthly_rate: 1_110 -- name: Enhanced provider part-time band bills hourly when it does not bill part-time. - period: 2027-01 - absolute_error_margin: 0.01 - input: - or_erdc_eligible_child: true - or_erdc_provider_area: AREA_A - or_erdc_provider_type: ENHANCED_FAMILY - or_erdc_age_group: PRESCHOOL - or_erdc_monthly_care_hours: 100 - or_erdc_provider_bills_part_time: false - state_code: OR - output: - # 100 hours falls in the enhanced part-time band, but the provider does not - # bill part-time, so the tier collapses to hourly: min(5.7 * 100, 982) = 570. - or_erdc_maximum_monthly_rate: 570 - -- name: High needs adds five dollars per factor per hour on hourly billing. - period: 2027-01 - absolute_error_margin: 0.01 - input: - or_erdc_eligible_child: true - or_erdc_provider_area: AREA_A - or_erdc_provider_type: CERTIFIED_CENTER - or_erdc_age_group: INFANT - or_erdc_monthly_care_hours: 10 - or_erdc_high_needs_rate_eligible: true - or_erdc_high_needs_factors: 2 - state_code: OR - output: - # min(12 * 10, 2083) + 2 factors * $5 * 10 hours = 120 + 100 = 220. - or_erdc_maximum_monthly_rate: 220 - -- name: High needs adds eight hundred forty dollars per factor on monthly billing. - period: 2027-01 - absolute_error_margin: 0.01 - input: - or_erdc_eligible_child: true - or_erdc_provider_area: AREA_A - or_erdc_provider_type: CERTIFIED_CENTER - or_erdc_age_group: INFANT - or_erdc_monthly_care_hours: 200 - or_erdc_high_needs_rate_eligible: true - or_erdc_high_needs_factors: 2 - state_code: OR - output: - # Monthly rate 2083 + 2 factors * $840 = 2083 + 1680 = 3763. - or_erdc_maximum_monthly_rate: 3_763 - -- name: High needs adds the monthly supplement on part-time billing. - period: 2027-01 - absolute_error_margin: 0.01 - input: - or_erdc_eligible_child: true - or_erdc_provider_area: AREA_A - or_erdc_provider_type: CERTIFIED_CENTER - or_erdc_age_group: INFANT - or_erdc_monthly_care_hours: 100 - or_erdc_provider_bills_part_time: true - or_erdc_high_needs_rate_eligible: true - or_erdc_high_needs_factors: 1 - state_code: OR - output: - # Part-time rate 1562 + 1 factor * $840 = 2402. - or_erdc_maximum_monthly_rate: 2_402 - -- name: High needs supplement requires the high needs rate eligibility flag. - period: 2027-01 - absolute_error_margin: 0.01 - input: - or_erdc_eligible_child: true - or_erdc_provider_area: AREA_A - or_erdc_provider_type: CERTIFIED_CENTER - or_erdc_age_group: INFANT - or_erdc_monthly_care_hours: 10 - or_erdc_high_needs_rate_eligible: false - or_erdc_high_needs_factors: 2 - state_code: OR - output: - # Factors present but not high-needs eligible, so no supplement: 12 * 10 = 120. - or_erdc_maximum_monthly_rate: 120 - - name: Hourly billing is capped at the monthly rate near the monthly threshold. period: 2027-01 absolute_error_margin: 0.01 diff --git a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_monthly_care_hours.yaml b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_monthly_care_hours.yaml index 5c5d0d336ae..099d09c4e5b 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_monthly_care_hours.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_monthly_care_hours.yaml @@ -83,13 +83,13 @@ weekly_hours_worked_before_lsr: 0 child: age: 4 + is_in_foster_care: true tax_units: tax_unit: members: [parent, child] spm_units: spm_unit: members: [parent, child] - or_erdc_expanded_child_welfare_eligible: true households: household: members: [parent, child] diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/copay/or_erdc_copay.py b/policyengine_us/variables/gov/states/or/delc/erdc/copay/or_erdc_copay.py index 6be5c0ef129..2ec361c6c8f 100644 --- a/policyengine_us/variables/gov/states/or/delc/erdc/copay/or_erdc_copay.py +++ b/policyengine_us/variables/gov/states/or/delc/erdc/copay/or_erdc_copay.py @@ -41,10 +41,8 @@ def formula(spm_unit, period, parameters): ], default=p.copay.size_8.calc(income), ) + # OAR 414-175-0023(3)(d)-(f) also waives the copay after a permanent + # job loss, a military transition, or medical leave at application; + # these circumstances are not tracked at the moment. categorical = spm_unit("or_erdc_categorically_eligible", period) - job_loss_waiver = spm_unit("or_erdc_permanent_job_loss", period.this_year) - medical_leave_waiver = spm_unit( - "or_erdc_medical_leave_at_application", period.this_year - ) - copay_waived = categorical | job_loss_waiver | medical_leave_waiver - return where(copay_waived, 0, amount) + return where(categorical, 0, amount) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_activity_eligible.py b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_activity_eligible.py index ac79c64664b..dfcf4fb24cc 100644 --- a/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_activity_eligible.py +++ b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_activity_eligible.py @@ -22,22 +22,23 @@ def formula(spm_unit, period, parameters): education_age_eligible = ( person("age", period.this_year) <= p.age_threshold.education ) + # OAR 414-175-0023(1)(a)(B) covers secondary school, GED, and + # equivalent training, which is_in_secondary_school includes; medical + # leave under (1)(a)(C) is not tracked at the moment. secondary_student = ( - person("is_in_secondary_school", period.this_year) - | person("or_erdc_in_ged_program", period.this_year) - ) & education_age_eligible - medical_leave = person("or_erdc_on_medical_leave", period.this_year) - unable_to_care = person("or_erdc_unable_to_provide_care", period.this_year) - supervised_contact = person( - "or_erdc_supervised_contact_required", period.this_year + person("is_in_secondary_school", period.this_year) & education_age_eligible ) + # OAR 414-175-0023(1)(b)(A) excuses a second caretaker who is + # physically or mentally unable to provide adequate care, proxied by + # disability status; the supervised-contact exception in (1)(b)(B) + # is not tracked at the moment. + unable_to_care = person("is_disabled", period.this_year) multiple_caretakers = spm_unit.project(caretaker_count > 1) caretaker_eligible = ( working | postsecondary_student | secondary_student - | medical_leave - | (multiple_caretakers & (unable_to_care | supervised_contact)) + | (multiple_caretakers & unable_to_care) ) has_caretaker = caretaker_count > 0 all_caretakers_eligible = spm_unit.sum(caretaker & ~caretaker_eligible) == 0 diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_categorically_eligible.py b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_categorically_eligible.py index 4a36c6f8180..5c5f14ea676 100644 --- a/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_categorically_eligible.py +++ b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_categorically_eligible.py @@ -12,6 +12,6 @@ class or_erdc_categorically_eligible(Variable): def formula(spm_unit, period, parameters): tanf_enrolled = spm_unit("is_tanf_enrolled", period) expanded_child_welfare = spm_unit( - "or_erdc_expanded_child_welfare_eligible", period.this_year + "or_erdc_expanded_child_welfare_eligible", period ) return tanf_enrolled | expanded_child_welfare diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_eligible_child.py b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_eligible_child.py index e22a4592267..0480b54f1d3 100644 --- a/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_eligible_child.py +++ b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_eligible_child.py @@ -12,11 +12,14 @@ class or_erdc_eligible_child(Variable): def formula(person, period, parameters): p = parameters(period).gov.states["or"].delc.erdc.age_threshold age = person("age", period.this_year) + # OAR 414-175-0022(2)(b): disability covers the high-needs-rate + # pathway in (2)(b)(D); court supervision under (2)(b)(B) and + # compromised-safety circumstances under (2)(b)(E) are not tracked + # at the moment. special_circumstances = ( person("is_incapable_of_self_care", period.this_year) - | person("is_in_foster_care", period.this_year) - | person("or_erdc_high_needs_rate_eligible", period.this_year) - | person("or_erdc_special_circumstances_child", period.this_year) + | person("is_in_foster_care", period) + | person("is_disabled", period.this_year) ) return (age < p.child) | ( (age < p.special_circumstances_child) & special_circumstances diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_expanded_child_welfare_eligible.py b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_expanded_child_welfare_eligible.py new file mode 100644 index 00000000000..dcbd4291ebc --- /dev/null +++ b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_expanded_child_welfare_eligible.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * + + +class or_erdc_expanded_child_welfare_eligible(Variable): + value_type = bool + entity = SPMUnit + definition_period = MONTH + label = "Eligible for Oregon ERDC through Expanded Child Welfare" + defined_for = StateCode.OR + reference = ( + "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0025" + ) + + def formula(spm_unit, period, parameters): + # OAR 414-175-0025(1)(b)(B) grants Expanded Child Welfare eligibility + # for use of Child Welfare protective services; we track foster care + # receipt but not Child Abuse Prevention or Family Reunification + # services, so those pathways are omitted. + return add(spm_unit, period, ["is_in_foster_care"]) > 0 diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/rates/or_erdc_age_group.py b/policyengine_us/variables/gov/states/or/delc/erdc/rates/or_erdc_age_group.py index 7b5ad0a15da..7c6f43073bc 100644 --- a/policyengine_us/variables/gov/states/or/delc/erdc/rates/or_erdc_age_group.py +++ b/policyengine_us/variables/gov/states/or/delc/erdc/rates/or_erdc_age_group.py @@ -40,14 +40,13 @@ def formula(person, period, parameters): ) age = person("age", period.this_year) age_months = age * MONTHS_IN_YEAR - special_needs = person("or_erdc_special_needs_rate_eligible", period.this_year) - # OAR 414-175-0076(1) grants the high needs supplement only to - # children eligible for the special needs rate, so high-needs - # eligibility implies the special-needs rate category. - high_needs = person("or_erdc_high_needs_rate_eligible", period.this_year) + # OAR 414-175-0024(1)(b) grants the special needs rate on request + # with a verified disability; we proxy that determination with + # disability status. + special_needs = person("is_disabled", period.this_year) return select( [ - special_needs | high_needs, + special_needs, age_months < infant_max_months, age_months < p.toddler_max_months, age < p.preschool_max_years, diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/rates/or_erdc_maximum_monthly_rate.py b/policyengine_us/variables/gov/states/or/delc/erdc/rates/or_erdc_maximum_monthly_rate.py index b4ac23f4eab..1ed5defa7bf 100644 --- a/policyengine_us/variables/gov/states/or/delc/erdc/rates/or_erdc_maximum_monthly_rate.py +++ b/policyengine_us/variables/gov/states/or/delc/erdc/rates/or_erdc_maximum_monthly_rate.py @@ -13,46 +13,28 @@ class or_erdc_maximum_monthly_rate(Variable): ) def formula(person, period, parameters): - p = parameters(period).gov.states["or"].delc.erdc.rates + p = parameters(period).gov.states["or"].delc.erdc provider_type = person("or_erdc_provider_type", period) - tiered_provider_type = person("or_erdc_tiered_provider_type", period) area = person("or_erdc_provider_area", period) age_group = person("or_erdc_age_group", period) - hourly_rate = p.hourly[area][provider_type][age_group] - part_time_rate = p.part_time[area][tiered_provider_type][age_group] - monthly_rate = p.monthly[area][provider_type][age_group] + hourly_rate = p.rates.hourly[area][provider_type][age_group] + monthly_rate = p.rates.monthly[area][provider_type][age_group] hours = person("or_erdc_monthly_care_hours", period) - - # OAR 414-175-0076(2): for children eligible for the high needs rate, - # an assessed factor (0-2) adds $5 per hour on hourly billing or $840 - # on monthly billing, in addition to the base provider rate. - factors = person("or_erdc_high_needs_factors", period.this_year) - high_needs = person("or_erdc_high_needs_rate_eligible", period.this_year) - supplement = p.high_needs_supplement - hourly_supplement = where(high_needs, factors * supplement.hourly * hours, 0) - monthly_supplement = where(high_needs, factors * supplement.monthly, 0) - - # OAR 414-175-0075(3),(6): hourly billing is the lesser of hours times - # the hourly rate and the full-time monthly rate, which also keeps the - # reimbursement monotonic across the monthly-billing threshold. - hourly_payment = min_(hourly_rate * hours, monthly_rate) + hourly_supplement - - tier = person("or_erdc_billing_tier", period) - tiers = tier.possible_values - return where( - hours > 0, - select( - [ - tier == tiers.HOURLY, - tier == tiers.PART_TIME, - tier == tiers.MONTHLY, - ], - [ - hourly_payment, - part_time_rate + monthly_supplement, - monthly_rate + monthly_supplement, - ], - default=0, - ), - 0, + types = provider_type.possible_values + standard_provider = (provider_type == types.STANDARD_FAMILY) | ( + provider_type == types.STANDARD_CENTER + ) + # OAR 414-175-0075(3)(a),(b),(e): care below the full-time hours + # threshold is paid hourly, capped at the full-time monthly rate. + # The part-time monthly rate in (3)(c) applies only to enhanced or + # licensed providers that customarily bill all families part-time, + # and the high needs supplement in OAR 414-175-0076 requires a + # Department-assessed factor; we track neither provider billing + # practices nor assessed factors, so both are omitted. + full_time_hours = where( + standard_provider, + p.hours.full_time_threshold.standard, + p.hours.full_time_threshold.licensed, ) + hourly_payment = min_(hourly_rate * hours, monthly_rate) + return where(hours >= full_time_hours, monthly_rate, hourly_payment) From 8200f73bc5b5cd04145c0449aaf4eaaefdae045c Mon Sep 17 00:00:00 2001 From: Ziming Date: Mon, 13 Jul 2026 18:41:59 -0400 Subject: [PATCH 6/7] Apply round-5 review fixes to Oregon ERDC Criticals: - Add CCDF immigration eligibility check to or_erdc_eligible_child - Add pre-increase 2024-01-01 FAM/QFM rates from the DELC 7492i (01/24) insert so Jan-Feb 2026 and 2024-2025 no longer backfill the 3/1/2026 increase - Read EXP-CW eligibility at the month period in or_erdc_income_eligible Should-address: - Exclude excused (disabled) second caretakers from the need-hours min() so OAR 414-175-0023(1)(b)(A) families are not denied - Corroborate the 215-hour cap with the rate chart; standardize all OAR references to rule-specific URLs - Document provider area/type data limitations - Add 7 test cases: multi-caretaker min, 20-hour band edge, excused caretaker, unearned income, sub-bracket copay, categorical false, and per-business self-employment flooring Co-Authored-By: Claude Fable 5 --- .../or/delc/erdc/age_threshold/child.yaml | 2 +- .../special_circumstances_child.yaml | 2 +- .../gov/states/or/delc/erdc/copay/size_2.yaml | 2 +- .../gov/states/or/delc/erdc/copay/size_3.yaml | 2 +- .../gov/states/or/delc/erdc/copay/size_4.yaml | 2 +- .../gov/states/or/delc/erdc/copay/size_5.yaml | 2 +- .../gov/states/or/delc/erdc/copay/size_6.yaml | 2 +- .../gov/states/or/delc/erdc/copay/size_7.yaml | 2 +- .../gov/states/or/delc/erdc/copay/size_8.yaml | 2 +- .../or/delc/erdc/hours/max_monthly.yaml | 4 +- .../countable_income/earned_sources.yaml | 4 +- .../erdc/income/countable_income/sources.yaml | 4 +- .../or/delc/erdc/income/fpl_rate/initial.yaml | 2 +- .../or/delc/erdc/income/fpl_rate/ongoing.yaml | 2 +- .../or/delc/erdc/income/smi_rate/ongoing.yaml | 2 +- .../states/or/delc/erdc/max_group_size.yaml | 2 +- .../gov/states/or/delc/erdc/rates/hourly.yaml | 32 +++++++ .../states/or/delc/erdc/rates/monthly.yaml | 32 +++++++ .../erdc/or_erdc_categorically_eligible.yaml | 24 ++++++ .../states/or/delc/erdc/or_erdc_copay.yaml | 12 +++ .../erdc/or_erdc_countable_earned_income.yaml | 27 ++++++ .../delc/erdc/or_erdc_countable_income.yaml | 26 ++++++ .../delc/erdc/or_erdc_monthly_care_hours.yaml | 83 +++++++++++++++++++ .../eligibility/or_erdc_activity_eligible.py | 4 +- .../or_erdc_categorically_eligible.py | 4 +- .../delc/erdc/eligibility/or_erdc_eligible.py | 4 +- .../eligibility/or_erdc_eligible_child.py | 10 ++- .../eligibility/or_erdc_income_eligible.py | 2 +- .../or_erdc_caretaker_weekly_need_hours.py | 21 ++++- .../erdc/income/or_erdc_countable_income.py | 4 +- .../or_erdc_allowable_child_care_cost.py | 4 +- .../delc/erdc/rates/or_erdc_provider_area.py | 12 +-- .../delc/erdc/rates/or_erdc_provider_type.py | 10 ++- 33 files changed, 310 insertions(+), 39 deletions(-) create mode 100644 policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_categorically_eligible.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_countable_income.yaml diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/age_threshold/child.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/age_threshold/child.yaml index bf19365c6e8..df11e4cc13f 100644 --- a/policyengine_us/parameters/gov/states/or/delc/erdc/age_threshold/child.yaml +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/age_threshold/child.yaml @@ -8,4 +8,4 @@ metadata: label: Oregon ERDC child age threshold reference: - title: OAR 414-175-0022(2)(a) - href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 + href: https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0022 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/age_threshold/special_circumstances_child.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/age_threshold/special_circumstances_child.yaml index 6c86cbbc17d..9a2655ad2fc 100644 --- a/policyengine_us/parameters/gov/states/or/delc/erdc/age_threshold/special_circumstances_child.yaml +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/age_threshold/special_circumstances_child.yaml @@ -8,4 +8,4 @@ metadata: label: Oregon ERDC special circumstances child age threshold reference: - title: OAR 414-175-0022(2)(b) - href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 + href: https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0022 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_2.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_2.yaml index b4466679536..9ab6066dfea 100644 --- a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_2.yaml +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_2.yaml @@ -7,7 +7,7 @@ metadata: label: Oregon ERDC group size 2 monthly copay reference: - title: OAR 414-175-0050(3)(b), Need group size 2 - href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 + href: https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0050 brackets: - threshold: diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_3.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_3.yaml index cf4f74d59d2..317e5ba6de8 100644 --- a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_3.yaml +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_3.yaml @@ -7,7 +7,7 @@ metadata: label: Oregon ERDC group size 3 monthly copay reference: - title: OAR 414-175-0050(3)(b), Need group size 3 - href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 + href: https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0050 brackets: - threshold: diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_4.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_4.yaml index b0da5bbff3a..73455661b89 100644 --- a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_4.yaml +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_4.yaml @@ -7,7 +7,7 @@ metadata: label: Oregon ERDC group size 4 monthly copay reference: - title: OAR 414-175-0050(3)(b), Need group size 4 - href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 + href: https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0050 brackets: - threshold: diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_5.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_5.yaml index 0437f10158f..931834d893f 100644 --- a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_5.yaml +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_5.yaml @@ -7,7 +7,7 @@ metadata: label: Oregon ERDC group size 5 monthly copay reference: - title: OAR 414-175-0050(3)(b), Need group size 5 - href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 + href: https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0050 brackets: - threshold: diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_6.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_6.yaml index df3ef386bfb..f5ce8a75531 100644 --- a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_6.yaml +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_6.yaml @@ -7,7 +7,7 @@ metadata: label: Oregon ERDC group size 6 monthly copay reference: - title: OAR 414-175-0050(3)(b), Need group size 6 - href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 + href: https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0050 brackets: - threshold: diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_7.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_7.yaml index e150064ab6c..8745c4a8874 100644 --- a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_7.yaml +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_7.yaml @@ -7,7 +7,7 @@ metadata: label: Oregon ERDC group size 7 monthly copay reference: - title: OAR 414-175-0050(3)(b), Need group size 7 - href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 + href: https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0050 brackets: - threshold: diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_8.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_8.yaml index 0a6b451d466..7f02d91aec5 100644 --- a/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_8.yaml +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/copay/size_8.yaml @@ -7,7 +7,7 @@ metadata: label: Oregon ERDC group size 8 or more monthly copay reference: - title: OAR 414-175-0050(3)(b), Need group size 8 or more - href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 + href: https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0050 brackets: - threshold: diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/hours/max_monthly.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/hours/max_monthly.yaml index f8a5d16f581..0b35cfc139d 100644 --- a/policyengine_us/parameters/gov/states/or/delc/erdc/hours/max_monthly.yaml +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/hours/max_monthly.yaml @@ -8,4 +8,6 @@ metadata: label: Oregon ERDC maximum standard monthly hours reference: - title: OAR 414-175-0075(6)-(8) - href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 + href: https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0075 + - title: ERDC Provider Guide Insert, 2026 monthly billing range + href: https://www.oregon.gov/delc/providers/Documents/Provider%20Rate%20Increase%20For%20Jan%202026_Phase%202_ENG.pdf#page=2 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/income/countable_income/earned_sources.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/income/countable_income/earned_sources.yaml index 31ac3b8e4cf..1c51a5117d6 100644 --- a/policyengine_us/parameters/gov/states/or/delc/erdc/income/countable_income/earned_sources.yaml +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/income/countable_income/earned_sources.yaml @@ -13,6 +13,6 @@ metadata: label: Oregon ERDC countable earned income sources reference: - title: OAR 414-175-0030(1), General Financial Eligibility Provisions - href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 + href: https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0030 - title: OAR 414-175-0035, Specific Financial Requirements - href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 + href: https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0035 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/income/countable_income/sources.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/income/countable_income/sources.yaml index 61523b0854b..e0db46c9d95 100644 --- a/policyengine_us/parameters/gov/states/or/delc/erdc/income/countable_income/sources.yaml +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/income/countable_income/sources.yaml @@ -32,6 +32,6 @@ metadata: label: Oregon ERDC countable income sources reference: - title: OAR 414-175-0030(1), General Financial Eligibility Provisions - href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 + href: https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0030 - title: OAR 414-175-0035, Specific Financial Requirements - href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 + href: https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0035 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/income/fpl_rate/initial.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/income/fpl_rate/initial.yaml index df01ee5333f..84117a4ee24 100644 --- a/policyengine_us/parameters/gov/states/or/delc/erdc/income/fpl_rate/initial.yaml +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/income/fpl_rate/initial.yaml @@ -8,4 +8,4 @@ metadata: label: Oregon ERDC initial income FPL rate reference: - title: OAR 414-175-0050(1)(b)(A) - href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 + href: https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0050 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/income/fpl_rate/ongoing.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/income/fpl_rate/ongoing.yaml index 46f0ea8a910..2f7f1634a46 100644 --- a/policyengine_us/parameters/gov/states/or/delc/erdc/income/fpl_rate/ongoing.yaml +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/income/fpl_rate/ongoing.yaml @@ -8,4 +8,4 @@ metadata: label: Oregon ERDC ongoing income FPL rate reference: - title: OAR 414-175-0050(1)(b)(B) - href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 + href: https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0050 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/income/smi_rate/ongoing.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/income/smi_rate/ongoing.yaml index 8531a12affa..08b01168b22 100644 --- a/policyengine_us/parameters/gov/states/or/delc/erdc/income/smi_rate/ongoing.yaml +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/income/smi_rate/ongoing.yaml @@ -8,4 +8,4 @@ metadata: label: Oregon ERDC ongoing income SMI rate reference: - title: OAR 414-175-0050(1)(b)(B) - href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 + href: https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0050 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/max_group_size.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/max_group_size.yaml index 09cd96d468e..37432243e84 100644 --- a/policyengine_us/parameters/gov/states/or/delc/erdc/max_group_size.yaml +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/max_group_size.yaml @@ -8,4 +8,4 @@ metadata: label: Oregon ERDC maximum group size reference: - title: OAR 414-175-0050(1)(b) - href: https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871 + href: https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0050 diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/rates/hourly.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/rates/hourly.yaml index a4913d9283e..24a5cd254a9 100644 --- a/policyengine_us/parameters/gov/states/or/delc/erdc/rates/hourly.yaml +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/rates/hourly.yaml @@ -10,18 +10,25 @@ metadata: reference: - title: Oregon DELC ERDC Child Care Maximum Rates, Group Areas A-C href: https://www.oregon.gov/delc/providers/Documents/Provider%20Rate%20Increase%20For%20Jan%202026_Phase%202_ENG.pdf#page=2 + - title: Oregon DELC ERDC Maximum Rates, Provider Guide Insert DELC 7492i (01/24), effective January 1, 2024 + href: http://web.archive.org/web/20251012133829id_/https://www.oregon.gov/delc/programs/ERDC%20Fliers/Provider%20Guide%20Insert%20Final%20EN.pdf AREA_A: STANDARD_FAMILY: INFANT: + 2024-01-01: 6.3 2026-03-01: 6.5 TODDLER: + 2024-01-01: 5.7 2026-03-01: 5.9 PRESCHOOL: + 2024-01-01: 5.4 2026-03-01: 5.4 SCHOOL: + 2024-01-01: 5.1 2026-03-01: 5.7 SPECIAL_NEEDS: + 2024-01-01: 6.3 2026-03-01: 6.5 STANDARD_CENTER: INFANT: @@ -36,14 +43,19 @@ AREA_A: 2026-01-01: 9 ENHANCED_FAMILY: INFANT: + 2024-01-01: 6.65 2026-03-01: 6.86 TODDLER: + 2024-01-01: 6.01 2026-03-01: 6.22 PRESCHOOL: + 2024-01-01: 5.7 2026-03-01: 5.7 SCHOOL: + 2024-01-01: 5.39 2026-03-01: 6.01 SPECIAL_NEEDS: + 2024-01-01: 6.65 2026-03-01: 6.86 ENHANCED_CENTER: INFANT: @@ -92,14 +104,19 @@ AREA_A: AREA_B: STANDARD_FAMILY: INFANT: + 2024-01-01: 4.2 2026-03-01: 4.95 TODDLER: + 2024-01-01: 3.9 2026-03-01: 4.73 PRESCHOOL: + 2024-01-01: 3.75 2026-03-01: 4.5 SCHOOL: + 2024-01-01: 3.9 2026-03-01: 5.4 SPECIAL_NEEDS: + 2024-01-01: 4.2 2026-03-01: 4.95 STANDARD_CENTER: INFANT: @@ -114,14 +131,19 @@ AREA_B: 2026-01-01: 6.56 ENHANCED_FAMILY: INFANT: + 2024-01-01: 4.44 2026-03-01: 5.23 TODDLER: + 2024-01-01: 4.11 2026-03-01: 4.99 PRESCHOOL: + 2024-01-01: 4.11 2026-03-01: 4.75 SCHOOL: + 2024-01-01: 4.11 2026-03-01: 5.7 SPECIAL_NEEDS: + 2024-01-01: 4.44 2026-03-01: 5.23 ENHANCED_CENTER: INFANT: @@ -170,14 +192,19 @@ AREA_B: AREA_C: STANDARD_FAMILY: INFANT: + 2024-01-01: 4.2 2026-03-01: 4.95 TODDLER: + 2024-01-01: 3.9 2026-03-01: 4.73 PRESCHOOL: + 2024-01-01: 3.75 2026-03-01: 4.5 SCHOOL: + 2024-01-01: 3.9 2026-03-01: 5.4 SPECIAL_NEEDS: + 2024-01-01: 4.2 2026-03-01: 4.95 STANDARD_CENTER: INFANT: @@ -192,14 +219,19 @@ AREA_C: 2026-01-01: 6.56 ENHANCED_FAMILY: INFANT: + 2024-01-01: 4.44 2026-03-01: 5.23 TODDLER: + 2024-01-01: 4.11 2026-03-01: 4.99 PRESCHOOL: + 2024-01-01: 4.11 2026-03-01: 4.75 SCHOOL: + 2024-01-01: 4.11 2026-03-01: 5.7 SPECIAL_NEEDS: + 2024-01-01: 4.44 2026-03-01: 5.23 ENHANCED_CENTER: INFANT: diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/rates/monthly.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/rates/monthly.yaml index 76632cace86..25186e21334 100644 --- a/policyengine_us/parameters/gov/states/or/delc/erdc/rates/monthly.yaml +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/rates/monthly.yaml @@ -10,18 +10,25 @@ metadata: reference: - title: Oregon DELC ERDC Child Care Maximum Rates, Group Areas A-C href: https://www.oregon.gov/delc/providers/Documents/Provider%20Rate%20Increase%20For%20Jan%202026_Phase%202_ENG.pdf#page=2 + - title: Oregon DELC ERDC Maximum Rates, Provider Guide Insert DELC 7492i (01/24), effective January 1, 2024 + href: http://web.archive.org/web/20251012133829id_/https://www.oregon.gov/delc/programs/ERDC%20Fliers/Provider%20Guide%20Insert%20Final%20EN.pdf AREA_A: STANDARD_FAMILY: INFANT: + 2024-01-01: 1_041 2026-03-01: 1_110 TODDLER: + 2024-01-01: 945 2026-03-01: 1_020 PRESCHOOL: + 2024-01-01: 870 2026-03-01: 930 SCHOOL: + 2024-01-01: 780 2026-03-01: 840 SPECIAL_NEEDS: + 2024-01-01: 1_041 2026-03-01: 1_110 STANDARD_CENTER: INFANT: @@ -36,14 +43,19 @@ AREA_A: 2026-01-01: 1_562 ENHANCED_FAMILY: INFANT: + 2024-01-01: 1_099 2026-03-01: 1_172 TODDLER: + 2024-01-01: 998 2026-03-01: 1_077 PRESCHOOL: + 2024-01-01: 919 2026-03-01: 982 SCHOOL: + 2024-01-01: 824 2026-03-01: 887 SPECIAL_NEEDS: + 2024-01-01: 1_099 2026-03-01: 1_172 ENHANCED_CENTER: INFANT: @@ -92,14 +104,19 @@ AREA_A: AREA_B: STANDARD_FAMILY: INFANT: + 2024-01-01: 750 2026-03-01: 855 TODDLER: + 2024-01-01: 705 2026-03-01: 788 PRESCHOOL: + 2024-01-01: 691 2026-03-01: 750 SCHOOL: + 2024-01-01: 647 2026-03-01: 720 SPECIAL_NEEDS: + 2024-01-01: 750 2026-03-01: 855 STANDARD_CENTER: INFANT: @@ -114,14 +131,19 @@ AREA_B: 2026-01-01: 1_125 ENHANCED_FAMILY: INFANT: + 2024-01-01: 791 2026-03-01: 903 TODDLER: + 2024-01-01: 744 2026-03-01: 831 PRESCHOOL: + 2024-01-01: 730 2026-03-01: 791 SCHOOL: + 2024-01-01: 683 2026-03-01: 760 SPECIAL_NEEDS: + 2024-01-01: 791 2026-03-01: 903 ENHANCED_CENTER: INFANT: @@ -170,14 +192,19 @@ AREA_B: AREA_C: STANDARD_FAMILY: INFANT: + 2024-01-01: 750 2026-03-01: 855 TODDLER: + 2024-01-01: 705 2026-03-01: 788 PRESCHOOL: + 2024-01-01: 691 2026-03-01: 750 SCHOOL: + 2024-01-01: 647 2026-03-01: 720 SPECIAL_NEEDS: + 2024-01-01: 750 2026-03-01: 855 STANDARD_CENTER: INFANT: @@ -192,14 +219,19 @@ AREA_C: 2026-01-01: 1_125 ENHANCED_FAMILY: INFANT: + 2024-01-01: 791 2026-03-01: 903 TODDLER: + 2024-01-01: 744 2026-03-01: 831 PRESCHOOL: + 2024-01-01: 730 2026-03-01: 791 SCHOOL: + 2024-01-01: 683 2026-03-01: 760 SPECIAL_NEEDS: + 2024-01-01: 791 2026-03-01: 903 ENHANCED_CENTER: INFANT: diff --git a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_categorically_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_categorically_eligible.yaml new file mode 100644 index 00000000000..1456f7ecbd3 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_categorically_eligible.yaml @@ -0,0 +1,24 @@ +# OAR 414-175-0025 grants categorical eligibility only through TANF enrollment +# or Expanded Child Welfare (foster care); a family with neither is not +# categorically eligible. + +- name: Case 1, a family with no TANF enrollment and no foster care is not categorically eligible. + period: 2027-01 + input: + people: + parent: + age: 30 + child: + age: 4 + tax_units: + tax_unit: + members: [parent, child] + spm_units: + spm_unit: + members: [parent, child] + households: + household: + members: [parent, child] + state_code: OR + output: + or_erdc_categorically_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_copay.yaml b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_copay.yaml index e991d35eebf..87aa7873ad0 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_copay.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_copay.yaml @@ -86,3 +86,15 @@ state_code: OR output: or_erdc_copay: 130 + +- name: Group size 2 non-categorical family below the first paid bracket has no copay. + period: 2027-01 + absolute_error_margin: 0.01 + input: + or_erdc_countable_income: 1_500 + spm_unit_size: 2 + state_code: OR + output: + # 1,500/month is below the first paid bracket threshold of 1,804, so the + # non-categorical family owes no copay. + or_erdc_copay: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_countable_earned_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_countable_earned_income.yaml index d8a459ab590..a310ab679f0 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_countable_earned_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_countable_earned_income.yaml @@ -126,3 +126,30 @@ state_code: OR output: or_erdc_countable_earned_income: [2_000, 0] + +- name: Case 6, a farm gain and a separate self-employment loss do not net across businesses. + period: 2027-01 + absolute_error_margin: 0.1 + input: + people: + parent: + age: 30 + farm_operations_income: 12_000 + self_employment_income: -12_000 + child: + age: 4 + tax_units: + tax_unit: + members: [parent, child] + spm_units: + spm_unit: + members: [parent, child] + households: + household: + members: [parent, child] + state_code: OR + output: + # OAR 414-175-0035(81)(a) determines each business separately: the farm gain + # (12,000/year) and the floored self-employment loss (0) do not net, so + # countable self-employment is 12,000/year = 1,000/month. + or_erdc_countable_self_employment_income: [1_000, 0] diff --git a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_countable_income.yaml new file mode 100644 index 00000000000..abe3e723bf8 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_countable_income.yaml @@ -0,0 +1,26 @@ +# OAR 414-175-0035 counts unearned income such as Social Security benefits +# under the Employment Related Day Care program. + +- name: Case 1, a caretaker's Social Security benefits count as unearned income. + period: 2027-01 + absolute_error_margin: 0.01 + input: + people: + parent: + age: 30 + social_security: 12_000 + child: + age: 4 + tax_units: + tax_unit: + members: [parent, child] + spm_units: + spm_unit: + members: [parent, child] + households: + household: + members: [parent, child] + state_code: OR + output: + # Social Security 12,000/year = 1,000/month countable. + or_erdc_countable_income: 1_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_monthly_care_hours.yaml b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_monthly_care_hours.yaml index 099d09c4e5b..39d0da79feb 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_monthly_care_hours.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/or_erdc_monthly_care_hours.yaml @@ -98,3 +98,86 @@ # No work hours, but the categorical 20-hour floor applies: # 20 * 1.25 * 4.3 = 107.5, rounded up to 108. or_erdc_monthly_care_hours: [0, 108] + +- name: An excused disabled second caretaker does not collapse the need to zero. + period: 2027-01 + absolute_error_margin: 0.01 + input: + people: + parent1: + age: 30 + is_disabled: true + weekly_hours_worked_before_lsr: 0 + parent2: + age: 28 + weekly_hours_worked_before_lsr: 40 + child: + age: 4 + tax_units: + tax_unit: + members: [parent1, parent2, child] + spm_units: + spm_unit: + members: [parent1, parent2, child] + households: + household: + members: [parent1, parent2, child] + state_code: OR + output: + # The disabled non-working second caretaker is excused and dropped from the + # overlap minimum, so the need follows the working caretaker's 40 hours: + # 40 * 1.25 * 4.3 = 215 monthly hours. + or_erdc_monthly_care_hours: [0, 0, 215] + +- name: Two working caretakers use the lower schedule for the overlap minimum. + period: 2027-01 + absolute_error_margin: 0.01 + input: + people: + parent1: + age: 30 + weekly_hours_worked_before_lsr: 40 + parent2: + age: 28 + weekly_hours_worked_before_lsr: 20 + child: + age: 4 + tax_units: + tax_unit: + members: [parent1, parent2, child] + spm_units: + spm_unit: + members: [parent1, parent2, child] + households: + household: + members: [parent1, parent2, child] + state_code: OR + output: + # Lowest caretaker hours (20) set the need -> 20-hour band: + # 20 * 1.25 * 4.3 = 107.5, rounded up to 108. + or_erdc_monthly_care_hours: [0, 0, 108] + +- name: A single caretaker at exactly twenty weekly hours stays in the 20-hour band. + period: 2027-01 + absolute_error_margin: 0.01 + input: + people: + parent: + age: 30 + weekly_hours_worked_before_lsr: 20 + child: + age: 4 + tax_units: + tax_unit: + members: [parent, child] + spm_units: + spm_unit: + members: [parent, child] + households: + household: + members: [parent, child] + state_code: OR + output: + # 20 need hours land in the 20-hour band (bracket threshold 20.0001): + # 20 * 1.25 * 4.3 = 107.5, rounded up to 108. + or_erdc_monthly_care_hours: [0, 108] diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_activity_eligible.py b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_activity_eligible.py index dfcf4fb24cc..fe82a5dbbd8 100644 --- a/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_activity_eligible.py +++ b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_activity_eligible.py @@ -7,7 +7,9 @@ class or_erdc_activity_eligible(Variable): definition_period = MONTH label = "Eligible for Oregon ERDC based on caretaker activity" defined_for = StateCode.OR - reference = "https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871" + reference = ( + "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0023" + ) def formula(spm_unit, period, parameters): p = parameters(period).gov.states["or"].delc.erdc diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_categorically_eligible.py b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_categorically_eligible.py index 5c5f14ea676..d083bf3389c 100644 --- a/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_categorically_eligible.py +++ b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_categorically_eligible.py @@ -7,7 +7,9 @@ class or_erdc_categorically_eligible(Variable): definition_period = MONTH label = "Categorically eligible for Oregon ERDC" defined_for = StateCode.OR - reference = "https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871" + reference = ( + "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0025" + ) def formula(spm_unit, period, parameters): tanf_enrolled = spm_unit("is_tanf_enrolled", period) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_eligible.py b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_eligible.py index 3be9a73b7f3..5aec787ed8c 100644 --- a/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_eligible.py +++ b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_eligible.py @@ -7,7 +7,9 @@ class or_erdc_eligible(Variable): definition_period = MONTH label = "Eligible for Oregon ERDC" defined_for = StateCode.OR - reference = "https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871" + reference = ( + "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0015" + ) def formula(spm_unit, period, parameters): has_eligible_child = add(spm_unit, period, ["or_erdc_eligible_child"]) > 0 diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_eligible_child.py b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_eligible_child.py index 0480b54f1d3..248484b97c9 100644 --- a/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_eligible_child.py +++ b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_eligible_child.py @@ -7,7 +7,9 @@ class or_erdc_eligible_child(Variable): definition_period = MONTH label = "Eligible child for Oregon ERDC" defined_for = StateCode.OR - reference = "https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871" + reference = ( + "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0022" + ) def formula(person, period, parameters): p = parameters(period).gov.states["or"].delc.erdc.age_threshold @@ -21,6 +23,10 @@ def formula(person, period, parameters): | person("is_in_foster_care", period) | person("is_disabled", period.this_year) ) - return (age < p.child) | ( + age_eligible = (age < p.child) | ( (age < p.special_circumstances_child) & special_circumstances ) + immigration_eligible = person( + "is_ccdf_immigration_eligible_child", period.this_year + ) + return age_eligible & immigration_eligible diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_income_eligible.py b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_income_eligible.py index 1a21f49f2ca..004a7c980e8 100644 --- a/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_income_eligible.py +++ b/policyengine_us/variables/gov/states/or/delc/erdc/eligibility/or_erdc_income_eligible.py @@ -16,7 +16,7 @@ class or_erdc_income_eligible(Variable): def formula(spm_unit, period, parameters): p = parameters(period).gov.states["or"].delc.erdc expanded_child_welfare = spm_unit( - "or_erdc_expanded_child_welfare_eligible", period.this_year + "or_erdc_expanded_child_welfare_eligible", period ) countable_income = spm_unit("or_erdc_countable_income", period) size = spm_unit("spm_unit_size", period.this_year) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/hours/or_erdc_caretaker_weekly_need_hours.py b/policyengine_us/variables/gov/states/or/delc/erdc/hours/or_erdc_caretaker_weekly_need_hours.py index 29e3da4fc80..1a64a45a987 100644 --- a/policyengine_us/variables/gov/states/or/delc/erdc/hours/or_erdc_caretaker_weekly_need_hours.py +++ b/policyengine_us/variables/gov/states/or/delc/erdc/hours/or_erdc_caretaker_weekly_need_hours.py @@ -24,8 +24,21 @@ def formula(spm_unit, period, parameters): # work or school schedules overlap; we do not track schedules, so we # use the lowest caretaker's hours, the maximum possible overlap. # Set this variable directly when actual overlapping hours are known. - # Non-caretakers get infinity so they never lower the need. weekly_hours = person("weekly_hours_worked_before_lsr", period.this_year) - has_caretaker = spm_unit.sum(is_caretaker) > 0 - lowest_caretaker_hours = spm_unit.min(where(is_caretaker, weekly_hours, np.inf)) - return where(has_caretaker, lowest_caretaker_hours, 0) + # OAR 414-175-0023(1)(b)(A) excuses a second caretaker who is unable to + # provide adequate care (proxied by disability, mirroring + # or_erdc_activity_eligible); drop them from the overlap minimum so a + # non-working excused caretaker does not collapse the need to zero. The + # excuse is only for a second caretaker, so a lone disabled caretaker is + # still counted. + caretaker_count = spm_unit.sum(is_caretaker) + multiple_caretakers = spm_unit.project(caretaker_count > 1) + unable_to_care = person("is_disabled", period.this_year) + counted_caretaker = is_caretaker & ~(multiple_caretakers & unable_to_care) + # Non-caretakers and excused caretakers get infinity so they never lower + # the need; if every caretaker is excused, fall back to zero. + has_counted_caretaker = spm_unit.sum(counted_caretaker) > 0 + lowest_caretaker_hours = spm_unit.min( + where(counted_caretaker, weekly_hours, np.inf) + ) + return where(has_counted_caretaker, lowest_caretaker_hours, 0) diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/income/or_erdc_countable_income.py b/policyengine_us/variables/gov/states/or/delc/erdc/income/or_erdc_countable_income.py index 7ab57014360..fc3f5af4488 100644 --- a/policyengine_us/variables/gov/states/or/delc/erdc/income/or_erdc_countable_income.py +++ b/policyengine_us/variables/gov/states/or/delc/erdc/income/or_erdc_countable_income.py @@ -8,5 +8,7 @@ class or_erdc_countable_income(Variable): unit = USD label = "Oregon ERDC countable income" defined_for = StateCode.OR - reference = "https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871" + reference = ( + "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0035" + ) adds = "gov.states.or.delc.erdc.income.countable_income.sources" diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/rates/or_erdc_allowable_child_care_cost.py b/policyengine_us/variables/gov/states/or/delc/erdc/rates/or_erdc_allowable_child_care_cost.py index dd181916578..7fd48d146b7 100644 --- a/policyengine_us/variables/gov/states/or/delc/erdc/rates/or_erdc_allowable_child_care_cost.py +++ b/policyengine_us/variables/gov/states/or/delc/erdc/rates/or_erdc_allowable_child_care_cost.py @@ -8,7 +8,9 @@ class or_erdc_allowable_child_care_cost(Variable): unit = USD label = "Oregon ERDC allowable child care cost" defined_for = StateCode.OR - reference = "https://secure.sos.state.or.us/oard/displayDivisionRules.action?selectedDivision=7871" + reference = ( + "https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0075" + ) def formula(spm_unit, period, parameters): person = spm_unit.members diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/rates/or_erdc_provider_area.py b/policyengine_us/variables/gov/states/or/delc/erdc/rates/or_erdc_provider_area.py index 73dc5c2bffa..7e7c14fb00d 100644 --- a/policyengine_us/variables/gov/states/or/delc/erdc/rates/or_erdc_provider_area.py +++ b/policyengine_us/variables/gov/states/or/delc/erdc/rates/or_erdc_provider_area.py @@ -11,11 +11,13 @@ class or_erdc_provider_area(Variable): value_type = Enum entity = Person possible_values = ORERDCProviderArea - # Area C is the conservative (lowest-rate) default until provider ZIP code - # mapping is implemented. In population runs this understates rates on its - # own, partly offsetting the highest-rate CERTIFIED_CENTER provider-type - # default; the remedy is populating provider area from data, not changing - # this default. + # We don't track a family's provider location at the moment, so this + # defaults to Area C. Areas B and C share an identical rate schedule, so the + # default is exact for those families but understates rates for Area A + # (metro ZIP) families, whose rates are higher. In population runs that + # understatement partly offsets the upward bias from the highest-rate + # CERTIFIED_CENTER provider-type default. The remedy is populating provider + # area from data or overriding it as an input, not changing this default. default_value = ORERDCProviderArea.AREA_C definition_period = MONTH label = "Oregon ERDC provider rate area" diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/rates/or_erdc_provider_type.py b/policyengine_us/variables/gov/states/or/delc/erdc/rates/or_erdc_provider_type.py index ddf805f0130..6e0e9820b12 100644 --- a/policyengine_us/variables/gov/states/or/delc/erdc/rates/or_erdc_provider_type.py +++ b/policyengine_us/variables/gov/states/or/delc/erdc/rates/or_erdc_provider_type.py @@ -15,10 +15,12 @@ class or_erdc_provider_type(Variable): value_type = Enum entity = Person possible_values = ORERDCProviderType - # CERTIFIED_CENTER (CNT) is the highest-rate provider type, so as a - # population default it biases modeled rates upward; it partly offsets the - # lowest-rate AREA_C area default. The remedy is populating provider type - # from data, not changing this default. + # We don't track a family's provider type at the moment, so this defaults + # to CERTIFIED_CENTER (CNT), the highest-rate provider type. As a population + # default it biases modeled rates upward, partly offsetting the downward + # bias from the Area C provider-area default. The remedy is populating + # provider type from data or overriding it as an input, not changing this + # default. default_value = ORERDCProviderType.CERTIFIED_CENTER definition_period = MONTH label = "Oregon ERDC provider type" From c80d414b97a1f44c6ed899ffa78a7ce0e70b2016 Mon Sep 17 00:00:00 2001 From: Ziming Date: Mon, 13 Jul 2026 19:58:59 -0400 Subject: [PATCH 7/7] Exclude 18-year-old students from ERDC caretaker earned income PolicyEngine's age-based headship assigns an 18-year-old child as the tax-unit spouse when no real spouse exists, so the head-or-spouse caretaker filter counted their wages. Per OAR 414-175-0015(2)(d), the filing group's children include those under 18 or age 18 attending secondary school, so their earned income stays excluded under OAR 414-175-0035(21)(a). Narrow the filter with a parameterized filing-group child definition. Co-Authored-By: Claude Fable 5 --- .../age_threshold/filing_group_child.yaml | 14 ++++++++++++ .../income/or_erdc_countable_earned_income.py | 22 +++++++++++++++---- 2 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 policyengine_us/parameters/gov/states/or/delc/erdc/age_threshold/filing_group_child.yaml diff --git a/policyengine_us/parameters/gov/states/or/delc/erdc/age_threshold/filing_group_child.yaml b/policyengine_us/parameters/gov/states/or/delc/erdc/age_threshold/filing_group_child.yaml new file mode 100644 index 00000000000..89933bf8ffd --- /dev/null +++ b/policyengine_us/parameters/gov/states/or/delc/erdc/age_threshold/filing_group_child.yaml @@ -0,0 +1,14 @@ +description: Oregon includes unmarried children under this age in the filing group under the Employment Related Day Care program. +# Children who are 18 and attending secondary or vocational school at least +# half-time also remain filing-group children; we don't track half-time +# attendance at the moment, so any 18-year-old secondary student qualifies. +values: + 2023-07-01: 18 + +metadata: + unit: year + period: year + label: Oregon ERDC filing group child age threshold + reference: + - title: OAR 414-175-0015(2)(d) + href: https://secure.sos.state.or.us/oard/view.action?ruleNumber=414-175-0015 diff --git a/policyengine_us/variables/gov/states/or/delc/erdc/income/or_erdc_countable_earned_income.py b/policyengine_us/variables/gov/states/or/delc/erdc/income/or_erdc_countable_earned_income.py index b800092fbef..e98e20adef2 100644 --- a/policyengine_us/variables/gov/states/or/delc/erdc/income/or_erdc_countable_earned_income.py +++ b/policyengine_us/variables/gov/states/or/delc/erdc/income/or_erdc_countable_earned_income.py @@ -15,8 +15,22 @@ class or_erdc_countable_earned_income(Variable): def formula(person, period, parameters): p = parameters(period).gov.states["or"].delc.erdc earned = add(person, period, p.income.countable_income.earned_sources) - # OAR 414-175-0035(21)(a) excludes the earned income of a child; the - # OAR 414-175-0015(2)(d) filing group counts earned income only from - # caretakers, proxied program-wide by tax unit heads and spouses. - caretaker = person("is_tax_unit_head_or_spouse", period.this_year) + # OAR 414-175-0015(2)(d) keeps unmarried children under 18, and + # 18-year-old secondary students, in the filing group as children, and + # OAR 414-175-0035(21)(a) excludes a child's earned income. We don't + # track half-time attendance at the moment, so any 18-year-old + # secondary student counts as a child. + age = person("age", period.this_year) + child_age_limit = p.age_threshold.filing_group_child + is_secondary_student = person("is_in_secondary_school", period.this_year) + is_filing_group_child = (age < child_age_limit) | ( + (age < child_age_limit + 1) & is_secondary_student + ) + # Earned income is counted only from caretakers (tax unit heads and + # spouses), never from a filing-group child that age-based headship + # would otherwise treat as a spouse. + caretaker = ( + person("is_tax_unit_head_or_spouse", period.this_year) + & ~is_filing_group_child + ) return earned * caretaker