diff --git a/changelog.d/sc-ccap.added.md b/changelog.d/sc-ccap.added.md new file mode 100644 index 00000000000..22ba940033f --- /dev/null +++ b/changelog.d/sc-ccap.added.md @@ -0,0 +1 @@ +Implement South Carolina CCAP. 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 99f799c90ac..89dc3c0bef2 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 @@ -13,6 +13,7 @@ values: - pa_child_care_subsidies # Pennsylvania Child Care Works - nj_child_care_subsidies # New Jersey Child Care Assistance Program - 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 metadata: diff --git a/policyengine_us/parameters/gov/household/household_state_benefits.yaml b/policyengine_us/parameters/gov/household/household_state_benefits.yaml index c79c1782ea5..6a2a3ff70eb 100644 --- a/policyengine_us/parameters/gov/household/household_state_benefits.yaml +++ b/policyengine_us/parameters/gov/household/household_state_benefits.yaml @@ -34,6 +34,8 @@ values: - id_aabd # Nebraska benefits - ne_child_care_subsidies + # South Carolina benefits + - sc_child_care_subsidies # New Mexico benefits - nm_ssi_state_supplement # South Carolina benefits @@ -91,6 +93,8 @@ values: - va_child_care_subsidies # North Carolina benefits - nc_scca + # South Carolina benefits + - sc_child_care_subsidies # Massachusetts benefits - ma_eaedc - ma_tafdc diff --git a/policyengine_us/parameters/gov/states/sc/dss/ccap/age_group/age.yaml b/policyengine_us/parameters/gov/states/sc/dss/ccap/age_group/age.yaml new file mode 100644 index 00000000000..d66f5e31a70 --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/dss/ccap/age_group/age.yaml @@ -0,0 +1,44 @@ +description: South Carolina determines child age group from age for payment rates under the Child Care Scholarship Program. +# 0 = UNDER_1, 1 = AGE_1, 2 = AGE_2, 3 = AGE_3, 4 = AGE_4, +# 5 = AGE_5_NOT_IN_K, 6 = AGE_5_12_IN_SCHOOL +# Note: age 5 classification depends on school enrollment, handled in variable formula. +# This bracket only handles the age-based portion (not the school enrollment check). +metadata: + type: single_amount + threshold_unit: year + amount_unit: /1 + period: year + label: South Carolina CCAP child age group by age + reference: + - title: SC CCAP Maximum Payments Allowed FFY2023 + href: https://www.scchildcare.org/media/vwybydmg/child-care-scholarship-maximum-payments-allowed-ffy2023-pdf.pdf#page=1 + +brackets: + - threshold: + 2022-10-01: 0 + amount: + 2022-10-01: 0 + - threshold: + 2022-10-01: 1 + amount: + 2022-10-01: 1 + - threshold: + 2022-10-01: 2 + amount: + 2022-10-01: 2 + - threshold: + 2022-10-01: 3 + amount: + 2022-10-01: 3 + - threshold: + 2022-10-01: 4 + amount: + 2022-10-01: 4 + - threshold: + 2022-10-01: 5 + amount: + 2022-10-01: 5 + - threshold: + 2022-10-01: 6 + amount: + 2022-10-01: 6 diff --git a/policyengine_us/parameters/gov/states/sc/dss/ccap/copay/fpg_exempt_in_effect.yaml b/policyengine_us/parameters/gov/states/sc/dss/ccap/copay/fpg_exempt_in_effect.yaml new file mode 100644 index 00000000000..52f9faf3297 --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/dss/ccap/copay/fpg_exempt_in_effect.yaml @@ -0,0 +1,14 @@ +description: Whether South Carolina's FPL-based copay exemption for the Child Care Scholarship Program is in effect. +values: + 2022-10-01: false + 2024-10-01: true + +metadata: + unit: bool + period: year + label: South Carolina CCAP FPL copay exemption in effect + reference: + - title: SC CCAP Fee Scale 2025-2026 + href: https://www.scchildcare.org/media/ih2mrjw5/fee-scale-2025-2026.pdf#page=1 + - title: SC CCDF State Plan FFY 2025-2027, Section 3.3.1(i)(ii) + href: https://www.scchildcare.org/media/cr5dc51w/submitted-version-of-the-ccdf-ffy-2025-2027-for-south-carolina-as-of-7-1-24pdf.pdf#page=25 diff --git a/policyengine_us/parameters/gov/states/sc/dss/ccap/copay/fpg_exempt_rate.yaml b/policyengine_us/parameters/gov/states/sc/dss/ccap/copay/fpg_exempt_rate.yaml new file mode 100644 index 00000000000..a0fbe81c60d --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/dss/ccap/copay/fpg_exempt_rate.yaml @@ -0,0 +1,13 @@ +description: South Carolina exempts families at or below this share of the federal poverty level from copayment under the Child Care Scholarship Program. +values: + 2024-10-01: 1.5 + +metadata: + unit: /1 + period: year + label: South Carolina CCAP copay FPL exemption rate + reference: + - title: SC CCAP Fee Scale 2025-2026 + href: https://www.scchildcare.org/media/ih2mrjw5/fee-scale-2025-2026.pdf#page=1 + - title: SC CCDF State Plan FFY 2025-2027, Section 3.3.1(i)(ii) + href: https://www.scchildcare.org/media/cr5dc51w/submitted-version-of-the-ccdf-ffy-2025-2027-for-south-carolina-as-of-7-1-24pdf.pdf#page=25 diff --git a/policyengine_us/parameters/gov/states/sc/dss/ccap/copay/income_cap_rate.yaml b/policyengine_us/parameters/gov/states/sc/dss/ccap/copay/income_cap_rate.yaml new file mode 100644 index 00000000000..da6d9ad37d6 --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/dss/ccap/copay/income_cap_rate.yaml @@ -0,0 +1,11 @@ +description: South Carolina limits copayment to this share of family income under the Child Care Scholarship Program. +values: + 2022-10-01: 0.02 + +metadata: + unit: /1 + period: year + label: South Carolina CCAP copay income cap rate + reference: + - title: SC CCDF State Plan FFY 2025-2027, Section 3.1.1 + href: https://www.scchildcare.org/media/cr5dc51w/submitted-version-of-the-ccdf-ffy-2025-2027-for-south-carolina-as-of-7-1-24pdf.pdf#page=43 diff --git a/policyengine_us/parameters/gov/states/sc/dss/ccap/copay/max_family_size.yaml b/policyengine_us/parameters/gov/states/sc/dss/ccap/copay/max_family_size.yaml new file mode 100644 index 00000000000..c7837e7897e --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/dss/ccap/copay/max_family_size.yaml @@ -0,0 +1,13 @@ +description: South Carolina sets this maximum family size in the copay fee scale under the Child Care Scholarship Program. +values: + 2022-10-01: 16 + +metadata: + unit: person + period: year + label: South Carolina CCAP copay maximum family size + reference: + - title: SC CCAP Fee Scale 2023-2024 + href: https://www.scchildcare.org/media/n3qmcb5u/sc-child-care-scholarship-program-fee-scale-2023-2024.pdf#page=1 + - title: SC CCAP Fee Scale 2025-2026 + href: https://www.scchildcare.org/media/ih2mrjw5/fee-scale-2025-2026.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/sc/dss/ccap/copay/max_paid_family_size.yaml b/policyengine_us/parameters/gov/states/sc/dss/ccap/copay/max_paid_family_size.yaml new file mode 100644 index 00000000000..fac2b5f566d --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/dss/ccap/copay/max_paid_family_size.yaml @@ -0,0 +1,13 @@ +description: South Carolina sets this maximum family size with positive copay tiers under the Child Care Scholarship Program fee scale. +values: + 2024-10-01: 14 + +metadata: + unit: person + period: year + label: South Carolina CCAP copay maximum paid-tier family size + reference: + - title: SC CCAP Fee Scale 2024-2025, Appendix 2 + href: https://www.scchildcare.org/media/ubhdm1at/1-13-2025_policy-manual.pdf#page=182 + - title: SC CCAP Fee Scale 2025-2026 + href: https://www.scchildcare.org/media/ih2mrjw5/fee-scale-2025-2026.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/sc/dss/ccap/copay/smi_tier_ratios.yaml b/policyengine_us/parameters/gov/states/sc/dss/ccap/copay/smi_tier_ratios.yaml new file mode 100644 index 00000000000..ee2047faba8 --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/dss/ccap/copay/smi_tier_ratios.yaml @@ -0,0 +1,35 @@ +description: South Carolina sets this share of state median income as each copay tier threshold under the Child Care Scholarship Program. + +metadata: + type: single_amount + threshold_unit: /1 + amount_unit: /1 + period: year + label: South Carolina CCAP copay SMI tier ratios + reference: + - title: SC CCAP Fee Scale 2023-2024 + href: https://www.scchildcare.org/media/n3qmcb5u/sc-child-care-scholarship-program-fee-scale-2023-2024.pdf#page=1 + - title: SC CCDF State Plan FFY 2025-2027, Section 3.3.1 + href: https://www.scchildcare.org/media/cr5dc51w/submitted-version-of-the-ccdf-ffy-2025-2027-for-south-carolina-as-of-7-1-24pdf.pdf#page=25 + +brackets: + - threshold: + 2022-10-01: 1 + amount: + 2022-10-01: 0.45 + - threshold: + 2022-10-01: 2 + amount: + 2022-10-01: 0.55 + - threshold: + 2022-10-01: 3 + amount: + 2022-10-01: 0.65 + - threshold: + 2022-10-01: 4 + amount: + 2022-10-01: 0.75 + - threshold: + 2022-10-01: 5 + amount: + 2022-10-01: 0.85 diff --git a/policyengine_us/parameters/gov/states/sc/dss/ccap/copay/weekly_amounts.yaml b/policyengine_us/parameters/gov/states/sc/dss/ccap/copay/weekly_amounts.yaml new file mode 100644 index 00000000000..89173d1a0a2 --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/dss/ccap/copay/weekly_amounts.yaml @@ -0,0 +1,41 @@ +description: South Carolina sets this weekly per-child copay amount for each fee scale tier under the Child Care Scholarship Program. + +metadata: + type: single_amount + threshold_unit: /1 + amount_unit: currency-USD + period: week + label: South Carolina CCAP weekly copay by tier + reference: + - title: SC CCAP Fee Scale 2023-2024 + href: https://www.scchildcare.org/media/n3qmcb5u/sc-child-care-scholarship-program-fee-scale-2023-2024.pdf#page=1 + - title: SC CCAP Fee Scale 2024-2025, Appendix 2 + href: https://www.scchildcare.org/media/ubhdm1at/1-13-2025_policy-manual.pdf#page=182 + - title: SC CCAP Fee Scale 2025-2026 + href: https://www.scchildcare.org/media/ih2mrjw5/fee-scale-2025-2026.pdf#page=1 + +brackets: + - threshold: + 2022-10-01: 0 + amount: + 2022-10-01: 0 + - threshold: + 2022-10-01: 1 + amount: + 2022-10-01: 6 + - threshold: + 2022-10-01: 2 + amount: + 2022-10-01: 11 + - threshold: + 2022-10-01: 3 + amount: + 2022-10-01: 14 + - threshold: + 2022-10-01: 4 + amount: + 2022-10-01: 17 + - threshold: + 2022-10-01: 5 + amount: + 2022-10-01: 20 diff --git a/policyengine_us/parameters/gov/states/sc/dss/ccap/eligibility/activity_hours.yaml b/policyengine_us/parameters/gov/states/sc/dss/ccap/eligibility/activity_hours.yaml new file mode 100644 index 00000000000..4ee6a0b98d2 --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/dss/ccap/eligibility/activity_hours.yaml @@ -0,0 +1,11 @@ +description: South Carolina sets this minimum weekly work hours requirement under the Child Care Scholarship Program. +values: + 2022-10-01: 15 + +metadata: + unit: hour + period: week + label: South Carolina CCAP minimum weekly work hours + reference: + - title: SC CCAP Policy Manual Vol. 038 Section 2.1.5 + href: https://www.scchildcare.org/media/ubhdm1at/1-13-2025_policy-manual.pdf#page=36 diff --git a/policyengine_us/parameters/gov/states/sc/dss/ccap/eligibility/child_age_limit.yaml b/policyengine_us/parameters/gov/states/sc/dss/ccap/eligibility/child_age_limit.yaml new file mode 100644 index 00000000000..52d44c5c8fa --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/dss/ccap/eligibility/child_age_limit.yaml @@ -0,0 +1,11 @@ +description: South Carolina limits the Child Care Scholarship Program to children younger than this age. +values: + 2022-10-01: 13 + +metadata: + unit: year + period: year + label: South Carolina CCAP child age limit + reference: + - title: SC CCAP Policy Manual Vol. 038 Section 2.1.2 + href: https://www.scchildcare.org/media/ubhdm1at/1-13-2025_policy-manual.pdf#page=30 diff --git a/policyengine_us/parameters/gov/states/sc/dss/ccap/eligibility/disabled_child_age_limit.yaml b/policyengine_us/parameters/gov/states/sc/dss/ccap/eligibility/disabled_child_age_limit.yaml new file mode 100644 index 00000000000..8efe115fb94 --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/dss/ccap/eligibility/disabled_child_age_limit.yaml @@ -0,0 +1,11 @@ +description: South Carolina limits the Child Care Scholarship Program to disabled children younger than this age. +values: + 2022-10-01: 19 + +metadata: + unit: year + period: year + label: South Carolina CCAP disabled child age limit + reference: + - title: SC CCAP Policy Manual Vol. 038 Section 2.1.2 + href: https://www.scchildcare.org/media/ubhdm1at/1-13-2025_policy-manual.pdf#page=30 diff --git a/policyengine_us/parameters/gov/states/sc/dss/ccap/geography/urban_counties.yaml b/policyengine_us/parameters/gov/states/sc/dss/ccap/geography/urban_counties.yaml new file mode 100644 index 00000000000..ec16e9b0a9a --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/dss/ccap/geography/urban_counties.yaml @@ -0,0 +1,32 @@ +description: South Carolina designates these counties as urban under the Child Care Scholarship Program. +values: + 2022-10-01: + - AIKEN_COUNTY_SC + - ALLENDALE_COUNTY_SC + - ANDERSON_COUNTY_SC + - BAMBERG_COUNTY_SC + - BARNWELL_COUNTY_SC + - BEAUFORT_COUNTY_SC + - BERKELEY_COUNTY_SC + - CHARLESTON_COUNTY_SC + - CHEROKEE_COUNTY_SC + - DORCHESTER_COUNTY_SC + - FLORENCE_COUNTY_SC + - GREENVILLE_COUNTY_SC + - HORRY_COUNTY_SC + - LEXINGTON_COUNTY_SC + - MARION_COUNTY_SC + - MARLBORO_COUNTY_SC + - PICKENS_COUNTY_SC + - RICHLAND_COUNTY_SC + - SPARTANBURG_COUNTY_SC + - SUMTER_COUNTY_SC + - YORK_COUNTY_SC + +metadata: + unit: list + period: year + label: South Carolina CCAP urban counties + reference: + - title: SC CCAP Policy Manual Vol. 038, Appendix 4 + href: https://www.scchildcare.org/media/ubhdm1at/1-13-2025_policy-manual.pdf#page=197 diff --git a/policyengine_us/parameters/gov/states/sc/dss/ccap/income/countable_income/sources.yaml b/policyengine_us/parameters/gov/states/sc/dss/ccap/income/countable_income/sources.yaml new file mode 100644 index 00000000000..ebca2e7895e --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/dss/ccap/income/countable_income/sources.yaml @@ -0,0 +1,33 @@ +description: South Carolina counts these income sources under the Child Care Scholarship Program. +values: + 2022-10-01: + - employment_income + - self_employment_income + - farm_income + - social_security + - pension_income + - unemployment_compensation + - workers_compensation + - child_support_received + - alimony_income + - interest_income + - dividend_income + - rental_income + - veterans_benefits + # - tanf + # The following are counted per Policy Manual 2.1.14 but have + # no matching variables: + # - royalties + # - income from estates/trusts + # - income from boarders/lodgers + # - general assistance (other than TANF) + +metadata: + unit: list + period: year + label: South Carolina CCAP countable income sources + reference: + - title: SC CCAP Policy Manual Vol. 038 Section 2.1.14 + href: https://www.scchildcare.org/media/ubhdm1at/1-13-2025_policy-manual.pdf#page=43 + - title: SC CCAP Policy Manual Vol. 038 Section 2.1.15 + href: https://www.scchildcare.org/media/ubhdm1at/1-13-2025_policy-manual.pdf#page=43 diff --git a/policyengine_us/parameters/gov/states/sc/dss/ccap/income/smi_rate.yaml b/policyengine_us/parameters/gov/states/sc/dss/ccap/income/smi_rate.yaml new file mode 100644 index 00000000000..691581124c6 --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/dss/ccap/income/smi_rate.yaml @@ -0,0 +1,13 @@ +description: South Carolina uses this share of state median income as the income threshold under the Child Care Scholarship Program. +values: + 2022-10-01: 0.85 + +metadata: + unit: /1 + period: year + label: South Carolina CCAP SMI income threshold rate + reference: + - title: SC CCAP Policy Manual Vol. 038 Section 2.13 + href: https://www.scchildcare.org/media/ubhdm1at/1-13-2025_policy-manual.pdf#page=88 + - title: SC CCDF State Plan FFY 2025-2027, Section 2.2.4 + href: https://www.scchildcare.org/media/cr5dc51w/submitted-version-of-the-ccdf-ffy-2025-2027-for-south-carolina-as-of-7-1-24pdf.pdf#page=25 diff --git a/policyengine_us/parameters/gov/states/sc/dss/ccap/rates/center.yaml b/policyengine_us/parameters/gov/states/sc/dss/ccap/rates/center.yaml new file mode 100644 index 00000000000..31e9e120a69 --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/dss/ccap/rates/center.yaml @@ -0,0 +1,380 @@ +description: South Carolina provides these maximum weekly payment rates for child care centers under the Child Care Scholarship Program. +metadata: + period: week + unit: currency-USD + label: South Carolina CCAP center weekly rates + breakdown: + - sc_ccap_time_category + - sc_ccap_quality_level + - sc_ccap_age_group + - sc_ccap_geography + reference: + - title: SC CCAP Maximum Payments Allowed FFY2023 + href: https://www.scchildcare.org/media/vwybydmg/child-care-scholarship-maximum-payments-allowed-ffy2023-pdf.pdf#page=1 + - title: SC CCAP Policy Manual Vol. 038 Appendix 3 - Maximum Payments Allowed + href: https://www.scchildcare.org/media/ubhdm1at/1-13-2025_policy-manual.pdf#page=183 + +# Level A+ (NAC) +FULL_TIME: + A_PLUS: + UNDER_1: + URBAN: + 2022-10-01: 296 + RURAL: + 2022-10-01: 158 + AGE_1: + URBAN: + 2022-10-01: 284 + RURAL: + 2022-10-01: 158 + AGE_2: + URBAN: + 2022-10-01: 284 + RURAL: + 2022-10-01: 155 + AGE_3: + URBAN: + 2022-10-01: 275 + RURAL: + 2022-10-01: 150 + AGE_4: + URBAN: + 2022-10-01: 274 + RURAL: + 2022-10-01: 150 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 274 + RURAL: + 2022-10-01: 150 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 274 + RURAL: + 2022-10-01: 130 + A: + UNDER_1: + URBAN: + 2022-10-01: 254 + RURAL: + 2022-10-01: 155 + AGE_1: + URBAN: + 2022-10-01: 254 + RURAL: + 2022-10-01: 155 + AGE_2: + URBAN: + 2022-10-01: 250 + RURAL: + 2022-10-01: 150 + AGE_3: + URBAN: + 2022-10-01: 242 + RURAL: + 2022-10-01: 140 + AGE_4: + URBAN: + 2022-10-01: 242 + RURAL: + 2022-10-01: 140 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 242 + RURAL: + 2022-10-01: 139 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 242 + RURAL: + 2022-10-01: 125 + B_PLUS: + UNDER_1: + URBAN: + 2022-10-01: 240 + RURAL: + 2022-10-01: 150 + AGE_1: + URBAN: + 2022-10-01: 237 + RURAL: + 2022-10-01: 150 + AGE_2: + URBAN: + 2022-10-01: 231 + RURAL: + 2022-10-01: 140 + AGE_3: + URBAN: + 2022-10-01: 218 + RURAL: + 2022-10-01: 135 + AGE_4: + URBAN: + 2022-10-01: 218 + RURAL: + 2022-10-01: 135 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 218 + RURAL: + 2022-10-01: 135 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 197 + RURAL: + 2022-10-01: 120 + B: + UNDER_1: + URBAN: + 2022-10-01: 223 + RURAL: + 2022-10-01: 145 + AGE_1: + URBAN: + 2022-10-01: 223 + RURAL: + 2022-10-01: 140 + AGE_2: + URBAN: + 2022-10-01: 216 + RURAL: + 2022-10-01: 135 + AGE_3: + URBAN: + 2022-10-01: 203 + RURAL: + 2022-10-01: 130 + AGE_4: + URBAN: + 2022-10-01: 200 + RURAL: + 2022-10-01: 130 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 200 + RURAL: + 2022-10-01: 130 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 175 + RURAL: + 2022-10-01: 115 + C: + UNDER_1: + URBAN: + 2022-10-01: 213 + RURAL: + 2022-10-01: 135 + AGE_1: + URBAN: + 2022-10-01: 213 + RURAL: + 2022-10-01: 135 + AGE_2: + URBAN: + 2022-10-01: 205 + RURAL: + 2022-10-01: 130 + AGE_3: + URBAN: + 2022-10-01: 195 + RURAL: + 2022-10-01: 127 + AGE_4: + URBAN: + 2022-10-01: 191 + RURAL: + 2022-10-01: 125 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 191 + RURAL: + 2022-10-01: 125 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 165 + RURAL: + 2022-10-01: 110 + +HALF_TIME: + A_PLUS: + UNDER_1: + URBAN: + 2022-10-01: 197 + RURAL: + 2022-10-01: 125 + AGE_1: + URBAN: + 2022-10-01: 196 + RURAL: + 2022-10-01: 125 + AGE_2: + URBAN: + 2022-10-01: 196 + RURAL: + 2022-10-01: 125 + AGE_3: + URBAN: + 2022-10-01: 195 + RURAL: + 2022-10-01: 125 + AGE_4: + URBAN: + 2022-10-01: 195 + RURAL: + 2022-10-01: 125 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 195 + RURAL: + 2022-10-01: 125 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 150 + RURAL: + 2022-10-01: 125 + A: + UNDER_1: + URBAN: + 2022-10-01: 180 + RURAL: + 2022-10-01: 123 + AGE_1: + URBAN: + 2022-10-01: 180 + RURAL: + 2022-10-01: 123 + AGE_2: + URBAN: + 2022-10-01: 177 + RURAL: + 2022-10-01: 120 + AGE_3: + URBAN: + 2022-10-01: 171 + RURAL: + 2022-10-01: 110 + AGE_4: + URBAN: + 2022-10-01: 169 + RURAL: + 2022-10-01: 110 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 169 + RURAL: + 2022-10-01: 110 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 125 + RURAL: + 2022-10-01: 86 + B_PLUS: + UNDER_1: + URBAN: + 2022-10-01: 175 + RURAL: + 2022-10-01: 121 + AGE_1: + URBAN: + 2022-10-01: 165 + RURAL: + 2022-10-01: 121 + AGE_2: + URBAN: + 2022-10-01: 155 + RURAL: + 2022-10-01: 112 + AGE_3: + URBAN: + 2022-10-01: 150 + RURAL: + 2022-10-01: 105 + AGE_4: + URBAN: + 2022-10-01: 150 + RURAL: + 2022-10-01: 105 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 139 + RURAL: + 2022-10-01: 105 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 110 + RURAL: + 2022-10-01: 85 + B: + UNDER_1: + URBAN: + 2022-10-01: 160 + RURAL: + 2022-10-01: 105 + AGE_1: + URBAN: + 2022-10-01: 160 + RURAL: + 2022-10-01: 105 + AGE_2: + URBAN: + 2022-10-01: 150 + RURAL: + 2022-10-01: 105 + AGE_3: + URBAN: + 2022-10-01: 139 + RURAL: + 2022-10-01: 100 + AGE_4: + URBAN: + 2022-10-01: 125 + RURAL: + 2022-10-01: 100 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 125 + RURAL: + 2022-10-01: 100 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 100 + RURAL: + 2022-10-01: 80 + C: + UNDER_1: + URBAN: + 2022-10-01: 140 + RURAL: + 2022-10-01: 100 + AGE_1: + URBAN: + 2022-10-01: 140 + RURAL: + 2022-10-01: 100 + AGE_2: + URBAN: + 2022-10-01: 140 + RURAL: + 2022-10-01: 100 + AGE_3: + URBAN: + 2022-10-01: 123 + RURAL: + 2022-10-01: 95 + AGE_4: + URBAN: + 2022-10-01: 122 + RURAL: + 2022-10-01: 85 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 122 + RURAL: + 2022-10-01: 85 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 88 + RURAL: + 2022-10-01: 75 diff --git a/policyengine_us/parameters/gov/states/sc/dss/ccap/rates/exempt_center.yaml b/policyengine_us/parameters/gov/states/sc/dss/ccap/rates/exempt_center.yaml new file mode 100644 index 00000000000..73134d7ec93 --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/dss/ccap/rates/exempt_center.yaml @@ -0,0 +1,379 @@ +description: South Carolina provides these maximum weekly payment rates for exempt and waivered child care centers under the Child Care Scholarship Program. +metadata: + period: week + unit: currency-USD + label: South Carolina CCAP exempt center weekly rates + breakdown: + - sc_ccap_time_category + - sc_ccap_quality_level + - sc_ccap_age_group + - sc_ccap_geography + reference: + - title: SC CCAP Maximum Payments Allowed FFY2023 + href: https://www.scchildcare.org/media/vwybydmg/child-care-scholarship-maximum-payments-allowed-ffy2023-pdf.pdf#page=4 + - title: SC CCAP Policy Manual Vol. 038 Appendix 3 - Maximum Payments Allowed + href: https://www.scchildcare.org/media/ubhdm1at/1-13-2025_policy-manual.pdf#page=183 + +FULL_TIME: + A_PLUS: + UNDER_1: + URBAN: + 2022-10-01: 266 + RURAL: + 2022-10-01: 142 + AGE_1: + URBAN: + 2022-10-01: 256 + RURAL: + 2022-10-01: 142 + AGE_2: + URBAN: + 2022-10-01: 256 + RURAL: + 2022-10-01: 140 + AGE_3: + URBAN: + 2022-10-01: 248 + RURAL: + 2022-10-01: 135 + AGE_4: + URBAN: + 2022-10-01: 247 + RURAL: + 2022-10-01: 135 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 247 + RURAL: + 2022-10-01: 135 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 247 + RURAL: + 2022-10-01: 117 + A: + UNDER_1: + URBAN: + 2022-10-01: 229 + RURAL: + 2022-10-01: 140 + AGE_1: + URBAN: + 2022-10-01: 229 + RURAL: + 2022-10-01: 140 + AGE_2: + URBAN: + 2022-10-01: 225 + RURAL: + 2022-10-01: 135 + AGE_3: + URBAN: + 2022-10-01: 218 + RURAL: + 2022-10-01: 126 + AGE_4: + URBAN: + 2022-10-01: 218 + RURAL: + 2022-10-01: 126 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 218 + RURAL: + 2022-10-01: 125 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 218 + RURAL: + 2022-10-01: 113 + B_PLUS: + UNDER_1: + URBAN: + 2022-10-01: 216 + RURAL: + 2022-10-01: 135 + AGE_1: + URBAN: + 2022-10-01: 213 + RURAL: + 2022-10-01: 135 + AGE_2: + URBAN: + 2022-10-01: 208 + RURAL: + 2022-10-01: 126 + AGE_3: + URBAN: + 2022-10-01: 196 + RURAL: + 2022-10-01: 122 + AGE_4: + URBAN: + 2022-10-01: 196 + RURAL: + 2022-10-01: 122 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 196 + RURAL: + 2022-10-01: 122 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 177 + RURAL: + 2022-10-01: 108 + B: + UNDER_1: + URBAN: + 2022-10-01: 201 + RURAL: + 2022-10-01: 131 + AGE_1: + URBAN: + 2022-10-01: 201 + RURAL: + 2022-10-01: 126 + AGE_2: + URBAN: + 2022-10-01: 194 + RURAL: + 2022-10-01: 122 + AGE_3: + URBAN: + 2022-10-01: 183 + RURAL: + 2022-10-01: 117 + AGE_4: + URBAN: + 2022-10-01: 180 + RURAL: + 2022-10-01: 117 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 180 + RURAL: + 2022-10-01: 117 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 158 + RURAL: + 2022-10-01: 104 + C: + UNDER_1: + URBAN: + 2022-10-01: 192 + RURAL: + 2022-10-01: 122 + AGE_1: + URBAN: + 2022-10-01: 192 + RURAL: + 2022-10-01: 122 + AGE_2: + URBAN: + 2022-10-01: 185 + RURAL: + 2022-10-01: 117 + AGE_3: + URBAN: + 2022-10-01: 176 + RURAL: + 2022-10-01: 114 + AGE_4: + URBAN: + 2022-10-01: 172 + RURAL: + 2022-10-01: 113 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 172 + RURAL: + 2022-10-01: 113 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 149 + RURAL: + 2022-10-01: 99 + +HALF_TIME: + A_PLUS: + UNDER_1: + URBAN: + 2022-10-01: 177 + RURAL: + 2022-10-01: 113 + AGE_1: + URBAN: + 2022-10-01: 176 + RURAL: + 2022-10-01: 113 + AGE_2: + URBAN: + 2022-10-01: 176 + RURAL: + 2022-10-01: 113 + AGE_3: + URBAN: + 2022-10-01: 176 + RURAL: + 2022-10-01: 113 + AGE_4: + URBAN: + 2022-10-01: 176 + RURAL: + 2022-10-01: 113 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 176 + RURAL: + 2022-10-01: 113 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 135 + RURAL: + 2022-10-01: 113 + A: + UNDER_1: + URBAN: + 2022-10-01: 162 + RURAL: + 2022-10-01: 111 + AGE_1: + URBAN: + 2022-10-01: 162 + RURAL: + 2022-10-01: 111 + AGE_2: + URBAN: + 2022-10-01: 159 + RURAL: + 2022-10-01: 108 + AGE_3: + URBAN: + 2022-10-01: 154 + RURAL: + 2022-10-01: 99 + AGE_4: + URBAN: + 2022-10-01: 152 + RURAL: + 2022-10-01: 99 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 152 + RURAL: + 2022-10-01: 99 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 113 + RURAL: + 2022-10-01: 77 + B_PLUS: + UNDER_1: + URBAN: + 2022-10-01: 158 + RURAL: + 2022-10-01: 109 + AGE_1: + URBAN: + 2022-10-01: 149 + RURAL: + 2022-10-01: 109 + AGE_2: + URBAN: + 2022-10-01: 140 + RURAL: + 2022-10-01: 101 + AGE_3: + URBAN: + 2022-10-01: 135 + RURAL: + 2022-10-01: 95 + AGE_4: + URBAN: + 2022-10-01: 135 + RURAL: + 2022-10-01: 95 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 125 + RURAL: + 2022-10-01: 95 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 99 + RURAL: + 2022-10-01: 77 + B: + UNDER_1: + URBAN: + 2022-10-01: 144 + RURAL: + 2022-10-01: 95 + AGE_1: + URBAN: + 2022-10-01: 144 + RURAL: + 2022-10-01: 95 + AGE_2: + URBAN: + 2022-10-01: 135 + RURAL: + 2022-10-01: 95 + AGE_3: + URBAN: + 2022-10-01: 125 + RURAL: + 2022-10-01: 90 + AGE_4: + URBAN: + 2022-10-01: 113 + RURAL: + 2022-10-01: 90 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 113 + RURAL: + 2022-10-01: 90 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 90 + RURAL: + 2022-10-01: 72 + C: + UNDER_1: + URBAN: + 2022-10-01: 126 + RURAL: + 2022-10-01: 90 + AGE_1: + URBAN: + 2022-10-01: 126 + RURAL: + 2022-10-01: 90 + AGE_2: + URBAN: + 2022-10-01: 126 + RURAL: + 2022-10-01: 90 + AGE_3: + URBAN: + 2022-10-01: 111 + RURAL: + 2022-10-01: 86 + AGE_4: + URBAN: + 2022-10-01: 110 + RURAL: + 2022-10-01: 77 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 110 + RURAL: + 2022-10-01: 77 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 79 + RURAL: + 2022-10-01: 68 diff --git a/policyengine_us/parameters/gov/states/sc/dss/ccap/rates/ffn.yaml b/policyengine_us/parameters/gov/states/sc/dss/ccap/rates/ffn.yaml new file mode 100644 index 00000000000..1cf26feaa2b --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/dss/ccap/rates/ffn.yaml @@ -0,0 +1,48 @@ +description: South Carolina provides these maximum weekly payment rates for family, friend, and neighbor care under the Child Care Scholarship Program. +# All 4 FFN subtypes (FRI, FNI, FRO, FNO) have identical rates. +# Urban and rural rates are also identical for FFN providers. +# Rates use a simplified 2-tier age structure: under 3 and 3+. +metadata: + period: week + unit: currency-USD + label: South Carolina CCAP FFN weekly rates + breakdown: + - sc_ccap_time_category + - sc_ccap_age_group + reference: + - title: SC CCAP Maximum Payments Allowed FFY2023 + href: https://www.scchildcare.org/media/vwybydmg/child-care-scholarship-maximum-payments-allowed-ffy2023-pdf.pdf#page=15 + - title: SC CCAP Policy Manual Vol. 038 Appendix 3 - Maximum Payments Allowed + href: https://www.scchildcare.org/media/ubhdm1at/1-13-2025_policy-manual.pdf#page=183 + +FULL_TIME: + UNDER_1: + 2022-10-01: 50 + AGE_1: + 2022-10-01: 50 + AGE_2: + 2022-10-01: 50 + AGE_3: + 2022-10-01: 46 + AGE_4: + 2022-10-01: 46 + AGE_5_NOT_IN_K: + 2022-10-01: 46 + AGE_5_12_IN_SCHOOL: + 2022-10-01: 46 + +HALF_TIME: + UNDER_1: + 2022-10-01: 30 + AGE_1: + 2022-10-01: 30 + AGE_2: + 2022-10-01: 30 + AGE_3: + 2022-10-01: 30 + AGE_4: + 2022-10-01: 30 + AGE_5_NOT_IN_K: + 2022-10-01: 30 + AGE_5_12_IN_SCHOOL: + 2022-10-01: 24 diff --git a/policyengine_us/parameters/gov/states/sc/dss/ccap/rates/group_home.yaml b/policyengine_us/parameters/gov/states/sc/dss/ccap/rates/group_home.yaml new file mode 100644 index 00000000000..3ea636c77af --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/dss/ccap/rates/group_home.yaml @@ -0,0 +1,379 @@ +description: South Carolina provides these maximum weekly payment rates for group child care homes under the Child Care Scholarship Program. +metadata: + period: week + unit: currency-USD + label: South Carolina CCAP group home weekly rates + breakdown: + - sc_ccap_time_category + - sc_ccap_quality_level + - sc_ccap_age_group + - sc_ccap_geography + reference: + - title: SC CCAP Maximum Payments Allowed FFY2023 + href: https://www.scchildcare.org/media/vwybydmg/child-care-scholarship-maximum-payments-allowed-ffy2023-pdf.pdf#page=7 + - title: SC CCAP Policy Manual Vol. 038 Appendix 3 - Maximum Payments Allowed + href: https://www.scchildcare.org/media/ubhdm1at/1-13-2025_policy-manual.pdf#page=183 + +FULL_TIME: + A_PLUS: + UNDER_1: + URBAN: + 2022-10-01: 190 + RURAL: + 2022-10-01: 140 + AGE_1: + URBAN: + 2022-10-01: 190 + RURAL: + 2022-10-01: 140 + AGE_2: + URBAN: + 2022-10-01: 185 + RURAL: + 2022-10-01: 140 + AGE_3: + URBAN: + 2022-10-01: 180 + RURAL: + 2022-10-01: 135 + AGE_4: + URBAN: + 2022-10-01: 180 + RURAL: + 2022-10-01: 135 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 178 + RURAL: + 2022-10-01: 135 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 160 + RURAL: + 2022-10-01: 115 + A: + UNDER_1: + URBAN: + 2022-10-01: 180 + RURAL: + 2022-10-01: 130 + AGE_1: + URBAN: + 2022-10-01: 180 + RURAL: + 2022-10-01: 130 + AGE_2: + URBAN: + 2022-10-01: 175 + RURAL: + 2022-10-01: 130 + AGE_3: + URBAN: + 2022-10-01: 160 + RURAL: + 2022-10-01: 127 + AGE_4: + URBAN: + 2022-10-01: 160 + RURAL: + 2022-10-01: 127 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 160 + RURAL: + 2022-10-01: 127 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 150 + RURAL: + 2022-10-01: 110 + B_PLUS: + UNDER_1: + URBAN: + 2022-10-01: 170 + RURAL: + 2022-10-01: 127 + AGE_1: + URBAN: + 2022-10-01: 170 + RURAL: + 2022-10-01: 127 + AGE_2: + URBAN: + 2022-10-01: 165 + RURAL: + 2022-10-01: 127 + AGE_3: + URBAN: + 2022-10-01: 150 + RURAL: + 2022-10-01: 125 + AGE_4: + URBAN: + 2022-10-01: 150 + RURAL: + 2022-10-01: 125 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 149 + RURAL: + 2022-10-01: 110 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 145 + RURAL: + 2022-10-01: 104 + B: + UNDER_1: + URBAN: + 2022-10-01: 160 + RURAL: + 2022-10-01: 126 + AGE_1: + URBAN: + 2022-10-01: 160 + RURAL: + 2022-10-01: 125 + AGE_2: + URBAN: + 2022-10-01: 160 + RURAL: + 2022-10-01: 125 + AGE_3: + URBAN: + 2022-10-01: 145 + RURAL: + 2022-10-01: 119 + AGE_4: + URBAN: + 2022-10-01: 145 + RURAL: + 2022-10-01: 119 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 141 + RURAL: + 2022-10-01: 111 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 130 + RURAL: + 2022-10-01: 111 + C: + UNDER_1: + URBAN: + 2022-10-01: 150 + RURAL: + 2022-10-01: 125 + AGE_1: + URBAN: + 2022-10-01: 150 + RURAL: + 2022-10-01: 120 + AGE_2: + URBAN: + 2022-10-01: 150 + RURAL: + 2022-10-01: 110 + AGE_3: + URBAN: + 2022-10-01: 140 + RURAL: + 2022-10-01: 105 + AGE_4: + URBAN: + 2022-10-01: 140 + RURAL: + 2022-10-01: 105 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 140 + RURAL: + 2022-10-01: 105 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 125 + RURAL: + 2022-10-01: 100 + +HALF_TIME: + A_PLUS: + UNDER_1: + URBAN: + 2022-10-01: 162 + RURAL: + 2022-10-01: 130 + AGE_1: + URBAN: + 2022-10-01: 162 + RURAL: + 2022-10-01: 130 + AGE_2: + URBAN: + 2022-10-01: 162 + RURAL: + 2022-10-01: 130 + AGE_3: + URBAN: + 2022-10-01: 140 + RURAL: + 2022-10-01: 130 + AGE_4: + URBAN: + 2022-10-01: 140 + RURAL: + 2022-10-01: 130 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 140 + RURAL: + 2022-10-01: 130 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 140 + RURAL: + 2022-10-01: 100 + A: + UNDER_1: + URBAN: + 2022-10-01: 159 + RURAL: + 2022-10-01: 126 + AGE_1: + URBAN: + 2022-10-01: 159 + RURAL: + 2022-10-01: 126 + AGE_2: + URBAN: + 2022-10-01: 159 + RURAL: + 2022-10-01: 126 + AGE_3: + URBAN: + 2022-10-01: 138 + RURAL: + 2022-10-01: 120 + AGE_4: + URBAN: + 2022-10-01: 138 + RURAL: + 2022-10-01: 120 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 138 + RURAL: + 2022-10-01: 120 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 121 + RURAL: + 2022-10-01: 85 + B_PLUS: + UNDER_1: + URBAN: + 2022-10-01: 150 + RURAL: + 2022-10-01: 125 + AGE_1: + URBAN: + 2022-10-01: 150 + RURAL: + 2022-10-01: 125 + AGE_2: + URBAN: + 2022-10-01: 150 + RURAL: + 2022-10-01: 125 + AGE_3: + URBAN: + 2022-10-01: 137 + RURAL: + 2022-10-01: 115 + AGE_4: + URBAN: + 2022-10-01: 137 + RURAL: + 2022-10-01: 115 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 137 + RURAL: + 2022-10-01: 115 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 120 + RURAL: + 2022-10-01: 80 + B: + UNDER_1: + URBAN: + 2022-10-01: 135 + RURAL: + 2022-10-01: 123 + AGE_1: + URBAN: + 2022-10-01: 135 + RURAL: + 2022-10-01: 123 + AGE_2: + URBAN: + 2022-10-01: 135 + RURAL: + 2022-10-01: 123 + AGE_3: + URBAN: + 2022-10-01: 124 + RURAL: + 2022-10-01: 110 + AGE_4: + URBAN: + 2022-10-01: 120 + RURAL: + 2022-10-01: 110 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 120 + RURAL: + 2022-10-01: 110 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 105 + RURAL: + 2022-10-01: 78 + C: + UNDER_1: + URBAN: + 2022-10-01: 125 + RURAL: + 2022-10-01: 120 + AGE_1: + URBAN: + 2022-10-01: 125 + RURAL: + 2022-10-01: 113 + AGE_2: + URBAN: + 2022-10-01: 125 + RURAL: + 2022-10-01: 113 + AGE_3: + URBAN: + 2022-10-01: 100 + RURAL: + 2022-10-01: 100 + AGE_4: + URBAN: + 2022-10-01: 100 + RURAL: + 2022-10-01: 100 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 100 + RURAL: + 2022-10-01: 100 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 100 + RURAL: + 2022-10-01: 75 diff --git a/policyengine_us/parameters/gov/states/sc/dss/ccap/rates/licensed_family_home.yaml b/policyengine_us/parameters/gov/states/sc/dss/ccap/rates/licensed_family_home.yaml new file mode 100644 index 00000000000..9f7f6db4c17 --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/dss/ccap/rates/licensed_family_home.yaml @@ -0,0 +1,379 @@ +description: South Carolina provides these maximum weekly payment rates for licensed family child care homes under the Child Care Scholarship Program. +metadata: + period: week + unit: currency-USD + label: South Carolina CCAP licensed family home weekly rates + breakdown: + - sc_ccap_time_category + - sc_ccap_quality_level + - sc_ccap_age_group + - sc_ccap_geography + reference: + - title: SC CCAP Maximum Payments Allowed FFY2023 + href: https://www.scchildcare.org/media/vwybydmg/child-care-scholarship-maximum-payments-allowed-ffy2023-pdf.pdf#page=9 + - title: SC CCAP Policy Manual Vol. 038 Appendix 3 - Maximum Payments Allowed + href: https://www.scchildcare.org/media/ubhdm1at/1-13-2025_policy-manual.pdf#page=183 + +FULL_TIME: + A_PLUS: + UNDER_1: + URBAN: + 2022-10-01: 190 + RURAL: + 2022-10-01: 140 + AGE_1: + URBAN: + 2022-10-01: 190 + RURAL: + 2022-10-01: 140 + AGE_2: + URBAN: + 2022-10-01: 185 + RURAL: + 2022-10-01: 140 + AGE_3: + URBAN: + 2022-10-01: 180 + RURAL: + 2022-10-01: 135 + AGE_4: + URBAN: + 2022-10-01: 180 + RURAL: + 2022-10-01: 135 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 178 + RURAL: + 2022-10-01: 135 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 160 + RURAL: + 2022-10-01: 115 + A: + UNDER_1: + URBAN: + 2022-10-01: 180 + RURAL: + 2022-10-01: 130 + AGE_1: + URBAN: + 2022-10-01: 180 + RURAL: + 2022-10-01: 130 + AGE_2: + URBAN: + 2022-10-01: 175 + RURAL: + 2022-10-01: 130 + AGE_3: + URBAN: + 2022-10-01: 160 + RURAL: + 2022-10-01: 127 + AGE_4: + URBAN: + 2022-10-01: 160 + RURAL: + 2022-10-01: 127 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 160 + RURAL: + 2022-10-01: 127 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 150 + RURAL: + 2022-10-01: 110 + B_PLUS: + UNDER_1: + URBAN: + 2022-10-01: 170 + RURAL: + 2022-10-01: 127 + AGE_1: + URBAN: + 2022-10-01: 170 + RURAL: + 2022-10-01: 127 + AGE_2: + URBAN: + 2022-10-01: 165 + RURAL: + 2022-10-01: 127 + AGE_3: + URBAN: + 2022-10-01: 150 + RURAL: + 2022-10-01: 125 + AGE_4: + URBAN: + 2022-10-01: 150 + RURAL: + 2022-10-01: 125 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 149 + RURAL: + 2022-10-01: 111 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 145 + RURAL: + 2022-10-01: 111 + B: + UNDER_1: + URBAN: + 2022-10-01: 160 + RURAL: + 2022-10-01: 125 + AGE_1: + URBAN: + 2022-10-01: 160 + RURAL: + 2022-10-01: 125 + AGE_2: + URBAN: + 2022-10-01: 160 + RURAL: + 2022-10-01: 125 + AGE_3: + URBAN: + 2022-10-01: 145 + RURAL: + 2022-10-01: 119 + AGE_4: + URBAN: + 2022-10-01: 145 + RURAL: + 2022-10-01: 119 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 141 + RURAL: + 2022-10-01: 110 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 130 + RURAL: + 2022-10-01: 110 + C: + UNDER_1: + URBAN: + 2022-10-01: 150 + RURAL: + 2022-10-01: 121 + AGE_1: + URBAN: + 2022-10-01: 150 + RURAL: + 2022-10-01: 120 + AGE_2: + URBAN: + 2022-10-01: 150 + RURAL: + 2022-10-01: 110 + AGE_3: + URBAN: + 2022-10-01: 140 + RURAL: + 2022-10-01: 105 + AGE_4: + URBAN: + 2022-10-01: 140 + RURAL: + 2022-10-01: 105 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 140 + RURAL: + 2022-10-01: 105 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 100 + RURAL: + 2022-10-01: 95 + +HALF_TIME: + A_PLUS: + UNDER_1: + URBAN: + 2022-10-01: 162 + RURAL: + 2022-10-01: 130 + AGE_1: + URBAN: + 2022-10-01: 162 + RURAL: + 2022-10-01: 130 + AGE_2: + URBAN: + 2022-10-01: 162 + RURAL: + 2022-10-01: 130 + AGE_3: + URBAN: + 2022-10-01: 140 + RURAL: + 2022-10-01: 130 + AGE_4: + URBAN: + 2022-10-01: 140 + RURAL: + 2022-10-01: 130 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 140 + RURAL: + 2022-10-01: 130 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 140 + RURAL: + 2022-10-01: 100 + A: + UNDER_1: + URBAN: + 2022-10-01: 159 + RURAL: + 2022-10-01: 126 + AGE_1: + URBAN: + 2022-10-01: 159 + RURAL: + 2022-10-01: 126 + AGE_2: + URBAN: + 2022-10-01: 159 + RURAL: + 2022-10-01: 126 + AGE_3: + URBAN: + 2022-10-01: 138 + RURAL: + 2022-10-01: 120 + AGE_4: + URBAN: + 2022-10-01: 138 + RURAL: + 2022-10-01: 120 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 138 + RURAL: + 2022-10-01: 120 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 121 + RURAL: + 2022-10-01: 85 + B_PLUS: + UNDER_1: + URBAN: + 2022-10-01: 150 + RURAL: + 2022-10-01: 125 + AGE_1: + URBAN: + 2022-10-01: 150 + RURAL: + 2022-10-01: 125 + AGE_2: + URBAN: + 2022-10-01: 150 + RURAL: + 2022-10-01: 125 + AGE_3: + URBAN: + 2022-10-01: 137 + RURAL: + 2022-10-01: 115 + AGE_4: + URBAN: + 2022-10-01: 137 + RURAL: + 2022-10-01: 115 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 137 + RURAL: + 2022-10-01: 115 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 120 + RURAL: + 2022-10-01: 80 + B: + UNDER_1: + URBAN: + 2022-10-01: 135 + RURAL: + 2022-10-01: 123 + AGE_1: + URBAN: + 2022-10-01: 135 + RURAL: + 2022-10-01: 123 + AGE_2: + URBAN: + 2022-10-01: 135 + RURAL: + 2022-10-01: 123 + AGE_3: + URBAN: + 2022-10-01: 124 + RURAL: + 2022-10-01: 110 + AGE_4: + URBAN: + 2022-10-01: 120 + RURAL: + 2022-10-01: 110 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 120 + RURAL: + 2022-10-01: 110 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 105 + RURAL: + 2022-10-01: 78 + C: + UNDER_1: + URBAN: + 2022-10-01: 125 + RURAL: + 2022-10-01: 120 + AGE_1: + URBAN: + 2022-10-01: 125 + RURAL: + 2022-10-01: 113 + AGE_2: + URBAN: + 2022-10-01: 125 + RURAL: + 2022-10-01: 113 + AGE_3: + URBAN: + 2022-10-01: 100 + RURAL: + 2022-10-01: 100 + AGE_4: + URBAN: + 2022-10-01: 100 + RURAL: + 2022-10-01: 100 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 100 + RURAL: + 2022-10-01: 100 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 100 + RURAL: + 2022-10-01: 75 diff --git a/policyengine_us/parameters/gov/states/sc/dss/ccap/rates/registered_family_home.yaml b/policyengine_us/parameters/gov/states/sc/dss/ccap/rates/registered_family_home.yaml new file mode 100644 index 00000000000..5426bac29e6 --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/dss/ccap/rates/registered_family_home.yaml @@ -0,0 +1,236 @@ +description: South Carolina provides these maximum weekly payment rates for registered family child care homes under the Child Care Scholarship Program. +# Registered family homes only have quality levels B+, B, and C. +metadata: + period: week + unit: currency-USD + label: South Carolina CCAP registered family home weekly rates + breakdown: + - sc_ccap_time_category + - sc_ccap_registered_quality_level + - sc_ccap_age_group + - sc_ccap_geography + reference: + - title: SC CCAP Maximum Payments Allowed FFY2023 + href: https://www.scchildcare.org/media/vwybydmg/child-care-scholarship-maximum-payments-allowed-ffy2023-pdf.pdf#page=11 + - title: SC CCAP Policy Manual Vol. 038 Appendix 3 - Maximum Payments Allowed + href: https://www.scchildcare.org/media/ubhdm1at/1-13-2025_policy-manual.pdf#page=183 + +FULL_TIME: + B_PLUS: + UNDER_1: + URBAN: + 2022-10-01: 157 + RURAL: + 2022-10-01: 123 + AGE_1: + URBAN: + 2022-10-01: 157 + RURAL: + 2022-10-01: 123 + AGE_2: + URBAN: + 2022-10-01: 157 + RURAL: + 2022-10-01: 123 + AGE_3: + URBAN: + 2022-10-01: 143 + RURAL: + 2022-10-01: 116 + AGE_4: + URBAN: + 2022-10-01: 143 + RURAL: + 2022-10-01: 116 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 138 + RURAL: + 2022-10-01: 100 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 105 + RURAL: + 2022-10-01: 99 + B: + UNDER_1: + URBAN: + 2022-10-01: 153 + RURAL: + 2022-10-01: 122 + AGE_1: + URBAN: + 2022-10-01: 153 + RURAL: + 2022-10-01: 122 + AGE_2: + URBAN: + 2022-10-01: 153 + RURAL: + 2022-10-01: 112 + AGE_3: + URBAN: + 2022-10-01: 142 + RURAL: + 2022-10-01: 108 + AGE_4: + URBAN: + 2022-10-01: 142 + RURAL: + 2022-10-01: 108 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 142 + RURAL: + 2022-10-01: 98 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 103 + RURAL: + 2022-10-01: 97 + C: + UNDER_1: + URBAN: + 2022-10-01: 125 + RURAL: + 2022-10-01: 121 + AGE_1: + URBAN: + 2022-10-01: 125 + RURAL: + 2022-10-01: 95 + AGE_2: + URBAN: + 2022-10-01: 125 + RURAL: + 2022-10-01: 95 + AGE_3: + URBAN: + 2022-10-01: 120 + RURAL: + 2022-10-01: 90 + AGE_4: + URBAN: + 2022-10-01: 120 + RURAL: + 2022-10-01: 90 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 120 + RURAL: + 2022-10-01: 90 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 90 + RURAL: + 2022-10-01: 75 + +HALF_TIME: + B_PLUS: + UNDER_1: + URBAN: + 2022-10-01: 132 + RURAL: + 2022-10-01: 122 + AGE_1: + URBAN: + 2022-10-01: 132 + RURAL: + 2022-10-01: 122 + AGE_2: + URBAN: + 2022-10-01: 132 + RURAL: + 2022-10-01: 122 + AGE_3: + URBAN: + 2022-10-01: 111 + RURAL: + 2022-10-01: 103 + AGE_4: + URBAN: + 2022-10-01: 111 + RURAL: + 2022-10-01: 103 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 111 + RURAL: + 2022-10-01: 103 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 102 + RURAL: + 2022-10-01: 77 + B: + UNDER_1: + URBAN: + 2022-10-01: 128 + RURAL: + 2022-10-01: 121 + AGE_1: + URBAN: + 2022-10-01: 128 + RURAL: + 2022-10-01: 121 + AGE_2: + URBAN: + 2022-10-01: 128 + RURAL: + 2022-10-01: 121 + AGE_3: + URBAN: + 2022-10-01: 102 + RURAL: + 2022-10-01: 102 + AGE_4: + URBAN: + 2022-10-01: 102 + RURAL: + 2022-10-01: 102 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 102 + RURAL: + 2022-10-01: 102 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 101 + RURAL: + 2022-10-01: 76 + C: + UNDER_1: + URBAN: + 2022-10-01: 95 + RURAL: + 2022-10-01: 70 + AGE_1: + URBAN: + 2022-10-01: 95 + RURAL: + 2022-10-01: 70 + AGE_2: + URBAN: + 2022-10-01: 95 + RURAL: + 2022-10-01: 70 + AGE_3: + URBAN: + 2022-10-01: 95 + RURAL: + 2022-10-01: 65 + AGE_4: + URBAN: + 2022-10-01: 95 + RURAL: + 2022-10-01: 65 + AGE_5_NOT_IN_K: + URBAN: + 2022-10-01: 95 + RURAL: + 2022-10-01: 65 + AGE_5_12_IN_SCHOOL: + URBAN: + 2022-10-01: 60 + RURAL: + 2022-10-01: 50 diff --git a/policyengine_us/parameters/gov/states/sc/dss/ccap/surcharge/foster_care.yaml b/policyengine_us/parameters/gov/states/sc/dss/ccap/surcharge/foster_care.yaml new file mode 100644 index 00000000000..ff571de3256 --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/dss/ccap/surcharge/foster_care.yaml @@ -0,0 +1,11 @@ +description: South Carolina provides this additional weekly amount for foster care children under the Child Care Scholarship Program. +values: + 2022-10-01: 30 + +metadata: + unit: currency-USD + period: week + label: South Carolina CCAP foster care surcharge + reference: + - title: SC CCAP Maximum Payments Allowed FFY2023 + href: https://www.scchildcare.org/media/vwybydmg/child-care-scholarship-maximum-payments-allowed-ffy2023-pdf.pdf#page=17 diff --git a/policyengine_us/parameters/gov/states/sc/dss/ccap/surcharge/special_needs.yaml b/policyengine_us/parameters/gov/states/sc/dss/ccap/surcharge/special_needs.yaml new file mode 100644 index 00000000000..b74bbdcccaa --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/dss/ccap/surcharge/special_needs.yaml @@ -0,0 +1,11 @@ +description: South Carolina provides this additional weekly amount for special needs children under the Child Care Scholarship Program. +values: + 2022-10-01: 20 + +metadata: + unit: currency-USD + period: week + label: South Carolina CCAP special needs surcharge + reference: + - title: SC CCAP Maximum Payments Allowed FFY2023 + href: https://www.scchildcare.org/media/vwybydmg/child-care-scholarship-maximum-payments-allowed-ffy2023-pdf.pdf#page=17 diff --git a/policyengine_us/parameters/gov/states/sc/dss/ccap/time_category/hours.yaml b/policyengine_us/parameters/gov/states/sc/dss/ccap/time_category/hours.yaml new file mode 100644 index 00000000000..2c1a2f91615 --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/dss/ccap/time_category/hours.yaml @@ -0,0 +1,23 @@ +description: South Carolina determines care schedule from weekly childcare hours under the Child Care Scholarship Program. +# 0 = HALF_TIME, 1 = FULL_TIME +# Per SC program rules, 25+ hours = Full Time, under 25 = Half Time. +metadata: + type: single_amount + threshold_unit: hour + amount_unit: /1 + period: year + label: South Carolina CCAP time category by hours + reference: + - title: SC CCAP Maximum Payments Allowed FFY2023 + href: https://www.scchildcare.org/media/vwybydmg/child-care-scholarship-maximum-payments-allowed-ffy2023-pdf.pdf#page=1 + +brackets: + - threshold: + 2022-10-01: 0 + amount: + 2022-10-01: 0 + - threshold: + 2022-10-01: 30 + 2024-10-01: 25 + amount: + 2022-10-01: 1 diff --git a/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/edge_cases.yaml b/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/edge_cases.yaml new file mode 100644 index 00000000000..3be04b8f23a --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/edge_cases.yaml @@ -0,0 +1,1180 @@ +# SC CCAP Edge Case Tests +# Tests boundary conditions for income, copay, age, hours, rates, surcharges. +# +# 2025 Key Values: +# SC SMI base (4-person, 2024-10-01): $98,172 +# SMI adj: first=0.52, 2nd-6th=+0.16, 7th+=+0.03 +# 85% SMI size 2: 98,172 * 0.68 * 0.85 = $56,743.416 +# Fee scale family_size_2 thresholds (monthly): +# $0 -> $0, $2,645 -> $6, $3,104 -> $11, +# $3,563 -> $14, $4,022 -> $17, $4,481 -> $20 +# Activity hours: >= 15 hrs/wk +# Time category: < 25 hrs = HT, >= 25 hrs = FT +# CCDF age limit: age < 13 +# +# Note: sc_ccap_copay is entity=SPMUnit, definition_period=MONTH. +# The copay formula returns total monthly copay for the SPM unit. + +# ============================================================ +# INCOME THRESHOLD EDGE CASES +# ============================================================ + +- name: Case 1, income exactly at 85 percent SMI threshold. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 56_743 + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 12_000 + tanf: 0 + households: + household: + members: [person1, person2] + state_code: SC + output: + # 85% SMI size 2 = 98,172 * 0.68 * 0.85 = 56,743.416 + # Monthly countable = 56,743 / 12 = 4,728.583 + # Monthly 85% SMI = 66,756.96 / 12 * 0.85 = 4,728.618 + # 4,728.583 <= 4,728.618 -> eligible (just barely) + sc_ccap_income_eligible: true + sc_ccap_eligible: true + +- name: Case 2, income one dollar above 85 percent SMI threshold. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 56_744 + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 12_000 + households: + household: + members: [person1, person2] + state_code: SC + output: + # Monthly countable = 56,744 / 12 = 4,728.667 + # Monthly 85% SMI = 4,728.618 + # 4,728.667 > 4,728.618 -> ineligible + sc_ccap_income_eligible: false + sc_ccap_eligible: false + sc_ccap: 0 + +- name: Case 3, zero income family. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 25 + employment_income: 0 + immigration_status: CITIZEN + is_full_time_student: true + person2: + age: 2 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 8_000 + households: + household: + members: [person1, person2] + state_code: SC + output: + # Zero income -> income eligible, $0 copay, student -> activity eligible + # Center C Rural (default) FT Age 2 = $130/wk + # Annual max = $130 * 52 = $6,760 + # Benefit = min(8,000 - 0, 6,760) = 6,760 + sc_ccap_income_eligible: true + sc_ccap_eligible: true + sc_ccap: 6_760 + +# ============================================================ +# COPAY BRACKET BOUNDARY EDGE CASES +# ============================================================ + +- name: Case 4, income at first copay bracket boundary family size 2. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + # Monthly income exactly at $2,645 (first non-zero tier) + employment_income: 31_740 + immigration_status: CITIZEN + weekly_hours_worked: 20 + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 12_000 + tanf: 0 + households: + household: + members: [person1, person2] + state_code: SC + output: + # Monthly income = 31,740 / 12 = $2,645 -> $6/wk per child + # $6/wk * 1 eligible child * (52/12) = $26.00/mo + # Annual copay (MONTH var at YEAR period) = $26 * 12 = $312 + # Center C Rural FT Age 3 = $127/wk + # Monthly max rate = $127 * 52 / 12 = $550.33 + # Monthly expenses = $12,000 / 12 = $1,000 + # Monthly uncapped = max(1,000 - 26, 0) = $974 + # Monthly benefit = min(974, 550.33) = $550.33 + # Annual benefit = $550.33 * 12 = $6,604 + sc_ccap_copay: 312 + sc_ccap_eligible: true + sc_ccap: 6_604 + +- name: Case 5, income one dollar below first copay threshold family size 2. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + # Monthly income $2,644 -> just below $2,645 -> $0 copay + employment_income: 31_728 + immigration_status: CITIZEN + weekly_hours_worked: 20 + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 12_000 + tanf: 0 + households: + household: + members: [person1, person2] + state_code: SC + output: + # Monthly income = 31,728 / 12 = $2,644.00 + # Family size 2: below $2,645 threshold -> $0/wk + sc_ccap_copay: 0 + sc_ccap_eligible: true + +- name: Case 6, income at highest copay bracket family size 2. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + # Monthly income $4,481 -> highest tier = $20/wk + employment_income: 53_772 + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 12_000 + tanf: 0 + households: + household: + members: [person1, person2] + state_code: SC + output: + # Family size 2: $4,481+ -> $20/wk per child + # 2% cap: 4,481 * 0.02 * 12 / 52 = $20.68/wk -> $20 < $20.68 -> fee applies + # $20/wk * 1 eligible child * (52/12) = $86.67/mo + # Annual copay (MONTH var at YEAR period) = $86.67 * 12 = $1,040 + sc_ccap_copay: 1_040 + sc_ccap_eligible: true + +# ============================================================ +# 2% COPAY CAP EDGE CASE +# ============================================================ + +- name: Case 7, multiple children copay at highest tier. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 53_772 + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 1 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + person3: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + person4: + age: 8 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + spm_unit_pre_subsidy_childcare_expenses: 30_000 + tanf: 0 + households: + household: + members: [person1, person2, person3, person4] + state_code: SC + output: + # Family size 4, monthly income = 53,772 / 12 = $4,481 + # Fee scale family_size_4: $4,020-$4,668 -> $6/wk per child + # 2% cap: 4,481 * 0.02 * 12 / 52 = $20.68/wk + # min(6, 20.68) = $6/wk per child -> cap does not bind + # $6/wk * 3 eligible children * (52/12) = $78.00/mo + # Annual copay (MONTH var at YEAR period) = $78 * 12 = $936 + sc_ccap_copay: 936 + sc_ccap_eligible: true + +# ============================================================ +# ACTIVITY HOURS EDGE CASES +# ============================================================ + +- name: Case 8, activity hours exactly at 15 hour minimum. + period: 2025 + input: + people: + person1: + age: 30 + employment_income: 30_000 + immigration_status: CITIZEN + weekly_hours_worked: 15 + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: SC + output: + # 15 >= 15 -> activity eligible + sc_ccap_activity_eligible: true + +- name: Case 9, activity hours below 15 hour minimum. + period: 2025 + input: + people: + person1: + age: 30 + employment_income: 30_000 + immigration_status: CITIZEN + weekly_hours_worked: 14 + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: SC + output: + # 14 < 15 -> not activity eligible (not a student) + sc_ccap_activity_eligible: false + sc_ccap_eligible: false + +- name: Case 10, zero work hours but full time student. + period: 2025 + input: + people: + person1: + age: 22 + employment_income: 0 + immigration_status: CITIZEN + weekly_hours_worked: 0 + is_full_time_student: true + person2: + age: 1 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: SC + output: + # 0 hrs but full-time student -> activity eligible + sc_ccap_activity_eligible: true + +# ============================================================ +# CHILDCARE HOURS / TIME CATEGORY EDGE CASES +# ============================================================ + +- name: Case 11, childcare hours exactly at FT boundary 25 hours. + period: 2025 + input: + people: + person1: + age: 3 + childcare_hours_per_week: 25 + households: + household: + members: [person1] + state_code: SC + output: + # Bracket: threshold 25 -> FULL_TIME; 25 >= 25 -> FULL_TIME + sc_ccap_time_category: FULL_TIME + +- name: Case 12, childcare hours 24 just below FT boundary. + period: 2025 + input: + people: + person1: + age: 3 + childcare_hours_per_week: 24 + households: + household: + members: [person1] + state_code: SC + output: + # 24 < 25 -> HALF_TIME + sc_ccap_time_category: HALF_TIME + +- name: Case 13, zero childcare hours. + period: 2025 + input: + people: + person1: + age: 3 + childcare_hours_per_week: 0 + households: + household: + members: [person1] + state_code: SC + output: + # 0 -> HALF_TIME (below 25) + sc_ccap_time_category: HALF_TIME + +# ============================================================ +# CHILD AGE BOUNDARY EDGE CASES +# ============================================================ + +- name: Case 14, child age 12 just under limit. + period: 2025 + input: + people: + person1: + age: 12 + is_tax_unit_dependent: true + immigration_status: CITIZEN + households: + household: + members: [person1] + state_code: SC + output: + # CCDF: age < 13 -> 12 < 13 = true + sc_ccap_eligible_child: true + +- name: Case 15, child age 13 at limit. + period: 2025 + input: + people: + person1: + age: 13 + is_tax_unit_dependent: true + immigration_status: CITIZEN + households: + household: + members: [person1] + state_code: SC + output: + # CCDF: age < 13 -> 13 < 13 = false + sc_ccap_eligible_child: false + +- name: Case 16, infant age 0. + period: 2025 + input: + people: + person1: + age: 0 + is_tax_unit_dependent: true + immigration_status: CITIZEN + households: + household: + members: [person1] + state_code: SC + output: + # 0 < 13 -> eligible + sc_ccap_eligible_child: true + +- name: Case 17, disabled child age 15 eligible. + period: 2025 + input: + people: + person1: + age: 15 + is_tax_unit_dependent: true + immigration_status: CITIZEN + is_disabled: true + households: + household: + members: [person1] + state_code: SC + output: + # SC disabled_child_age_limit = 19; age 15 < 19 -> eligible + sc_ccap_eligible_child: true + +# ============================================================ +# AGE GROUP CLASSIFICATION EDGE CASES +# ============================================================ + +- name: Case 18, age 5 not in school gets AGE_5_NOT_IN_K. + period: 2025 + input: + people: + person1: + age: 5 + is_in_k12_school: false + households: + household: + members: [person1] + state_code: SC + output: + sc_ccap_age_group: AGE_5_NOT_IN_K + +- name: Case 19, age 5 in school gets AGE_5_12_IN_SCHOOL. + period: 2025 + input: + people: + person1: + age: 5 + is_in_k12_school: true + households: + household: + members: [person1] + state_code: SC + output: + sc_ccap_age_group: AGE_5_12_IN_SCHOOL + +- name: Case 20, infant age 0 gets UNDER_1. + period: 2025 + input: + people: + person1: + age: 0 + households: + household: + members: [person1] + state_code: SC + output: + sc_ccap_age_group: UNDER_1 + +# ============================================================ +# PROVIDER TYPE AND RATE EDGE CASES +# ============================================================ + +- name: Case 21, FFN vs center rate difference same child age. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 24_000 + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: FFN + person3: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + tax_units: + tax_unit: + members: [person1, person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + spm_unit_pre_subsidy_childcare_expenses: 20_000 + tanf: 0 + households: + household: + members: [person1, person2, person3] + state_code: SC + output: + # FFN FT Age 3 = $46/wk (no quality/geography dimension) + # Center C Rural (default) FT Age 3 = $127/wk + # MONTH var at YEAR period -> values * 12 + sc_ccap_maximum_weekly_benefit: [0, 552, 1_524] + +- name: Case 22, urban vs rural rate for highest quality center. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 24_000 + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 0 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: A_PLUS + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 20_000 + tanf: 0 + households: + household: + members: [person1, person2] + state_code: SC + county_str: RICHLAND_COUNTY_SC + output: + # Richland County = Urban + sc_ccap_geography: URBAN + # Center A+ Urban FT Under 1 = $296/wk (highest possible rate) + # MONTH var at YEAR period -> values * 12 + sc_ccap_maximum_weekly_benefit: [0, 3_552] + +- name: Case 23, rural county rate for highest quality center. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 24_000 + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 0 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: A_PLUS + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 20_000 + tanf: 0 + households: + household: + members: [person1, person2] + state_code: SC + county_str: ABBEVILLE_COUNTY_SC + output: + # Abbeville County = Rural (not in urban list) + sc_ccap_geography: RURAL + # Center A+ Rural FT Under 1 = $158/wk + # MONTH var at YEAR period -> values * 12 + sc_ccap_maximum_weekly_benefit: [0, 1_896] + +# ============================================================ +# QUALITY LEVEL EXTREMES +# ============================================================ + +- name: Case 24, highest quality A plus vs lowest quality C center urban. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 24_000 + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 0 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: A_PLUS + person3: + age: 0 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + tax_units: + tax_unit: + members: [person1, person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + spm_unit_pre_subsidy_childcare_expenses: 30_000 + tanf: 0 + households: + household: + members: [person1, person2, person3] + state_code: SC + county_str: RICHLAND_COUNTY_SC + output: + # Center A+ Urban FT Under 1 = $296/wk + # Center C Urban FT Under 1 = $213/wk + # $83/wk quality premium + # MONTH var at YEAR period -> values * 12 + sc_ccap_maximum_weekly_benefit: [0, 3_552, 2_556] + +# ============================================================ +# SURCHARGE STACKING EDGE CASES +# ============================================================ + +- name: Case 25, special needs plus foster care surcharges stack. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 30_000 + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + is_disabled: true + is_in_foster_care: true + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 20_000 + tanf: 0 + households: + household: + members: [person1, person2] + state_code: SC + output: + # Center C Rural FT Age 3 = $127 + $20 special needs + $30 foster = $177/wk + # MONTH var at YEAR period -> values * 12 + sc_ccap_maximum_weekly_benefit: [0, 2_124] + # Foster care -> $0 copay + sc_ccap_copay: 0 + # Annual max = $177 * 52 / 12 * 12 = $177 * 52 = $9,204 + # Benefit = min(20,000 - 0, 9,204) = 9,204 + sc_ccap: 9_204 + +# ============================================================ +# REGISTERED FAMILY HOME QUALITY LEVEL EDGE CASE +# ============================================================ + +- name: Case 26, registered family home uses separate quality enum. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 24_000 + immigration_status: CITIZEN + weekly_hours_worked: 20 + person2: + age: 0 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: REGISTERED_FAMILY_HOME + sc_ccap_registered_quality_level: C + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 10_000 + tanf: 0 + households: + household: + members: [person1, person2] + state_code: SC + output: + # Registered Family Home C Rural FT Under 1 = $121/wk + # MONTH var at YEAR period -> values * 12 + sc_ccap_maximum_weekly_benefit: [0, 1_452] + # Annual max = $121 * 52 = $6,292 + # Benefit = min(10,000, 6,292) = 6,292 + sc_ccap: 6_292 + +# ============================================================ +# FAMILY SIZE EDGE CASES +# ============================================================ + +- name: Case 27, family size 16 only zero copay tier. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 40_000 + immigration_status: CITIZEN + weekly_hours_worked: 20 + person2: + age: 28 + weekly_hours_worked: 20 + person3: + age: 12 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: FFN + person4: + age: 11 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: FFN + person5: + age: 10 + is_tax_unit_dependent: true + immigration_status: CITIZEN + person6: + age: 9 + is_tax_unit_dependent: true + immigration_status: CITIZEN + person7: + age: 8 + is_tax_unit_dependent: true + immigration_status: CITIZEN + person8: + age: 7 + is_tax_unit_dependent: true + immigration_status: CITIZEN + person9: + age: 6 + is_tax_unit_dependent: true + immigration_status: CITIZEN + person10: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + person11: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + person12: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + person13: + age: 2 + is_tax_unit_dependent: true + immigration_status: CITIZEN + person14: + age: 1 + is_tax_unit_dependent: true + immigration_status: CITIZEN + person15: + age: 17 + person16: + age: 16 + tax_units: + tax_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14, person15, person16] + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14, person15, person16] + spm_unit_pre_subsidy_childcare_expenses: 10_000 + tanf: 0 + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14, person15, person16] + state_code: SC + output: + # Family size 16, capped at 16 -> family_size_16 fee scale: only $0 tier + # $0/wk copay regardless of income + sc_ccap_eligible: true + +# ============================================================ +# EXEMPT COPAY EDGE CASES +# ============================================================ + +- name: Case 28, TANF enrolled family gets zero copay. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 36_000 + immigration_status: CITIZEN + weekly_hours_worked: 25 + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + is_tanf_enrolled: true + spm_unit_pre_subsidy_childcare_expenses: 12_000 + households: + household: + members: [person1, person2] + state_code: SC + output: + # TANF enrolled -> $0 copay regardless of income + sc_ccap_copay: 0 + sc_ccap_eligible: true + +- name: Case 29, homeless family gets zero copay. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 36_000 + immigration_status: CITIZEN + weekly_hours_worked: 25 + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 12_000 + households: + household: + members: [person1, person2] + state_code: SC + is_homeless: true + output: + # Homeless -> $0 copay + sc_ccap_copay: 0 + sc_ccap_eligible: true + +# ============================================================ +# BENEFIT CAP AND EXPENSE INTERACTION +# ============================================================ + +- name: Case 30, benefit capped by actual expenses when less than max rate. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 24_000 + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 0 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: A_PLUS + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 3_000 + households: + household: + members: [person1, person2] + state_code: SC + county_str: RICHLAND_COUNTY_SC + output: + # Center A+ Urban FT Under 1 = $296/wk -> annual max = $15,392 + # Copay $0 (income 2,000/mo < 2,645 for fam size 2) + # Benefit = min(3,000 - 0, 15,392) = 3,000 + sc_ccap: 3_000 + +- name: Case 31, benefit capped by max rate when expenses exceed it. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 24_000 + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 20 + sc_ccap_provider_type: FFN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 10_000 + households: + household: + members: [person1, person2] + state_code: SC + output: + # FFN HT Age 3 = $30/wk (Rural default) + # Annual max = $30 * 52 = $1,560 + # Benefit = min(10,000 - 0, 1,560) = 1,560 + sc_ccap: 1_560 + +- name: Case 32, zero childcare expenses yields zero benefit. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 24_000 + immigration_status: CITIZEN + weekly_hours_worked: 20 + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 0 + households: + household: + members: [person1, person2] + state_code: SC + output: + # Expenses = $0 -> uncapped = max(0 - 0, 0) = 0 + sc_ccap: 0 + +- name: Case 33, copay exceeds expenses yields zero benefit. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + # $20/wk copay tier for family size 2 + employment_income: 53_772 + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + # Very low expenses + spm_unit_pre_subsidy_childcare_expenses: 500 + households: + household: + members: [person1, person2] + state_code: SC + output: + # Monthly copay = $20 * 1 * 52/12 = $86.67 + # Annual copay = $86.67 * 12 = $1,040 + # Annual max rate = Center C Rural FT Age 3 = $127 * 52 = $6,604 + # Uncapped = max(500 - 1,040, 0) = 0 + sc_ccap: 0 + +# ============================================================ +# MULTIPLE CHILDREN WITH DIFFERENT PROVIDERS AND TIME CATEGORIES +# ============================================================ + +- name: Case 34, multiple children different ages providers and schedules. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + employment_income: 36_000 + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 0 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: A_PLUS + person3: + age: 10 + is_tax_unit_dependent: true + immigration_status: CITIZEN + is_in_k12_school: true + childcare_hours_per_week: 15 + sc_ccap_provider_type: FFN + tax_units: + tax_unit: + members: [person1, person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + spm_unit_pre_subsidy_childcare_expenses: 15_000 + tanf: 0 + households: + household: + members: [person1, person2, person3] + state_code: SC + output: + sc_ccap_eligible_child: [false, true, true] + # person1 (adult, 0 hrs): HT; person2 (age 0, 35 hrs): FT; person3 (age 10, 15 hrs): HT + sc_ccap_time_category: [HALF_TIME, FULL_TIME, HALF_TIME] + # person1 (age 35): AGE_5_12_IN_SCHOOL (adults fall into last bucket) + sc_ccap_age_group: [AGE_5_12_IN_SCHOOL, UNDER_1, AGE_5_12_IN_SCHOOL] + # person2: Center A+ Rural FT Under 1 = $158/wk + # person3: FFN HT School Age = $24/wk + # MONTH var at YEAR period -> values * 12 + sc_ccap_maximum_weekly_benefit: [0, 1_896, 288] + # Family size 3, monthly income = 36,000 / 12 = 3,000 + # Fee scale family_size_3: $0-$3,331 -> $0/wk + # Annual max = ($158 + $24) * 52 = $9,464 + # Benefit = min(15,000 - 0, 9,464) = 9,464 + sc_ccap: 9_464 diff --git a/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/integration.yaml new file mode 100644 index 00000000000..84750f9946d --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/integration.yaml @@ -0,0 +1,428 @@ +# SC CCAP Integration Tests +# 2025 FPG (Contiguous US): +# first_person = 15,650, additional = 5,500 +# Family of 2: 21,150 +# Family of 3: 26,650 +# Family of 4: 32,150 +# 150% FPG family of 4: 32,150 * 1.50 = 48,225/yr = 4,018.75/mo +# 85% SMI (SC): +# Family of 2: $56,743/yr ($4,729/mo) +# Family of 3: $70,095/yr ($5,841/mo) +# Family of 4: $83,446/yr ($6,954/mo) +# Fee Scale 2025-2026 (family size 4): +# $0-$4,019/mo -> $0/wk +# $4,020-$4,668 -> $6/wk +# $4,669-$5,317 -> $11/wk +# $5,318-$5,966 -> $14/wk +# $5,967-$6,615 -> $17/wk +# $6,616-$7,263 -> $20/wk + +- name: Case 1, working family with 2 children in center care urban full time. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + employment_income: 60_000 + immigration_status: CITIZEN + weekly_hours_worked: 40 + person2: + age: 33 + weekly_hours_worked: 35 + person3: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + person4: + age: 8 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + spm_unit_pre_subsidy_childcare_expenses: 18_000 + tanf: 0 + households: + household: + members: [person1, person2, person3, person4] + state_code: SC + sc_ccap_geography: URBAN + output: + # === Eligibility === + # Child ages: 3 and 8, both < 13, citizen, dependent -> eligible + sc_ccap_eligible_child: [false, false, true, true] + + # Family size 4, income 60,000 <= 83,446 (85% SMI) -> eligible + sc_ccap_income_eligible: true + is_ccdf_asset_eligible: true + sc_ccap_eligible: true + + # === Copay === + # Monthly income = 60,000 / 12 = 5,000 + # Family size 4 fee scale: 4,669 <= 5,000 <= 5,317 -> $11/wk per child + # 2% cap: 5,000 * 0.02 = $100/mo; $100 / 4.33 = ~$23.09/wk cap + # $11 < $23.09 -> fee scale applies, $11/wk per child + # $11/wk * 2 eligible children * (52/12) = $95.33/mo + # Annual copay (MONTH var at YEAR period) = $95.33 * 12 = $1,144 + sc_ccap_copay: 1_144 + + # === Time categories === + # person1 (adult, 0 hrs): HT; person2 (adult, 0 hrs): HT + # person3: 35 hrs -> FULL_TIME; person4: 30 hrs -> FULL_TIME + sc_ccap_time_category: [HALF_TIME, HALF_TIME, FULL_TIME, FULL_TIME] + + # === Provider rates === + # Child1 (age 3): Center C, Urban, FT = $195/wk + # Child2 (age 8): Center C, Urban, FT, school age = $165/wk + # MONTH var at YEAR period -> values * 12 + sc_ccap_maximum_weekly_benefit: [0, 0, 2_340, 1_980] + + # === Benefit (MONTH formula, YEAR test period) === + # Monthly copay = $95.33 (from above) + # Monthly max rate = ($195 + $165) * 52 / 12 = $1,560 + # Monthly expenses = $18,000 / 12 = $1,500 + # Monthly uncapped = max(1,500 - 95.33, 0) = 1,404.67 + # Monthly benefit = min(1,404.67, 1,560) = 1,404.67 + # Annual benefit = 1,404.67 * 12 = 16,856.04 + sc_ccap: 16_856 + +- name: Case 2, low income family at zero copay tier. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 28 + employment_income: 24_000 + immigration_status: CITIZEN + weekly_hours_worked: 25 + person2: + age: 1 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 12_000 + tanf: 0 + households: + household: + members: [person1, person2] + state_code: SC + sc_ccap_geography: URBAN + output: + # === Eligibility === + sc_ccap_eligible_child: [false, true] + + # Family size 2, income 24,000 <= 56,743 (85% SMI) -> eligible + sc_ccap_income_eligible: true + sc_ccap_eligible: true + + # === Copay === + # Monthly income = 24,000 / 12 = 2,000 + # Family size 2 fee scale: $0-$2,644 -> $0/wk + # 2,000 < 2,645 -> $0 tier + sc_ccap_copay: 0 + + # === Provider rates === + # person1 (adult, 0 hrs): HT; person2 (age 1, 30 hrs): FT + sc_ccap_time_category: [HALF_TIME, FULL_TIME] + + # === Benefit === + # Center C, Urban, FT, Age 1 = $213/wk + # Monthly max rate = $213 * 52 / 12 = $923 + # Monthly expenses = $12,000 / 12 = $1,000 + # Monthly benefit = min(1,000 - 0, 923) = $923 (rate caps it) + # Annual benefit = $923 * 12 = $11,076 + sc_ccap: 11_076 + +- name: Case 3, family just above 85 percent SMI ineligible. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + employment_income: 84_000 + immigration_status: CITIZEN + weekly_hours_worked: 40 + person2: + age: 33 + person3: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + person4: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + spm_unit_pre_subsidy_childcare_expenses: 20_000 + households: + household: + members: [person1, person2, person3, person4] + state_code: SC + sc_ccap_geography: URBAN + output: + # === Eligibility === + sc_ccap_eligible_child: [false, false, true, true] + + # Family size 4, 85% SMI = $83,446/yr + # 84,000 > 83,446 -> ineligible + sc_ccap_income_eligible: false + sc_ccap_eligible: false + + # === Benefit === + sc_ccap: 0 + +- name: Case 4, FFN provider care scenario. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 30_000 + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 2 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: FFN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 5_000 + tanf: 0 + households: + household: + members: [person1, person2] + state_code: SC + sc_ccap_geography: RURAL + output: + # === Eligibility === + sc_ccap_eligible_child: [false, true] + + # Family size 2, income 30,000 <= 56,743 -> eligible + sc_ccap_income_eligible: true + sc_ccap_eligible: true + + # === Copay === + # Monthly income = 30,000 / 12 = 2,500 + # Family size 2: $0-$2,644 -> $0/wk + # 2,500 < 2,645 -> $0 tier + sc_ccap_copay: 0 + + # === Provider rates === + # person1 (adult, 0 hrs): HT; person2 (age 2, 30 hrs): FT + sc_ccap_time_category: [HALF_TIME, FULL_TIME] + # MONTH var at YEAR period -> values * 12 + sc_ccap_maximum_weekly_benefit: [0, 600] + + # === Benefit === + # Annual max = $50 * 52 = $2,600 + # Uncapped benefit = max(5,000 - 0, 0) = 5,000 + # Annual benefit = min(5,000, 2,600) = 2,600 + sc_ccap: 2_600 + +- name: Case 5, special needs child with surcharge. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + employment_income: 40_000 + immigration_status: CITIZEN + weekly_hours_worked: 35 + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + is_disabled: true + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 12_000 + tanf: 0 + households: + household: + members: [person1, person2] + state_code: SC + sc_ccap_geography: URBAN + output: + # === Eligibility === + # Disabled child age 5 < 19 -> eligible + sc_ccap_eligible_child: [false, true] + + # Family size 2, income 40,000 <= 56,743 -> eligible + sc_ccap_income_eligible: true + sc_ccap_eligible: true + + # === Copay === + # Disabled child in family -> exempt from copay ($0) + sc_ccap_copay: 0 + + # === Provider rates === + # person1 (adult, 0 hrs): HT; person2 (child, 30 hrs): FT + sc_ccap_time_category: [HALF_TIME, FULL_TIME] + + # === Benefit (MONTH formula, YEAR test period) === + # Age 5 defaults in-school (is_in_k12_school True for ages 5-17) + # Center C, Urban, FT, Age 5-12 in school = $165 + $20 surcharge = $185/wk + # Monthly max rate = $185 * 52 / 12 = $801.67 + # Monthly expenses = $12,000 / 12 = $1,000 + # Monthly uncapped = max(1,000 - 0, 0) = $1,000 + # Monthly benefit = min(1,000, 801.67) = $801.67 + # Annual benefit = $801.67 * 12 = $9,620 + sc_ccap: 9_620 + +- name: Case 6, foster care family with zero copay and surcharge. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + employment_income: 50_000 + immigration_status: CITIZEN + weekly_hours_worked: 40 + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + is_in_foster_care: true + childcare_hours_per_week: 35 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 14_000 + tanf: 0 + households: + household: + members: [person1, person2] + state_code: SC + sc_ccap_geography: URBAN + output: + # === Eligibility === + sc_ccap_eligible_child: [false, true] + + # Family size 2, income 50,000 <= 56,743 -> eligible + sc_ccap_income_eligible: true + sc_ccap_eligible: true + + # === Copay === + # Foster care -> $0 copay + sc_ccap_copay: 0 + + # === Provider rates === + # person1 (adult, 0 hrs): HT; person2 (child, 35 hrs): FT + sc_ccap_time_category: [HALF_TIME, FULL_TIME] + # Center C, Urban, FT, Age 3 = $195 + $30 foster surcharge = $225/wk + # MONTH var at YEAR period -> values * 12 + sc_ccap_maximum_weekly_benefit: [0, 2_700] + + # === Benefit === + # Annual max = $225 * 52 = $11,700 + # Uncapped benefit = max(14,000 - 0, 0) = 14,000 + # Annual benefit = min(14,000, 11,700) = 11,700 + sc_ccap: 11_700 + +- name: Case 7, half time care scenario. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 25_000 + immigration_status: CITIZEN + weekly_hours_worked: 20 + person2: + age: 0 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 20 + sc_ccap_provider_type: FFN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 3_000 + tanf: 0 + households: + household: + members: [person1, person2] + state_code: SC + sc_ccap_geography: RURAL + output: + # === Eligibility === + sc_ccap_eligible_child: [false, true] + + # Family size 2, income 25,000 <= 56,743 -> eligible + sc_ccap_income_eligible: true + # weekly_hours_worked 20 >= 15 -> activity eligible + sc_ccap_eligible: true + + # === Copay === + # Monthly income = 25,000 / 12 = 2,083.33 + # Family size 2: $0-$2,644 -> $0/wk + sc_ccap_copay: 0 + + # === Provider rates === + # person1 (adult, 0 hrs): HT; person2 (child, 20 hrs < 25): HT + sc_ccap_time_category: [HALF_TIME, HALF_TIME] + # FFN, HT, Under 3 = $30/wk + # MONTH var at YEAR period -> values * 12 + sc_ccap_maximum_weekly_benefit: [0, 360] + + # === Benefit === + # Annual max = $30 * 52 = $1,560 + # Uncapped benefit = max(3,000 - 0, 0) = 3,000 + # Annual benefit = min(3,000, 1,560) = 1,560 + sc_ccap: 1_560 diff --git a/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap.yaml b/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap.yaml new file mode 100644 index 00000000000..fd0e591ff96 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap.yaml @@ -0,0 +1,115 @@ +# SC CCAP benefit tests +# sc_ccap is SPMUnit, MONTH +# Annual benefit = sum over 12 months of per-child monthly benefits + +- name: Case 1, basic benefit calculation. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 36_000 + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 10_000 + tanf: 0 + households: + household: + members: [person1, person2] + state_code: SC + sc_ccap_geography: URBAN + output: + # Family size 2, income 36,000/yr = 3,000/mo + # 85% SMI family size 2 = $56,743/yr -> eligible + # Monthly income $3,000 >= $2,645 -> $6/wk copay tier + # Monthly copay = $6 * 1 child * (52/12) = $26.00 + # Max weekly rate: Center C Urban FT Age 3 = $195/wk + # Monthly max = $195 * 52 / 12 = $845 + # Monthly expenses = $10,000 / 12 = $833.33 + # Uncapped = max(833.33 - 26, 0) = $807.33 + # Monthly benefit = min(807.33, 845) = $807.33 + # Annual benefit = $807.33 * 12 = $9,688 + sc_ccap: 9_688 + +- name: Case 2, ineligible family gets zero. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 90_000 + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 10_000 + households: + household: + members: [person1, person2] + state_code: SC + sc_ccap_geography: URBAN + output: + # Family size 2, 85% SMI = $56,743/yr + # 90,000 > 56,743 -> ineligible -> $0 + sc_ccap: 0 + +- name: Case 3, benefit capped at max rate. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 36_000 + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 8 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 20 + sc_ccap_provider_type: FFN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 5_000 + households: + household: + members: [person1, person2] + state_code: SC + output: + # Family size 2, 36,000/yr = 3,000/mo -> $0 copay + # FFN, HT, school age = $24/wk + # Annual max = $24 * 52 = $1,248 + # Uncapped benefit = max(5,000 - 0, 0) = 5,000 + # Annual benefit = min(5,000, 1,248) = 1,248 + sc_ccap: 1_248 diff --git a/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap_age_group.yaml b/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap_age_group.yaml new file mode 100644 index 00000000000..72dfb363904 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap_age_group.yaml @@ -0,0 +1,80 @@ +# SC CCAP age group tests +# sc_ccap_age_group is Person (enum) + +- name: Case 1, infant under 1. + period: 2025 + input: + people: + person1: + age: 0 + households: + household: + members: [person1] + state_code: SC + output: + sc_ccap_age_group: [UNDER_1] + +- name: Case 2, toddler age 1. + period: 2025 + input: + people: + person1: + age: 1 + households: + household: + members: [person1] + state_code: SC + output: + sc_ccap_age_group: [AGE_1] + +- name: Case 3, toddler age 2. + period: 2025 + input: + people: + person1: + age: 2 + households: + household: + members: [person1] + state_code: SC + output: + sc_ccap_age_group: [AGE_2] + +- name: Case 4, preschool age 3. + period: 2025 + input: + people: + person1: + age: 3 + households: + household: + members: [person1] + state_code: SC + output: + sc_ccap_age_group: [AGE_3] + +- name: Case 5, preschool age 4. + period: 2025 + input: + people: + person1: + age: 4 + households: + household: + members: [person1] + state_code: SC + output: + sc_ccap_age_group: [AGE_4] + +- name: Case 6, school age child. + period: 2025 + input: + people: + person1: + age: 8 + households: + household: + members: [person1] + state_code: SC + output: + sc_ccap_age_group: [AGE_5_12_IN_SCHOOL] diff --git a/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap_copay.yaml b/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap_copay.yaml new file mode 100644 index 00000000000..bf05bb2fa07 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap_copay.yaml @@ -0,0 +1,802 @@ +# SC CCAP copay tests +# sc_ccap_copay is SPMUnit, MONTH (total monthly copay for the unit) +# +# Fee Scale 2025-2026, family size 4 (monthly income brackets): +# $0 - $4,019 -> $0/wk +# $4,020 - $4,668 -> $6/wk +# $4,669 - $5,317 -> $11/wk +# $5,318 - $5,966 -> $14/wk +# $5,967 - $6,615 -> $17/wk +# $6,616 - $7,263 -> $20/wk +# +# 2025 FPG family of 4: 15,650 + 5,500 * 3 = 32,150 +# 150% FPG family of 4: 32,150 * 1.50 = 48,225/yr = 4,018.75/mo + +- name: Case 1, family size 4 in zero copay tier. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 36_000 + person2: + age: 28 + person3: + age: 5 + is_tax_unit_dependent: true + person4: + age: 3 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: SC + output: + # Monthly income = 36,000 / 12 = 3,000 < 4,020 -> $0/wk tier + # $0/wk * 2 eligible children * (52/12) = $0/mo + sc_ccap_copay: 0 + +- name: Case 2, family size 4 in $6 copay tier. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 50_400 + person2: + age: 28 + person3: + age: 5 + is_tax_unit_dependent: true + childcare_hours_per_week: 30 + person4: + age: 3 + is_tax_unit_dependent: true + childcare_hours_per_week: 30 + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + tanf: 0 + households: + household: + members: [person1, person2, person3, person4] + state_code: SC + output: + # Monthly income = 50,400 / 12 = 4,200 + # 4,020 <= 4,200 <= 4,668 -> $6/wk per child + # $6/wk * 2 children in care * (52/12) = $52.00/mo + sc_ccap_copay: 52 + +- name: Case 3, family size 4 in $11 copay tier. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 60_000 + person2: + age: 28 + person3: + age: 5 + is_tax_unit_dependent: true + childcare_hours_per_week: 30 + person4: + age: 3 + is_tax_unit_dependent: true + childcare_hours_per_week: 30 + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + tanf: 0 + households: + household: + members: [person1, person2, person3, person4] + state_code: SC + output: + # Monthly income = 60,000 / 12 = 5,000 + # 4,669 <= 5,000 <= 5,317 -> $11/wk per child + # $11/wk * 2 children in care * (52/12) = $95.33/mo + sc_ccap_copay: 95.33 + +- name: Case 4, family size 4 in $14 copay tier. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 66_000 + person2: + age: 28 + person3: + age: 5 + is_tax_unit_dependent: true + childcare_hours_per_week: 30 + person4: + age: 3 + is_tax_unit_dependent: true + childcare_hours_per_week: 30 + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + tanf: 0 + households: + household: + members: [person1, person2, person3, person4] + state_code: SC + output: + # Monthly income = 66,000 / 12 = 5,500 + # 5,318 <= 5,500 <= 5,966 -> $14/wk per child + # Uncapped: $14/wk * 2 children * (52/12) = $121.33/mo + # 2% family cap: 5,500 * 0.02 = $110/mo + # min($121.33, $110) = $110/mo + sc_ccap_copay: 110 + +- name: Case 5, family size 4 in $17 copay tier. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 68_400 + person2: + age: 28 + person3: + age: 5 + is_tax_unit_dependent: true + childcare_hours_per_week: 30 + person4: + age: 3 + is_tax_unit_dependent: true + childcare_hours_per_week: 30 + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: SC + output: + # FPG for 4 (2025): 32,150 -> 150% = 48,225/yr = 4,019/mo + # SMI for 4 (SC): 98,172/yr -> 85% = 6,954/mo + # Band width: ceil((6954 - 4019) / 5) = 587 + # Tier 3 ($14): income > 4019+587*2=5193 and <= 4019+587*3=5780 + # Monthly income = 68,400 / 12 = 5,700 -> tier 2 ($14/wk) + # Uncapped: $14/wk * 2 children * (52/12) = $121.33/mo + # 2% family cap: 5,700 * 0.02 = $114/mo + # min($121.33, $114) = $114/mo + sc_ccap_copay: 114 + +- name: Case 6, family size 4 in $20 copay tier. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 80_400 + person2: + age: 28 + person3: + age: 5 + is_tax_unit_dependent: true + childcare_hours_per_week: 30 + person4: + age: 3 + is_tax_unit_dependent: true + childcare_hours_per_week: 30 + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: SC + output: + # Monthly income = 80,400 / 12 = 6,700 + # 6,616 <= 6,700 <= 7,263 -> $20/wk per child + # Uncapped: $20/wk * 2 children * (52/12) = $173.33/mo + # 2% family cap: 6,700 * 0.02 = $134/mo + # min($173.33, $134) = $134/mo + sc_ccap_copay: 134 + +- name: Case 7, TANF enrolled family gets zero copay. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 60_000 + person2: + age: 5 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + is_tanf_enrolled: true + households: + household: + members: [person1, person2] + state_code: SC + output: + # TANF enrolled -> $0 copay regardless of income + sc_ccap_copay: 0 + +- name: Case 8, foster care family gets zero copay. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + employment_income: 60_000 + person2: + age: 5 + is_tax_unit_dependent: true + is_in_foster_care: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: SC + output: + # Foster care -> $0 copay regardless of income + sc_ccap_copay: 0 + +- name: Case 9, homeless family gets zero copay. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 60_000 + person2: + age: 5 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: SC + is_homeless: true + output: + # Homeless -> $0 copay regardless of income + sc_ccap_copay: 0 + +- name: Case 10, copay capped at 2 percent of family income. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 24_000 + person2: + age: 5 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: SC + output: + # Monthly income = 24,000 / 12 = 2,000 + # Family size 2 fee scale: look up bracket for $2,000/mo + # 2% cap: 2,000 * 0.02 = $40/mo -> $40 / 4.33 = ~$9.24/wk cap + # If fee from scale > $9.24/wk, cap applies + # Fee from scale at this income for family size 2: + # Fee scale family size 2: $0-$2,643->$0, $2,644-$3,073->$6 + # $2,000 < $2,644 -> $0/wk from scale + # min($0, cap) = $0 + # $0/wk * 1 eligible child * (52/12) = $0/mo + sc_ccap_copay: 0 + +- name: Case 11, CPS protective services child gets zero copay. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 60_000 + person2: + age: 5 + is_tax_unit_dependent: true + receives_or_needs_protective_services: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: SC + output: + # Protective services -> $0 copay regardless of income + sc_ccap_copay: 0 + +- name: Case 12, Head Start child gets zero copay. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 40_000 + person2: + age: 4 + is_tax_unit_dependent: true + is_enrolled_in_head_start: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: SC + output: + # Head Start category -> $0 copay regardless of income + sc_ccap_copay: 0 + +# Pre-2024 era: no FPL exemption, tiers at SMI ratios (45/55/65/75%) +- name: Case 13, pre-2024 era family size 2 in lowest SMI tier. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 18_000 + person2: + age: 4 + is_tax_unit_dependent: true + childcare_hours_per_week: 30 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + tanf: 0 + households: + household: + members: [person1, person2] + state_code: SC + output: + # Pre-2024: no FPL exemption, all families pay at least $6/wk. + # SMI for FS 2 (SC, 2023-10-01): 89,725 * 0.68 = 61,013/yr = 5,084/mo + # 45% SMI = 2,288; income $1,500 < 2,288 -> tier 0 ($6/wk) + # $6/wk * 1 child in care * 52/12 = $26/mo + sc_ccap_copay: 26 + +- name: Case 14, pre-2024 era family size 4 in $11 tier. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 48_000 + person2: + age: 28 + person3: + age: 5 + is_tax_unit_dependent: true + childcare_hours_per_week: 30 + person4: + age: 3 + is_tax_unit_dependent: true + childcare_hours_per_week: 30 + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + tanf: 0 + households: + household: + members: [person1, person2, person3, person4] + state_code: SC + output: + # SMI for FS 4 (SC, 2023-10-01): 89,725/yr = 7,477/mo + # 45% = 3,365; 55% = 4,112 + # income $4,000 > 3,365 and <= 4,112 -> tier 1 ($11/wk) + # Uncapped: $11/wk * 2 children * 52/12 = $95.33/mo + # 2% family cap: 4,000 * 0.02 = $80/mo + # min($95.33, $80) = $80/mo + sc_ccap_copay: 80 + +# Post-2024 era: FPL exemption + equal FPL-to-SMI bands +- name: Case 15, post-2024 family size 2 below FPL exempt. + period: 2025-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 24_000 + person2: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + tanf: 0 + households: + household: + members: [person1, person2] + state_code: SC + output: + # FPG for FS 2 (2025): 21,150 -> 150% = 31,725/yr = 2,644/mo + # Income $2,000 <= $2,644 -> FPL exempt, $0 copay + sc_ccap_copay: 0 + +- name: Case 16, post-2024 family size 2 in $14 tier. + period: 2025-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 42_000 + person2: + age: 4 + is_tax_unit_dependent: true + childcare_hours_per_week: 30 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + tanf: 0 + households: + household: + members: [person1, person2] + state_code: SC + output: + # FPG for FS 2: 150% = 2,644/mo; 85% SMI = 4,729/mo + # band_width = ceil((4729-2644)/5) = 417 + # Thresholds: 3061, 3478, 3895, 4312 + # Income $3,500 > 3,478 but <= 3,895 -> tier 2 ($14/wk) + # $14/wk * 1 child in care * 52/12 = $60.67/mo + sc_ccap_copay: 60.67 + +- name: Case 17, post-2024 family size 10 below FPL exempt. + period: 2025-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 60_000 + person2: + age: 28 + person3: + age: 12 + is_tax_unit_dependent: true + person4: + age: 10 + is_tax_unit_dependent: true + person5: + age: 8 + is_tax_unit_dependent: true + person6: + age: 6 + is_tax_unit_dependent: true + person7: + age: 4 + is_tax_unit_dependent: true + person8: + age: 3 + is_tax_unit_dependent: true + person9: + age: 2 + is_tax_unit_dependent: true + person10: + age: 1 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10] + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10] + tanf: 0 + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10] + state_code: SC + output: + # FPG for FS 10 (2025): 65,150 -> 150% = 97,725/yr = 8,144/mo + # Income $5,000 <= $8,144 -> FPL exempt, $0 copay + sc_ccap_copay: 0 + +- name: Case 18, post-2024 family size 10 in paid tier. + period: 2025-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 108_000 + person2: + age: 28 + person3: + age: 12 + is_tax_unit_dependent: true + childcare_hours_per_week: 30 + person4: + age: 10 + is_tax_unit_dependent: true + childcare_hours_per_week: 30 + person5: + age: 8 + is_tax_unit_dependent: true + childcare_hours_per_week: 30 + person6: + age: 6 + is_tax_unit_dependent: true + childcare_hours_per_week: 30 + person7: + age: 4 + is_tax_unit_dependent: true + childcare_hours_per_week: 30 + person8: + age: 3 + is_tax_unit_dependent: true + childcare_hours_per_week: 30 + person9: + age: 2 + is_tax_unit_dependent: true + childcare_hours_per_week: 30 + person10: + age: 1 + is_tax_unit_dependent: true + childcare_hours_per_week: 30 + tax_units: + tax_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10] + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10] + tanf: 0 + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10] + state_code: SC + output: + # FPG for FS 10: 150% = 8,144/mo; 85% SMI = 10,014/mo + # band_width = ceil((10014-8144)/5) = ceil(374) = 374 + # Income $9,000 > 8,144 -> in paid band + # $9,000 > 8518? Yes; > 8892? Yes; > 9266? No -> tier 2 ($14/wk) + # Uncapped: 8 children * $14/wk * 52/12 = $485.33/mo + # 2% family cap: 9,000 * 0.02 = $180/mo + # min($485.33, $180) = $180/mo + sc_ccap_copay: 180 + +- name: Case 19, Head Start only family with sibling gets zero copay. + period: 2025-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 90_000 + weekly_hours_worked: 0 + is_full_time_student: false + person2: + age: 4 + is_tax_unit_dependent: true + is_enrolled_in_head_start: true + person3: + age: 7 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + tanf: 0 + households: + household: + members: [person1, person2, person3] + state_code: SC + output: + # Family qualifies only through Head Start path (high income, no work). + # Head Start child (person2) has $0 copay per Section 2.15. + # Sibling (person3) is not covered by the Head Start path and does + # not meet standard path requirements, so num_paying = 0. + # Total copay = $0. + sc_ccap_copay: 0 + +- name: Case 21, post-2024 family size 15 row is zero only. + period: 2025-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 132_000 + person2: + age: 28 + person3: + age: 12 + is_tax_unit_dependent: true + childcare_hours_per_week: 30 + person4: + age: 11 + is_tax_unit_dependent: true + childcare_hours_per_week: 30 + person5: + age: 10 + is_tax_unit_dependent: true + person6: + age: 9 + is_tax_unit_dependent: true + person7: + age: 8 + is_tax_unit_dependent: true + person8: + age: 7 + is_tax_unit_dependent: true + person9: + age: 6 + is_tax_unit_dependent: true + person10: + age: 5 + is_tax_unit_dependent: true + person11: + age: 4 + is_tax_unit_dependent: true + person12: + age: 3 + is_tax_unit_dependent: true + person13: + age: 2 + is_tax_unit_dependent: true + person14: + age: 1 + is_tax_unit_dependent: true + person15: + age: 17 + tax_units: + tax_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14, person15] + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14, person15] + tanf: 0 + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14, person15] + state_code: SC + output: + # Family size 15 row in the 2025-2026 fee scale is $0 only. + # Monthly income = 11,000 remains income-eligible but should not inherit + # size-14 paid tiers. + sc_ccap_copay: 0 + +- name: Case 22, post-2024 family size 16 row is zero only. + period: 2025-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 132_000 + person2: + age: 28 + person3: + age: 12 + is_tax_unit_dependent: true + childcare_hours_per_week: 30 + person4: + age: 11 + is_tax_unit_dependent: true + childcare_hours_per_week: 30 + person5: + age: 10 + is_tax_unit_dependent: true + person6: + age: 9 + is_tax_unit_dependent: true + person7: + age: 8 + is_tax_unit_dependent: true + person8: + age: 7 + is_tax_unit_dependent: true + person9: + age: 6 + is_tax_unit_dependent: true + person10: + age: 5 + is_tax_unit_dependent: true + person11: + age: 4 + is_tax_unit_dependent: true + person12: + age: 3 + is_tax_unit_dependent: true + person13: + age: 2 + is_tax_unit_dependent: true + person14: + age: 1 + is_tax_unit_dependent: true + person15: + age: 17 + person16: + age: 16 + tax_units: + tax_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14, person15, person16] + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14, person15, person16] + tanf: 0 + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14, person15, person16] + state_code: SC + output: + # Family size 16 row in the 2025-2026 fee scale is $0 only. + # Monthly income = 11,000 remains income-eligible but should not inherit + # size-14 paid tiers. + sc_ccap_copay: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap_countable_income.yaml new file mode 100644 index 00000000000..afc12697219 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap_countable_income.yaml @@ -0,0 +1,123 @@ +# SC CCAP countable income tests +# Countable income uses sources.yaml pattern — sums listed income variables +# sc_ccap_countable_income is SPMUnit, MONTH + +- name: Case 1, employment income included. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 40_000 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: SC + output: + sc_ccap_countable_income: 40_000 + +- name: Case 2, SSI excluded from countable income. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 30_000 + ssi: 10_000 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: SC + output: + # SSI is excluded per Policy Manual 2.1.15 + # Only employment_income counts + sc_ccap_countable_income: 30_000 + +- name: Case 3, multiple included income sources. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + employment_income: 25_000 + self_employment_income: 10_000 + social_security: 5_000 + child_support_received: 3_600 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: SC + output: + # 25,000 + 10,000 + 5,000 + 3,600 = 43,600 + sc_ccap_countable_income: 43_600 + +- name: Case 4, two person household income summed. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + employment_income: 30_000 + person2: + age: 33 + employment_income: 20_000 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: SC + output: + # 30,000 + 20,000 = 50,000 + sc_ccap_countable_income: 50_000 + +- name: Case 5, zero income family. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: SC + output: + sc_ccap_countable_income: 0 + +- name: Case 6, SNAP excluded from countable income. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 20_000 + spm_units: + spm_unit: + members: [person1] + snap: 3_600 + households: + household: + members: [person1] + state_code: SC + output: + # SNAP is excluded per Policy Manual 2.1.15 + sc_ccap_countable_income: 20_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap_eligible.yaml new file mode 100644 index 00000000000..fca07822e83 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap_eligible.yaml @@ -0,0 +1,319 @@ +# SC CCAP overall eligibility tests +# sc_ccap_eligible is SPMUnit, MONTH +# Combines: income eligible, asset eligible, activity eligible, has eligible child, residency + +- name: Case 1, eligible family in SC. + period: 2025 + input: + people: + person1: + age: 30 + employment_income: 40_000 + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: SC + output: + sc_ccap_eligible: true + +- name: Case 2, ineligible due to income above 85 percent SMI. + period: 2025 + input: + people: + person1: + age: 30 + employment_income: 90_000 + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: SC + output: + # Family size 2, 85% SMI = $56,743/yr + # 90,000 > 56,743 -> ineligible + sc_ccap_eligible: false + +- name: Case 3, ineligible no eligible child. + period: 2025 + input: + people: + person1: + age: 30 + employment_income: 30_000 + immigration_status: CITIZEN + weekly_hours_worked: 30 + tax_units: + tax_unit: + members: [person1] + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: SC + output: + # No children -> no eligible child -> ineligible + sc_ccap_eligible: false + +- name: Case 4, non-SC family ineligible. + period: 2025 + input: + people: + person1: + age: 30 + employment_income: 30_000 + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: GA + output: + sc_ccap_eligible: false + +- name: Case 5, activity ineligible parent. + period: 2025 + input: + people: + person1: + age: 30 + employment_income: 30_000 + immigration_status: CITIZEN + weekly_hours_worked: 10 + is_full_time_student: false + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: SC + output: + # Works 10 hrs/wk < 15 minimum, not a student -> ineligible + sc_ccap_eligible: false + +- name: Case 6, full time student meets activity requirement. + period: 2025 + input: + people: + person1: + age: 22 + employment_income: 20_000 + immigration_status: CITIZEN + weekly_hours_worked: 0 + is_full_time_student: true + person2: + age: 2 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: SC + output: + # FT student -> activity eligible even with 0 work hours + sc_ccap_eligible: true + +- name: Case 7, protective services family with no work is eligible. + period: 2025 + input: + people: + person1: + age: 30 + employment_income: 30_000 + immigration_status: CITIZEN + weekly_hours_worked: 0 + is_full_time_student: false + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + is_in_foster_care: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: SC + output: + # Foster child = protective services -> activity waived + # Income 30,000 < 85% SMI for size 2 -> income eligible + sc_ccap_eligible: true + +- name: Case 8, Head Start child with high income and no work is eligible. + period: 2025 + input: + people: + person1: + age: 30 + employment_income: 90_000 + immigration_status: CITIZEN + weekly_hours_worked: 0 + is_full_time_student: false + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + is_enrolled_in_head_start: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: SC + output: + # Enrolled in Head Start -> Head Start pathway + # Income and activity waived for Head Start + # 90,000 > 85% SMI but income waived for Head Start + sc_ccap_eligible: true + +- name: Case 9, protective services but income too high is ineligible. + period: 2025 + input: + people: + person1: + age: 30 + employment_income: 90_000 + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 8 + is_tax_unit_dependent: true + immigration_status: CITIZEN + receives_or_needs_protective_services: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: SC + output: + # Protective services waives activity but NOT income + # 90,000 > 85% SMI for size 2 (~56,743) -> income ineligible + # Child age 8 not Head Start eligible -> no Head Start bypass + sc_ccap_eligible: false + +- name: Case 10, Head Start child plus non-Head-Start sibling with no work. + period: 2025-01 + input: + people: + person1: + age: 30 + employment_income: 90_000 + weekly_hours_worked: 0 + is_full_time_student: false + person2: + age: 4 + is_tax_unit_dependent: true + is_enrolled_in_head_start: true + person3: + age: 7 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: SC + output: + # Head Start child (person2) is CCDF-eligible and enrolled -> + # Head Start path qualifies the unit. Sibling (person3) is not + # independently covered (no work, high income) but unit is eligible + # for the Head Start child only. + sc_ccap_eligible: true + +- name: Case 11, Head Start enrolled child is not CCDF-eligible but sibling is. + period: 2025-01 + input: + people: + person1: + age: 30 + employment_income: 90_000 + weekly_hours_worked: 0 + is_full_time_student: false + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: UNDOCUMENTED + is_enrolled_in_head_start: true + person3: + age: 7 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: SC + output: + # Head Start child (person2) is undocumented -> not CCDF-eligible. + # Sibling (person3) is CCDF-eligible but not Head Start enrolled. + # No work + high income -> standard path fails for sibling. + # Head Start path requires the SAME child to be both enrolled + # and CCDF-eligible, so unit is ineligible. + sc_ccap_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap_eligible_child.yaml b/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap_eligible_child.yaml new file mode 100644 index 00000000000..8f7d4872ed8 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap_eligible_child.yaml @@ -0,0 +1,231 @@ +# SC CCAP eligible child tests + +- name: Case 1, eligible child under 13. + period: 2025 + input: + people: + person1: + age: 30 + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: SC + output: + sc_ccap_eligible_child: [false, true] + +- name: Case 2, child age 13 ineligible without disability. + period: 2025 + input: + people: + person1: + age: 35 + person2: + age: 13 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: SC + output: + sc_ccap_eligible_child: [false, false] + +- name: Case 3, disabled child age 15 eligible. + period: 2025 + input: + people: + person1: + age: 40 + person2: + age: 15 + is_tax_unit_dependent: true + is_disabled: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: SC + output: + sc_ccap_eligible_child: [false, true] + +- name: Case 4, disabled child age 19 ineligible. + period: 2025 + input: + people: + person1: + age: 45 + person2: + age: 19 + is_tax_unit_dependent: true + is_disabled: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: SC + output: + sc_ccap_eligible_child: [false, false] + +- name: Case 5, undocumented child ineligible. + period: 2025 + input: + people: + person1: + age: 30 + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: UNDOCUMENTED + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: SC + output: + sc_ccap_eligible_child: [false, false] + +- name: Case 6, child who is not a tax dependent is ineligible. + period: 2025 + input: + people: + person1: + age: 30 + person2: + age: 8 + is_tax_unit_dependent: false + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: SC + output: + # Policy Manual 2.1.7: child must be a dependent + sc_ccap_eligible_child: [false, false] + +- name: Case 7, adult is never an eligible child. + period: 2025 + input: + people: + person1: + age: 30 + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1] + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: SC + output: + sc_ccap_eligible_child: [false] + +- name: Case 8, disabled child age 18 eligible. + period: 2025 + input: + people: + person1: + age: 45 + person2: + age: 18 + is_tax_unit_dependent: true + is_disabled: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: SC + output: + sc_ccap_eligible_child: [false, true] + +- name: Case 9, infant eligible. + period: 2025 + input: + people: + person1: + age: 25 + person2: + age: 0 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: SC + output: + sc_ccap_eligible_child: [false, true] + +- name: Case 10, child age 12 at boundary eligible. + period: 2025 + input: + people: + person1: + age: 40 + person2: + age: 12 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: SC + output: + sc_ccap_eligible_child: [false, true] diff --git a/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap_geography.yaml b/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap_geography.yaml new file mode 100644 index 00000000000..f0b549fac01 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap_geography.yaml @@ -0,0 +1,59 @@ +# SC CCAP geography tests +# sc_ccap_geography is Household (enum: URBAN, RURAL) +# Based on county mapping to Appendix 4 designations + +- name: Case 1, Richland County is urban. + period: 2025 + input: + people: + person1: + age: 5 + households: + household: + members: [person1] + state_code: SC + county_fips: "45079" + output: + sc_ccap_geography: [URBAN] + +- name: Case 2, Abbeville County is rural. + period: 2025 + input: + people: + person1: + age: 5 + households: + household: + members: [person1] + state_code: SC + county_fips: "45001" + output: + sc_ccap_geography: [RURAL] + +- name: Case 3, Charleston County is urban. + period: 2025 + input: + people: + person1: + age: 5 + households: + household: + members: [person1] + state_code: SC + county_fips: "45019" + output: + sc_ccap_geography: [URBAN] + +- name: Case 4, Chester County is rural. + period: 2025 + input: + people: + person1: + age: 5 + households: + household: + members: [person1] + state_code: SC + county_fips: "45023" + output: + sc_ccap_geography: [RURAL] diff --git a/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap_income_eligible.yaml new file mode 100644 index 00000000000..6ba3e4a14ff --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap_income_eligible.yaml @@ -0,0 +1,116 @@ +# SC CCAP income eligibility tests +# sc_ccap_income_eligible is SPMUnit, MONTH +# 2025 HHS SMI for SC, family size 4: +# 85% SMI = $83,446/yr ($6,954/mo) per Income Standards 2024-2025 + +- name: Case 1, income below 85 percent SMI. + period: 2025 + input: + people: + person1: + age: 30 + employment_income: 60_000 + person2: + age: 28 + person3: + age: 5 + person4: + age: 3 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: SC + output: + # Family size 4, 85% SMI = $83,446/yr + # 60,000 <= 83,446 -> eligible + sc_ccap_income_eligible: true + +- name: Case 2, income above 85 percent SMI. + period: 2025 + input: + people: + person1: + age: 30 + employment_income: 90_000 + person2: + age: 28 + person3: + age: 5 + person4: + age: 3 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: SC + output: + # Family size 4, 85% SMI = $83,446/yr + # 90,000 > 83,446 -> ineligible + sc_ccap_income_eligible: false + +- name: Case 3, zero income family eligible. + period: 2025 + input: + people: + person1: + age: 30 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: SC + output: + # 0 <= any threshold -> eligible + sc_ccap_income_eligible: true + +- name: Case 4, single parent family size 2. + period: 2025 + input: + people: + person1: + age: 30 + employment_income: 55_000 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + tanf: 0 + households: + household: + members: [person1, person2] + state_code: SC + output: + # Family size 2, 85% SMI = $56,743/yr + # 55,000 <= 56,743 -> eligible + sc_ccap_income_eligible: true + +- name: Case 5, single parent family size 2 above threshold. + period: 2025 + input: + people: + person1: + age: 30 + employment_income: 57_000 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: SC + output: + # Family size 2, 85% SMI = $56,743/yr + # 57,000 > 56,743 -> ineligible + sc_ccap_income_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap_maximum_weekly_benefit.yaml b/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap_maximum_weekly_benefit.yaml new file mode 100644 index 00000000000..d7ab9f32d2e --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap_maximum_weekly_benefit.yaml @@ -0,0 +1,313 @@ +# SC CCAP maximum weekly benefit tests +# sc_ccap_maximum_weekly_benefit is Person, MONTH +# Sample rates from Maximum Payments FFY2023: +# Level C Center, Urban, FT: Under 1=$213, Age 3=$195, 5-12 in school=$165 +# FFN (any location, FT): Under 1-2=$50, Age 3-12=$46 +# FFN HT: Under 3=$30, School age=$24 +# Special needs surcharge: $20/wk +# Foster care surcharge: $30/wk + +- name: Case 1, level C center urban full time infant. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 0 + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + households: + household: + members: [person1] + state_code: SC + sc_ccap_geography: URBAN + output: + # Center, Level C, Urban, FT, Under 1 = $213/wk + sc_ccap_maximum_weekly_benefit: [213] + +- name: Case 2, level C center urban full time age 3. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 3 + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + households: + household: + members: [person1] + state_code: SC + sc_ccap_geography: URBAN + output: + # Center, Level C, Urban, FT, Age 3 = $195/wk + sc_ccap_maximum_weekly_benefit: [195] + +- name: Case 3, level C center urban full time school age. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 8 + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + households: + household: + members: [person1] + state_code: SC + sc_ccap_geography: URBAN + output: + # Center, Level C, Urban, FT, 5-12 in school = $165/wk + sc_ccap_maximum_weekly_benefit: [165] + +- name: Case 4, FFN full time infant. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 0 + childcare_hours_per_week: 30 + sc_ccap_provider_type: FFN + households: + household: + members: [person1] + state_code: SC + sc_ccap_geography: URBAN + output: + # FFN, any location, FT, Under 1-2 = $50/wk + sc_ccap_maximum_weekly_benefit: [50] + +- name: Case 5, FFN full time school age. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 8 + childcare_hours_per_week: 30 + sc_ccap_provider_type: FFN + households: + household: + members: [person1] + state_code: SC + sc_ccap_geography: URBAN + output: + # FFN, any location, FT, Age 3-12 = $46/wk + sc_ccap_maximum_weekly_benefit: [46] + +- name: Case 6, FFN half time infant. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 0 + childcare_hours_per_week: 20 + sc_ccap_provider_type: FFN + households: + household: + members: [person1] + state_code: SC + sc_ccap_geography: RURAL + output: + # FFN, any location, HT, Under 3 = $30/wk + sc_ccap_maximum_weekly_benefit: [30] + +- name: Case 7, FFN half time school age. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 8 + childcare_hours_per_week: 20 + sc_ccap_provider_type: FFN + households: + household: + members: [person1] + state_code: SC + sc_ccap_geography: RURAL + output: + # FFN, any location, HT, School age = $24/wk + sc_ccap_maximum_weekly_benefit: [24] + +- name: Case 8, special needs surcharge. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 5 + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + is_disabled: true + households: + household: + members: [person1] + state_code: SC + sc_ccap_geography: URBAN + output: + # Age 5 defaults to in school (is_in_k12_school imputed True for ages 5-17) + # Center C, Urban, FT, Age 5-12 in school = $165 + $20 special needs = $185/wk + sc_ccap_maximum_weekly_benefit: [185] + +- name: Case 9, foster care surcharge. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 3 + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + is_in_foster_care: true + households: + household: + members: [person1] + state_code: SC + sc_ccap_geography: URBAN + output: + # Center C, Urban, FT, Age 3 = $195 + $30 foster surcharge = $225/wk + sc_ccap_maximum_weekly_benefit: [225] + +# Second child discount tests +# Per Policy Manual 5.11, the discount is provider-determined and applies +# to all children except the youngest. + +- name: Case 10, second child discount with two children. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 3 + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + sc_ccap_second_child_discount_rate: 0.10 + person3: + age: 0 + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + sc_ccap_second_child_discount_rate: 0.10 + tax_units: + tax_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: SC + sc_ccap_geography: URBAN + output: + # person2 (age 3) = child_index 2 (older) -> discount applies + # Base rate: Center C, Urban, FT, Age 3 = $195 + # Discounted: $195 * (1 - 0.10) = $175.50 + # person3 (age 0) = child_index 1 (youngest) -> no discount + # Base rate: Center C, Urban, FT, Under 1 = $213 + sc_ccap_maximum_weekly_benefit: [0, 175.50, 213] + +- name: Case 11, no discount when only one child. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 3 + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + sc_ccap_second_child_discount_rate: 0.10 + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: SC + sc_ccap_geography: URBAN + output: + # child_index 1 (youngest and only) -> no discount despite rate being set + # Base rate: Center C, Urban, FT, Age 3 = $195 + sc_ccap_maximum_weekly_benefit: [0, 195] + +- name: Case 12, no discount when provider does not offer one. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 3 + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + person3: + age: 0 + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + tax_units: + tax_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: SC + sc_ccap_geography: URBAN + output: + # No sc_ccap_second_child_discount_rate set -> defaults to 0 -> no discount + # person2 (age 3): Center C, Urban, FT, Age 3 = $195 + # person3 (age 0): Center C, Urban, FT, Under 1 = $213 + sc_ccap_maximum_weekly_benefit: [0, 195, 213] + +- name: Case 13, three children with discount on oldest two. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 4 + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + sc_ccap_second_child_discount_rate: 0.15 + person3: + age: 2 + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + sc_ccap_second_child_discount_rate: 0.15 + person4: + age: 0 + childcare_hours_per_week: 30 + sc_ccap_provider_type: CENTER + sc_ccap_quality_level: C + sc_ccap_second_child_discount_rate: 0.15 + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: SC + sc_ccap_geography: URBAN + output: + # person2 (age 4) = child_index 3 -> discount: $191 * (1 - 0.15) = $162.35 + # person3 (age 2) = child_index 2 -> discount: $205 * (1 - 0.15) = $174.25 + # person4 (age 0) = child_index 1 (youngest) -> no discount: $213 + sc_ccap_maximum_weekly_benefit: [0, 162.35, 174.25, 213] diff --git a/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap_protective_services.yaml b/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap_protective_services.yaml new file mode 100644 index 00000000000..ff155b020bb --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap_protective_services.yaml @@ -0,0 +1,79 @@ +# SC CCAP protective services category tests +# sc_ccap_protective_services is SPMUnit, MONTH +# True when family has foster child, is homeless, or has child +# receiving/needing protective services (Section 2.4, p.65) + +- name: Case 1, foster child triggers protective services. + period: 2025-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + is_in_foster_care: true + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: SC + output: + sc_ccap_protective_services: true + +- name: Case 2, homeless family triggers protective services. + period: 2025-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: SC + is_homeless: true + output: + sc_ccap_protective_services: true + +- name: Case 3, child receiving protective services. + period: 2025-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + receives_or_needs_protective_services: true + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: SC + output: + sc_ccap_protective_services: true + +- name: Case 4, no protective services indicators. + period: 2025-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: SC + output: + sc_ccap_protective_services: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap_time_category.yaml b/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap_time_category.yaml new file mode 100644 index 00000000000..1439a0f5575 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/sc_ccap_time_category.yaml @@ -0,0 +1,80 @@ +# SC CCAP time category tests +# sc_ccap_time_category is Person, derived from childcare_hours_per_week + +- name: Case 1, full time at 30 hours per week. + period: 2025 + input: + people: + person1: + childcare_hours_per_week: 30 + households: + household: + members: [person1] + state_code: SC + output: + sc_ccap_time_category: [FULL_TIME] + +- name: Case 2, half time at 20 hours per week. + period: 2025 + input: + people: + person1: + childcare_hours_per_week: 20 + households: + household: + members: [person1] + state_code: SC + output: + sc_ccap_time_category: [HALF_TIME] + +- name: Case 3, full time at exactly 25 hours per week. + period: 2025 + input: + people: + person1: + childcare_hours_per_week: 25 + households: + household: + members: [person1] + state_code: SC + output: + sc_ccap_time_category: [FULL_TIME] + +- name: Case 4, half time at 24 hours per week. + period: 2025 + input: + people: + person1: + childcare_hours_per_week: 24 + households: + household: + members: [person1] + state_code: SC + output: + sc_ccap_time_category: [HALF_TIME] + +- name: Case 5, full time at 40 hours per week. + period: 2025 + input: + people: + person1: + childcare_hours_per_week: 40 + households: + household: + members: [person1] + state_code: SC + output: + sc_ccap_time_category: [FULL_TIME] + +- name: Case 6, zero hours defaults to half time. + period: 2025 + input: + people: + person1: + childcare_hours_per_week: 0 + households: + household: + members: [person1] + state_code: SC + output: + sc_ccap_time_category: [HALF_TIME] diff --git a/policyengine_us/variables/gov/states/sc/dss/ccap/copay/sc_ccap_copay.py b/policyengine_us/variables/gov/states/sc/dss/ccap/copay/sc_ccap_copay.py new file mode 100644 index 00000000000..cddd49a59c4 --- /dev/null +++ b/policyengine_us/variables/gov/states/sc/dss/ccap/copay/sc_ccap_copay.py @@ -0,0 +1,134 @@ +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 sc_ccap_copay(Variable): + value_type = float + entity = SPMUnit + unit = USD + label = "South Carolina CCAP monthly family copay" + definition_period = MONTH + defined_for = StateCode.SC + reference = ( + "https://www.scchildcare.org/media/ubhdm1at/1-13-2025_policy-manual.pdf#page=86", + "https://www.scchildcare.org/media/n3qmcb5u/sc-child-care-scholarship-program-fee-scale-2023-2024.pdf#page=1", + "https://www.scchildcare.org/media/ih2mrjw5/fee-scale-2025-2026.pdf#page=1", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.sc.dss.ccap.copay + monthly_income = spm_unit("sc_ccap_countable_income", period) + tier_count = len(p.smi_tier_ratios.thresholds) + + size = spm_unit("spm_unit_size", period.this_year) + max_size = int(p.max_family_size) + fee_scale_size = min_(size, max_size) + + state = spm_unit.household("state_code_str", period) + state_group = spm_unit.household("state_group_str", period) + + # Family-level copay exemptions (Section 3.4.2, p.108). + # Head Start copay waiver is per-child, handled below. + protective = spm_unit("sc_ccap_protective_services", period) + is_tanf = spm_unit("is_tanf_enrolled", period) + p_elig = parameters(period).gov.states.sc.dss.ccap.eligibility + person = spm_unit.members + is_disabled = person("is_disabled", period.this_year) + is_young = person("age", period.this_year) < p_elig.disabled_child_age_limit + is_dependent = person("is_tax_unit_dependent", period.this_year) + has_disabled_child = spm_unit.any(is_disabled & is_young & is_dependent) + + # Compute copay tier from income position in the fee scale. + # Pre-2024-10-01: tiers at fixed SMI ratios (45/55/65/75% mark + # boundaries between 5 tiers). + # Post-2024-10-01: equal-width bands from 150% FPL to 85% SMI. + tier = np.zeros_like(monthly_income, dtype=int) + below_fpl_threshold = np.zeros_like(monthly_income, dtype=bool) + zero_only_row = np.zeros_like(monthly_income, dtype=bool) + if p.fpg_exempt_in_effect: + max_paid_size = int(p.max_paid_family_size) + zero_only_row = fee_scale_size > max_paid_size + + # Rows 15-16 are $0-only on the published fee scale. For rows with + # paid tiers, fall back to the largest published paid-tier size + # whose derived 150% FPL and 85% SMI bounds still form a + # nonnegative band. + paid_band_size = np.ones_like(size, dtype=int) + for candidate in range(1, max_paid_size + 1): + lower_candidate = np.floor( + fpg(candidate, state_group, period, parameters) + / MONTHS_IN_YEAR + * p.fpg_exempt_rate + + 0.5 + ) + upper_candidate = np.floor( + smi(candidate, state, period, parameters) + / MONTHS_IN_YEAR + * p.smi_tier_ratios.calc(tier_count) + + 0.5 + ) + valid_candidate = (fee_scale_size >= candidate) & ( + lower_candidate <= upper_candidate + ) + paid_band_size = where( + valid_candidate, + candidate, + paid_band_size, + ) + + monthly_fpg = ( + fpg(paid_band_size, state_group, period, parameters) / MONTHS_IN_YEAR + ) + monthly_smi = ( + smi(paid_band_size, state, period, parameters) / MONTHS_IN_YEAR + ) + lower = np.floor(monthly_fpg * p.fpg_exempt_rate + 0.5) + upper = np.floor(monthly_smi * p.smi_tier_ratios.calc(tier_count) + 0.5) + band_width = np.ceil((upper - lower) / tier_count) + below_fpl_threshold = (~zero_only_row) & (monthly_income <= lower) + for i in range(1, tier_count): + threshold = lower + band_width * i + tier = tier + ((~zero_only_row) & (monthly_income > threshold)).astype( + int + ) + else: + monthly_smi = ( + smi(fee_scale_size, state, period, parameters) / MONTHS_IN_YEAR + ) + for i in range(1, tier_count): + ratio = p.smi_tier_ratios.calc(i) + threshold = np.floor(monthly_smi * ratio + 0.5) + tier = tier + (monthly_income > threshold).astype(int) + + exempt = protective | is_tanf | below_fpl_threshold | has_disabled_child + + weekly_copay_per_child = where( + zero_only_row, + 0, + p.weekly_amounts.calc(tier + 1), + ) + + # Head Start children have no copay (Section 2.15); only count + # non-Head-Start eligible children for the copay calculation. + # Non-Head-Start children are only covered when the unit qualifies + # through the standard or protective pathway (income + activity + # or protective services). Head Start-only units pay $0. + is_eligible = person("sc_ccap_eligible_child", period) + is_head_start = person("is_enrolled_in_head_start", period.this_year) + in_care = person("childcare_hours_per_week", period) > 0 + income_eligible = spm_unit("sc_ccap_income_eligible", period) + activity_eligible = spm_unit("sc_ccap_activity_eligible", period) + covers_non_hs = (income_eligible & activity_eligible) | protective + num_paying = where( + covers_non_hs, + spm_unit.sum(is_eligible & ~is_head_start & in_care), + 0, + ) + uncapped_monthly = ( + weekly_copay_per_child * num_paying * (WEEKS_IN_YEAR / MONTHS_IN_YEAR) + ) + # Cap total family copay at 2% of monthly income. + monthly_income_cap = monthly_income * p.income_cap_rate + monthly_copay = min_(uncapped_monthly, monthly_income_cap) + return where(exempt, 0, monthly_copay) diff --git a/policyengine_us/variables/gov/states/sc/dss/ccap/eligibility/sc_ccap_activity_eligible.py b/policyengine_us/variables/gov/states/sc/dss/ccap/eligibility/sc_ccap_activity_eligible.py new file mode 100644 index 00000000000..96e06a7c832 --- /dev/null +++ b/policyengine_us/variables/gov/states/sc/dss/ccap/eligibility/sc_ccap_activity_eligible.py @@ -0,0 +1,26 @@ +from policyengine_us.model_api import * + + +class sc_ccap_activity_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Eligible for South Carolina CCAP based on activity requirements" + definition_period = MONTH + defined_for = StateCode.SC + reference = ( + "https://www.scchildcare.org/media/ubhdm1at/1-13-2025_policy-manual.pdf#page=22" + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.sc.dss.ccap.eligibility + person = spm_unit.members + is_head_or_spouse = person("is_tax_unit_head_or_spouse", period.this_year) + hours_worked = person("weekly_hours_worked", period.this_year) + meets_work_requirement = hours_worked >= p.activity_hours + is_student = person("is_full_time_student", period.this_year) + # Per Section 2.13, a disabled parent satisfies the activity + # requirement (one parent working/school + other disabled, + # or both parents disabled). + is_disabled = person("is_disabled", period.this_year) + individually_eligible = meets_work_requirement | is_student | is_disabled + return spm_unit.sum(is_head_or_spouse & ~individually_eligible) == 0 diff --git a/policyengine_us/variables/gov/states/sc/dss/ccap/eligibility/sc_ccap_eligible.py b/policyengine_us/variables/gov/states/sc/dss/ccap/eligibility/sc_ccap_eligible.py new file mode 100644 index 00000000000..25108affa81 --- /dev/null +++ b/policyengine_us/variables/gov/states/sc/dss/ccap/eligibility/sc_ccap_eligible.py @@ -0,0 +1,46 @@ +from policyengine_us.model_api import * + + +class sc_ccap_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Eligible for South Carolina CCAP" + definition_period = MONTH + defined_for = StateCode.SC + reference = ( + "https://www.scchildcare.org/media/ubhdm1at/1-13-2025_policy-manual.pdf#page=14", + "https://www.scchildcare.org/media/ubhdm1at/1-13-2025_policy-manual.pdf#page=65", + "https://www.scchildcare.org/media/ubhdm1at/1-13-2025_policy-manual.pdf#page=91", + ) + + def formula(spm_unit, period, parameters): + has_eligible_child = add(spm_unit, period, ["sc_ccap_eligible_child"]) > 0 + income_eligible = spm_unit("sc_ccap_income_eligible", period) + asset_eligible = spm_unit("is_ccdf_asset_eligible", period.this_year) + activity_eligible = spm_unit("sc_ccap_activity_eligible", period) + + # Standard non-welfare low-income pathway (Section 2.13). + standard = ( + has_eligible_child & income_eligible & asset_eligible & activity_eligible + ) + + # Protective services pathway (Section 2.4) — waives copay and + # activity. Section 2.4 does not explicitly waive income; families + # are still subject to the 85% SMI income test. + protective = spm_unit("sc_ccap_protective_services", period) + protective_path = ( + has_eligible_child & income_eligible & asset_eligible & protective + ) + + # Head Start wraparound pathway (Section 2.15) — waives income + # and activity. The Head Start child itself must be CCDF-eligible + # (age + immigration); a sibling's eligibility cannot combine with + # a different child's Head Start enrollment. + person = spm_unit.members + head_start_eligible_child = person("sc_ccap_eligible_child", period) & person( + "is_enrolled_in_head_start", period.this_year + ) + has_head_start_eligible_child = spm_unit.any(head_start_eligible_child) + head_start_path = has_head_start_eligible_child & asset_eligible + + return standard | protective_path | head_start_path diff --git a/policyengine_us/variables/gov/states/sc/dss/ccap/eligibility/sc_ccap_eligible_child.py b/policyengine_us/variables/gov/states/sc/dss/ccap/eligibility/sc_ccap_eligible_child.py new file mode 100644 index 00000000000..d1e0217cb67 --- /dev/null +++ b/policyengine_us/variables/gov/states/sc/dss/ccap/eligibility/sc_ccap_eligible_child.py @@ -0,0 +1,28 @@ +from policyengine_us.model_api import * + + +class sc_ccap_eligible_child(Variable): + value_type = bool + entity = Person + label = "Eligible child for South Carolina CCAP" + definition_period = MONTH + defined_for = StateCode.SC + reference = ( + "https://www.scchildcare.org/media/ubhdm1at/1-13-2025_policy-manual.pdf#page=14", + "https://www.scchildcare.org/media/ubhdm1at/1-13-2025_policy-manual.pdf#page=19", + ) + + def formula(person, period, parameters): + p = parameters(period).gov.states.sc.dss.ccap.eligibility + age = person("age", period.this_year) + is_disabled = person("is_disabled", period.this_year) + age_eligible = where( + is_disabled, + age < p.disabled_child_age_limit, + age < p.child_age_limit, + ) + immigration_eligible = person( + "is_ccdf_immigration_eligible_child", period.this_year + ) + is_dependent = person("is_tax_unit_dependent", period.this_year) + return age_eligible & immigration_eligible & is_dependent diff --git a/policyengine_us/variables/gov/states/sc/dss/ccap/eligibility/sc_ccap_income_eligible.py b/policyengine_us/variables/gov/states/sc/dss/ccap/eligibility/sc_ccap_income_eligible.py new file mode 100644 index 00000000000..aa9e6c01126 --- /dev/null +++ b/policyengine_us/variables/gov/states/sc/dss/ccap/eligibility/sc_ccap_income_eligible.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * + + +class sc_ccap_income_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Eligible for South Carolina CCAP based on income" + definition_period = MONTH + defined_for = StateCode.SC + reference = ( + "https://www.scchildcare.org/media/ubhdm1at/1-13-2025_policy-manual.pdf#page=37", + "https://www.scchildcare.org/media/cr5dc51w/submitted-version-of-the-ccdf-ffy-2025-2027-for-south-carolina-as-of-7-1-24pdf.pdf#page=17", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.sc.dss.ccap.income + countable_income = spm_unit("sc_ccap_countable_income", period) + smi = spm_unit("hhs_smi", period) + return countable_income <= smi * p.smi_rate diff --git a/policyengine_us/variables/gov/states/sc/dss/ccap/eligibility/sc_ccap_protective_services.py b/policyengine_us/variables/gov/states/sc/dss/ccap/eligibility/sc_ccap_protective_services.py new file mode 100644 index 00000000000..7b44b9e2323 --- /dev/null +++ b/policyengine_us/variables/gov/states/sc/dss/ccap/eligibility/sc_ccap_protective_services.py @@ -0,0 +1,26 @@ +from policyengine_us.model_api import * + + +class sc_ccap_protective_services(Variable): + value_type = bool + entity = SPMUnit + label = "South Carolina CCAP protective services category" + definition_period = MONTH + defined_for = StateCode.SC + reference = ( + "https://www.scchildcare.org/media/ubhdm1at/1-13-2025_policy-manual.pdf#page=65", + "https://www.scchildcare.org/media/ubhdm1at/1-13-2025_policy-manual.pdf#page=108", + ) + + def formula(spm_unit, period, parameters): + has_foster_child = add(spm_unit, period, ["is_in_foster_care"]) > 0 + is_homeless = spm_unit.household("is_homeless", period.this_year) + has_protective_child = ( + add( + spm_unit, + period.this_year, + ["receives_or_needs_protective_services"], + ) + > 0 + ) + return has_foster_child | is_homeless | has_protective_child diff --git a/policyengine_us/variables/gov/states/sc/dss/ccap/sc_ccap.py b/policyengine_us/variables/gov/states/sc/dss/ccap/sc_ccap.py new file mode 100644 index 00000000000..442592ebfa3 --- /dev/null +++ b/policyengine_us/variables/gov/states/sc/dss/ccap/sc_ccap.py @@ -0,0 +1,28 @@ +from policyengine_us.model_api import * + + +class sc_ccap(Variable): + value_type = float + entity = SPMUnit + unit = USD + label = "South Carolina CCAP benefit amount" + definition_period = MONTH + defined_for = "sc_ccap_eligible" + reference = ( + "https://www.scchildcare.org/media/ubhdm1at/1-13-2025_policy-manual.pdf#page=183", + "https://www.scchildcare.org/media/cr5dc51w/submitted-version-of-the-ccdf-ffy-2025-2027-for-south-carolina-as-of-7-1-24pdf.pdf#page=17", + ) + + def formula(spm_unit, period, parameters): + copay = spm_unit("sc_ccap_copay", period) + maximum_weekly_benefit = add( + spm_unit, period, ["sc_ccap_maximum_weekly_benefit"] + ) + maximum_monthly_benefit = maximum_weekly_benefit * ( + WEEKS_IN_YEAR / MONTHS_IN_YEAR + ) + pre_subsidy_childcare_expenses = spm_unit( + "spm_unit_pre_subsidy_childcare_expenses", period + ) + uncapped = max_(pre_subsidy_childcare_expenses - copay, 0) + return min_(uncapped, maximum_monthly_benefit) diff --git a/policyengine_us/variables/gov/states/sc/dss/ccap/sc_ccap_age_group.py b/policyengine_us/variables/gov/states/sc/dss/ccap/sc_ccap_age_group.py new file mode 100644 index 00000000000..ae295c3e28e --- /dev/null +++ b/policyengine_us/variables/gov/states/sc/dss/ccap/sc_ccap_age_group.py @@ -0,0 +1,37 @@ +from policyengine_us.model_api import * + + +class SCCCAPAgeGroup(Enum): + UNDER_1 = "Under 1" + AGE_1 = "Age 1" + AGE_2 = "Age 2" + AGE_3 = "Age 3" + AGE_4 = "Age 4" + AGE_5_NOT_IN_K = "Age 5, Not in Kindergarten" + AGE_5_12_IN_SCHOOL = "Age 5-12, In School" + + +class sc_ccap_age_group(Variable): + value_type = Enum + entity = Person + possible_values = SCCCAPAgeGroup + default_value = SCCCAPAgeGroup.AGE_5_12_IN_SCHOOL + definition_period = MONTH + label = "South Carolina CCAP child age group for payment rates" + defined_for = StateCode.SC + reference = "https://www.scchildcare.org/media/vwybydmg/child-care-scholarship-maximum-payments-allowed-ffy2023-pdf.pdf#page=1" + + def formula(person, period, parameters): + age = person("age", period.this_year) + is_in_school = person("is_in_k12_school", period.this_year) + p = parameters(period).gov.states.sc.dss.ccap.age_group + age_index = p.age.calc(age) + # age_index 0-4 map directly to UNDER_1 through AGE_4. + # age_index 5 = exactly age 5: if in school -> AGE_5_12_IN_SCHOOL (6), + # else -> AGE_5_NOT_IN_K (5). + # age_index 6 = age 6+: always AGE_5_12_IN_SCHOOL (6). + return where( + (age_index == 5) & ~is_in_school, + 5, + where(age_index >= 5, 6, age_index), + ) diff --git a/policyengine_us/variables/gov/states/sc/dss/ccap/sc_ccap_countable_income.py b/policyengine_us/variables/gov/states/sc/dss/ccap/sc_ccap_countable_income.py new file mode 100644 index 00000000000..e94624b07ee --- /dev/null +++ b/policyengine_us/variables/gov/states/sc/dss/ccap/sc_ccap_countable_income.py @@ -0,0 +1,16 @@ +from policyengine_us.model_api import * + + +class sc_ccap_countable_income(Variable): + value_type = float + entity = SPMUnit + label = "South Carolina CCAP countable income" + definition_period = MONTH + unit = USD + defined_for = StateCode.SC + reference = ( + "https://www.scchildcare.org/media/ubhdm1at/1-13-2025_policy-manual.pdf#page=32", + "https://www.scchildcare.org/media/ubhdm1at/1-13-2025_policy-manual.pdf#page=33", + ) + + adds = "gov.states.sc.dss.ccap.income.countable_income.sources" diff --git a/policyengine_us/variables/gov/states/sc/dss/ccap/sc_ccap_geography.py b/policyengine_us/variables/gov/states/sc/dss/ccap/sc_ccap_geography.py new file mode 100644 index 00000000000..626f80b98c9 --- /dev/null +++ b/policyengine_us/variables/gov/states/sc/dss/ccap/sc_ccap_geography.py @@ -0,0 +1,27 @@ +from policyengine_us.model_api import * + + +class SCCCAPGeography(Enum): + URBAN = "Urban" + RURAL = "Rural" + + +class sc_ccap_geography(Variable): + value_type = Enum + entity = Household + possible_values = SCCCAPGeography + default_value = SCCCAPGeography.RURAL + definition_period = YEAR + label = "South Carolina CCAP urban or rural county designation" + defined_for = StateCode.SC + reference = "https://www.scchildcare.org/media/ubhdm1at/1-13-2025_policy-manual.pdf#page=198" + + def formula(household, period, parameters): + county = household("county_str", period) + p = parameters(period).gov.states.sc.dss.ccap.geography + is_urban = np.isin(county, p.urban_counties) + return where( + is_urban, + SCCCAPGeography.URBAN, + SCCCAPGeography.RURAL, + ) diff --git a/policyengine_us/variables/gov/states/sc/dss/ccap/sc_ccap_maximum_weekly_benefit.py b/policyengine_us/variables/gov/states/sc/dss/ccap/sc_ccap_maximum_weekly_benefit.py new file mode 100644 index 00000000000..28005e80eae --- /dev/null +++ b/policyengine_us/variables/gov/states/sc/dss/ccap/sc_ccap_maximum_weekly_benefit.py @@ -0,0 +1,106 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.states.sc.dss.ccap.sc_ccap_provider_type import ( + SCCCAPProviderType, +) + + +class sc_ccap_maximum_weekly_benefit(Variable): + value_type = float + entity = Person + unit = USD + label = "South Carolina CCAP maximum weekly benefit per child" + definition_period = MONTH + defined_for = "sc_ccap_eligible_child" + reference = ( + "https://www.scchildcare.org/media/vwybydmg/child-care-scholarship-maximum-payments-allowed-ffy2023-pdf.pdf#page=1", + "https://www.scchildcare.org/media/ubhdm1at/1-13-2025_policy-manual.pdf#page=183", + ) + + def formula(person, period, parameters): + p = parameters(period).gov.states.sc.dss.ccap + provider_type = person("sc_ccap_provider_type", period) + time_category = person("sc_ccap_time_category", period) + age_group = person("sc_ccap_age_group", period) + geography = person.household("sc_ccap_geography", period.this_year) + + quality = person("sc_ccap_quality_level", period) + reg_quality = person("sc_ccap_registered_quality_level", period) + + rates = p.rates + # Centers, exempt centers, group homes, and licensed family homes + # all use the same 4-dimensional breakdown: + # time_category x quality_level x age_group x geography. + center_rate = rates.center[time_category][quality][age_group][geography] + exempt_center_rate = rates.exempt_center[time_category][quality][age_group][ + geography + ] + group_home_rate = rates.group_home[time_category][quality][age_group][geography] + licensed_family_rate = rates.licensed_family_home[time_category][quality][ + age_group + ][geography] + # Registered family homes have a reduced quality scale (B+, B, C). + registered_family_rate = rates.registered_family_home[time_category][ + reg_quality + ][age_group][geography] + # FFN has no quality level or geography dimension. + ffn_rate = rates.ffn[time_category][age_group] + + base_rate = select( + [ + provider_type == SCCCAPProviderType.CENTER, + provider_type == SCCCAPProviderType.EXEMPT_CENTER, + provider_type == SCCCAPProviderType.GROUP_HOME, + provider_type == SCCCAPProviderType.LICENSED_FAMILY_HOME, + provider_type == SCCCAPProviderType.REGISTERED_FAMILY_HOME, + provider_type == SCCCAPProviderType.FFN, + ], + [ + center_rate, + exempt_center_rate, + group_home_rate, + licensed_family_rate, + registered_family_rate, + ffn_rate, + ], + ) + + # Apply provider-determined second child discount. + # Per Policy Manual 5.11 (p.137), the discount applies per-facility + # to all children except the youngest at that facility. We assume + # all children use the same provider as a simplification. + # Only children actually in care count for the youngest determination. + discount_rate = person("sc_ccap_second_child_discount_rate", period) + in_care = person("childcare_hours_per_week", period) > 0 + child_index = person("child_index", period.this_year) + in_care_index = where(in_care, child_index, -1) + max_in_care_index = person.spm_unit.max(in_care_index) + is_not_youngest = in_care & (child_index < max_in_care_index) + discounted_rate = where( + is_not_youngest, + base_rate * (1 - discount_rate), + base_rate, + ) + + # Add surcharges for special needs and foster care children. + is_disabled = person("is_disabled", period.this_year) + is_foster = person("is_in_foster_care", period) + special_needs_surcharge = where(is_disabled, p.surcharge.special_needs, 0) + foster_surcharge = where(is_foster, p.surcharge.foster_care, 0) + + rate = discounted_rate + special_needs_surcharge + foster_surcharge + + # Head Start pathway only covers the enrolled child (Section 2.15). + # Non-Head-Start children need the family to qualify through + # standard or protective pathway. + is_head_start = person("is_enrolled_in_head_start", period.this_year) + income_eligible = person.spm_unit("sc_ccap_income_eligible", period) + asset_eligible = person.spm_unit("is_ccdf_asset_eligible", period.this_year) + activity_eligible = person.spm_unit("sc_ccap_activity_eligible", period) + protective = person.spm_unit("sc_ccap_protective_services", period) + standard_or_protective = ( + income_eligible & asset_eligible & (activity_eligible | protective) + ) + child_covered = is_head_start | standard_or_protective + in_care = person("childcare_hours_per_week", period) > 0 + + return where(child_covered & in_care, rate, 0) diff --git a/policyengine_us/variables/gov/states/sc/dss/ccap/sc_ccap_provider_type.py b/policyengine_us/variables/gov/states/sc/dss/ccap/sc_ccap_provider_type.py new file mode 100644 index 00000000000..3ec7eb40d7c --- /dev/null +++ b/policyengine_us/variables/gov/states/sc/dss/ccap/sc_ccap_provider_type.py @@ -0,0 +1,21 @@ +from policyengine_us.model_api import * + + +class SCCCAPProviderType(Enum): + CENTER = "Child Care Center" + EXEMPT_CENTER = "Exempt/Waivered Center" + GROUP_HOME = "Group Child Care Home" + LICENSED_FAMILY_HOME = "Licensed Family Child Care Home" + REGISTERED_FAMILY_HOME = "Registered Family Child Care Home" + FFN = "Family, Friend, and Neighbor" + + +class sc_ccap_provider_type(Variable): + value_type = Enum + entity = Person + possible_values = SCCCAPProviderType + default_value = SCCCAPProviderType.CENTER + definition_period = MONTH + label = "South Carolina CCAP child care provider type" + defined_for = StateCode.SC + reference = "https://www.scchildcare.org/media/vwybydmg/child-care-scholarship-maximum-payments-allowed-ffy2023-pdf.pdf#page=1" diff --git a/policyengine_us/variables/gov/states/sc/dss/ccap/sc_ccap_quality_level.py b/policyengine_us/variables/gov/states/sc/dss/ccap/sc_ccap_quality_level.py new file mode 100644 index 00000000000..635e93e013e --- /dev/null +++ b/policyengine_us/variables/gov/states/sc/dss/ccap/sc_ccap_quality_level.py @@ -0,0 +1,20 @@ +from policyengine_us.model_api import * + + +class SCCCAPQualityLevel(Enum): + A_PLUS = "Level A+ (NAC)" + A = "Level A (ERS)" + B_PLUS = "Level B+ (EPC)" + B = "Level B (ECR)" + C = "Level C (LRC)" + + +class sc_ccap_quality_level(Variable): + value_type = Enum + entity = Person + possible_values = SCCCAPQualityLevel + default_value = SCCCAPQualityLevel.C + definition_period = MONTH + label = "South Carolina CCAP provider quality level" + defined_for = StateCode.SC + reference = "https://www.scchildcare.org/media/vwybydmg/child-care-scholarship-maximum-payments-allowed-ffy2023-pdf.pdf#page=1" diff --git a/policyengine_us/variables/gov/states/sc/dss/ccap/sc_ccap_registered_quality_level.py b/policyengine_us/variables/gov/states/sc/dss/ccap/sc_ccap_registered_quality_level.py new file mode 100644 index 00000000000..012c10a22e3 --- /dev/null +++ b/policyengine_us/variables/gov/states/sc/dss/ccap/sc_ccap_registered_quality_level.py @@ -0,0 +1,18 @@ +from policyengine_us.model_api import * + + +class SCCCAPRegisteredQualityLevel(Enum): + B_PLUS = "Level B+ (EPC)" + B = "Level B (ECR)" + C = "Level C (LRC)" + + +class sc_ccap_registered_quality_level(Variable): + value_type = Enum + entity = Person + possible_values = SCCCAPRegisteredQualityLevel + default_value = SCCCAPRegisteredQualityLevel.C + definition_period = MONTH + label = "South Carolina CCAP registered family home quality level" + defined_for = StateCode.SC + reference = "https://www.scchildcare.org/media/vwybydmg/child-care-scholarship-maximum-payments-allowed-ffy2023-pdf.pdf#page=11" diff --git a/policyengine_us/variables/gov/states/sc/dss/ccap/sc_ccap_second_child_discount_rate.py b/policyengine_us/variables/gov/states/sc/dss/ccap/sc_ccap_second_child_discount_rate.py new file mode 100644 index 00000000000..92e53e8049d --- /dev/null +++ b/policyengine_us/variables/gov/states/sc/dss/ccap/sc_ccap_second_child_discount_rate.py @@ -0,0 +1,11 @@ +from policyengine_us.model_api import * + + +class sc_ccap_second_child_discount_rate(Variable): + value_type = float + entity = Person + unit = "/1" + label = "South Carolina CCAP provider-determined second child discount rate" + definition_period = MONTH + defined_for = StateCode.SC + reference = "https://www.scchildcare.org/media/ubhdm1at/1-13-2025_policy-manual.pdf#page=137" diff --git a/policyengine_us/variables/gov/states/sc/dss/ccap/sc_ccap_time_category.py b/policyengine_us/variables/gov/states/sc/dss/ccap/sc_ccap_time_category.py new file mode 100644 index 00000000000..d16e8f07af7 --- /dev/null +++ b/policyengine_us/variables/gov/states/sc/dss/ccap/sc_ccap_time_category.py @@ -0,0 +1,30 @@ +from policyengine_us.model_api import * + + +class SCCCAPTimeCategory(Enum): + HALF_TIME = "Half Time" + FULL_TIME = "Full Time" + + +class sc_ccap_time_category(Variable): + value_type = Enum + entity = Person + possible_values = SCCCAPTimeCategory + default_value = SCCCAPTimeCategory.FULL_TIME + definition_period = MONTH + label = "South Carolina CCAP care schedule category" + defined_for = StateCode.SC + reference = "https://www.scchildcare.org/media/vwybydmg/child-care-scholarship-maximum-payments-allowed-ffy2023-pdf.pdf#page=1" + + def formula(person, period, parameters): + hours = person("childcare_hours_per_week", period.this_year) + p = parameters(period).gov.states.sc.dss.ccap.time_category + standard_category = p.hours.calc(hours) + # Per Section 2.15, Head Start children are paid part-time + # while enrolled to extend the Head Start day. + is_head_start = person("is_enrolled_in_head_start", period.this_year) + return where( + is_head_start, + SCCCAPTimeCategory.HALF_TIME, + standard_category, + ) diff --git a/policyengine_us/variables/gov/states/sc/dss/ccap/sc_child_care_subsidies.py b/policyengine_us/variables/gov/states/sc/dss/ccap/sc_child_care_subsidies.py new file mode 100644 index 00000000000..7987a2dbdf0 --- /dev/null +++ b/policyengine_us/variables/gov/states/sc/dss/ccap/sc_child_care_subsidies.py @@ -0,0 +1,11 @@ +from policyengine_us.model_api import * + + +class sc_child_care_subsidies(Variable): + value_type = float + entity = SPMUnit + label = "South Carolina child care subsidies" + unit = USD + definition_period = YEAR + defined_for = StateCode.SC + adds = ["sc_ccap"] diff --git a/policyengine_us/variables/household/demographic/person/is_enrolled_in_head_start.py b/policyengine_us/variables/household/demographic/person/is_enrolled_in_head_start.py new file mode 100644 index 00000000000..d17298976d4 --- /dev/null +++ b/policyengine_us/variables/household/demographic/person/is_enrolled_in_head_start.py @@ -0,0 +1,8 @@ +from policyengine_us.model_api import * + + +class is_enrolled_in_head_start(Variable): + value_type = bool + entity = Person + label = "Enrolled in a Head Start or Early Head Start program" + definition_period = YEAR