diff --git a/changelog.d/added/8359.md b/changelog.d/added/8359.md new file mode 100644 index 00000000000..2a961c84193 --- /dev/null +++ b/changelog.d/added/8359.md @@ -0,0 +1 @@ +Add San Mateo County General Assistance. diff --git a/changelog.d/fixed/8360.md b/changelog.d/fixed/8360.md new file mode 100644 index 00000000000..d4319ea0c9f --- /dev/null +++ b/changelog.d/fixed/8360.md @@ -0,0 +1 @@ +Fix Alameda County General Assistance county-string check and program registry parameter prefix. diff --git a/policyengine_us/parameters/gov/local/ca/smc/general_assistance/income/earned_income_deduction_rate.yaml b/policyengine_us/parameters/gov/local/ca/smc/general_assistance/income/earned_income_deduction_rate.yaml new file mode 100644 index 00000000000..7bfd4276a99 --- /dev/null +++ b/policyengine_us/parameters/gov/local/ca/smc/general_assistance/income/earned_income_deduction_rate.yaml @@ -0,0 +1,12 @@ +description: San Mateo County deducts this share of earned income from countable income under the General Assistance program, aligning with CalFresh earned income deduction rules. +values: + 2022-03-01: 0.2 +metadata: + unit: /1 + period: year + label: San Mateo County General Assistance earned income deduction rate + reference: + - title: San Mateo County Board Resolution 21-720, Modification of GA Rules and Regulations, Item E + href: https://sanmateocounty.legistar.com/View.ashx?GUID=25359405-C9EB-4566-AE97-D927CC455B02&ID=9802358&M=F#page=2 + - title: 7 CFR 273.9(d)(2), CalFresh (SNAP) Earned Income Deduction + href: https://www.ecfr.gov/current/title-7/subtitle-B/chapter-II/subchapter-C/part-273/subpart-D/section-273.9#p-273.9(d)(2) diff --git a/policyengine_us/parameters/gov/local/ca/smc/general_assistance/income/earned_sources.yaml b/policyengine_us/parameters/gov/local/ca/smc/general_assistance/income/earned_sources.yaml new file mode 100644 index 00000000000..370524216b2 --- /dev/null +++ b/policyengine_us/parameters/gov/local/ca/smc/general_assistance/income/earned_sources.yaml @@ -0,0 +1,13 @@ +description: San Mateo County treats these income sources as earned income for the CalFresh-aligned earned income deduction under the General Assistance program. +values: + 2022-03-01: + - employment_income + - self_employment_income + - sstb_self_employment_income +metadata: + unit: list + period: year + label: San Mateo County General Assistance earned income sources + reference: + - title: San Mateo County Board Resolution 21-720, Modification of GA Rules and Regulations, Item E + href: https://sanmateocounty.legistar.com/View.ashx?GUID=25359405-C9EB-4566-AE97-D927CC455B02&ID=9802358&M=F#page=2 diff --git a/policyengine_us/parameters/gov/local/ca/smc/general_assistance/income/sources.yaml b/policyengine_us/parameters/gov/local/ca/smc/general_assistance/income/sources.yaml new file mode 100644 index 00000000000..4e97b6ff8d5 --- /dev/null +++ b/policyengine_us/parameters/gov/local/ca/smc/general_assistance/income/sources.yaml @@ -0,0 +1,28 @@ +description: San Mateo County counts these income sources under the General Assistance program. +values: + 2023-10-01: + - employment_income + - self_employment_income + - sstb_self_employment_income + - unemployment_compensation + - workers_compensation + - disability_benefits + - ca_state_disability_insurance + - social_security + - veterans_benefits + - pension_income + - retirement_distributions + - interest_income + - dividend_income + - rental_income + - child_support_received + - alimony_income +metadata: + unit: list + period: year + label: San Mateo County General Assistance income sources + reference: + - title: San Mateo County Human Services Agency General Assistance Program Fact Sheet, Income Limits for Applicants + href: https://www.smcgov.org/media/153295/download?inline=#page=2 + - title: San Mateo County Human Services Agency General Assistance, What do I need to apply? + href: https://www.smcgov.org/hsa/general-assistance-ga diff --git a/policyengine_us/parameters/gov/local/ca/smc/general_assistance/minimum_age.yaml b/policyengine_us/parameters/gov/local/ca/smc/general_assistance/minimum_age.yaml new file mode 100644 index 00000000000..2f8819f76ba --- /dev/null +++ b/policyengine_us/parameters/gov/local/ca/smc/general_assistance/minimum_age.yaml @@ -0,0 +1,10 @@ +description: San Mateo County requires an applicant to be at least this age under the General Assistance program. +values: + 2023-10-01: 18 +metadata: + unit: year + period: year + label: San Mateo County General Assistance minimum age + reference: + - title: San Mateo County Human Services Agency General Assistance, What do I need to apply? + href: https://www.smcgov.org/hsa/general-assistance-ga diff --git a/policyengine_us/parameters/gov/local/ca/smc/general_assistance/payment_standard.yaml b/policyengine_us/parameters/gov/local/ca/smc/general_assistance/payment_standard.yaml new file mode 100644 index 00000000000..8e227c960a7 --- /dev/null +++ b/policyengine_us/parameters/gov/local/ca/smc/general_assistance/payment_standard.yaml @@ -0,0 +1,22 @@ +description: San Mateo County provides this maximum monthly payment under the General Assistance program, based on the recipient's living arrangement. +INDEPENDENT_LIVING: + 2023-10-01: 732 +DRUG_ALCOHOL_TREATMENT_CENTER: + 2023-10-01: 732 +NMOHC_WITHOUT_REFERRAL: + 2023-10-01: 732 +NMOHC_WITH_REFERRAL: + # Tracks the California SSI NMOHC rate (CDSS-set, annual COLA on Jan 1). Pre-2025 amounts are not in available sources. + 2025-01-01: 1_599.07 + 2026-01-01: 1_626.07 +metadata: + unit: currency-USD + period: month + breakdown: + - ca_smc_general_assistance_living_arrangement + label: San Mateo County General Assistance payment standard + reference: + - title: San Mateo County Human Services Agency Standards of Assistance, General Assistance + href: https://www.smcgov.org/media/156974/download?inline= + - title: San Mateo County Board File 26-290, Modification to the General Assistance Program Rules and Regulations + href: https://sanmateocounty.legistar.com/ViewReport.ashx?GID=659&GUID=LATEST&ID=94585&M=R&N=TextL5&Title=Board+Memo#page=1 diff --git a/policyengine_us/parameters/gov/local/ca/smc/general_assistance/property/additional_vehicle_combined_equity_limit.yaml b/policyengine_us/parameters/gov/local/ca/smc/general_assistance/property/additional_vehicle_combined_equity_limit.yaml new file mode 100644 index 00000000000..8dcf9ce5fe1 --- /dev/null +++ b/policyengine_us/parameters/gov/local/ca/smc/general_assistance/property/additional_vehicle_combined_equity_limit.yaml @@ -0,0 +1,10 @@ +description: San Mateo County excludes this amount of combined equity in additional vehicles from countable property under the General Assistance program. +values: + 2023-10-01: 2_928 +metadata: + unit: currency-USD + period: year + label: San Mateo County General Assistance additional vehicle combined equity limit + reference: + - title: San Mateo County Board Resolution 21-720, Modification of GA Rules and Regulations, Item B(3) + href: https://sanmateocounty.legistar.com/View.ashx?GUID=25359405-C9EB-4566-AE97-D927CC455B02&ID=9802358&M=F#page=2 diff --git a/policyengine_us/parameters/gov/local/ca/smc/general_assistance/property/limit.yaml b/policyengine_us/parameters/gov/local/ca/smc/general_assistance/property/limit.yaml new file mode 100644 index 00000000000..18eac70c603 --- /dev/null +++ b/policyengine_us/parameters/gov/local/ca/smc/general_assistance/property/limit.yaml @@ -0,0 +1,14 @@ +description: San Mateo County limits property to this amount under the General Assistance program. +values: + 2023-10-01: 1_464 +metadata: + unit: currency-USD + period: year + label: San Mateo County General Assistance property limit + reference: + - title: San Mateo County Human Services Agency Standards of Assistance Chart (C-335), GA Property Limit + href: https://www.smcgov.org/media/156974/download?inline=#page=1 + - title: San Mateo County Human Services Agency General Assistance Program Fact Sheet, Property Limits + href: https://www.smcgov.org/media/153295/download?inline=#page=2 + - title: San Mateo County Board Resolution 21-720, Modification of GA Rules and Regulations, Item B(2) + href: https://sanmateocounty.legistar.com/View.ashx?GUID=25359405-C9EB-4566-AE97-D927CC455B02&ID=9802358&M=F#page=2 diff --git a/policyengine_us/parameters/gov/local/ca/smc/general_assistance/property/sources.yaml b/policyengine_us/parameters/gov/local/ca/smc/general_assistance/property/sources.yaml new file mode 100644 index 00000000000..ac1336dd5c3 --- /dev/null +++ b/policyengine_us/parameters/gov/local/ca/smc/general_assistance/property/sources.yaml @@ -0,0 +1,12 @@ +description: San Mateo County counts these sources as property under the General Assistance program. +values: + 2023-10-01: + - spm_unit_cash_assets + - ca_smc_general_assistance_countable_vehicle_value +metadata: + unit: list + period: year + label: San Mateo County General Assistance property sources + reference: + - title: San Mateo County Human Services Agency General Assistance Program Fact Sheet, Property Limits + href: https://www.smcgov.org/media/153295/download?inline=#page=2 diff --git a/policyengine_us/parameters/gov/local/ca/smc/general_assistance/qualified_immigration_statuses.yaml b/policyengine_us/parameters/gov/local/ca/smc/general_assistance/qualified_immigration_statuses.yaml new file mode 100644 index 00000000000..4677d0eb374 --- /dev/null +++ b/policyengine_us/parameters/gov/local/ca/smc/general_assistance/qualified_immigration_statuses.yaml @@ -0,0 +1,17 @@ +description: San Mateo County limits General Assistance to these immigration statuses. +values: + 2023-10-01: + - CITIZEN + - LEGAL_PERMANENT_RESIDENT + - REFUGEE + - ASYLEE + - DEPORTATION_WITHHELD + - CUBAN_HAITIAN_ENTRANT + - CONDITIONAL_ENTRANT +metadata: + unit: list + period: year + label: San Mateo County General Assistance qualified immigration statuses + reference: + - title: San Mateo County Human Services Agency General Assistance Program Fact Sheet, Immigration Eligibility + href: https://www.smcgov.org/media/153295/download?inline=#page=1 diff --git a/policyengine_us/parameters/gov/local/ca/smc/general_assistance/work_requirement/senior_exemption_age.yaml b/policyengine_us/parameters/gov/local/ca/smc/general_assistance/work_requirement/senior_exemption_age.yaml new file mode 100644 index 00000000000..448c7f917f2 --- /dev/null +++ b/policyengine_us/parameters/gov/local/ca/smc/general_assistance/work_requirement/senior_exemption_age.yaml @@ -0,0 +1,10 @@ +description: San Mateo County exempts people this age or older from the General Assistance work requirement. +values: + 2023-10-01: 65 +metadata: + unit: year + period: year + label: San Mateo County General Assistance work requirement senior exemption age + reference: + - title: San Mateo County Human Services Agency General Assistance Program Fact Sheet, Work Requirement + href: https://www.smcgov.org/media/153295/download?inline=#page=1 diff --git a/policyengine_us/parameters/gov/local/ca/smc/general_assistance/work_requirement/weekly_hours_threshold.yaml b/policyengine_us/parameters/gov/local/ca/smc/general_assistance/work_requirement/weekly_hours_threshold.yaml new file mode 100644 index 00000000000..7a8b6334eef --- /dev/null +++ b/policyengine_us/parameters/gov/local/ca/smc/general_assistance/work_requirement/weekly_hours_threshold.yaml @@ -0,0 +1,12 @@ +description: San Mateo County exempts individuals working at least this many hours per week from the General Assistance work requirement, interpreting the Fact Sheet "Employed full-time" exemption via the CalWORKs full-time work threshold per Resolution 21-720, Item A. +values: + 2023-10-01: 30 +metadata: + unit: hour + period: week + label: San Mateo County General Assistance work requirement weekly hours threshold + reference: + - title: San Mateo County Human Services Agency General Assistance Program Fact Sheet, Work Requirement + href: https://www.smcgov.org/media/153295/download?inline=#page=1 + - title: San Mateo County Board Resolution 21-720, Modification of GA Rules and Regulations, Item A + href: https://sanmateocounty.legistar.com/View.ashx?GUID=25359405-C9EB-4566-AE97-D927CC455B02&ID=9802358&M=F#page=3 diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index 93fa0160641..fe59c90360e 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -1266,7 +1266,18 @@ programs: status: complete coverage: Alameda County variable: ca_ala_general_assistance - parameter_prefix: gov.local.ca.ala.ga + parameter_prefix: gov.local.ca.ala.general_assistance + + - id: ca_smc_general_assistance + name: San Mateo County General Assistance + full_name: San Mateo County General Assistance + category: Benefits + agency: Local + status: complete + coverage: San Mateo County + variable: ca_smc_general_assistance + parameter_prefix: gov.local.ca.smc.general_assistance + verified_start_year: 2025 - id: nyc_income_tax name: NYC income tax diff --git a/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/ca_smc_general_assistance.yaml b/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/ca_smc_general_assistance.yaml new file mode 100644 index 00000000000..22a29789246 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/ca_smc_general_assistance.yaml @@ -0,0 +1,96 @@ +- name: Case 1, eligible single adult receives standard less countable income. + period: 2026-01 + input: + people: + person1: + ca_smc_general_assistance_eligible_person: true + households: + household: + members: [person1] + in_smc: true + spm_units: + spm_unit: + members: [person1] + ca_smc_general_assistance_eligible: true + ca_smc_general_assistance_payment_standard: 732 + ca_smc_general_assistance_countable_income: 200 + output: + ca_smc_general_assistance: 532 + +- name: Case 2, benefit floors at zero when income exceeds standard. + period: 2026-01 + input: + people: + person1: + ca_smc_general_assistance_eligible_person: true + households: + household: + members: [person1] + in_smc: true + spm_units: + spm_unit: + members: [person1] + ca_smc_general_assistance_eligible: true + ca_smc_general_assistance_payment_standard: 732 + ca_smc_general_assistance_countable_income: 800 + output: + ca_smc_general_assistance: 0 + +- name: Case 3, ineligible unit receives zero. + period: 2026-01 + input: + people: + person1: + ca_smc_general_assistance_eligible_person: true + households: + household: + members: [person1] + in_smc: true + spm_units: + spm_unit: + members: [person1] + ca_smc_general_assistance_eligible: false + ca_smc_general_assistance_payment_standard: 732 + ca_smc_general_assistance_countable_income: 0 + output: + ca_smc_general_assistance: 0 + +- name: Case 4, negative countable income floors at zero, benefit caps at standard. + period: 2026-01 + input: + people: + person1: + ca_smc_general_assistance_eligible_person: true + households: + household: + members: [person1] + in_smc: true + spm_units: + spm_unit: + members: [person1] + ca_smc_general_assistance_eligible: true + ca_smc_general_assistance_payment_standard: 732 + ca_smc_general_assistance_countable_income: -200 + output: + ca_smc_general_assistance: 732 + +- name: Case 5, two eligible adults each receive their own benefit at the SPM unit level. + period: 2026-01 + input: + people: + person1: + ca_smc_general_assistance_eligible_person: true + person2: + ca_smc_general_assistance_eligible_person: true + households: + household: + members: [person1, person2] + in_smc: true + spm_units: + spm_unit: + members: [person1, person2] + ca_smc_general_assistance_eligible: true + ca_smc_general_assistance_payment_standard: 732 + ca_smc_general_assistance_countable_income: 400 + output: + ca_smc_general_assistance: 1_064 diff --git a/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_eligible.yaml new file mode 100644 index 00000000000..eea5e236711 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_eligible.yaml @@ -0,0 +1,60 @@ +- name: Case 1, eligible when all modeled tests pass. + period: 2026-01 + input: + in_smc: true + ca_smc_general_assistance_eligible_person: true + ca_smc_general_assistance_income_eligible: true + ca_smc_general_assistance_property_eligible: true + output: + ca_smc_general_assistance_eligible: true + +- name: Case 2, ineligible when immigration test fails. + period: 2026-01 + input: + in_smc: true + ca_smc_general_assistance_eligible_person: false + ca_smc_general_assistance_income_eligible: true + ca_smc_general_assistance_property_eligible: true + output: + ca_smc_general_assistance_eligible: false + +- name: Case 3, ineligible when income test fails. + period: 2026-01 + input: + in_smc: true + ca_smc_general_assistance_eligible_person: true + ca_smc_general_assistance_income_eligible: false + ca_smc_general_assistance_property_eligible: true + output: + ca_smc_general_assistance_eligible: false + +- name: Case 4, ineligible when property test fails. + period: 2026-01 + input: + in_smc: true + ca_smc_general_assistance_eligible_person: true + ca_smc_general_assistance_income_eligible: true + ca_smc_general_assistance_property_eligible: false + output: + ca_smc_general_assistance_eligible: false + +- name: Case 5, ineligible when unit includes a minor child. + period: 2026-01 + input: + people: + person1: + age: 30 + ca_smc_general_assistance_eligible_person: true + person2: + age: 5 + households: + household: + members: [person1, person2] + in_smc: true + spm_units: + spm_unit: + members: [person1, person2] + ca_smc_general_assistance_income_eligible: true + ca_smc_general_assistance_property_eligible: true + output: + ca_smc_general_assistance_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_eligible_person.yaml b/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_eligible_person.yaml new file mode 100644 index 00000000000..1b35ce6e763 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_eligible_person.yaml @@ -0,0 +1,47 @@ +- name: Case 1, adult citizen meeting the work requirement is eligible. + period: 2026-01 + input: + age: 18 + immigration_status: CITIZEN + in_smc: true + is_in_work_program: true + output: + ca_smc_general_assistance_eligible_person: true + +- name: Case 2, child citizen is ineligible. + period: 2026-01 + input: + age: 17 + immigration_status: CITIZEN + in_smc: true + output: + ca_smc_general_assistance_eligible_person: false + +- name: Case 3, adult with ineligible immigration status is ineligible. + period: 2026-01 + input: + age: 30 + immigration_status: UNDOCUMENTED + in_smc: true + output: + ca_smc_general_assistance_eligible_person: false + +- name: Case 4, active SSI recipient is ineligible. + period: 2026-01 + input: + age: 30 + immigration_status: CITIZEN + in_smc: true + ssi: 12_000 + output: + ca_smc_general_assistance_eligible_person: false + +- name: Case 5, SSI-pending applicant (eligible category but not yet receiving) remains eligible. + period: 2026-01 + input: + age: 65 + immigration_status: CITIZEN + in_smc: true + ssi: 0 + output: + ca_smc_general_assistance_eligible_person: true diff --git a/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_immigration_status_eligible_person.yaml b/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_immigration_status_eligible_person.yaml new file mode 100644 index 00000000000..a8f0c578911 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_immigration_status_eligible_person.yaml @@ -0,0 +1,31 @@ +- name: Case 1, citizen is eligible. + period: 2026 + input: + in_smc: true + immigration_status: CITIZEN + output: + ca_smc_general_assistance_immigration_status_eligible_person: true + +- name: Case 2, legal permanent resident is eligible. + period: 2026 + input: + in_smc: true + immigration_status: LEGAL_PERMANENT_RESIDENT + output: + ca_smc_general_assistance_immigration_status_eligible_person: true + +- name: Case 3, refugee is eligible. + period: 2026 + input: + in_smc: true + immigration_status: REFUGEE + output: + ca_smc_general_assistance_immigration_status_eligible_person: true + +- name: Case 4, undocumented person is ineligible. + period: 2026 + input: + in_smc: true + immigration_status: UNDOCUMENTED + output: + ca_smc_general_assistance_immigration_status_eligible_person: false diff --git a/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_income_eligible.yaml new file mode 100644 index 00000000000..90f334a9335 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_income_eligible.yaml @@ -0,0 +1,59 @@ +- name: Case 1, income below payment standard is eligible. + period: 2026-01 + input: + people: + person1: + age: 30 + immigration_status: CITIZEN + is_in_work_program: true + households: + household: + members: [person1] + in_smc: true + spm_units: + spm_unit: + members: [person1] + ca_smc_general_assistance_countable_income: 731 + ca_smc_general_assistance_payment_standard: 732 + output: + ca_smc_general_assistance_income_eligible: true + +- name: Case 2, income at payment standard is ineligible. + period: 2026-01 + input: + people: + person1: + age: 30 + immigration_status: CITIZEN + is_in_work_program: true + households: + household: + members: [person1] + in_smc: true + spm_units: + spm_unit: + members: [person1] + ca_smc_general_assistance_countable_income: 732 + ca_smc_general_assistance_payment_standard: 732 + output: + ca_smc_general_assistance_income_eligible: false + +- name: Case 3, income above payment standard is ineligible. + period: 2026-01 + input: + people: + person1: + age: 30 + immigration_status: CITIZEN + is_in_work_program: true + households: + household: + members: [person1] + in_smc: true + spm_units: + spm_unit: + members: [person1] + ca_smc_general_assistance_countable_income: 733 + ca_smc_general_assistance_payment_standard: 732 + output: + ca_smc_general_assistance_income_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_meets_work_requirements.yaml b/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_meets_work_requirements.yaml new file mode 100644 index 00000000000..21a8df74a7c --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_meets_work_requirements.yaml @@ -0,0 +1,79 @@ +- name: Case 1, able-bodied adult outside any exemption does not meet work requirements. + period: 2026-01 + input: + age: 30 + in_smc: true + weekly_hours_worked_before_lsr: 0 + output: + ca_smc_general_assistance_meets_work_requirements: false + +- name: Case 2, adult working at the full-time threshold meets work requirements. + period: 2026-01 + input: + age: 30 + in_smc: true + weekly_hours_worked_before_lsr: 30 + output: + ca_smc_general_assistance_meets_work_requirements: true + +- name: Case 3, adult working below the full-time threshold does not meet work requirements. + period: 2026-01 + input: + age: 30 + in_smc: true + weekly_hours_worked_before_lsr: 29 + output: + ca_smc_general_assistance_meets_work_requirements: false + +- name: Case 4, senior at the exemption age threshold meets work requirements. + period: 2026-01 + input: + age: 65 + in_smc: true + output: + ca_smc_general_assistance_meets_work_requirements: true + +- name: Case 5, adult just below the senior threshold does not meet work requirements. + period: 2026-01 + input: + age: 64 + in_smc: true + weekly_hours_worked_before_lsr: 0 + output: + ca_smc_general_assistance_meets_work_requirements: false + +- name: Case 6, disabled adult meets work requirements. + period: 2026-01 + input: + age: 30 + in_smc: true + is_disabled: true + output: + ca_smc_general_assistance_meets_work_requirements: true + +- name: Case 7, full-time student meets work requirements. + period: 2026-01 + input: + age: 30 + in_smc: true + is_full_time_student: true + output: + ca_smc_general_assistance_meets_work_requirements: true + +- name: Case 8, adult in a non-English-speaking household meets work requirements. + period: 2026-01 + input: + age: 30 + in_smc: true + is_non_english_speaking_home: true + output: + ca_smc_general_assistance_meets_work_requirements: true + +- name: Case 9, adult participating in the work program meets work requirements. + period: 2026-01 + input: + age: 30 + in_smc: true + is_in_work_program: true + output: + ca_smc_general_assistance_meets_work_requirements: true diff --git a/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_property_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_property_eligible.yaml new file mode 100644 index 00000000000..7686171f80c --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_property_eligible.yaml @@ -0,0 +1,31 @@ +- name: Case 1, property below limit is eligible. + period: 2026 + input: + in_smc: true + ca_smc_general_assistance_countable_property: 1_463 + output: + ca_smc_general_assistance_property_eligible: true + +- name: Case 2, property at limit is ineligible. + period: 2026 + input: + in_smc: true + ca_smc_general_assistance_countable_property: 1_464 + output: + ca_smc_general_assistance_property_eligible: false + +- name: Case 3, property clearly above limit is ineligible. + period: 2026 + input: + in_smc: true + ca_smc_general_assistance_countable_property: 5_000 + output: + ca_smc_general_assistance_property_eligible: false + +- name: Case 4, limit derives from 2x independent living grant in earlier years. + period: 2024 + input: + in_smc: true + ca_smc_general_assistance_countable_property: 1_463 + output: + ca_smc_general_assistance_property_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/income/ca_smc_general_assistance_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/income/ca_smc_general_assistance_countable_income.yaml new file mode 100644 index 00000000000..94db088ae07 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/income/ca_smc_general_assistance_countable_income.yaml @@ -0,0 +1,87 @@ +- name: Case 1, veterans benefits count and SSI does not. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + veterans_benefits: 1_200 + ssi: 1_200 + households: + household: + members: [person1] + in_smc: true + spm_units: + spm_unit: + members: [person1] + output: + ca_smc_general_assistance_countable_income: 100 + +- name: Case 2, earned income receives the 20 percent CalFresh-aligned deduction. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + employment_income: 12_000 + households: + household: + members: [person1] + in_smc: true + spm_units: + spm_unit: + members: [person1] + output: + ca_smc_general_assistance_countable_income: 800 + +- name: Case 3, unearned income receives no earned income deduction. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + rental_income: 12_000 + households: + household: + members: [person1] + in_smc: true + spm_units: + spm_unit: + members: [person1] + output: + ca_smc_general_assistance_countable_income: 1_000 + +- name: Case 4, negative self-employment income flows in without inflating the deduction. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + self_employment_income: -2_400 + households: + household: + members: [person1] + in_smc: true + spm_units: + spm_unit: + members: [person1] + output: + ca_smc_general_assistance_countable_income: -200 + +- name: Case 5, peer-convergence sources (workers compensation, rental income, dividend income) count as unearned. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + workers_compensation: 1_200 + rental_income: 1_200 + dividend_income: 1_200 + households: + household: + members: [person1] + in_smc: true + spm_units: + spm_unit: + members: [person1] + output: + ca_smc_general_assistance_countable_income: 300 diff --git a/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/integration.yaml b/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/integration.yaml new file mode 100644 index 00000000000..a06a3c01c5c --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/integration.yaml @@ -0,0 +1,325 @@ +- name: Case 1, independent living unit with no income receives full standard. + period: 2026-01 + input: + people: + person1: + age: 30 + immigration_status: CITIZEN + is_in_work_program: true + households: + household: + members: [person1] + in_smc: true + spm_units: + spm_unit: + members: [person1] + ca_smc_general_assistance_living_arrangement: INDEPENDENT_LIVING + output: + ca_smc_general_assistance_payment_standard: 732 + ca_smc_general_assistance_eligible: true + ca_smc_general_assistance: 732 + +- name: Case 2, independent living unit with earned income receives reduced benefit after the 20 percent deduction. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 2_400 + immigration_status: CITIZEN + is_in_work_program: true + households: + household: + members: [person1] + in_smc: true + spm_units: + spm_unit: + members: [person1] + ca_smc_general_assistance_living_arrangement: INDEPENDENT_LIVING + output: + ca_smc_general_assistance_countable_income: 160 + ca_smc_general_assistance: 572 + +- name: Case 3, unearned income above independent living standard makes unit ineligible. + period: 2026-01 + input: + people: + person1: + age: 30 + unemployment_compensation: 8_796 + immigration_status: CITIZEN + is_in_work_program: true + households: + household: + members: [person1] + in_smc: true + spm_units: + spm_unit: + members: [person1] + ca_smc_general_assistance_living_arrangement: INDEPENDENT_LIVING + output: + ca_smc_general_assistance_countable_income: 733 + ca_smc_general_assistance_income_eligible: false + ca_smc_general_assistance: 0 + +- name: Case 4, NMOHC with referral uses 2025 standard. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + immigration_status: LEGAL_PERMANENT_RESIDENT + is_in_work_program: true + households: + household: + members: [person1] + in_smc: true + spm_units: + spm_unit: + members: [person1] + ca_smc_general_assistance_living_arrangement: NMOHC_WITH_REFERRAL + output: + ca_smc_general_assistance: 1_599.07 + +- name: Case 5, NMOHC with referral uses 2026 standard and offsets income. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 3_000 + immigration_status: REFUGEE + is_in_work_program: true + households: + household: + members: [person1] + in_smc: true + spm_units: + spm_unit: + members: [person1] + ca_smc_general_assistance_living_arrangement: NMOHC_WITH_REFERRAL + output: + ca_smc_general_assistance_payment_standard: 1_626.07 + ca_smc_general_assistance_countable_income: 200 + ca_smc_general_assistance: 1_426.07 + +- name: Case 6, property at limit makes unit ineligible. + period: 2026-01 + input: + people: + person1: + age: 30 + immigration_status: CITIZEN + households: + household: + members: [person1] + in_smc: true + spm_units: + spm_unit: + members: [person1] + spm_unit_cash_assets: 1_464 + ca_smc_general_assistance_living_arrangement: INDEPENDENT_LIVING + output: + ca_smc_general_assistance_property_eligible: false + ca_smc_general_assistance: 0 + +- name: Case 7, one vehicle is excluded from property. + period: 2026-01 + input: + people: + person1: + age: 30 + immigration_status: CITIZEN + is_in_work_program: true + households: + household: + members: [person1] + in_smc: true + household_vehicles_owned: 1 + household_vehicles_value: 50_000 + spm_units: + spm_unit: + members: [person1] + spm_unit_cash_assets: 1_463 + ca_smc_general_assistance_living_arrangement: INDEPENDENT_LIVING + output: + ca_smc_general_assistance_countable_vehicle_value: 0 + ca_smc_general_assistance_property_eligible: true + ca_smc_general_assistance: 732 + +- name: Case 8, single parent with a young child is ineligible. + period: 2026-01 + input: + people: + person1: + age: 30 + immigration_status: CITIZEN + person2: + age: 5 + immigration_status: CITIZEN + households: + household: + members: [person1, person2] + in_smc: true + spm_units: + spm_unit: + members: [person1, person2] + ca_smc_general_assistance_living_arrangement: INDEPENDENT_LIVING + output: + ca_smc_general_assistance_eligible: false + ca_smc_general_assistance: 0 + +- name: Case 9, two unrelated adults without children each receive their own benefit. + period: 2026-01 + input: + people: + person1: + age: 30 + immigration_status: CITIZEN + is_in_work_program: true + person2: + age: 28 + immigration_status: CITIZEN + is_in_work_program: true + households: + household: + members: [person1, person2] + in_smc: true + spm_units: + spm_unit: + members: [person1, person2] + ca_smc_general_assistance_living_arrangement: INDEPENDENT_LIVING + output: + ca_smc_general_assistance_eligible: true + ca_smc_general_assistance: 1_464 + +- name: Case 10, two adults where one receives SSI still qualifies the non-SSI adult via the SPM unit. + period: 2026-01 + input: + people: + person1: + age: 30 + immigration_status: CITIZEN + ssi: 0 + is_in_work_program: true + person2: + age: 65 + immigration_status: CITIZEN + ssi: 12_000 + households: + household: + members: [person1, person2] + in_smc: true + spm_units: + spm_unit: + members: [person1, person2] + ca_smc_general_assistance_living_arrangement: INDEPENDENT_LIVING + output: + ca_smc_general_assistance_eligible: true + ca_smc_general_assistance: 732 + +- name: Case 11, couple where one adult has very high income is ineligible (income deeming via SPM unit aggregation). + period: 2026-01 + input: + people: + person1: + age: 30 + immigration_status: CITIZEN + employment_income: 0 + person2: + age: 32 + immigration_status: CITIZEN + employment_income: 48_000 + households: + household: + members: [person1, person2] + in_smc: true + spm_units: + spm_unit: + members: [person1, person2] + ca_smc_general_assistance_living_arrangement: INDEPENDENT_LIVING + output: + ca_smc_general_assistance_eligible: false + ca_smc_general_assistance: 0 + +- name: Case 12, both adults already receive SSI so the unit is categorically ineligible. + period: 2026-01 + input: + people: + person1: + age: 30 + immigration_status: CITIZEN + ssi: 12_000 + person2: + age: 32 + immigration_status: CITIZEN + ssi: 12_000 + households: + household: + members: [person1, person2] + in_smc: true + spm_units: + spm_unit: + members: [person1, person2] + ca_smc_general_assistance_living_arrangement: INDEPENDENT_LIVING + output: + ca_smc_general_assistance_eligible: false + ca_smc_general_assistance: 0 + +- name: Case 13, three adults with combined property below the flat limit and no income each receive their own benefit. + period: 2026-01 + input: + people: + person1: + age: 30 + immigration_status: CITIZEN + is_in_work_program: true + person2: + age: 28 + immigration_status: CITIZEN + is_in_work_program: true + person3: + age: 25 + immigration_status: CITIZEN + is_in_work_program: true + households: + household: + members: [person1, person2, person3] + in_smc: true + spm_units: + spm_unit: + members: [person1, person2, person3] + spm_unit_cash_assets: 1_000 + ca_smc_general_assistance_living_arrangement: INDEPENDENT_LIVING + output: + ca_smc_general_assistance_eligible: true + ca_smc_general_assistance: 2_196 + +- name: Case 14, three adults with combined property above the flat limit are ineligible. + period: 2026-01 + input: + people: + person1: + age: 30 + immigration_status: CITIZEN + person2: + age: 28 + immigration_status: CITIZEN + person3: + age: 25 + immigration_status: CITIZEN + households: + household: + members: [person1, person2, person3] + in_smc: true + spm_units: + spm_unit: + members: [person1, person2, person3] + spm_unit_cash_assets: 5_000 + ca_smc_general_assistance_living_arrangement: INDEPENDENT_LIVING + output: + ca_smc_general_assistance_property_eligible: false + ca_smc_general_assistance: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/payment/ca_smc_general_assistance_payment_standard.yaml b/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/payment/ca_smc_general_assistance_payment_standard.yaml new file mode 100644 index 00000000000..0aaad92b5ae --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/payment/ca_smc_general_assistance_payment_standard.yaml @@ -0,0 +1,39 @@ +- name: Case 1, independent living standard. + period: 2026-01 + input: + in_smc: true + ca_smc_general_assistance_living_arrangement: INDEPENDENT_LIVING + output: + ca_smc_general_assistance_payment_standard: 732 + +- name: Case 2, drug and alcohol treatment center standard. + period: 2026-01 + input: + in_smc: true + ca_smc_general_assistance_living_arrangement: DRUG_ALCOHOL_TREATMENT_CENTER + output: + ca_smc_general_assistance_payment_standard: 732 + +- name: Case 3, NMOHC without referral standard. + period: 2026-01 + input: + in_smc: true + ca_smc_general_assistance_living_arrangement: NMOHC_WITHOUT_REFERRAL + output: + ca_smc_general_assistance_payment_standard: 732 + +- name: Case 4, NMOHC with referral 2025 standard. + period: 2025-01 + input: + in_smc: true + ca_smc_general_assistance_living_arrangement: NMOHC_WITH_REFERRAL + output: + ca_smc_general_assistance_payment_standard: 1_599.07 + +- name: Case 5, NMOHC with referral 2026 standard. + period: 2026-01 + input: + in_smc: true + ca_smc_general_assistance_living_arrangement: NMOHC_WITH_REFERRAL + output: + ca_smc_general_assistance_payment_standard: 1_626.07 diff --git a/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/property/ca_smc_general_assistance_countable_vehicle_value.yaml b/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/property/ca_smc_general_assistance_countable_vehicle_value.yaml new file mode 100644 index 00000000000..15c725c296b --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/local/ca/smc/general_assistance/property/ca_smc_general_assistance_countable_vehicle_value.yaml @@ -0,0 +1,91 @@ +- name: Case 1, one vehicle is fully excluded. + period: 2026 + input: + in_smc: true + household_vehicles_owned: 1 + household_vehicles_value: 20_000 + output: + ca_smc_general_assistance_countable_vehicle_value: 0 + +- name: Case 2, additional vehicle equity above the combined limit is countable. + period: 2026 + input: + in_smc: true + household_vehicles_owned: 2 + household_vehicles_value: 20_000 + output: + ca_smc_general_assistance_countable_vehicle_value: 7_072 + +- name: Case 3, no vehicle value is countable when no vehicles are owned. + period: 2026 + input: + in_smc: true + household_vehicles_owned: 0 + household_vehicles_value: 0 + output: + ca_smc_general_assistance_countable_vehicle_value: 0 + +- name: Case 4, additional vehicles with low combined equity are fully exempt. + period: 2026 + input: + in_smc: true + household_vehicles_owned: 2 + household_vehicles_value: 2_000 + output: + ca_smc_general_assistance_countable_vehicle_value: 0 + +- name: Case 5, three low-value vehicles with combined additional equity under the threshold are fully exempt. + period: 2026 + input: + in_smc: true + household_vehicles_owned: 3 + household_vehicles_value: 4_000 + output: + ca_smc_general_assistance_countable_vehicle_value: 0 + +- name: Case 6, two-adult unit with two vehicles exempts one; the additional vehicle equity above the combined limit is countable. + period: 2026 + input: + people: + person1: + age: 30 + immigration_status: CITIZEN + person2: + age: 28 + immigration_status: CITIZEN + households: + household: + members: [person1, person2] + in_smc: true + household_vehicles_owned: 2 + household_vehicles_value: 20_000 + spm_units: + spm_unit: + members: [person1, person2] + output: + ca_smc_general_assistance_countable_vehicle_value: 7_072 + +- name: Case 7, three-adult unit with three vehicles exempts one; the additional vehicle equity above the combined limit is countable. + period: 2026 + input: + people: + person1: + age: 30 + immigration_status: CITIZEN + person2: + age: 28 + immigration_status: CITIZEN + person3: + age: 25 + immigration_status: CITIZEN + households: + household: + members: [person1, person2, person3] + in_smc: true + household_vehicles_owned: 3 + household_vehicles_value: 15_000 + spm_units: + spm_unit: + members: [person1, person2, person3] + output: + ca_smc_general_assistance_countable_vehicle_value: 7_072 diff --git a/policyengine_us/tests/policy/baseline/gov/local/ca/smc/in_smc.yaml b/policyengine_us/tests/policy/baseline/gov/local/ca/smc/in_smc.yaml new file mode 100644 index 00000000000..3090f958bac --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/local/ca/smc/in_smc.yaml @@ -0,0 +1,13 @@ +- name: Case 1, San Mateo County is true. + period: 2026 + input: + county_str: SAN_MATEO_COUNTY_CA + output: + in_smc: true + +- name: Case 2, another county is false. + period: 2026 + input: + county_str: LOS_ANGELES_COUNTY_CA + output: + in_smc: false diff --git a/policyengine_us/variables/gov/local/ca/ala/in_ala.py b/policyengine_us/variables/gov/local/ca/ala/in_ala.py index e53b48c4367..da357b147e2 100644 --- a/policyengine_us/variables/gov/local/ca/ala/in_ala.py +++ b/policyengine_us/variables/gov/local/ca/ala/in_ala.py @@ -9,4 +9,4 @@ class in_ala(Variable): def formula(household, period, parameters): county = household("county_str", period) - return county == "Alameda_COUNTY_CA" + return county == "ALAMEDA_COUNTY_CA" diff --git a/policyengine_us/variables/gov/local/ca/smc/general_assistance/ca_smc_general_assistance.py b/policyengine_us/variables/gov/local/ca/smc/general_assistance/ca_smc_general_assistance.py new file mode 100644 index 00000000000..b9de3c17d91 --- /dev/null +++ b/policyengine_us/variables/gov/local/ca/smc/general_assistance/ca_smc_general_assistance.py @@ -0,0 +1,24 @@ +from policyengine_us.model_api import * + + +class ca_smc_general_assistance(Variable): + value_type = float + entity = SPMUnit + unit = USD + label = "San Mateo County General Assistance" + definition_period = MONTH + defined_for = "ca_smc_general_assistance_eligible" + reference = ( + "https://www.smcgov.org/media/153295/download?inline=#page=2", + "https://www.smcgov.org/media/156974/download?inline=", + ) + + def formula(spm_unit, period, parameters): + standard = spm_unit("ca_smc_general_assistance_payment_standard", period) + income = spm_unit("ca_smc_general_assistance_countable_income", period) + n_eligible = add( + spm_unit, period, ["ca_smc_general_assistance_eligible_person"] + ) + per_person_income = where(n_eligible > 0, income / n_eligible, 0) + per_person_benefit = max_(standard - max_(per_person_income, 0), 0) + return n_eligible * per_person_benefit diff --git a/policyengine_us/variables/gov/local/ca/smc/general_assistance/ca_smc_general_assistance_living_arrangement.py b/policyengine_us/variables/gov/local/ca/smc/general_assistance/ca_smc_general_assistance_living_arrangement.py new file mode 100644 index 00000000000..4310552fa57 --- /dev/null +++ b/policyengine_us/variables/gov/local/ca/smc/general_assistance/ca_smc_general_assistance_living_arrangement.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * + + +class CaSMCGeneralAssistanceLivingArrangement(Enum): + INDEPENDENT_LIVING = "Independent living" + DRUG_ALCOHOL_TREATMENT_CENTER = "Drug and alcohol treatment center" + NMOHC_WITHOUT_REFERRAL = "Non-medical out-of-home care without BHRS/SMMC referral" + NMOHC_WITH_REFERRAL = "Non-medical out-of-home care with BHRS/SMMC referral" + + +class ca_smc_general_assistance_living_arrangement(Variable): + value_type = Enum + entity = SPMUnit + label = "San Mateo County General Assistance living arrangement" + definition_period = MONTH + defined_for = "in_smc" + possible_values = CaSMCGeneralAssistanceLivingArrangement + default_value = CaSMCGeneralAssistanceLivingArrangement.INDEPENDENT_LIVING + reference = "https://www.smcgov.org/media/156974/download?inline=#page=2" diff --git a/policyengine_us/variables/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_eligible.py b/policyengine_us/variables/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_eligible.py new file mode 100644 index 00000000000..13735dd2870 --- /dev/null +++ b/policyengine_us/variables/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_eligible.py @@ -0,0 +1,30 @@ +from policyengine_us.model_api import * + + +class ca_smc_general_assistance_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Eligible for San Mateo County General Assistance" + definition_period = MONTH + defined_for = "in_smc" + reference = ( + "https://www.smcgov.org/media/153295/download?inline=#page=1", + "https://sanmateocounty.legistar.com/View.ashx?GUID=25359405-C9EB-4566-AE97-D927CC455B02&ID=9802358&M=F#page=2", + ) + + def formula(spm_unit, period, parameters): + eligible_adult = ( + add( + spm_unit, + period, + ["ca_smc_general_assistance_eligible_person"], + ) + > 0 + ) + has_minor_child = add(spm_unit, period, ["is_child"]) > 0 + return ( + eligible_adult + & ~has_minor_child + & spm_unit("ca_smc_general_assistance_income_eligible", period) + & spm_unit("ca_smc_general_assistance_property_eligible", period) + ) diff --git a/policyengine_us/variables/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_eligible_person.py b/policyengine_us/variables/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_eligible_person.py new file mode 100644 index 00000000000..ac3308a1040 --- /dev/null +++ b/policyengine_us/variables/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_eligible_person.py @@ -0,0 +1,30 @@ +from policyengine_us.model_api import * + + +class ca_smc_general_assistance_eligible_person(Variable): + value_type = bool + entity = Person + label = "Eligible person for San Mateo County General Assistance" + definition_period = MONTH + defined_for = "in_smc" + reference = ( + "https://www.smcgov.org/hsa/general-assistance-ga", + "https://sanmateocounty.legistar.com/View.ashx?GUID=25359405-C9EB-4566-AE97-D927CC455B02&ID=9802358&M=F#page=2", + ) + + def formula(person, period, parameters): + # We don't track 15-day county residency, fleeing-felon + # disqualification, or the requirement to apply for other potential + # income at the moment. The SSI gate below captures SSI recipients + # but does not separately exclude CAPI recipients. + p = parameters(period).gov.local.ca.smc.general_assistance + adult = person("age", period.this_year) >= p.minimum_age + immigration_eligible = person( + "ca_smc_general_assistance_immigration_status_eligible_person", + period, + ) + not_on_ssi = person("ssi", period) == 0 + meets_work_requirements = person( + "ca_smc_general_assistance_meets_work_requirements", period + ) + return adult & immigration_eligible & not_on_ssi & meets_work_requirements diff --git a/policyengine_us/variables/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_immigration_status_eligible_person.py b/policyengine_us/variables/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_immigration_status_eligible_person.py new file mode 100644 index 00000000000..801b33abe12 --- /dev/null +++ b/policyengine_us/variables/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_immigration_status_eligible_person.py @@ -0,0 +1,18 @@ +from policyengine_us.model_api import * + + +class ca_smc_general_assistance_immigration_status_eligible_person(Variable): + value_type = bool + entity = Person + label = "Eligible for San Mateo County General Assistance due to immigration status" + definition_period = MONTH + defined_for = "in_smc" + reference = "https://www.smcgov.org/media/153295/download?inline=#page=1" + + def formula(person, period, parameters): + p = parameters(period).gov.local.ca.smc.general_assistance + immigration_status = person("immigration_status", period.this_year) + return np.isin( + immigration_status.decode_to_str(), + p.qualified_immigration_statuses, + ) diff --git a/policyengine_us/variables/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_income_eligible.py b/policyengine_us/variables/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_income_eligible.py new file mode 100644 index 00000000000..9cf614041a2 --- /dev/null +++ b/policyengine_us/variables/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_income_eligible.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * + + +class ca_smc_general_assistance_income_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Eligible for San Mateo County General Assistance due to income" + definition_period = MONTH + defined_for = "in_smc" + reference = "https://www.smcgov.org/media/153295/download?inline=#page=2" + + def formula(spm_unit, period, parameters): + income = spm_unit("ca_smc_general_assistance_countable_income", period) + standard = spm_unit("ca_smc_general_assistance_payment_standard", period) + n_eligible = add( + spm_unit, period, ["ca_smc_general_assistance_eligible_person"] + ) + per_person_income = where(n_eligible > 0, income / n_eligible, 0) + return (n_eligible > 0) & (per_person_income < standard) diff --git a/policyengine_us/variables/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_meets_work_requirements.py b/policyengine_us/variables/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_meets_work_requirements.py new file mode 100644 index 00000000000..577ac2a9b8c --- /dev/null +++ b/policyengine_us/variables/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_meets_work_requirements.py @@ -0,0 +1,34 @@ +from policyengine_us.model_api import * + + +class ca_smc_general_assistance_meets_work_requirements(Variable): + value_type = bool + entity = Person + label = "Meets work requirements for San Mateo County General Assistance" + definition_period = MONTH + defined_for = "in_smc" + reference = "https://www.smcgov.org/media/153295/download?inline=#page=1" + + def formula(person, period, parameters): + # We don't track caregiving for an ill parent/spouse/child/sibling, + # the "child under 16" exemption (moot — minor children disqualify + # the SPM unit), or HSA-approved training/rehabilitation programs at + # the moment. + p = parameters(period).gov.local.ca.smc.general_assistance.work_requirement + weekly_hours_worked = person("weekly_hours_worked_before_lsr", period.this_year) + is_working_full_time = weekly_hours_worked >= p.weekly_hours_threshold + is_senior = person("age", period.this_year) >= p.senior_exemption_age + is_disabled = person("is_disabled", period) + is_full_time_student = person("is_full_time_student", period) + is_lep_household = person.household( + "is_non_english_speaking_home", period.this_year + ) + is_in_work_program = person("is_in_work_program", period) + return ( + is_working_full_time + | is_senior + | is_disabled + | is_full_time_student + | is_lep_household + | is_in_work_program + ) diff --git a/policyengine_us/variables/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_property_eligible.py b/policyengine_us/variables/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_property_eligible.py new file mode 100644 index 00000000000..38de916cf1b --- /dev/null +++ b/policyengine_us/variables/gov/local/ca/smc/general_assistance/eligibility/ca_smc_general_assistance_property_eligible.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * + + +class ca_smc_general_assistance_property_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Eligible for San Mateo County General Assistance due to property" + definition_period = YEAR + defined_for = "in_smc" + reference = ( + "https://www.smcgov.org/media/153295/download?inline=#page=2", + "https://www.smcgov.org/media/156974/download?inline=", + "https://sanmateocounty.legistar.com/View.ashx?GUID=25359405-C9EB-4566-AE97-D927CC455B02&ID=9802358&M=F#page=2", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.local.ca.smc.general_assistance.property + countable = spm_unit("ca_smc_general_assistance_countable_property", period) + return countable < p.limit diff --git a/policyengine_us/variables/gov/local/ca/smc/general_assistance/income/ca_smc_general_assistance_countable_income.py b/policyengine_us/variables/gov/local/ca/smc/general_assistance/income/ca_smc_general_assistance_countable_income.py new file mode 100644 index 00000000000..a0a100bfe31 --- /dev/null +++ b/policyengine_us/variables/gov/local/ca/smc/general_assistance/income/ca_smc_general_assistance_countable_income.py @@ -0,0 +1,21 @@ +from policyengine_us.model_api import * + + +class ca_smc_general_assistance_countable_income(Variable): + value_type = float + entity = SPMUnit + unit = USD + label = "San Mateo County General Assistance countable income" + definition_period = MONTH + defined_for = "in_smc" + reference = ( + "https://www.smcgov.org/media/153295/download?inline=#page=2", + "https://sanmateocounty.legistar.com/View.ashx?GUID=25359405-C9EB-4566-AE97-D927CC455B02&ID=9802358&M=F#page=2", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.local.ca.smc.general_assistance.income + total = add(spm_unit, period, p.sources) + earned = add(spm_unit, period, p.earned_sources) + deduction = max_(earned, 0) * p.earned_income_deduction_rate + return total - deduction diff --git a/policyengine_us/variables/gov/local/ca/smc/general_assistance/payment/ca_smc_general_assistance_payment_standard.py b/policyengine_us/variables/gov/local/ca/smc/general_assistance/payment/ca_smc_general_assistance_payment_standard.py new file mode 100644 index 00000000000..731c404071c --- /dev/null +++ b/policyengine_us/variables/gov/local/ca/smc/general_assistance/payment/ca_smc_general_assistance_payment_standard.py @@ -0,0 +1,20 @@ +from policyengine_us.model_api import * + + +class ca_smc_general_assistance_payment_standard(Variable): + value_type = float + entity = SPMUnit + unit = USD + label = "San Mateo County General Assistance payment standard" + definition_period = MONTH + defined_for = "in_smc" + reference = ( + "https://www.smcgov.org/media/156974/download?inline=", + "https://sanmateocounty.legistar.com/ViewReport.ashx?GID=659&GUID=LATEST&ID=94585&M=R&N=TextL5&Title=Board+Memo#page=1", + ) + + def formula(spm_unit, period, parameters): + arrangement = spm_unit("ca_smc_general_assistance_living_arrangement", period) + return parameters(period).gov.local.ca.smc.general_assistance.payment_standard[ + arrangement + ] diff --git a/policyengine_us/variables/gov/local/ca/smc/general_assistance/property/ca_smc_general_assistance_countable_property.py b/policyengine_us/variables/gov/local/ca/smc/general_assistance/property/ca_smc_general_assistance_countable_property.py new file mode 100644 index 00000000000..79534df4d2a --- /dev/null +++ b/policyengine_us/variables/gov/local/ca/smc/general_assistance/property/ca_smc_general_assistance_countable_property.py @@ -0,0 +1,16 @@ +from policyengine_us.model_api import * + + +class ca_smc_general_assistance_countable_property(Variable): + value_type = float + entity = SPMUnit + unit = USD + label = "San Mateo County General Assistance countable property" + definition_period = YEAR + defined_for = "in_smc" + reference = ( + "https://www.smcgov.org/media/153295/download?inline=#page=2", + "https://sanmateocounty.legistar.com/View.ashx?GUID=25359405-C9EB-4566-AE97-D927CC455B02&ID=9802358&M=F#page=2", + ) + + adds = "gov.local.ca.smc.general_assistance.property.sources" diff --git a/policyengine_us/variables/gov/local/ca/smc/general_assistance/property/ca_smc_general_assistance_countable_vehicle_value.py b/policyengine_us/variables/gov/local/ca/smc/general_assistance/property/ca_smc_general_assistance_countable_vehicle_value.py new file mode 100644 index 00000000000..dd371f4cd10 --- /dev/null +++ b/policyengine_us/variables/gov/local/ca/smc/general_assistance/property/ca_smc_general_assistance_countable_vehicle_value.py @@ -0,0 +1,31 @@ +from policyengine_us.model_api import * + + +class ca_smc_general_assistance_countable_vehicle_value(Variable): + value_type = float + entity = SPMUnit + unit = USD + label = "San Mateo County General Assistance countable vehicle value" + definition_period = YEAR + defined_for = "in_smc" + reference = ( + "https://www.smcgov.org/media/153295/download?inline=#page=2", + "https://sanmateocounty.legistar.com/View.ashx?GUID=25359405-C9EB-4566-AE97-D927CC455B02&ID=9802358&M=F#page=2", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.local.ca.smc.general_assistance.property + household = spm_unit.household + vehicle_count = household("household_vehicles_owned", period) + vehicle_value = household("household_vehicles_value", period) + average_vehicle_value = where( + vehicle_count > 0, + vehicle_value / vehicle_count, + 0, + ) + additional_vehicle_count = max_(vehicle_count - 1, 0) + additional_vehicle_equity = average_vehicle_value * additional_vehicle_count + return max_( + additional_vehicle_equity - p.additional_vehicle_combined_equity_limit, + 0, + ) diff --git a/policyengine_us/variables/gov/local/ca/smc/in_smc.py b/policyengine_us/variables/gov/local/ca/smc/in_smc.py new file mode 100644 index 00000000000..b27806602de --- /dev/null +++ b/policyengine_us/variables/gov/local/ca/smc/in_smc.py @@ -0,0 +1,11 @@ +from policyengine_us.model_api import * + + +class in_smc(Variable): + value_type = bool + entity = Household + definition_period = YEAR + label = "Is in San Mateo County" + + def formula(household, period, parameters): + return household("county_str", period) == "SAN_MATEO_COUNTY_CA" diff --git a/policyengine_us/variables/household/demographic/person/is_in_work_program.py b/policyengine_us/variables/household/demographic/person/is_in_work_program.py new file mode 100644 index 00000000000..6a886e54446 --- /dev/null +++ b/policyengine_us/variables/household/demographic/person/is_in_work_program.py @@ -0,0 +1,9 @@ +from policyengine_us.model_api import * + + +class is_in_work_program(Variable): + value_type = bool + entity = Person + definition_period = MONTH + label = "Is in a work program" + documentation = "Whether the person is participating in a state, county, or federal work program tied to a benefit (for example, a welfare-to-work activity, SNAP Employment and Training, or a county work center)."