From 63ad171c8a1cf5b43c60b1be204203702c4d13e6 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sun, 24 May 2026 13:43:58 -0400 Subject: [PATCH] Widen disability benefit flags from reported amounts --- .../datasets/disability_benefits.py | 46 +++++++++++++++++-- .../tests/test_disability_benefits.py | 42 ++++++++++++++++- 2 files changed, 82 insertions(+), 6 deletions(-) diff --git a/policyengine_uk_data/datasets/disability_benefits.py b/policyengine_uk_data/datasets/disability_benefits.py index f223a94a9..db6e9c93b 100644 --- a/policyengine_uk_data/datasets/disability_benefits.py +++ b/policyengine_uk_data/datasets/disability_benefits.py @@ -33,6 +33,20 @@ "pip_dl_category", ) +BASE_DISABILITY_FLAG_REPORTED_AMOUNT_COLUMNS = ( + "attendance_allowance_reported", + "dla_sc_reported", + "dla_m_reported", + "pip_m_reported", + "pip_dl_reported", + "sda_reported", + "incapacity_benefit_reported", + "iidb_reported", + "afcs_reported", + "esa_contrib_reported", + "esa_income_reported", +) + SAFETY_MARGIN = 0.1 SURVEY_REPORTED_AMOUNT_WEEKS_IN_YEAR = 365.25 / 7 @@ -56,6 +70,16 @@ def _reported_amount(person: pd.DataFrame, column: str) -> pd.Series: return pd.to_numeric(person[column], errors="coerce").fillna(0.0) +def _reported_amount_sum( + person: pd.DataFrame, + columns: tuple[str, ...], +) -> pd.Series: + total = pd.Series(0.0, index=person.index) + for column in columns: + total += _reported_amount(person, column) + return total + + def _category_from_reported_amount( reported_amount: pd.Series, thresholds: tuple[tuple[str, float], ...], @@ -148,15 +172,20 @@ def add_disability_benefit_flags_from_reported_amounts( person = person.copy() dwp = _dwp_flag_parameters(int(year)) + attendance_allowance = _reported_amount(person, "attendance_allowance_reported") dla_sc = _reported_amount(person, "dla_sc_reported") - dla_m = _reported_amount(person, "dla_m_reported") - pip_m = _reported_amount(person, "pip_m_reported") pip_dl = _reported_amount(person, "pip_dl_reported") afcs = _reported_amount(person, "afcs_reported") - person["is_disabled_for_benefits"] = (dla_sc + dla_m + pip_m + pip_dl) > 0 + person["is_disabled_for_benefits"] = ( + _reported_amount_sum(person, BASE_DISABILITY_FLAG_REPORTED_AMOUNT_COLUMNS) > 0 + ) threshold_safety_gap = 1 * SURVEY_REPORTED_AMOUNT_WEEKS_IN_YEAR + aa_higher = ( + dwp.attendance_allowance.higher * SURVEY_REPORTED_AMOUNT_WEEKS_IN_YEAR + - threshold_safety_gap + ) dla_sc_higher = ( dwp.dla.self_care.higher * SURVEY_REPORTED_AMOUNT_WEEKS_IN_YEAR - threshold_safety_gap @@ -166,9 +195,16 @@ def add_disability_benefit_flags_from_reported_amounts( - threshold_safety_gap ) - person["is_enhanced_disabled_for_benefits"] = dla_sc > dla_sc_higher + person["is_enhanced_disabled_for_benefits"] = ( + (attendance_allowance >= aa_higher) + | (dla_sc > dla_sc_higher) + | (pip_dl >= pip_dl_enhanced) + ) person["is_severely_disabled_for_benefits"] = ( - (dla_sc >= dla_sc_higher) | (pip_dl >= pip_dl_enhanced) | (afcs > 0) + (attendance_allowance > 0) + | (dla_sc >= dla_sc_higher) + | (pip_dl >= pip_dl_enhanced) + | (afcs > 0) ) return person diff --git a/policyengine_uk_data/tests/test_disability_benefits.py b/policyengine_uk_data/tests/test_disability_benefits.py index 44bb016d7..f355aff2f 100644 --- a/policyengine_uk_data/tests/test_disability_benefits.py +++ b/policyengine_uk_data/tests/test_disability_benefits.py @@ -60,6 +60,7 @@ def test_reported_amounts_recompute_disability_flags(): dwp = CountryTaxBenefitSystem().parameters(year).gov.dwp person = pd.DataFrame( { + "attendance_allowance_reported": [0.0, 0.0, 0.0], "dla_sc_reported": [ 0.0, dwp.dla.self_care.higher * (365.25 / 7), @@ -85,7 +86,7 @@ def test_reported_amounts_recompute_disability_flags(): assert result["is_enhanced_disabled_for_benefits"].tolist() == [ False, True, - False, + True, ] assert result["is_severely_disabled_for_benefits"].tolist() == [ False, @@ -94,6 +95,45 @@ def test_reported_amounts_recompute_disability_flags(): ] +def test_reported_amounts_widen_base_disability_flag(): + year = 2025 + person = pd.DataFrame( + { + "attendance_allowance_reported": [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + "sda_reported": [0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0], + "incapacity_benefit_reported": [0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0], + "iidb_reported": [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0], + "afcs_reported": [0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0], + "esa_contrib_reported": [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0], + "esa_income_reported": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0], + } + ) + + result = add_disability_benefit_flags_from_reported_amounts(person, year) + + assert result["is_disabled_for_benefits"].all() + + +def test_attendance_allowance_feeds_stronger_disability_flags(): + year = 2025 + dwp = CountryTaxBenefitSystem().parameters(year).gov.dwp + weeks = 365.25 / 7 + person = pd.DataFrame( + { + "attendance_allowance_reported": [ + dwp.attendance_allowance.lower * weeks, + dwp.attendance_allowance.higher * weeks, + ], + } + ) + + result = add_disability_benefit_flags_from_reported_amounts(person, year) + + assert result["is_disabled_for_benefits"].tolist() == [True, True] + assert result["is_enhanced_disabled_for_benefits"].tolist() == [False, True] + assert result["is_severely_disabled_for_benefits"].tolist() == [True, True] + + def test_drop_internal_disability_reported_amounts_keeps_categories(): person = pd.DataFrame( {