diff --git a/changelog.d/added/8358.md b/changelog.d/added/8358.md new file mode 100644 index 00000000000..37fab43f2a5 --- /dev/null +++ b/changelog.d/added/8358.md @@ -0,0 +1 @@ +Add Santa Clara County General Assistance program. diff --git a/policyengine_us/parameters/gov/local/ca/scc/general_assistance/age_threshold.yaml b/policyengine_us/parameters/gov/local/ca/scc/general_assistance/age_threshold.yaml new file mode 100644 index 00000000000..e7d6390a5c5 --- /dev/null +++ b/policyengine_us/parameters/gov/local/ca/scc/general_assistance/age_threshold.yaml @@ -0,0 +1,12 @@ +description: Santa Clara County limits the General Assistance program to individuals of this age or older. +values: + 2016-04-01: 18 +metadata: + label: Santa Clara County General Assistance age eligibility threshold + unit: year + period: year + reference: + - title: Santa Clara County General Assistance Handbook, GA 112 (Unmarried Minor) + href: https://stgenssa.sccgov.org/debs/program_handbooks/general_assistance/assets/01Policy/Policy.htm + - title: California Family Code Section 6500 (Age of majority) + href: https://california.public.law/codes/ca_fam_code_section_6500 diff --git a/policyengine_us/parameters/gov/local/ca/scc/general_assistance/amount/board_and_care.yaml b/policyengine_us/parameters/gov/local/ca/scc/general_assistance/amount/board_and_care.yaml new file mode 100644 index 00000000000..8d2f00b3c90 --- /dev/null +++ b/policyengine_us/parameters/gov/local/ca/scc/general_assistance/amount/board_and_care.yaml @@ -0,0 +1,12 @@ +description: Santa Clara County provides this amount to recipients residing in a State-licensed Board and Care or Residential Care Home under the General Assistance program. +values: + 2016-04-01: 929 +metadata: + label: Santa Clara County General Assistance Board and Care amount + period: month + unit: currency-USD + reference: + - title: Santa Clara County General Assistance Need Standards Chart (state-licensed RCH) + href: https://stgenssa.sccgov.org/debs/program_handbooks/charts/assets/4GA/NeedStnds.htm + - title: Santa Clara County GA-62 Program Information Sheet, State-Licensed Board and Care row + href: https://stgenssa.sccgov.org/debs/Forms/GA_62_en.pdf#page=2 diff --git a/policyengine_us/parameters/gov/local/ca/scc/general_assistance/amount/married.yaml b/policyengine_us/parameters/gov/local/ca/scc/general_assistance/amount/married.yaml new file mode 100644 index 00000000000..cb2ae9338ea --- /dev/null +++ b/policyengine_us/parameters/gov/local/ca/scc/general_assistance/amount/married.yaml @@ -0,0 +1,12 @@ +description: Santa Clara County provides this amount as the cash grant for married filers under the General Assistance program. +values: + 2016-04-01: 460 +metadata: + label: Santa Clara County General Assistance married amount + period: month + unit: currency-USD + reference: + - title: Santa Clara County General Assistance Need Standards Chart (GA 280) + href: https://stgenssa.sccgov.org/debs/program_handbooks/charts/assets/4GA/NeedStnds.htm + - title: Santa Clara County GA-62 Program Information Sheet + href: https://stgenssa.sccgov.org/debs/Forms/GA_62_en.pdf#page=2 diff --git a/policyengine_us/parameters/gov/local/ca/scc/general_assistance/amount/medical_institution.yaml b/policyengine_us/parameters/gov/local/ca/scc/general_assistance/amount/medical_institution.yaml new file mode 100644 index 00000000000..1dbe77a17d8 --- /dev/null +++ b/policyengine_us/parameters/gov/local/ca/scc/general_assistance/amount/medical_institution.yaml @@ -0,0 +1,10 @@ +description: Santa Clara County provides this amount to recipients residing in a medical institution under the General Assistance program. +values: + 2016-04-01: 11 +metadata: + label: Santa Clara County General Assistance medical institution amount + period: month + unit: currency-USD + reference: + - title: Santa Clara County General Assistance Need Standards Chart (one person in medical institution) + href: https://stgenssa.sccgov.org/debs/program_handbooks/charts/assets/4GA/NeedStnds.htm diff --git a/policyengine_us/parameters/gov/local/ca/scc/general_assistance/amount/single.yaml b/policyengine_us/parameters/gov/local/ca/scc/general_assistance/amount/single.yaml new file mode 100644 index 00000000000..5be01078ecf --- /dev/null +++ b/policyengine_us/parameters/gov/local/ca/scc/general_assistance/amount/single.yaml @@ -0,0 +1,12 @@ +description: Santa Clara County provides this amount as the cash grant for single filers under the General Assistance program. +values: + 2016-04-01: 343 +metadata: + label: Santa Clara County General Assistance single amount + period: month + unit: currency-USD + reference: + - title: Santa Clara County General Assistance Need Standards Chart (GA 280) + href: https://stgenssa.sccgov.org/debs/program_handbooks/charts/assets/4GA/NeedStnds.htm + - title: Santa Clara County GA-62 Program Information Sheet + href: https://stgenssa.sccgov.org/debs/Forms/GA_62_en.pdf#page=2 diff --git a/policyengine_us/parameters/gov/local/ca/scc/general_assistance/countable_income/earned_deductions/person_sources.yaml b/policyengine_us/parameters/gov/local/ca/scc/general_assistance/countable_income/earned_deductions/person_sources.yaml new file mode 100644 index 00000000000..886489a15ba --- /dev/null +++ b/policyengine_us/parameters/gov/local/ca/scc/general_assistance/countable_income/earned_deductions/person_sources.yaml @@ -0,0 +1,15 @@ +description: Santa Clara County deducts these person-level involuntary withholdings from gross earned income under the General Assistance program. +values: + 2016-04-01: + - employee_social_security_tax + - employee_medicare_tax + - ca_employee_state_disability_insurance_contribution +metadata: + unit: list + period: year + label: Santa Clara County General Assistance person-level earned income deductions + reference: + - title: Santa Clara County General Assistance Handbook, GA 204 (Exempt Income) + href: https://stgenssa.sccgov.org/debs/program_handbooks/general_assistance/assets/01Policy/Policy.htm + - title: Santa Clara County General Assistance Handbook, Verification of Income — Earned Income Deductions + href: https://stgenssa.sccgov.org/debs/program_handbooks/general_assistance/assets/09Income/Verification_Income.htm diff --git a/policyengine_us/parameters/gov/local/ca/scc/general_assistance/countable_income/earned_sources.yaml b/policyengine_us/parameters/gov/local/ca/scc/general_assistance/countable_income/earned_sources.yaml new file mode 100644 index 00000000000..6778ddbc595 --- /dev/null +++ b/policyengine_us/parameters/gov/local/ca/scc/general_assistance/countable_income/earned_sources.yaml @@ -0,0 +1,15 @@ +description: Santa Clara County uses these earned income sources when determining eligibility for the General Assistance program. +values: + 2016-04-01: + - employment_income + - self_employment_income + - sstb_self_employment_income +metadata: + unit: list + period: year + label: Santa Clara County General Assistance earned income sources + reference: + - title: Santa Clara County General Assistance Handbook, GA 200-204 (Income Policies) + href: https://stgenssa.sccgov.org/debs/program_handbooks/general_assistance/assets/09Income/GA_Policies.htm + - title: Santa Clara County General Assistance Handbook, Types of Income chapter (Earned Income) + href: https://stgenssa.sccgov.org/debs/program_handbooks/general_assistance/assets/09Income/Types_Income.htm diff --git a/policyengine_us/parameters/gov/local/ca/scc/general_assistance/countable_income/unearned_sources.yaml b/policyengine_us/parameters/gov/local/ca/scc/general_assistance/countable_income/unearned_sources.yaml new file mode 100644 index 00000000000..eee5cbcc950 --- /dev/null +++ b/policyengine_us/parameters/gov/local/ca/scc/general_assistance/countable_income/unearned_sources.yaml @@ -0,0 +1,28 @@ +description: Santa Clara County uses these unearned income sources when determining eligibility for the General Assistance program. +values: + 2016-04-01: + - social_security + - ca_state_disability_insurance + - disability_benefits + - railroad_benefits + - unemployment_compensation + - veterans_benefits + - workers_compensation + - taxable_pension_income + - tax_exempt_pension_income + - taxable_interest_income + - tax_exempt_interest_income + - qualified_dividend_income + - non_qualified_dividend_income + - alimony_income + - child_support_received + - rental_income +metadata: + unit: list + period: year + label: Santa Clara County General Assistance unearned income sources + reference: + - title: Santa Clara County General Assistance Handbook, GA 200-204 (Income Policies) + href: https://stgenssa.sccgov.org/debs/program_handbooks/general_assistance/assets/09Income/GA_Policies.htm + - title: Santa Clara County General Assistance Handbook, Types of Income chapter (Unearned Income) + href: https://stgenssa.sccgov.org/debs/program_handbooks/general_assistance/assets/09Income/Types_Income.htm diff --git a/policyengine_us/parameters/gov/local/ca/scc/general_assistance/personal_property/limit.yaml b/policyengine_us/parameters/gov/local/ca/scc/general_assistance/personal_property/limit.yaml new file mode 100644 index 00000000000..39a23e0918e --- /dev/null +++ b/policyengine_us/parameters/gov/local/ca/scc/general_assistance/personal_property/limit.yaml @@ -0,0 +1,14 @@ +description: Santa Clara County limits personal property to this amount under the General Assistance program. +values: + 2016-04-01: 500 +metadata: + label: Santa Clara County General Assistance personal property limit amount + unit: currency-USD + period: year + reference: + - title: Santa Clara County General Assistance Handbook, GA 180 (Personal Property) + href: https://stgenssa.sccgov.org/debs/program_handbooks/general_assistance/assets/01Policy/Policy.htm + - title: Santa Clara County General Assistance Handbook, Personal Property chapter + href: https://stgenssa.sccgov.org/debs/program_handbooks/general_assistance/assets/08Property/Personal_Property.htm + - title: Santa Clara County GA-62 Program Information Sheet + href: https://stgenssa.sccgov.org/debs/Forms/GA_62_en.pdf#page=2 diff --git a/policyengine_us/parameters/gov/local/ca/scc/general_assistance/qualified_immigration_status.yaml b/policyengine_us/parameters/gov/local/ca/scc/general_assistance/qualified_immigration_status.yaml new file mode 100644 index 00000000000..e1c2843d5ec --- /dev/null +++ b/policyengine_us/parameters/gov/local/ca/scc/general_assistance/qualified_immigration_status.yaml @@ -0,0 +1,18 @@ +description: Santa Clara County uses these immigration statuses as qualified non-citizens under the General Assistance program. +values: + 2016-04-01: + - CITIZEN + - LEGAL_PERMANENT_RESIDENT + - REFUGEE + - ASYLEE + - DEPORTATION_WITHHELD # "entitled to remain indefinitely" per GA 141 + - CUBAN_HAITIAN_ENTRANT +metadata: + label: Santa Clara County General Assistance qualified immigration statuses + period: year + unit: list + reference: + - title: Santa Clara County General Assistance Handbook, GA 141 (Residence of a Non-Citizen) + href: https://stgenssa.sccgov.org/debs/program_handbooks/general_assistance/assets/01Policy/Policy.htm + - title: Santa Clara County General Assistance Handbook, Noncitizen Status chapter + href: https://stgenssa.sccgov.org/debs/program_handbooks/general_assistance/assets/07Citizens_Noncitizens/Non_Citizen_Status.htm diff --git a/policyengine_us/parameters/gov/local/ca/scc/general_assistance/shared_housing/reduction.yaml b/policyengine_us/parameters/gov/local/ca/scc/general_assistance/shared_housing/reduction.yaml new file mode 100644 index 00000000000..e059b5e46d1 --- /dev/null +++ b/policyengine_us/parameters/gov/local/ca/scc/general_assistance/shared_housing/reduction.yaml @@ -0,0 +1,26 @@ +description: Santa Clara County excludes this share of the maximum aid payment for shared housing recipients under the General Assistance program. +metadata: + unit: /1 + period: year + label: Santa Clara County General Assistance shared housing reduction rate + breakdown: + - ca_scc_general_assistance_living_arrangement + reference: + - title: Santa Clara County General Assistance Handbook, GA 282 (Shared Housing) + href: https://stgenssa.sccgov.org/debs/program_handbooks/general_assistance/assets/14Payment/Shared_Housing.htm + - title: Santa Clara County General Assistance Need Standards Chart (GA 282 footnote) + href: https://stgenssa.sccgov.org/debs/program_handbooks/charts/assets/4GA/NeedStnds.htm + - title: Santa Clara County General Assistance Program Information Sheet (GA-62), Maximum Aid Payment table + href: https://stgenssa.sccgov.org/debs/Forms/GA_62_en.pdf#page=2 +NOT_SHARED: + 2016-04-01: 0 +SHARED_WITH_ONE: + 2016-04-01: 0.15 +SHARED_WITH_TWO: + 2016-04-01: 0.2 +SHARED_WITH_THREE_OR_MORE: + 2016-04-01: 0.25 +BOARD_AND_CARE: + 2016-04-01: 0 +MEDICAL_INSTITUTION: + 2016-04-01: 0 diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index be23800f5a4..73589f30ff6 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -1279,6 +1279,16 @@ programs: variable: ca_ala_general_assistance parameter_prefix: gov.local.ca.ala.ga + - id: ca_scc_general_assistance + name: Santa Clara County General Assistance + full_name: Santa Clara County General Assistance + category: Benefits + agency: Local + status: complete + coverage: Santa Clara County + variable: ca_scc_general_assistance + parameter_prefix: gov.local.ca.scc.general_assistance + - id: nyc_income_tax name: NYC income tax full_name: New York City Income Tax diff --git a/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance.yaml b/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance.yaml new file mode 100644 index 00000000000..f54b93ae793 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance.yaml @@ -0,0 +1,217 @@ +- name: Case 1, single eligible adult with zero income, receives full single MAP. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 0 + immigration_status: CITIZEN + households: + household: + members: [person1] + in_scc: true + spm_units: + spm_unit: + members: [person1] + ca_scc_general_assistance_living_arrangement: NOT_SHARED + output: + ca_scc_general_assistance: 343 + +- name: Case 2, single eligible adult with partial unearned income. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 0 + immigration_status: CITIZEN + social_security: 1_200 + households: + household: + members: [person1] + in_scc: true + spm_units: + spm_unit: + members: [person1] + ca_scc_general_assistance_living_arrangement: NOT_SHARED + output: + # countable = 1_200/12 = 100; benefit = 343 - 100 = 243. + ca_scc_general_assistance: 243 + +- name: Case 3, single eligible adult with unearned income at MAP, zero benefit. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 0 + immigration_status: CITIZEN + social_security: 4_116 + households: + household: + members: [person1] + in_scc: true + spm_units: + spm_unit: + members: [person1] + ca_scc_general_assistance_living_arrangement: NOT_SHARED + output: + # countable = 4_116/12 = 343 == MAP; benefit = 0. + ca_scc_general_assistance: 0 + +- name: Case 4, ineligible due to SSI receipt. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 100 + personal_property: 0 + immigration_status: CITIZEN + households: + household: + members: [person1] + in_scc: true + spm_units: + spm_unit: + members: [person1] + ca_scc_general_assistance_living_arrangement: NOT_SHARED + output: + ca_scc_general_assistance: 0 + +- name: Case 5, negative employment income does not inflate benefit beyond MAP. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 0 + immigration_status: CITIZEN + self_employment_income: -120_000 + households: + household: + members: [person1] + in_scc: true + spm_units: + spm_unit: + members: [person1] + ca_scc_general_assistance_living_arrangement: NOT_SHARED + output: + ca_scc_general_assistance: 343 + +- name: Case 6, extremely negative SE income — benefit must not exceed single MAP. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 0 + immigration_status: CITIZEN + self_employment_income: -1_000_000 + households: + household: + members: [person1] + in_scc: true + spm_units: + spm_unit: + members: [person1] + ca_scc_general_assistance_living_arrangement: NOT_SHARED + output: + # Benefit must be capped at the MAP ($343), not 343 - (-83_333) = 83_676. + ca_scc_general_assistance: 343 + +- name: Case 7, single eligible adult with countable income exactly at single MAP, zero benefit. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 0 + immigration_status: CITIZEN + social_security: 4_116 + households: + household: + members: [person1] + in_scc: true + spm_units: + spm_unit: + members: [person1] + ca_scc_general_assistance_living_arrangement: NOT_SHARED + output: + # countable_income = 4_116 / 12 = 343 == MAP -> income_eligible true but fill-the-gap = 343 - 343 = 0 + ca_scc_general_assistance: 0 + +- name: Case 8, single eligible adult with countable income $1 below single MAP, $1 benefit. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 0 + immigration_status: CITIZEN + social_security: 4_104 + households: + household: + members: [person1] + in_scc: true + spm_units: + spm_unit: + members: [person1] + ca_scc_general_assistance_living_arrangement: NOT_SHARED + output: + # countable = 4_104 / 12 = 342; benefit = 343 - 342 = 1 + ca_scc_general_assistance: 1 + +- name: Case 9, married couple with $200 combined unearned countable income receives $260. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + social_security: 1_200 + person2: + age: 28 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + social_security: 1_200 + households: + household: + members: [person1, person2] + in_scc: true + spm_units: + spm_unit: + members: [person1, person2] + ca_scc_general_assistance_living_arrangement: NOT_SHARED + output: + # combined countable = (1_200 + 1_200) / 12 = 200; benefit = 460 - 200 = 260 + ca_scc_general_assistance: 260 diff --git a/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance_age_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance_age_eligible.yaml new file mode 100644 index 00000000000..8b08618a8c2 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance_age_eligible.yaml @@ -0,0 +1,55 @@ +- name: Case 1, adult age 30 is eligible. + period: 2024 + input: + age: 30 + in_scc: true + output: + ca_scc_general_assistance_age_eligible: true + +- name: Case 2, minor age 17 is ineligible. + period: 2024 + input: + age: 17 + in_scc: true + output: + ca_scc_general_assistance_age_eligible: false + +- name: Case 3, age exactly 18 is eligible at boundary. + period: 2024 + input: + age: 18 + in_scc: true + output: + ca_scc_general_assistance_age_eligible: true + +- name: Case 4, age 25 is eligible. + period: 2024 + input: + age: 25 + in_scc: true + output: + ca_scc_general_assistance_age_eligible: true + +- name: Case 5, infant age 0 is ineligible. + period: 2024 + input: + age: 0 + in_scc: true + output: + ca_scc_general_assistance_age_eligible: false + +- name: Case 6, age 17.99 (float) is ineligible just below 18. + period: 2024 + input: + age: 17.99 + in_scc: true + output: + ca_scc_general_assistance_age_eligible: false + +- name: Case 7, age 100 is eligible. + period: 2024 + input: + age: 100 + in_scc: true + output: + ca_scc_general_assistance_age_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance_base_amount.yaml b/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance_base_amount.yaml new file mode 100644 index 00000000000..f5401b9d1c2 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance_base_amount.yaml @@ -0,0 +1,275 @@ +- name: Case 1, single eligible adult, not shared housing, full single MAP. + period: 2024-01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + households: + household: + members: [person1] + in_scc: true + spm_units: + spm_unit: + members: [person1] + ca_scc_general_assistance_living_arrangement: NOT_SHARED + absolute_error_margin: 0.1 + output: + ca_scc_general_assistance_base_amount: 343 + +- name: Case 2, married eligible couple, not shared housing, full married MAP. + period: 2024-01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + person2: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + households: + household: + members: [person1, person2] + in_scc: true + spm_units: + spm_unit: + members: [person1, person2] + ca_scc_general_assistance_living_arrangement: NOT_SHARED + absolute_error_margin: 0.1 + output: + ca_scc_general_assistance_base_amount: 460 + +- name: Case 3, only one of two persons eligible, returns single MAP. + period: 2024-01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + person2: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: UNDOCUMENTED + households: + household: + members: [person1, person2] + in_scc: true + spm_units: + spm_unit: + members: [person1, person2] + ca_scc_general_assistance_living_arrangement: NOT_SHARED + absolute_error_margin: 0.1 + output: + ca_scc_general_assistance_base_amount: 343 + +- name: Case 4, single eligible adult shared with one other (15 percent reduction). + period: 2024-01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + households: + household: + members: [person1] + in_scc: true + spm_units: + spm_unit: + members: [person1] + ca_scc_general_assistance_living_arrangement: SHARED_WITH_ONE + absolute_error_margin: 0.1 + output: + ca_scc_general_assistance_base_amount: 291.55 + +- name: Case 5, single eligible adult shared with two others (20 percent reduction). + period: 2024-01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + households: + household: + members: [person1] + in_scc: true + spm_units: + spm_unit: + members: [person1] + ca_scc_general_assistance_living_arrangement: SHARED_WITH_TWO + absolute_error_margin: 0.1 + output: + ca_scc_general_assistance_base_amount: 274.4 + +- name: Case 6, single eligible adult shared with three or more (25 percent reduction). + period: 2024-01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + households: + household: + members: [person1] + in_scc: true + spm_units: + spm_unit: + members: [person1] + ca_scc_general_assistance_living_arrangement: SHARED_WITH_THREE_OR_MORE + absolute_error_margin: 0.1 + output: + ca_scc_general_assistance_base_amount: 257.25 + +- name: Case 7, married couple shared with one (15 percent reduction on married MAP). + period: 2024-01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + person2: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + households: + household: + members: [person1, person2] + in_scc: true + spm_units: + spm_unit: + members: [person1, person2] + ca_scc_general_assistance_living_arrangement: SHARED_WITH_ONE + absolute_error_margin: 0.1 + output: + ca_scc_general_assistance_base_amount: 391 + +- name: Case 8, married couple shared with two (20 percent reduction on married MAP). + period: 2024-01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + person2: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + households: + household: + members: [person1, person2] + in_scc: true + spm_units: + spm_unit: + members: [person1, person2] + ca_scc_general_assistance_living_arrangement: SHARED_WITH_TWO + absolute_error_margin: 0.1 + output: + # 460 * 0.80 = 368 + ca_scc_general_assistance_base_amount: 368 + +- name: Case 9, married couple shared with three or more (25 percent reduction on married MAP). + period: 2024-01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + person2: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + households: + household: + members: [person1, person2] + in_scc: true + spm_units: + spm_unit: + members: [person1, person2] + ca_scc_general_assistance_living_arrangement: SHARED_WITH_THREE_OR_MORE + absolute_error_margin: 0.1 + output: + # 460 * 0.75 = 345 + ca_scc_general_assistance_base_amount: 345 + +- name: Case 10, single eligible adult in State-licensed Board and Care. + period: 2024-01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + households: + household: + members: [person1] + in_scc: true + spm_units: + spm_unit: + members: [person1] + ca_scc_general_assistance_living_arrangement: BOARD_AND_CARE + absolute_error_margin: 0.1 + output: + # $901 vendor payment + $28 personal needs = $929 total. + ca_scc_general_assistance_base_amount: 929 + +- name: Case 11, single eligible adult in medical institution. + period: 2024-01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + households: + household: + members: [person1] + in_scc: true + spm_units: + spm_unit: + members: [person1] + ca_scc_general_assistance_living_arrangement: MEDICAL_INSTITUTION + absolute_error_margin: 0.1 + output: + # Personal needs only; rest of support covered by Medi-Cal. + ca_scc_general_assistance_base_amount: 11 diff --git a/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance_countable_income.yaml new file mode 100644 index 00000000000..49d9d73f2f7 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance_countable_income.yaml @@ -0,0 +1,60 @@ +- name: Case 1, single head with unearned income. + period: 2024-01 + input: + people: + person1: + is_tax_unit_head_or_spouse: true + social_security: 1_200 + households: + household: + members: [person1] + in_scc: true + spm_units: + spm_unit: + members: [person1] + absolute_error_margin: 0.1 + output: + ca_scc_general_assistance_countable_income: 100 + +- name: Case 2, head and spouse both have unearned income, sums across SPMUnit. + period: 2024-01 + input: + people: + person1: + is_tax_unit_head_or_spouse: true + social_security: 1_200 + person2: + is_tax_unit_head_or_spouse: true + workers_compensation: 2_400 + households: + household: + members: [person1, person2] + in_scc: true + spm_units: + spm_unit: + members: [person1, person2] + absolute_error_margin: 0.1 + output: + # (1_200 + 2_400) / 12 = 300. + ca_scc_general_assistance_countable_income: 300 + +- name: Case 3, dependent child income excluded. + period: 2024-01 + input: + people: + person1: + is_tax_unit_head_or_spouse: true + social_security: 1_200 + person2: + is_tax_unit_head_or_spouse: false + social_security: 6_000 + households: + household: + members: [person1, person2] + in_scc: true + spm_units: + spm_unit: + members: [person1, person2] + absolute_error_margin: 0.1 + output: + ca_scc_general_assistance_countable_income: 100 diff --git a/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance_countable_income_person.yaml b/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance_countable_income_person.yaml new file mode 100644 index 00000000000..412a9d316f4 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance_countable_income_person.yaml @@ -0,0 +1,104 @@ +- name: Case 1, head with unearned income only, no deductions applied. + period: 2024-01 + input: + is_tax_unit_head_or_spouse: true + social_security: 1_200 + in_scc: true + absolute_error_margin: 0.1 + output: + # Unearned income flows through unchanged; 1_200 / 12 = 100. + ca_scc_general_assistance_countable_income_person: 100 + +- name: Case 2, head with multiple unearned sources sums correctly. + period: 2024-01 + input: + is_tax_unit_head_or_spouse: true + social_security: 2_400 + workers_compensation: 600 + in_scc: true + absolute_error_margin: 0.1 + output: + # (2_400 + 600) / 12 = 250. + ca_scc_general_assistance_countable_income_person: 250 + +- name: Case 3, non head or spouse contributes zero. + period: 2024-01 + input: + is_tax_unit_head_or_spouse: false + employment_income: 12_000 + in_scc: true + absolute_error_margin: 0.1 + output: + ca_scc_general_assistance_countable_income_person: 0 + +- name: Case 4, head with zero income. + period: 2024-01 + input: + is_tax_unit_head_or_spouse: true + employment_income: 0 + in_scc: true + absolute_error_margin: 0.1 + output: + ca_scc_general_assistance_countable_income_person: 0 + +- name: Case 5, head with negative self-employment income floors at zero earned, no unearned. + period: 2024-01 + input: + is_tax_unit_head_or_spouse: true + self_employment_income: -12_000 + in_scc: true + absolute_error_margin: 0.1 + output: + # max_(earned - deductions, 0) floors negative earned at 0; no unearned -> 0. + ca_scc_general_assistance_countable_income_person: 0 + +- name: Case 6, head with multiple unearned sources including pension. + period: 2024-01 + input: + is_tax_unit_head_or_spouse: true + social_security: 1_200 + workers_compensation: 600 + taxable_pension_income: 2_400 + in_scc: true + absolute_error_margin: 0.1 + output: + # (1_200 + 600 + 2_400) / 12 = 350. + ca_scc_general_assistance_countable_income_person: 350 + +- name: Case 7, head with truly zero income across all sources. + period: 2024-01 + input: + is_tax_unit_head_or_spouse: true + employment_income: 0 + self_employment_income: 0 + social_security: 0 + in_scc: true + absolute_error_margin: 0.1 + output: + ca_scc_general_assistance_countable_income_person: 0 + +- name: Case 8, head with SSI receipt zeroes out all countable income. + period: 2024-01 + input: + is_tax_unit_head_or_spouse: true + ssi: 500 + social_security: 12_000 + workers_compensation: 6_000 + in_scc: true + absolute_error_margin: 0.1 + output: + # SSI recipient — all income excluded per Responsible Relatives chapter. + ca_scc_general_assistance_countable_income_person: 0 + +- name: Case 9, head with disability benefits, railroad benefits, and CA SDI. + period: 2024-01 + input: + is_tax_unit_head_or_spouse: true + disability_benefits: 1_200 + railroad_benefits: 2_400 + ca_state_disability_insurance: 600 + in_scc: true + absolute_error_margin: 0.1 + output: + # (1_200 + 2_400 + 600) / 12 = 350. + ca_scc_general_assistance_countable_income_person: 350 diff --git a/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance_earned_income_deductions.yaml b/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance_earned_income_deductions.yaml new file mode 100644 index 00000000000..395231e097d --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance_earned_income_deductions.yaml @@ -0,0 +1,56 @@ +- name: Case 1, no earned income produces zero deductions. + period: 2024-01 + input: + is_tax_unit_head_or_spouse: true + employment_income: 0 + self_employment_income: 0 + in_scc: true + absolute_error_margin: 0.1 + output: + ca_scc_general_assistance_earned_income_deductions: 0 + +- name: Case 2, non head or spouse contributes zero deductions. + period: 2024-01 + input: + is_tax_unit_head_or_spouse: false + employment_income: 24_000 + in_scc: true + absolute_error_margin: 0.1 + output: + ca_scc_general_assistance_earned_income_deductions: 0 + +- name: Case 3, unearned income alone does not trigger deductions. + period: 2024-01 + input: + is_tax_unit_head_or_spouse: true + social_security: 12_000 + workers_compensation: 6_000 + in_scc: true + absolute_error_margin: 0.1 + output: + # Deductions only apply to earned income; pure unearned income generates none. + ca_scc_general_assistance_earned_income_deductions: 0 + +- name: Case 4, state withheld income tax is deducted from earned income. + period: 2024-01 + input: + people: + person1: + is_tax_unit_head_or_spouse: true + employment_income: 12_000 + employee_social_security_tax: 0 + employee_medicare_tax: 0 + ca_employee_state_disability_insurance_contribution: 0 + tax_units: + tax_unit: + members: [person1] + income_tax_before_credits: 0 + state_withheld_income_tax: 120 + state_income_tax: 0 + households: + household: + members: [person1] + in_scc: true + absolute_error_margin: 0.1 + output: + ca_scc_general_assistance_earned_income_deductions: 10 diff --git a/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance_eligible.yaml new file mode 100644 index 00000000000..ecb47f0d3f5 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance_eligible.yaml @@ -0,0 +1,139 @@ +- name: Case 1, single eligible adult with zero income. + period: 2024-01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 0 + immigration_status: CITIZEN + households: + household: + members: [person1] + in_scc: true + spm_units: + spm_unit: + members: [person1] + output: + ca_scc_general_assistance_eligible: true + +- name: Case 2, household with minor child — referred to CalWORKs. + period: 2024-01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 0 + immigration_status: CITIZEN + person2: + age: 5 + is_tax_unit_head_or_spouse: false + ssi: 0 + personal_property: 0 + immigration_status: CITIZEN + households: + household: + members: [person1, person2] + in_scc: true + spm_units: + spm_unit: + members: [person1, person2] + output: + # Single mom with a 5-year-old child must apply for CalWORKs per + # Chapter 2 (Eligibility for Other Programs — CalWORKs) and Chapter 9 + # (Potential Income and Resources). + ca_scc_general_assistance_eligible: false + +- name: Case 3, no eligible person in unit (all SSI). + period: 2024-01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 100 + personal_property: 0 + immigration_status: CITIZEN + households: + household: + members: [person1] + in_scc: true + spm_units: + spm_unit: + members: [person1] + output: + ca_scc_general_assistance_eligible: false + +- name: Case 4, income above payment standard — ineligible. + period: 2024-01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 0 + immigration_status: CITIZEN + social_security: 12_000 + households: + household: + members: [person1] + in_scc: true + spm_units: + spm_unit: + members: [person1] + ca_scc_general_assistance_living_arrangement: NOT_SHARED + output: + # $12,000/12 = $1,000 > $343 single MAP -> income-ineligible. + ca_scc_general_assistance_eligible: false + +- name: Case 5, married couple, both eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 0 + immigration_status: CITIZEN + person2: + age: 28 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 0 + immigration_status: CITIZEN + households: + household: + members: [person1, person2] + in_scc: true + spm_units: + spm_unit: + members: [person1, person2] + output: + ca_scc_general_assistance_eligible: true + +- name: Case 6, pregnant adult — referred to CalWORKs. + period: 2024-01 + input: + people: + person1: + age: 26 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 0 + immigration_status: CITIZEN + is_pregnant: true + households: + household: + members: [person1] + in_scc: true + spm_units: + spm_unit: + members: [person1] + output: + # Pregnant women age 19+ must apply for CalWORKs per Chapter 2 — no GA. + ca_scc_general_assistance_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance_eligible_person.yaml b/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance_eligible_person.yaml new file mode 100644 index 00000000000..4765177da49 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance_eligible_person.yaml @@ -0,0 +1,124 @@ +- name: Case 1, single adult citizen with low income, eligible. + period: 2024-01 + input: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + in_scc: true + output: + ca_scc_general_assistance_eligible_person: true + +- name: Case 2, ineligible due to SSI receipt. + period: 2024-01 + input: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 100 + personal_property: 100 + immigration_status: CITIZEN + in_scc: true + output: + ca_scc_general_assistance_eligible_person: false + +- name: Case 3, ineligible because not head or spouse. + period: 2024-01 + input: + age: 30 + is_tax_unit_head_or_spouse: false + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + in_scc: true + output: + ca_scc_general_assistance_eligible_person: false + +- name: Case 4, ineligible due to undocumented status. + period: 2024-01 + input: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: UNDOCUMENTED + in_scc: true + output: + ca_scc_general_assistance_eligible_person: false + +- name: Case 5, ineligible due to age under 18 (blocker short-circuits). + period: 2024-01 + input: + age: 17 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + in_scc: true + output: + ca_scc_general_assistance_eligible_person: false + +- name: Case 6, ineligible due to personal property over $500 (blocker short-circuits). + period: 2024-01 + input: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 501 + immigration_status: CITIZEN + in_scc: true + output: + ca_scc_general_assistance_eligible_person: false + +- name: Case 7, ineligible due to DACA status (blocker short-circuits). + period: 2024-01 + input: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: DACA + in_scc: true + output: + ca_scc_general_assistance_eligible_person: false + +- name: Case 8, eligible with legal permanent resident status (qualified immigration path). + period: 2024-01 + input: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: LEGAL_PERMANENT_RESIDENT + in_scc: true + output: + ca_scc_general_assistance_eligible_person: true + +- name: Case 9, ineligible because eligible for CAPI (parallel cash aid program). + period: 2024-01 + input: + age: 68 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 0 # forces CAPI path for aged LPR + in_scc: true + output: + # Aged LPR without 40 SSI-qualifying quarters is CAPI-eligible. + # Per GA 202, eligibility for another federal/state cash aid program + # disqualifies them from GA. + ca_scc_general_assistance_eligible_person: false + +- name: Case 10, ineligible while actively self-employed. + period: 2024-01 + input: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + is_self_employed: true + in_scc: true + output: + ca_scc_general_assistance_eligible_person: false diff --git a/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance_immigration_status_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance_immigration_status_eligible.yaml new file mode 100644 index 00000000000..541560c42e6 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance_immigration_status_eligible.yaml @@ -0,0 +1,63 @@ +- name: Case 1, citizen is eligible. + period: 2024 + input: + in_scc: true + immigration_status: CITIZEN + output: + ca_scc_general_assistance_immigration_status_eligible: true + +- name: Case 2, legal permanent resident is eligible. + period: 2024 + input: + in_scc: true + immigration_status: LEGAL_PERMANENT_RESIDENT + output: + ca_scc_general_assistance_immigration_status_eligible: true + +- name: Case 3, refugee is eligible. + period: 2024 + input: + in_scc: true + immigration_status: REFUGEE + output: + ca_scc_general_assistance_immigration_status_eligible: true + +- name: Case 4, asylee is eligible. + period: 2024 + input: + in_scc: true + immigration_status: ASYLEE + output: + ca_scc_general_assistance_immigration_status_eligible: true + +- name: Case 5, Cuban/Haitian entrant is eligible. + period: 2024 + input: + in_scc: true + immigration_status: CUBAN_HAITIAN_ENTRANT + output: + ca_scc_general_assistance_immigration_status_eligible: true + +- name: Case 6, paroled one year is ineligible because SCC requires indefinite parole. + period: 2024 + input: + in_scc: true + immigration_status: PAROLED_ONE_YEAR + output: + ca_scc_general_assistance_immigration_status_eligible: false + +- name: Case 7, undocumented is ineligible. + period: 2024 + input: + in_scc: true + immigration_status: UNDOCUMENTED + output: + ca_scc_general_assistance_immigration_status_eligible: false + +- name: Case 8, DACA is ineligible. + period: 2024 + input: + in_scc: true + immigration_status: DACA + output: + ca_scc_general_assistance_immigration_status_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance_income_eligible.yaml new file mode 100644 index 00000000000..3747df14375 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance_income_eligible.yaml @@ -0,0 +1,62 @@ +- name: Case 1, countable income below single MAP, eligible. + period: 2024-01 + input: + ca_scc_general_assistance_countable_income: 342 + ca_scc_general_assistance_base_amount: 343 + in_scc: true + output: + ca_scc_general_assistance_income_eligible: true + +- name: Case 2, countable income equal to single MAP, eligible (GA 200 ineligible only when income exceeds MAP). + period: 2024-01 + input: + ca_scc_general_assistance_countable_income: 343 + ca_scc_general_assistance_base_amount: 343 + in_scc: true + output: + ca_scc_general_assistance_income_eligible: true + +- name: Case 3, countable income above single MAP, ineligible. + period: 2024-01 + input: + ca_scc_general_assistance_countable_income: 344 + ca_scc_general_assistance_base_amount: 343 + in_scc: true + output: + ca_scc_general_assistance_income_eligible: false + +- name: Case 4, countable income below married MAP, eligible. + period: 2024-01 + input: + ca_scc_general_assistance_countable_income: 459 + ca_scc_general_assistance_base_amount: 460 + in_scc: true + output: + ca_scc_general_assistance_income_eligible: true + +- name: Case 5, zero countable income with single MAP, eligible. + period: 2024-01 + input: + ca_scc_general_assistance_countable_income: 0 + ca_scc_general_assistance_base_amount: 343 + in_scc: true + output: + ca_scc_general_assistance_income_eligible: true + +- name: Case 6, married MAP one cent above threshold, ineligible. + period: 2024-01 + input: + ca_scc_general_assistance_countable_income: 460.01 + ca_scc_general_assistance_base_amount: 460 + in_scc: true + output: + ca_scc_general_assistance_income_eligible: false + +- name: Case 7, income far above threshold, ineligible. + period: 2024-01 + input: + ca_scc_general_assistance_countable_income: 10_000 + ca_scc_general_assistance_base_amount: 343 + in_scc: true + output: + ca_scc_general_assistance_income_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance_personal_property_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance_personal_property_eligible.yaml new file mode 100644 index 00000000000..acbf47c414c --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/ca_scc_general_assistance_personal_property_eligible.yaml @@ -0,0 +1,63 @@ +- name: Case 1, personal property below $500 limit, eligible. + period: 2024-01 + input: + personal_property: 499 + in_scc: true + output: + ca_scc_general_assistance_personal_property_eligible: true + +- name: Case 2, personal property at $500 limit, eligible (at-or-below). + period: 2024-01 + input: + personal_property: 500 + in_scc: true + output: + ca_scc_general_assistance_personal_property_eligible: true + +- name: Case 3, personal property above $500 limit, ineligible. + period: 2024-01 + input: + personal_property: 501 + in_scc: true + output: + ca_scc_general_assistance_personal_property_eligible: false + +- name: Case 4, personal property well above $500 limit, ineligible. + period: 2024-01 + input: + personal_property: 1_000 + in_scc: true + output: + ca_scc_general_assistance_personal_property_eligible: false + +- name: Case 5, zero personal property, eligible. + period: 2024-01 + input: + personal_property: 0 + in_scc: true + output: + ca_scc_general_assistance_personal_property_eligible: true + +- name: Case 6, personal property exactly $500.00, eligible at boundary (at-or-below). + period: 2024-01 + input: + personal_property: 500.00 + in_scc: true + output: + ca_scc_general_assistance_personal_property_eligible: true + +- name: Case 7, personal property $500.01 (one cent over), ineligible. + period: 2024-01 + input: + personal_property: 500.01 + in_scc: true + output: + ca_scc_general_assistance_personal_property_eligible: false + +- name: Case 8, very large personal property, ineligible. + period: 2024-01 + input: + personal_property: 1_000_000 + in_scc: true + output: + ca_scc_general_assistance_personal_property_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/integration.yaml b/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/integration.yaml new file mode 100644 index 00000000000..2eaba136180 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/local/ca/scc/ga/integration.yaml @@ -0,0 +1,662 @@ +- name: Case 1, eligible single adult with zero income receives full single MAP. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + households: + household: + members: [person1] + in_scc: true + spm_units: + spm_unit: + members: [person1] + ca_scc_general_assistance_living_arrangement: NOT_SHARED + output: + ca_scc_general_assistance_base_amount: 343 + ca_scc_general_assistance_countable_income: 0 + ca_scc_general_assistance: 343 + +- name: Case 2, eligible single adult with $100/month unearned income, fill-the-gap benefit. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + social_security: 1_200 + households: + household: + members: [person1] + in_scc: true + spm_units: + spm_unit: + members: [person1] + ca_scc_general_assistance_living_arrangement: NOT_SHARED + output: + ca_scc_general_assistance_base_amount: 343 + ca_scc_general_assistance_countable_income: 100 + ca_scc_general_assistance: 243 + +- name: Case 3, eligible married couple with zero income receives full married MAP. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + person2: + age: 28 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + households: + household: + members: [person1, person2] + in_scc: true + spm_units: + spm_unit: + members: [person1, person2] + ca_scc_general_assistance_living_arrangement: NOT_SHARED + output: + ca_scc_general_assistance_base_amount: 460 + ca_scc_general_assistance_countable_income: 0 + ca_scc_general_assistance: 460 + +- name: Case 4, ineligible due to SSI receipt. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 100 + personal_property: 100 + immigration_status: CITIZEN + households: + household: + members: [person1] + in_scc: true + spm_units: + spm_unit: + members: [person1] + ca_scc_general_assistance_living_arrangement: NOT_SHARED + output: + ca_scc_general_assistance: 0 + +- name: Case 5, ineligible due to personal property over $500 limit. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 501 + immigration_status: CITIZEN + households: + household: + members: [person1] + in_scc: true + spm_units: + spm_unit: + members: [person1] + ca_scc_general_assistance_living_arrangement: NOT_SHARED + output: + ca_scc_general_assistance: 0 + +- name: Case 6, ineligible due to undocumented immigration status. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: UNDOCUMENTED + households: + household: + members: [person1] + in_scc: true + spm_units: + spm_unit: + members: [person1] + ca_scc_general_assistance_living_arrangement: NOT_SHARED + output: + ca_scc_general_assistance: 0 + +- name: Case 7, single eligible adult sharing housing with one other, MAP reduced 15 percent. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + households: + household: + members: [person1] + in_scc: true + spm_units: + spm_unit: + members: [person1] + ca_scc_general_assistance_living_arrangement: SHARED_WITH_ONE + output: + ca_scc_general_assistance_base_amount: 291.55 + ca_scc_general_assistance_countable_income: 0 + ca_scc_general_assistance: 291.55 + +- name: Case 8, expanded income source workers_compensation counted in countable income. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + workers_compensation: 2_400 + households: + household: + members: [person1] + in_scc: true + spm_units: + spm_unit: + members: [person1] + ca_scc_general_assistance_living_arrangement: NOT_SHARED + output: + ca_scc_general_assistance_base_amount: 343 + ca_scc_general_assistance_countable_income: 200 + ca_scc_general_assistance: 143 + +- name: Case 9, household with minor child — referred to CalWORKs, ineligible for GA. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 35 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 50 + immigration_status: CITIZEN + person2: + age: 32 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 50 + immigration_status: CITIZEN + person3: + age: 5 + is_tax_unit_head_or_spouse: false + ssi: 0 + personal_property: 0 + immigration_status: CITIZEN + households: + household: + members: [person1, person2, person3] + in_scc: true + spm_units: + spm_unit: + members: [person1, person2, person3] + ca_scc_general_assistance_living_arrangement: NOT_SHARED + output: + # Per Chapter 2 (Eligibility for Other Programs — CalWORKs) and Chapter 9 + # (Potential Income and Resources), households with physical custody of a + # minor child must apply for CalWORKs and are not eligible for GA. + ca_scc_general_assistance_eligible: false + ca_scc_general_assistance: 0 + +- name: Case 10, two-adult SPMUnit with one undocumented spouse — only eligible person counted. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 50 + immigration_status: CITIZEN + person2: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 50 + immigration_status: UNDOCUMENTED + households: + household: + members: [person1, person2] + in_scc: true + spm_units: + spm_unit: + members: [person1, person2] + ca_scc_general_assistance_living_arrangement: NOT_SHARED + output: + # Only person1 is eligible; num_eligible == 1 -> single MAP $343. + ca_scc_general_assistance_base_amount: 343 + ca_scc_general_assistance_countable_income: 0 + ca_scc_general_assistance: 343 + +- name: Case 11, SPMUnit-level shared housing reduction applies once across all members. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 40 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + person2: + age: 38 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + households: + household: + members: [person1, person2] + in_scc: true + spm_units: + spm_unit: + members: [person1, person2] + # Shared with two other persons -> 20% reduction on married MAP. + ca_scc_general_assistance_living_arrangement: SHARED_WITH_TWO + output: + # 460 * 0.80 = 368; countable income = 0; benefit = 368. + ca_scc_general_assistance_base_amount: 368 + ca_scc_general_assistance_countable_income: 0 + ca_scc_general_assistance: 368 + +- name: Case 12, Board and Care recipient — absolute amount overrides standard formula. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 50 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + households: + household: + members: [person1] + in_scc: true + spm_units: + spm_unit: + members: [person1] + ca_scc_general_assistance_living_arrangement: BOARD_AND_CARE + output: + # Override skips the single/married + shared housing formula. + ca_scc_general_assistance_base_amount: 929 + ca_scc_general_assistance_countable_income: 0 + ca_scc_general_assistance: 929 + +- name: Case 13, single adult with income exactly at MAP — eligible with zero fill-the-gap. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + # 343 * 12 = 4116 annual → 343/month + social_security: 4_116 + households: + household: + members: [person1] + in_scc: true + spm_units: + spm_unit: + members: [person1] + ca_scc_general_assistance_living_arrangement: NOT_SHARED + output: + # Income exactly equals MAP; per GA 200 "exceeds" is the bar (income > MAP). + ca_scc_general_assistance_income_eligible: true + ca_scc_general_assistance_base_amount: 343 + ca_scc_general_assistance_countable_income: 343 + ca_scc_general_assistance: 0 + +- name: Case 14, undocumented spouse income IS included in GA applicant's budget. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 50 + immigration_status: CITIZEN + person2: + # Per Responsible Relatives "Undocumented Non-citizen Spouse": + # immigration status does not affect spouse-for-spouse responsibility. + # Spouse is not personally eligible, but their income still counts. + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 50 + immigration_status: UNDOCUMENTED + social_security: 1_200 # 100/month + households: + household: + members: [person1, person2] + in_scc: true + spm_units: + spm_unit: + members: [person1, person2] + ca_scc_general_assistance_living_arrangement: NOT_SHARED + output: + # Only person1 is eligible → single MAP $343. + # Undocumented spouse's $100/month social_security still flows into budget. + ca_scc_general_assistance_base_amount: 343 + ca_scc_general_assistance_countable_income: 100 + ca_scc_general_assistance: 243 + +- name: Case 15, SSI-receiving spouse income excluded from GA applicant's budget. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + person2: + # SSI-receiving spouse — per Responsible Relatives chapter, their income + # and property are excluded from the GA applicant's eligibility budget. + age: 67 + is_tax_unit_head_or_spouse: true + ssi: 900 + personal_property: 100 + immigration_status: CITIZEN + social_security: 12_000 # 1_000/month — would otherwise count + households: + household: + members: [person1, person2] + in_scc: true + spm_units: + spm_unit: + members: [person1, person2] + ca_scc_general_assistance_living_arrangement: NOT_SHARED + output: + # Only person1 (non-SSI spouse) is GA-eligible → single MAP. + # Person2's $1,000/month social_security is excluded → countable_income = 0. + ca_scc_general_assistance_base_amount: 343 + ca_scc_general_assistance_countable_income: 0 + ca_scc_general_assistance: 343 + +- name: Case 16, single mother with 5-year-old child — referred to CalWORKs. + period: 2026-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 28 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 0 + immigration_status: CITIZEN + person2: + age: 5 + is_tax_unit_head_or_spouse: false + ssi: 0 + personal_property: 0 + immigration_status: CITIZEN + households: + household: + members: [person1, person2] + in_scc: true + spm_units: + spm_unit: + members: [person1, person2] + ca_scc_general_assistance_living_arrangement: NOT_SHARED + output: + # Per Chapter 2 and Chapter 9, single parent with custody of a minor child + # must apply for CalWORKs and is structurally not eligible for GA. + ca_scc_general_assistance_eligible: false + ca_scc_general_assistance: 0 + +- name: Case 17, pregnant single woman — referred to CalWORKs. + period: 2026-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 24 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 0 + immigration_status: CITIZEN + is_pregnant: true + households: + household: + members: [person1] + in_scc: true + spm_units: + spm_unit: + members: [person1] + ca_scc_general_assistance_living_arrangement: NOT_SHARED + output: + # Pregnant women age 19+ must apply for CalWORKs per Chapter 2. + ca_scc_general_assistance_eligible: false + ca_scc_general_assistance: 0 + +- name: Case 18, aged LPR without 40 SSI quarters — CAPI-eligible, ineligible for GA. + period: 2026-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 68 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 0 + households: + household: + members: [person1] + in_scc: true + spm_units: + spm_unit: + members: [person1] + ca_scc_general_assistance_living_arrangement: NOT_SHARED + output: + # Per GA 202, eligibility for another federal/state cash aid program + # (CAPI for aged/blind/disabled noncitizens without 40 SSI quarters) + # disqualifies the person from GA. + ca_scc_general_assistance_eligible: false + ca_scc_general_assistance: 0 + +- name: Case 19, single adult living with elderly SSI parent — applicant gets single MAP. + period: 2026-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 42 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + person2: + age: 78 + is_tax_unit_head_or_spouse: true + ssi: 900 + personal_property: 0 + immigration_status: CITIZEN + social_security: 12_000 + households: + household: + members: [person1, person2] + in_scc: true + spm_units: + spm_unit: + members: [person1, person2] + ca_scc_general_assistance_living_arrangement: NOT_SHARED + output: + # Elderly parent receives SSI -> fails SSI gate, excluded from num_eligible. + # Parent's $1,000/month Social Security is excluded from countable income + # (SSI recipient rule). Only person1 is eligible -> single MAP $343. + ca_scc_general_assistance_base_amount: 343 + ca_scc_general_assistance_countable_income: 0 + ca_scc_general_assistance: 343 + +- name: Case 20, married couple plus adult college-aged child — couple gets married MAP. + period: 2026-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 50 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 50 + immigration_status: CITIZEN + person2: + age: 48 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 50 + immigration_status: CITIZEN + person3: + age: 22 + is_tax_unit_head_or_spouse: false + ssi: 0 + personal_property: 0 + immigration_status: CITIZEN + households: + household: + members: [person1, person2, person3] + in_scc: true + spm_units: + spm_unit: + members: [person1, person2, person3] + ca_scc_general_assistance_living_arrangement: NOT_SHARED + output: + # Adult child (22) is not a minor and not head/spouse -> doesn't trigger + # CalWORKs gate and doesn't add to num_eligible. Couple gets married MAP. + ca_scc_general_assistance_eligible: true + ca_scc_general_assistance_base_amount: 460 + ca_scc_general_assistance: 460 + +- name: Case 21, single adult sharing housing with three roommates — 25 percent reduction. + period: 2026-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 32 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 100 + immigration_status: CITIZEN + households: + household: + members: [person1] + in_scc: true + spm_units: + spm_unit: + members: [person1] + ca_scc_general_assistance_living_arrangement: SHARED_WITH_THREE_OR_MORE + output: + # 343 * 0.75 = 257.25 + ca_scc_general_assistance_base_amount: 257.25 + ca_scc_general_assistance: 257.25 + +- name: Case 22, three-generation household with minor grandchild — ineligible. + period: 2026-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 60 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 50 + immigration_status: CITIZEN + person2: + age: 35 + is_tax_unit_head_or_spouse: false + ssi: 0 + personal_property: 50 + immigration_status: CITIZEN + person3: + age: 8 + is_tax_unit_head_or_spouse: false + ssi: 0 + personal_property: 0 + immigration_status: CITIZEN + households: + household: + members: [person1, person2, person3] + in_scc: true + spm_units: + spm_unit: + members: [person1, person2, person3] + ca_scc_general_assistance_living_arrangement: NOT_SHARED + output: + # Minor grandchild in SPM unit triggers the CalWORKs referral rule. + # Whole unit is ineligible, even though the grandparent applicant is + # not the child's parent. + ca_scc_general_assistance_eligible: false + ca_scc_general_assistance: 0 + +- name: Case 23, older single citizen with $250/month Social Security — partial benefit. + period: 2026-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 63 + is_tax_unit_head_or_spouse: true + ssi: 0 + personal_property: 0 + immigration_status: CITIZEN + social_security: 3_000 + households: + household: + members: [person1] + in_scc: true + spm_units: + spm_unit: + members: [person1] + ca_scc_general_assistance_living_arrangement: NOT_SHARED + output: + # 3_000 / 12 = 250 monthly unearned (no deductions on unearned). + # benefit = 343 - 250 = 93. + ca_scc_general_assistance_base_amount: 343 + ca_scc_general_assistance_countable_income: 250 + ca_scc_general_assistance: 93 diff --git a/policyengine_us/tests/policy/baseline/gov/local/ca/scc/in_scc.yaml b/policyengine_us/tests/policy/baseline/gov/local/ca/scc/in_scc.yaml new file mode 100644 index 00000000000..e0cc5d3033d --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/local/ca/scc/in_scc.yaml @@ -0,0 +1,13 @@ +- name: Santa Clara County is True + period: 2026 + input: + county_str: SANTA_CLARA_COUNTY_CA + output: + in_scc: true + +- name: Not Santa Clara County is False + period: 2026 + input: + county_str: LOS_ANGELES_COUNTY_CA + output: + in_scc: false diff --git a/policyengine_us/variables/gov/local/ca/scc/ga/ca_scc_general_assistance.py b/policyengine_us/variables/gov/local/ca/scc/ga/ca_scc_general_assistance.py new file mode 100644 index 00000000000..490791d89b5 --- /dev/null +++ b/policyengine_us/variables/gov/local/ca/scc/ga/ca_scc_general_assistance.py @@ -0,0 +1,16 @@ +from policyengine_us.model_api import * + + +class ca_scc_general_assistance(Variable): + value_type = float + entity = SPMUnit + unit = USD + definition_period = MONTH + label = "Santa Clara County General Assistance" + defined_for = "ca_scc_general_assistance_eligible" + reference = "https://stgenssa.sccgov.org/debs/program_handbooks/general_assistance/assets/01Policy/Policy.htm" + + def formula(spm_unit, period, parameters): + base = spm_unit("ca_scc_general_assistance_base_amount", period) + countable = spm_unit("ca_scc_general_assistance_countable_income", period) + return base - max_(countable, 0) diff --git a/policyengine_us/variables/gov/local/ca/scc/ga/ca_scc_general_assistance_base_amount.py b/policyengine_us/variables/gov/local/ca/scc/ga/ca_scc_general_assistance_base_amount.py new file mode 100644 index 00000000000..bf3fb2ecdfc --- /dev/null +++ b/policyengine_us/variables/gov/local/ca/scc/ga/ca_scc_general_assistance_base_amount.py @@ -0,0 +1,40 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.local.ca.scc.ga.ca_scc_general_assistance_living_arrangement import ( + CaSccGeneralAssistanceLivingArrangement, +) + + +class ca_scc_general_assistance_base_amount(Variable): + value_type = float + entity = SPMUnit + unit = USD + definition_period = MONTH + label = "Santa Clara County General Assistance base amount" + defined_for = "ca_scc_general_assistance_eligible_person" + reference = ( + "https://stgenssa.sccgov.org/debs/program_handbooks/charts/assets/4GA/NeedStnds.htm", + "https://stgenssa.sccgov.org/debs/Forms/GA_62_en.pdf#page=2", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.local.ca.scc.general_assistance + eligible_persons = spm_unit.members( + "ca_scc_general_assistance_eligible_person", period + ) + num_eligible = spm_unit.sum(eligible_persons) + unshared = where(num_eligible >= 2, p.amount.married, p.amount.single) + arrangement = spm_unit("ca_scc_general_assistance_living_arrangement", period) + reduction = p.shared_housing.reduction[arrangement] + standard = unshared * (1 - reduction) + return select( + [ + arrangement == CaSccGeneralAssistanceLivingArrangement.BOARD_AND_CARE, + arrangement + == CaSccGeneralAssistanceLivingArrangement.MEDICAL_INSTITUTION, + ], + [ + p.amount.board_and_care, + p.amount.medical_institution, + ], + default=standard, + ) diff --git a/policyengine_us/variables/gov/local/ca/scc/ga/ca_scc_general_assistance_living_arrangement.py b/policyengine_us/variables/gov/local/ca/scc/ga/ca_scc_general_assistance_living_arrangement.py new file mode 100644 index 00000000000..f9d1fe62dbc --- /dev/null +++ b/policyengine_us/variables/gov/local/ca/scc/ga/ca_scc_general_assistance_living_arrangement.py @@ -0,0 +1,23 @@ +from policyengine_us.model_api import * + + +class CaSccGeneralAssistanceLivingArrangement(Enum): + NOT_SHARED = "Not shared" + SHARED_WITH_ONE = "Shared with one other person" + SHARED_WITH_TWO = "Shared with two other persons" + SHARED_WITH_THREE_OR_MORE = "Shared with three or more other persons" + BOARD_AND_CARE = "State-licensed Board and Care or Residential Care Home" + MEDICAL_INSTITUTION = "Medical institution" + + +class ca_scc_general_assistance_living_arrangement(Variable): + value_type = Enum + entity = SPMUnit + possible_values = CaSccGeneralAssistanceLivingArrangement + default_value = CaSccGeneralAssistanceLivingArrangement.NOT_SHARED + definition_period = MONTH + label = "Santa Clara County General Assistance living arrangement" + reference = ( + "https://stgenssa.sccgov.org/debs/program_handbooks/charts/assets/4GA/NeedStnds.htm", + "https://stgenssa.sccgov.org/debs/Forms/GA_62_en.pdf#page=2", + ) diff --git a/policyengine_us/variables/gov/local/ca/scc/ga/eligibility/ca_scc_general_assistance_age_eligible.py b/policyengine_us/variables/gov/local/ca/scc/ga/eligibility/ca_scc_general_assistance_age_eligible.py new file mode 100644 index 00000000000..f50388bcb8a --- /dev/null +++ b/policyengine_us/variables/gov/local/ca/scc/ga/eligibility/ca_scc_general_assistance_age_eligible.py @@ -0,0 +1,17 @@ +from policyengine_us.model_api import * + + +class ca_scc_general_assistance_age_eligible(Variable): + value_type = bool + entity = Person + definition_period = MONTH + label = ( + "Eligible for Santa Clara County General Assistance based on age requirements" + ) + defined_for = "in_scc" + reference = "https://stgenssa.sccgov.org/debs/program_handbooks/general_assistance/assets/01Policy/Policy.htm" + + def formula(person, period, parameters): + p = parameters(period).gov.local.ca.scc.general_assistance + age = person("monthly_age", period) + return age >= p.age_threshold diff --git a/policyengine_us/variables/gov/local/ca/scc/ga/eligibility/ca_scc_general_assistance_eligible.py b/policyengine_us/variables/gov/local/ca/scc/ga/eligibility/ca_scc_general_assistance_eligible.py new file mode 100644 index 00000000000..2ba9e92ec99 --- /dev/null +++ b/policyengine_us/variables/gov/local/ca/scc/ga/eligibility/ca_scc_general_assistance_eligible.py @@ -0,0 +1,26 @@ +from policyengine_us.model_api import * + + +class ca_scc_general_assistance_eligible(Variable): + value_type = bool + entity = SPMUnit + definition_period = MONTH + label = "Eligible for Santa Clara County General Assistance" + defined_for = "in_scc" + reference = ( + "https://stgenssa.sccgov.org/debs/program_handbooks/general_assistance/assets/02Application/Application_Process.htm", + "https://stgenssa.sccgov.org/debs/program_handbooks/general_assistance/assets/09Income/Potential_Inc_Res.htm", + ) + + def formula(spm_unit, period, parameters): + # Per Chapter 2 (Eligibility for Other Programs — CalWORKs) and + # Chapter 9 (Potential Income and Resources), households with a + # minor child or pregnant adult must first apply for CalWORKs. + # Only households that would not qualify for CalWORKs can fall + # back to General Assistance. + ca_tanf_eligible = spm_unit("ca_tanf_eligible", period.this_year) + has_eligible_person = ( + add(spm_unit, period, ["ca_scc_general_assistance_eligible_person"]) > 0 + ) + income_eligible = spm_unit("ca_scc_general_assistance_income_eligible", period) + return ~ca_tanf_eligible & has_eligible_person & income_eligible diff --git a/policyengine_us/variables/gov/local/ca/scc/ga/eligibility/ca_scc_general_assistance_eligible_person.py b/policyengine_us/variables/gov/local/ca/scc/ga/eligibility/ca_scc_general_assistance_eligible_person.py new file mode 100644 index 00000000000..ac54bf6e061 --- /dev/null +++ b/policyengine_us/variables/gov/local/ca/scc/ga/eligibility/ca_scc_general_assistance_eligible_person.py @@ -0,0 +1,35 @@ +from policyengine_us.model_api import * + + +class ca_scc_general_assistance_eligible_person(Variable): + value_type = bool + entity = Person + definition_period = MONTH + label = "Eligible person for Santa Clara County General Assistance" + defined_for = "in_scc" + reference = "https://stgenssa.sccgov.org/debs/program_handbooks/general_assistance/assets/01Policy/Policy.htm" + + def formula(person, period, parameters): + age_eligible = person("ca_scc_general_assistance_age_eligible", period) + personal_property_eligible = person.spm_unit( + "ca_scc_general_assistance_personal_property_eligible", period + ) + immigration_status_eligible = person( + "ca_scc_general_assistance_immigration_status_eligible", period + ) + receives_ssi = person("ssi", period) > 0 + # Per GA 202, persons eligible for another federal or state cash aid + # program (here: CAPI for aged/blind/disabled noncitizens) are not + # eligible for General Assistance. + capi_eligible = person("ca_capi_eligible_person", period) + is_self_employed = person("is_self_employed", period.this_year) + is_head_or_spouse = person("is_tax_unit_head_or_spouse", period) + return ( + age_eligible + & personal_property_eligible + & immigration_status_eligible + & ~receives_ssi + & ~capi_eligible + & ~is_self_employed + & is_head_or_spouse + ) diff --git a/policyengine_us/variables/gov/local/ca/scc/ga/eligibility/ca_scc_general_assistance_immigration_status_eligible.py b/policyengine_us/variables/gov/local/ca/scc/ga/eligibility/ca_scc_general_assistance_immigration_status_eligible.py new file mode 100644 index 00000000000..f321dbe9a4e --- /dev/null +++ b/policyengine_us/variables/gov/local/ca/scc/ga/eligibility/ca_scc_general_assistance_immigration_status_eligible.py @@ -0,0 +1,25 @@ +from policyengine_us.model_api import * + + +class ca_scc_general_assistance_immigration_status_eligible(Variable): + value_type = bool + entity = Person + definition_period = MONTH + label = ( + "Eligible for Santa Clara County General Assistance based on immigration status" + ) + defined_for = "in_scc" + reference = "https://stgenssa.sccgov.org/debs/program_handbooks/general_assistance/assets/07Citizens_Noncitizens/Non_Citizen_Status.htm" + + def formula(person, period, parameters): + # GA 141 limits eligibility to noncitizens with the right to remain + # permanently or indefinitely. The handbook excludes parolees admitted + # "for a specific period of time" — only indefinite-period parolees + # qualify. PAROLED_ONE_YEAR is kept in the qualified list because the + # PolicyEngine enum represents "Paroled for at Least One Year," which + # is typically renewed indefinitely in practice; partners should treat + # short fixed-term parolees as UNDOCUMENTED for SCC GA purposes. + p = parameters(period).gov.local.ca.scc.general_assistance + immigration_status = person("immigration_status", period.this_year) + immigration_status_str = immigration_status.decode_to_str() + return np.isin(immigration_status_str, p.qualified_immigration_status) diff --git a/policyengine_us/variables/gov/local/ca/scc/ga/eligibility/ca_scc_general_assistance_income_eligible.py b/policyengine_us/variables/gov/local/ca/scc/ga/eligibility/ca_scc_general_assistance_income_eligible.py new file mode 100644 index 00000000000..d381f558d7f --- /dev/null +++ b/policyengine_us/variables/gov/local/ca/scc/ga/eligibility/ca_scc_general_assistance_income_eligible.py @@ -0,0 +1,15 @@ +from policyengine_us.model_api import * + + +class ca_scc_general_assistance_income_eligible(Variable): + value_type = bool + entity = SPMUnit + definition_period = MONTH + label = "Eligible for Santa Clara County General Assistance based on income requirements" + defined_for = "in_scc" + reference = "https://stgenssa.sccgov.org/debs/program_handbooks/general_assistance/assets/01Policy/Policy.htm" + + def formula(spm_unit, period, parameters): + income = spm_unit("ca_scc_general_assistance_countable_income", period) + limit = spm_unit("ca_scc_general_assistance_base_amount", period) + return income <= limit diff --git a/policyengine_us/variables/gov/local/ca/scc/ga/eligibility/ca_scc_general_assistance_personal_property_eligible.py b/policyengine_us/variables/gov/local/ca/scc/ga/eligibility/ca_scc_general_assistance_personal_property_eligible.py new file mode 100644 index 00000000000..a163abe91a3 --- /dev/null +++ b/policyengine_us/variables/gov/local/ca/scc/ga/eligibility/ca_scc_general_assistance_personal_property_eligible.py @@ -0,0 +1,15 @@ +from policyengine_us.model_api import * + + +class ca_scc_general_assistance_personal_property_eligible(Variable): + value_type = bool + entity = SPMUnit + definition_period = MONTH + label = "Meets property limit for Santa Clara County General Assistance" + defined_for = "in_scc" + reference = "https://stgenssa.sccgov.org/debs/program_handbooks/general_assistance/assets/08Property/Personal_Property.htm" + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.local.ca.scc.general_assistance.personal_property + personal_property = add(spm_unit, period.this_year, ["personal_property"]) + return personal_property <= p.limit diff --git a/policyengine_us/variables/gov/local/ca/scc/ga/income/ca_scc_general_assistance_countable_income.py b/policyengine_us/variables/gov/local/ca/scc/ga/income/ca_scc_general_assistance_countable_income.py new file mode 100644 index 00000000000..b5fff7fd44d --- /dev/null +++ b/policyengine_us/variables/gov/local/ca/scc/ga/income/ca_scc_general_assistance_countable_income.py @@ -0,0 +1,13 @@ +from policyengine_us.model_api import * + + +class ca_scc_general_assistance_countable_income(Variable): + value_type = float + entity = SPMUnit + unit = USD + definition_period = MONTH + label = "Santa Clara County General Assistance countable income" + defined_for = "in_scc" + reference = "https://stgenssa.sccgov.org/debs/program_handbooks/general_assistance/assets/09Income/GA_Policies.htm" + + adds = ["ca_scc_general_assistance_countable_income_person"] diff --git a/policyengine_us/variables/gov/local/ca/scc/ga/income/ca_scc_general_assistance_countable_income_person.py b/policyengine_us/variables/gov/local/ca/scc/ga/income/ca_scc_general_assistance_countable_income_person.py new file mode 100644 index 00000000000..b9536e34b89 --- /dev/null +++ b/policyengine_us/variables/gov/local/ca/scc/ga/income/ca_scc_general_assistance_countable_income_person.py @@ -0,0 +1,25 @@ +from policyengine_us.model_api import * + + +class ca_scc_general_assistance_countable_income_person(Variable): + value_type = float + entity = Person + unit = USD + definition_period = MONTH + label = "Santa Clara County General Assistance countable income for each person" + defined_for = "is_tax_unit_head_or_spouse" + reference = ( + "https://stgenssa.sccgov.org/debs/program_handbooks/general_assistance/assets/09Income/Types_Income.htm", + "https://stgenssa.sccgov.org/debs/program_handbooks/general_assistance/assets/02Application/Responsible_Relatives.htm", + ) + + def formula(person, period, parameters): + p = parameters(period).gov.local.ca.scc.general_assistance.countable_income + earned = add(person, period, p.earned_sources) + deductions = person( + "ca_scc_general_assistance_earned_income_deductions", period + ) + unearned = add(person, period, p.unearned_sources) + net_earned = max_(earned - deductions, 0) + receives_ssi = person("ssi", period) > 0 + return (net_earned + unearned) * ~receives_ssi diff --git a/policyengine_us/variables/gov/local/ca/scc/ga/income/ca_scc_general_assistance_earned_income_deductions.py b/policyengine_us/variables/gov/local/ca/scc/ga/income/ca_scc_general_assistance_earned_income_deductions.py new file mode 100644 index 00000000000..ddb5f41771c --- /dev/null +++ b/policyengine_us/variables/gov/local/ca/scc/ga/income/ca_scc_general_assistance_earned_income_deductions.py @@ -0,0 +1,27 @@ +from policyengine_us.model_api import * + + +class ca_scc_general_assistance_earned_income_deductions(Variable): + value_type = float + entity = Person + unit = USD + definition_period = MONTH + label = "Santa Clara County General Assistance earned income deductions" + defined_for = "is_tax_unit_head_or_spouse" + reference = ( + "https://stgenssa.sccgov.org/debs/program_handbooks/general_assistance/assets/01Policy/Policy.htm", + "https://stgenssa.sccgov.org/debs/program_handbooks/general_assistance/assets/09Income/Verification_Income.htm", + ) + + def formula(person, period, parameters): + p = parameters(period).gov.local.ca.scc.general_assistance.countable_income + person_level = add(person, period, p.earned_deductions.person_sources) + # Apportion tax-unit-level federal and state income tax across spouses + # by each person's share of tax-unit earned income, so both spouses' + # earnings are reduced proportionally by their involuntary withholding. + person_earned = add(person, period, p.earned_sources) + tax_unit_earned = person.tax_unit("tax_unit_earned_income", period) + share = where(tax_unit_earned > 0, person_earned / tax_unit_earned, 0) + federal_tax = person.tax_unit("income_tax_before_credits", period) * share + state_tax = person.tax_unit("state_withheld_income_tax", period) * share + return person_level + federal_tax + state_tax diff --git a/policyengine_us/variables/gov/local/ca/scc/in_scc.py b/policyengine_us/variables/gov/local/ca/scc/in_scc.py new file mode 100644 index 00000000000..bbb99bfec88 --- /dev/null +++ b/policyengine_us/variables/gov/local/ca/scc/in_scc.py @@ -0,0 +1,12 @@ +from policyengine_us.model_api import * + + +class in_scc(Variable): + value_type = bool + entity = Household + definition_period = YEAR + label = "Is in Santa Clara County" + + def formula(household, period, parameters): + county = household("county_str", period) + return county == "SANTA_CLARA_COUNTY_CA" diff --git a/uv.lock b/uv.lock index 3469ec5e071..55e5a5cd8e4 100644 --- a/uv.lock +++ b/uv.lock @@ -2974,7 +2974,7 @@ wheels = [ [[package]] name = "policyengine-us" -version = "1.702.1" +version = "1.707.1" source = { editable = "." } dependencies = [ { name = "microdf-python" },