diff --git a/changelog.d/1971.fixed.md b/changelog.d/1971.fixed.md new file mode 100644 index 0000000000..8203a92bc9 --- /dev/null +++ b/changelog.d/1971.fixed.md @@ -0,0 +1 @@ +Pay the legacy enhanced disability premium for an award of enhanced PIP daily living or armed forces independence payment as well as the highest DLA care rate, and apply its State Pension Credit age limit. Count an award only where its amount is positive, and count an amount entered without its category when it reaches `52 × (top weekly rate − £1)`. Give four working-age Council Tax Reduction schemes their own lists. Scottish councils count attendance allowance at either rate from April 2023, and the Scottish Ministers removed the age limit from June 2022. Merton and Westminster count either PIP daily living rate and omit armed forces independence payment; Newham counts either PIP daily living rate and armed forces independence payment. In Kingston upon Thames the model keeps reading `is_enhanced_disabled_for_benefits`, with no age limit, until it can apply the council's own list. diff --git a/policyengine_uk/parameters/gov/dwp/disability_premia/enhanced_qualifying_benefits.yaml b/policyengine_uk/parameters/gov/dwp/disability_premia/enhanced_qualifying_benefits.yaml new file mode 100644 index 0000000000..2b27fd8483 --- /dev/null +++ b/policyengine_uk/parameters/gov/dwp/disability_premia/enhanced_qualifying_benefits.yaml @@ -0,0 +1,41 @@ +description: > + Claimants and partners in Great Britain qualify for the legacy enhanced + disability premium through the care component of disability living allowance + at the highest rate (has_highest_dla_sc_award), the daily living component + of personal independence payment at the enhanced rate + (has_enhanced_pip_dl_award) and armed forces independence payment. The model + applies each programme's further conditions, such as the age limit, + elsewhere. Claimants also qualify through the Scottish equivalents (the care + components of child disability payment and Scottish adult disability living + allowance at the highest rate, and the daily living component of adult + disability payment at the enhanced rate), for which the model has no + separate variables. Claimants qualify through the PIP daily living component + from 8 April 2013 under S.I. 2013/388, and through armed forces independence + payment from the same date under S.I. 2013/591. The + enhanced_qualifying_benefits_northern_ireland parameter holds Northern + Ireland's list. The model reads the list as at 30 April of each year from + 2015 and does not prorate a change made during a year. +metadata: + label: Legacy benefit enhanced disability premium qualifying benefits + period: year + unit: list + reference: + - title: The Housing Benefit Regulations 2006 Sch. 3 para. 15(1)(b), (c), (d) + href: https://www.legislation.gov.uk/uksi/2006/213/schedule/3/paragraph/15 + - title: The Income Support (General) Regulations 1987 Sch. 2 para. 13A(1ZA) + href: https://www.legislation.gov.uk/uksi/1987/1967/schedule/2/paragraph/13A + - title: The Employment and Support Allowance Regulations 2008 Sch. 4 para. 7(1)(b)-(d) + href: https://www.legislation.gov.uk/uksi/2008/794/schedule/4/paragraph/7 + - title: The Jobseeker's Allowance Regulations 1996 Sch. 1 para. 15A(1ZA) + href: https://www.legislation.gov.uk/uksi/1996/207/schedule/1/paragraph/15A + - title: The Personal Independence Payment (Supplementary Provisions and Consequential Amendments) Regulations 2013 reg. 2 + href: https://www.legislation.gov.uk/uksi/2013/388/regulation/2 + - title: "The Armed Forces and Reserve Forces Compensation Scheme (Consequential Provisions: Subordinate Legislation) Order 2013 art. 2" + href: https://www.legislation.gov.uk/uksi/2013/591/article/2 +values: + 2006-03-06: + - has_highest_dla_sc_award + 2013-04-08: + - has_highest_dla_sc_award + - has_enhanced_pip_dl_award + - armed_forces_independence_payment diff --git a/policyengine_uk/parameters/gov/dwp/disability_premia/enhanced_qualifying_benefits_northern_ireland.yaml b/policyengine_uk/parameters/gov/dwp/disability_premia/enhanced_qualifying_benefits_northern_ireland.yaml new file mode 100644 index 0000000000..9b6b7b4338 --- /dev/null +++ b/policyengine_uk/parameters/gov/dwp/disability_premia/enhanced_qualifying_benefits_northern_ireland.yaml @@ -0,0 +1,47 @@ +description: > + Claimants and partners in Northern Ireland qualify for the legacy enhanced + disability premium through the care component of disability living allowance + at the highest rate. In Income Support, Jobseeker's Allowance, Housing + Benefit and Employment and Support Allowance, they also qualify through + armed forces independence payment from 24 December 2013 under S.I. + 2013/3021, and through the daily living component of personal independence + payment at the enhanced rate from 20 June 2016 under S.R. 2016/228. The + model reads the list as at 30 April of each year from 2015 and does not + prorate a change made during a year, so it counts the daily living component + from 2017. The model dates the first value from the Great Britain list's + start, not from the commencement of S.R. 2006/405 on 20 November 2006. +metadata: + label: Northern Ireland legacy benefit enhanced disability premium qualifying benefits + period: year + unit: list + reference: + - title: The Housing Benefit Regulations (Northern Ireland) 2006 Sch. 4 para. 15(1)(aa), (b), (c) + href: https://www.legislation.gov.uk/nisr/2006/405/schedule/4/paragraph/15 + - title: The Employment and Support Allowance Regulations (Northern Ireland) 2008 Sch. 4 para. 7(1)(aa), (b), (c) + href: https://www.legislation.gov.uk/nisr/2008/280/schedule/4/paragraph/7 + - title: S.I. 2013/3021 art. 1 (commencement) + href: https://www.legislation.gov.uk/uksi/2013/3021/article/1 + - title: S.I. 2013/3021 art. 14(5)(d) (Income Support) + href: https://www.legislation.gov.uk/uksi/2013/3021/article/14 + - title: S.I. 2013/3021 art. 17(7)(d) (Jobseeker's Allowance) + href: https://www.legislation.gov.uk/uksi/2013/3021/article/17 + - title: S.I. 2013/3021 art. 26(6)(d) (Housing Benefit) + href: https://www.legislation.gov.uk/uksi/2013/3021/article/26 + - title: S.R. 2016/228 reg. 1 (commencement) + href: https://www.legislation.gov.uk/nisr/2016/228/regulation/1 + - title: S.R. 2016/228 reg. 11 (Income Support) + href: https://www.legislation.gov.uk/nisr/2016/228/regulation/11 + - title: S.R. 2016/228 reg. 14 (Jobseeker's Allowance) + href: https://www.legislation.gov.uk/nisr/2016/228/regulation/14 + - title: S.R. 2016/228 reg. 30(7)(d) (Housing Benefit) + href: https://www.legislation.gov.uk/nisr/2016/228/regulation/30 +values: + 2006-03-06: + - has_highest_dla_sc_award + 2013-12-24: + - has_highest_dla_sc_award + - armed_forces_independence_payment + 2016-06-20: + - has_highest_dla_sc_award + - has_enhanced_pip_dl_award + - armed_forces_independence_payment diff --git a/policyengine_uk/parameters/gov/dwp/disability_premia/top_rate_amount_tolerance.yaml b/policyengine_uk/parameters/gov/dwp/disability_premia/top_rate_amount_tolerance.yaml new file mode 100644 index 0000000000..9561f197f1 --- /dev/null +++ b/policyengine_uk/parameters/gov/dwp/disability_premia/top_rate_amount_tolerance.yaml @@ -0,0 +1,11 @@ +description: The model counts a DLA care or PIP daily living amount as a top-rate award for the enhanced disability premium when the amount reaches 52 × (top weekly rate − this weekly tolerance). policyengine-uk-data uses the same weekly tolerance when it derives award categories from reported amounts. +values: + 2015-01-01: 1 +metadata: + period: week + unit: currency-GBP + label: Enhanced disability premium top-rate amount tolerance + economy: false + reference: + - title: policyengine-uk-data, disability_benefits.py, CATEGORY_THRESHOLD_WEEKLY_TOLERANCE + href: https://github.com/PolicyEngine/policyengine-uk-data/blob/575ae3764cf0823ccf4c302fe7b640824cdb32c1/policyengine_uk_data/datasets/disability_benefits.py#L58 diff --git a/policyengine_uk/parameters/gov/local_authorities/merton/council_tax_reduction/enhanced_disability_premium/qualifying_benefits.yaml b/policyengine_uk/parameters/gov/local_authorities/merton/council_tax_reduction/enhanced_disability_premium/qualifying_benefits.yaml new file mode 100644 index 0000000000..c5b835d9eb --- /dev/null +++ b/policyengine_uk/parameters/gov/local_authorities/merton/council_tax_reduction/enhanced_disability_premium/qualifying_benefits.yaml @@ -0,0 +1,59 @@ +description: > + The London Borough of Merton counts the care component of disability living + allowance at the highest rate and the daily living component of personal + independence payment at either rate, for the applicant or a member of the + applicant's family, towards the enhanced disability premium in its + working-age Council Tax Support scheme. It omits armed forces independence + payment, and counts each award only for a person under the qualifying age + for State Pension Credit. The council sets this list in its scheme rules for + 2013-14, 2014-15, 2015-16, 2020-21, 2021-22, 2022-23, 2023-24, 2025-26 and + 2026-27, and links its 2023 rules as its 2024-25 scheme. In its Cabinet and + Council reports for 2017/18 to 2020/21 the council says it continued the + same scheme through 2019/20, so the model also applies the list from + 2016-17 to 2019-20, for which it cites no scheme text. The model reads the + list as at 30 April of each year. +metadata: + label: Merton Council Tax Support enhanced disability premium qualifying benefits + period: year + unit: list + reference: + - title: Council Tax Reduction Scheme L B Merton April 2013 (archived copy), Sch. 3 para. 12(1)(b), (c) + href: https://web.archive.org/web/20150530202253id_/http://www.merton.gov.uk/council_tax_reduction_scheme_l_b_merton_april_2013_with_uprated_amounts_final_310113-2.pdf + - title: Council Tax Reduction Scheme L B Merton April 2014 (archived copy), Sch. 3 para. 12(1)(b), (c) + href: https://web.archive.org/web/20150530203929id_/http://www.merton.gov.uk/council_tax_reduction_scheme_l_b_merton_april_2014_with_uprated_amounts_final_280114.pdf + - title: Council Tax Reduction Scheme L B Merton April 2015 (archived copy), Sch. 3 para. 12(1)(b), (c) + href: https://web.archive.org/web/20150530203354id_/http://www.merton.gov.uk/council_tax_reduction_scheme_l_b_merton_april_2015_with_uprated_amounts_final_280115.pdf + - title: Cabinet report on the Council Tax Support Scheme 2017/18 (archived copy; the Council continued the same scheme) + href: https://web.archive.org/web/20240912160841id_/https://democracy.merton.gov.uk/documents/s15005/Council%20Tax%20Support%20Scheme.pdf + - title: Cabinet report on the Council Tax Support Scheme 2018/19, 13 November 2017 (archived copy) + href: https://web.archive.org/web/20250420052844id_/https://democracy.merton.gov.uk/documents/s20013/Council%20Tax%20Support%20Scheme%20Cabinet%20Report%201819.pdf + - title: Council report on the Council Tax Support Scheme 2018/19, 22 November 2017 (archived copy) + href: https://web.archive.org/web/20250513135239id_/https://democracy.merton.gov.uk/documents/s20163/Council%20Tax%20Support%20Scheme%20Full%20Council%20Report%201819.pdf + - title: Cabinet report on the Council Tax Support Scheme 2019/20 (archived copy) + href: https://web.archive.org/web/20220325065644id_/https://democracy.merton.gov.uk/documents/s25279/Council%20Tax%20Support%20Scheme%20and%20Council%20Tax%20Technical%20Reforms%20201920%20full%20Council%20eport.pdf + - title: Council report on the Council Tax Support Scheme 2019/20, 21 November 2018 (archived copy) + href: https://web.archive.org/web/20200919054918id_/https://democracy.merton.gov.uk/documents/s25438/Council%20Tax%20Support%20Scheme%20and%20Council%20Tax%20Technical%20Reforms%20201920%20full%20Council%20report%202.pdf + - title: Cabinet report on the Council Tax Support Scheme 2020/21, 11 November 2019 (archived copy) + href: https://web.archive.org/web/20220208235004id_/https://democracy.merton.gov.uk/documents/s30060/Council%20Tax%20Support%20Scheme%20202021.pdf + - title: Council report on the Council Tax Support Scheme 2020/21, 5 February 2020 (archived copy) + href: https://web.archive.org/web/20200928082644id_/https://democracy.merton.gov.uk/documents/s30950/Council%20Tax%20Support%20Sceme%20202021.pdf + - title: Council Tax Reduction Scheme L B Merton 2020-21 (archived copy), Sch. 3 para. 12(1)(b), (c) + href: https://web.archive.org/web/20230207113512id_/https://www.merton.gov.uk/system/files?file=council20tax20reduction20scheme20l20b20merton20final20formatting20numbers202020-21.pdf + - title: Council Tax Reduction Scheme L B Merton 2021-22 (archived copy), Sch. 3 para. 12(1)(b), (c) + href: https://web.archive.org/web/20240911170941id_/https://www.merton.gov.uk/system/files?file=council20tax20reduction20scheme20l20b20merton202021-2220final.pdf + - title: Council Tax Reduction Scheme L B Merton 2022-2023 (archived copy), Sch. 3 para. 12(1)(b), (c) + href: https://web.archive.org/web/20230129084916id_/https://www.merton.gov.uk/system/files/Council%20Tax%20Reduction%20Scheme%20L%20B%20Merton%202022-2023.pdf + - title: Council Tax Reduction Scheme L B Merton 2022-2023 final (archived copy), Sch. 3 para. 12(1)(b), (c) + href: https://web.archive.org/web/20260117195021id_/https://www.merton.gov.uk/system/files/Council%20Tax%20Reduction%20Scheme%20L%20B%20Merton%202022-2023%20final.pdf + - title: Council Tax Reduction Scheme L B Merton 2023-24 (archived copy), Sch. 3 para. 12(1)(b), (c) + href: https://web.archive.org/web/20240718130610id_/https://www.merton.gov.uk/system/files/Council%20Tax%20Reduction%20Scheme%20L%20B%20Merton%202023-24.pdf + - title: The London Borough of Merton Local Council Tax Support Scheme Rules 2023, Sch. 3 para. 12(1)(b), (c) + href: https://www.merton.gov.uk/system/files/Council%20Tax%20Reduction%20Scheme%20L%20B%20Merton%202023-24_0.pdf + - title: The London Borough of Merton Local Council Tax Support Scheme Rules 2025, Sch. 3 para. 12(1)(b), (c) + href: https://www.merton.gov.uk/sites/default/files/2025-03/Council%20Tax%20Reduction%20Scheme%20L%20B%20Merton%202025-26.pdf + - title: The London Borough of Merton Local Council Tax Support Scheme Rules 2026, Sch. 3 para. 12(1)(b), (c) + href: https://www.merton.gov.uk/sites/default/files/2026-03/Council%20Tax%20Reduction%20Scheme%20L%20B%20Merton%202026-27.pdf +values: + 2013-04-01: + - has_highest_dla_sc_award + - pip_dl diff --git a/policyengine_uk/parameters/gov/local_authorities/newham/council_tax_reduction/enhanced_disability_premium/qualifying_benefits.yaml b/policyengine_uk/parameters/gov/local_authorities/newham/council_tax_reduction/enhanced_disability_premium/qualifying_benefits.yaml new file mode 100644 index 0000000000..52818af0fb --- /dev/null +++ b/policyengine_uk/parameters/gov/local_authorities/newham/council_tax_reduction/enhanced_disability_premium/qualifying_benefits.yaml @@ -0,0 +1,61 @@ +description: > + The London Borough of Newham counts the care component of disability living + allowance at the highest rate and the daily living component of personal + independence payment at either rate, for the applicant or a member of the + applicant's family, towards the enhanced disability premium in its + working-age Council Tax Reduction scheme, and from 1 April 2014 armed forces + independence payment. It counts each award only for a person under the + qualifying age for State Pension Credit. From its 2022 text the council + also counts the care component of child disability payment at the highest + rate, for which the model has no separate variable. The council sets these + lists in its texts for 2013, 2014, 2017, 2022, 2023 and 2026. For the years + between, the council says in its budget reports that the scheme will remain + unchanged (2015-16, 2016-17) or proposes no changes (2020-21, 2021-22), says + in its 2024-25 Council Tax booklet that it is keeping the scheme in place, + and changed other provisions in its 2019-20 and 2025-26 revisions; in its + texts on either side of each of those years, and of 2018-19, it counts the + same DLA care, PIP daily living and armed forces independence payment + awards. The model reads the list as at 30 April of each year. +metadata: + label: Newham Council Tax Reduction enhanced disability premium qualifying benefits + period: year + unit: list + reference: + - title: Council, 24 January 2013, minutes (adopting the local scheme in Appendix 1 from 1 April 2013) + href: https://mgov.newham.gov.uk/documents/g9739/Printed%20minutes%2024th-Jan-2013%2018.00%20Council.pdf?T=1 + - title: Council Tax Reduction Scheme 2013 (Appendix 1), Sch. 3 para. 12(1)(b), (c) + href: https://mgov.newham.gov.uk/documents/s74450/Appendix%201%20-%20LB%20Newham%20Local%20CTR%20Scheme_16_01_13.pdf + - title: Council, 9 December 2013, minutes (adopting the scheme in Appendix 2 from 1 April 2014) + href: https://mgov.newham.gov.uk/documents/g9807/Printed%20minutes%2009th-Dec-2013%2020.00%20Council.pdf?T=1 + - title: Council Tax Reduction Scheme 2014, Sch. 3 para. 12(1)(b), (c), (d) + href: https://mgov.newham.gov.uk/documents/s85542/LB%20Newham%20Local%20CTR%20Scheme_1415_12_11_13A.pdf + - title: Budget proposals report (Council, 23 February 2015), appendix 1, para. 7.12 (the 2015/16 scheme "will remain unchanged") + href: https://mgov.newham.gov.uk/documents/s94929/Mayors%20Budget%20Proposals%20Report%20-%20appendix%201.pdf + - title: Budget proposals report (Council, 22 February 2016), para. 7.15 (the 2016/17 scheme "will remain unchanged") + href: https://mgov.newham.gov.uk/documents/s102326/Mayors%20Budget%20Proposals%20Report%20PDF.pdf + - title: Council Tax Reduction Scheme 2017 (Appendix 1), Sch. 3 para. 12(1)(b), (c), (d) + href: https://mgov.newham.gov.uk/documents/s110300/Appendix%201%20LB%20Newham%20Local%20CTR%20Scheme%201718.pdf + - title: Council, 18 February 2019, minutes (a lower minimum contribution from 1 April 2019) + href: https://mgov.newham.gov.uk/documents/g12186/Printed%20minutes%2018th-Feb-2019%2019.00%20Council.pdf?T=1 + - title: Budget report 2020-21 (Council, 2 March 2020), para. 4.31 ("No changes to the council tax support scheme are proposed in 2020/21") + href: https://mgov.newham.gov.uk/documents/s135762/Budget%20Report%202020-21%20to%202022-23.pdf + - title: Budget report 2021-22 (Council, 1 March 2021), para. 5.19 (no changes proposed) + href: https://mgov.newham.gov.uk/documents/s143898/210219%20Budget%20report%202021-22%20-%202023%20FINAL.pdf + - title: Council, 28 February 2022, supplementary agenda (Council Tax Reduction Scheme 2022), Sch. 3 para. 12(1)(b), (c), (d) + href: https://mgov.newham.gov.uk/documents/b31136/Supplementary%20Agenda%20-%20Council%20Tax%20Reduction%20Scheme%2028th-Feb-2022%2019.00%20Council.pdf?T=9 + - title: Council Tax Reduction Scheme 2023, Sch. 3 para. 12(1)(b), (c), (d) + href: https://www.newham.gov.uk/downloads/file/5876/council-tax-reduction-scheme-2023 + - title: Council Tax booklet 2024-25, Mayor's message ("keeping firmly in place the 90% council tax reduction scheme") + href: https://www.newham.gov.uk/downloads/file/7105/council-tax-2024-25-budget-booklet + - title: Budget setting report 2025-26 (Council, 27 February 2025), para. 8.5 (changes to maximum support, taper, capital limit and non-dependant deductions) + href: https://mgov.newham.gov.uk/documents/s179147/Final%20Budget%20Setting%20Report%20Full%20Councilx.pdf + - title: Council Tax Reduction Scheme 2026, Sch. 3 para. 12(1)(n), (o), (p) + href: https://www.newham.gov.uk/downloads/file/10753/council-tax-reduction-scheme-2026 +values: + 2013-04-01: + - has_highest_dla_sc_award + - pip_dl + 2014-04-01: + - has_highest_dla_sc_award + - pip_dl + - armed_forces_independence_payment diff --git a/policyengine_uk/parameters/gov/local_authorities/scotland/council_tax_reduction/working_age/enhanced_disability_premium/age_limit_applies.yaml b/policyengine_uk/parameters/gov/local_authorities/scotland/council_tax_reduction/working_age/enhanced_disability_premium/age_limit_applies.yaml new file mode 100644 index 0000000000..ae81518926 --- /dev/null +++ b/policyengine_uk/parameters/gov/local_authorities/scotland/council_tax_reduction/working_age/enhanced_disability_premium/age_limit_applies.yaml @@ -0,0 +1,26 @@ +description: > + If this is true, Scottish councils include the enhanced disability premium + in a working-age Council Tax Reduction applicable amount only for an + applicant or partner under the qualifying age for State Pension Credit. The + Scottish Ministers set this limit in the 2012 scheme, which ran until 31 + March 2022. In the 2021 scheme they set the limit at pensionable age, which + the model reads as the same qualifying age (the two have agreed for everyone + since 2019-20), and from 20 June 2022 they removed it (S.S.I. 2022/161). The + model reads this as at 30 April of each year from 2015, so it applies the + limit in 2022 and not from 2023. +metadata: + label: Scottish working-age Council Tax Reduction enhanced disability premium age limit applies + period: year + unit: bool + reference: + - title: The Council Tax Reduction (Scotland) Regulations 2012 Sch. 1 para. 12(1)(b), (ba), (c) (to 31 March 2022) + href: https://www.legislation.gov.uk/ssi/2012/303/schedule/1/paragraph/12/2021-04-01 + - title: The Council Tax Reduction (Scotland) Regulations 2021 Sch. 1 para. 14(1) as in force on 1 April 2022 + href: https://www.legislation.gov.uk/ssi/2021/249/schedule/1/paragraph/14/2022-04-01 + - title: The Council Tax Reduction (Scotland) Amendment (No. 3) Regulations 2022 reg. 1 (in force 20 June 2022) + href: https://www.legislation.gov.uk/ssi/2022/161/regulation/1 + - title: The Council Tax Reduction (Scotland) Regulations 2021 Sch. 1 para. 14(1) + href: https://www.legislation.gov.uk/ssi/2021/249/schedule/1/paragraph/14 +values: + 2013-04-01: true + 2022-06-20: false diff --git a/policyengine_uk/parameters/gov/local_authorities/scotland/council_tax_reduction/working_age/enhanced_disability_premium/qualifying_benefits.yaml b/policyengine_uk/parameters/gov/local_authorities/scotland/council_tax_reduction/working_age/enhanced_disability_premium/qualifying_benefits.yaml new file mode 100644 index 0000000000..f1ed21c9ef --- /dev/null +++ b/policyengine_uk/parameters/gov/local_authorities/scotland/council_tax_reduction/working_age/enhanced_disability_premium/qualifying_benefits.yaml @@ -0,0 +1,36 @@ +description: > + Scottish councils count the care component of disability living allowance at + the highest rate, the daily living component of personal independence + payment at the enhanced rate, armed forces independence payment and, from 1 + April 2023, attendance allowance at either rate (S.S.I. 2023/38), for the + applicant or partner, toward the enhanced disability premium in working-age + Council Tax Reduction. Scottish councils also count Scottish benefits (child + disability payment, adult disability payment, pension age disability payment + and Scottish adult disability living allowance), for which the model has no + separate variables. Applicants and family members qualify through armed + forces independence payment from 11 June 2013 under S.S.I. 2013/142. The + model reads the list as at 30 April of each year from 2015. +metadata: + label: Scottish working-age Council Tax Reduction enhanced disability premium qualifying benefits + period: year + unit: list + reference: + - title: The Council Tax Reduction (Scotland) Regulations 2012 Sch. 1 para. 12(1) (to 31 March 2022) + href: https://www.legislation.gov.uk/ssi/2012/303/schedule/1/paragraph/12/2021-04-01 + - title: The Council Tax Reduction (Scotland) Regulations 2021 Sch. 1 para. 14(1) + href: https://www.legislation.gov.uk/ssi/2021/249/schedule/1/paragraph/14 + - title: The Council Tax Reduction and Council Tax (Discounts) (Miscellaneous Amendment) (Scotland) Regulations 2023 reg. 16(c) + href: https://www.legislation.gov.uk/ssi/2023/38/regulation/16 +values: + 2013-04-01: + - has_highest_dla_sc_award + - has_enhanced_pip_dl_award + 2013-06-11: + - has_highest_dla_sc_award + - has_enhanced_pip_dl_award + - armed_forces_independence_payment + 2023-04-01: + - has_highest_dla_sc_award + - has_enhanced_pip_dl_award + - armed_forces_independence_payment + - attendance_allowance diff --git a/policyengine_uk/parameters/gov/local_authorities/westminster/council_tax_reduction/enhanced_disability_premium/qualifying_benefits.yaml b/policyengine_uk/parameters/gov/local_authorities/westminster/council_tax_reduction/enhanced_disability_premium/qualifying_benefits.yaml new file mode 100644 index 0000000000..f9379c3faf --- /dev/null +++ b/policyengine_uk/parameters/gov/local_authorities/westminster/council_tax_reduction/enhanced_disability_premium/qualifying_benefits.yaml @@ -0,0 +1,36 @@ +description: > + The model counts the care component of disability living allowance at the + highest rate and the daily living component of personal independence + payment at either rate, for the applicant or a member of the applicant's + family, towards the enhanced disability premium in Westminster City + Council's working-age Council Tax Support scheme. It omits armed forces + independence payment, and counts each award only for a person under the + qualifying age for State Pension Credit. This is the Default Scheme's list + (S.I. 2012/2886 Sch 3 para 12). The council has approved the same scheme, + based on the Default Scheme Regulations, since 2013/14, and its Cabinet + says from December 2020 that the council's local scheme mirrors those + Regulations. The model cites no full Westminster scheme text. + The model reads the list as at 30 April of each year. +metadata: + label: Westminster Council Tax Support enhanced disability premium qualifying benefits + period: year + unit: list + reference: + - title: Report of the Cabinet, 10 December 2018, Council Tax (archived copy; the same scheme for 2019/20, based on the Default Scheme Regulations) + href: https://web.archive.org/web/20220927103652id_/https://committees.westminster.gov.uk/documents/s30518/Report%20of%20the%20Cabinet%20on%2010%20Dec%202018%20-%20Council%20Tax.pdf + - title: Statement of decision, Council Tax Discounts including Council Tax Local Reduction Scheme, 2020/21 (archived copy) + href: https://web.archive.org/web/20250501010325id_/https://committees.westminster.gov.uk/documents/d1138/Printed%20decision%20Council%20Tax%20Discounts%20including%20Council%20Tax%20Local%20Reduction%20Scheme%20and%20Council%20T.pdf?T=5 + - title: Report of the Cabinet, 14 December 2020, Council Tax Discounts (archived copy; the Default Scheme Regulations "are mirrored within the City Council's local scheme") + href: https://web.archive.org/web/20240621074656id_/https://committees.westminster.gov.uk/documents/s40219/Report%20of%20the%20Cabinet%2014%20December%202020%20-Council%20Tax%20Discounts.pdf + - title: Cabinet report, 13 December 2021, Council Tax Taxbase and Discounts (archived copy) + href: https://web.archive.org/web/20211205134208id_/https://committees.westminster.gov.uk/documents/s45385/Cabinet%20Report%20-%20Council%20Tax%20Taxbase%20and%20Discounts%20Report.pdf + - title: Cabinet report, 12 December 2022, Council Tax Discounts (archived copy) + href: https://web.archive.org/web/20230106164259id_/https://committees.westminster.gov.uk/documents/s50264/Council%20Tax%20Discounts.pdf + - title: Cabinet report, 11 December 2023, Council Tax Discounts including Council Tax Local Reduction Scheme (archived copy) + href: https://web.archive.org/web/20250207010503id_/https://committees.westminster.gov.uk/documents/s57091/Council%20Tax%20Discounts%20including%20Council%20Tax%20Local%20Reduction%20Scheme%20and%20Council%20Tax%20Base%20report.pdf + - title: The Council Tax Reduction Schemes (Default Scheme) (England) Regulations 2012 Sch. 3 para. 12 (as made) + href: https://www.legislation.gov.uk/uksi/2012/2886/appendix/3/regulation/12/made +values: + 2013-04-01: + - has_highest_dla_sc_award + - pip_dl diff --git a/policyengine_uk/tests/policy/baseline/gov/dwp/enhanced_disability_premium.yaml b/policyengine_uk/tests/policy/baseline/gov/dwp/enhanced_disability_premium.yaml new file mode 100644 index 0000000000..7535951f7a --- /dev/null +++ b/policyengine_uk/tests/policy/baseline/gov/dwp/enhanced_disability_premium.yaml @@ -0,0 +1,557 @@ +# Legacy enhanced disability premium for a claimant or partner. +# Conditions: HB Regs 2006 Sch 3 para 15(1)(b)-(d); IS Regs 1987 Sch 2 para +# 13A(1), (1ZA); ESA Regs 2008 Sch 4 para 7(1)(b)-(d); JSA Regs 1996 Sch 1 +# para 15A(1), (1ZA); HB Regs (NI) 2006 Sch 4 para 15(1)(aa)-(c). +# Amounts (HB Regs 2006 Sch 3 Part 4, enhanced disability premium row (9), +# 2026-27): £22.00 for a person who is not a member of a couple, £31.40 where +# a member of a couple meets the condition. +# 2026-27 weekly rates: DLA care highest £114.60, middle £76.70; PIP daily +# living enhanced £114.60, standard £76.70 (gov.dwp parameters). +# The model counts an award only with a positive amount, and counts an amount +# entered without its category at the top rate when it reaches +# 52 × (top weekly rate − £1): (114.60 - 1) * 52 = 5,907.20 in 2026-27. + +- name: Case 1, enhanced PIP daily living qualifies a single claimant. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + pip_dl_category: ENHANCED + households: + household: + members: [person1] + country: ENGLAND + output: + # 114.60 * 52 = 5,959.20 (HB para 15(1)(c); IS para 13A(1ZA)(c)). + pip_dl: 5_959.20 + receives_enhanced_disability_premium_qualifying_benefit: true + num_enhanced_disabled_claimants_or_partners_for_legacy_benefits: 1 + # 22.00 * 52 = 1,144.00. + enhanced_disability_premium: 1_144 + +- name: Case 2, the highest DLA care rate qualifies a single claimant. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + dla_sc_category: HIGHER + households: + household: + members: [person1] + country: ENGLAND + output: + # 114.60 * 52 = 5,959.20 (HB para 15(1)(b); IS para 13A(1ZA)(b)). + dla_sc: 5_959.20 + receives_enhanced_disability_premium_qualifying_benefit: true + enhanced_disability_premium: 1_144 + +- name: Case 3, standard PIP daily living does not qualify. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + pip_dl_category: STANDARD + households: + household: + members: [person1] + country: ENGLAND + output: + # 76.70 * 52 = 3,988.40; claimants qualify under para 15(1)(c) only at + # the enhanced rate. + pip_dl: 3_988.40 + receives_enhanced_disability_premium_qualifying_benefit: false + enhanced_disability_premium: 0 + +- name: Case 4, the middle DLA care rate does not qualify. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + dla_sc_category: MIDDLE + households: + household: + members: [person1] + country: ENGLAND + output: + # 76.70 * 52 = 3,988.40; claimants qualify under para 15(1)(b) only at + # the highest rate. + dla_sc: 3_988.40 + receives_enhanced_disability_premium_qualifying_benefit: false + enhanced_disability_premium: 0 + +- name: Case 5, armed forces independence payment qualifies a single claimant. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + armed_forces_independence_payment: 2_000 + households: + household: + members: [person1] + country: ENGLAND + output: + # HB para 15(1)(d); IS para 13A(1ZA)(a): any payment of AFIP. + receives_enhanced_disability_premium_qualifying_benefit: true + enhanced_disability_premium: 1_144 + +- name: Case 6, attendance allowance at the higher rate does not qualify. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + aa_category: HIGHER + households: + household: + members: [person1] + country: ENGLAND + output: + # Claimants do not qualify through attendance allowance under HB para + # 15(1), IS para 13A(1ZA), ESA para 7(1) or JSA para 15A(1ZA). + receives_enhanced_disability_premium_qualifying_benefit: false + enhanced_disability_premium: 0 + +- name: Case 7, a single claimant over the State Pension Credit qualifying age gets no premium. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + dla_sc_category: HIGHER + households: + household: + members: [person1] + country: ENGLAND + output: + has_attained_state_pension_credit_qualifying_age: true + receives_enhanced_disability_premium_qualifying_benefit: true + # HB para 15(1)(b): "who has not attained the qualifying age for state + # pension credit". + num_enhanced_disabled_claimants_or_partners_for_legacy_benefits: 0 + enhanced_disability_premium: 0 + +- name: Case 8, a couple where one member qualifies gets the couple rate. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + pip_dl_category: ENHANCED + person2: + age: 31 + benunits: + benunit: + members: [person1, person2] + households: + household: + members: [person1, person2] + country: ENGLAND + output: + receives_enhanced_disability_premium_qualifying_benefit: [true, false] + num_enhanced_disabled_claimants_or_partners_for_legacy_benefits: 1 + # 31.40 * 52 = 1,632.80. + enhanced_disability_premium: 1_632.80 + +- name: Case 9, a couple where both members qualify still gets one couple rate. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + pip_dl_category: ENHANCED + person2: + age: 31 + dla_sc_category: HIGHER + benunits: + benunit: + members: [person1, person2] + households: + household: + members: [person1, person2] + country: ENGLAND + output: + num_enhanced_disabled_claimants_or_partners_for_legacy_benefits: 2 + # Housing Benefit pays £31.40 under row (9)(c) "where the claimant is a + # member of a couple and the conditions ... are satisfied in respect of a + # member of that couple": 31.40 * 52 = 1,632.80, not two single rates + # (2 * 1,144.00). + enhanced_disability_premium: 1_632.80 + +- name: Case 10, a couple whose only qualifying member is over the qualifying age gets no premium. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 60 + person2: + age: 70 + dla_sc_category: HIGHER + benunits: + benunit: + members: [person1, person2] + households: + household: + members: [person1, person2] + country: ENGLAND + output: + is_couple: true + has_attained_state_pension_credit_qualifying_age: [false, true] + # IS para 13A(1)(b): "the claimant's partner, if any, who has not + # attained the qualifying age for state pension credit". + num_enhanced_disabled_claimants_or_partners_for_legacy_benefits: 0 + enhanced_disability_premium: 0 + +- name: Case 11, a couple with a qualifying member under the qualifying age gets the couple rate. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 60 + pip_dl_category: ENHANCED + person2: + age: 70 + dla_sc_category: HIGHER + benunits: + benunit: + members: [person1, person2] + households: + household: + members: [person1, person2] + country: ENGLAND + output: + is_couple: true + num_enhanced_disabled_claimants_or_partners_for_legacy_benefits: 1 + enhanced_disability_premium: 1_632.80 + +- name: Case 12, Northern Ireland reads enhanced PIP daily living from 2017. + period: 2016 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + pip_dl_category: ENHANCED + households: + household: + members: [person1] + country: NORTHERN_IRELAND + output: + # Claimants in Northern Ireland qualify through PIP from 20 June 2016 + # under S.R. 2016/228; the model reads the list at 30 April, so it counts + # no PIP in Northern Ireland in 2016. + receives_enhanced_disability_premium_qualifying_benefit: false + enhanced_disability_premium: 0 + +- name: Case 13, enhanced PIP daily living qualifies in Northern Ireland in 2017. + period: 2017 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + pip_dl_category: ENHANCED + households: + household: + members: [person1] + country: NORTHERN_IRELAND + output: + receives_enhanced_disability_premium_qualifying_benefit: true + # 2017-18 single rate £15.90: 15.90 * 52 = 826.80. + enhanced_disability_premium: 826.80 + +- name: Case 14, Northern Ireland already counts armed forces independence payment in 2016. + period: 2016 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + armed_forces_independence_payment: 2_000 + households: + household: + members: [person1] + country: NORTHERN_IRELAND + output: + # Claimants in Northern Ireland qualify through AFIP from 24 December 2013 + # under S.I. 2013/3021. 2016-17 single rate £15.75: 15.75 * 52 = 819.00. + receives_enhanced_disability_premium_qualifying_benefit: true + enhanced_disability_premium: 819 + +- name: Case 15, Great Britain counts enhanced PIP daily living in 2016. + period: 2016 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + pip_dl_category: ENHANCED + households: + household: + members: [person1] + country: WALES + output: + # Claimants in Great Britain qualify through PIP from 8 April 2013 under + # S.I. 2013/388. + receives_enhanced_disability_premium_qualifying_benefit: true + enhanced_disability_premium: 819 + +- name: Case 16, Housing Benefit premiums include the premium for enhanced PIP daily living. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + pip_dl_category: ENHANCED + households: + household: + members: [person1] + country: ENGLAND + output: + housing_benefit_pension_age_regulations_apply: false + enhanced_disability_premium: 1_144 + # The severe disability premium list + # (gov.dwp.disability_premia.severe_qualifying_benefits) also includes + # enhanced PIP daily living; the claimant lives alone and nobody receives + # a carer benefit for caring for them: 86.05 * 52 = 4,474.60. + severe_disability_premium: 4_474.60 + # 1,144.00 + 4,474.60 = 5,618.60. + benefits_premiums: 5_618.60 + +- name: Case 17, Housing Benefit for an over-age partner in the working-age regulations has no premium. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 60 + person2: + age: 70 + dla_sc_category: HIGHER + benunits: + benunit: + members: [person1, person2] + jsa_income: 3_000 + households: + household: + members: [person1, person2] + country: ENGLAND + output: + is_couple: true + # Because the couple receives income-based Jobseeker's Allowance, the + # model applies the working-age regulations + # (housing_benefit_pension_age_regulations_apply), under whose para + # 15(1)(b) a family member who has attained the qualifying age does not + # qualify. + housing_benefit_pension_age_regulations_apply: false + enhanced_disability_premium: 0 + # Only one partner receives a severe disability premium qualifying + # benefit and the other is not blind, so the model pays no severe + # disability premium either (severe_disability_premium). + benefits_premiums: 0 + +- name: Case 18, the Income Support applicable amount includes the premium for enhanced PIP daily living. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + pip_dl_category: ENHANCED + households: + household: + members: [person1] + country: ENGLAND + output: + # Personal allowance for a single claimant aged 25 or over, £95.55 + # (2026-27 DWP rates): 95.55 * 52 = 4,968.60. Premiums 1,144.00 + + # 4,474.60 = 5,618.60. Total 10,587.20. + income_support_applicable_amount: 10_587.20 + +- name: Case 19, a DLA care amount at the highest rate without its category qualifies. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + dla_sc: 5_959.20 + households: + household: + members: [person1] + country: ENGLAND + output: + receives_highest_dla_sc: false + # 5,959.20 reaches 5,907.20. + has_highest_dla_sc_award: true + receives_enhanced_disability_premium_qualifying_benefit: true + enhanced_disability_premium: 1_144 + +- name: Case 20, a PIP daily living amount at the enhanced rate without its category qualifies. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + pip_dl: 5_959.20 + households: + household: + members: [person1] + country: ENGLAND + output: + receives_enhanced_pip_dl: false + has_enhanced_pip_dl_award: true + enhanced_disability_premium: 1_144 + +- name: Case 21, an amount within £1 a week of the highest DLA care rate qualifies. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + # £113.65 a week: 113.65 * 52 = 5,909.80, above 5,907.20. + dla_sc: 5_909.80 + households: + household: + members: [person1] + country: ENGLAND + output: + has_highest_dla_sc_award: true + enhanced_disability_premium: 1_144 + +- name: Case 22, an amount more than £1 a week below the highest DLA care rate does not qualify. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + # £113.50 a week: 113.50 * 52 = 5,902.00, below 5,907.20. + dla_sc: 5_902 + households: + household: + members: [person1] + country: ENGLAND + output: + has_highest_dla_sc_award: false + enhanced_disability_premium: 0 + +- name: Case 23, the highest DLA care category with an amount of zero is no award. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + dla_sc_category: HIGHER + dla_sc: 0 + households: + household: + members: [person1] + country: ENGLAND + output: + receives_highest_dla_sc: true + has_highest_dla_sc_award: false + receives_enhanced_disability_premium_qualifying_benefit: false + enhanced_disability_premium: 0 + +- name: Case 24, the enhanced PIP daily living category with an amount of zero is no award. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + pip_dl_category: ENHANCED + pip_dl: 0 + households: + household: + members: [person1] + country: ENGLAND + output: + has_enhanced_pip_dl_award: false + enhanced_disability_premium: 0 + +- name: Case 25, the highest DLA care category qualifies with an amount below the rate. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + dla_sc_category: HIGHER + dla_sc: 1_000 + households: + household: + members: [person1] + country: ENGLAND + output: + # The model takes the rate from the category and the award from the + # positive amount. + has_highest_dla_sc_award: true + enhanced_disability_premium: 1_144 + +- name: Case 26, a child with the highest DLA care category and an amount of zero gets no child premium. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + parent: + age: 35 + child: + age: 10 + dla_sc_category: HIGHER + dla_sc: 0 + benunits: + benunit: + members: [parent, child] + households: + household: + members: [parent, child] + country: ENGLAND + output: + receives_enhanced_disability_premium_qualifying_benefit: [false, false] + # With no DLA amount, the model pays neither the disabled-child nor the + # enhanced rate. + housing_benefit_child_disability_premiums: 0 + +- name: Case 27, a child with a highest-rate DLA care amount and no category gets both child premiums. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + parent: + age: 35 + child: + age: 10 + dla_sc: 5_959.20 + benunits: + benunit: + members: [parent, child] + households: + household: + members: [parent, child] + country: ENGLAND + output: + receives_enhanced_disability_premium_qualifying_benefit: [false, true] + # HB Sch 3 Part 4: disabled child £84.46 plus enhanced child £33.99, + # 118.45 * 52 = 6,159.40. + housing_benefit_child_disability_premiums: 6_159.40 diff --git a/policyengine_uk/tests/policy/baseline/gov/local_authorities/council_tax_reduction/applicant_or_partner.yaml b/policyengine_uk/tests/policy/baseline/gov/local_authorities/council_tax_reduction/applicant_or_partner.yaml index 42ee19cbed..3073fabe9e 100644 --- a/policyengine_uk/tests/policy/baseline/gov/local_authorities/council_tax_reduction/applicant_or_partner.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/local_authorities/council_tax_reduction/applicant_or_partner.yaml @@ -222,12 +222,15 @@ savings: 0 output: # Disability (44.85) and severe disability (86.05) premiums at the single - # rate: (44.85 + 86.05) * 52. The young mother's disability does not give - # the grandmother a premium, and at 17 neither parent is a non-dependant - # who bars the severe disability premium. - council_tax_reduction_premiums: [6_806.80] + # rate, and the enhanced disability premium (22.00), which Scottish + # councils pay for attendance allowance from 1 April 2023 (SSI 2021/249 + # Sch 1 para 14(1)(g)): (44.85 + 86.05 + 22.00) * 52. The young + # mother's disability does not give the grandmother a premium, and at 17 + # neither parent counts as a non-dependant who bars the severe disability + # premium. + council_tax_reduction_premiums: [7_950.80] # Single aged 25 or over, 95.55 * 52 = 4,968.60, plus the premiums. - council_tax_reduction_applicable_amount: [11_775.40] + council_tax_reduction_applicable_amount: [12_919.40] - name: Adult parents in a lone-applying head's benefit unit are her non-dependants and bar her severe disability premium period: 2026 @@ -268,9 +271,11 @@ # At 19 the parents are residents aged 18 or over outside her family, so # the severe disability premium is not payable (HB Regs 2006 Sch 3 para # 14(2)(a)(ii), which the model applies to Council Tax Reduction too). - # Only the disability premium remains: 44.85 * 52. - council_tax_reduction_premiums: [2_332.20] - council_tax_reduction_applicable_amount: [7_300.80] + # The disability premium and the enhanced disability premium for her + # attendance allowance (SSI 2021/249 Sch 1 para 14(1)(g)) remain: + # (44.85 + 22.00) * 52. + council_tax_reduction_premiums: [3_476.20] + council_tax_reduction_applicable_amount: [8_444.80] - name: A blind grandmother head who applies alone has no non-dependant deduction in Merton period: 2026 diff --git a/policyengine_uk/tests/policy/baseline/gov/local_authorities/council_tax_reduction/enhanced_disability_premium.yaml b/policyengine_uk/tests/policy/baseline/gov/local_authorities/council_tax_reduction/enhanced_disability_premium.yaml new file mode 100644 index 0000000000..2a62a3664c --- /dev/null +++ b/policyengine_uk/tests/policy/baseline/gov/local_authorities/council_tax_reduction/enhanced_disability_premium.yaml @@ -0,0 +1,1022 @@ +# Enhanced disability premium in working-age Council Tax Reduction. +# Welsh councils count DLA care highest, PIP daily living enhanced or AFIP, +# for an applicant or family member "who has not attained the qualifying age +# for state pension credit" (CTR (Prescribed Requirements) (Wales) Regs 2013 +# Sch 7 para 12(1)). Scottish councils count the same benefits for the +# applicant or partner (CTR (Scotland) Regs 2021 Sch 1 para 14(1)), with no +# age limit from 20 June 2022 (S.S.I. 2022/161), and attendance allowance at +# either rate from 1 April 2023 (para 14(1)(g), S.S.I. 2023/38). Merton counts +# DLA care highest and PIP daily living at either rate and omits AFIP (Merton's +# Local Council Tax Support Scheme Rules 2026, Sch 3 para 12(1)). Newham counts +# DLA care highest, PIP daily living at either rate and AFIP (Newham's Council +# Tax Reduction Scheme 2026, Sch 3 para 12(1)). In Westminster the model applies +# the Default Scheme's list (S.I. 2012/2886 Sch 3 para 12(1)): DLA care highest +# and PIP daily living at either rate, without AFIP. Those three councils keep +# the qualifying age for State Pension Credit as the age limit, and their lists +# apply in every model year. In Kingston upon Thames the model reads +# is_enhanced_disabled_for_benefits, with no age limit (issue #2881): the value +# a case supplies, or else the flag's formula, which counts DLA care of at +# least 52 times the highest weekly rate. The model reads each year's rules at +# 30 April. +# Unless a case sets `is_disabled_for_benefits`, it keeps its default, false, +# and the model pays no disability premium, although the schemes give one to +# a claimant under the qualifying age who receives these awards (for example +# HB Regs 2006 Sch 3 paras 12(a) and 13(1)(a)(i); Merton's rules Sch 3 paras +# 9(a) and 10(1)(a)(i)). In those cases the totals from +# `council_tax_reduction_premiums` down follow that default, not the schemes. +# 2026-27 amounts: enhanced disability premium £22.00 single, £31.40 couple; +# severe disability premium £86.05 single. + +- name: Case 1, Welsh working-age CTR premiums include the premium for enhanced PIP daily living. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + pip_dl_category: ENHANCED + households: + household: + members: [person1] + country: WALES + local_authority: CARDIFF + output: + council_tax_reduction_pensioner: false + # 22.00 * 52 = 1,144.00. + council_tax_reduction_enhanced_disability_premium: 1_144 + # Plus the severe disability premium, 86.05 * 52 = 4,474.60: 5,618.60. + council_tax_reduction_premiums: 5_618.60 + +- name: Case 2, Scottish working-age CTR counts attendance allowance at either rate from 2023. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + aa_category: LOWER + households: + household: + members: [person1] + country: SCOTLAND + local_authority: CITY_OF_EDINBURGH + output: + council_tax_reduction_pensioner: false + # The model's legacy premium does not count attendance allowance. + enhanced_disability_premium: 0 + # Para 14(1)(g): 22.00 * 52 = 1,144.00. + meets_council_tax_reduction_enhanced_disability_premium_condition: true + council_tax_reduction_enhanced_disability_premium: 1_144 + # Severe disability premium 4,474.60 + 1,144.00 = 5,618.60. + council_tax_reduction_premiums: 5_618.60 + +- name: Case 3, Scottish working-age CTR does not count attendance allowance in 2022. + period: 2022 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + aa_category: LOWER + households: + household: + members: [person1] + country: SCOTLAND + local_authority: CITY_OF_EDINBURGH + output: + meets_council_tax_reduction_enhanced_disability_premium_condition: false + council_tax_reduction_enhanced_disability_premium: 0 + # The model pays only the severe disability premium, at the 2022-23 + # single rate £69.40: 69.40 * 52 = 3,608.80. + council_tax_reduction_premiums: 3_608.80 + +- name: Case 4, Scottish working-age CTR pays the couple rate for an over-age partner from 2023. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 60 + person2: + age: 70 + dla_sc_category: HIGHER + benunits: + benunit: + members: [person1, person2] + jsa_income: 3_000 + households: + household: + members: [person1, person2] + country: SCOTLAND + local_authority: CITY_OF_EDINBURGH + output: + is_couple: true + # Because the couple receives income-based Jobseeker's Allowance, the + # model applies the working-age scheme. + council_tax_reduction_pensioner: false + # The model's legacy premium applies the age limit. + enhanced_disability_premium: 0 + # Scottish councils apply no age limit under para 14(1)(b): 31.40 * 52 = + # 1,632.80. + council_tax_reduction_enhanced_disability_premium: 1_632.80 + # The model pays no other premium, because only one partner has a severe + # disability premium qualifying benefit. + council_tax_reduction_premiums: 1_632.80 + +- name: Case 5, Scottish working-age CTR applied the age limit in 2022. + period: 2022 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 60 + person2: + age: 70 + dla_sc_category: HIGHER + benunits: + benunit: + members: [person1, person2] + jsa_income: 3_000 + households: + household: + members: [person1, person2] + country: SCOTLAND + local_authority: CITY_OF_EDINBURGH + output: + is_couple: true + council_tax_reduction_pensioner: false + # Para 14(1)(b) as in force on 30 April 2022: "the applicant's partner, + # who has not attained pensionable age". + council_tax_reduction_enhanced_disability_premium: 0 + council_tax_reduction_premiums: 0 + +- name: Case 6, Welsh working-age CTR keeps the age limit for an over-age partner. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 60 + person2: + age: 70 + dla_sc_category: HIGHER + benunits: + benunit: + members: [person1, person2] + jsa_income: 3_000 + households: + household: + members: [person1, person2] + country: WALES + local_authority: CARDIFF + output: + is_couple: true + council_tax_reduction_pensioner: false + # Sch 7 para 12(1)(b): "who has not attained the qualifying age for state + # pension credit". + council_tax_reduction_enhanced_disability_premium: 0 + council_tax_reduction_premiums: 0 + +- name: Case 7, a household head who applies alone gets the premium for enhanced PIP daily living. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 50 + is_household_head: true + pip_dl_category: ENHANCED + person2: + age: 17 + is_parent: true + is_household_head: false + person3: + age: 17 + is_parent: true + is_household_head: false + person4: + age: 0 + is_household_head: false + benunits: + benunit: + members: [person1, person2, person3, person4] + claims_all_entitled_benefits: true + would_claim_uc: false + households: + household: + members: [person1, person2, person3, person4] + country: WALES + local_authority: CARDIFF + council_tax: 1_800 + savings: 0 + output: + council_tax_reduction_head_applies_alone: true + council_tax_reduction_pensioner: false + meets_council_tax_reduction_enhanced_disability_premium_condition: [true, false, false, false] + # The head's own single-rate premium 1,144.00, plus the severe disability + # premium 4,474.60 (the other residents are under 18): 5,618.60. + council_tax_reduction_premiums: 5_618.60 + +- name: Case 8, a Scottish household head who applies alone and receives attendance allowance gets the premium. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 50 + is_household_head: true + aa_category: LOWER + person2: + age: 17 + is_parent: true + is_household_head: false + person3: + age: 17 + is_parent: true + is_household_head: false + person4: + age: 0 + is_household_head: false + benunits: + benunit: + members: [person1, person2, person3, person4] + claims_all_entitled_benefits: true + would_claim_uc: false + households: + household: + members: [person1, person2, person3, person4] + country: SCOTLAND + local_authority: CITY_OF_EDINBURGH + council_tax: 1_800 + savings: 0 + output: + council_tax_reduction_head_applies_alone: true + council_tax_reduction_pensioner: false + # Para 14(1)(g) 1,144.00 plus the severe disability premium 4,474.60: + # 5,618.60. + council_tax_reduction_premiums: 5_618.60 + +- name: Case 9, AFIP adds no enhanced disability premium to a Merton reduction. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + armed_forces_independence_payment: 2_000 + private_pension_income: 12_000 + benunits: + benunit: + members: [person1] + would_claim_uc: false + would_claim_IS: false + would_claim_pc: false + claims_all_entitled_benefits: true + households: + household: + members: [person1] + country: ENGLAND + local_authority: MERTON + council_tax: 1_800 + savings: 0 + output: + # The model's legacy premium still counts AFIP for Housing Benefit and + # Income Support (HB para 15(1)(d)). + enhanced_disability_premium: 1_144 + # Merton omits AFIP from Sch 3 para 12(1). + meets_council_tax_reduction_enhanced_disability_premium_condition: false + council_tax_reduction_enhanced_disability_premium: 0 + # AFIP counts toward the severe disability premium: 86.05 * 52 = + # 4,474.60. + council_tax_reduction_premiums: 4_474.60 + # Personal allowance 95.55 * 52 = 4,968.60, plus 4,474.60: 9,443.20. + council_tax_reduction_applicable_amount: 9_443.20 + # 1,800 - 20% of (12,000 - 9,443.20) = 1,800 - 511.36 = 1,288.64. + simulated_council_tax_reduction_benunit: 1_288.64 + +- name: Case 10, AFIP meets Newham's condition but not Merton's or Westminster's. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + merton: + age: 30 + armed_forces_independence_payment: 2_000 + newham: + age: 30 + armed_forces_independence_payment: 2_000 + westminster: + age: 30 + armed_forces_independence_payment: 2_000 + benunits: + merton: + members: [merton] + newham: + members: [newham] + westminster: + members: [westminster] + households: + merton: + members: [merton] + country: ENGLAND + local_authority: MERTON + newham: + members: [newham] + country: ENGLAND + local_authority: NEWHAM + westminster: + members: [westminster] + country: ENGLAND + local_authority: WESTMINSTER + output: + meets_council_tax_reduction_enhanced_disability_premium_condition: [false, true, false] + # 22.00 * 52 = 1,144.00. + council_tax_reduction_enhanced_disability_premium: [0, 1_144, 0] + enhanced_disability_premium: [1_144, 1_144, 1_144] + +- name: Case 11, standard PIP daily living meets the Merton, Newham and Westminster conditions. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + merton: + age: 30 + pip_dl_category: STANDARD + newham: + age: 30 + pip_dl_category: STANDARD + westminster: + age: 30 + pip_dl_category: STANDARD + benunits: + merton: + members: [merton] + newham: + members: [newham] + westminster: + members: [westminster] + households: + merton: + members: [merton] + country: ENGLAND + local_authority: MERTON + newham: + members: [newham] + country: ENGLAND + local_authority: NEWHAM + westminster: + members: [westminster] + country: ENGLAND + local_authority: WESTMINSTER + output: + meets_council_tax_reduction_enhanced_disability_premium_condition: [true, true, true] + council_tax_reduction_enhanced_disability_premium: [1_144, 1_144, 1_144] + # Under HB para 15(1)(c), claimants qualify only at the enhanced rate. + enhanced_disability_premium: [0, 0, 0] + +- name: Case 12, the Merton and Newham schemes keep the age limit for an over-age partner. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + merton1: + age: 60 + merton2: + age: 70 + pip_dl_category: STANDARD + newham1: + age: 60 + newham2: + age: 70 + armed_forces_independence_payment: 2_000 + benunits: + merton: + members: [merton1, merton2] + jsa_income: 3_000 + newham: + members: [newham1, newham2] + jsa_income: 3_000 + households: + merton: + members: [merton1, merton2] + country: ENGLAND + local_authority: MERTON + newham: + members: [newham1, newham2] + country: ENGLAND + local_authority: NEWHAM + output: + is_couple: [true, true] + # Because each couple receives income-based Jobseeker's Allowance, the + # model applies the working-age scheme. + council_tax_reduction_pensioner: [false, false] + # Para 12(1)(c) and (p): "who has not attained the qualifying age for + # state pension credit". + meets_council_tax_reduction_enhanced_disability_premium_condition: [false, false, false, false] + council_tax_reduction_enhanced_disability_premium: [0, 0] + +- name: Case 13, Merton's own list counts standard PIP daily living in 2022. + # Merton's scheme rules for 2022-23, Sch 3 para 12(1)(c), count the PIP + # daily living component at either rate. The case pins the 2022-23 energy + # and cost of living payments at zero, so household net income moves only + # with the reduction. 2022-23 rates: PIP daily living standard 61.85, + # personal allowance (25 or over) 77.00, severe disability premium 69.40, + # disability premium 36.20, enhanced disability premium 17.75. + period: 2022 + absolute_error_margin: 0.01 + # The claimant receives PIP, so the case sets is_disabled_for_benefits for + # the disability premium (HB Regs 2006 Sch 3 paras 12(a) and 13(1)(a)(i); + # Merton's rules Sch 3 paras 9(a) and 10(1)(a)(i)). A pension of 12,500, + # below the 12,570 personal allowance, keeps the reduction on the taper. + input: + people: + person1: + age: 30 + pip_dl_category: STANDARD + is_disabled_for_benefits: true + private_pension_income: 12_500 + benunits: + benunit: + members: [person1] + would_claim_uc: false + would_claim_IS: false + would_claim_pc: false + claims_all_entitled_benefits: true + households: + household: + members: [person1] + country: ENGLAND + local_authority: MERTON + council_tax: 1_800 + savings: 0 + tv_licence: 0 + energy_bills_rebate: 0 + cost_of_living_support_payment: 0 + output: + # The legacy premium counts the enhanced rate only. + enhanced_disability_premium: 0 + meets_council_tax_reduction_enhanced_disability_premium_condition: true + # Merton's list counts the standard PIP daily living rate: 17.75 * 52 = 923.00. + council_tax_reduction_enhanced_disability_premium: 923 + # Severe disability premium 69.40 * 52 = 3,608.80, disability premium + # 36.20 * 52 = 1,882.40 and the enhanced disability premium 923.00: 6,414.20. + council_tax_reduction_premiums: 6_414.20 + # Personal allowance 77.00 * 52 = 4,004.00, plus 6,414.20: 10,418.20. + council_tax_reduction_applicable_amount: 10_418.20 + # 1,800 - 20% of (12,500 - 10,418.20) = 1,800 - 416.36 = 1,383.64. + council_tax_reduction: 1_383.64 + # Pension 12,500 + PIP 61.85 * 52 = 3,216.20 + reduction 1,383.64 - + # council tax 1,800 = 15,299.84. + household_net_income: 15_299.84 + +- name: Case 14, Merton's own list counts standard PIP daily living in 2023. + # Merton's Local Council Tax Support Scheme Rules 2023, Sch 3 para 12(1)(c): + # PIP daily living "payable at either rate". The case pins the 2023-24 energy + # and cost of living payments at zero. 2023-24 rates: PIP daily living + # standard 68.10, personal allowance (25 or over) 84.80, severe disability + # premium 76.40, disability premium 39.85, enhanced disability premium + # 19.55. + period: 2023 + absolute_error_margin: 0.01 + # The claimant receives PIP, so the case sets is_disabled_for_benefits for + # the disability premium (HB Regs 2006 Sch 3 paras 12(a) and 13(1)(a)(i); + # Merton's rules Sch 3 paras 9(a) and 10(1)(a)(i)). A pension of 12,500, + # below the 12,570 personal allowance, keeps the reduction on the taper. + input: + people: + person1: + age: 30 + pip_dl_category: STANDARD + is_disabled_for_benefits: true + private_pension_income: 12_500 + benunits: + benunit: + members: [person1] + would_claim_uc: false + would_claim_IS: false + would_claim_pc: false + claims_all_entitled_benefits: true + households: + household: + members: [person1] + country: ENGLAND + local_authority: MERTON + council_tax: 1_800 + savings: 0 + tv_licence: 0 + energy_bills_rebate: 0 + cost_of_living_support_payment: 0 + output: + # The legacy premium still counts the enhanced rate only. + enhanced_disability_premium: 0 + meets_council_tax_reduction_enhanced_disability_premium_condition: true + # 19.55 * 52 = 1,016.60. + council_tax_reduction_enhanced_disability_premium: 1_016.60 + # Severe disability premium 76.40 * 52 = 3,972.80, disability premium + # 39.85 * 52 = 2,072.20 and the enhanced disability premium 1,016.60: + # 7,061.60. + council_tax_reduction_premiums: 7_061.60 + # Personal allowance 84.80 * 52 = 4,409.60, plus 7,061.60: 11,471.20. + council_tax_reduction_applicable_amount: 11_471.20 + # 1,800 - 20% of (12,500 - 11,471.20) = 1,800 - 205.76 = 1,594.24. + council_tax_reduction: 1_594.24 + # Pension 12,500 + PIP 68.10 * 52 = 3,541.20 + reduction 1,594.24 - + # council tax 1,800 = 15,835.44. + household_net_income: 15_835.44 + +- name: Case 15, Merton's own list counts standard PIP daily living and omits AFIP in 2015. + # Merton's scheme rules for 2015-16, Sch 3 para 12(1)(b), (c), count the DLA + # care component at the highest rate and the PIP daily living component at + # either rate, and name no armed forces payment. 2015-16 rates: PIP daily + # living standard 55.10, personal allowance (25 or over) 73.10, severe + # disability premium 61.85, disability premium 32.25, enhanced disability + # premium 15.75. Each claimant receives PIP or AFIP, so the case sets + # is_disabled_for_benefits for the disability premium. A pension of 10,500, + # below the 10,600 personal allowance, keeps each reduction on the taper. + # The case pins the cost of living and energy payments at zero. + period: 2015 + absolute_error_margin: 0.01 + input: + people: + pip: + age: 30 + pip_dl_category: STANDARD + is_disabled_for_benefits: true + private_pension_income: 10_500 + afip: + age: 30 + armed_forces_independence_payment: 2_000 + is_disabled_for_benefits: true + private_pension_income: 10_500 + benunits: + pip: + members: [pip] + would_claim_uc: false + would_claim_IS: false + would_claim_pc: false + claims_all_entitled_benefits: true + afip: + members: [afip] + would_claim_uc: false + would_claim_IS: false + would_claim_pc: false + claims_all_entitled_benefits: true + households: + pip: + members: [pip] + country: ENGLAND + local_authority: MERTON + council_tax: 1_800 + savings: 0 + tv_licence: 0 + energy_bills_rebate: 0 + cost_of_living_support_payment: 0 + afip: + members: [afip] + country: ENGLAND + local_authority: MERTON + council_tax: 1_800 + savings: 0 + tv_licence: 0 + energy_bills_rebate: 0 + cost_of_living_support_payment: 0 + output: + # The legacy premium counts AFIP (HB para 15(1)(d)) but not the standard + # PIP rate: 15.75 * 52 = 819.00. + enhanced_disability_premium: [0, 819] + meets_council_tax_reduction_enhanced_disability_premium_condition: [true, false] + council_tax_reduction_enhanced_disability_premium: [819, 0] + # Severe disability premium 61.85 * 52 = 3,216.20 and disability premium + # 32.25 * 52 = 1,677.00: 4,893.20, plus 819.00 for PIP: 5,712.20. + council_tax_reduction_premiums: [5_712.20, 4_893.20] + # Personal allowance 73.10 * 52 = 3,801.20: 9,513.40 and 8,694.40. + council_tax_reduction_applicable_amount: [9_513.40, 8_694.40] + # 1,800 - 20% of (10,500 - 9,513.40) = 1,800 - 197.32 = 1,602.68; + # 1,800 - 20% of (10,500 - 8,694.40) = 1,800 - 361.12 = 1,438.88. + council_tax_reduction: [1_602.68, 1_438.88] + # Pension 10,500 + PIP 55.10 * 52 = 2,865.20 + 1,602.68 - 1,800 = + # 13,167.88. The model leaves AFIP out of household benefits + # (HOUSEHOLD_BENEFIT_VARIABLES), so 10,500 + 1,438.88 - 1,800 = 10,138.88. + household_net_income: [13_167.88, 10_138.88] + +- name: Case 16, Westminster's list counts standard PIP daily living and omits AFIP in 2015. + # The model applies the Default Scheme's list (S.I. 2012/2886 Sch 3 para + # 12(1)(b), (c)) in Westminster. 2015-16 rates as in Case 15; Westminster's + # maximum reduction (100%) and withdrawal rate (20%) match Merton's. + period: 2015 + absolute_error_margin: 0.01 + input: + people: + pip: + age: 30 + pip_dl_category: STANDARD + is_disabled_for_benefits: true + private_pension_income: 10_500 + afip: + age: 30 + armed_forces_independence_payment: 2_000 + is_disabled_for_benefits: true + private_pension_income: 10_500 + benunits: + pip: + members: [pip] + would_claim_uc: false + would_claim_IS: false + would_claim_pc: false + claims_all_entitled_benefits: true + afip: + members: [afip] + would_claim_uc: false + would_claim_IS: false + would_claim_pc: false + claims_all_entitled_benefits: true + households: + pip: + members: [pip] + country: ENGLAND + local_authority: WESTMINSTER + council_tax: 1_800 + savings: 0 + tv_licence: 0 + energy_bills_rebate: 0 + cost_of_living_support_payment: 0 + afip: + members: [afip] + country: ENGLAND + local_authority: WESTMINSTER + council_tax: 1_800 + savings: 0 + tv_licence: 0 + energy_bills_rebate: 0 + cost_of_living_support_payment: 0 + output: + # 15.75 * 52 = 819.00. + enhanced_disability_premium: [0, 819] + meets_council_tax_reduction_enhanced_disability_premium_condition: [true, false] + council_tax_reduction_enhanced_disability_premium: [819, 0] + # 3,216.20 + 1,677.00 = 4,893.20, plus 819.00 for PIP: 5,712.20. + council_tax_reduction_premiums: [5_712.20, 4_893.20] + # Plus the personal allowance 3,801.20: 9,513.40 and 8,694.40. + council_tax_reduction_applicable_amount: [9_513.40, 8_694.40] + # 1,800 - 20% of (10,500 - 9,513.40) = 1,602.68; + # 1,800 - 20% of (10,500 - 8,694.40) = 1,438.88. + council_tax_reduction: [1_602.68, 1_438.88] + # 10,500 + 2,865.20 + 1,602.68 - 1,800 = 13,167.88; + # 10,500 + 1,438.88 - 1,800 = 10,138.88, without AFIP as in Case 15. + household_net_income: [13_167.88, 10_138.88] + +- name: Case 17, Westminster's list counts standard PIP daily living and omits AFIP in 2026. + # 2026-27 rates: PIP daily living standard 76.70, personal allowance (under + # 25) 75.65, severe disability premium 86.05, disability premium 44.85, + # enhanced disability premium 22.00. Each claimant, aged 24, takes the lower + # personal allowance, which keeps each applicable amount below a pension of + # 12,500, under the 12,570 personal allowance, and each reduction on the + # taper. + # The case pins the 2026-27 household energy payment and the earlier + # payments at zero. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + pip: + age: 24 + pip_dl_category: STANDARD + is_disabled_for_benefits: true + private_pension_income: 12_500 + afip: + age: 24 + armed_forces_independence_payment: 2_000 + is_disabled_for_benefits: true + private_pension_income: 12_500 + benunits: + pip: + members: [pip] + would_claim_uc: false + would_claim_IS: false + would_claim_pc: false + claims_all_entitled_benefits: true + afip: + members: [afip] + would_claim_uc: false + would_claim_IS: false + would_claim_pc: false + claims_all_entitled_benefits: true + households: + pip: + members: [pip] + country: ENGLAND + local_authority: WESTMINSTER + council_tax: 1_800 + savings: 0 + tv_licence: 0 + energy_bills_rebate: 0 + cost_of_living_support_payment: 0 + household_energy_payment: 0 + afip: + members: [afip] + country: ENGLAND + local_authority: WESTMINSTER + council_tax: 1_800 + savings: 0 + tv_licence: 0 + energy_bills_rebate: 0 + cost_of_living_support_payment: 0 + household_energy_payment: 0 + output: + # 22.00 * 52 = 1,144.00. + enhanced_disability_premium: [0, 1_144] + meets_council_tax_reduction_enhanced_disability_premium_condition: [true, false] + council_tax_reduction_enhanced_disability_premium: [1_144, 0] + # Severe disability premium 86.05 * 52 = 4,474.60 and disability premium + # 44.85 * 52 = 2,332.20: 6,806.80, plus 1,144.00 for PIP: 7,950.80. + council_tax_reduction_premiums: [7_950.80, 6_806.80] + # Personal allowance 75.65 * 52 = 3,933.80: 11,884.60 and 10,740.60. + council_tax_reduction_applicable_amount: [11_884.60, 10_740.60] + # 1,800 - 20% of (12,500 - 11,884.60) = 1,800 - 123.08 = 1,676.92; + # 1,800 - 20% of (12,500 - 10,740.60) = 1,800 - 351.88 = 1,448.12. + council_tax_reduction: [1_676.92, 1_448.12] + # Pension 12,500 + PIP 76.70 * 52 = 3,988.40 + 1,676.92 - 1,800 = + # 16,365.32; pension 12,500 + 1,448.12 - 1,800 = 12,148.12, without AFIP + # as in Case 15. + household_net_income: [16_365.32, 12_148.12] + +- name: Case 18, Merton's own list omits AFIP in 2020. + period: 2020 + input: + people: + person1: + age: 30 + armed_forces_independence_payment: 2_000 + households: + household: + members: [person1] + country: ENGLAND + local_authority: MERTON + output: + # Merton's list counts only highest DLA care or PIP daily living. + meets_council_tax_reduction_enhanced_disability_premium_condition: false + +- name: Case 19, in Kingston upon Thames the flag's formula counts only highest-rate DLA care. + # The case supplies no is_enhanced_disabled_for_benefits, so the model applies + # the flag's formula: DLA care of at least 52 times the highest weekly rate. + # The council's texts from 2023-24 print a wider list with an age limit (Sch 3 + # para 12), and issue #2881 lists what the model needs to apply it. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + dla: + age: 30 + dla_sc_category: HIGHER + enhanced_pip: + age: 30 + pip_dl_category: ENHANCED + standard_pip: + age: 30 + pip_dl_category: STANDARD + afip: + age: 30 + armed_forces_independence_payment: 2_000 + benunits: + dla: + members: [dla] + enhanced_pip: + members: [enhanced_pip] + standard_pip: + members: [standard_pip] + afip: + members: [afip] + households: + dla: + members: [dla] + country: ENGLAND + local_authority: KINGSTON_UPON_THAMES + enhanced_pip: + members: [enhanced_pip] + country: ENGLAND + local_authority: KINGSTON_UPON_THAMES + standard_pip: + members: [standard_pip] + country: ENGLAND + local_authority: KINGSTON_UPON_THAMES + afip: + members: [afip] + country: ENGLAND + local_authority: KINGSTON_UPON_THAMES + output: + meets_council_tax_reduction_enhanced_disability_premium_condition: [true, false, false, false] + # 22.00 * 52 = 1,144.00. + council_tax_reduction_enhanced_disability_premium: [1_144, 0, 0, 0] + # The legacy premium also counts enhanced PIP daily living and AFIP. + enhanced_disability_premium: [1_144, 1_144, 0, 1_144] + # Every award here also gives the severe disability premium, 86.05 * 52 = + # 4,474.60, and the first adds 1,144.00: 5,618.60. + council_tax_reduction_premiums: [5_618.60, 4_474.60, 4_474.60, 4_474.60] + +- name: Case 20, in Kingston upon Thames the model sets no age limit for an over-age partner. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 60 + person2: + age: 70 + dla_sc_category: HIGHER + benunits: + benunit: + members: [person1, person2] + jsa_income: 3_000 + households: + household: + members: [person1, person2] + country: ENGLAND + local_authority: KINGSTON_UPON_THAMES + output: + is_couple: true + # Because the couple receives income-based Jobseeker's Allowance, the + # model applies the working-age scheme. + council_tax_reduction_pensioner: false + # The model's legacy premium applies the age limit. + enhanced_disability_premium: 0 + meets_council_tax_reduction_enhanced_disability_premium_condition: [false, true] + # The couple rate, 31.40 * 52 = 1,632.80, with no age limit in Kingston. + council_tax_reduction_enhanced_disability_premium: 1_632.80 + # The model pays no other premium, because only one partner has a severe + # disability premium qualifying benefit. + council_tax_reduction_premiums: 1_632.80 + +- name: Case 21, Scotland's working-age route counts attendance allowance at either rate. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + aa_category: LOWER + households: + household: + members: [person1] + country: SCOTLAND + local_authority: CITY_OF_EDINBURGH + output: + council_tax_reduction_devolved_working_age: true + # (22.00 + the severe disability premium 86.05) * 52 = 5,618.60. + council_tax_reduction_working_age_adult_premiums: 5_618.60 + # Plus the single allowance, 95.55 * 52 = 4,968.60. + council_tax_reduction_working_age_applicable_amount: 10_587.20 + +- name: Case 22, Scotland's working-age route pays the couple rate for an over-age partner. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 60 + person2: + age: 70 + dla_sc_category: HIGHER + benunits: + benunit: + members: [person1, person2] + jsa_income: 3_000 + households: + household: + members: [person1, person2] + country: SCOTLAND + local_authority: CITY_OF_EDINBURGH + output: + council_tax_reduction_devolved_working_age: true + # 31.40 * 52. + council_tax_reduction_working_age_adult_premiums: 1_632.80 + +- name: Case 23, Wales's working-age route doesn't count attendance allowance for the premium. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + aa_category: LOWER + benunits: + benunit: + members: [person1] + # A Universal Credit award in Wales takes the route to the maximum amount. + would_claim_uc: false + households: + household: + members: [person1] + country: WALES + local_authority: CARDIFF + output: + council_tax_reduction_devolved_working_age: true + meets_council_tax_reduction_enhanced_disability_premium_condition: false + # The severe disability premium alone, 86.05 * 52 = 4,474.60. + council_tax_reduction_working_age_adult_premiums: 4_474.60 + # Plus the single allowance, 101.85 * 52 = 5,296.20. + council_tax_reduction_working_age_applicable_amount: 9_770.80 + +- name: Case 24, Scotland's working-age route counts attendance allowance for a head who applies alone. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 50 + is_household_head: true + aa_category: LOWER + person2: + age: 17 + is_parent: true + is_household_head: false + person3: + age: 17 + is_parent: true + is_household_head: false + person4: + age: 0 + is_household_head: false + benunits: + benunit: + members: [person1, person2, person3, person4] + claims_all_entitled_benefits: true + would_claim_uc: false + households: + household: + members: [person1, person2, person3, person4] + country: SCOTLAND + local_authority: CITY_OF_EDINBURGH + council_tax: 1_800 + savings: 0 + output: + council_tax_reduction_head_applies_alone: true + council_tax_reduction_devolved_working_age: true + # The head's own conditions: (22.00 + 86.05) * 52. + council_tax_reduction_working_age_adult_premiums: 5_618.60 + +- name: Case 25, in Kingston upon Thames a supplied is_enhanced_disabled_for_benefits gives the premium. + # Two applicants aged 40 with enhanced PIP daily living. The first carries + # the flag, as policyengine-uk-data sets it for that award; the second + # doesn't. A pension of 15,000 keeps both reductions on the taper. 2026-27 + # rates: personal allowance (25 or over) 95.55, severe disability premium + # 86.05, disability premium 44.85, enhanced disability premium 22.00; + # Kingston's withdrawal rate 20%. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + flag: + age: 40 + pip_dl_category: ENHANCED + is_disabled_for_benefits: true + is_enhanced_disabled_for_benefits: true + private_pension_income: 15_000 + no_flag: + age: 40 + pip_dl_category: ENHANCED + is_disabled_for_benefits: true + is_enhanced_disabled_for_benefits: false + private_pension_income: 15_000 + benunits: + flag: + members: [flag] + would_claim_uc: false + would_claim_IS: false + would_claim_pc: false + claims_all_entitled_benefits: true + no_flag: + members: [no_flag] + would_claim_uc: false + would_claim_IS: false + would_claim_pc: false + claims_all_entitled_benefits: true + households: + flag: + members: [flag] + country: ENGLAND + local_authority: KINGSTON_UPON_THAMES + council_tax: 1_800 + savings: 0 + no_flag: + members: [no_flag] + country: ENGLAND + local_authority: KINGSTON_UPON_THAMES + council_tax: 1_800 + savings: 0 + output: + # Without the flag, the model reads its formula, which counts DLA care + # alone, though the council's texts list PIP daily living (issue #2881). + meets_council_tax_reduction_enhanced_disability_premium_condition: [true, false] + # The legacy premium counts enhanced PIP daily living in both. + enhanced_disability_premium: [1_144, 1_144] + # 22.00 * 52 = 1,144.00. + council_tax_reduction_enhanced_disability_premium: [1_144, 0] + # Severe disability premium 86.05 * 52 = 4,474.60 and disability premium + # 44.85 * 52 = 2,332.20, plus 1,144.00 with the flag: 7,950.80 and 6,806.80. + council_tax_reduction_premiums: [7_950.80, 6_806.80] + # Personal allowance 95.55 * 52 = 4,968.60, plus the premiums. + council_tax_reduction_applicable_amount: [12_919.40, 11_775.40] + # Income tax of 20% of (15,000 - 12,570) = 486 leaves income of 14,514. + # 1,800 - 20% of (14,514 - 12,919.40) = 1,481.08, and 1,800 - 20% of + # (14,514 - 11,775.40) = 1,252.28. + council_tax_reduction: [1_481.08, 1_252.28] diff --git a/policyengine_uk/tests/policy/baseline/gov/local_authorities/council_tax_reduction/severe_disability_premium_young_person.yaml b/policyengine_uk/tests/policy/baseline/gov/local_authorities/council_tax_reduction/severe_disability_premium_young_person.yaml index cd84156576..c0f75df3e3 100644 --- a/policyengine_uk/tests/policy/baseline/gov/local_authorities/council_tax_reduction/severe_disability_premium_young_person.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/local_authorities/council_tax_reduction/severe_disability_premium_young_person.yaml @@ -1,14 +1,18 @@ # SSI2021/249 regs6,8(2)(a),Sch1para13. Existing2026 model controls: # allowance95.55*52=4968.60; severe86.05*52=4474.60; withdrawal20%. # PIP qualifies SDP but generic disability flag is separately supplied/defaultfalse. +# Enhanced PIP daily living also qualifies for the enhanced disability premium, +# 22.00*52=1144 (HB Regs 2006 Sch3 para15(1)(c); IS Regs 1987 Sch2 +# para13A(1ZA)(c); SSI2021/249 Sch1 para14(1)(f)). # Pension12570:no tax; PIP disregarded; Child Benefit claim declined. -# CTR=2000-20%*(12570-allowance):479.72 under the shared formula. Where the -# student is a UC qualifying young person, Scotland's working-age route -# (council_tax_reduction_devolved_working_age) makes the applicant a lone -# parent with a child premium: (95.55 + 109.85 + 86.05 severe disability -# premium) * 52 = 15,155.40 (SSI 2026/56 reg 14), above the 12,570 income, -# so the award is the full 2,000. The shared council_tax_reduction_applicable_ -# amount (9,443.20) has no child amounts and no longer sets the award. +# CTR=2000-20%*(12570-6112.60):708.52 under the shared formula and Scotland's +# working-age route alike. Where the student is a UC qualifying young person, +# that route (council_tax_reduction_devolved_working_age) makes the applicant +# a lone parent with a child premium: (95.55 + 109.85 + 86.05 severe disability +# premium + 22.00 enhanced disability premium) * 52 = 16,299.40 (SSI 2026/56 +# reg 14), above the 12,570 income, so the award is the full 2,000. The shared +# council_tax_reduction_applicable_amount (10,587.20) has no child amounts and +# no longer sets the award. # Annual UC terminal-date input represents unavailable assessment-period detail. # Reverse case supplies CB family status: input-contract composition, # not a naturally derived eligibility pair or full statutory rate audit. @@ -54,21 +58,25 @@ council_tax: 2000 savings: 0 output: - simulated_council_tax_reduction_benunit: 479.72 + # 2000 - 20% * (12570 - 6112.60) = 708.52. + simulated_council_tax_reduction_benunit: 708.52 is_council_tax_reduction_lone_parent: false - council_tax_reduction_working_age_applicable_amount: 4968.6 + # 4968.60 + 1144. + council_tax_reduction_working_age_applicable_amount: 6112.6 disability_premium: 0 - enhanced_disability_premium: 0 + enhanced_disability_premium: 1144 severe_disability_premium: 4474.6 council_tax_reduction_pensioner: false council_tax_reduction_applicable_income: 12570 - council_tax_reduction_applicable_amount: 4968.6 + # 4968.60 + 1144 (enhanced disability premium only). + council_tax_reduction_applicable_amount: 6112.6 council_tax_reduction_non_dep_deductions: 0 severe_disability_premium_before_non_dependant_test: 4474.6 council_tax_reduction_severe_disability_premium: 0 - working_age_benefits_premiums: 4474.6 - benefits_premiums: 4474.6 - income_support_applicable_amount: 9443.2 + # 4474.60 + 1144 = 5618.60; IS 4968.60 + 5618.60 = 10587.20. + working_age_benefits_premiums: 5618.6 + benefits_premiums: 5618.6 + income_support_applicable_amount: 10587.2 - name: Before terminal date both definitions retain Scottish CTR premium period: 2026 absolute_error_margin: 0.01 @@ -110,21 +118,22 @@ simulated_council_tax_reduction_benunit: 2000 is_council_tax_reduction_lone_parent: true council_tax_reduction_working_age_child_amounts: 109.85 * 52 - council_tax_reduction_working_age_adult_premiums: 4474.6 - council_tax_reduction_working_age_applicable_amount: (95.55 + 109.85 + 86.05) * 52 + council_tax_reduction_working_age_adult_premiums: (86.05 + 22.00) * 52 + council_tax_reduction_working_age_applicable_amount: (95.55 + 109.85 + 86.05 + 22.00) * 52 council_tax_reduction_working_age_applicable_income: 12570 disability_premium: 0 - enhanced_disability_premium: 0 + enhanced_disability_premium: 1144 severe_disability_premium: 4474.6 council_tax_reduction_pensioner: false council_tax_reduction_applicable_income: 12570 - council_tax_reduction_applicable_amount: 9443.2 + # 4968.60 + 4474.60 + 1144 = 10587.20. + council_tax_reduction_applicable_amount: 10587.2 council_tax_reduction_non_dep_deductions: 0 severe_disability_premium_before_non_dependant_test: 4474.6 council_tax_reduction_severe_disability_premium: 4474.6 - working_age_benefits_premiums: 4474.6 - benefits_premiums: 4474.6 - income_support_applicable_amount: 9443.2 + working_age_benefits_premiums: 5618.6 + benefits_premiums: 5618.6 + income_support_applicable_amount: 10587.2 - name: 'Supplied-status contract: UC young person outside CB family restores Scottish CTR premium' period: 2026 @@ -168,18 +177,21 @@ simulated_council_tax_reduction_benunit: 2000 is_council_tax_reduction_lone_parent: true council_tax_reduction_working_age_child_amounts: 109.85 * 52 - council_tax_reduction_working_age_adult_premiums: 4474.6 - council_tax_reduction_working_age_applicable_amount: (95.55 + 109.85 + 86.05) * 52 + council_tax_reduction_working_age_adult_premiums: (86.05 + 22.00) * 52 + council_tax_reduction_working_age_applicable_amount: (95.55 + 109.85 + 86.05 + 22.00) * 52 council_tax_reduction_working_age_applicable_income: 12570 disability_premium: 0 - enhanced_disability_premium: 0 + enhanced_disability_premium: 1144 severe_disability_premium: 0 council_tax_reduction_pensioner: false council_tax_reduction_applicable_income: 12570 - council_tax_reduction_applicable_amount: 9443.2 + # 4968.60 + 4474.60 + 1144 = 10587.20. + council_tax_reduction_applicable_amount: 10587.2 council_tax_reduction_non_dep_deductions: 0 severe_disability_premium_before_non_dependant_test: 4474.6 council_tax_reduction_severe_disability_premium: 4474.6 - working_age_benefits_premiums: 0 - benefits_premiums: 0 - income_support_applicable_amount: 4968.6 + # The non-dependant bars only the severe premium: 1144; IS 4968.60 + + # 1144 = 6112.60. + working_age_benefits_premiums: 1144 + benefits_premiums: 1144 + income_support_applicable_amount: 6112.6 diff --git a/policyengine_uk/tests/test_council_tax_reduction_applicant_properties.py b/policyengine_uk/tests/test_council_tax_reduction_applicant_properties.py index 13ef3b526b..fc534a6d84 100644 --- a/policyengine_uk/tests/test_council_tax_reduction_applicant_properties.py +++ b/policyengine_uk/tests/test_council_tax_reduction_applicant_properties.py @@ -73,13 +73,18 @@ ] SHAPES = ["alone", "couple", "young_parents"] # The head's own circumstances that the premiums and the exemption read: -# disability, Attendance Allowance (a severe disability premium qualifying -# benefit, which also exempts her from non-dependant deductions), Carer's -# Allowance (the carer premium) and blindness. +# disability, the enhanced disability flag (the enhanced disability premium +# condition in Kingston upon Thames), the enhanced PIP daily living component +# (an enhanced disability premium qualifying benefit elsewhere), Attendance +# Allowance (a severe disability premium qualifying benefit, which also +# exempts her from non-dependant deductions, and an enhanced disability +# premium one for Scottish councils from 2023), Carer's Allowance (the carer +# premium) and blindness. head_circumstances = st.fixed_dictionaries( dict( is_disabled_for_benefits=st.booleans(), is_enhanced_disabled_for_benefits=st.booleans(), + pip_dl_category=st.sampled_from(["NONE", "NONE", "ENHANCED"]), attendance_allowance=st.sampled_from([0, 0, 4_000]), carers_allowance=st.sampled_from([0, 0, 4_000]), is_blind=st.booleans(), diff --git a/policyengine_uk/tests/test_enhanced_disability_premium_properties.py b/policyengine_uk/tests/test_enhanced_disability_premium_properties.py new file mode 100644 index 0000000000..2ae2d6f9a8 --- /dev/null +++ b/policyengine_uk/tests/test_enhanced_disability_premium_properties.py @@ -0,0 +1,554 @@ +"""Property-based tests for the legacy enhanced disability premium. + +A claimant or partner meets the premium's condition (HB Regs 2006 Sch 3 para +15(1)(b)-(d); IS Regs 1987 Sch 2 para 13A; HB Regs (NI) 2006 Sch 4 para 15) +with an award of the highest-rate DLA care component, the enhanced-rate PIP +daily living component or armed forces independence payment, while under the +qualifying age for State Pension Credit. Claimants in Northern Ireland qualify +through AFIP from 24 December 2013 and through PIP from 20 June 2016, which +the model reads at 30 April, so from 2017. Housing Benefit pays the single +rate to a person who is not a member of a couple, and one couple rate where +either or both members meet the condition (HB Regs 2006 Sch 3 Part 4). + +The model counts an award only with a positive amount of the benefit, and +takes its rate from the award category or from an amount that reaches +52 × (top weekly rate − £1). + +Scottish councils count attendance allowance at either rate from 1 April 2023 +(SSI 2021/249 Sch 1 para 14), and the Scottish Ministers removed the age limit +from 20 June 2022, which the model reads from 2023. Merton (Sch 3 para 12) +counts the PIP daily living component at either rate and omits AFIP; Newham +counts the PIP daily living component at either rate and AFIP. In Westminster +the model applies the Default Scheme's list (S.I. 2012/2886 Sch 3 para 12), +which counts the PIP daily living component at either rate and omits AFIP. +Each of those lists starts on or before 1 April 2013 (COUNCIL_LISTS) and +applies in every model year. In Kingston upon Thames the model reads +is_enhanced_disabled_for_benefits, with no age limit (issue #2881). The test +supplies no value for that flag, so the model applies its formula: DLA care of +at least 52 times the highest weekly rate, with no tolerance. The model also +applies the Housing Benefit condition in Wales and every other scheme. + +The test generates single people, couples and lone parents in the places and +age range below, with the listed awards, and adds a family in each council in +COUNCIL_LISTS to every example. It supplies each person's entered DLA +care and PIP daily living amount, or computes an amount from their category. +It checks these invariants in every year from 2015 to 2030: + +1. The test computes the statutory amount from the award inputs and the + parameter rates. enhanced_disability_premium equals that amount, and + council_tax_reduction_enhanced_disability_premium equals the amount under + the list the model applies to the scheme in that year. +2. The model pays no premium to a family in which no claimant or partner has + a qualifying award. +3. Giving a claimant or partner a qualifying benefit on top of their awards + never lowers either premium. +4. Each premium equals nil, the single rate or the couple rate, and never + exceeds two single rates; the couple rate never exceeds two single rates + in any year. +5. The Council Tax Reduction premium equals the legacy premium in Wales, + Northern Ireland, Oxford and the default English council, and in Scotland + before 2023. It never falls below the legacy premium in Scotland from 2023, + or where a council's own list counts AFIP (Newham's). Where a council's own + list omits AFIP (Merton's and Westminster's), it never falls below the + legacy premium unless that premium rests on AFIP alone, and then the model + pays none unless an under-age claimant or partner has a PIP daily living + award. In Kingston upon Thames it never falls below the legacy premium where + a claimant or partner of any age has DLA care of at least 52 times the + highest weekly rate. +6. For a child or young person in Great Britain, the qualifying flag matches + the test's own calculation. The model pays the child's enhanced rate in the + Housing Benefit child premiums (housing_benefit_child_disability_premiums) + when the flag holds and pays none when it does not. +""" + +import numpy as np +from hypothesis import HealthCheck, given, settings +from hypothesis import strategies as st +from policyengine_core.reforms import Reform + +from policyengine_uk import CountryTaxBenefitSystem, Simulation + +PROPERTY_SETTINGS = settings( + max_examples=8, + deadline=None, + derandomize=True, + suppress_health_check=[HealthCheck.too_slow, HealthCheck.data_too_large], +) +WEEKS_IN_YEAR = 52 +# The test allows this weekly tolerance below the top rate +# (policyengine-uk-data's CATEGORY_THRESHOLD_WEEKLY_TOLERANCE). +TOLERANCE = 1 +# Each example builds one simulation with inputs for every year from 2015 to +# 2030, so every example tests both sides of the Northern Ireland PIP date +# (2017) and the Scottish changes (2023). Every council's own list starts in +# 2013-14, before the model's first year, so the test checks each list in +# every year the model applies it. +YEARS = list(range(2015, 2031)) +# (country, local authority): None keeps the default local authority. +PLACES = [ + ("ENGLAND", None), + ("ENGLAND", "MERTON"), + ("ENGLAND", "KINGSTON_UPON_THAMES"), + ("ENGLAND", "NEWHAM"), + ("ENGLAND", "WESTMINSTER"), + ("ENGLAND", "OXFORD"), + ("WALES", "CARDIFF"), + ("SCOTLAND", "CITY_OF_EDINBURGH"), + ("NORTHERN_IRELAND", None), +] +# The generator assigns the award inputs below. The reported amounts of 7,000 +# and 3,000 respectively exceed and fall below each tested year's threshold, +# which rises from (82.30 - 1) * 52 = 4,227.60 in 2015 to 6,596.16 at the +# model's uprated 2030 rates (test_entered_amounts_straddle_the_threshold). +AWARDS = { + "dla_care_lowest": {"dla_sc_category": "LOWER"}, + "dla_care_middle": {"dla_sc_category": "MIDDLE"}, + "dla_care_highest": {"dla_sc_category": "HIGHER"}, + "dla_care_top_amount_only": {"dla_sc": 7_000}, + "dla_care_low_amount_only": {"dla_sc": 3_000}, + "dla_care_highest_zero_amount": {"dla_sc_category": "HIGHER", "dla_sc": 0}, + "dla_care_highest_part_amount": {"dla_sc_category": "HIGHER", "dla_sc": 1_000}, + "pip_daily_living_standard": {"pip_dl_category": "STANDARD"}, + "pip_daily_living_enhanced": {"pip_dl_category": "ENHANCED"}, + "pip_daily_living_top_amount_only": {"pip_dl": 7_000}, + "pip_daily_living_low_amount_only": {"pip_dl": 3_000}, + "pip_daily_living_enhanced_zero_amount": { + "pip_dl_category": "ENHANCED", + "pip_dl": 0, + }, + "afip": {"armed_forces_independence_payment": 2_000}, + "attendance_allowance_lower": {"aa_category": "LOWER"}, + "attendance_allowance_higher": {"aa_category": "HIGHER"}, +} +QUALIFYING_AWARDS = ["dla_care_highest", "pip_daily_living_enhanced", "afip"] +ADULT_AGES = [20, 30, 45, 60, 64, 66, 67, 70, 85] +# Each council's own list (Sch 3 para 12 of its scheme), by the scheme year +# it starts: "dla_highest" is the DLA care component at the highest rate, +# "any_pip" the PIP daily living component at either rate and "afip" armed +# forces independence payment. "enhanced_disabled_flag" is the formula of +# is_enhanced_disabled_for_benefits, which the model reads in place of a list. +COUNCIL_LISTS = { + # The 2013 rules. + "MERTON": {2013: ("dla_highest", "any_pip")}, + # The model's condition: the council's texts from 2023-24 print a wider + # list with an age limit, which the model doesn't yet apply (issue #2881). + "KINGSTON_UPON_THAMES": {2013: ("enhanced_disabled_flag",)}, + # The 2013 scheme, and the 2014 scheme with AFIP. + "NEWHAM": { + 2013: ("dla_highest", "any_pip"), + 2014: ("dla_highest", "any_pip", "afip"), + }, + # The Default Scheme: the council has approved the same scheme since + # 2013-14, and its Cabinet says the council's scheme mirrors it. + "WESTMINSTER": {2013: ("dla_highest", "any_pip")}, +} + +system = CountryTaxBenefitSystem() + + +def award_inputs(awards): + """Return the model inputs for a tuple of awards, letting a later award's + input replace an earlier one's.""" + inputs = {} + for award in awards: + inputs.update(AWARDS[award]) + return inputs + + +def amount(inputs, benefit, year): + """Return the entered annual amount of DLA care (dla_sc) or PIP daily + living (pip_dl), or compute it from the award category.""" + if benefit in inputs: + return inputs[benefit] + dwp = system.parameters(year).gov.dwp + rates = dwp.dla.self_care if benefit == "dla_sc" else dwp.pip.daily_living + category = inputs.get(f"{benefit}_category", "NONE") + if category == "NONE": + return 0 + return getattr(rates, category.lower()) * WEEKS_IN_YEAR + + +def top_rate_award(inputs, benefit, year): + """Check for an award at the highest DLA care or enhanced PIP daily living + rate: a positive amount and either the top category or an amount within + the tolerance of the top rate.""" + dwp = system.parameters(year).gov.dwp + if benefit == "dla_sc": + top_category, top_rate = "HIGHER", dwp.dla.self_care.higher + else: + top_category, top_rate = "ENHANCED", dwp.pip.daily_living.enhanced + annual = amount(inputs, benefit, year) + top = inputs.get(f"{benefit}_category") == top_category or ( + annual >= (top_rate - TOLERANCE) * WEEKS_IN_YEAR + ) + return annual > 0 and top + + +def afip(inputs): + return inputs.get("armed_forces_independence_payment", 0) > 0 + + +def enhanced_disabled_flag(inputs, year): + """Compute the formula of is_enhanced_disabled_for_benefits, which the + model reads in Kingston upon Thames: DLA care of at least 52 times the + highest weekly rate, entered or computed from the category.""" + higher = system.parameters(year).gov.dwp.dla.self_care.higher + return amount(inputs, "dla_sc", year) >= higher * WEEKS_IN_YEAR + + +def qualifies(inputs, country, year): + """Check for the legacy premium's qualifying awards under the + Regulations.""" + if top_rate_award(inputs, "dla_sc", year) or afip(inputs): + return True + if top_rate_award(inputs, "pip_dl", year): + return country != "NORTHERN_IRELAND" or year >= 2017 + return False + + +def council_list(council, year): + """Return the awards on a council's own list in a year, or None where + the model applies the Housing Benefit condition.""" + starts = [start for start in COUNCIL_LISTS.get(council, {}) if start <= year] + return COUNCIL_LISTS[council][max(starts)] if starts else None + + +def qualifies_for_scheme(inputs, place, year): + """Check for the awards on the list the model applies to the scheme in + that year, before the scheme's age limit.""" + country, council = place + if country == "SCOTLAND": + # SSI 2021/249 Sch 1 para 14(1), with head (g) from 2023. + attendance_allowance = inputs.get("aa_category") in ("LOWER", "HIGHER") + return qualifies(inputs, country, year) or ( + attendance_allowance and year >= 2023 + ) + listed = council_list(council, year) + if listed is None: + # The Housing Benefit condition. + return qualifies(inputs, country, year) + held = dict( + dla_highest=top_rate_award(inputs, "dla_sc", year), + any_pip=amount(inputs, "pip_dl", year) > 0, + afip=afip(inputs), + enhanced_disabled_flag=enhanced_disabled_flag(inputs, year), + ) + return any(held[award] for award in listed) + + +def scheme_age_limit(place, year): + if place[1] == "KINGSTON_UPON_THAMES": + return False + return place[0] != "SCOTLAND" or year < 2023 + + +awards = st.lists(st.sampled_from(sorted(AWARDS)), max_size=2).map(tuple) +adult = st.fixed_dictionaries(dict(age=st.sampled_from(ADULT_AGES), awards=awards)) +family = st.fixed_dictionaries( + dict( + place=st.sampled_from(PLACES), + shape=st.sampled_from(["single", "couple", "lone_parent"]), + adults=st.lists(adult, min_size=2, max_size=2), + upgrade_member=st.integers(0, 1), + upgrade_award=st.sampled_from(QUALIFYING_AWARDS), + ) +) +# A family in each council in COUNCIL_LISTS, drawn for every example. +council_families = st.tuples( + *( + family.map(lambda f, place=place: dict(f, place=place)) + for place in PLACES + if place[1] in COUNCIL_LISTS + ) +) +child = st.fixed_dictionaries( + dict( + age=st.sampled_from([4, 10, 16, 17]), + awards=awards, + country=st.sampled_from(["ENGLAND", "WALES", "SCOTLAND"]), + ) +) + + +def adults_of(f): + return f["adults"][: 2 if f["shape"] == "couple" else 1] + + +def upgraded(f): + """Add a qualifying benefit to one claimant's or partner's awards and + return the family.""" + adults = [dict(a) for a in f["adults"]] + j = f["upgrade_member"] % len(adults_of(f)) + adults[j]["awards"] = adults[j]["awards"] + (f["upgrade_award"],) + return dict(f, adults=adults) + + +def every_year(inputs): + return {k: {year: v for year in YEARS} for k, v in inputs.items()} + + +def person_inputs(age, awards, **extra): + """Return a person's inputs for every year. A situation that supplies an + amount for one person supplies the default, zero, for everyone else, as + it does for categories (utils/pip.py). So the test gives every person + both amounts: the amount entered, or the rate for the award category, + which the amount formulas would give.""" + inputs = award_inputs(awards) + person = every_year(dict(age=age, **extra, **inputs)) + for benefit in ("dla_sc", "pip_dl"): + person[benefit] = {year: amount(inputs, benefit, year) for year in YEARS} + return person + + +def household_inputs(country, council): + inputs = dict(country=country) + if council is not None: + inputs["local_authority"] = council + return every_year(inputs) + + +def build(families, children): + """Build one household and one benefit unit per family, and one per child + with a parent aged 35. The test marks claimants and partners as such, so + the model never reads an age gap as making one the other's child.""" + people, benunits, households = {}, {}, {} + for i, f in enumerate(families): + members = [] + for j, a in enumerate(adults_of(f)): + name = f"f{i}_adult{j}" + people[name] = person_inputs( + a["age"], a["awards"], is_claimant_or_partner=True + ) + members.append(name) + if f["shape"] == "lone_parent": + name = f"f{i}_child" + people[name] = person_inputs(8, (), is_claimant_or_partner=False) + members.append(name) + benunits[f"f{i}"] = {"members": members} + households[f"f{i}"] = dict(members=members, **household_inputs(*f["place"])) + for i, c in enumerate(children): + members = [f"c{i}_parent", f"c{i}_child"] + people[members[0]] = person_inputs(35, ()) + people[members[1]] = person_inputs(c["age"], c["awards"]) + benunits[f"c{i}"] = {"members": members} + households[f"c{i}"] = dict( + members=members, **household_inputs(c["country"], None) + ) + sim = Simulation( + situation=dict(people=people, benunits=benunits, households=households) + ) + person_ids = list(sim.populations["person"].ids) + benunit_ids = list(sim.populations["benunit"].ids) + return sim, person_ids.index, benunit_ids.index + + +def oracle(f, year, attained): + """Compute the two annual premiums for one family from the Regulations + and COUNCIL_LISTS. attained[j] holds when adult j has attained the + qualifying age for State Pension Credit.""" + p = system.parameters(year).gov.dwp.disability_premia + rate = p.enhanced_couple if f["shape"] == "couple" else p.enhanced_single + country = f["place"][0] + inputs = [award_inputs(a["awards"]) for a in adults_of(f)] + legacy = any( + qualifies(x, country, year) and not attained[j] for j, x in enumerate(inputs) + ) + age_limit = scheme_age_limit(f["place"], year) + scheme = any( + qualifies_for_scheme(x, f["place"], year) and not (age_limit and attained[j]) + for j, x in enumerate(inputs) + ) + return rate * WEEKS_IN_YEAR * legacy, rate * WEEKS_IN_YEAR * scheme + + +def check_scheme_against_legacy(f, year, attained, edp, ctr): + """Check invariant 5: each scheme's premium against the legacy + premium.""" + country, council = f["place"] + listed = council_list(council, year) + under_age = [ + award_inputs(a["awards"]) for j, a in enumerate(adults_of(f)) if not attained[j] + ] + if country == "SCOTLAND": + if year < 2023: + assert np.isclose(ctr, edp, atol=0.01) + else: + assert ctr >= edp - 0.01 + elif listed is None: + assert np.isclose(ctr, edp, atol=0.01) + elif "afip" in listed: + assert ctr >= edp - 0.01 + elif council == "KINGSTON_UPON_THAMES": + # The legacy premium also counts PIP daily living, AFIP, highest-rate + # DLA care entered with a smaller amount, and DLA care amounts within + # £1 a week of the top rate, all of which the flag's formula leaves + # out. The flag sets no age limit. + claimants = [award_inputs(a["awards"]) for a in adults_of(f)] + if any(enhanced_disabled_flag(x, year) for x in claimants): + assert ctr >= edp - 0.01 + else: + rests_on_afip = edp > 0 and not any( + top_rate_award(x, "dla_sc", year) or top_rate_award(x, "pip_dl", year) + for x in under_age + ) + if not rests_on_afip: + assert ctr >= edp - 0.01 + elif not any(amount(x, "pip_dl", year) > 0 for x in under_age): + # The list omits AFIP. + assert ctr == 0 + + +def check_families(sim, person, benunit, families, year): + n = len(families) // 2 + edp = sim.calculate("enhanced_disability_premium", year) + ctr = sim.calculate("council_tax_reduction_enhanced_disability_premium", year) + attained = sim.calculate("has_attained_state_pension_credit_qualifying_age", year) + is_couple = sim.calculate("is_couple", year) + p = system.parameters(year).gov.dwp.disability_premia + single_annual = p.enhanced_single * WEEKS_IN_YEAR + couple_annual = p.enhanced_couple * WEEKS_IN_YEAR + family_edp, family_ctr = [], [] + for i, f in enumerate(families): + b = benunit(f"f{i}") + member_attained = [ + bool(attained[person(f"f{i}_adult{j}")]) for j in range(len(adults_of(f))) + ] + assert bool(is_couple[b]) == (f["shape"] == "couple") + legacy, scheme = oracle(f, year, member_attained) + family_edp.append(edp[b]) + family_ctr.append(ctr[b]) + # 1. Oracle. + assert np.isclose(edp[b], legacy, atol=0.01), (f, year, edp[b], legacy) + assert np.isclose(ctr[b], scheme, atol=0.01), (f, year, ctr[b], scheme) + # 2. No qualifying award, no premium. + inputs = [award_inputs(a["awards"]) for a in adults_of(f)] + if not any(qualifies(x, f["place"][0], year) for x in inputs): + assert edp[b] == 0 + if not any(qualifies_for_scheme(x, f["place"], year) for x in inputs): + assert ctr[b] == 0 + # 4. Bounds. + for annual in (edp[b], ctr[b]): + assert any( + np.isclose(annual, x, atol=0.01) + for x in (0, single_annual, couple_annual) + ) + assert annual <= 2 * single_annual + 0.01 + check_scheme_against_legacy(f, year, member_attained, edp[b], ctr[b]) + # 3. Monotone: the test pairs each family in the first half with its twin + # in the second half, which has a qualifying benefit added. + assert all(t >= s - 0.01 for s, t in zip(family_edp[:n], family_edp[n:])) + assert all(t >= s - 0.01 for s, t in zip(family_ctr[:n], family_ctr[n:])) + + +def check_children(sim, person, benunit, children, year): + # 6. The Housing Benefit child premiums' enhanced rate. + p = system.parameters(year).gov.dwp.housing_benefit.premiums + premiums = sim.calculate("housing_benefit_child_disability_premiums", year) + qualifying = sim.calculate( + "receives_enhanced_disability_premium_qualifying_benefit", year + ) + young = sim.calculate("is_child_or_young_person_for_legacy_benefits", year) + for i, c in enumerate(children): + k = person(f"c{i}_child") + if not young[k]: + continue + inputs = award_inputs(c["awards"]) + assert bool(qualifying[k]) == qualifies(inputs, c["country"], year), (c, year) + # A child qualifies for the disabled child rate with a positive DLA or + # PIP amount, or AFIP. + disabled = ( + amount(inputs, "dla_sc", year) > 0 + or amount(inputs, "pip_dl", year) > 0 + or afip(inputs) + ) + weekly = premiums[benunit(f"c{i}")] / WEEKS_IN_YEAR + enhanced_weekly = weekly - p.disabled_child * disabled + assert np.isclose( + enhanced_weekly, p.enhanced_disabled_child * qualifying[k], atol=0.01 + ), (c, year, weekly) + + +@PROPERTY_SETTINGS +@given( + families=st.lists(family, min_size=1, max_size=30), + council_families=council_families, + children=st.lists(child, max_size=15), +) +def test_enhanced_disability_premium_invariants(families, council_families, children): + families = families + list(council_families) + everyone = families + [upgraded(f) for f in families] + sim, person, benunit = build(everyone, children) + for year in YEARS: + check_families(sim, person, benunit, everyone, year) + check_children(sim, person, benunit, children, year) + + +def test_couple_rate_never_exceeds_two_single_rates(): + for year in range(2015, 2031): + p = system.parameters(year).gov.dwp.disability_premia + assert p.enhanced_couple <= 2 * p.enhanced_single, year + + +def test_entered_amounts_straddle_the_threshold(): + """In every tested year the entered top amount reaches the top-rate + threshold and the entered low amount falls below it.""" + for year in YEARS: + for benefit, award in (("dla_sc", "dla_care"), ("pip_dl", "pip_daily_living")): + top = AWARDS[f"{award}_top_amount_only"] + low = AWARDS[f"{award}_low_amount_only"] + assert top_rate_award(top, benefit, year), (award, year) + assert not top_rate_award(low, benefit, year), (award, year) + + +class NeutraliseDlaCareAndPipDailyLiving(Reform): + def apply(self): + self.neutralize_variable("dla_sc") + self.neutralize_variable("pip_dl") + + +def test_neutralised_awards_pay_no_enhanced_premium(): + """A reform that neutralises DLA care and PIP daily living leaves their + categories in place but sets both amounts to zero, so no award remains. + The model then pays neither adult premium nor the child's disability + premiums.""" + year = 2026 + people = dict( + dla=dict(age=30, dla_sc_category="HIGHER"), + pip=dict(age=30, pip_dl_category="ENHANCED"), + parent=dict(age=35), + child=dict(age=10, dla_sc_category="HIGHER"), + ) + groups = dict(dla=["dla"], pip=["pip"], family=["parent", "child"]) + situation = dict( + people={name: every_year(inputs) for name, inputs in people.items()}, + benunits={name: {"members": members} for name, members in groups.items()}, + households={ + name: dict(members=members, **household_inputs("ENGLAND", "MERTON")) + for name, members in groups.items() + }, + ) + p = system.parameters(year).gov.dwp + single_annual = p.disability_premia.enhanced_single * WEEKS_IN_YEAR + child_annual = ( + p.housing_benefit.premiums.disabled_child + + p.housing_benefit.premiums.enhanced_disabled_child + ) * WEEKS_IN_YEAR + for reform, adult_premium, child_premium, flag in ( + (None, single_annual, child_annual, True), + (NeutraliseDlaCareAndPipDailyLiving, 0, 0, False), + ): + sim = Simulation(situation=situation, reform=reform) + assert sim.calculate( + "receives_enhanced_disability_premium_qualifying_benefit", year + ).tolist() == [flag, flag, False, flag] + for variable in ( + "enhanced_disability_premium", + "council_tax_reduction_enhanced_disability_premium", + ): + assert np.allclose( + sim.calculate(variable, year), [adult_premium, adult_premium, 0] + ), (reform, variable) + assert np.allclose( + sim.calculate("housing_benefit_child_disability_premiums", year), + [0, 0, child_premium], + ), reform diff --git a/policyengine_uk/variables/gov/dwp/dla/has_highest_dla_sc_award.py b/policyengine_uk/variables/gov/dwp/dla/has_highest_dla_sc_award.py new file mode 100644 index 0000000000..f6899e6060 --- /dev/null +++ b/policyengine_uk/variables/gov/dwp/dla/has_highest_dla_sc_award.py @@ -0,0 +1,32 @@ +from policyengine_uk.model_api import * + + +class has_highest_dla_sc_award(Variable): + label = "Has an award of the DLA care component at the highest rate" + documentation = ( + "The model counts an award of the care component of disability " + "living allowance at the highest rate when the person has a positive " + "amount (dla_sc) and either the highest-rate category " + "(dla_sc_category) or an amount that reaches 52 × (highest weekly " + "rate − weekly tolerance), with the tolerance in " + "gov.dwp.disability_premia.top_rate_amount_tolerance. It rejects an amount of zero, including one that " + "a reform sets by neutralising dla_sc. Claimants also qualify while " + "the suspension or hospital rules stop or abate payment of the award " + "(HB Regs 2006 Sch 3 para 15(1)(b)); the model has no input for that." + ) + entity = Person + definition_period = YEAR + value_type = bool + reference = ( + "https://www.legislation.gov.uk/uksi/2006/213/schedule/3/paragraph/15", + "https://www.legislation.gov.uk/uksi/1987/1967/schedule/2/paragraph/13A", + ) + + def formula(person, period, parameters): + p = parameters(period).gov.dwp + amount = person("dla_sc", period) + threshold = ( + p.dla.self_care.higher - p.disability_premia.top_rate_amount_tolerance + ) * WEEKS_IN_YEAR + highest_rate = person("receives_highest_dla_sc", period) | (amount >= threshold) + return (amount > 0) & highest_rate diff --git a/policyengine_uk/variables/gov/dwp/housing_benefit/housing_benefit_child_disability_premiums.py b/policyengine_uk/variables/gov/dwp/housing_benefit/housing_benefit_child_disability_premiums.py index b2ad3bb956..171979a8cb 100644 --- a/policyengine_uk/variables/gov/dwp/housing_benefit/housing_benefit_child_disability_premiums.py +++ b/policyengine_uk/variables/gov/dwp/housing_benefit/housing_benefit_child_disability_premiums.py @@ -8,15 +8,18 @@ class housing_benefit_child_disability_premiums(Variable): unit = GBP label = "Housing Benefit child disability premiums" documentation = ( - "Disabled-child and enhanced-child premiums for legally dependent " - "children and young persons. Uses actual DLA or PIP receipt, AFIP, " - "and the existing blindness indicator; enhanced rates additionally " - "require highest DLA care or enhanced PIP daily living receipt, or " - "AFIP. Scottish replacement awards must be represented in the existing " - "benefit fields: separate replacement-award fields are not available. " - "Hospital suspension, blindness run-on and bereavement continuation " - "are not reconstructed. A generic disability flag is insufficient. " - "These child amounts are separate from the shared adult premiums." + "The model pays the disabled-child and enhanced-child premiums for " + "legally dependent children and young persons. A child qualifies for " + "the disabled-child rate through a positive DLA or PIP amount (either " + "component), AFIP or the blindness indicator, and for the enhanced " + "rate through an award that meets the adult condition: the highest " + "DLA care rate (has_highest_dla_sc_award), the enhanced PIP daily " + "living rate (has_enhanced_pip_dl_award) or AFIP. The model has no " + "separate fields for Scottish replacement awards, so callers enter " + "them in the DLA and PIP fields. The model omits hospital suspension, " + "the blindness run-on and bereavement continuation, and a generic " + "disability flag does not qualify. The model computes these child " + "premiums separately from the adult premiums." ) reference = ( "https://www.legislation.gov.uk/uksi/2006/213/schedule/3/paragraph/15", @@ -40,8 +43,8 @@ def formula(benunit, period, parameters): afip = person("armed_forces_independence_payment", period) > 0 disabled = dla | pip | afip | person("is_blind", period) enhanced = ( - (dla_care & person("receives_highest_dla_sc", period)) - | (pip_daily & person("receives_enhanced_pip_dl", period)) + person("has_highest_dla_sc_award", period) + | person("has_enhanced_pip_dl_award", period) | afip ) weekly = p.disabled_child * disabled + p.enhanced_disabled_child * enhanced diff --git a/policyengine_uk/variables/gov/dwp/num_enhanced_disabled_claimants_or_partners_for_legacy_benefits.py b/policyengine_uk/variables/gov/dwp/num_enhanced_disabled_claimants_or_partners_for_legacy_benefits.py index 6b7428f74e..6ca2676bc6 100644 --- a/policyengine_uk/variables/gov/dwp/num_enhanced_disabled_claimants_or_partners_for_legacy_benefits.py +++ b/policyengine_uk/variables/gov/dwp/num_enhanced_disabled_claimants_or_partners_for_legacy_benefits.py @@ -6,18 +6,41 @@ class num_enhanced_disabled_claimants_or_partners_for_legacy_benefits(Variable): entity = BenUnit label = "Enhanced-disabled claimants or partners for legacy benefits" documentation = ( - "Claimants and partners satisfying the model's existing " - "is_enhanced_disabled_for_benefits indicator. This count excludes " - "children and young persons, whose separate enhanced premium is " - "not modelled here." + "The model counts the claimants and partners who meet the enhanced " + "disability premium condition: they receive a qualifying benefit " + "(receives_enhanced_disability_premium_qualifying_benefit) and have " + "not attained the qualifying age for State Pension Credit. Under the " + "Housing Benefit and Jobseeker's Allowance Regulations, the Welsh " + "Council Tax Reduction scheme and England's Default Scheme, the age " + "limit applies to the claimant and to family members or partners. " + "Parliament and the Northern Ireland Assembly limit Income Support to " + "claimants under that age (SSCBA 1992 s.124(1)(aa); SSCBA (NI) 1992 " + "s.123(1)(aa), inserted by the State Pension Credit Act (Northern " + "Ireland) 2002) and Employment and Support Allowance to claimants " + "under pensionable age (WRA 2007 s.1(3)(c); WRA (NI) 2007 " + "s.1(3)(c)), so their Regulations state the age limit only for the " + "partner. The count leaves out children and young " + "persons, whose separate enhanced premium the model computes for " + "Housing Benefit only (housing_benefit_child_disability_premiums)." ) definition_period = YEAR reference = ( - "https://www.legislation.gov.uk/uksi/1987/1967/schedule/2/paragraph/13A", "https://www.legislation.gov.uk/uksi/2006/213/schedule/3/paragraph/15", + "https://www.legislation.gov.uk/uksi/1987/1967/schedule/2/paragraph/13A", + "https://www.legislation.gov.uk/uksi/2008/794/schedule/4/paragraph/7", + "https://www.legislation.gov.uk/uksi/1996/207/schedule/1/paragraph/15A", + "https://www.legislation.gov.uk/nisr/2006/405/schedule/4/paragraph/15", + "https://www.legislation.gov.uk/wsi/2013/3029/schedule/7/paragraph/12", ) def formula(benunit, period, parameters): - claimant_or_partner = benunit.members("is_claimant_or_partner", period) - disabled = benunit.members("is_enhanced_disabled_for_benefits", period) - return benunit.sum(claimant_or_partner & disabled) + person = benunit.members + claimant_or_partner = person("is_claimant_or_partner", period) + qualifying = person( + "receives_enhanced_disability_premium_qualifying_benefit", period + ) + # "who has not attained the qualifying age for state pension credit" + # (HB Regs 2006 Sch 3 para 15(1)(b)-(d); IS Regs 1987 Sch 2 para + # 13A(1)(b)). + under_age = ~person("has_attained_state_pension_credit_qualifying_age", period) + return benunit.sum(claimant_or_partner & qualifying & under_age) diff --git a/policyengine_uk/variables/gov/dwp/pip/has_enhanced_pip_dl_award.py b/policyengine_uk/variables/gov/dwp/pip/has_enhanced_pip_dl_award.py new file mode 100644 index 0000000000..268c96c37d --- /dev/null +++ b/policyengine_uk/variables/gov/dwp/pip/has_enhanced_pip_dl_award.py @@ -0,0 +1,34 @@ +from policyengine_uk.model_api import * + + +class has_enhanced_pip_dl_award(Variable): + label = "Has an award of the PIP daily living component at the enhanced rate" + documentation = ( + "The model counts an award of the daily living component of personal " + "independence payment at the enhanced rate when the person has a " + "positive amount (pip_dl) and either the enhanced-rate category " + "(pip_dl_category) or an amount that reaches 52 × (enhanced weekly " + "rate − weekly tolerance), with the tolerance in " + "gov.dwp.disability_premia.top_rate_amount_tolerance. It rejects an amount of zero, including one that " + "a reform sets by neutralising pip_dl. Claimants also qualify when the " + "hospital in-patient rules end payment of the award (HB Regs 2006 Sch " + "3 para 15(1)(c)); the model has no input for that." + ) + entity = Person + definition_period = YEAR + value_type = bool + reference = ( + "https://www.legislation.gov.uk/uksi/2006/213/schedule/3/paragraph/15", + "https://www.legislation.gov.uk/uksi/1987/1967/schedule/2/paragraph/13A", + ) + + def formula(person, period, parameters): + p = parameters(period).gov.dwp + amount = person("pip_dl", period) + threshold = ( + p.pip.daily_living.enhanced - p.disability_premia.top_rate_amount_tolerance + ) * WEEKS_IN_YEAR + enhanced_rate = person("receives_enhanced_pip_dl", period) | ( + amount >= threshold + ) + return (amount > 0) & enhanced_rate diff --git a/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/council_tax_reduction_enhanced_disability_premium.py b/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/council_tax_reduction_enhanced_disability_premium.py new file mode 100644 index 0000000000..0f3afd3974 --- /dev/null +++ b/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/council_tax_reduction_enhanced_disability_premium.py @@ -0,0 +1,49 @@ +from policyengine_uk.model_api import * + + +class council_tax_reduction_enhanced_disability_premium(Variable): + value_type = float + entity = BenUnit + label = "Working-age CTR enhanced disability premium" + documentation = ( + "The model includes the enhanced disability premium in a working-age " + "Council Tax Reduction applicable amount at the single rate, or at the " + "couple rate where either or both members of a couple meet the " + "scheme's condition " + "(meets_council_tax_reduction_enhanced_disability_premium_condition). " + "It pays a different premium from the legacy one " + "(enhanced_disability_premium) in Scotland, Merton, Newham and " + "Westminster, where the scheme counts its own awards, and in Kingston " + "upon Thames, where the model reads is_enhanced_disabled_for_benefits " + "with no age limit. " + "This variable pays the Housing Benefit amounts in every scheme; " + "Scotland's and Wales's working-age awards read only whether it is " + "payable and pay their own amounts " + "(council_tax_reduction_working_age_adult_premiums). Both 2026-27 " + "editions of Kingston upon Thames's scheme print £17.10 single and " + "£24.50 couple (Sch 3 para 17(5)), and no decision the model cites " + "sets Kingston's own 2026-27 amounts (issue #2881). Pension-age " + "Council Tax Reduction includes no adult enhanced disability premium." + ) + definition_period = YEAR + unit = GBP + reference = ( + "https://www.legislation.gov.uk/ssi/2021/249/schedule/1/paragraph/14", + "https://www.legislation.gov.uk/wsi/2013/3029/schedule/7/paragraph/12", + "https://www.legislation.gov.uk/uksi/2006/213/schedule/3/part/4", + ) + + def formula(benunit, period, parameters): + dis = parameters(period).gov.dwp.disability_premia + person = benunit.members + qualifies = benunit.any( + person("is_claimant_or_partner", period) + & person( + "meets_council_tax_reduction_enhanced_disability_premium_condition", + period, + ) + ) + single = benunit("is_single", period.this_year) + couple = benunit("is_couple", period.this_year) + weekly_amount = single * dis.enhanced_single + couple * dis.enhanced_couple + return weekly_amount * WEEKS_IN_YEAR * qualifies diff --git a/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/council_tax_reduction_premiums.py b/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/council_tax_reduction_premiums.py index d6bc318621..912f2d7b63 100644 --- a/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/council_tax_reduction_premiums.py +++ b/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/council_tax_reduction_premiums.py @@ -15,8 +15,10 @@ class council_tax_reduction_premiums(Variable): "working_age_benefits_premiums). Where the household head applies " "alone (council_tax_reduction_head_applies_alone), they are the " "premiums of a single claimant on the head's own circumstances, under " - "the same conditions: the disability and enhanced disability premiums " - "on her own disability (working age only); the severe disability " + "the same conditions: the disability premium on her own disability and " + "the enhanced disability premium on the scheme's condition " + "(meets_council_tax_reduction_enhanced_disability_premium_condition), " + "both working age only; the severe disability " "premium if she receives a qualifying benefit, no carer benefit is " "paid for caring for her, and no other resident aged 18 or over is " "her non-dependant (everyone else in the household, since she has no " @@ -46,7 +48,9 @@ def formula(benunit, period, parameters): pensioner = benunit("council_tax_reduction_pensioner", period) # The working-age severe disability premium takes Council Tax # Reduction's own family test (council_tax_reduction_severe_disability_ - # premium, which differs from the shared premium in Scotland). + # premium, which differs from the shared premium in Scotland), and the + # enhanced disability premium the scheme's own condition + # (council_tax_reduction_enhanced_disability_premium). benefit_unit_premiums = where( pensioner, benunit("pension_age_benefits_premiums", period), @@ -54,6 +58,10 @@ def formula(benunit, period, parameters): + ( benunit("council_tax_reduction_severe_disability_premium", period) - benunit("severe_disability_premium", period) + ) + + ( + benunit("council_tax_reduction_enhanced_disability_premium", period) + - benunit("enhanced_disability_premium", period) ), ) head_applies_alone = benunit("council_tax_reduction_head_applies_alone", period) @@ -94,7 +102,12 @@ def head_has(condition): disability_premiums = ~pensioner * ( head_has(person("is_disabled_for_benefits", period)) * disability.disability_single - + head_has(person("is_enhanced_disabled_for_benefits", period)) + + head_has( + person( + "meets_council_tax_reduction_enhanced_disability_premium_condition", + period, + ) + ) * disability.enhanced_single ) head_premiums = (disability_premiums + severe + carer_premium) * WEEKS_IN_YEAR diff --git a/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/meets_council_tax_reduction_enhanced_disability_premium_condition.py b/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/meets_council_tax_reduction_enhanced_disability_premium_condition.py new file mode 100644 index 0000000000..a5b7fb6a0f --- /dev/null +++ b/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/meets_council_tax_reduction_enhanced_disability_premium_condition.py @@ -0,0 +1,101 @@ +from policyengine_uk.model_api import * +from policyengine_uk.variables.gov.local_authorities.council_tax_reduction.config import ( + is_kingston_upon_thames_area, + is_merton_area, + is_newham_area, + is_scotland_scheme, + is_westminster_area, +) + + +class meets_council_tax_reduction_enhanced_disability_premium_condition(Variable): + value_type = bool + entity = Person + label = "Meets the working-age CTR enhanced disability premium condition" + documentation = ( + "The model checks whether this person, as an applicant or partner, " + "meets the enhanced disability premium condition of the working-age " + "Council Tax Reduction scheme that covers their household. Scottish " + "councils count attendance allowance at either rate from 1 April " + "2023, and the Scottish Ministers removed the age limit from 20 June " + "2022. Merton counts the PIP daily living component at either rate " + "and omits armed forces independence payment; Newham counts the PIP " + "daily living component at either rate and armed forces independence " + "payment. In Westminster the model applies " + "the Default Scheme's list (S.I. 2012/2886 Sch 3 para 12), which " + "counts the PIP daily living component at either rate and omits armed " + "forces independence payment: the council has approved the same " + "scheme, based on the Default Scheme Regulations, since 2013/14, and " + "its Cabinet says from December 2020 that its local scheme mirrors " + "those Regulations, though the model cites no full Westminster scheme " + "text. Those three councils count an award only for a person under the " + "qualifying age for State Pension Credit, and their lists start on or " + "before 1 April 2013 and apply in every model year. In Kingston upon " + "Thames the model reads is_enhanced_disabled_for_benefits, with no age " + "limit; that variable's documentation says what sets it. The council's " + "texts from 2023-24 print a wider list with an age limit (Sch 3 para " + "12), and issue #2881 lists what the model needs to apply it. In " + "every other scheme the model applies the Housing Benefit condition " + "(receives_enhanced_disability_premium_qualifying_benefit, under the " + "same age limit). Welsh councils apply that condition under W.S.I. " + "2013/3029 Sch 7 para 12. Oxford City Council sets its working-age " + "award from income bands, so the premium does not reach it." + ) + definition_period = YEAR + reference = ( + "https://www.legislation.gov.uk/ssi/2021/249/schedule/1/paragraph/14", + "https://www.legislation.gov.uk/ssi/2012/303/schedule/1/paragraph/12/2021-04-01", + "https://www.legislation.gov.uk/wsi/2013/3029/schedule/7/paragraph/12", + "https://web.archive.org/web/20150530202253id_/http://www.merton.gov.uk/council_tax_reduction_scheme_l_b_merton_april_2013_with_uprated_amounts_final_310113-2.pdf", + "https://www.merton.gov.uk/system/files/Council%20Tax%20Reduction%20Scheme%20L%20B%20Merton%202023-24_0.pdf", + "https://www.merton.gov.uk/sites/default/files/2026-03/Council%20Tax%20Reduction%20Scheme%20L%20B%20Merton%202026-27.pdf", + "https://www.legislation.gov.uk/uksi/2012/2886/appendix/3/regulation/12/made", + "https://www.kingston.gov.uk/sites/default/files/2026-03/Council%20Tax%20Reduction%20Scheme%202026%20-%202027.pdf", + "https://mgov.newham.gov.uk/documents/s74450/Appendix%201%20-%20LB%20Newham%20Local%20CTR%20Scheme_16_01_13.pdf", + "https://www.newham.gov.uk/downloads/file/10753/council-tax-reduction-scheme-2026", + "https://web.archive.org/web/20240621074656id_/https://committees.westminster.gov.uk/documents/s40219/Report%20of%20the%20Cabinet%2014%20December%202020%20-Council%20Tax%20Discounts.pdf", + "https://committees.westminster.gov.uk/mgAi.aspx?ID=22982", + "https://www.westminster.gov.uk/sites/default/files/media/documents/business-and-financial-planning-2026-27-to-2028-29.pdf", + "https://committees.westminster.gov.uk/ieDecisionDetails.aspx?ID=1181", + ) + + def formula(person, period, parameters): + la = parameters(period).gov.local_authorities + household = person.household + country = household("country", period) + local_authority = household("local_authority", period) + under_age = ~person("has_attained_state_pension_credit_qualifying_age", period) + + def receives(benefits): + return add(person, period, benefits) > 0 + + housing_benefit = ( + person("receives_enhanced_disability_premium_qualifying_benefit", period) + & under_age + ) + + def council_condition(council): + p = council.council_tax_reduction.enhanced_disability_premium + return receives(p.qualifying_benefits) & under_age + + p = la.scotland.council_tax_reduction.working_age.enhanced_disability_premium + scottish = receives(p.qualifying_benefits) & ( + under_age | (not p.age_limit_applies) + ) + return select( + [ + is_scotland_scheme(country), + is_merton_area(local_authority, country), + is_kingston_upon_thames_area(local_authority, country), + is_newham_area(local_authority, country), + is_westminster_area(local_authority, country), + ], + [ + scottish, + council_condition(la.merton), + person("is_enhanced_disabled_for_benefits", period), + council_condition(la.newham), + council_condition(la.westminster), + ], + default=housing_benefit, + ) diff --git a/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/working_age/_applicant.py b/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/working_age/_applicant.py index a244de2cd3..df967451ce 100644 --- a/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/working_age/_applicant.py +++ b/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/working_age/_applicant.py @@ -48,15 +48,16 @@ def working_age_adult_premium_conditions(benunit, period, parameters): disability and severe disability premiums, and whether the severe disability premium is at the double rate. - Who qualifies follows the model's legacy premium variables, with Council - Tax Reduction's own severe disability premium family test - (council_tax_reduction_severe_disability_premium). Where the household - head applies alone, the conditions are the head's own as a single person, - as in council_tax_reduction_premiums. + Who qualifies follows the model's legacy disability premium, with Council + Tax Reduction's own enhanced disability premium condition + (council_tax_reduction_enhanced_disability_premium) and severe disability + premium family test (council_tax_reduction_severe_disability_premium). + Where the household head applies alone, the conditions are the head's own + as a single person, as in council_tax_reduction_premiums. """ dwp = parameters(period).gov.dwp.disability_premia disability = benunit("disability_premium", period) > 0 - enhanced = benunit("enhanced_disability_premium", period) > 0 + enhanced = benunit("council_tax_reduction_enhanced_disability_premium", period) > 0 severe_weekly = ( benunit("council_tax_reduction_severe_disability_premium", period) / WEEKS_IN_YEAR @@ -99,7 +100,12 @@ def head_has(condition): ), where( head_applies_alone, - head_has(person("is_enhanced_disabled_for_benefits", period)), + head_has( + person( + "meets_council_tax_reduction_enhanced_disability_premium_condition", + period, + ) + ), enhanced, ), where(head_applies_alone, head_severe, severe), diff --git a/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/working_age/council_tax_reduction_working_age_adult_premiums.py b/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/working_age/council_tax_reduction_working_age_adult_premiums.py index 4ac8bbbe35..be6b4cb75f 100644 --- a/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/working_age/council_tax_reduction_working_age_adult_premiums.py +++ b/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/working_age/council_tax_reduction_working_age_adult_premiums.py @@ -16,8 +16,9 @@ class council_tax_reduction_working_age_adult_premiums(Variable): "Annual disability, severe disability, enhanced disability and carer " "premiums in a working-age applicable amount in Scotland or Wales, at " "each country's own amounts. Who qualifies follows the model's " - "legacy-benefit premium variables (disability_premium, " - "enhanced_disability_premium) and Council Tax Reduction's own severe " + "legacy-benefit disability premium (disability_premium) and Council " + "Tax Reduction's own enhanced disability premium condition " + "(council_tax_reduction_enhanced_disability_premium) and severe " "disability premium test (council_tax_reduction_severe_disability_" "premium), including whether that premium is at the single or couple " "rate; where the household head applies alone, the conditions are her " diff --git a/policyengine_uk/variables/household/demographic/enhanced_disability_premium.py b/policyengine_uk/variables/household/demographic/enhanced_disability_premium.py index 296ab7b49e..aecfcfecff 100644 --- a/policyengine_uk/variables/household/demographic/enhanced_disability_premium.py +++ b/policyengine_uk/variables/household/demographic/enhanced_disability_premium.py @@ -6,15 +6,22 @@ class enhanced_disability_premium(Variable): entity = BenUnit label = "Enhanced disability premium" documentation = ( - "Legacy benefit enhanced disability premium for the claimant or " - "partner, using the model's existing enhanced-disability indicator. " - "The separate Housing Benefit enhanced rate for children and young " - "persons is not modelled here." + "The model pays the legacy benefit enhanced disability premium for " + "the claimant or partner at the single rate, or at the couple rate " + "where either or both members of a couple meet the condition " + "(num_enhanced_disabled_claimants_or_partners_for_legacy_benefits). " + "The model's Housing Benefit, Income Support and Council Tax " + "Reduction applicable amounts read it, and Council Tax Reduction " + "replaces it with its own scheme's premium " + "(council_tax_reduction_enhanced_disability_premium). " + "housing_benefit_child_disability_premiums computes Housing Benefit's " + "separate enhanced rate for children and young persons." ) definition_period = YEAR reference = ( "https://www.legislation.gov.uk/uksi/1987/1967/schedule/2/paragraph/13A", "https://www.legislation.gov.uk/uksi/2006/213/schedule/3/paragraph/15", + "https://www.legislation.gov.uk/uksi/2006/213/schedule/3/part/4", ) unit = GBP diff --git a/policyengine_uk/variables/household/demographic/is_enhanced_disabled_for_benefits.py b/policyengine_uk/variables/household/demographic/is_enhanced_disabled_for_benefits.py index 7782b4ca94..273ec67b76 100644 --- a/policyengine_uk/variables/household/demographic/is_enhanced_disabled_for_benefits.py +++ b/policyengine_uk/variables/household/demographic/is_enhanced_disabled_for_benefits.py @@ -5,6 +5,22 @@ class is_enhanced_disabled_for_benefits(Variable): value_type = bool entity = Person label = "Whether meets the middle disability benefit entitlement" + documentation = ( + "The model reads this flag for the enhanced disability premium in " + "Kingston upon Thames's working-age Council Tax Reduction, with no age " + "limit (meets_council_tax_reduction_enhanced_disability_premium_condition), " + "and in the deprecated counts num_enhanced_disabled_adults and " + "num_enhanced_disabled_children. No other premium reads it. The formula " + "holds where DLA care reaches 52 times the highest weekly rate. " + "policyengine-uk-data stores its own value of this flag in the Enhanced " + "FRS, and the model uses that value in place of the formula in dataset " + "runs. The stored flag holds where reported attendance allowance " + "reaches the higher weekly rate less £1, reported disability living " + "allowance care exceeds the highest weekly rate less £1, or reported " + "personal independence payment daily living reaches the enhanced weekly " + "rate less £1. Issue #2881 lists what the model needs to apply Kingston " + "upon Thames's own list." + ) definition_period = YEAR def formula(person, period, parameters): diff --git a/policyengine_uk/variables/household/demographic/receives_enhanced_disability_premium_qualifying_benefit.py b/policyengine_uk/variables/household/demographic/receives_enhanced_disability_premium_qualifying_benefit.py new file mode 100644 index 0000000000..e955416fbb --- /dev/null +++ b/policyengine_uk/variables/household/demographic/receives_enhanced_disability_premium_qualifying_benefit.py @@ -0,0 +1,55 @@ +from policyengine_uk.model_api import * + + +class receives_enhanced_disability_premium_qualifying_benefit(Variable): + value_type = bool + entity = Person + label = "Receives an enhanced disability premium qualifying benefit" + documentation = ( + "The model counts a person as receiving a qualifying benefit for the " + "legacy enhanced disability premium when they have an award of the " + "care component of disability living allowance at the highest rate " + "(has_highest_dla_sc_award), the daily living component of personal " + "independence payment at the enhanced rate (has_enhanced_pip_dl_award) " + "or armed forces independence payment. It counts only positive " + "amounts, and takes the rate from the award category or, for an " + "amount entered without its category, from the amount. The model " + "applies each programme's further conditions elsewhere: the age limit " + "(num_enhanced_disabled_claimants_or_partners_for_legacy_benefits) " + "and, in Council Tax Reduction, the scheme's own list " + "(meets_council_tax_reduction_enhanced_disability_premium_condition). " + "Attendance allowance does not qualify. The model has no separate " + "variables for the Scottish equivalents (the care components of child " + "disability payment and Scottish adult disability living allowance at " + "the highest rate, and the daily living component of adult disability " + "payment at the enhanced rate). It omits the limited capability for " + "work-related activity limb (Housing Benefit), the support component " + "limb (Employment and Support Allowance), the hospital rules and the " + "long-term patient exclusion. The model reads the Northern Ireland " + "list for households in Northern Ireland and the Great Britain list " + "elsewhere. Claimants in Northern Ireland qualify through armed forces " + "independence payment from 24 December 2013 and through PIP daily " + "living from 20 June 2016, and claimants in Great Britain through both " + "from 8 April 2013. The model reads each list as at 30 April of the " + "year from 2015, without within-year proration." + ) + definition_period = YEAR + reference = ( + "https://www.legislation.gov.uk/uksi/2006/213/schedule/3/paragraph/15", + "https://www.legislation.gov.uk/uksi/1987/1967/schedule/2/paragraph/13A", + "https://www.legislation.gov.uk/uksi/2008/794/schedule/4/paragraph/7", + "https://www.legislation.gov.uk/uksi/1996/207/schedule/1/paragraph/15A", + "https://www.legislation.gov.uk/nisr/2006/405/schedule/4/paragraph/15", + "https://www.legislation.gov.uk/nisr/2008/280/schedule/4/paragraph/7", + "https://www.legislation.gov.uk/wsi/2013/3029/schedule/7/paragraph/12", + ) + + def formula(person, period, parameters): + p = parameters(period).gov.dwp.disability_premia + country = person.household("country", period) + northern_ireland = country == country.possible_values.NORTHERN_IRELAND + return where( + northern_ireland, + add(person, period, p.enhanced_qualifying_benefits_northern_ireland) > 0, + add(person, period, p.enhanced_qualifying_benefits) > 0, + )