diff --git a/changelog.d/riv-gr-property-boundary-500.fixed.md b/changelog.d/riv-gr-property-boundary-500.fixed.md new file mode 100644 index 00000000000..71a81a7782a --- /dev/null +++ b/changelog.d/riv-gr-property-boundary-500.fixed.md @@ -0,0 +1 @@ +Make Riverside County General Relief eligible at exactly $500 of total combined countable property, since the DPSS fact sheet says the total cannot exceed $500. diff --git a/policyengine_us/parameters/gov/local/ca/riv/general_relief/property/limit.yaml b/policyengine_us/parameters/gov/local/ca/riv/general_relief/property/limit.yaml index fb99a292a9f..30d2ded334d 100644 --- a/policyengine_us/parameters/gov/local/ca/riv/general_relief/property/limit.yaml +++ b/policyengine_us/parameters/gov/local/ca/riv/general_relief/property/limit.yaml @@ -1,4 +1,4 @@ -description: Riverside County limits General Relief to filers with property value below this amount. +description: Riverside County limits General Relief to units whose total combined countable property does not exceed this amount. values: 2020-01-01: 500 @@ -10,3 +10,5 @@ metadata: reference: # The program manual is not publicly available - title: General Assistance Eligibility p.22 + - title: Riverside County DPSS General Assistance fact sheet (archived 2021-07-13) + href: https://web.archive.org/web/20210713051521/http://dpss.co.riverside.ca.us/files/pdf/dpss-general-assistance.pdf#page=1 diff --git a/policyengine_us/tests/core/test_riverside_general_relief_attribution_invariants.py b/policyengine_us/tests/core/test_riverside_general_relief_attribution_invariants.py index 52f549db318..3ac5b7ecb0c 100644 --- a/policyengine_us/tests/core/test_riverside_general_relief_attribution_invariants.py +++ b/policyengine_us/tests/core/test_riverside_general_relief_attribution_invariants.py @@ -15,7 +15,7 @@ 1. Property differential: countable property equals an independent numpy sum of the members' bank, stock and bond assets, vehicle value above the $4,650 exemption and the members' personal property. Property eligibility - is that sum below $500. + is that sum at or below $500. 2. Property monotone: raising one member's assets never lowers countable property. 3. Withholding bounds and differential: 0 <= additional_medicare_tax_withheld @@ -236,7 +236,7 @@ def _check(batch): np.testing.assert_allclose(countable, property_value, atol=TOLERANCE) np.testing.assert_array_equal( base["ca_riv_general_relief_property_eligible"].astype(bool), - property_value < PROPERTY_LIMIT, + property_value <= PROPERTY_LIMIT, ) # 3. Withholding bounds and differential. diff --git a/policyengine_us/tests/policy/baseline/gov/local/ca/riv/general_relief/ca_riv_general_relief_countable_property_value.yaml b/policyengine_us/tests/policy/baseline/gov/local/ca/riv/general_relief/ca_riv_general_relief_countable_property_value.yaml index 2a8fb021981..417f49078b2 100644 --- a/policyengine_us/tests/policy/baseline/gov/local/ca/riv/general_relief/ca_riv_general_relief_countable_property_value.yaml +++ b/policyengine_us/tests/policy/baseline/gov/local/ca/riv/general_relief/ca_riv_general_relief_countable_property_value.yaml @@ -89,5 +89,6 @@ members: [person1, person2] output: # Cash 300 + 100, countable vehicles 25, member property 50 + 25. - # Assert the stock amount without choosing eligibility at exactly $500. + # The total doesn't exceed the $500 limit, so the unit is property-eligible. ca_riv_general_relief_countable_property_value: 500 + ca_riv_general_relief_property_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/local/ca/riv/general_relief/eligibility/ca_riv_general_relief_property_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/local/ca/riv/general_relief/eligibility/ca_riv_general_relief_property_eligible.yaml index 18323066d1c..3538f763705 100644 --- a/policyengine_us/tests/policy/baseline/gov/local/ca/riv/general_relief/eligibility/ca_riv_general_relief_property_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/local/ca/riv/general_relief/eligibility/ca_riv_general_relief_property_eligible.yaml @@ -6,13 +6,14 @@ output: ca_riv_general_relief_property_eligible: true -- name: Case 2, ineligible. +- name: Case 2, exactly the $500 limit is eligible. period: 2024 input: ca_riv_general_relief_countable_property_value: 500 in_riv: true output: - ca_riv_general_relief_property_eligible: false + # Total combined property cannot exceed $500; $500 does not exceed it. + ca_riv_general_relief_property_eligible: true - name: Case 3, cash held by one member of a two-person unit counts once. period: 2024 @@ -76,3 +77,143 @@ output: # Countable property is 4,850 - 4,650 = $200, below the $500 limit. ca_riv_general_relief_property_eligible: true + +- name: Case 6, a single adult with $499.99 of cash. + period: 2024 + input: + people: + person1: + age: 30 + bank_account_assets: 499.99 + households: + household: + members: [person1] + in_riv: true + spm_units: + spm_unit: + members: [person1] + output: + # $499.99 is under the $500 limit. + ca_riv_general_relief_countable_property_value: 499.99 + ca_riv_general_relief_property_eligible: true + +- name: Case 7, a single adult with exactly $500 of cash. + period: 2024 + input: + people: + person1: + age: 30 + bank_account_assets: 500 + households: + household: + members: [person1] + in_riv: true + spm_units: + spm_unit: + members: [person1] + output: + # $500 does not exceed the $500 limit. + ca_riv_general_relief_countable_property_value: 500 + ca_riv_general_relief_property_eligible: true + +- name: Case 8, a single adult with $500.01 of cash. + period: 2024 + input: + people: + person1: + age: 30 + bank_account_assets: 500.01 + households: + household: + members: [person1] + in_riv: true + spm_units: + spm_unit: + members: [person1] + output: + # $500.01 exceeds the $500 limit. + ca_riv_general_relief_countable_property_value: 500.01 + ca_riv_general_relief_property_eligible: false + +- name: Case 9, a two-adult unit with $499.99 of cash. + period: 2024 + input: + people: + person1: + age: 30 + bank_account_assets: 499.99 + person2: + age: 65 + households: + household: + members: [person1, person2] + in_riv: true + spm_units: + spm_unit: + members: [person1, person2] + output: + # $499.99 is under the $500 limit. + ca_riv_general_relief_countable_property_value: 499.99 + ca_riv_general_relief_property_eligible: true + +- name: Case 10, a two-adult unit with exactly $500 of cash. + period: 2024 + input: + people: + person1: + age: 30 + bank_account_assets: 500 + person2: + age: 65 + households: + household: + members: [person1, person2] + in_riv: true + spm_units: + spm_unit: + members: [person1, person2] + output: + # $500 does not exceed the $500 limit. + ca_riv_general_relief_countable_property_value: 500 + ca_riv_general_relief_property_eligible: true + +- name: Case 11, a two-adult unit with $500.01 of cash. + period: 2024 + input: + people: + person1: + age: 30 + bank_account_assets: 500.01 + person2: + age: 65 + households: + household: + members: [person1, person2] + in_riv: true + spm_units: + spm_unit: + members: [person1, person2] + output: + # $500.01 exceeds the $500 limit. + ca_riv_general_relief_countable_property_value: 500.01 + ca_riv_general_relief_property_eligible: false + +- name: Case 12, cash spread over three accounts totalling exactly $500.00. + period: 2024 + input: + people: + person1: + age: 30 + bank_account_assets: 265.92 + stock_assets: 133.82 + bond_assets: 100.26 + households: + household: + members: [person1] + in_riv: true + spm_units: + spm_unit: + members: [person1] + output: + # 265.92 + 133.82 + 100.26 = 500.00, which does not exceed the $500 limit. + ca_riv_general_relief_property_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/local/ca/riv/general_relief/integration.yaml b/policyengine_us/tests/policy/baseline/gov/local/ca/riv/general_relief/integration.yaml index 9e33dee4f32..8d7e9c010ce 100644 --- a/policyengine_us/tests/policy/baseline/gov/local/ca/riv/general_relief/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/local/ca/riv/general_relief/integration.yaml @@ -278,3 +278,196 @@ # 326 needs standard for one person + 2.5 special needs - 277.60 ca_riv_general_relief_eligible: true ca_riv_general_relief: 50.90 + +- name: Case 11, single adult with no property. + period: 2024-01 + input: + people: + person1: + age: 64 + employment_income: 0 + ssi: 0 + bank_account_assets: 0 + is_incapable_of_self_care: true + households: + household: + members: [person1] + in_riv: true + spm_units: + spm_unit: + members: [person1] + ca_tanf: 0 + housing_cost: 300 * 12 + output: + # Single adult: min(300, 223 housing) + 92 food + 11 personal needs + # = 326 a month, plus the $30 annual transportation amount / 12 = 2.50, + # less $0 countable income: 328.50. + ca_riv_general_relief_property_eligible: true + ca_riv_general_relief_eligible: true + ca_riv_general_relief: 328.5 + +- name: Case 12, single adult with $499.99 of cash. + period: 2024-01 + input: + people: + person1: + age: 64 + employment_income: 0 + ssi: 0 + bank_account_assets: 499.99 + is_incapable_of_self_care: true + households: + household: + members: [person1] + in_riv: true + spm_units: + spm_unit: + members: [person1] + ca_tanf: 0 + housing_cost: 300 * 12 + output: + # $499.99 is under the $500 limit; the grant equals Case 11's. + ca_riv_general_relief_property_eligible: true + ca_riv_general_relief_eligible: true + ca_riv_general_relief: 328.5 + +- name: Case 13, single adult with exactly $500 of cash. + period: 2024-01 + input: + people: + person1: + age: 64 + employment_income: 0 + ssi: 0 + bank_account_assets: 500 + is_incapable_of_self_care: true + households: + household: + members: [person1] + in_riv: true + spm_units: + spm_unit: + members: [person1] + ca_tanf: 0 + housing_cost: 300 * 12 + output: + # $500 does not exceed the $500 limit, so the unit is eligible and the + # grant equals Case 11's no-property grant. + ca_riv_general_relief_property_eligible: true + ca_riv_general_relief_eligible: true + ca_riv_general_relief: 328.5 + +- name: Case 14, single adult with $500.01 of cash. + period: 2024-01 + input: + people: + person1: + age: 64 + employment_income: 0 + ssi: 0 + bank_account_assets: 500.01 + is_incapable_of_self_care: true + households: + household: + members: [person1] + in_riv: true + spm_units: + spm_unit: + members: [person1] + ca_tanf: 0 + housing_cost: 300 * 12 + output: + # $500.01 exceeds the $500 limit. + ca_riv_general_relief_property_eligible: false + ca_riv_general_relief_eligible: false + ca_riv_general_relief: 0 + +- name: Case 15, two adults with $499.99 of cash. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 0 + ssi: 0 + bank_account_assets: 499.99 + person2: + age: 65 + employment_income: 0 + ssi: 0 + is_incapable_of_self_care: true + households: + household: + members: [person1, person2] + in_riv: true + spm_units: + spm_unit: + members: [person1, person2] + ca_tanf: 0 + housing_cost: 300 * 12 + output: + # $499.99 is under the $500 limit; the grant equals Case 1's. + ca_riv_general_relief_property_eligible: true + ca_riv_general_relief_eligible: true + ca_riv_general_relief: 438.5 + +- name: Case 16, two adults with exactly $500 of cash. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 0 + ssi: 0 + bank_account_assets: 500 + person2: + age: 65 + employment_income: 0 + ssi: 0 + is_incapable_of_self_care: true + households: + household: + members: [person1, person2] + in_riv: true + spm_units: + spm_unit: + members: [person1, person2] + ca_tanf: 0 + housing_cost: 300 * 12 + output: + # $500 does not exceed the $500 limit, so the unit is eligible and the + # grant equals Case 1's no-property grant. + # Two adults: min(300, 257 housing) + 160 food + 19 personal needs + # = 436 a month, plus 30 / 12 = 2.50, less $0 income: 438.50 (Case 1). + ca_riv_general_relief_property_eligible: true + ca_riv_general_relief_eligible: true + ca_riv_general_relief: 438.5 + +- name: Case 17, two adults with $500.01 of cash. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 0 + ssi: 0 + bank_account_assets: 500.01 + person2: + age: 65 + employment_income: 0 + ssi: 0 + is_incapable_of_self_care: true + households: + household: + members: [person1, person2] + in_riv: true + spm_units: + spm_unit: + members: [person1, person2] + ca_tanf: 0 + housing_cost: 300 * 12 + output: + # $500.01 exceeds the $500 limit. + ca_riv_general_relief_property_eligible: false + ca_riv_general_relief_eligible: false + ca_riv_general_relief: 0 diff --git a/policyengine_us/variables/gov/local/ca/riv/general_relief/eligibility/ca_riv_general_relief_property_eligible.py b/policyengine_us/variables/gov/local/ca/riv/general_relief/eligibility/ca_riv_general_relief_property_eligible.py index 8a46150c4d6..f0d23358da0 100644 --- a/policyengine_us/variables/gov/local/ca/riv/general_relief/eligibility/ca_riv_general_relief_property_eligible.py +++ b/policyengine_us/variables/gov/local/ca/riv/general_relief/eligibility/ca_riv_general_relief_property_eligible.py @@ -7,10 +7,14 @@ class ca_riv_general_relief_property_eligible(Variable): label = "Meets property limit for Riverside County General Relief" definition_period = YEAR defined_for = "in_riv" + reference = "https://web.archive.org/web/20210713051521/http://dpss.co.riverside.ca.us/files/pdf/dpss-general-assistance.pdf#page=1" def formula(spm_unit, period, parameters): p = parameters(period).gov.local.ca.riv.general_relief.property total_property_value = spm_unit( "ca_riv_general_relief_countable_property_value", period ) - return total_property_value < p.limit + # The fact sheet's property bullet says the total cannot exceed the + # limit, so a unit holding exactly the limit is eligible. + # Inputs are stored as float32, so compare whole cents with the limit. + return np.round(total_property_value, 2) <= p.limit