diff --git a/changelog.d/pension-credit-mixed-age-saving.fixed.md b/changelog.d/pension-credit-mixed-age-saving.fixed.md new file mode 100644 index 0000000000..bf1181fa6b --- /dev/null +++ b/changelog.d/pension-credit-mixed-age-saving.fixed.md @@ -0,0 +1 @@ +- Date the Pension Credit exclusion of mixed-age couples (State Pension Credit Act 2002 s.4(1A)) from 15 May 2019, and model the SI 2019/37 article 4 saving. Before the change, mixed-age couples could claim Pension Credit and pension-age Housing Benefit, and now take that route rather than Universal Credit. Afterwards, a couple entitled to Pension Credit or pension-age Housing Benefit on 14 May 2019 keeps them while it stays entitled. The saving is a new input, `has_mixed_age_couple_pension_credit_saving`, which by default is inferred from reported Pension Credit or pension-age Housing Benefit without reported Universal Credit, where the older member was born by 1954. A family on the Pension Credit route is no longer eligible for Universal Credit. diff --git a/docs/book/programs/gov/dwp/housing-benefit.ipynb b/docs/book/programs/gov/dwp/housing-benefit.ipynb index 3fa1f88ec0..01ae7d9a50 100644 --- a/docs/book/programs/gov/dwp/housing-benefit.ipynb +++ b/docs/book/programs/gov/dwp/housing-benefit.ipynb @@ -21,8 +21,8 @@ "\n", "`housing_benefit_eligible` requires the benunit to be either in **social housing** or eligible for the **Local Housing Allowance** rate (broadly, private renters), with assessable capital at or below the working-age (or pension-age) capital limit, and to reach Housing Benefit by one of two routes:\n", "\n", - "- **Pension age**: every adult in the benunit has reached the qualifying age for State Pension Credit (State Pension age). New Housing Benefit claims are open to them ([SI 2014/1230 reg. 6A(4)](https://www.legislation.gov.uk/uksi/2014/1230/regulation/6A)), and Universal Credit is not, so neither a previous claim nor `would_claim_uc` matters.\n", - "- **Continuing award**: any other benunit was **already claiming** Housing Benefit (proxied by a positive `housing_benefit_reported`) and is **not claiming Universal Credit**. Working-age and mixed-age families cannot make new claims; they claim the Universal Credit housing element instead. For mixed-age couples the reported award stands in for the saving for couples who were entitled to Housing Benefit or Pension Credit on 14 May 2019 ([SI 2019/37 art. 4](https://www.legislation.gov.uk/uksi/2019/37/article/4)).\n", + "- **Pension age**: the claimant and any partner have reached the qualifying age for State Pension Credit (State Pension age), or the family is a mixed-age couple that keeps the pension-age route: one entitled to Pension Credit or pension-age Housing Benefit on 14 May 2019 and ever since ([SI 2019/37 art. 4](https://www.legislation.gov.uk/uksi/2019/37/article/4)), or any mixed-age couple not reported on Universal Credit before 15 May 2019 (`meets_pension_credit_age_conditions`). New Housing Benefit claims are open to them ([SI 2014/1230 reg. 6A(4) and (5)](https://www.legislation.gov.uk/uksi/2014/1230/regulation/6A)), and Universal Credit is not, so neither a previous claim nor `would_claim_uc` matters.\n", + "- **Continuing award**: any other benunit was **already claiming** Housing Benefit (proxied by a positive `housing_benefit_reported`) and is **not claiming Universal Credit**. Working-age families, and mixed-age couples without the saving, cannot make new claims; they claim the Universal Credit housing element instead.\n", "\n", "The pension-age test counts the same benunit members as Universal Credit's working-age test, and the continuing-award route requires not claiming Universal Credit, so no benunit receives both. Working-age awards outside specified or temporary accommodation ended on 1 July 2026 in Great Britain ([SI 2025/1148 art. 7](https://www.legislation.gov.uk/uksi/2025/1148/article/7)); PolicyEngine does not yet model that. Claims for specified or temporary accommodation, which remain open at any age, are not modelled.\n", "\n", diff --git a/policyengine_uk/parameters/gov/dwp/pension_credit/mixed_age_couples/excluded.yaml b/policyengine_uk/parameters/gov/dwp/pension_credit/mixed_age_couples/excluded.yaml new file mode 100644 index 0000000000..8f2358440e --- /dev/null +++ b/policyengine_uk/parameters/gov/dwp/pension_credit/mixed_age_couples/excluded.yaml @@ -0,0 +1,14 @@ +description: Whether a member of a mixed-age couple, where one partner has not reached the qualifying age for State Pension Credit, is excluded from State Pension Credit. The exclusion also bars the couple from new pension-age Housing Benefit claims. +values: + 2003-10-06: false + 2019-05-15: true +metadata: + unit: bool + label: Mixed-age couple exclusion from Pension Credit in force + reference: + - title: State Pension Credit Act 2002 s.4(1A) + href: https://www.legislation.gov.uk/ukpga/2002/16/section/4 + - title: SI 2019/37 art. 3 (appointed day 15 May 2019) + href: https://www.legislation.gov.uk/uksi/2019/37/article/3 + - title: SR 2019/4 art. 3 (Northern Ireland, appointed day 15 May 2019) + href: https://www.legislation.gov.uk/nisr/2019/4/article/3 diff --git a/policyengine_uk/parameters/gov/dwp/pension_credit/mixed_age_couples/saving_latest_birth_year.yaml b/policyengine_uk/parameters/gov/dwp/pension_credit/mixed_age_couples/saving_latest_birth_year.yaml new file mode 100644 index 0000000000..9207413045 --- /dev/null +++ b/policyengine_uk/parameters/gov/dwp/pension_credit/mixed_age_couples/saving_latest_birth_year.yaml @@ -0,0 +1,13 @@ +description: Latest birth year of the older member of a mixed-age couple for the couple to keep Pension Credit under the SI 2019/37 article 4 saving. The older member must have reached the qualifying age for State Pension Credit by 14 May 2019, which means being born on or before 5 February 1954. With whole-year ages the model admits the whole of 1954. +values: + 2019-05-15: 1954 +metadata: + unit: year + label: Latest birth year for the mixed-age couple Pension Credit saving + reference: + - title: SI 2019/37 art. 4(1) + href: https://www.legislation.gov.uk/uksi/2019/37/article/4 + - title: Pensions Act 1995 Sch 4 para 1 (pensionable age by date of birth) + href: https://www.legislation.gov.uk/ukpga/1995/26/schedule/4 + - title: State Pension Credit Act 2002 s.1(6) (qualifying age) + href: https://www.legislation.gov.uk/ukpga/2002/16/section/1 diff --git a/policyengine_uk/tests/policy/baseline/gov/dwp/pension_credit/mixed_age_couples.yaml b/policyengine_uk/tests/policy/baseline/gov/dwp/pension_credit/mixed_age_couples.yaml new file mode 100644 index 0000000000..14846b2ead --- /dev/null +++ b/policyengine_uk/tests/policy/baseline/gov/dwp/pension_credit/mixed_age_couples.yaml @@ -0,0 +1,637 @@ +# Mixed-age couples: State Pension Credit Act 2002 s.4(1A), in force 15 May +# 2019 (SI 2019/37 art. 3; NI: SR 2019/4 art. 3), with the SI 2019/37 art. 4 +# saving (NI: SR 2019/4 art. 4). Housing Benefit follows UC (Transitional +# Provisions) Regs 2014 reg 6A(4)-(5). +# +# Expected amounts are hand-computed from the law's rates: +# 2026-27 couple standard minimum guarantee GBP 363.25 a week: 363.25 x 52 = 18,889 +# 2018-19 couple standard minimum guarantee GBP 248.80 a week: 248.80 x 52 = 12,937.60 +# Guarantee Credit = minimum guarantee - income (State Pension 9,000 only) +# Housing Benefit on Guarantee Credit = full eligible rent (HB SPC Regs reg 26) + +- name: Protected mixed-age couple (art. 4 saving input) gets Pension Credit and HB, not UC + period: 2026 + absolute_error_margin: 0.01 + input: + people: + older: + age: 75 + state_pension: 9_000 + younger: + age: 60 + benunits: + benunit: + members: [older, younger] + has_mixed_age_couple_pension_credit_saving: true + households: + household: + members: [older, younger] + rent: 6_240 + tenure_type: RENT_FROM_COUNCIL + output: + is_mixed_age_couple: true + meets_pension_credit_age_conditions: true + is_pension_credit_eligible: true + guarantee_credit: 9_889 + pension_credit: 9_889 + housing_benefit_eligible: true + housing_benefit: 6_240 + is_uc_eligible: false + universal_credit: 0 + +- name: Reported Pension Credit sets the saving, whatever the UC take-up draw + period: 2026 + absolute_error_margin: 0.01 + input: + people: + older: + age: 75 + state_pension: 9_000 + pension_credit_reported: 1_000 + younger: + age: 60 + benunits: + benunit: + members: [older, younger] + would_claim_uc: true + households: + household: + members: [older, younger] + rent: 6_240 + tenure_type: RENT_FROM_COUNCIL + output: + has_mixed_age_couple_pension_credit_saving: true + pension_credit: 9_889 + universal_credit: 0 + +- name: Reported pension-age HB sets the saving + period: 2026 + absolute_error_margin: 0.01 + input: + people: + older: + age: 75 + state_pension: 9_000 + housing_benefit_reported: 5_000 + younger: + age: 60 + benunits: + benunit: + members: [older, younger] + households: + household: + members: [older, younger] + rent: 6_240 + tenure_type: RENT_FROM_COUNCIL + output: + has_mixed_age_couple_pension_credit_saving: true + is_pension_credit_eligible: true + housing_benefit: 6_240 + universal_credit: 0 + +- name: HB alongside income-related ESA is working-age HB, so no saving (art. 2(3); HB SPC Regs reg 5(2)) + period: 2026 + absolute_error_margin: 0.01 + input: + people: + older: + age: 75 + state_pension: 9_000 + housing_benefit_reported: 5_000 + esa_income_reported: 3_000 + younger: + age: 60 + benunits: + benunit: + members: [older, younger] + would_claim_uc: false + households: + household: + members: [older, younger] + rent: 6_240 + tenure_type: RENT_FROM_COUNCIL + output: + has_mixed_age_couple_pension_credit_saving: false + is_pension_credit_eligible: false + pension_credit: 0 + # continuing award route (TP reg 8(2A)), unchanged from main + housing_benefit_eligible: true + +- name: A UC award ends the saving (art. 4(2)) + period: 2026 + absolute_error_margin: 0.01 + input: + people: + older: + age: 75 + state_pension: 9_000 + pension_credit_reported: 1_000 + universal_credit_reported: 2_000 + younger: + age: 60 + benunits: + benunit: + members: [older, younger] + households: + household: + members: [older, younger] + rent: 6_240 + tenure_type: RENT_FROM_COUNCIL + output: + has_mixed_age_couple_pension_credit_saving: false + pension_credit: 0 + is_uc_eligible: true + +- name: The saving input can be switched off despite reported Pension Credit + period: 2026 + absolute_error_margin: 0.01 + input: + people: + older: + age: 75 + state_pension: 9_000 + pension_credit_reported: 1_000 + younger: + age: 60 + benunits: + benunit: + members: [older, younger] + has_mixed_age_couple_pension_credit_saving: false + households: + household: + members: [older, younger] + rent: 6_240 + tenure_type: RENT_FROM_COUNCIL + output: + is_pension_credit_eligible: false + pension_credit: 0 + is_uc_eligible: true + +- name: Unprotected mixed-age couple after 15 May 2019 claims UC, not PC or HB + period: 2026 + absolute_error_margin: 0.01 + input: + people: + older: + age: 70 + state_pension: 9_000 + younger: + age: 60 + benunits: + benunit: + members: [older, younger] + households: + household: + members: [older, younger] + rent: 6_240 + tenure_type: RENT_FROM_COUNCIL + output: + has_mixed_age_couple_pension_credit_saving: false + is_pension_credit_eligible: false + housing_benefit_eligible: false + is_uc_eligible: true + +- name: Before 15 May 2019 a mixed-age couple takes the Pension Credit route (2018-19) + period: 2018 + absolute_error_margin: 0.01 + input: + people: + older: + age: 70 + state_pension: 9_000 + younger: + age: 60 + benunits: + benunit: + members: [older, younger] + households: + household: + members: [older, younger] + rent: 6_240 + tenure_type: RENT_FROM_COUNCIL + output: + meets_pension_credit_age_conditions: true + guarantee_credit: 3_937.60 + pension_credit: 3_937.60 + housing_benefit: 6_240 + is_uc_eligible: false + universal_credit: 0 + +- name: Model year 2019 (2019-20, parameters read at 30 April 2019) is before the exclusion + period: 2019 + absolute_error_margin: 0.01 + input: + people: + older: + age: 70 + state_pension: 9_000 + younger: + age: 60 + benunits: + benunit: + members: [older, younger] + households: + household: + members: [older, younger] + rent: 6_240 + tenure_type: RENT_FROM_COUNCIL + output: + meets_pension_credit_age_conditions: true + is_uc_eligible: false + universal_credit: 0 + +- name: From model year 2020 an unprotected mixed-age couple is excluded + period: 2020 + absolute_error_margin: 0.01 + input: + people: + older: + age: 70 + state_pension: 9_000 + younger: + age: 60 + benunits: + benunit: + members: [older, younger] + households: + household: + members: [older, younger] + rent: 6_240 + tenure_type: RENT_FROM_COUNCIL + output: + meets_pension_credit_age_conditions: false + is_pension_credit_eligible: false + is_uc_eligible: true + +- name: Wholly pension-age couple is unaffected by the saving input + period: 2026 + absolute_error_margin: 0.01 + input: + people: + older: + age: 70 + state_pension: 9_000 + younger: + age: 68 + benunits: + benunit: + members: [older, younger] + has_mixed_age_couple_pension_credit_saving: true + households: + household: + members: [older, younger] + rent: 6_240 + tenure_type: RENT_FROM_COUNCIL + output: + is_mixed_age_couple: false + pension_credit: 9_889 + housing_benefit: 6_240 + universal_credit: 0 + +- name: Working-age couple is unaffected by the saving input + period: 2026 + absolute_error_margin: 0.01 + input: + people: + older: + age: 40 + younger: + age: 38 + benunits: + benunit: + members: [older, younger] + has_mixed_age_couple_pension_credit_saving: true + households: + household: + members: [older, younger] + rent: 6_240 + tenure_type: RENT_FROM_COUNCIL + output: + is_mixed_age_couple: false + meets_pension_credit_age_conditions: false + is_pension_credit_eligible: false + is_uc_eligible: true + +- name: Reported Pension Credit does not protect a couple whose older member reached pension age after 14 May 2019 + # 70 in 2026-27 means 63 on 14 May 2019, below the qualifying age (65 in the + # model's 2019 parameters), so the couple was not a mixed-age couple then. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + older: + age: 70 + state_pension: 9_000 + pension_credit_reported: 1_000 + younger: + age: 60 + benunits: + benunit: + members: [older, younger] + households: + household: + members: [older, younger] + rent: 6_240 + tenure_type: RENT_FROM_COUNCIL + output: + has_mixed_age_couple_pension_credit_saving: false + pension_credit: 0 + is_uc_eligible: true + +- name: Protected couple gets the pension-age couple HB allowance (HB SPC Regs Sch 3 para 1(2)(b)) + # 383.35 a week x 52 = 19,934.20 + period: 2026 + absolute_error_margin: 0.01 + input: + people: + older: + age: 75 + state_pension: 9_000 + pension_credit_reported: 1_000 + younger: + age: 60 + benunits: + benunit: + members: [older, younger] + households: + household: + members: [older, younger] + rent: 6_240 + tenure_type: RENT_FROM_COUNCIL + output: + housing_benefit_applicable_amount: 19_934.20 + +- name: Protected couple that does not take up Pension Credit gets neither PC nor UC, but keeps reported HB + period: 2026 + absolute_error_margin: 0.01 + input: + people: + older: + age: 75 + state_pension: 9_000 + housing_benefit_reported: 5_000 + younger: + age: 60 + benunits: + benunit: + members: [older, younger] + would_claim_pc: false + households: + household: + members: [older, younger] + rent: 6_240 + tenure_type: RENT_FROM_COUNCIL + output: + has_mixed_age_couple_pension_credit_saving: true + pension_credit: 0 + housing_benefit: 6_240 + universal_credit: 0 + +- name: Northern Ireland protected couple follows the same rule (SR 2019/4 art. 4) + period: 2026 + absolute_error_margin: 0.01 + input: + people: + older: + age: 75 + state_pension: 9_000 + pension_credit_reported: 1_000 + younger: + age: 60 + benunits: + benunit: + members: [older, younger] + households: + household: + members: [older, younger] + rent: 6_240 + tenure_type: RENT_FROM_COUNCIL + region: NORTHERN_IRELAND + output: + pension_credit: 9_889 + housing_benefit: 6_240 + universal_credit: 0 + +- name: A single pensioner with an 18 year old dependant in education is not a mixed-age couple + period: 2026 + absolute_error_margin: 0.01 + input: + people: + pensioner: + age: 75 + state_pension: 9_000 + pension_credit_reported: 1_000 + is_parent: true + dependant: + age: 18 + current_education: UPPER_SECONDARY + benunits: + benunit: + members: [pensioner, dependant] + households: + household: + members: [pensioner, dependant] + rent: 6_240 + tenure_type: RENT_FROM_COUNCIL + output: + is_child_or_qualifying_young_person_for_pension_credit: [false, true] + is_claimant_or_partner: [true, false] + is_mixed_age_couple: false + has_mixed_age_couple_pension_credit_saving: false + # The dependant is not a claimant or partner (SPCA 2002 s.17), so the + # pensioner alone meets the age conditions. + meets_pension_credit_age_conditions: true + +- name: A mixed-age couple with an 18 year old dependant in education can keep the saving + period: 2026 + absolute_error_margin: 0.01 + input: + people: + older: + age: 75 + state_pension: 9_000 + pension_credit_reported: 1_000 + is_parent: true + younger: + age: 60 + dependant: + age: 18 + current_education: UPPER_SECONDARY + benunits: + benunit: + members: [older, younger, dependant] + households: + household: + members: [older, younger, dependant] + rent: 6_240 + tenure_type: RENT_FROM_COUNCIL + output: + is_mixed_age_couple: true + has_mixed_age_couple_pension_credit_saving: true + is_uc_eligible: false + universal_credit: 0 + +- name: Housing Benefit reported by the younger member does not set the saving (HB SPC Regs reg 5(1)) + period: 2026 + absolute_error_margin: 0.01 + input: + people: + older: + age: 75 + state_pension: 9_000 + younger: + age: 60 + housing_benefit_reported: 5_000 + benunits: + benunit: + members: [older, younger] + households: + household: + members: [older, younger] + rent: 6_240 + tenure_type: RENT_FROM_COUNCIL + output: + has_mixed_age_couple_pension_credit_saving: false + meets_pension_credit_age_conditions: false + pension_credit: 0 + +- name: Before 15 May 2019 a mixed-age couple reported on Universal Credit stays on it + period: 2018 + absolute_error_margin: 0.01 + input: + people: + older: + age: 70 + state_pension: 9_000 + universal_credit_reported: 2_000 + younger: + age: 60 + benunits: + benunit: + members: [older, younger] + households: + household: + members: [older, younger] + rent: 6_240 + tenure_type: RENT_FROM_COUNCIL + output: + is_mixed_age_couple: true + meets_pension_credit_age_conditions: false + is_pension_credit_eligible: false + is_uc_eligible: true + +- name: A grandparent outside the couple does not supply the saving's age evidence + # The benefit unit's claimant and partner are 70 and 60; the 70-year-old was + # born in 1956, after the qualifying date. A 90-year-old grandparent in the + # same benefit unit is not the claimant or partner, so their age cannot meet + # SI 2019/37 art. 4(1). + period: 2026 + absolute_error_margin: 0.01 + input: + people: + grandparent: + age: 90 + is_claimant_or_partner: false + housing_benefit_reported: 5_000 + claimant: + age: 70 + is_claimant_or_partner: true + state_pension: 9_000 + pension_credit_reported: 1_000 + partner: + age: 60 + is_claimant_or_partner: true + benunits: + benunit: + members: [grandparent, claimant, partner] + households: + household: + members: [grandparent, claimant, partner] + output: + is_mixed_age_couple: true + has_mixed_age_couple_pension_credit_saving: false + +- name: A grandparent's reported Pension Credit does not supply the couple's saving + # The claimant (75, born 1951) and partner (60) report nothing; only the + # grandparent reports Pension Credit, which is not the couple's award. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + grandparent: + age: 92 + is_claimant_or_partner: false + pension_credit_reported: 1_000 + claimant: + age: 75 + is_claimant_or_partner: true + state_pension: 9_000 + partner: + age: 60 + is_claimant_or_partner: true + benunits: + benunit: + members: [grandparent, claimant, partner] + households: + household: + members: [grandparent, claimant, partner] + output: + is_mixed_age_couple: true + has_mixed_age_couple_pension_credit_saving: false + +- name: A grandparent's reported Housing Benefit does not supply the couple's saving + # The claimant (75, born 1951) is old enough and the couple reports nothing. + # Only the grandparent, who is over State Pension age, reports Housing + # Benefit, and that is not the couple's award (SI 2019/37 art. 2(2)(a)). + period: 2026 + absolute_error_margin: 0.01 + input: + people: + grandparent: + age: 90 + is_claimant_or_partner: false + housing_benefit_reported: 5_000 + claimant: + age: 75 + is_claimant_or_partner: true + state_pension: 9_000 + partner: + age: 60 + is_claimant_or_partner: true + benunits: + benunit: + members: [grandparent, claimant, partner] + households: + household: + members: [grandparent, claimant, partner] + output: + is_mixed_age_couple: true + has_mixed_age_couple_pension_credit_saving: false + +- name: Before the exclusion, a grandparent's Universal Credit does not move the couple onto it + # In model year 2018 a mixed-age couple not reported on Universal Credit + # takes the Pension Credit route. Only the couple's own report counts. + period: 2018 + absolute_error_margin: 0.01 + input: + people: + grandparent: + age: 90 + is_claimant_or_partner: false + universal_credit_reported: 3_000 + claimant: + age: 70 + is_claimant_or_partner: true + state_pension: 7_000 + partner: + age: 55 + is_claimant_or_partner: true + benunits: + benunit: + members: [grandparent, claimant, partner] + households: + household: + members: [grandparent, claimant, partner] + output: + is_mixed_age_couple: true + meets_pension_credit_age_conditions: true diff --git a/policyengine_uk/tests/test_housing_benefit_pension_age_properties.py b/policyengine_uk/tests/test_housing_benefit_pension_age_properties.py index 147b4e3fe9..083de4e693 100644 --- a/policyengine_uk/tests/test_housing_benefit_pension_age_properties.py +++ b/policyengine_uk/tests/test_housing_benefit_pension_age_properties.py @@ -19,7 +19,9 @@ 3. Dataset mode (claims_all_entitled_benefits False, as in the FRS): Housing Benefit is paid only to reported claimants, and for families with a working-age adult eligibility equals the continuing-award rule (reported, - not claiming Universal Credit, renting, capital within the limit). + not claiming Universal Credit, renting, capital within the limit), or, + for a mixed-age couple keeping the SI 2019/37 art. 4 saving, the new-claim + rule (renting, capital within the limit; reg 6A(5)). 4. Metamorphic: flipping would_claim_uc never changes a wholly pension-age family's Housing Benefit. 5. Metamorphic: a wholly pension-age family's Housing Benefit is @@ -208,13 +210,26 @@ def test_dataset_take_up_stays_anchored_to_reported_claims(units): if values["housing_benefit"][i] > 0: assert unit["hb_reported"] > 0, unit if not wholly_pension_age(unit): + renting_within_capital = values["renting"][i] and values["capital_ok"][i] continuing_award = ( unit["hb_reported"] > 0 and not unit["would_claim_uc"] - and values["renting"][i] - and values["capital_ok"][i] + and renting_within_capital ) - assert bool(values["housing_benefit_eligible"][i]) == continuing_award + # SI 2019/37 art. 4 saving, computed from the drawn unit rather + # than the model: a mixed-age couple whose pension-age claimant + # reports Housing Benefit (no UC or legacy benefits are drawn) + # and was born by 1954 (over the qualifying age on 14 May 2019). + claimant_age = unit["members"][0][1] + saved_mixed_age_couple = ( + unit["shape"] == "mixed_age" + and unit["hb_reported"] > 0 + and YEAR - claimant_age <= 1954 + and renting_within_capital + ) + assert bool(values["housing_benefit_eligible"][i]) == ( + continuing_award or saved_mixed_age_couple + ), unit @PROPERTY_SETTINGS diff --git a/policyengine_uk/tests/test_mixed_age_couple_properties.py b/policyengine_uk/tests/test_mixed_age_couple_properties.py new file mode 100644 index 0000000000..a6b08165e9 --- /dev/null +++ b/policyengine_uk/tests/test_mixed_age_couple_properties.py @@ -0,0 +1,274 @@ +"""Mixed-age couples: State Pension Credit Act 2002 s.4(1A) and SI 2019/37. + +From 15 May 2019 (SI 2019/37 art. 3) a member of a couple whose partner has +not reached the qualifying age for State Pension Credit is not entitled to +it, and the couple claims Universal Credit instead. Couples entitled to +Pension Credit or pension-age Housing Benefit on 14 May 2019 keep them while +they stay entitled (art. 4). Before that date a mixed-age couple could claim +Pension Credit and pension-age Housing Benefit. + +Invariants, for every drawn household: + +P1 pension_credit > 0 implies universal_credit == 0. +P2 housing_benefit > 0 implies universal_credit == 0. +P3 meets_pension_credit_age_conditions implies not is_uc_eligible (UC + (Transitional Provisions) Regs 2014 reg 5(1)(d): one route per family). +P4 For a benefit unit that is not a mixed-age couple, the saving input + changes nothing. +P5 Differential against the formulas before this change: units that are + not mixed-age couples, and mixed-age couples without the saving from + model year 2020, get the same Pension Credit, Housing Benefit, Universal + Credit and household net income. +P6 From model year 2020, the saving never lowers Pension Credit or Housing + Benefit and leaves Universal Credit at 0. +P7 In model years 2018 and 2019 every mixed-age couple not reported on + Universal Credit meets the Pension Credit age conditions, whatever the + saving input; one reported on UC meets them only with the saving. +P8 The default saving is never set where the older member was born after + 1954 (so had not reached the qualifying age by 14 May 2019), or where + the couple reports Universal Credit. +""" + +import json + +from hypothesis import HealthCheck, given, settings +from hypothesis import strategies as st +from policyengine_core.reforms import Reform + +from policyengine_uk import Simulation +from policyengine_uk.model_api import * + +OUTPUTS = ["pension_credit", "housing_benefit", "universal_credit"] +SHAPES = [ + "single_pension", + "couple_pension", + "mixed", + "single_working", + "couple_working", + # An 18 year old dependant in upper secondary education is a qualifying + # young person for Pension Credit, not a partner. + "single_pension_with_dependant", + "couple_pension_with_dependant", + "mixed_with_dependant", +] +MIXED_AGE_COUPLE_SHAPES = {"mixed", "mixed_with_dependant"} +TENURES = ["RENT_FROM_COUNCIL", "RENT_PRIVATELY", "OWNED_OUTRIGHT"] + + +# The three eligibility formulas as they were before the mixed-age couple +# rules, kept verbatim as the reference for the differential invariant P5. +# They read the claimant and partner (is_claimant_or_partner), so an 18 or 19 +# year old dependant does not put a pensioner on the Universal Credit route. +class is_pension_credit_eligible(Variable): + value_type = bool + entity = BenUnit + label = "Eligible for Pension Credit (before the mixed-age couple rules)" + definition_period = YEAR + + def formula(benunit, period, parameters): + claimant_or_partner = benunit.members("is_claimant_or_partner", period) + claimant_count = benunit.sum(claimant_or_partner) + all_claimants_are_sp_age = ( + benunit.sum(claimant_or_partner & benunit.members("is_SP_age", period)) + == claimant_count + ) + is_gc_eligible = benunit("is_guarantee_credit_eligible", period) + is_sc_eligible = benunit("is_savings_credit_eligible", period) + return ( + (claimant_count > 0) + & all_claimants_are_sp_age + & (is_gc_eligible | is_sc_eligible) + ) + + +class housing_benefit_eligible(Variable): + value_type = bool + entity = BenUnit + label = "Eligible for Housing Benefit (before the mixed-age couple rules)" + definition_period = YEAR + + def formula(benunit, period, parameters): + person = benunit.members + sp_age = person("is_SP_age", period) + claimant_or_partner = person("is_claimant_or_partner", period) + count = benunit.sum(claimant_or_partner) + pension_age = (count > 0) & (benunit.sum(claimant_or_partner & sp_age) == count) + already_claiming = add(benunit, period, ["housing_benefit_reported"]) > 0 + claiming_uc = benunit("would_claim_uc", period) + continuing_award = already_claiming & ~claiming_uc + social = benunit.any(person("in_social_housing", period)) + lha_eligible = benunit("LHA_eligible", period) + any_over_SP_age = benunit.any(sp_age) + capital = benunit("housing_benefit_assessable_capital", period) + hb_capital = parameters(period).gov.dwp.housing_benefit.means_test.capital + limit = where( + any_over_SP_age, + hb_capital.pension_age.limit, + hb_capital.working_age.limit, + ) + return ( + (pension_age | continuing_award) + & (social | lha_eligible) + & (capital <= limit) + ) + + +class is_uc_eligible(Variable): + value_type = bool + entity = BenUnit + label = "Eligible for Universal Credit (before the mixed-age couple rules)" + definition_period = YEAR + + def formula(benunit, period, parameters): + capital = benunit("uc_assessable_capital", period) + limit = parameters(period).gov.dwp.universal_credit.means_test.capital.limit + claimant = benunit.members("is_uc_claimant", period) + meets_minimum_age = benunit.members("meets_uc_minimum_age_condition", period) + pension_age = benunit.members("is_SP_age", period) + has_qualifying_claimant = benunit.any( + claimant & meets_minimum_age & ~pension_age + ) + return has_qualifying_claimant & (capital <= limit) + + +class before_mixed_age_couple_rules(Reform): + def apply(self): + self.update_variable(is_pension_credit_eligible) + self.update_variable(housing_benefit_eligible) + self.update_variable(is_uc_eligible) + + +@st.composite +def cases(draw): + year = draw(st.sampled_from([2018, 2019, 2020, 2025, 2026])) + shape = draw(st.sampled_from(SHAPES)) + pension_age = st.integers(67, 90) + working_age = st.integers(25, 59) + older_is_pension_age = "pension" in shape or shape.startswith("mixed") + people = { + "older": {"age": draw(pension_age if older_is_pension_age else working_age)} + } + if shape.startswith("couple") or shape.startswith("mixed"): + people["younger"] = { + "age": draw( + pension_age if shape.startswith("couple_pension") else working_age + ) + } + if shape.endswith("with_dependant"): + people["dependant"] = {"age": 18, "current_education": "UPPER_SECONDARY"} + people["older"]["is_parent"] = True + for name, person in people.items(): + if name == "dependant": + continue + if person["age"] >= 67: + person["state_pension"] = draw(st.integers(0, 15_000)) + else: + person["employment_income"] = draw( + st.sampled_from([0, 0, 5_000, 15_000, 30_000]) + ) + older = people["older"] + older["pension_credit_reported"] = draw(st.sampled_from([0, 0, 1_000])) + older["housing_benefit_reported"] = draw(st.sampled_from([0, 0, 4_000])) + older["universal_credit_reported"] = draw(st.sampled_from([0, 0, 0, 2_000])) + older["esa_income_reported"] = draw(st.sampled_from([0, 0, 0, 3_000])) + tenure = draw(st.sampled_from(TENURES)) + return { + "year": year, + "shape": shape, + "people": people, + "benunit": { + "would_claim_uc": draw(st.booleans()), + "would_claim_pc": draw(st.booleans()), + "BRMA_LHA_rate": draw(st.integers(4_000, 12_000)), + }, + "household": { + "tenure_type": tenure, + "rent": 0 if tenure == "OWNED_OUTRIGHT" else draw(st.integers(0, 12_000)), + "savings": draw(st.sampled_from([0, 5_000, 20_000])), + "region": "NORTH_WEST", + "council_tax": 1_500, + }, + } + + +def situation(case): + year = case["year"] + + def at_year(values): + return {name: {year: value} for name, value in values.items()} + + members = list(case["people"]) + return { + "people": {name: at_year(p) for name, p in case["people"].items()}, + "benunits": {"b": {"members": members, **at_year(case["benunit"])}}, + "households": {"h": {"members": members, **at_year(case["household"])}}, + } + + +def run(case, before=False, saving=None): + simulation = Simulation(situation=situation(case)) + year = case["year"] + if before: + simulation.apply_reform(before_mixed_age_couple_rules) + elif saving is not None: + simulation.set_input( + "has_mixed_age_couple_pension_credit_saving", year, [saving] + ) + + def get(variable): + return simulation.calculate(variable, year)[0] + + result = {variable: float(get(variable)) for variable in OUTPUTS} + result["net"] = float(get("household_net_income")) + if not before: + result["age_conditions"] = bool(get("meets_pension_credit_age_conditions")) + result["uc_eligible"] = bool(get("is_uc_eligible")) + result["mixed"] = bool(get("is_mixed_age_couple")) + result["saving"] = bool(get("has_mixed_age_couple_pension_credit_saving")) + return result + + +def close(a, b): + return abs(a - b) < 0.01 + + +@settings( + max_examples=40, + deadline=None, + derandomize=True, + suppress_health_check=[HealthCheck.too_slow], +) +@given(cases()) +def test_mixed_age_couple_invariants(case): + before = run(case, before=True) + on = run(case, saving=True) + off = run(case, saving=False) + default = run(case) + context = json.dumps(case) + for result in (on, off, default): + assert not (result["pension_credit"] > 0 and result["universal_credit"] > 0) + assert not (result["housing_benefit"] > 0 and result["universal_credit"] > 0) + assert not (result["age_conditions"] and result["uc_eligible"]), context + mixed = on["mixed"] + assert mixed == (case["shape"] in MIXED_AGE_COUPLE_SHAPES), context + if not mixed: + for variable in OUTPUTS + ["net"]: + assert close(on[variable], off[variable]), (variable, context) # P4 + assert close(on[variable], default[variable]), (variable, context) + assert close(off[variable], before[variable]), (variable, context) # P5 + elif case["year"] >= 2020: + for variable in OUTPUTS + ["net"]: + assert close(off[variable], before[variable]), (variable, context) # P5 + assert on["pension_credit"] >= off["pension_credit"] - 0.01, context # P6 + assert on["housing_benefit"] >= off["housing_benefit"] - 0.01, context + assert on["universal_credit"] == 0, context + else: + # P7: before the exclusion only a couple reported on UC stays on it. + on_uc = case["people"]["older"]["universal_credit_reported"] > 0 + assert on["age_conditions"], context + assert off["age_conditions"] == (not on_uc), context + assert default["age_conditions"] == (not on_uc), context + older = case["people"]["older"] + if default["saving"]: # P8 + assert case["year"] - older["age"] <= 1954, context + assert older["universal_credit_reported"] == 0, context diff --git a/policyengine_uk/variables/gov/dwp/housing_benefit/housing_benefit_eligible.py b/policyengine_uk/variables/gov/dwp/housing_benefit/housing_benefit_eligible.py index 6c65db61b8..f3955f6b5a 100644 --- a/policyengine_uk/variables/gov/dwp/housing_benefit/housing_benefit_eligible.py +++ b/policyengine_uk/variables/gov/dwp/housing_benefit/housing_benefit_eligible.py @@ -18,6 +18,7 @@ class housing_benefit_eligible(Variable): definition_period = YEAR reference = ( "https://www.legislation.gov.uk/uksi/2014/1230/regulation/6A", + "https://www.legislation.gov.uk/ukpga/2002/16/section/4", "https://www.legislation.gov.uk/uksi/2014/1230/regulation/8", "https://www.legislation.gov.uk/uksi/2019/37/article/4", "https://www.legislation.gov.uk/ukpga/2012/5/section/4", @@ -29,21 +30,22 @@ def formula(benunit, period, parameters): sp_age = person("is_SP_age", period) # New claims are barred except where the claimant, and any partner, # has reached the qualifying age for State Pension Credit - # (SI 2014/1230 reg 6A(4); NI: SR 2016/226 reg 4A(4)). This is the - # same claimant-and-partner set is_uc_eligible and - # is_pension_credit_eligible use, so a pensioner with an 18 or 19 year - # old dependant can claim Housing Benefit and not Universal Credit; - # change the three together. - claimant_or_partner = person("is_claimant_or_partner", period) - count = benunit.sum(claimant_or_partner) - pension_age = (count > 0) & (benunit.sum(claimant_or_partner & sp_age) == count) - # Working-age and mixed-age families (since 15 May 2019) claim - # Universal Credit instead. They keep an existing award until they - # claim it (reg 8(2A)), so this route also rules out receiving - # Universal Credit. For mixed-age couples the reported award stands - # in for the SI 2019/37 art. 4 saving (reg 6A(5)). Working-age awards - # outside specified or temporary accommodation ended on 1 July 2026 - # in Great Britain (SI 2025/1148 art. 7); that is not modelled. + # (SI 2014/1230 reg 6A(4); NI: SR 2016/226 reg 4A(4)), or the claim + # is made by the older member of a mixed-age couple that keeps the + # SI 2019/37 art. 4 saving (reg 6A(5); NI reg 4A(5)). Before 15 May + # 2019 mixed-age couples could claim too. These are the Pension + # Credit age conditions, which also rule out Universal Credit + # (is_uc_eligible), so no family on this route receives it. They read + # the claimant and partner (is_claimant_or_partner), so a pensioner + # with an 18 or 19 year old dependant can claim Housing Benefit and + # not Universal Credit. + pension_age = benunit("meets_pension_credit_age_conditions", period) + # Working-age families, and mixed-age couples without the saving + # (since 15 May 2019), claim Universal Credit instead. They keep an + # existing award until they claim it (reg 8(2A)), so this route also + # rules out receiving Universal Credit. Working-age awards outside + # specified or temporary accommodation ended on 1 July 2026 in Great + # Britain (SI 2025/1148 art. 7); that is not modelled. already_claiming = add(benunit, period, ["housing_benefit_reported"]) > 0 claiming_uc = benunit("would_claim_uc", period) continuing_award = already_claiming & ~claiming_uc diff --git a/policyengine_uk/variables/gov/dwp/pension_credit/guarantee_credit/in_receipt_of_guarantee_credit.py b/policyengine_uk/variables/gov/dwp/pension_credit/guarantee_credit/in_receipt_of_guarantee_credit.py index 877ab3606b..1127e6753d 100644 --- a/policyengine_uk/variables/gov/dwp/pension_credit/guarantee_credit/in_receipt_of_guarantee_credit.py +++ b/policyengine_uk/variables/gov/dwp/pension_credit/guarantee_credit/in_receipt_of_guarantee_credit.py @@ -9,10 +9,10 @@ class in_receipt_of_guarantee_credit(Variable): "claims it, and its Guarantee Credit is positive. A Guarantee Credit " "computed for a family that does not claim Pension Credit, or that the " "model does not treat as eligible for it (for example a working-age " - "family), is not received. The model's Pension Credit eligibility " - "omits the SI 2019/37 article 4 saving, so a mixed-age couple it saves " - "(entitled to Pension Credit or Housing Benefit as that couple on 14 " - "May 2019, and to either ever since) is not treated as in receipt. Under " + "family), is not received. A mixed-age couple that keeps Pension " + "Credit under the SI 2019/37 article 4 saving is eligible " + "(meets_pension_credit_age_conditions), so it is in receipt when it " + "claims and its Guarantee Credit is positive. Under " "the Pension Credit freeze the baseline receipt is kept, because the " "frozen award is the baseline award." ) diff --git a/policyengine_uk/variables/gov/dwp/pension_credit/is_pension_credit_eligible.py b/policyengine_uk/variables/gov/dwp/pension_credit/is_pension_credit_eligible.py index ec51831654..d970390993 100644 --- a/policyengine_uk/variables/gov/dwp/pension_credit/is_pension_credit_eligible.py +++ b/policyengine_uk/variables/gov/dwp/pension_credit/is_pension_credit_eligible.py @@ -10,20 +10,12 @@ class is_pension_credit_eligible(Variable): reference = ( "https://www.legislation.gov.uk/ukpga/2002/16/section/1", "https://www.legislation.gov.uk/ukpga/2002/16/section/4", + "https://www.legislation.gov.uk/uksi/2019/37/article/4", ) def formula(benunit, period, parameters): - claimant_or_partner = benunit.members("is_claimant_or_partner", period) - claimant_count = benunit.sum(claimant_or_partner) - all_claimants_are_sp_age = ( - benunit.sum(claimant_or_partner & benunit.members("is_SP_age", period)) - == claimant_count - ) - # Mixed-age transitional protection under SI 2019/37 art. 4 is not modelled. is_gc_eligible = benunit("is_guarantee_credit_eligible", period) is_sc_eligible = benunit("is_savings_credit_eligible", period) - return ( - (claimant_count > 0) - & all_claimants_are_sp_age - & (is_gc_eligible | is_sc_eligible) + return benunit("meets_pension_credit_age_conditions", period) & ( + is_gc_eligible | is_sc_eligible ) diff --git a/policyengine_uk/variables/gov/dwp/pension_credit/meets_pension_credit_age_conditions.py b/policyengine_uk/variables/gov/dwp/pension_credit/meets_pension_credit_age_conditions.py new file mode 100644 index 0000000000..1df5294698 --- /dev/null +++ b/policyengine_uk/variables/gov/dwp/pension_credit/meets_pension_credit_age_conditions.py @@ -0,0 +1,53 @@ +from policyengine_uk.model_api import * + + +class meets_pension_credit_age_conditions(Variable): + value_type = bool + entity = BenUnit + label = "Meets the State Pension Credit age conditions" + documentation = ( + "The claimant has reached the qualifying age for State Pension Credit " + "and, while the mixed-age couple exclusion is in force (from 15 May " + "2019), so has any partner, unless the couple keeps Pension Credit " + "under the SI 2019/37 article 4 saving. A family meeting these " + "conditions is on the pension-age route (Pension Credit and pension-age " + "Housing Benefit) and is not eligible for Universal Credit." + ) + definition_period = YEAR + reference = ( + "https://www.legislation.gov.uk/ukpga/2002/16/section/1", + "https://www.legislation.gov.uk/ukpga/2002/16/section/4", + "https://www.legislation.gov.uk/uksi/2019/37/article/4", + "https://www.legislation.gov.uk/uksi/2014/1230/regulation/5", + "https://www.legislation.gov.uk/uksi/2014/1230/regulation/6A", + ) + + def formula(benunit, period, parameters): + person = benunit.members + claimant_or_partner = person("is_claimant_or_partner", period) + count = benunit.sum(claimant_or_partner) + all_pension_age = (count > 0) & ( + benunit.sum(claimant_or_partner & person("is_SP_age", period)) == count + ) + # Parameters are read at 30 April of the model year + # (convert_to_fiscal_year_parameters), so model year 2019 (2019-20) + # falls before the 15 May 2019 exclusion. Couples already on Pension + # Credit or pension-age Housing Benefit on 14 May 2019 kept them, so + # the old rule is the closer approximation for that year. + excluded = parameters(period).gov.dwp.pension_credit.mixed_age_couples.excluded + saving = benunit("has_mixed_age_couple_pension_credit_saving", period) + # Before the exclusion a mixed-age couple could claim either Pension + # Credit or Universal Credit jointly (UC Regs 2013 reg 3(2)(a)); a + # couple reported on Universal Credit stays on it, and any other takes + # the Pension Credit route. This is a modelling choice. + reports_uc = ( + add_for_members( + benunit, period, ["universal_credit_reported"], claimant_or_partner + ) + > 0 + ) + before_exclusion = np.logical_not(excluded) & ~reports_uc + mixed_age_route = benunit("is_mixed_age_couple", period) & ( + before_exclusion | saving + ) + return all_pension_age | mixed_age_route diff --git a/policyengine_uk/variables/gov/dwp/pension_credit/mixed_age_couples/has_mixed_age_couple_pension_credit_saving.py b/policyengine_uk/variables/gov/dwp/pension_credit/mixed_age_couples/has_mixed_age_couple_pension_credit_saving.py new file mode 100644 index 0000000000..57b3d9b4e7 --- /dev/null +++ b/policyengine_uk/variables/gov/dwp/pension_credit/mixed_age_couples/has_mixed_age_couple_pension_credit_saving.py @@ -0,0 +1,80 @@ +from policyengine_uk.model_api import * + + +class has_mixed_age_couple_pension_credit_saving(Variable): + value_type = bool + entity = BenUnit + label = "Mixed-age couple keeps Pension Credit under the SI 2019/37 saving" + documentation = ( + "Whether the State Pension Credit Act 2002 s.4(1A) exclusion does not " + "apply to a mixed-age couple, because on 14 May 2019 the couple was " + "entitled, as that couple, to Pension Credit or pension-age Housing " + "Benefit, and has been entitled to one of them ever since. Set it as " + "an input where it is known. By default it is inferred from current " + "receipt: reported Pension Credit, or Housing Benefit reported by the " + "pension-age member without Income Support, income-based JSA or " + "income-related ESA (which would " + "put the couple under the working-age Housing Benefit Regulations), " + "with no reported Universal Credit, where the older member was born " + "early enough to have reached the qualifying age by 14 May 2019." + ) + definition_period = YEAR + reference = ( + "https://www.legislation.gov.uk/uksi/2019/37/article/2", + "https://www.legislation.gov.uk/uksi/2019/37/article/4", + "https://www.legislation.gov.uk/uksi/2006/214/regulation/5", + "https://www.legislation.gov.uk/uksi/2014/1230/regulation/5", + "https://www.legislation.gov.uk/nisr/2019/4/article/4", + ) + + def formula(benunit, period, parameters): + p = parameters(period).gov.dwp.pension_credit.mixed_age_couples + + person = benunit.members + # Only the claimant and partner's own awards and ages count: the + # saving belongs to the couple (art. 4(1)), not to other members of + # the benefit unit. + claimant_or_partner = person("is_claimant_or_partner", period) + + def reported(variables): + return add_for_members(benunit, period, variables, claimant_or_partner) > 0 + + # Art. 2(3): only Housing Benefit under the pension-age regulations + # (SI 2006/214) carries the saving. They apply to a claimant who has + # reached the qualifying age (reg 5(1)), so only HB reported by the + # pension-age member counts, and not where the couple is on an + # income-related legacy benefit, which puts it under the working-age + # regulations (reg 5(2)). + pension_age_member_hb = ( + benunit.sum( + person("housing_benefit_reported", period) + * person("is_SP_age", period) + * claimant_or_partner + ) + > 0 + ) + pension_age_hb = pension_age_member_hb & ~reported( + [ + "income_support_reported", + "jsa_income_reported", + "esa_income_reported", + ] + ) + # Art. 4(2) ends the saving once the couple is entitled to neither + # benefit, which Universal Credit entitlement implies (TP Regs 2014 + # reg 5(1)(d)). + receives_uc = reported(["universal_credit_reported"]) + # Art. 4(1) needs the couple to have been a mixed-age couple on + # 14 May 2019, so its older member had reached the qualifying age by + # then. + older_member_qualified = benunit.any( + claimant_or_partner + & person("is_SP_age", period) + & (person("birth_year", period) <= p.saving_latest_birth_year) + ) + return ( + benunit("is_mixed_age_couple", period) + & older_member_qualified + & (reported(["pension_credit_reported"]) | pension_age_hb) + & ~receives_uc + ) diff --git a/policyengine_uk/variables/gov/dwp/pension_credit/mixed_age_couples/is_mixed_age_couple.py b/policyengine_uk/variables/gov/dwp/pension_credit/mixed_age_couples/is_mixed_age_couple.py new file mode 100644 index 0000000000..353036cb5f --- /dev/null +++ b/policyengine_uk/variables/gov/dwp/pension_credit/mixed_age_couples/is_mixed_age_couple.py @@ -0,0 +1,25 @@ +from policyengine_uk.model_api import * + + +class is_mixed_age_couple(Variable): + value_type = bool + entity = BenUnit + label = "Mixed-age couple" + documentation = ( + "A couple one member of which has reached the qualifying age for State " + "Pension Credit and the other of which has not." + ) + definition_period = YEAR + reference = ( + "https://www.legislation.gov.uk/uksi/2019/37/article/2", + "https://www.legislation.gov.uk/ukpga/2002/16/section/4", + ) + + def formula(benunit, period, parameters): + person = benunit.members + # The claimant and partner (SPCA 2002 s.17), so a pensioner with an + # 18 or 19 year old dependant is not a couple here. + claimant_or_partner = person("is_claimant_or_partner", period) + pension_age = person("is_SP_age", period) + n_pension_age = benunit.sum(claimant_or_partner & pension_age) + return (benunit.sum(claimant_or_partner) == 2) & (n_pension_age == 1) diff --git a/policyengine_uk/variables/gov/dwp/universal_credit/is_uc_eligible.py b/policyengine_uk/variables/gov/dwp/universal_credit/is_uc_eligible.py index f8c205416b..214f762c85 100644 --- a/policyengine_uk/variables/gov/dwp/universal_credit/is_uc_eligible.py +++ b/policyengine_uk/variables/gov/dwp/universal_credit/is_uc_eligible.py @@ -9,13 +9,16 @@ class is_uc_eligible(Variable): "Whether a claimant or partner meets the modelled minimum-age and " "pension-age conditions and the benefit unit meets the capital limit. " "One qualifying claimant suffices, preserving mixed-age couples under " - "regulation 3(2)(a). Dependants cannot satisfy the claimant age test." + "regulation 3(2)(a). Dependants cannot satisfy the claimant age test. " + "A family on the Pension Credit route " + "(meets_pension_credit_age_conditions) is not eligible." ) definition_period = YEAR reference = ( "https://www.legislation.gov.uk/ukpga/2012/5/section/3", "https://www.legislation.gov.uk/ukpga/2012/5/section/4", "https://www.legislation.gov.uk/uksi/2013/376/regulation/3", + "https://www.legislation.gov.uk/uksi/2014/1230/regulation/5", ) def formula(benunit, period, parameters): @@ -27,4 +30,13 @@ def formula(benunit, period, parameters): has_qualifying_claimant = benunit.any( claimant & meets_minimum_age & ~pension_age ) - return has_qualifying_claimant & (capital <= limit) + # No family gets both Pension Credit and Universal Credit (UC + # (Transitional Provisions) Regs 2014 reg 5(1)(d)). A mixed-age couple + # keeping the SI 2019/37 saving could still choose Universal Credit + # jointly (UC Regs 2013 reg 3(2)(a)) and lose the saving; the model + # keeps it on the Pension Credit route, anchored to its reported + # Pension Credit or Housing Benefit. That, and routing mixed-age + # couples not reported on Universal Credit to Pension Credit before + # 15 May 2019, are modelling choices. + pension_credit_route = benunit("meets_pension_credit_age_conditions", period) + return has_qualifying_claimant & ~pension_credit_route & (capital <= limit)