diff --git a/changelog.d/sdp-carer-attribution.fixed.md b/changelog.d/sdp-carer-attribution.fixed.md new file mode 100644 index 0000000000..ceda1cf9a4 --- /dev/null +++ b/changelog.d/sdp-carer-attribution.fixed.md @@ -0,0 +1 @@ +The legacy severe disability premium and the Pension Credit severe disability addition now share one attribution of whom each carer benefit is paid for caring for (`is_cared_for_by_carer_benefit_recipient`), so a carer in another benefit unit of the household bars the legacy premium as it already barred the addition, even when that carer is ignored as a non-dependant. diff --git a/policyengine_uk/parameters/gov/dwp/carers_allowance/qualifying_disability_benefits.yaml b/policyengine_uk/parameters/gov/dwp/carers_allowance/qualifying_disability_benefits.yaml new file mode 100644 index 0000000000..19c81815df --- /dev/null +++ b/policyengine_uk/parameters/gov/dwp/carers_allowance/qualifying_disability_benefits.yaml @@ -0,0 +1,31 @@ +description: > + Benefits whose receipt makes a person severely disabled for Carer's + Allowance, so that a carer benefit may be paid for caring for them: + attendance allowance, the care component of disability living allowance at + the highest or middle rate, the daily living component of personal + independence payment and armed forces independence payment. The Scottish + equivalents are not separate model variables, and the constant attendance + allowances prescribed by regulation 3 of the Invalid Care Allowance + Regulations are not modelled. +metadata: + label: Carer's Allowance qualifying disability benefits + period: year + unit: list + reference: + - title: Social Security Contributions and Benefits Act 1992 s. 70(2) + href: https://www.legislation.gov.uk/ukpga/1992/4/section/70 + - title: The Personal Independence Payment (Supplementary Provisions and Consequential Amendments) Regulations 2013 Sch. para. 5 + href: https://www.legislation.gov.uk/uksi/2013/388/schedule/paragraph/5 + - title: "The Armed Forces and Reserve Forces (Compensation Scheme) (Consequential Provisions: Primary Legislation) Order 2013 art. 3(2)" + href: https://www.legislation.gov.uk/uksi/2013/796/article/3 + - title: The Social Security (Invalid Care Allowance) Regulations 1976 reg. 3 + href: https://www.legislation.gov.uk/uksi/1976/409/regulation/3 +values: + 1992-07-01: + - attendance_allowance + - dla_sc_middle_plus + 2013-04-08: + - attendance_allowance + - dla_sc_middle_plus + - pip_dl + - armed_forces_independence_payment diff --git a/policyengine_uk/tests/policy/baseline/finance/benefit/family/severe_disability_premium.yaml b/policyengine_uk/tests/policy/baseline/finance/benefit/family/severe_disability_premium.yaml index fffdd43830..1e999a9034 100644 --- a/policyengine_uk/tests/policy/baseline/finance/benefit/family/severe_disability_premium.yaml +++ b/policyengine_uk/tests/policy/baseline/finance/benefit/family/severe_disability_premium.yaml @@ -520,6 +520,190 @@ output: severe_disability_premium: [4474.60, 0] +# Carers in other benefit units (para 14(2)(a)(iii) and (2)(b), with 14(4)). +# The carer condition is separate from the non-dependant condition: a +# non-dependant whose presence is ignored under para 14(4) can still be the +# person who receives a carer benefit for caring for the claimant. Whom each +# carer benefit is paid for is attributed by +# is_cared_for_by_carer_benefit_recipient, shared with the Pension Credit +# severe disability addition. + +- name: A non-dependant ignored for receiving a qualifying benefit still bars the premium as the claimant's carer + period: 2026 + absolute_error_margin: 0.01 + input: + people: + claimant: + age: 50 + pip_dl_category: STANDARD + son: + age: 25 + pip_dl_category: STANDARD + receives_carer_benefit: true + benunits: + claimant_family: + members: [claimant] + son_family: + members: [son] + households: + household: + members: [claimant, son] + output: + # Each is ignored as the other's non-dependant (para 14(4)(a)). The son's + # Carer's Allowance is for caring for the claimant, so the claimant fails + # para 14(2)(a)(iii); no one is paid for caring for the son. + has_non_dependant_for_severe_disability_premium: [false, false] + is_cared_for_by_carer_benefit_recipient: [true, false] + severe_disability_premium: [0, 4474.60] + +- name: A blind non-dependant who receives a carer benefit bars the premium + period: 2026 + absolute_error_margin: 0.01 + input: + people: + claimant: + age: 50 + pip_dl_category: STANDARD + son: + age: 25 + is_blind: true + receives_carer_benefit: true + benunits: + claimant_family: + members: [claimant] + son_family: + members: [son] + households: + household: + members: [claimant, son] + output: + # The son is ignored as a non-dependant (para 14(4)(b)) but is the + # claimant's carer. + has_non_dependant_for_severe_disability_premium: [false, false] + is_cared_for_by_carer_benefit_recipient: [true, false] + severe_disability_premium: [0, 0] + +- name: A couple who both qualify get the single rate when an ignored non-dependant is paid for caring for one of them + period: 2026 + absolute_error_margin: 0.01 + input: + people: + claimant: + age: 50 + pip_dl_category: STANDARD + partner: + age: 48 + pip_dl_category: ENHANCED + son: + age: 25 + pip_dl_category: STANDARD + receives_carer_benefit: true + benunits: + couple: + members: [claimant, partner] + son_family: + members: [son] + households: + household: + members: [claimant, partner, son] + output: + # One award is for one person: a carer for only one of the couple leaves + # the single rate (para 14(2)(b); Sch 3 para 20(6)(b)(i)). + is_cared_for_by_carer_benefit_recipient: [true, false, false] + severe_disability_premium: [4474.60, 4474.60] + +- name: A non-dependant who receives a carer benefit and has a severely disabled partner is treated as caring for their partner + period: 2026 + absolute_error_margin: 0.01 + input: + people: + claimant: + age: 50 + pip_dl_category: STANDARD + son: + age: 30 + pip_dl_category: STANDARD + receives_carer_benefit: true + sons_partner: + age: 28 + pip_dl_category: STANDARD + benunits: + claimant_family: + members: [claimant] + son_family: + members: [son, sons_partner] + households: + household: + members: [claimant, son, sons_partner] + output: + # A carer cares within their own benefit unit first, so the claimant has + # no carer. The son and his partner both qualify with a carer paid for + # one of them: the single rate. + is_cared_for_by_carer_benefit_recipient: [false, false, true] + severe_disability_premium: [4474.60, 4474.60] + +- name: One carer's award bars the premium of only one of two other benefit units, the one with the eldest member + period: 2026 + absolute_error_margin: 0.01 + input: + people: + older: + age: 60 + pip_dl_category: STANDARD + younger: + age: 55 + pip_dl_category: STANDARD + carer: + age: 30 + pip_dl_category: STANDARD + receives_carer_benefit: true + benunits: + older_family: + members: [older] + younger_family: + members: [younger] + carer_family: + members: [carer] + households: + household: + members: [older, younger, carer] + output: + is_cared_for_by_carer_benefit_recipient: [true, false, false] + severe_disability_premium: [0, 4474.60, 4474.60] + +- name: The legacy premium and the Pension Credit addition read the same carer attribution + period: 2026 + absolute_error_margin: 0.01 + input: + people: + pensioner: + age: 70 + aa_category: LOWER + working_age: + age: 45 + pip_dl_category: STANDARD + carer: + age: 40 + pip_dl_category: STANDARD + receives_carer_benefit: true + benunits: + pensioner_family: + members: [pensioner] + working_age_family: + members: [working_age] + carer_family: + members: [carer] + households: + household: + members: [pensioner, working_age, carer] + output: + # The one carer benefit is for the pensioner under both rules, so the + # working-age claimant keeps the premium and the pensioner loses the + # addition. + is_cared_for_by_carer_benefit_recipient: [true, false, false] + severe_disability_premium: [0, 4474.60, 4474.60] + severe_disability_minimum_guarantee_addition: [0, 4474.60, 4474.60] + # Flow-through to the applicable amounts. - name: The premium is part of the legacy benefit premiums diff --git a/policyengine_uk/tests/policy/baseline/gov/dwp/pension_credit/guarantee_credit/severe_disability_residence_and_carers.yaml b/policyengine_uk/tests/policy/baseline/gov/dwp/pension_credit/guarantee_credit/severe_disability_residence_and_carers.yaml index 75e75aafbd..e10994ac62 100644 --- a/policyengine_uk/tests/policy/baseline/gov/dwp/pension_credit/guarantee_credit/severe_disability_residence_and_carers.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/dwp/pension_credit/guarantee_credit/severe_disability_residence_and_carers.yaml @@ -4,7 +4,8 @@ # (para 1(1)(a)(iii), (b)(ii) and (c)(iv)). 2026-27 weekly rates: one rate # 86.05 (4,474.60 a year), two rates 172.10 (8,949.20 a year). # Carer benefits are attributed as documented on -# num_severe_disability_addition_qualifiers_cared_for. +# is_cared_for_by_carer_benefit_recipient, which the legacy severe disability +# premium shares. - name: A single claimant on Attendance Allowance who lives alone gets one rate period: 2026 @@ -212,7 +213,7 @@ country: ENGLAND output: receives_carer_benefit: true - num_severe_disability_addition_qualifiers_cared_for: 0 + is_cared_for_by_carer_benefit_recipient: false severe_disability_minimum_guarantee_addition: 4_474.60 - name: Carer's Allowance paid to another household member stops a single claimant's addition @@ -241,7 +242,7 @@ members: [claimant, daughter] country: ENGLAND output: - num_severe_disability_addition_qualifiers_cared_for: [1, 0] + is_cared_for_by_carer_benefit_recipient: [true, false] severe_disability_minimum_guarantee_addition: [0, 4_474.60] - name: A couple who both qualify get one rate when the claimant receives Carer's Allowance @@ -267,7 +268,7 @@ members: [claimant, partner] country: ENGLAND output: - num_severe_disability_addition_qualifiers_cared_for: 1 + is_cared_for_by_carer_benefit_recipient: [false, true] severe_disability_minimum_guarantee_addition: 4_474.60 - name: A couple who both qualify get one rate when another household member receives Carer's Allowance @@ -296,7 +297,7 @@ members: [claimant, partner, daughter] country: ENGLAND output: - num_severe_disability_addition_qualifiers_cared_for: [1, 0] + is_cared_for_by_carer_benefit_recipient: [true, false, false] severe_disability_minimum_guarantee_addition: [4_474.60, 4_474.60] - name: A couple get nothing when carer benefits are paid for both partners @@ -329,7 +330,7 @@ members: [claimant, partner, daughter] country: ENGLAND output: - num_severe_disability_addition_qualifiers_cared_for: [2, 0] + is_cared_for_by_carer_benefit_recipient: [true, true, false] severe_disability_minimum_guarantee_addition: [0, 4_474.60] - name: A qualifying partner's own Carer's Allowance does not stop the blind-partner route @@ -356,7 +357,7 @@ members: [claimant, partner] country: ENGLAND output: - num_severe_disability_addition_qualifiers_cared_for: 0 + is_cared_for_by_carer_benefit_recipient: [false, false] severe_disability_minimum_guarantee_addition: 4_474.60 - name: The blind-partner route also needs no other adult resident @@ -649,7 +650,7 @@ members: [younger, elder, carer] country: ENGLAND output: - num_severe_disability_addition_qualifiers_cared_for: [0, 1, 0] + is_cared_for_by_carer_benefit_recipient: [false, true, false] severe_disability_minimum_guarantee_addition: [4_474.60, 0, 0] - name: Two carers in the household cover two benefit units @@ -685,7 +686,7 @@ members: [younger, elder, carer_1, carer_2] country: ENGLAND output: - num_severe_disability_addition_qualifiers_cared_for: [1, 1, 0, 0] + is_cared_for_by_carer_benefit_recipient: [true, true, false, false] severe_disability_minimum_guarantee_addition: [0, 0, 0, 0] - name: Two single pensioners who each receive Carer's Allowance care for each other @@ -713,7 +714,7 @@ members: [first, second] country: ENGLAND output: - num_severe_disability_addition_qualifiers_cared_for: [1, 1] + is_cared_for_by_carer_benefit_recipient: [true, true] severe_disability_minimum_guarantee_addition: [0, 0] - name: A resident who has just attained 18 and is not a qualifying young person counts @@ -772,6 +773,7 @@ members: [first, second, third] country: ENGLAND output: + is_cared_for_by_carer_benefit_recipient: [true, true, true] severe_disability_minimum_guarantee_addition: 0 - name: A carer whose own disabled child qualifies is treated as caring for the child @@ -804,7 +806,7 @@ members: [grandmother, daughter, child] country: ENGLAND output: - num_severe_disability_addition_qualifiers_cared_for: [0, 0] + is_cared_for_by_carer_benefit_recipient: [false, false, true] severe_disability_minimum_guarantee_addition: [4_474.60, 4_474.60] - name: A second carer in a pensioner's unit is attributed to a pensioner in another unit @@ -839,7 +841,7 @@ members: [first, carer_1, carer_2, second] country: ENGLAND output: - num_severe_disability_addition_qualifiers_cared_for: [1, 1] + is_cared_for_by_carer_benefit_recipient: [true, false, false, true] severe_disability_minimum_guarantee_addition: [0, 0] - name: When two benefit units' eldest members are the same age, the one whose eldest member comes first in person order takes a carer @@ -869,7 +871,7 @@ members: [listed_first, listed_second, carer] country: ENGLAND output: - num_severe_disability_addition_qualifiers_cared_for: [1, 0, 0] + is_cared_for_by_carer_benefit_recipient: [true, false, false] severe_disability_minimum_guarantee_addition: [0, 4_474.60, 0] - name: A carer who is the only qualifying member of their own unit cares for someone in another unit @@ -903,7 +905,7 @@ members: [grandmother, father, daughter] country: ENGLAND output: - num_severe_disability_addition_qualifiers_cared_for: [1, 0] + is_cared_for_by_carer_benefit_recipient: [true, false, false] severe_disability_minimum_guarantee_addition: [0, 0] - name: The two young carers cover both pensioners when each is in their own unit too @@ -941,5 +943,5 @@ members: [first, carer_1, carer_2, second] country: ENGLAND output: - num_severe_disability_addition_qualifiers_cared_for: [1, 0, 0, 1] + is_cared_for_by_carer_benefit_recipient: [true, false, false, true] severe_disability_minimum_guarantee_addition: [0, 0, 0, 0] diff --git a/policyengine_uk/tests/policy/baseline/household/demographic/is_cared_for_by_carer_benefit_recipient.yaml b/policyengine_uk/tests/policy/baseline/household/demographic/is_cared_for_by_carer_benefit_recipient.yaml new file mode 100644 index 0000000000..2b067dd810 --- /dev/null +++ b/policyengine_uk/tests/policy/baseline/household/demographic/is_cared_for_by_carer_benefit_recipient.yaml @@ -0,0 +1,361 @@ +# Whom a carer benefit is paid for caring for: the carer condition of the +# legacy severe disability premium (HB Regs 2006 Sch 3 para 14(2)(a)(iii) and +# (2)(b)) and of the Pension Credit severe disability addition (SPC Regs 2002 +# Sch I para 1(1)). A carer benefit is paid for caring for a severely disabled +# person (SSCBA 1992 s.70(2)), one award per carer (s.70(7)) and one carer per +# severely disabled person (s.70(7ZA) to (7ZC)). The data do not say whom a carer cares +# for, so each award is attributed: within the carer's own benefit unit first +# (a claimant or partner, then another member), then to a claimant or partner +# of another benefit unit in the household, eldest unit first. + +- name: Attendance Allowance, DLA care at the middle rate, PIP daily living and AFIP make a person severely disabled for Carer's Allowance + period: 2026 + input: + people: + attendance_allowance: + age: 70 + aa_category: LOWER + dla_care_middle: + age: 40 + dla_sc_category: MIDDLE + dla_care_lowest: + age: 40 + dla_sc_category: LOWER + pip_daily_living: + age: 40 + pip_dl_category: STANDARD + pip_mobility_only: + age: 40 + pip_m_category: ENHANCED + afip: + age: 40 + armed_forces_independence_payment: 1_000 + none: + age: 40 + output: + is_severely_disabled_for_carers_allowance: [true, true, false, true, false, true, false] + +- name: No one is their own carer + period: 2026 + input: + age: 40 + pip_dl_category: STANDARD + receives_carer_benefit: true + output: + is_cared_for_by_carer_benefit_recipient: false + +- name: A carer benefit is not paid for caring for someone who is not severely disabled + period: 2026 + input: + people: + claimant: + age: 40 + partner: + age: 40 + receives_carer_benefit: true + benunits: + couple: + members: [claimant, partner] + output: + is_cared_for_by_carer_benefit_recipient: [false, false] + +- name: A partner who receives a carer benefit cares for the claimant + period: 2026 + input: + people: + claimant: + age: 40 + pip_dl_category: STANDARD + partner: + age: 40 + receives_carer_benefit: true + benunits: + couple: + members: [claimant, partner] + output: + is_cared_for_by_carer_benefit_recipient: [true, false] + +- name: When both partners are severely disabled and one receives a carer benefit, the other is cared for + period: 2026 + input: + people: + claimant: + age: 40 + pip_dl_category: STANDARD + receives_carer_benefit: true + partner: + age: 40 + pip_dl_category: STANDARD + benunits: + couple: + members: [claimant, partner] + output: + is_cared_for_by_carer_benefit_recipient: [false, true] + +- name: When both partners receive a carer benefit, each cares for the other + period: 2026 + input: + people: + claimant: + age: 40 + pip_dl_category: STANDARD + receives_carer_benefit: true + partner: + age: 40 + pip_dl_category: STANDARD + receives_carer_benefit: true + benunits: + couple: + members: [claimant, partner] + output: + is_cared_for_by_carer_benefit_recipient: [true, true] + +- name: One carer for two severely disabled partners cares for the first in person order + period: 2026 + input: + people: + claimant: + age: 45 + pip_dl_category: STANDARD + partner: + age: 45 + pip_dl_category: STANDARD + young_carer: + age: 17 + receives_carer_benefit: true + benunits: + family: + members: [claimant, partner, young_carer] + output: + is_cared_for_by_carer_benefit_recipient: [true, false, false] + +- name: A parent who receives a carer benefit cares for their disabled child + period: 2026 + input: + people: + parent: + age: 40 + receives_carer_benefit: true + child: + age: 10 + dla_sc_category: MIDDLE + benunits: + family: + members: [parent, child] + output: + is_cared_for_by_carer_benefit_recipient: [false, true] + +- name: A carer cares for a severely disabled partner before a disabled child + period: 2026 + input: + people: + claimant: + age: 40 + pip_dl_category: STANDARD + partner: + age: 40 + receives_carer_benefit: true + child: + age: 10 + dla_sc_category: MIDDLE + benunits: + family: + members: [claimant, partner, child] + output: + is_cared_for_by_carer_benefit_recipient: [true, false, false] + +- name: Two carers in a benefit unit care for the severely disabled partner and the disabled child + period: 2026 + input: + people: + claimant: + age: 45 + pip_dl_category: STANDARD + partner: + age: 45 + receives_carer_benefit: true + young_carer: + age: 17 + receives_carer_benefit: true + child: + age: 10 + dla_sc_category: MIDDLE + benunits: + family: + members: [claimant, partner, young_carer, child] + output: + is_cared_for_by_carer_benefit_recipient: [true, false, false, true] + +- name: A carer with no one to care for in their own benefit unit cares for a claimant in another + period: 2026 + input: + people: + claimant: + age: 50 + pip_dl_category: STANDARD + son: + age: 25 + receives_carer_benefit: true + benunits: + claimant_family: + members: [claimant] + son_family: + members: [son] + households: + household: + members: [claimant, son] + output: + is_cared_for_by_carer_benefit_recipient: [true, false] + +- name: A carer in another benefit unit cares for a claimant or partner, not a disabled child + period: 2026 + input: + people: + parent: + age: 40 + child: + age: 10 + dla_sc_category: MIDDLE + grandparent: + age: 70 + receives_carer_benefit: true + benunits: + family: + members: [parent, child] + grandparent_family: + members: [grandparent] + households: + household: + members: [parent, child, grandparent] + output: + # The attribution places a carer from another benefit unit only with a + # claimant or partner, so the grandparent's award is for someone outside + # the household. + is_cared_for_by_carer_benefit_recipient: [false, false, false] + +- name: One carer's award is for one person, in the benefit unit with the eldest member + period: 2026 + input: + people: + younger: + age: 55 + pip_dl_category: STANDARD + older: + age: 60 + pip_dl_category: STANDARD + carer: + age: 30 + receives_carer_benefit: true + benunits: + younger_family: + members: [younger] + older_family: + members: [older] + carer_family: + members: [carer] + households: + household: + members: [younger, older, carer] + output: + is_cared_for_by_carer_benefit_recipient: [false, true, false] + +- name: A carer in another household is not attributed + period: 2026 + input: + people: + claimant: + age: 50 + pip_dl_category: STANDARD + daughter: + age: 25 + receives_carer_benefit: true + benunits: + claimant_family: + members: [claimant] + daughter_family: + members: [daughter] + households: + claimant_household: + members: [claimant] + daughter_household: + members: [daughter] + output: + is_cared_for_by_carer_benefit_recipient: [false, false] + +- name: Three members flagged as claimant or partner, each a carer, each care for another + period: 2026 + input: + people: + first: + age: 75 + aa_category: HIGHER + receives_carer_benefit: true + is_claimant_or_partner: true + second: + age: 74 + aa_category: HIGHER + receives_carer_benefit: true + is_claimant_or_partner: true + third: + age: 73 + aa_category: HIGHER + receives_carer_benefit: true + is_claimant_or_partner: true + benunits: + benunit: + members: [first, second, third] + output: + is_cared_for_by_carer_benefit_recipient: [true, true, true] + +- name: Three members flagged as claimant or partner with one carer in another benefit unit, who cares for the first in person order + period: 2026 + input: + people: + first: + age: 75 + aa_category: HIGHER + is_claimant_or_partner: true + second: + age: 74 + aa_category: HIGHER + is_claimant_or_partner: true + third: + age: 73 + aa_category: HIGHER + is_claimant_or_partner: true + carer: + age: 40 + receives_carer_benefit: true + benunits: + benunit: + members: [first, second, third] + carer_family: + members: [carer] + households: + household: + members: [first, second, third, carer] + output: + is_cared_for_by_carer_benefit_recipient: [true, false, false, false] + +- name: Three members flagged as claimant or partner, one of them the only carer, who cares for the first other one + period: 2026 + input: + people: + first: + age: 75 + aa_category: HIGHER + receives_carer_benefit: true + is_claimant_or_partner: true + second: + age: 74 + aa_category: HIGHER + is_claimant_or_partner: true + third: + age: 73 + aa_category: HIGHER + is_claimant_or_partner: true + benunits: + benunit: + members: [first, second, third] + output: + is_cared_for_by_carer_benefit_recipient: [false, true, false] diff --git a/policyengine_uk/tests/test_severe_disability_addition_properties.py b/policyengine_uk/tests/test_severe_disability_addition_properties.py index c03142839b..86c2659998 100644 --- a/policyengine_uk/tests/test_severe_disability_addition_properties.py +++ b/policyengine_uk/tests/test_severe_disability_addition_properties.py @@ -27,12 +27,31 @@ unit's addition. 5. Symmetry: swapping the drawn attributes of a couple's two partners leaves their addition unchanged. +6. Shared carer attribution, differential: the claimants and partners that + is_cared_for_by_carer_benefit_recipient marks in each benefit unit are one + of the sets the reference's person-to-person matching allows, and the + number of other members marked (such as disabled children) is the number + the reference's within-unit matching covers. Structural: only a person + who is severely disabled for Carer's Allowance is marked, a household has + no more people cared for than carer benefits, and a household's only + carer is never marked as caring for themselves. +7. Cross-programme, differential: the legacy severe disability premium (HB + Regs 2006 Sch 3 para 14) reads the same attribution, and its qualifying + benefits, couple, blind-partner and carer rules and rates are those of the + addition. The two residence tests differ only over 16- to 19-year-olds + (HB reg 3 non-dependants against SPC Sch I para 2(2)(f)), so in a + household with no one of that age the premium equals the addition for + every benefit unit, carers in other benefit units included. """ import numpy as np from hypothesis import HealthCheck, given, settings from hypothesis import strategies as st -from severe_disability_addition_reference import reference_rates +from severe_disability_addition_reference import ( + _best_within_unit, + household_carer_assignments, + reference_rates, +) from policyengine_uk import Simulation @@ -139,6 +158,10 @@ def calc(variable): "qualifies": calc("receives_severe_disability_addition_qualifying_benefit"), "carer": calc("receives_carer_benefit"), "is_couple": calc("is_couple"), + "cared_for": calc("is_cared_for_by_carer_benefit_recipient"), + "could_be_cared_for": calc("is_severely_disabled_for_carers_allowance"), + "addition": calc("severe_disability_minimum_guarantee_addition"), + "legacy_premium": calc("severe_disability_premium"), } @@ -279,3 +302,81 @@ def test_swapping_partners_leaves_a_couples_addition_unchanged(original): result = simulate([original, swapped]) before, after = rates_by_household(result) assert before[0] == after[0] + + +@PROPERTY_SETTINGS +@given(st.lists(household(), min_size=1, max_size=6)) +def test_shared_carer_attribution_matches_the_reference_matching(households): + result = simulate(households) + cared_for = result["cared_for"].astype(bool) + # Only someone a carer benefit can be paid for is marked. + assert not np.any(cared_for & ~result["could_be_cared_for"].astype(bool)) + np.testing.assert_array_equal(result["could_be_cared_for"], result["qualifies"]) + k = 0 + for h, layout in enumerate(result["layout"]): + allowed = household_carer_assignments(reference_household(result, h)) + names = [name for unit in layout for name, _, _ in unit] + marked = {name for i, name in enumerate(names) if cared_for[k + i]} + carers = int(result["carer"][k : k + len(names)].sum()) + # Each award is for one person. + assert len(marked) <= carers, (layout, marked) + if carers == 1 and len(names) > 0: + (carer,) = [n for i, n in enumerate(names) if result["carer"][k + i]] + assert carer not in marked, (layout, marked) + reference = reference_household(result, h) + for b, unit in enumerate(layout): + claimants = {name for name, role, _ in unit if role == "cp"} + assert frozenset(marked & claimants) in allowed[b], ( + layout, + marked, + allowed[b], + ) + # Other members (such as a disabled child) are cared for only by + # carers of their own unit, after its claimants and partners. + others = {name for name, role, _ in unit if role != "cp"} + unit_carers = sum( + reference["people"][n]["receives_carer_benefit"] + for n in claimants | others + ) + within_cp, left_over = _best_within_unit( + reference["people"], reference["benunits"][b] + ) + assert len(marked & others) == unit_carers - left_over - within_cp, ( + layout, + marked, + ) + k += len(names) + + +def no_one_aged_16_to_19(units): + return not any( + 16 <= p["age"] <= 19 + for unit in units + for p in unit["claimants"] + unit["dependants"] + ) + + +@PROPERTY_SETTINGS +@given(st.lists(household().filter(no_one_aged_16_to_19), min_size=1, max_size=6)) +def test_legacy_premium_equals_the_addition_without_young_people(households): + result = simulate(households) + np.testing.assert_allclose(result["legacy_premium"], result["addition"], atol=0.01) + + +def test_the_three_qualifying_benefit_lists_agree(): + """The attribution's candidates are the Carer's Allowance list (SSCBA 1992 + s.70(2)); the premium and the addition each count their own qualifying + claimants and partners among those marked. In the model's variables the + three lists are the same from 8 April 2013, when PIP and AFIP joined + s.70(2), which is what makes the two programmes' cared-for counts agree.""" + from policyengine_uk import CountryTaxBenefitSystem + + parameters = CountryTaxBenefitSystem().parameters + for instant in ("2013-04-08", "2020-01-01", "2026-01-01", "2030-01-01"): + dwp = parameters(instant).gov.dwp + carers_allowance = set(dwp.carers_allowance.qualifying_disability_benefits) + legacy = set(dwp.disability_premia.severe_qualifying_benefits) + pension_credit = set( + dwp.pension_credit.guarantee_credit.severe_disability.relevant_benefits + ) + assert carers_allowance == legacy == pension_credit, instant diff --git a/policyengine_uk/tests/test_severe_disability_premium_properties.py b/policyengine_uk/tests/test_severe_disability_premium_properties.py index 3326a19210..6e8764ddb8 100644 --- a/policyengine_uk/tests/test_severe_disability_premium_properties.py +++ b/policyengine_uk/tests/test_severe_disability_premium_properties.py @@ -14,20 +14,24 @@ 1. Range: the premium is 0, the single rate or the double rate, and the double rate goes only to a couple who both qualify. -2. Oracle: the premium equals a second, separately written implementation - of the rule, with its own benefit classification and a carer condition - that brute-forces the assignment of each carer award to a benefit-unit - member other than its recipient. It is algorithmically independent of the - model but not of the model's assumptions: it shares the carer attribution - (the model does not observe who is cared for, so both take the assignment - that covers the most qualifying members) and the symmetric blind-partner - rule (either partner may be the claimant). Agreement shows the model - implements those assumptions, not that they match the Regulations. +2. Oracle: the premium equals a separately written implementation of the + rule, in which the carer condition is the person-to-person matching of + severe_disability_addition_reference.household_carer_assignments, the + reference the Pension Credit severe disability addition is tested against + (the model does not observe who is cared for; both rules read the one + attribution, is_cared_for_by_carer_benefit_recipient). Carers in other + benefit units of the household are attributed too, so a non-dependant + whose presence is ignored can still bar the premium as the claimant's + carer. The oracle is independent of the model's code but not of its + assumptions: it shares the carer attribution and the symmetric + blind-partner rule (either partner may be the claimant), so agreement + shows the model implements those assumptions, not that they match the + Regulations. 3. Metamorphic: adding a household member aged 18 or over, in another benefit unit, who receives no qualifying benefit and is not blind, removes the premium. The oracle also treats a benefit-unit member aged 18 or 19 who is not a qualifying young person as a non-dependant (HB Regs regs 3, 19). -4. Metamorphic: paying anyone in the benefit unit a carer benefit never +4. Metamorphic: paying anyone in the household a carer benefit never increases the premium. 5. Metamorphic: giving anyone in the household a qualifying benefit, or making them blind, never reduces the premium. @@ -38,11 +42,10 @@ two encodings of the same rule in step; it is not an independent oracle. """ -from itertools import product - import numpy as np from hypothesis import HealthCheck, event, example, given, settings from hypothesis import strategies as st +from severe_disability_addition_reference import household_carer_assignments from policyengine_uk import Simulation, parameters @@ -202,13 +205,45 @@ def simulate_before_after(units, changed): return premium[: len(units)], premium[len(units) :] +def claimants_and_partners_cared_for(unit): + """Every allowed set of the family's adults a carer benefit is paid for. + + The household as the shared carer reference reads it: the family's adults + are its claimant and partner, and each other person is a benefit unit of + their own, its claimant from age 16. People are listed in simulation + order. + """ + family = family_members(unit) + people, benunits = {}, {} + benunits["family"] = {"claimant_or_partner": [], "others": []} + for i, p in enumerate(family): + role = "claimant_or_partner" if i < len(unit["adults"]) else "others" + benunits["family"][role].append(("family", i)) + people[("family", i)] = p + for j, p in enumerate(unit["others"]): + role = "claimant_or_partner" if p["age"] >= 16 else "others" + benunits[("other", j)] = {"claimant_or_partner": [], "others": []} + benunits[("other", j)][role].append(("other", j)) + people[("other", j)] = p + people = { + pid: dict( + age=p["age"], + qualifying_benefit=qualifies(p), + receives_carer_benefit=p["carer"], + ) + for pid, p in people.items() + } + allowed = household_carer_assignments({"people": people, "benunits": benunits}) + return [{i for _, i in cared_for} for cared_for in allowed["family"]] + + def oracle(unit): """The premium from a separately written implementation of the rule. Independent of the model's code, but it shares the model's carer attribution and symmetric blind-partner assumptions. """ - adults, family = unit["adults"], family_members(unit) + adults = unit["adults"] # Non-dependants: other benefit units in the household, and anyone in the # benefit unit who is not the claimant, partner, a child or a qualifying # young person (HB Regs regs 3(2)(a), 19). @@ -229,17 +264,18 @@ def oracle(unit): return 0.0 elif len(adults) == 1 and not qualifying: return 0.0 - # Assign each carer award to one family member other than its recipient, - # and count the most qualifying members that can be covered. - carers = [i for i, p in enumerate(family) if p["carer"]] - cared_for = 0 - for assignment in product(range(len(family)), repeat=len(carers)): - if any(c == target for c, target in zip(carers, assignment)): - continue - cared_for = max(cared_for, len(set(assignment) & set(qualifying))) - if len(adults) == 2 and len(qualifying) == 2: - return (2 - cared_for) * SINGLE - return SINGLE if cared_for == 0 else 0.0 + # Which qualifying members a carer benefit is paid for caring for. Where + # the attribution leaves a choice between partners, the premium must not + # depend on it. + premiums = set() + for cared_for in claimants_and_partners_cared_for(unit): + cared_for = len(cared_for & set(qualifying)) + if len(adults) == 2 and len(qualifying) == 2: + premiums.add((2 - cared_for) * SINGLE) + else: + premiums.add(SINGLE if cared_for == 0 else 0.0) + assert len(premiums) == 1, (unit, premiums) + return premiums.pop() def _adult(benefit, blind=False, carer=False): @@ -277,6 +313,20 @@ def _adult(benefit, blind=False, carer=False): young=[dict(_adult("none"), age=19, in_education=True, entry_age=17)], others=[], ), + # A non-dependant who receives a qualifying benefit is ignored as a + # resident (para 14(4)(a)) but, receiving a carer benefit, is the + # claimant's carer: no premium. + dict( + adults=[_adult("pip_standard")], + children=[], + others=[_adult("pip_standard", carer=True)], + ), + # The same for a couple who both qualify: the single rate. + dict( + adults=[_adult("pip_standard"), _adult("aa_lower")], + children=[], + others=[_adult("none", blind=True, carer=True)], + ), ] ) def test_premium_matches_independent_oracle_and_range(units): @@ -303,13 +353,14 @@ def test_counted_non_dependant_removes_premium(units, age): @PROPERTY_SETTINGS -@given(st.lists(households(), min_size=1, max_size=10), st.integers(0, 2)) +@given(st.lists(households(), min_size=1, max_size=10), st.integers(0, 4)) def test_carer_benefit_never_increases_premium(units, index): def pay_carer(unit): family = family_members(unit) - i = index % len(family) - family = [dict(p, carer=p["carer"] or k == i) for k, p in enumerate(family)] - return with_family(unit, family) + everyone = family + unit["others"] + i = index % len(everyone) + paid = [dict(p, carer=p["carer"] or k == i) for k, p in enumerate(everyone)] + return dict(with_family(unit, paid[: len(family)]), others=paid[len(family) :]) before, after = simulate_before_after(units, [pay_carer(u) for u in units]) assert np.all(after <= before + 0.01) diff --git a/policyengine_uk/variables/gov/dwp/pension_credit/guarantee_credit/minimum_guarantee/additional/num_severe_disability_addition_qualifiers_cared_for.py b/policyengine_uk/variables/gov/dwp/pension_credit/guarantee_credit/minimum_guarantee/additional/num_severe_disability_addition_qualifiers_cared_for.py deleted file mode 100644 index da7e25d637..0000000000 --- a/policyengine_uk/variables/gov/dwp/pension_credit/guarantee_credit/minimum_guarantee/additional/num_severe_disability_addition_qualifiers_cared_for.py +++ /dev/null @@ -1,102 +0,0 @@ -from policyengine_uk.model_api import * - - -class num_severe_disability_addition_qualifiers_cared_for(Variable): - value_type = int - entity = BenUnit - label = ( - "Qualifying claimants or partners with a carer benefit paid for caring for them" - ) - documentation = ( - "How many of the claimant and partner who receive a qualifying " - "disability benefit have someone entitled to and in receipt of " - "Carer's Allowance or Carer Support Payment in respect of caring for " - "them. The data do not say whom a carer cares for. A carer benefit " - "needs the person cared for to receive a qualifying disability " - "benefit, and each award is for one person, who has only one such " - "carer (SSCBA 1992 s.70(7) and (7ZA)), so each carer is attributed as " - "follows. No one is their own carer. A carer cares for someone in " - "their own benefit unit who receives a qualifying benefit if there is " - "one: a qualifying claimant or partner first, then another member such " - "as a disabled child, each such person having one carer. Every other " - "carer in the household, including one left over in their own unit, " - "is allocated to a qualifying claimant or partner not yet cared for in " - "another benefit unit, one each, taking the units in descending order " - "of their eldest member's age (ties in person order, the order people " - "are listed in the input or dataset). Carers outside the household, " - "and Universal Credit awards that include the carer element, are not " - "counted. Reading Universal Credit here would be circular, because the " - "Universal Credit non-dependant deduction exemption reads Pension " - "Credit; a Universal Credit carer in the household already stops the " - "addition through the residence condition unless their presence is " - "ignored. Receipt is receives_carer_benefit, so it inherits " - "carers_allowance, which does not apply the overlapping-benefit rule " - "that stops Carer's Allowance being paid alongside a higher State " - "Pension." - ) - definition_period = YEAR - reference = ( - "https://www.legislation.gov.uk/uksi/2002/1792/schedule/I/paragraph/1", - "https://www.legislation.gov.uk/uksi/2002/1792/regulation/6", - "https://www.legislation.gov.uk/ukpga/1992/4/section/70", - ) - - def formula(benunit, period, parameters): - person = benunit.members - claimant_or_partner = person("is_claimant_or_partner", period) - receives = person( - "receives_severe_disability_addition_qualifying_benefit", period - ) - qualifies = claimant_or_partner & receives - dependant_receives = ~claimant_or_partner & receives - carer = person("receives_carer_benefit", period) - qualifying = benunit.sum(qualifies) - receiving_dependants = benunit.sum(dependant_receives) - # People in the carer's own unit the carer could be caring for. - qualifiers_in_own_unit = benunit.project(qualifying) - qualifies - dependants_in_own_unit = ( - benunit.project(receiving_dependants) - dependant_receives - ) - cares_for_a_qualifier = carer & (qualifiers_in_own_unit > 0) - cares_within_unit = carer & ( - (qualifiers_in_own_unit + dependants_in_own_unit) > 0 - ) - # Qualifying claimants and partners first, one carer each. - cared_for_within = min_(qualifying, benunit.sum(cares_for_a_qualifier)) - not_yet_cared_for = qualifying - cared_for_within - placed_within = min_( - benunit.sum(cares_within_unit), qualifying + receiving_dependants - ) - # Every other carer benefit is for someone in another unit. - outside_here = benunit.sum(carer) - placed_within - outside_members = where( - person.get_rank(person.benunit, -person("age", period)) == 0, - benunit.project(outside_here), - 0, - ) - outside_in_household = benunit.max(person.household.sum(outside_members)) - # Order the household's units by their eldest member (ties by person order) - # and give each unit, in turn, carers from the other units. - age = person("age", period) - representative = person.get_rank(person.benunit, -age) == 0 - order = person.get_rank(person.household, -age, condition=representative) - unit_order = benunit.max(where(representative, order, -1)) - allocated_in_household = np.zeros_like(outside_here) - cared_for_from_other_units = np.zeros_like(outside_here) - for rank in range(int(np.max(unit_order, initial=-1)) + 1): - available = max_( - 0, - min_( - outside_in_household - outside_here, - outside_in_household - allocated_in_household, - ), - ) - allocated = where(unit_order == rank, min_(not_yet_cared_for, available), 0) - cared_for_from_other_units = cared_for_from_other_units + allocated - allocated_by_representative = where( - representative, benunit.project(allocated), 0 - ) - allocated_in_household = allocated_in_household + benunit.max( - person.household.sum(allocated_by_representative) - ) - return cared_for_within + cared_for_from_other_units diff --git a/policyengine_uk/variables/gov/dwp/pension_credit/guarantee_credit/minimum_guarantee/additional/severe_disability_minimum_guarantee_addition.py b/policyengine_uk/variables/gov/dwp/pension_credit/guarantee_credit/minimum_guarantee/additional/severe_disability_minimum_guarantee_addition.py index 9e8d299a53..56cf7b0bca 100644 --- a/policyengine_uk/variables/gov/dwp/pension_credit/guarantee_credit/minimum_guarantee/additional/severe_disability_minimum_guarantee_addition.py +++ b/policyengine_uk/variables/gov/dwp/pension_credit/guarantee_credit/minimum_guarantee/additional/severe_disability_minimum_guarantee_addition.py @@ -23,10 +23,11 @@ class severe_disability_minimum_guarantee_addition(Variable): "either partner, to qualify where the other partner is blind. Not " "modelled: the hospital-patient deeming (para 1(2)(b)-(bd)) " "and backdating (para 1(2)(a), (c)); sight regained within 28 weeks " - "(para 1(3)); polygamous marriages; and the unmodelled para 2 and 3 " - "exceptions and carer attribution described on " - "is_counted_resident_for_severe_disability_addition and " - "num_severe_disability_addition_qualifiers_cared_for. Blindness " + "(para 1(3)); polygamous marriages; and the para 2 and 3 exceptions " + "listed on is_counted_resident_for_severe_disability_addition. Whom " + "a carer benefit is paid for caring for is attributed by " + "is_cared_for_by_carer_benefit_recipient, which the legacy severe " + "disability premium shares. Blindness " "(is_blind) is not in the survey data, so in microsimulation the " "blind-partner route never applies and a blind resident is counted." ) @@ -54,8 +55,13 @@ def formula(benunit, period, parameters): other_partner_blind = benunit.any( claimant_or_partner & ~qualifies & person("is_blind", period) ) - cared_for = benunit( - "num_severe_disability_addition_qualifiers_cared_for", period + # How many qualifying claimants and partners someone receives a carer + # benefit for caring for (the attribution is shared with the legacy + # severe disability premium). + cared_for = benunit.sum( + claimant_or_partner + & qualifies + & person("is_cared_for_by_carer_benefit_recipient", period) ) # Para 1(1)(b) with reg 6(5): two rates, less one for each partner a # carer benefit is paid for (none if paid for both). Para 1(1)(c): one diff --git a/policyengine_uk/variables/household/demographic/is_cared_for_by_carer_benefit_recipient.py b/policyengine_uk/variables/household/demographic/is_cared_for_by_carer_benefit_recipient.py new file mode 100644 index 0000000000..6772dfa69b --- /dev/null +++ b/policyengine_uk/variables/household/demographic/is_cared_for_by_carer_benefit_recipient.py @@ -0,0 +1,121 @@ +from policyengine_uk.model_api import * + + +class is_cared_for_by_carer_benefit_recipient(Variable): + value_type = bool + entity = Person + label = "Someone receives a carer benefit for caring for this person" + documentation = ( + "Someone is entitled to and in receipt of Carer's Allowance or Carer " + "Support Payment in respect of caring for this person: the carer " + "condition of the legacy severe disability premium (HB Regs 2006 Sch 3 " + "para 14(2)(a)(iii) and (2)(b); IS, ESA and JSA alike) and of the " + "Pension Credit severe disability addition (SPC Regs 2002 Sch I para " + "1(1)). The data say who receives a carer benefit but not whom they " + "care for, so each award is attributed. A carer benefit is paid for " + "caring for a person who is severely disabled for Carer's Allowance " + "(is_severely_disabled_for_carers_allowance), a carer has one award " + "(SSCBA 1992 s.70(7)), and only one person is paid for caring for the " + "same severely disabled person (s.70(7ZA) to (7ZC); both rules were " + "in s.70(7) before 16 November 2023). No one is their own carer. A " + "carer cares for someone in their own benefit unit if they can: a " + "claimant or partner first, then another member such as a disabled " + "child. Every other carer in the household, including one left over " + "in their own unit, cares for a claimant or partner not yet cared for " + "in another benefit unit if there is one, taking the units in " + "descending order of their eldest member's age (ties in person order, " + "the order people are listed in the input or dataset); otherwise the " + "award is taken to be for someone outside the household. The data " + "cannot say whether a carer cares for a claimant or partner or for " + "another disabled member, such as a child, so putting claimants and " + "partners first, and placing left-over carers only with claimants and " + "partners of other units, is a choice: where the carer in fact cares " + "for the child and the claimant or partner otherwise qualifies, it " + "withholds a premium or addition the law would pay, or for a couple " + "pays the single rate instead of the double rate. Where not " + "everyone can have a carer, those who are not carers themselves come " + "first, then person order; the number cared for in a benefit unit " + "does not depend on that choice. Carers outside the household are not " + "observed, and nor is a carer whose allowance runs on for up to eight " + "weeks after the person they cared for has died (s.70(1A)). A " + "Universal Credit award that includes the carer element also counts " + "in law but is not attributed here: " + "reading Universal Credit would be circular, because the Universal " + "Credit non-dependant deduction exemption reads Pension Credit. Such a " + "carer living in the household already bars both the premium and the " + "addition through their residence conditions unless their presence " + "is ignored. Receipt is receives_carer_benefit: a positive Carer's " + "Allowance or Carer Support Payment after the overlapping-benefit " + "adjustment. A carer whose award an overlapping benefit, such as a " + "higher State Pension, reduces to nil is entitled but not in receipt, " + "so is not attributed." + ) + definition_period = YEAR + reference = ( + "https://www.legislation.gov.uk/ukpga/1992/4/section/70", + "https://www.legislation.gov.uk/uksi/2006/213/schedule/3/paragraph/14", + "https://www.legislation.gov.uk/uksi/2002/1792/schedule/I/paragraph/1", + "https://www.legislation.gov.uk/uksi/1987/1967/schedule/2/paragraph/13", + "https://www.legislation.gov.uk/uksi/2008/794/schedule/4/paragraph/6", + "https://www.legislation.gov.uk/uksi/1996/207/schedule/1/paragraph/15", + ) + + def formula(person, period, parameters): + claimant_or_partner = person("is_claimant_or_partner", period) + could_be_cared_for = person("is_severely_disabled_for_carers_allowance", period) + carer = person("receives_carer_benefit", period) + age = person("age", period) + # Who takes a carer when not everyone can: someone who is not a carer + # themselves, then person order (get_rank breaks ties by position). + priority = carer.astype(int) + + # Within the benefit unit: claimants and partners, then other members. + cp_target = claimant_or_partner & could_be_cared_for + cp_targets = person.benunit.sum(cp_target) + targets = person.benunit.sum(could_be_cared_for) + can_care_for_cp = carer & (cp_targets - cp_target > 0) + can_care_within = carer & (targets - could_be_cared_for > 0) + cp_cared_for_within = min_(cp_targets, person.benunit.sum(can_care_for_cp)) + cared_for_within = min_(targets, person.benunit.sum(can_care_within)) + cp_within = cp_target & ( + person.get_rank(person.benunit, priority, condition=cp_target) + < cp_cared_for_within + ) + other_target = could_be_cared_for & ~claimant_or_partner + other_within = other_target & ( + person.get_rank(person.benunit, priority, condition=other_target) + < cared_for_within - cp_cared_for_within + ) + + # Every carer not placed in their own unit cares for a claimant or + # partner of another unit. Units take them in descending order of + # their eldest member's age, each taking as many as it needs from the + # carers of other units that are not yet placed. + left_over = person.benunit.sum(carer) - cared_for_within + eldest = person.get_rank(person.benunit, -age) == 0 + left_over_in_household = person.household.sum(where(eldest, left_over, 0)) + needed = cp_targets - cp_cared_for_within + unit_order = person.benunit.max( + where(eldest, person.get_rank(person.household, -age, condition=eldest), -1) + ) + from_other_units = np.zeros_like(needed) + placed_in_household = np.zeros_like(needed) + for rank in range(int(np.max(unit_order, initial=-1)) + 1): + available = max_( + 0, + min_( + left_over_in_household - left_over, + left_over_in_household - placed_in_household, + ), + ) + taken = where(unit_order == rank, min_(needed, available), 0) + from_other_units = from_other_units + taken + placed_in_household = placed_in_household + person.household.sum( + where(eldest, taken, 0) + ) + cp_not_yet = cp_target & ~cp_within + cp_from_other_units = cp_not_yet & ( + person.get_rank(person.benunit, priority, condition=cp_not_yet) + < from_other_units + ) + return cp_within | other_within | cp_from_other_units diff --git a/policyengine_uk/variables/household/demographic/is_severely_disabled_for_carers_allowance.py b/policyengine_uk/variables/household/demographic/is_severely_disabled_for_carers_allowance.py new file mode 100644 index 0000000000..8d70f6a67c --- /dev/null +++ b/policyengine_uk/variables/household/demographic/is_severely_disabled_for_carers_allowance.py @@ -0,0 +1,27 @@ +from policyengine_uk.model_api import * + + +class is_severely_disabled_for_carers_allowance(Variable): + value_type = bool + entity = Person + label = "Severely disabled person for Carer's Allowance" + documentation = ( + "A severely disabled person within SSCBA 1992 s.70(2): one for whom " + "attendance allowance, the care component of disability living " + "allowance at the highest or middle rate, the daily living component " + "of personal independence payment, or armed forces independence " + "payment is payable. A carer benefit can only be paid for caring for " + "such a person. The Scottish equivalents, which Carer Support Payment " + "also accepts, are not separate model variables, and the constant " + "attendance allowances prescribed by the Invalid Care Allowance " + "Regulations 1976 reg 3 are not modelled." + ) + definition_period = YEAR + reference = ( + "https://www.legislation.gov.uk/ukpga/1992/4/section/70", + "https://www.legislation.gov.uk/uksi/1976/409/regulation/3", + ) + + def formula(person, period, parameters): + p = parameters(period).gov.dwp.carers_allowance + return add(person, period, p.qualifying_disability_benefits) > 0 diff --git a/policyengine_uk/variables/household/demographic/severe_disability_premium.py b/policyengine_uk/variables/household/demographic/severe_disability_premium.py index 4621a87000..0518743097 100644 --- a/policyengine_uk/variables/household/demographic/severe_disability_premium.py +++ b/policyengine_uk/variables/household/demographic/severe_disability_premium.py @@ -19,8 +19,11 @@ class severe_disability_premium(Variable): "for caring for them. A couple who both qualify get the double rate " "when no carer benefit is paid for either of them, the single rate " "when one is paid for only one of them, and nothing when carers are " - "paid for both. The law also counts a Universal Credit award with the " - "carer element, which the model does not. Not modelled: a carer's " + "paid for both. Whom a carer benefit is paid for caring for is " + "attributed by is_cared_for_by_carer_benefit_recipient, shared with " + "the Pension Credit severe disability addition; the law also counts " + "a Universal Credit award with the carer element, which the model " + "does not. Not modelled: a carer's " "allowance or carer element that would be paid but for a loss of " "benefit restriction under section 6B or 7 of the Social Security " "Fraud Act 2001 also counts (HB Regs 2006 Sch 3 para 14(7), IS Regs " @@ -47,12 +50,11 @@ class severe_disability_premium(Variable): unit = GBP def formula(benunit, period, parameters): - # The person cared for is not observed. A carer benefit paid to - # someone in the benefit unit is assumed to be for a claimant or - # partner other than its recipient, one person per award. Carers in - # other benefit units are not counted, and carers in other households - # are not observed. The hospital rules that keep a patient treated as - # in receipt (and then pay the single rate) are not modelled. + # Whom a carer benefit is paid for caring for is attributed by + # is_cared_for_by_carer_benefit_recipient, which the Pension Credit + # severe disability addition shares. The hospital rules that keep a + # patient treated as in receipt (and then pay the single rate) are not + # modelled. p = parameters(period).gov.dwp.disability_premia person = benunit.members claimant_or_partner = person("is_claimant_or_partner", period) @@ -64,9 +66,10 @@ def formula(benunit, period, parameters): partner_treated_as_absent = benunit.any( claimant_or_partner & ~qualifies & person("is_blind", period) ) - carer = person("receives_carer_benefit", period) - carers = benunit.sum(carer) - carers_for_qualifying_member = benunit.sum(carer & ~qualifying_member) + cared_for = benunit.sum( + qualifying_member + & person("is_cared_for_by_carer_benefit_recipient", period) + ) # Number of single rates payable: two for a couple who both qualify # with no carer paid for either, one when a carer is paid for only # one of them, and one for a single claimant (or a couple whose @@ -76,10 +79,10 @@ def formula(benunit, period, parameters): couple, (qualifying == 1) & partner_treated_as_absent, qualifying >= 1, - ) & (carers_for_qualifying_member == 0) + ) & (cared_for == 0) rates = where( couple & (qualifying >= 2), - max_(2 - carers, 0), + max_(2 - cared_for, 0), single_condition, ) weekly_amount = select(