From 54a4db743c8d373b3e7dd8b1ee008c4a77f538df Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Wed, 30 Sep 2026 08:26:36 -0400 Subject: [PATCH 1/9] Fix Care to Learn, extended childcare, maintenance loan and Tax-Free Childcare legal gaps - Care to Learn: pay each qualifying child's childcare costs up to the ESFA weekly maximum per child, once per child, and only to young parents on a study programme. - Extended childcare: add the SI 2022/1134 reg 13 young-child condition and the reg 14(4)/15(4) route for a parent or partner with limited capability for work or a specified benefit; fix the reg 18 and reg 14(3)(c) boundaries. - Maintenance loans: add the Sch 4 para 2(1)(a) age-25 independence test to the dependent-student proxy. - Tax-Free Childcare: use the SI 2015/448 reg 13(1) benefit list and deem the reg 13(2)(b) minimum income. Co-Authored-By: Claude Opus 5.5 --- ...fe-childcare-student-support-gaps.fixed.md | 4 + .../gov/dfe/care_to_learn/amount.yaml | 16 +- .../disability_criteria.yaml | 33 ++- .../income/limit.yaml | 6 +- .../minimum_weekly_hours.yaml | 6 +- .../young_child_minimum_age.yaml | 18 ++ .../independent_student_age.yaml | 12 + .../caring_or_incapacity_benefits.yaml | 36 +++ .../gov/dfe/care_to_learn/care_to_learn.yaml | 190 ++++++++++++- .../care_to_learn/care_to_learn_eligible.yaml | 24 ++ .../extended_childcare_entitlement.yaml | 21 +- ...tended_childcare_entitlement_eligible.yaml | 260 +++++++++++++---- ...hildcare_entitlement_income_condition.yaml | 48 +++- ..._childcare_entitlement_work_condition.yaml | 261 +++++++++++++++--- .../maintenance_loans/maintenance_loan.yaml | 58 ++++ .../tax_free_childcare_eligibility.yaml | 77 ++++++ .../tax_free_childcare_income_condition.yaml | 66 +++++ .../tax_free_childcare_work_condition.yaml | 198 ++++++++++++- .../gov/dfe/care_to_learn/care_to_learn.py | 35 ++- .../care_to_learn/care_to_learn_eligible.py | 24 +- .../care_to_learn_qualifying_child.py | 24 ++ ...limited_capability_or_specified_benefit.py | 45 +++ ...e_entitlement_meets_income_requirements.py | 23 +- ...ed_childcare_entitlement_work_condition.py | 89 +++--- .../extended_childcare_entitlement.py | 10 +- ...extended_childcare_entitlement_eligible.py | 35 +-- ..._childcare_entitlement_qualifying_child.py | 50 ++++ .../is_child_receiving_extended_childcare.py | 11 +- .../maintenance_loan_household_income.py | 12 +- ...ves_limited_capability_for_work_credits.py | 18 ++ ..._childcare_caring_or_incapacity_benefit.py | 23 ++ ...ree_childcare_meets_income_requirements.py | 16 +- .../tax_free_childcare_on_carers_leave.py | 16 ++ ...free_childcare_regarded_as_in_paid_work.py | 40 +++ .../tax_free_childcare_work_condition.py | 62 +---- 35 files changed, 1597 insertions(+), 270 deletions(-) create mode 100644 changelog.d/dfe-childcare-student-support-gaps.fixed.md create mode 100644 policyengine_uk/parameters/gov/dfe/extended_childcare_entitlement/young_child_minimum_age.yaml create mode 100644 policyengine_uk/parameters/gov/dfe/maintenance_loans/independent_student_age.yaml create mode 100644 policyengine_uk/parameters/gov/hmrc/tax_free_childcare/caring_or_incapacity_benefits.yaml create mode 100644 policyengine_uk/variables/gov/dfe/care_to_learn/care_to_learn_qualifying_child.py create mode 100644 policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/conditions/extended_childcare_entitlement_limited_capability_or_specified_benefit.py create mode 100644 policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement_qualifying_child.py create mode 100644 policyengine_uk/variables/gov/dwp/receives_limited_capability_for_work_credits.py create mode 100644 policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_caring_or_incapacity_benefit.py create mode 100644 policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_on_carers_leave.py create mode 100644 policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_regarded_as_in_paid_work.py diff --git a/changelog.d/dfe-childcare-student-support-gaps.fixed.md b/changelog.d/dfe-childcare-student-support-gaps.fixed.md new file mode 100644 index 0000000000..1c5898ff2a --- /dev/null +++ b/changelog.d/dfe-childcare-student-support-gaps.fixed.md @@ -0,0 +1,4 @@ +- Care to Learn pays each qualifying child's childcare costs up to the weekly maximum per child, once per child, and only to young parents on a study programme (ESFA conditions of grant 2026-27). +- The extended childcare entitlement requires a qualifying young child (SI 2022/1134 reg 13: aged three, two from April 2024, nine months from September 2024), and lets a parent or partner with limited capability for work or a specified benefit qualify without the work and income tests when the other meets them (regs 14(4) and 15(4)). The income test's boundaries now match regs 14(3)(c) and 18. +- Maintenance loan household income treats students aged 25 or over as independent (Education (Student Support) Regulations 2011 Sch 4 para 2(1)(a)). +- Tax-Free Childcare's caring and incapacity route uses the benefits in SI 2015/448 reg 13(1), not the Pension Credit child disability list, and treats a qualifying partner as meeting the minimum income (reg 13(2)(b)). diff --git a/policyengine_uk/parameters/gov/dfe/care_to_learn/amount.yaml b/policyengine_uk/parameters/gov/dfe/care_to_learn/amount.yaml index 12ca54e32a..7fd191166c 100644 --- a/policyengine_uk/parameters/gov/dfe/care_to_learn/amount.yaml +++ b/policyengine_uk/parameters/gov/dfe/care_to_learn/amount.yaml @@ -1,12 +1,14 @@ -description: The Department for Education provides this amount of financial support through the Care to Learn scheme. +description: The Department for Education pays up to this weekly amount per child through the Care to Learn scheme, towards childcare and travel costs. in_london: - description: The Department for Education provides this amount of financial support through the Care to Learn scheme for those living in London. + description: The Department for Education pays up to this weekly amount per child through the Care to Learn scheme, towards childcare and travel costs, for young parents whose home address is in London. metadata: unit: currency-GBP period: week label: Maximum weekly amount per child in London reference: - - title: Documentation for Care to Learn scheme + - title: ESFA, Care to Learn 2026 to 2027 academic year conditions of grant funding, sections 2.2 and 4.1 + href: https://www.gov.uk/government/publications/care-to-learn-conditions-of-grant-funding/care-to-learn-academic-year-2026-to-2027-conditions-of-grant-funding + - title: Documentation for Care to Learn scheme href: https://www.gov.uk/care-to-learn - title: House of Commons Library – Paying for Childcare in England (12 July 2024) href: https://researchbriefings.files.parliament.uk/documents/CBP-8054/CBP-8054.pdf#page=43 @@ -14,15 +16,17 @@ in_london: 2024-01-01: 195 outside_london: - description: The Department for Education provides this amount of financial support through the Care to Learn scheme for those living outside London. + description: The Department for Education pays up to this weekly amount per child through the Care to Learn scheme, towards childcare and travel costs, for young parents whose home address is outside London. metadata: unit: currency-GBP period: week label: Maximum weekly amount per child outside London reference: - - title: Documentation for Care to Learn scheme + - title: ESFA, Care to Learn 2026 to 2027 academic year conditions of grant funding, sections 2.2 and 4.1 + href: https://www.gov.uk/government/publications/care-to-learn-conditions-of-grant-funding/care-to-learn-academic-year-2026-to-2027-conditions-of-grant-funding + - title: Documentation for Care to Learn scheme href: https://www.gov.uk/care-to-learn - title: House of Commons Library – Paying for Childcare in England (12 July 2024) href: https://researchbriefings.files.parliament.uk/documents/CBP-8054/CBP-8054.pdf#page=43 values: - 2024-01-01: 180 \ No newline at end of file + 2024-01-01: 180 diff --git a/policyengine_uk/parameters/gov/dfe/extended_childcare_entitlement/disability_criteria.yaml b/policyengine_uk/parameters/gov/dfe/extended_childcare_entitlement/disability_criteria.yaml index ad83f0f8ca..9ebcc5d7c2 100644 --- a/policyengine_uk/parameters/gov/dfe/extended_childcare_entitlement/disability_criteria.yaml +++ b/policyengine_uk/parameters/gov/dfe/extended_childcare_entitlement/disability_criteria.yaml @@ -1,15 +1,34 @@ -description: The Department for Education exempts participants in these programs from work requirements of extended childcare entitlement. +description: The Department for Education lets a parent or partner who has limited capability for work or receives one of these benefits meet the extended childcare entitlement conditions without working, when the other member of the couple works. metadata: reference: - - title: The Childcare Regulations 2022 - Regulation 11A + - title: The Childcare (Free of Charge for Working Parents) (England) Regulations 2016 - Regulation 9(1)(b) + href: https://www.legislation.gov.uk/uksi/2016/1257/regulation/9/made + - title: The Childcare (Free of Charge for Working Parents) (England) Regulations 2022 - Regulations 14(4) and 15(4) + href: https://www.legislation.gov.uk/uksi/2022/1134/regulation/14 + - title: The Childcare (Free of Charge for Working Parents) (England) Regulations 2022 - Regulation 11A href: https://www.legislation.gov.uk/uksi/2022/1134/regulation/11A period: year unit: program label: Extended childcare entitlement disability criteria values: + # SI 2016/1257 reg 9(1)(b). 2015-09-01: - - carers_allowance # 11A(1)(a): Carer's allowance under Section 70 of Social Security Contributions and Benefits Act 1992 - - uc_carer_element # 11A(1)(c): Universal Credit carer element under Regulation 29 of the Universal Credit Regulations 2013 - - esa_contrib # 11A(1)(e): Employment and support allowance under Welfare Reform Act 2007 - - incapacity_benefit # 11A(1)(g): Long-term or short-term incapacity benefit under Social Security Contributions and Benefits Act - - sda # 11A(1)(h): Severe disablement allowance under Section 68 of Social Security Contributions and Benefits Act + - incapacity_benefit # (i) and (iii): incapacity benefit and long-term incapacity benefit + - sda # (ii): severe disablement allowance + - carers_allowance # (iv): carer's allowance + - esa_contrib # (v): contributory employment and support allowance + - receives_limited_capability_for_work_credits # (vi): credits for incapacity for work or limited capability for work + - uc_carer_element # (vii): Universal Credit carer element + - uc_limited_capability_for_WRA # (viii): limited capability for work and work-related activity + # SI 2022/1134 reg 14(4)(b) and the specified benefits in reg 14(5) as made, + # moved to reg 11A from 30 March 2023 by SI 2023/276. + 2022-12-01: + - uc_limited_capability_for_WRA # 14(4)(b)(i)-(ii): limited capability for work, or for work and work-related activity + - carers_allowance # 11A(1)(a): carer's allowance + - carer_support_payment # 11A(1)(b): carer's assistance under the Social Security (Scotland) Act 2018 s.28 + - uc_carer_element # 11A(1)(c): Universal Credit carer element + - receives_limited_capability_for_work_credits # 11A(1)(d): credits for incapacity for work or limited capability for work + - esa_contrib # 11A(1)(e): employment and support allowance (contribution-based) + - esa_income # 11A(1)(e): employment and support allowance (income-related) + - incapacity_benefit # 11A(1)(f)-(g): long-term, short-term and transitional incapacity benefit + - sda # 11A(1)(h): severe disablement allowance diff --git a/policyengine_uk/parameters/gov/dfe/extended_childcare_entitlement/income/limit.yaml b/policyengine_uk/parameters/gov/dfe/extended_childcare_entitlement/income/limit.yaml index 8789e42823..119f81d30c 100644 --- a/policyengine_uk/parameters/gov/dfe/extended_childcare_entitlement/income/limit.yaml +++ b/policyengine_uk/parameters/gov/dfe/extended_childcare_entitlement/income/limit.yaml @@ -1,10 +1,12 @@ -description: The Department for Education limits extended childcare entitlement eligibility to households where each parent's individual income is less than this amount. +description: The Department for Education limits the extended childcare entitlement to parents and partners whose adjusted net income does not exceed this amount. metadata: unit: currency-GBP period: year label: Extended childcare entitlement individual income limit reference: + - title: The Childcare (Free of Charge for Working Parents) (England) Regulations 2022 - Regulations 14(3)(c)(i) and 15(3)(b)(i) + href: https://www.legislation.gov.uk/uksi/2022/1134/regulation/14 - title: The Childcare Payments (Eligibility) Regulations 2015 - Regulation 15 href: https://www.legislation.gov.uk/uksi/2015/448/regulation/15#commentary-key-e27c923eee152accd495af8425536e29 values: - 2015-01-01: 100_000 \ No newline at end of file + 2015-01-01: 100_000 diff --git a/policyengine_uk/parameters/gov/dfe/extended_childcare_entitlement/minimum_weekly_hours.yaml b/policyengine_uk/parameters/gov/dfe/extended_childcare_entitlement/minimum_weekly_hours.yaml index a76e767f29..93f24924d3 100644 --- a/policyengine_uk/parameters/gov/dfe/extended_childcare_entitlement/minimum_weekly_hours.yaml +++ b/policyengine_uk/parameters/gov/dfe/extended_childcare_entitlement/minimum_weekly_hours.yaml @@ -1,10 +1,12 @@ -description: The Department for Education limits extended childcare entitlement to benefit units in which each spouse earns at least the product of their minimum wage and this number of hours per week. +description: The Department for Education limits extended childcare entitlement to parents and partners who expect to earn at least the product of their minimum wage and this number of hours per week. metadata: period: year unit: hour label: Extended childcare entitlement weekly work hours minimum reference: + - title: The Childcare (Free of Charge for Working Parents) (England) Regulations 2022 - Regulation 18(3) ("minimum weekly income") + href: https://www.legislation.gov.uk/uksi/2022/1134/regulation/18 - title: The Childcare Payments (Eligibility) (Amendment) Regulations 2016 - regulation 3 href: https://www.legislation.gov.uk/uksi/2016/793/regulation/3/made values: - 2016-01-01: 16 \ No newline at end of file + 2016-01-01: 16 diff --git a/policyengine_uk/parameters/gov/dfe/extended_childcare_entitlement/young_child_minimum_age.yaml b/policyengine_uk/parameters/gov/dfe/extended_childcare_entitlement/young_child_minimum_age.yaml new file mode 100644 index 0000000000..eec4ef3871 --- /dev/null +++ b/policyengine_uk/parameters/gov/dfe/extended_childcare_entitlement/young_child_minimum_age.yaml @@ -0,0 +1,18 @@ +description: The Department for Education limits the extended childcare entitlement to young children who have reached this age. +metadata: + unit: year + period: year + label: Extended childcare entitlement young child minimum age + reference: + - title: The Childcare (Free of Charge for Working Parents) (England) Regulations 2016, regulation 3(1)(a) + href: https://www.legislation.gov.uk/uksi/2016/1257/regulation/3/made + - title: The Childcare (Free of Charge for Working Parents) (England) Regulations 2022, regulation 13(2)(a) + href: https://www.legislation.gov.uk/uksi/2022/1134/regulation/13 + - title: The Childcare (Free of Charge for Working Parents) (England) (Amendment and Transitional Provision) Regulations 2023, regulation 2(5) + href: https://www.legislation.gov.uk/uksi/2023/1330/regulation/2/made +values: + 2015-01-01: 3 + # SI 2023/1330 reg 2(5)(a): "two" from 1 April 2024 to 31 August 2024. + 2024-04-01: 2 + # SI 2023/1330 reg 2(5)(b): "nine months" from 1 September 2024. + 2024-09-01: 0.75 diff --git a/policyengine_uk/parameters/gov/dfe/maintenance_loans/independent_student_age.yaml b/policyengine_uk/parameters/gov/dfe/maintenance_loans/independent_student_age.yaml new file mode 100644 index 0000000000..c35b69817c --- /dev/null +++ b/policyengine_uk/parameters/gov/dfe/maintenance_loans/independent_student_age.yaml @@ -0,0 +1,12 @@ +description: Student Finance England treats a student who is at least this age on the first day of the academic year as independent, so it assesses their household income without their parents' income. +metadata: + unit: year + period: year + label: Maintenance loan independent student age + reference: + - title: The Education (Student Support) Regulations 2011 - Schedule 4, paragraph 2(1)(a) + href: https://www.legislation.gov.uk/uksi/2011/1986/schedule/4 +values: + # SI 2011/1986 reg 1(3): applies to academic years beginning on or after + # 1 September 2012. + 2012-09-01: 25 diff --git a/policyengine_uk/parameters/gov/hmrc/tax_free_childcare/caring_or_incapacity_benefits.yaml b/policyengine_uk/parameters/gov/hmrc/tax_free_childcare/caring_or_incapacity_benefits.yaml new file mode 100644 index 0000000000..c5e84d0680 --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/tax_free_childcare/caring_or_incapacity_benefits.yaml @@ -0,0 +1,36 @@ +description: HMRC regards a person whose partner is in qualifying paid work as in qualifying paid work themselves, for Tax-Free Childcare, while they receive or are entitled to any of these benefits, allowances or credits, or are on carer's leave. +metadata: + reference: + - title: The Childcare Payments (Eligibility) Regulations 2015 - Regulation 13(1) + href: https://www.legislation.gov.uk/uksi/2015/448/regulation/13 + - title: The Childcare Payments (Miscellaneous Amendments) Regulations 2022 - Regulation 2(6) + href: https://www.legislation.gov.uk/uksi/2022/1148/regulation/2/made + - title: The Carer's Leave (Consequential Amendments to Subordinate Legislation) Regulations 2024 - Regulation 8(2) + href: https://www.legislation.gov.uk/uksi/2024/266/regulation/8/made + period: year + unit: program + label: Tax-Free Childcare caring or incapacity benefits +values: + 2015-01-01: + - incapacity_benefit # 13(1)(b)(i) and (iii): incapacity benefit and long-term incapacity benefit + - sda # 13(1)(b)(ii): severe disablement allowance + - carers_allowance # 13(1)(b)(iv): carer's allowance + - esa_contrib # 13(1)(b)(v): contributory employment and support allowance + - receives_limited_capability_for_work_credits # 13(1)(b)(vi): credits for incapacity or limited capability for work + # SI 2022/1148 reg 2(6)(b) inserted 13(1)(b)(vii) from 1 December 2022. + 2022-12-01: + - incapacity_benefit + - sda + - carers_allowance + - esa_contrib + - receives_limited_capability_for_work_credits + - carer_support_payment # 13(1)(b)(vii): carer's assistance under the Social Security (Scotland) Act 2018 s.28 + # SI 2024/266 reg 8(2) inserted 13(1)(c) from 6 April 2024. + 2024-04-06: + - incapacity_benefit + - sda + - carers_allowance + - esa_contrib + - receives_limited_capability_for_work_credits + - carer_support_payment + - tax_free_childcare_on_carers_leave # 13(1)(c): carer's leave under the Employment Rights Act 1996 s.80J diff --git a/policyengine_uk/tests/policy/baseline/gov/dfe/care_to_learn/care_to_learn.yaml b/policyengine_uk/tests/policy/baseline/gov/dfe/care_to_learn/care_to_learn.yaml index 63aa0c9e4c..ef686ae6cd 100644 --- a/policyengine_uk/tests/policy/baseline/gov/dfe/care_to_learn/care_to_learn.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/dfe/care_to_learn/care_to_learn.yaml @@ -1,18 +1,184 @@ -- name: Care to Learn amount - Outside London - period: 2024 +# Care to Learn pays childcare costs up to £180 per child per week outside +# London and £195 per child per week in London (ESFA Care to Learn 2026 to 2027 +# conditions of grant, sections 2.2 and 4.1). Over 52 weeks those caps are +# £9,360 and £10,140 per child. +- name: One child outside London with costs above the cap + period: 2025 input: - region: EAST_OF_ENGLAND - care_to_learn_eligible: true + people: + parent: + age: 18 + is_parent: true + current_education: UPPER_SECONDARY + is_apprentice: false + child: + age: 1 + childcare_expenses: 12_000 + benunits: + benunit: + members: [parent, child] + households: + household: + members: [parent, child] + country: ENGLAND + region: EAST_OF_ENGLAND output: - care_to_learn: 9_360 # 180 * 52 - -- name: Care to Learn amount - Inside London - period: 2024 + care_to_learn: [9_360, 0] # min(12,000, 180 x 52) + +# The weekly maximum is per child, so each child's costs are capped separately: +# min(12,000, 9,360) + min(5,000, 9,360) = 14,360. +- name: Two children outside London are each capped at the weekly maximum + period: 2025 + input: + people: + parent: + age: 18 + is_parent: true + current_education: UPPER_SECONDARY + is_apprentice: false + child1: + age: 1 + childcare_expenses: 12_000 + child2: + age: 0 + childcare_expenses: 5_000 + benunits: + benunit: + members: [parent, child1, child2] + households: + household: + members: [parent, child1, child2] + country: ENGLAND + region: EAST_OF_ENGLAND + output: + care_to_learn: [14_360, 0, 0] + +- name: Two children in London are each capped at the London weekly maximum + period: 2025 + input: + people: + parent: + age: 19 + is_parent: true + current_education: POST_SECONDARY + is_apprentice: false + child1: + age: 2 + childcare_expenses: 12_000 + child2: + age: 1 + childcare_expenses: 12_000 + benunits: + benunit: + members: [parent, child1, child2] + households: + household: + members: [parent, child1, child2] + country: ENGLAND + region: LONDON + output: + care_to_learn: [20_280, 0, 0] # 2 x min(12,000, 195 x 52) + +- name: Costs below the cap are paid in full + period: 2025 + input: + people: + parent: + age: 18 + is_parent: true + current_education: UPPER_SECONDARY + is_apprentice: false + child: + age: 1 + childcare_expenses: 3_000 + benunits: + benunit: + members: [parent, child] + households: + household: + members: [parent, child] + country: ENGLAND + region: EAST_OF_ENGLAND + output: + care_to_learn: [3_000, 0] + +- name: No childcare costs, no Care to Learn + period: 2025 + input: + people: + parent: + age: 18 + is_parent: true + current_education: UPPER_SECONDARY + is_apprentice: false + child: + age: 1 + benunits: + benunit: + members: [parent, child] + households: + household: + members: [parent, child] + country: ENGLAND + region: EAST_OF_ENGLAND + output: + care_to_learn: [0, 0] + +# Only one parent can claim for a child (section 2.2), so when both young +# parents are eligible the child's costs are paid once, to the elder. +- name: Two eligible young parents - the child's costs are paid once + period: 2025 + input: + people: + parent1: + age: 18 + is_parent: true + current_education: UPPER_SECONDARY + is_apprentice: false + parent2: + age: 19 + is_parent: true + current_education: POST_SECONDARY + is_apprentice: false + child: + age: 1 + childcare_expenses: 12_000 + benunits: + benunit: + members: [parent1, parent2, child] + households: + household: + members: [parent1, parent2, child] + country: ENGLAND + region: EAST_OF_ENGLAND + output: + care_to_learn_eligible: [true, true, false] + care_to_learn: [0, 9_360, 0] + +# Care to Learn funds childcare while the young parent is on a study programme +# (sections 1.2 and 2.3). +- name: A young parent not in education gets no Care to Learn + period: 2025 input: - region: LONDON - care_to_learn_eligible: true + people: + parent: + age: 18 + is_parent: true + current_education: NOT_IN_EDUCATION + is_apprentice: false + child: + age: 1 + childcare_expenses: 12_000 + benunits: + benunit: + members: [parent, child] + households: + household: + members: [parent, child] + country: ENGLAND + region: EAST_OF_ENGLAND output: - care_to_learn: 10_140 # 195 * 52 + care_to_learn: [0, 0] - name: Not eligible for Care to Learn period: 2024 @@ -20,4 +186,4 @@ region: EAST_OF_ENGLAND care_to_learn_eligible: false output: - care_to_learn: 0 \ No newline at end of file + care_to_learn: 0 diff --git a/policyengine_uk/tests/policy/baseline/gov/dfe/care_to_learn/care_to_learn_eligible.yaml b/policyengine_uk/tests/policy/baseline/gov/dfe/care_to_learn/care_to_learn_eligible.yaml index 1628789ff6..9e3e3fe833 100644 --- a/policyengine_uk/tests/policy/baseline/gov/dfe/care_to_learn/care_to_learn_eligible.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/dfe/care_to_learn/care_to_learn_eligible.yaml @@ -207,3 +207,27 @@ country: ENGLAND output: care_to_learn_eligible: [true, false] + +# Care to Learn funds childcare while the young parent is on a publicly funded +# study programme (ESFA conditions of grant, sections 1.2 and 2.3), so a young +# parent who is not in education is not eligible. +- name: Care to Learn - Not in education + period: 2024 + input: + people: + parent: + age: 18 + is_parent: true + current_education: NOT_IN_EDUCATION + is_apprentice: false + child: + age: 1 + benunits: + benunit: + members: ["parent", "child"] + households: + household: + members: ["parent", "child"] + country: ENGLAND + output: + care_to_learn_eligible: [false, false] diff --git a/policyengine_uk/tests/policy/baseline/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement.yaml b/policyengine_uk/tests/policy/baseline/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement.yaml index 70a84c567f..f6348c2fa2 100644 --- a/policyengine_uk/tests/policy/baseline/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement.yaml @@ -219,4 +219,23 @@ members: [child1, child2] extended_childcare_entitlement_eligible: true output: - extended_childcare_entitlement: 17108.518 \ No newline at end of file + extended_childcare_entitlement: 17108.518 +# SI 2022/1134 reg 13(2)(b): a child looked after by a local authority is not a +# qualifying child, so only the other three-year-old's 30 hours count +# (the same £6,872.805 as the single three-year-old above). +- name: A looked-after child's hours do not count + period: 2025 + absolute_error_margin: 3 + input: + people: + child1: + age: 3 + is_looked_after_by_local_authority: true + child2: + age: 3 + benunits: + benunit1: + members: [child1, child2] + extended_childcare_entitlement_eligible: true + output: + extended_childcare_entitlement: 6872.805 diff --git a/policyengine_uk/tests/policy/baseline/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement_eligible.yaml b/policyengine_uk/tests/policy/baseline/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement_eligible.yaml index 53f74422a2..6162047377 100644 --- a/policyengine_uk/tests/policy/baseline/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement_eligible.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement_eligible.yaml @@ -1,3 +1,6 @@ +# Eligibility needs a qualifying young child (Childcare Act 2016 s.1(2)(a)-(c); +# SI 2022/1134 reg 13) and each parent and partner meeting regs 14 and 15 +# (extended_childcare_entitlement_work_condition, tested in its own file). - name: Eligible - Lives in England with all conditions met period: 2025 input: @@ -8,15 +11,12 @@ people: parent1: age: 35 - extended_childcare_entitlement_meets_income_requirements: true extended_childcare_entitlement_work_condition: true parent2: age: 35 - extended_childcare_entitlement_meets_income_requirements: true - extended_childcare_entitlement_work_condition: false + extended_childcare_entitlement_work_condition: true child1: age: 3 - extended_childcare_entitlement_work_condition: false benunits: benunit1: members: [parent1, parent2, child1] @@ -33,47 +33,19 @@ people: parent1: age: 35 - extended_childcare_entitlement_meets_income_requirements: true extended_childcare_entitlement_work_condition: true parent2: age: 35 - extended_childcare_entitlement_meets_income_requirements: true - extended_childcare_entitlement_work_condition: false - child1: - age: 3 - extended_childcare_entitlement_work_condition: false - benunits: - benunit1: - members: [parent1, parent2, child1] - output: - extended_childcare_entitlement_eligible: false - -- name: Not eligible - Lives in England but income condition not met - period: 2025 - input: - households: - household1: - members: [parent1, parent2, child1] - country: ENGLAND - people: - parent1: - age: 35 - extended_childcare_entitlement_meets_income_requirements: false extended_childcare_entitlement_work_condition: true - parent2: - age: 35 - extended_childcare_entitlement_meets_income_requirements: true - extended_childcare_entitlement_work_condition: false child1: age: 3 - extended_childcare_entitlement_work_condition: false benunits: benunit1: members: [parent1, parent2, child1] output: extended_childcare_entitlement_eligible: false -- name: Not eligible - Lives in England but work condition not met +- name: Not eligible - one parent does not meet the parent or partner conditions period: 2025 input: households: @@ -83,15 +55,12 @@ people: parent1: age: 35 - extended_childcare_entitlement_meets_income_requirements: true - extended_childcare_entitlement_work_condition: false + extended_childcare_entitlement_work_condition: true parent2: age: 35 - extended_childcare_entitlement_meets_income_requirements: true extended_childcare_entitlement_work_condition: false child1: age: 3 - extended_childcare_entitlement_work_condition: false benunits: benunit1: members: [parent1, parent2, child1] @@ -108,11 +77,9 @@ people: parent1: age: 35 - extended_childcare_entitlement_meets_income_requirements: true extended_childcare_entitlement_work_condition: true child1: age: 3 - extended_childcare_entitlement_work_condition: false benunits: benunit1: members: [parent1, child1] @@ -129,20 +96,19 @@ people: parent1: age: 35 - extended_childcare_entitlement_meets_income_requirements: true extended_childcare_entitlement_work_condition: true child1: age: 3 - extended_childcare_entitlement_work_condition: false benunits: benunit1: members: [parent1, child1] output: extended_childcare_entitlement_eligible: false -# The income conditions apply to the parent and the parent's partner -# (Childcare Act 2016 s.1(2)(d); SI 2022/1134 regs 14, 15 and 18), not to an -# older child still at school. -- name: Eligible - an 18-year-old at school does not have to meet the income test + +# The conditions apply to the parent and the parent's partner (Childcare Act +# 2016 s.1(2)(d); SI 2022/1134 regs 14 and 15), not to an older child still at +# school. +- name: Eligible - an 18-year-old at school does not have to meet the parent conditions period: 2025 input: households: @@ -153,21 +119,16 @@ parent1: age: 35 is_parent: true - extended_childcare_entitlement_meets_income_requirements: true extended_childcare_entitlement_work_condition: true parent2: age: 35 is_parent: true - extended_childcare_entitlement_meets_income_requirements: true - extended_childcare_entitlement_work_condition: false + extended_childcare_entitlement_work_condition: true student: age: 18 current_education: UPPER_SECONDARY - extended_childcare_entitlement_meets_income_requirements: false - extended_childcare_entitlement_work_condition: false child1: age: 3 - extended_childcare_entitlement_work_condition: false benunits: benunit1: members: [parent1, parent2, student, child1] @@ -185,11 +146,206 @@ parent1: age: 17 is_parent: true + in_work: true extended_childcare_entitlement_meets_income_requirements: false + child1: + age: 1 + benunits: + benunit1: + members: [parent1, child1] + output: + extended_childcare_entitlement_eligible: false + +# SI 2022/1134 reg 13(2)(a) and s.1(2)(a): the entitlement is for young children +# of the minimum age who are under compulsory school age. A working family whose +# only child is at school is not eligible. +- name: Not eligible - the only child is of compulsory school age + period: 2025 + input: + households: + household1: + members: [parent1, child1] + country: ENGLAND + people: + parent1: + age: 35 + extended_childcare_entitlement_work_condition: true + child1: + age: 7 + benunits: + benunit1: + members: [parent1, child1] + output: + extended_childcare_entitlement_eligible: false + +- name: Not eligible - no children + period: 2025 + input: + households: + household1: + members: [parent1] + country: ENGLAND + people: + parent1: + age: 35 + extended_childcare_entitlement_work_condition: true + benunits: + benunit1: + members: [parent1] + output: + extended_childcare_entitlement_eligible: false + +# A benefit unit with no claimant or partner cannot meet regs 14 and 15. +- name: Not eligible - a benefit unit of a lone young child + period: 2025 + input: + households: + household1: + members: [child1] + country: ENGLAND + people: + child1: + age: 3 + benunits: + benunit1: + members: [child1] + output: + extended_childcare_entitlement_eligible: false + +# Reg 13(2)(a): "nine months" from 1 September 2024 (SI 2023/1330 reg 2(5)(b)). +# PolicyEngine reads a year's parameters on 30 April, so this applies from 2025. +- name: Eligible - a child aged exactly nine months in 2025 + period: 2025 + input: + households: + household1: + members: [parent1, child1] + country: ENGLAND + people: + parent1: + age: 35 + extended_childcare_entitlement_work_condition: true + child1: + age: 0.75 + benunits: + benunit1: + members: [parent1, child1] + output: + extended_childcare_entitlement_eligible: true + +- name: Not eligible - a child aged six months in 2025 + period: 2025 + input: + households: + household1: + members: [parent1, child1] + country: ENGLAND + people: + parent1: + age: 35 + extended_childcare_entitlement_work_condition: true + child1: + age: 0.5 + benunits: + benunit1: + members: [parent1, child1] + output: + extended_childcare_entitlement_eligible: false + +# Reg 13(2)(a): "two" from 1 April 2024 to 31 August 2024 (SI 2023/1330 +# reg 2(5)(a)), which is the value on 30 April 2024. +- name: Eligible - a two-year-old in 2024 + period: 2024 + input: + households: + household1: + members: [parent1, child1] + country: ENGLAND + people: + parent1: + age: 35 + extended_childcare_entitlement_work_condition: true + child1: + age: 2 + benunits: + benunit1: + members: [parent1, child1] + output: + extended_childcare_entitlement_eligible: true + +- name: Not eligible - a one-year-old in 2024 + period: 2024 + input: + households: + household1: + members: [parent1, child1] + country: ENGLAND + people: + parent1: + age: 35 extended_childcare_entitlement_work_condition: true child1: age: 1 - extended_childcare_entitlement_work_condition: false + benunits: + benunit1: + members: [parent1, child1] + output: + extended_childcare_entitlement_eligible: false + +# Reg 13(2)(a) as made: "three". +- name: Not eligible - a two-year-old in 2023 + period: 2023 + input: + households: + household1: + members: [parent1, child1] + country: ENGLAND + people: + parent1: + age: 35 + extended_childcare_entitlement_work_condition: true + child1: + age: 2 + benunits: + benunit1: + members: [parent1, child1] + output: + extended_childcare_entitlement_eligible: false + +- name: Eligible - a three-year-old in 2023 + period: 2023 + input: + households: + household1: + members: [parent1, child1] + country: ENGLAND + people: + parent1: + age: 35 + extended_childcare_entitlement_work_condition: true + child1: + age: 3 + benunits: + benunit1: + members: [parent1, child1] + output: + extended_childcare_entitlement_eligible: true + +# Reg 13(2)(b): the young child must not be looked after by a local authority. +- name: Not eligible - the only young child is looked after by a local authority + period: 2025 + input: + households: + household1: + members: [parent1, child1] + country: ENGLAND + people: + parent1: + age: 35 + extended_childcare_entitlement_work_condition: true + child1: + age: 3 + is_looked_after_by_local_authority: true benunits: benunit1: members: [parent1, child1] diff --git a/policyengine_uk/tests/policy/baseline/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement_income_condition.yaml b/policyengine_uk/tests/policy/baseline/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement_income_condition.yaml index 5ffbf3590d..2573ec3c69 100644 --- a/policyengine_uk/tests/policy/baseline/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement_income_condition.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement_income_condition.yaml @@ -45,4 +45,50 @@ employment_income: 100_0000 # At assumed maximum threshold adjusted_net_income: 100_0000 output: - extended_childcare_entitlement_meets_income_requirements: false \ No newline at end of file + extended_childcare_entitlement_meets_income_requirements: false + +# SI 2022/1134 reg 18(1): expected income over the three-month relevant period +# must be "equal to or greater than" 16 hours x minimum wage x 13 weeks. With a +# £10 minimum wage that is £2,080 a quarter; £8,320 a year is exactly £2,080 a +# quarter. +- name: Income exactly at the reg 18 minimum meets the requirement + period: 2025 + input: + age: 35 + minimum_wage: 10 + employment_income: 8_320 + adjusted_net_income: 8_320 + output: + extended_childcare_entitlement_meets_income_requirements: true + +- name: Income £4 a year below the reg 18 minimum does not meet the requirement + period: 2025 + input: + age: 35 + minimum_wage: 10 + employment_income: 8_316 + adjusted_net_income: 8_316 + output: + extended_childcare_entitlement_meets_income_requirements: false + +# Regs 14(3)(c)(i) and 15(3)(b)(i): the person must not expect adjusted net +# income to "exceed £100,000", so exactly £100,000 qualifies. +- name: Adjusted net income of exactly £100,000 meets the requirement + period: 2025 + input: + age: 35 + minimum_wage: 10 + employment_income: 100_000 + adjusted_net_income: 100_000 + output: + extended_childcare_entitlement_meets_income_requirements: true + +- name: Adjusted net income of £100,001 does not meet the requirement + period: 2025 + input: + age: 35 + minimum_wage: 10 + employment_income: 100_001 + adjusted_net_income: 100_001 + output: + extended_childcare_entitlement_meets_income_requirements: false diff --git a/policyengine_uk/tests/policy/baseline/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement_work_condition.yaml b/policyengine_uk/tests/policy/baseline/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement_work_condition.yaml index 5430535bb6..713a204129 100644 --- a/policyengine_uk/tests/policy/baseline/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement_work_condition.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement_work_condition.yaml @@ -1,126 +1,313 @@ -- name: Lone parent working - eligible +# Each parent and partner must meet SI 2022/1134 reg 14(3)/15(3): qualifying +# paid work, meaning expected income over three months of at least +# 16 hours x minimum wage x 13 weeks (reg 18), and adjusted net income of no +# more than £100,000. Or they must meet reg 14(4)/15(4) instead: limited +# capability for work or a specified benefit (reg 11A), with a partner who meets +# reg 14(3)/15(3). +# +# These tests set minimum_wage to £10, so the reg 18 threshold is +# 10 x 16 x 13 = £2,080 a quarter, or £8,320 a year. The £20,000 earners below +# have £5,000 a quarter and adjusted net income of £20,000, so they meet +# reg 14(3)/15(3). +- name: Lone parent working - meets the condition period: 2025 input: people: parent: age: 35 - in_work: true is_parent: true + employment_income: 20_000 + adjusted_net_income: 20_000 + minimum_wage: 10 child: age: 4 - is_parent: false benunits: benunit: members: [parent, child] - family_type: LONE_PARENT output: - extended_childcare_entitlement_work_condition: [1, 0] + extended_childcare_entitlement_work_condition: [true, false] -- name: Couple with children both working - eligible +- name: Couple with children both working - both meet the condition period: 2025 input: people: parent1: age: 40 - in_work: true is_parent: true + employment_income: 20_000 + adjusted_net_income: 20_000 + minimum_wage: 10 parent2: age: 38 - in_work: true is_parent: true + employment_income: 20_000 + adjusted_net_income: 20_000 + minimum_wage: 10 child: age: 4 - is_parent: false benunits: benunit: members: [parent1, parent2, child] - family_type: COUPLE_WITH_CHILDREN output: - extended_childcare_entitlement_work_condition: [1, 1, 0] + extended_childcare_entitlement_work_condition: [true, true, false] -- name: Couple with children, one working one with carer element - eligible +# Reg 15(4)(c) and 11A(1)(a): the partner on Carer's Allowance has no earnings, +# so fails the reg 18 minimum income, but needs neither the work nor the income +# condition because the other parent meets reg 14(3). +- name: One parent working, the other on Carer's Allowance - both meet the condition period: 2025 input: people: parent1: age: 40 - in_work: true is_parent: true + employment_income: 20_000 + adjusted_net_income: 20_000 + minimum_wage: 10 parent2: age: 38 - in_work: false is_parent: true + carers_allowance: 4_000 + minimum_wage: 10 + child: + age: 4 + benunits: + benunit: + members: [parent1, parent2, child] + output: + extended_childcare_entitlement_work_condition: [true, true, false] + +# Reg 11A(1)(c): the Universal Credit carer element. It is a benefit-unit +# amount, so it counts for both members of the couple. +- name: One parent working, the family has the UC carer element - both meet the condition + period: 2025 + input: + people: + parent1: + age: 40 + is_parent: true + employment_income: 20_000 + adjusted_net_income: 20_000 + minimum_wage: 10 + parent2: + age: 38 + is_parent: true + minimum_wage: 10 child: age: 4 - is_parent: false benunits: benunit: members: [parent1, parent2, child] - family_type: COUPLE_WITH_CHILDREN uc_carer_element: 100 output: - extended_childcare_entitlement_work_condition: [1, 1, 0] + extended_childcare_entitlement_work_condition: [true, true, false] + +# Reg 11A(1)(e): employment and support allowance under WRA 2007 s.1, which +# includes income-related ESA. +- name: One parent working, the family has income-related ESA in 2025 - both meet the condition + period: 2025 + input: + people: + parent1: + age: 40 + is_parent: true + employment_income: 20_000 + adjusted_net_income: 20_000 + minimum_wage: 10 + parent2: + age: 38 + is_parent: true + minimum_wage: 10 + child: + age: 4 + benunits: + benunit: + members: [parent1, parent2, child] + esa_income: 3_000 + output: + extended_childcare_entitlement_work_condition: [true, true, false] + +# Before 1 December 2022, SI 2016/1257 reg 9(1)(b)(v) listed only +# contributory ESA. +- name: One parent working, the family has income-related ESA in 2022 - the other does not meet the condition + period: 2022 + input: + people: + parent1: + age: 40 + is_parent: true + employment_income: 20_000 + adjusted_net_income: 20_000 + minimum_wage: 10 + parent2: + age: 38 + is_parent: true + minimum_wage: 10 + child: + age: 4 + benunits: + benunit: + members: [parent1, parent2, child] + esa_income: 3_000 + output: + extended_childcare_entitlement_work_condition: [true, false, false] + +# Reg 15(4)(a)-(b): limited capability for work, or for work and work-related +# activity. +- name: One parent working, the other with limited capability for work - both meet the condition + period: 2025 + input: + people: + parent1: + age: 40 + is_parent: true + employment_income: 20_000 + adjusted_net_income: 20_000 + minimum_wage: 10 + parent2: + age: 38 + is_parent: true + uc_limited_capability_for_WRA: true + minimum_wage: 10 + child: + age: 4 + benunits: + benunit: + members: [parent1, parent2, child] + output: + extended_childcare_entitlement_work_condition: [true, true, false] + +# Personal Independence Payment is not a specified benefit (reg 11A). +- name: One parent working, the other on PIP only - the other does not meet the condition + period: 2025 + input: + people: + parent1: + age: 40 + is_parent: true + employment_income: 20_000 + adjusted_net_income: 20_000 + minimum_wage: 10 + parent2: + age: 38 + is_parent: true + pip: 5_000 + minimum_wage: 10 + child: + age: 4 + benunits: + benunit: + members: [parent1, parent2, child] + output: + extended_childcare_entitlement_work_condition: [true, false, false] + +- name: One parent working, the other neither working nor on a specified benefit + period: 2025 + input: + people: + parent1: + age: 40 + is_parent: true + employment_income: 20_000 + adjusted_net_income: 20_000 + minimum_wage: 10 + parent2: + age: 38 + is_parent: true + minimum_wage: 10 + child: + age: 4 + benunits: + benunit: + members: [parent1, parent2, child] + output: + extended_childcare_entitlement_work_condition: [true, false, false] -- name: Couple with children, one working one with Carer's Allowance - eligible +# Reg 14(4)/15(4) need the other member of the couple to meet reg 14(3)/15(3). +- name: Both parents on Carer's Allowance, neither working - neither meets the condition period: 2025 input: people: parent1: age: 40 - in_work: true is_parent: true + carers_allowance: 4_000 + minimum_wage: 10 parent2: age: 38 - in_work: false is_parent: true - carers_allowance: 1 + carers_allowance: 4_000 + minimum_wage: 10 child: age: 4 - is_parent: false benunits: benunit: members: [parent1, parent2, child] - family_type: COUPLE_WITH_CHILDREN output: - extended_childcare_entitlement_work_condition: [1, 1, 0] + extended_childcare_entitlement_work_condition: [false, false, false] + +# Reg 14(4)(a): a parent can rely on a specified benefit only if they have a +# partner. +- name: Lone parent on Carer's Allowance, not working - does not meet the condition + period: 2025 + input: + people: + parent: + age: 35 + is_parent: true + carers_allowance: 4_000 + minimum_wage: 10 + child: + age: 4 + benunits: + benunit: + members: [parent, child] + output: + extended_childcare_entitlement_work_condition: [false, false] -- name: Couple with children one working one not - ineligible +# The earner's adjusted net income of £120,000 exceeds the reg 14(3)(c)(i) +# limit, so the earner fails reg 14(3), and the carer has no partner meeting it. +- name: Earner above the income limit, partner on Carer's Allowance - neither meets the condition period: 2025 input: people: parent1: age: 40 - in_work: true is_parent: true + employment_income: 120_000 + adjusted_net_income: 120_000 + minimum_wage: 10 parent2: age: 38 - in_work: false is_parent: true + carers_allowance: 4_000 + minimum_wage: 10 child: age: 4 - is_parent: false benunits: benunit: members: [parent1, parent2, child] - family_type: COUPLE_WITH_CHILDREN output: - extended_childcare_entitlement_work_condition: [0, 0, 0] + extended_childcare_entitlement_work_condition: [false, false, false] -- name: Couple without children both working - ineligible +# The condition applies to the claimant and partner whether or not they have a +# young child; the young child condition is in extended_childcare_entitlement_eligible. +- name: Couple without children both working - both meet the condition period: 2025 input: people: person1: age: 40 - in_work: true - is_parent: false + employment_income: 20_000 + adjusted_net_income: 20_000 + minimum_wage: 10 person2: age: 38 - in_work: true - is_parent: false + employment_income: 20_000 + adjusted_net_income: 20_000 + minimum_wage: 10 benunits: benunit: members: [person1, person2] - family_type: COUPLE_NO_CHILDREN output: - extended_childcare_entitlement_work_condition: [0, 0] + extended_childcare_entitlement_work_condition: [true, true] diff --git a/policyengine_uk/tests/policy/baseline/gov/dfe/maintenance_loans/maintenance_loan.yaml b/policyengine_uk/tests/policy/baseline/gov/dfe/maintenance_loans/maintenance_loan.yaml index 2c53b50689..cc8493b21b 100644 --- a/policyengine_uk/tests/policy/baseline/gov/dfe/maintenance_loans/maintenance_loan.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/dfe/maintenance_loans/maintenance_loan.yaml @@ -520,3 +520,61 @@ region: LONDON output: maintenance_loan: [14_135] + +# Education (Student Support) Regulations 2011 Sch 4 para 2(1)(a): a student +# aged 25 or over on the first day of the academic year is independent, so the +# parents' income is not assessed. At 24 the parent's £40,000 is added to the +# student's own £5,000; at 25 only the student's own income counts. +- name: Maintenance loan household income adds a sponsor's income for a 24-year-old + period: 2025 + input: + people: + parent: + age: 50 + current_education: NOT_IN_EDUCATION + adjusted_net_income: 40_000 + is_household_head: true + student: + age: 24 + current_education: TERTIARY + adjusted_net_income: 5_000 + is_household_head: false + benunits: + parent_benunit: + members: ["parent"] + student_benunit: + members: ["student"] + households: + household: + members: ["parent", "student"] + country: ENGLAND + output: + maintenance_loan_has_sponsor: [false, true] + maintenance_loan_household_income: [40_000, 45_000] + +- name: Maintenance loan household income treats a 25-year-old as independent + period: 2025 + input: + people: + parent: + age: 50 + current_education: NOT_IN_EDUCATION + adjusted_net_income: 40_000 + is_household_head: true + student: + age: 25 + current_education: TERTIARY + adjusted_net_income: 5_000 + is_household_head: false + benunits: + parent_benunit: + members: ["parent"] + student_benunit: + members: ["student"] + households: + household: + members: ["parent", "student"] + country: ENGLAND + output: + maintenance_loan_has_sponsor: [false, true] + maintenance_loan_household_income: [40_000, 5_000] diff --git a/policyengine_uk/tests/policy/baseline/gov/hmrc/tax_free_childcare/tax_free_childcare_eligibility.yaml b/policyengine_uk/tests/policy/baseline/gov/hmrc/tax_free_childcare/tax_free_childcare_eligibility.yaml index f29383b56f..bf45eaee41 100644 --- a/policyengine_uk/tests/policy/baseline/gov/hmrc/tax_free_childcare/tax_free_childcare_eligibility.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/hmrc/tax_free_childcare/tax_free_childcare_eligibility.yaml @@ -60,3 +60,80 @@ tax_free_childcare_work_condition: true output: tax_free_childcare_eligible: false + + +# End to end: one parent earns £20,000 and the other receives Carer's Allowance +# with no earnings. Reg 13 regards the carer as in qualifying paid work with the +# minimum income, so the family is eligible. The child's £10,000 of childcare +# attracts a 20% top-up of £2,000, which equals the £2,000 annual cap +# (4 periods x £500). +- name: A working parent and a partner on Carer's Allowance are eligible, and receive the top-up + period: 2025 + input: + people: + earner: + age: 40 + is_parent: true + employment_income: 20_000 + adjusted_net_income: 20_000 + minimum_wage: 10 + carer: + age: 38 + is_parent: true + carers_allowance: 4_000 + adjusted_net_income: 4_000 + minimum_wage: 10 + child: + age: 3 + childcare_expenses: 10_000 + benunits: + benunit: + members: [earner, carer, child] + universal_credit_pre_benefit_cap: 0 + working_tax_credit: 0 + child_tax_credit: 0 + households: + household: + members: [earner, carer, child] + country: ENGLAND + output: + tax_free_childcare_work_condition: [true, true, false] + tax_free_childcare_eligible: true + tax_free_childcare: [0, 0, 2_000] + +# The same family with Disability Living Allowance in place of Carer's +# Allowance: DLA is not a reg 13(1)(b) benefit, so the non-earner is not in +# qualifying paid work and the family is not eligible. +- name: A working parent and a partner on Disability Living Allowance only are not eligible + period: 2025 + input: + people: + earner: + age: 40 + is_parent: true + employment_income: 20_000 + adjusted_net_income: 20_000 + minimum_wage: 10 + partner: + age: 38 + is_parent: true + dla: 4_000 + adjusted_net_income: 4_000 + minimum_wage: 10 + child: + age: 3 + childcare_expenses: 10_000 + benunits: + benunit: + members: [earner, partner, child] + universal_credit_pre_benefit_cap: 0 + working_tax_credit: 0 + child_tax_credit: 0 + households: + household: + members: [earner, partner, child] + country: ENGLAND + output: + tax_free_childcare_work_condition: [false, false, false] + tax_free_childcare_eligible: false + tax_free_childcare: [0, 0, 0] diff --git a/policyengine_uk/tests/policy/baseline/gov/hmrc/tax_free_childcare/tax_free_childcare_income_condition.yaml b/policyengine_uk/tests/policy/baseline/gov/hmrc/tax_free_childcare/tax_free_childcare_income_condition.yaml index eea99435da..c58c0b617a 100644 --- a/policyengine_uk/tests/policy/baseline/gov/hmrc/tax_free_childcare/tax_free_childcare_income_condition.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/hmrc/tax_free_childcare/tax_free_childcare_income_condition.yaml @@ -84,3 +84,69 @@ tax_free_childcare_self_employment_start_up_period: true output: tax_free_childcare_meets_income_requirements: true + + +# SI 2015/448 reg 13(2)(b): a person regarded as in paid work under reg 13 has +# expected income equal to the minimum weekly income, so meets the minimum +# income requirement with no earnings. With a £10 minimum wage the threshold is +# 10 x 16 x 13 = £2,080 a declaration period; the earner's £20,000 a year is +# £5,000 a period. +- name: A non-working partner on Carer's Allowance whose partner works meets the income requirement + period: 2025 + input: + people: + earner: + age: 40 + employment_income: 20_000 + adjusted_net_income: 20_000 + minimum_wage: 10 + carer: + age: 38 + carers_allowance: 4_000 + adjusted_net_income: 4_000 + minimum_wage: 10 + benunits: + benunit: + members: [earner, carer] + output: + tax_free_childcare_regarded_as_in_paid_work: [false, true] + tax_free_childcare_meets_income_requirements: [true, true] + +- name: A lone Carer's Allowance recipient with no earnings does not meet the income requirement + period: 2025 + input: + people: + carer: + age: 38 + carers_allowance: 4_000 + adjusted_net_income: 4_000 + minimum_wage: 10 + benunits: + benunit: + members: [carer] + output: + tax_free_childcare_regarded_as_in_paid_work: false + tax_free_childcare_meets_income_requirements: false + +# Reg 13 deems work and minimum income only; reg 15's £100,000 adjusted net +# income limit still applies. +- name: A Carer's Allowance recipient over the adjusted net income limit does not meet the income requirement + period: 2025 + input: + people: + earner: + age: 40 + employment_income: 20_000 + adjusted_net_income: 20_000 + minimum_wage: 10 + carer: + age: 38 + carers_allowance: 4_000 + adjusted_net_income: 150_000 + minimum_wage: 10 + benunits: + benunit: + members: [earner, carer] + output: + tax_free_childcare_regarded_as_in_paid_work: [false, true] + tax_free_childcare_meets_income_requirements: [true, false] diff --git a/policyengine_uk/tests/policy/baseline/gov/hmrc/tax_free_childcare/tax_free_childcare_work_condition.yaml b/policyengine_uk/tests/policy/baseline/gov/hmrc/tax_free_childcare/tax_free_childcare_work_condition.yaml index b0f8195c60..85efbe37a0 100644 --- a/policyengine_uk/tests/policy/baseline/gov/hmrc/tax_free_childcare/tax_free_childcare_work_condition.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/hmrc/tax_free_childcare/tax_free_childcare_work_condition.yaml @@ -108,7 +108,10 @@ output: tax_free_childcare_work_condition: false -- name: Couple both with disability one working - eligible +# SI 2015/448 reg 13(3): a partner paid a reg 13(1)(b) benefit is not in +# qualifying paid work for reg 13(1)(a), so the non-working spouse cannot rely +# on reg 13 when the working one also receives incapacity benefit. +- name: Couple both on incapacity benefit, one working - ineligible under reg 13(3) period: 2025 input: people: @@ -122,7 +125,7 @@ benunit: members: [person, spouse] output: - tax_free_childcare_work_condition: true + tax_free_childcare_work_condition: false - name: Single working adult with disability - eligible period: 2025 @@ -318,6 +321,197 @@ output: tax_free_childcare_work_condition: [false, false, false] +# SI 2015/448 reg 13(1): a person whose partner is in qualifying paid work is +# regarded as in qualifying paid work while paid or entitled to incapacity +# benefit, severe disablement allowance, carer's allowance, contributory ESA, +# credits for incapacity or limited capability for work, or (from 1 December +# 2022) Scottish carer's assistance, or while on carer's leave (from 6 April +# 2024). Disability Living Allowance, Personal Independence Payment and +# income-related ESA are not on the list. + +- name: Couple one working one on Carer's Allowance - eligible under reg 13(1)(b)(iv) + period: 2025 + input: + people: + person: + in_work: true + spouse: + in_work: false + carers_allowance: 4000 + benunits: + benunit: + members: [person, spouse] + output: + tax_free_childcare_work_condition: true + +- name: Couple one working one on severe disablement allowance - eligible under reg 13(1)(b)(ii) + period: 2025 + input: + people: + person: + in_work: true + spouse: + in_work: false + sda: 4000 + benunits: + benunit: + members: [person, spouse] + output: + tax_free_childcare_work_condition: true + +- name: Couple one working one on contributory ESA - eligible under reg 13(1)(b)(v) + period: 2025 + input: + people: + person: + in_work: true + spouse: + in_work: false + esa_contrib: 4000 + benunits: + benunit: + members: [person, spouse] + output: + tax_free_childcare_work_condition: true + +- name: Couple one working one with credits for limited capability for work - eligible under reg 13(1)(b)(vi) + period: 2025 + input: + people: + person: + in_work: true + spouse: + in_work: false + receives_limited_capability_for_work_credits: true + benunits: + benunit: + members: [person, spouse] + output: + tax_free_childcare_work_condition: true + +- name: Couple one working one on Carer Support Payment in 2025 - eligible under reg 13(1)(b)(vii) + period: 2025 + input: + people: + person: + in_work: true + spouse: + in_work: false + carer_support_payment: 4000 + benunits: + benunit: + members: [person, spouse] + output: + tax_free_childcare_work_condition: true + +- name: Couple one working one on Scottish carer's assistance in 2022 - reg 13(1)(b)(vii) not yet in force + period: 2022 + input: + people: + person: + in_work: true + spouse: + in_work: false + carer_support_payment: 4000 + benunits: + benunit: + members: [person, spouse] + output: + tax_free_childcare_work_condition: false + +- name: Couple one working one on carer's leave in 2024 - eligible under reg 13(1)(c) + period: 2024 + input: + people: + person: + in_work: true + spouse: + in_work: false + tax_free_childcare_on_carers_leave: true + benunits: + benunit: + members: [person, spouse] + output: + tax_free_childcare_work_condition: true + +- name: Couple one working one on carer's leave in 2023 - reg 13(1)(c) not yet in force + period: 2023 + input: + people: + person: + in_work: true + spouse: + in_work: false + tax_free_childcare_on_carers_leave: true + benunits: + benunit: + members: [person, spouse] + output: + tax_free_childcare_work_condition: false + +- name: Couple one working one on Disability Living Allowance only - ineligible + period: 2025 + input: + people: + person: + in_work: true + spouse: + in_work: false + dla: 4000 + benunits: + benunit: + members: [person, spouse] + output: + tax_free_childcare_work_condition: false + +- name: Couple one working one on Personal Independence Payment only - ineligible + period: 2025 + input: + people: + person: + in_work: true + spouse: + in_work: false + pip: 4000 + benunits: + benunit: + members: [person, spouse] + output: + tax_free_childcare_work_condition: false + +- name: Couple one working, the family on income-related ESA only - ineligible + period: 2025 + input: + people: + person: + in_work: true + spouse: + in_work: false + benunits: + benunit: + members: [person, spouse] + esa_income: 4000 + output: + tax_free_childcare_work_condition: false + +# Reg 13(1)(a): a lone parent has no partner in qualifying paid work. +- name: Lone parent on Carer's Allowance, not working - ineligible + period: 2025 + input: + people: + parent: + age: 30 + is_parent: true + in_work: false + carers_allowance: 4_000 + child: + age: 3 + benunits: + benunit: + members: [parent, child] + output: + tax_free_childcare_work_condition: [false, false] + - name: A working lone parent with an 18-year-old and a toddler meets the work condition # Default inputs: the 18-year-old is the parent's child, not a partner who # would also have to work. diff --git a/policyengine_uk/variables/gov/dfe/care_to_learn/care_to_learn.py b/policyengine_uk/variables/gov/dfe/care_to_learn/care_to_learn.py index 839ee8a1a8..cc5484dff3 100644 --- a/policyengine_uk/variables/gov/dfe/care_to_learn/care_to_learn.py +++ b/policyengine_uk/variables/gov/dfe/care_to_learn/care_to_learn.py @@ -5,20 +5,43 @@ class care_to_learn(Variable): value_type = float entity = Person label = "Care to Learn scheme amount" + documentation = ( + "Care to Learn pays a young parent's childcare costs, and any extra " + "travel between home and the childcare provider, up to a weekly " + "maximum per child (ESFA conditions of grant, sections 2.2 and 4.1). " + "The model caps each qualifying child's annual childcare_expenses at " + "52 weeks of that maximum; it does not model the travel costs. Only " + "one parent can claim for a child, so the benefit unit's total is " + "paid to one eligible young parent, the eldest." + ) definition_period = YEAR quantity_type = FLOW unit = GBP default_value = 0 defined_for = "care_to_learn_eligible" + reference = ( + "https://www.gov.uk/government/publications/care-to-learn-conditions-of-grant-funding/care-to-learn-academic-year-2026-to-2027-conditions-of-grant-funding", + ) def formula(person, period, parameters): - # Get amounts from parameters + p = parameters(period).gov.dfe.care_to_learn.amount + # London weighting follows the young parent's home address. region = person.household("region", period) - p = parameters(period).gov.dfe.care_to_learn - max_amount = where( + weekly_maximum_per_child = where( region == region.possible_values.LONDON, - p.amount.in_london, - p.amount.outside_london, + p.in_london, + p.outside_london, ) + qualifying_child = person("care_to_learn_qualifying_child", period) + childcare_costs = max_(person("childcare_expenses", period), 0) + amount_per_child = qualifying_child * min_( + childcare_costs, weekly_maximum_per_child * WEEKS_IN_YEAR + ) + benunit_amount = person.benunit.sum(amount_per_child) - return max_amount * WEEKS_IN_YEAR + eligible = person("care_to_learn_eligible", period) + claims_for_benunit = ( + person.get_rank(person.benunit, -person("age", period), condition=eligible) + == 0 + ) + return where(claims_for_benunit, benunit_amount, 0) diff --git a/policyengine_uk/variables/gov/dfe/care_to_learn/care_to_learn_eligible.py b/policyengine_uk/variables/gov/dfe/care_to_learn/care_to_learn_eligible.py index ccc4d49f1d..8e119e5073 100644 --- a/policyengine_uk/variables/gov/dfe/care_to_learn/care_to_learn_eligible.py +++ b/policyengine_uk/variables/gov/dfe/care_to_learn/care_to_learn_eligible.py @@ -19,21 +19,23 @@ def formula(person, period, parameters): is_parent = person("is_parent", period) # The young parent must be the main carer of, and receive Child - # Benefit for, the child they claim for (ESFA conditions of grant). - # So the child is a Child Benefit child or qualifying young person in - # the benefit unit, other than the parent themselves. - cares_for_child_benefit_child = person.benunit.any( - person("is_child_or_qualifying_young_person_for_child_benefit", period) - & ~is_parent + # Benefit for, a child they claim for (ESFA conditions of grant, + # section 2.2). + cares_for_qualifying_child = person.benunit.any( + person("care_to_learn_qualifying_child", period) ) p = parameters(period).gov.dfe.care_to_learn age_eligible = person("age", period) < p.age_limit + # Care to Learn funds childcare while the young parent is on a + # publicly funded study programme (sections 1.2 and 2.3). Higher + # education courses are not eligible, and a young parent who is not + # in education has no study programme to fund childcare for. current_ed = person("current_education", period) education_types = current_ed.possible_values - - # Only exclude higher education/tertiary - not_higher_education = current_ed != education_types.TERTIARY + on_study_programme = (current_ed != education_types.NOT_IN_EDUCATION) & ( + current_ed != education_types.TERTIARY + ) not_apprentice = ~person("is_apprentice", period) @@ -44,9 +46,9 @@ def formula(person, period, parameters): return ( is_parent - & cares_for_child_benefit_child + & cares_for_qualifying_child & age_eligible - & not_higher_education + & on_study_programme & lives_in_england & not_apprentice ) diff --git a/policyengine_uk/variables/gov/dfe/care_to_learn/care_to_learn_qualifying_child.py b/policyengine_uk/variables/gov/dfe/care_to_learn/care_to_learn_qualifying_child.py new file mode 100644 index 0000000000..9d686e4571 --- /dev/null +++ b/policyengine_uk/variables/gov/dfe/care_to_learn/care_to_learn_qualifying_child.py @@ -0,0 +1,24 @@ +from policyengine_uk.model_api import * + + +class care_to_learn_qualifying_child(Variable): + value_type = bool + entity = Person + label = "child a young parent can claim Care to Learn for" + documentation = ( + "A child in the benefit unit whom a young parent can claim Care to " + "Learn for. The young parent must be the main carer of, and receive " + "Child Benefit for, the child they claim for (ESFA conditions of " + "grant, section 2.2), so the child is a Child Benefit child or " + "qualifying young person in the benefit unit other than a parent." + ) + definition_period = YEAR + reference = ( + "https://www.gov.uk/government/publications/care-to-learn-conditions-of-grant-funding/care-to-learn-academic-year-2026-to-2027-conditions-of-grant-funding", + "https://www.legislation.gov.uk/ukpga/1992/4/section/142", + ) + + def formula(person, period, parameters): + return person( + "is_child_or_qualifying_young_person_for_child_benefit", period + ) & ~person("is_parent", period) diff --git a/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/conditions/extended_childcare_entitlement_limited_capability_or_specified_benefit.py b/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/conditions/extended_childcare_entitlement_limited_capability_or_specified_benefit.py new file mode 100644 index 0000000000..93b9e00441 --- /dev/null +++ b/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/conditions/extended_childcare_entitlement_limited_capability_or_specified_benefit.py @@ -0,0 +1,45 @@ +from policyengine_uk.model_api import * + + +class extended_childcare_entitlement_limited_capability_or_specified_benefit(Variable): + value_type = bool + entity = Person + label = "limited capability for work or a specified benefit, for the extended childcare entitlement" + documentation = ( + "Whether this person has limited capability for work, or for work and " + "work-related activity, or is entitled to a specified benefit such as " + "Carer's Allowance or Employment and Support Allowance (SI 2022/1134 " + "regs 11A, 14(4)(b) and 15(4); SI 2016/1257 reg 9(1)(b) before " + "1 December 2022). A parent or partner in this position meets the " + "parent and partner conditions without the work or income conditions " + "when the other meets them. A benefit-unit-level benefit in the list, " + "such as the Universal Credit carer element, counts for both members " + "of a couple." + ) + definition_period = YEAR + reference = ( + "https://www.legislation.gov.uk/uksi/2022/1134/regulation/11A", + "https://www.legislation.gov.uk/uksi/2022/1134/regulation/14", + "https://www.legislation.gov.uk/uksi/2022/1134/regulation/15", + ) + + def formula(person, period, parameters): + p = parameters(period).gov.dfe.extended_childcare_entitlement + criteria = list(p.disability_criteria) + person_criteria = [ + variable + for variable in criteria + if person.entity.get_variable(variable).entity.is_person + ] + group_criteria = [ + variable + for variable in criteria + if not person.entity.get_variable(variable).entity.is_person + ] + meets_person_criteria = ( + add(person, period, person_criteria) > 0 if person_criteria else False + ) + meets_group_criteria = ( + add(person.benunit, period, group_criteria) > 0 if group_criteria else False + ) + return meets_person_criteria | meets_group_criteria diff --git a/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/conditions/extended_childcare_entitlement_meets_income_requirements.py b/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/conditions/extended_childcare_entitlement_meets_income_requirements.py index b20e41db8c..35a610ce38 100644 --- a/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/conditions/extended_childcare_entitlement_meets_income_requirements.py +++ b/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/conditions/extended_childcare_entitlement_meets_income_requirements.py @@ -5,11 +5,16 @@ class extended_childcare_entitlement_meets_income_requirements(Variable): value_type = bool entity = Person label = "Income eligible for the extended childcare entitlement" - documentation = "Whether this person meets the income requirements for extended childcare entitlement based on age and income thresholds" + documentation = ( + "Whether this person expects at least the minimum income from work " + "(SI 2022/1134 reg 18) and adjusted net income of no more than the " + "limit (regs 14(3)(c)(i) and 15(3)(b)(i))." + ) definition_period = YEAR - - # Legislation: https://www.legislation.gov.uk/ukdsi/2015/9780111127063 , part 9 and 10 - # Also, you can check here: https://www.gov.uk/tax-free-childcare + reference = ( + "https://www.legislation.gov.uk/uksi/2022/1134/regulation/14", + "https://www.legislation.gov.uk/uksi/2022/1134/regulation/18", + ) def formula(person, period, parameters): p = parameters(period).gov.dfe.extended_childcare_entitlement @@ -21,11 +26,13 @@ def formula(person, period, parameters): # Get minimum wage rate using existing variable min_wage_rate = person("minimum_wage", period) - # Calculate required threshold (weekly hours * 13 weeks (a quarter) * minimum wage) - # Reference for the quarterly logic: part 9.3 in https://www.legislation.gov.uk/uksi/2015/448/regulation/9 + # Reg 18(1): expected income over the three-month relevant period must + # be equal to or greater than the minimum weekly income (16 hours at + # the person's minimum wage) times the number of weeks (13). required_threshold = min_wage_rate * p.minimum_weekly_hours * 13 - # Get adjusted net income and check against max threshold + # Regs 14(3)(c)(i) and 15(3)(b)(i): the person must not expect adjusted + # net income to exceed the limit. ani = person("adjusted_net_income", period) - return (quarterly_income > required_threshold) & (ani < p.income.limit) + return (quarterly_income >= required_threshold) & (ani <= p.income.limit) diff --git a/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/conditions/extended_childcare_entitlement_work_condition.py b/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/conditions/extended_childcare_entitlement_work_condition.py index 20f9d28c5a..a1c571c904 100644 --- a/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/conditions/extended_childcare_entitlement_work_condition.py +++ b/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/conditions/extended_childcare_entitlement_work_condition.py @@ -4,60 +4,49 @@ class extended_childcare_entitlement_work_condition(Variable): value_type = bool entity = Person - label = "Work conditions for extended childcare entitlement" - documentation = "Whether this person meets work requirements for extended childcare entitlement." + label = "meets the parent or partner conditions for extended childcare entitlement" + documentation = ( + "Whether this parent or partner meets SI 2022/1134 reg 14(3) or 15(3): " + "qualifying paid work, with at least the minimum income, and adjusted " + "net income of no more than £100,000. Or whether they meet reg 14(4) " + "or 15(4) instead: limited capability for work or a specified " + "benefit, with a partner who meets reg 14(3) or 15(3). Under reg " + "14(4) or 15(4) a person needs neither the work nor the income " + "condition, and a lone parent cannot qualify that way." + ) definition_period = YEAR - defined_for = "is_parent" + defined_for = "is_claimant_or_partner" + reference = ( + "https://www.legislation.gov.uk/ukpga/2016/5/section/1", + "https://www.legislation.gov.uk/uksi/2022/1134/regulation/14", + "https://www.legislation.gov.uk/uksi/2022/1134/regulation/15", + "https://www.legislation.gov.uk/uksi/2022/1134/regulation/18", + ) def formula(person, period, parameters): - benunit = person.benunit - in_work = person("in_work", period) - - p = parameters(period).gov.dfe.extended_childcare_entitlement - disability_criteria = list(p.disability_criteria) - person_disability_criteria = [ - variable - for variable in disability_criteria - if person.entity.get_variable(variable).entity.is_person - ] - group_disability_criteria = [ - variable - for variable in disability_criteria - if not person.entity.get_variable(variable).entity.is_person - ] - - eligible_based_on_person_disability = ( - add(person, period, person_disability_criteria) > 0 - if person_disability_criteria - else False - ) - eligible_based_on_group_disability = ( - add(benunit, period, group_disability_criteria) > 0 - if group_disability_criteria - else False + claimant_or_partner = person("is_claimant_or_partner", period) + + # Reg 14(3)/15(3): in qualifying paid work (the minimum income + # requirement in reg 18) and adjusted net income not above £100,000. + meets_work_and_income_conditions = ( + claimant_or_partner + & person("in_work", period) + & person("extended_childcare_entitlement_meets_income_requirements", period) ) - eligible_based_on_disability = ( - eligible_based_on_person_disability | eligible_based_on_group_disability - ) - - # Count parents in benefit unit - parent_count = benunit.sum(person("is_parent", period)) - # Eligibility conditions for lone parents - lone_parent_eligible = (parent_count == 1) & in_work - - # Break out the complex nested conditions for couples - all_parents_working = benunit.all(in_work | ~person("is_parent", period)) - some_parents_working = benunit.any(in_work & person("is_parent", period)) - any_parent_disability_eligible = benunit.any( - eligible_based_on_disability & person("is_parent", period) - ) - - # Work condition for couples - either both working or one working with other disabled or receiving UC Carer Element - couple_work_condition = all_parents_working | ( - some_parents_working & any_parent_disability_eligible + # Reg 14(4)/15(4): limited capability for work or a specified benefit, + # with a partner who meets reg 14(3)/15(3). + partner_meets_work_and_income_conditions = ( + person.benunit.sum(meets_work_and_income_conditions) + - meets_work_and_income_conditions + ) > 0 + exempt_through_partner = ( + claimant_or_partner + & person( + "extended_childcare_entitlement_limited_capability_or_specified_benefit", + period, + ) + & partner_meets_work_and_income_conditions ) - couple_eligible = (parent_count == 2) & couple_work_condition - - return lone_parent_eligible | couple_eligible + return meets_work_and_income_conditions | exempt_through_partner diff --git a/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement.py b/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement.py index 17aa6da3f6..87172798d6 100644 --- a/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement.py +++ b/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement.py @@ -14,8 +14,14 @@ def formula(benunit, period, parameters): p = parameters(period).gov.dfe age = benunit.members("age", period) - # Compute weekly hours directly inside this function - weekly_hours_per_child = p.extended_childcare_entitlement.hours.calc(age) + # Only qualifying children of working parents (SI 2022/1134 reg 13) + # receive the entitlement's hours. + qualifying_child = benunit.members( + "extended_childcare_entitlement_qualifying_child", period + ) + weekly_hours_per_child = ( + p.extended_childcare_entitlement.hours.calc(age) * qualifying_child + ) # Get max hours used per child max_hours_used = benunit.members("max_free_entitlement_hours_used", period) diff --git a/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement_eligible.py b/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement_eligible.py index 0e5f5bc408..38ec10d2d1 100644 --- a/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement_eligible.py +++ b/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement_eligible.py @@ -9,29 +9,30 @@ class extended_childcare_entitlement_eligible(Variable): defined_for = "would_claim_extended_childcare" reference = ( "https://www.legislation.gov.uk/ukpga/2016/5/section/1", + "https://www.legislation.gov.uk/uksi/2022/1134/regulation/13", "https://www.legislation.gov.uk/uksi/2022/1134/regulation/14", "https://www.legislation.gov.uk/uksi/2022/1134/regulation/15", ) def formula(benunit, period, parameters): - # Check if household is in England - country = benunit.household("country", period) - countries = country.possible_values - in_england = country == countries.ENGLAND - - # The income conditions apply to the parent and the parent's partner - # (Childcare Act 2016 s.1(2)(d); SI 2022/1134 regs 14, 15 and 18): - # the claimant and partner of the benefit unit, not their children. person = benunit.members - person_meets_income_condition = person( - "extended_childcare_entitlement_meets_income_requirements", - period, - ) | ~person("is_claimant_or_partner", period) - meets_income_condition = benunit.all(person_meets_income_condition) - # Check work condition - work_eligible = ( - benunit("extended_childcare_entitlement_work_condition", period) > 0 + # A qualifying child of working parents is a young child of the + # description in reg 13, under compulsory school age and in England + # (Childcare Act 2016 s.1(2)(a)-(c)). + has_qualifying_child = benunit.any( + person("extended_childcare_entitlement_qualifying_child", period) + ) + + # The parent and the parent's partner, if any, must meet the + # conditions in regs 14 and 15 (Childcare Act 2016 s.1(2)(d)): the + # claimant and partner of the benefit unit, not their children. + claimant_or_partner = person("is_claimant_or_partner", period) + meets_parent_and_partner_conditions = benunit.any( + claimant_or_partner + ) & benunit.all( + person("extended_childcare_entitlement_work_condition", period) + | ~claimant_or_partner ) - return in_england & meets_income_condition & work_eligible + return has_qualifying_child & meets_parent_and_partner_conditions diff --git a/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement_qualifying_child.py b/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement_qualifying_child.py new file mode 100644 index 0000000000..8692fd3363 --- /dev/null +++ b/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement_qualifying_child.py @@ -0,0 +1,50 @@ +from policyengine_uk.model_api import * + + +class extended_childcare_entitlement_qualifying_child(Variable): + value_type = bool + entity = Person + label = "qualifying child of working parents for the extended childcare entitlement" + documentation = ( + "A young child for whom working parents can take up the extended " + "childcare entitlement: under compulsory school age and in England " + "(Childcare Act 2016 s.1(2)(a)-(b)), and at least the minimum age and " + "not looked after by a local authority (SI 2022/1134 reg 13(2); " + "SI 2016/1257 reg 3(1) before 1 December 2022)." + ) + definition_period = YEAR + reference = ( + "https://www.legislation.gov.uk/ukpga/2016/5/section/1", + "https://www.legislation.gov.uk/uksi/2022/1134/regulation/13", + ) + + def formula(person, period, parameters): + p = parameters(period).gov.dfe + age = person("age", period) + + # Compulsory school age starts at the lowest age in the scale + # (Education Act 1996 s.8); a young child has not reached it. + compulsory_school_age = p.compulsory_school_age + compulsory_school_age_start = min( + threshold + for threshold, is_compulsory in zip( + compulsory_school_age.thresholds, compulsory_school_age.amounts + ) + if is_compulsory + ) + under_compulsory_school_age = age < compulsory_school_age_start + + country = person.household("country", period) + in_england = country == country.possible_values.ENGLAND + + meets_minimum_age = ( + age >= p.extended_childcare_entitlement.young_child_minimum_age + ) + not_looked_after = ~person("is_looked_after_by_local_authority", period) + + return ( + under_compulsory_school_age + & in_england + & meets_minimum_age + & not_looked_after + ) diff --git a/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/is_child_receiving_extended_childcare.py b/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/is_child_receiving_extended_childcare.py index 6d3e35eb24..7819c70a63 100644 --- a/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/is_child_receiving_extended_childcare.py +++ b/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/is_child_receiving_extended_childcare.py @@ -17,11 +17,16 @@ def formula(person, period, parameters): # Check if hours > 0 for this age (using the hours parameter) hours_by_age = p.hours.calc(age) + qualifying_child = person( + "extended_childcare_entitlement_qualifying_child", period + ) + # Get the benefit unit's extended childcare entitlement amount benunit = person.benunit entitlement_amount = benunit("extended_childcare_entitlement", period) # Child is eligible if: - # 1. Hours > 0 for this age AND - # 2. Benefit unit's entitlement amount > 0 - return (hours_by_age > 0) & (entitlement_amount > 0) + # 1. They are a qualifying child of working parents AND + # 2. Hours > 0 for this age AND + # 3. Benefit unit's entitlement amount > 0 + return qualifying_child & (hours_by_age > 0) & (entitlement_amount > 0) diff --git a/policyengine_uk/variables/gov/dfe/maintenance_loans/maintenance_loan_household_income.py b/policyengine_uk/variables/gov/dfe/maintenance_loans/maintenance_loan_household_income.py index 6e6d22de82..3da851c3ec 100644 --- a/policyengine_uk/variables/gov/dfe/maintenance_loans/maintenance_loan_household_income.py +++ b/policyengine_uk/variables/gov/dfe/maintenance_loans/maintenance_loan_household_income.py @@ -10,15 +10,24 @@ class maintenance_loan_household_income(Variable): "Student Finance England-style household income for maintenance loan assessment. " "This can be set explicitly in simulations. By default, the model uses a proxy: " "dependent students use sponsor income from a selected older household benefit unit, " - "plus their own benefit-unit income; otherwise the model uses benefit-unit adjusted net income." + "plus their own benefit-unit income; otherwise the model uses benefit-unit adjusted net income. " + "A student is dependent only if none of the independence tests the model can see applies " + "(Education (Student Support) Regulations 2011 Sch 4 para 2(1)): aged under 25 on the first " + "day of the academic year (para 2(1)(a)), not in a couple (a proxy for para 2(1)(b)), and " + "not a parent (a proxy for para 2(1)(j))." ) definition_period = YEAR unit = GBP + reference = "https://www.legislation.gov.uk/uksi/2011/1986/schedule/4" def formula(person, period, parameters): + p = parameters(period).gov.dfe.maintenance_loans in_higher_education = person("maintenance_loan_in_higher_education", period) has_sponsor = person("maintenance_loan_has_sponsor", period) sponsor_income = person("maintenance_loan_sponsor_income", period) + # Sch 4 para 2(1)(a): a student aged 25 or over on the first day of the + # academic year is independent. + under_independent_age = person("age", period) < p.independent_student_age is_couple = person.benunit("is_couple", period) is_household_head = person("is_household_head", period) is_parent = person("is_parent", period) @@ -38,6 +47,7 @@ def formula(person, period, parameters): dependent_student_proxy = ( in_higher_education & has_sponsor + & under_independent_age & np.logical_not(is_couple) & np.logical_not(is_household_head) & np.logical_not(is_parent) diff --git a/policyengine_uk/variables/gov/dwp/receives_limited_capability_for_work_credits.py b/policyengine_uk/variables/gov/dwp/receives_limited_capability_for_work_credits.py new file mode 100644 index 0000000000..7b56eec431 --- /dev/null +++ b/policyengine_uk/variables/gov/dwp/receives_limited_capability_for_work_credits.py @@ -0,0 +1,18 @@ +from policyengine_uk.model_api import * + + +class receives_limited_capability_for_work_credits(Variable): + value_type = bool + entity = Person + label = "entitled to National Insurance credits for incapacity or limited capability for work" + documentation = ( + "Whether this person is entitled to National Insurance credits on the " + "grounds of incapacity for work or limited capability for work under " + "regulation 8B of the Social Security (Credits) Regulations 1975. " + "Tax-Free Childcare and the extended childcare entitlement treat these " + "credits like the benefits that let a partner qualify without working. " + "Not in the survey data, so false unless supplied." + ) + definition_period = YEAR + default_value = False + reference = "https://www.legislation.gov.uk/uksi/1975/556/regulation/8B" diff --git a/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_caring_or_incapacity_benefit.py b/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_caring_or_incapacity_benefit.py new file mode 100644 index 0000000000..2666284b3d --- /dev/null +++ b/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_caring_or_incapacity_benefit.py @@ -0,0 +1,23 @@ +from policyengine_uk.model_api import * + + +class tax_free_childcare_caring_or_incapacity_benefit(Variable): + value_type = bool + entity = Person + label = "receives a caring or incapacity benefit for Tax-Free Childcare" + documentation = ( + "Whether this person is paid or entitled to a benefit, allowance or " + "credit listed in regulation 13(1)(b) of the Childcare Payments " + "(Eligibility) Regulations 2015, or is on carer's leave (regulation " + "13(1)(c)). The list is incapacity benefit, severe disablement " + "allowance, carer's allowance, contributory employment and support " + "allowance, credits for incapacity or limited capability for work, " + "and Scottish carer's assistance. Disability Living Allowance and " + "Personal Independence Payment are not on it." + ) + definition_period = YEAR + reference = "https://www.legislation.gov.uk/uksi/2015/448/regulation/13" + + def formula(person, period, parameters): + p = parameters(period).gov.hmrc.tax_free_childcare + return add(person, period, p.caring_or_incapacity_benefits) > 0 diff --git a/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_meets_income_requirements.py b/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_meets_income_requirements.py index 5f85bffd2d..1e31e9ab84 100644 --- a/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_meets_income_requirements.py +++ b/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_meets_income_requirements.py @@ -6,6 +6,11 @@ class tax_free_childcare_meets_income_requirements(Variable): entity = Person label = "income eligible for the tax-free childcare" definition_period = YEAR + reference = ( + "https://www.legislation.gov.uk/uksi/2015/448/regulation/9", + "https://www.legislation.gov.uk/uksi/2015/448/regulation/13", + "https://www.legislation.gov.uk/uksi/2015/448/regulation/15", + ) def formula(person, period, parameters): p = parameters(period).gov.hmrc.tax_free_childcare @@ -26,10 +31,15 @@ def formula(person, period, parameters): "tax_free_childcare_self_employment_start_up_period", period, ) + # Reg 13(2)(b): a person regarded as in paid work through caring or + # incapacity has expected income equal to the minimum weekly income. + regarded_as_in_paid_work = person( + "tax_free_childcare_regarded_as_in_paid_work", period + ) # Get adjusted net income and check against max threshold ani = person("adjusted_net_income", period) - return (meets_minimum_income | in_start_up_period) & ( - ani <= p.income.income_limit - ) + return ( + meets_minimum_income | in_start_up_period | regarded_as_in_paid_work + ) & (ani <= p.income.income_limit) diff --git a/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_on_carers_leave.py b/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_on_carers_leave.py new file mode 100644 index 0000000000..2ca6a85527 --- /dev/null +++ b/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_on_carers_leave.py @@ -0,0 +1,16 @@ +from policyengine_uk.model_api import * + + +class tax_free_childcare_on_carers_leave(Variable): + value_type = bool + entity = Person + label = "on carer's leave for Tax-Free Childcare" + documentation = ( + "Whether this person is absent from work on carer's leave under " + "section 80J of the Employment Rights Act 1996, which regulation " + "13(1)(c) of the Childcare Payments (Eligibility) Regulations 2015 " + "treats like the caring and incapacity benefits from 6 April 2024." + ) + definition_period = YEAR + default_value = False + reference = "https://www.legislation.gov.uk/uksi/2015/448/regulation/13" diff --git a/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_regarded_as_in_paid_work.py b/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_regarded_as_in_paid_work.py new file mode 100644 index 0000000000..68632c343b --- /dev/null +++ b/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_regarded_as_in_paid_work.py @@ -0,0 +1,40 @@ +from policyengine_uk.model_api import * + + +class tax_free_childcare_regarded_as_in_paid_work(Variable): + value_type = bool + entity = Person + label = "regarded as in qualifying paid work for Tax-Free Childcare through caring or incapacity" + documentation = ( + "Whether regulation 13 of the Childcare Payments (Eligibility) " + "Regulations 2015 regards this person as in paid work, with expected " + "income equal to the minimum weekly income. It applies while the " + "person receives a caring or incapacity benefit (reg 13(1)(b)-(c)) " + "and has a partner in qualifying paid work (reg 13(1)(a)). The partner " + "does not count as in qualifying paid work while they receive such a " + "benefit themselves (reg 13(3)). A lone parent cannot qualify this " + "way. The partner's own minimum income is tested by the income " + "condition." + ) + definition_period = YEAR + reference = "https://www.legislation.gov.uk/uksi/2015/448/regulation/13" + + def formula(person, period, parameters): + claimant_or_partner = person("is_claimant_or_partner", period) + caring_or_incapacity = person( + "tax_free_childcare_caring_or_incapacity_benefit", period + ) + # Reg 13(1)(a) and (3): in paid work, and not paid or entitled to a + # caring or incapacity benefit. + in_work_without_caring_or_incapacity = ( + claimant_or_partner + & person("tax_free_childcare_treated_as_in_work", period) + & ~caring_or_incapacity + ) + partner_in_qualifying_paid_work = ( + person.benunit.sum(in_work_without_caring_or_incapacity) + - in_work_without_caring_or_incapacity + ) > 0 + return ( + claimant_or_partner & caring_or_incapacity & partner_in_qualifying_paid_work + ) diff --git a/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_work_condition.py b/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_work_condition.py index 18352d4172..94a92846f6 100644 --- a/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_work_condition.py +++ b/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_work_condition.py @@ -6,10 +6,12 @@ class tax_free_childcare_work_condition(Variable): entity = Person label = "work conditions for tax-free childcare" documentation = ( - "The person applying and, if they have one, their partner must be " - "in qualifying paid work, unless the partner has a qualifying " - "disability or incapacity. Both must be at least 16. Children in the " - "family play no part." + "The person applying and, if they have one, their partner must each " + "be at least 16 and in qualifying paid work. A person counts as in " + "qualifying paid work while on qualifying leave or statutory pay " + "(regs 12 and 14), or while they receive a caring or incapacity " + "benefit and their partner is in qualifying paid work (reg 13). " + "Children in the family play no part." ) definition_period = YEAR reference = ( @@ -17,53 +19,19 @@ class tax_free_childcare_work_condition(Variable): "https://www.legislation.gov.uk/ukpga/2014/28/section/6", "https://www.legislation.gov.uk/uksi/2015/448/regulation/3", "https://www.legislation.gov.uk/uksi/2015/448/regulation/9", + "https://www.legislation.gov.uk/uksi/2015/448/regulation/13", ) def formula(person, period, parameters): benunit = person.benunit # The person applying and their partner (Childcare Payments Act 2014 - # s.3(1), s.6; SI 2015/448 reg 3): the claimant or partner, aged 16+. - applicant_or_partner = person("is_claimant_or_partner", period) & person( - "over_16", period - ) + # s.3(1), s.6; SI 2015/448 reg 3). + claimant_or_partner = person("is_claimant_or_partner", period) - treated_as_in_work = person( - "tax_free_childcare_treated_as_in_work", - period, - ) + in_qualifying_paid_work = person( + "tax_free_childcare_treated_as_in_work", period + ) | person("tax_free_childcare_regarded_as_in_paid_work", period) + meets_condition = person("over_16", period) & in_qualifying_paid_work - # Get disability parameters and check eligibility - p_gc_disability = parameters( - period - ).gov.dwp.pension_credit.guarantee_credit.child.disability - receives_disability_programs = ( - add( - person, - period, - p_gc_disability.eligibility + p_gc_disability.severe.eligibility, - ) - > 0 - ) - - has_incapacity = person("incapacity_benefit", period) > 0 - eligible_based_on_disability = receives_disability_programs | has_incapacity - - # Build conditions - # Single adult conditions - is_single = person.benunit("is_single", period) - single_working = is_single & treated_as_in_work & applicant_or_partner - - # Couple conditions - is_couple = person.benunit("is_couple", period) - benunit_has_condition = benunit.any( - eligible_based_on_disability & applicant_or_partner - ) - benunit_has_worker = benunit.any(treated_as_in_work & applicant_or_partner) - couple_both_working = is_couple & benunit.all( - treated_as_in_work | ~applicant_or_partner - ) - couple_one_working_one_disabled = ( - is_couple & benunit_has_worker & benunit_has_condition - ) - - return single_working | couple_both_working | couple_one_working_one_disabled + # Reported on the applicant and partner; their children play no part. + return claimant_or_partner & benunit.all(meets_condition | ~claimant_or_partner) From 919468f2f30f4ccbf7c22ab17835a617cc381454 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Wed, 30 Sep 2026 08:53:07 -0400 Subject: [PATCH 2/9] Property-test Care to Learn, extended childcare, Tax-Free Childcare and maintenance loan against scalar references Co-Authored-By: Claude Opus 5.5 --- ...fe_childcare_student_support_properties.py | 408 ++++++++++++++++++ 1 file changed, 408 insertions(+) create mode 100644 policyengine_uk/tests/test_dfe_childcare_student_support_properties.py diff --git a/policyengine_uk/tests/test_dfe_childcare_student_support_properties.py b/policyengine_uk/tests/test_dfe_childcare_student_support_properties.py new file mode 100644 index 0000000000..a6bb6ee815 --- /dev/null +++ b/policyengine_uk/tests/test_dfe_childcare_student_support_properties.py @@ -0,0 +1,408 @@ +"""Care to Learn, extended childcare, maintenance loan and Tax-Free Childcare. + +Each property compares the model with an independent scalar reference written +from the source below, over randomly drawn families batched into one +Simulation per example. + +Invariants: + +1. Care to Learn (ESFA conditions of grant 2026-27, sections 1.2, 2.2, 2.3, + 4.1). For each benefit unit the amounts paid sum to the sum over the + Child Benefit children of min(childcare costs, weekly maximum x 52) when + some parent is eligible, and to 0 otherwise. Eligible means under 20, in + non-higher education, not an apprentice and living in England. At most one + person is paid, the eldest eligible parent. Each child adds at most the + per-child cap. +2. Extended childcare (SI 2022/1134 regs 11A, 13-15 and 18). A family is + eligible if and only if it has a young child of the minimum age for the + year (3, 2 in 2024, nine months from 2025), under 5 and not looked after. + Each claimant or partner must also meet reg 14(3)/15(3), meaning earnings + of at least 16 x minimum wage x 13 a quarter and adjusted net income of at + most £100,000, or meet reg 14(4)/15(4): a specified benefit or limited + capability for work, with a partner who meets reg 14(3)/15(3). PIP never + matters. +3. Tax-Free Childcare work condition (SI 2015/448 reg 13). Each applicant or + partner is in work, or receives a reg 13(1)(b) benefit and has a partner in + work who receives none (reg 13(3)). DLA, PIP and income-related ESA never + matter. Reg 13(2)(b) deems the minimum income for anyone regarded as in + paid work. +4. Maintenance loan household income (SI 2011/1986 Sch 4 para 2(1)(a)). A + student's assessed income is their own benefit unit's income plus the + sponsor's only if they are under 25 and the model detects a sponsor. At 25 + or over it is exactly their own, so it never falls when the sponsor's + income falls, and never exceeds the dependent-student figure. + +Scope: these test the encoded conditions, not full entitlement. Travel costs +under Care to Learn, the reg 16/17 leave exemptions and National Insurance +number conditions of the extended entitlement, and Sch 4 para 2(1)(b)-(k) +beyond the couple and parent proxies are not modelled. Sources were fetched on +2026-09-28: +https://www.gov.uk/government/publications/care-to-learn-conditions-of-grant-funding/care-to-learn-academic-year-2026-to-2027-conditions-of-grant-funding +https://www.legislation.gov.uk/uksi/2022/1134/regulation/13 +https://www.legislation.gov.uk/uksi/2022/1134/regulation/14 +https://www.legislation.gov.uk/uksi/2022/1134/regulation/15 +https://www.legislation.gov.uk/uksi/2022/1134/regulation/11A +https://www.legislation.gov.uk/uksi/2022/1134/regulation/18 +https://www.legislation.gov.uk/uksi/2023/1330/regulation/2/made +https://www.legislation.gov.uk/uksi/2015/448/regulation/13 +https://www.legislation.gov.uk/uksi/2011/1986/schedule/4 +""" + +from unittest.mock import patch + +import numpy as np +from hypothesis import HealthCheck, given, settings +from hypothesis import strategies as st + +from policyengine_uk import Simulation +from policyengine_uk.tax_benefit_system import system + +_PROPERTY_SYSTEM = system.clone() +PROPERTY_SETTINGS = settings( + max_examples=25, + deadline=None, + derandomize=True, + suppress_health_check=[HealthCheck.too_slow, HealthCheck.data_too_large], +) +EDUCATIONS = ( + "NOT_IN_EDUCATION", + "LOWER_SECONDARY", + "UPPER_SECONDARY", + "POST_SECONDARY", + "TERTIARY", +) +MINIMUM_WAGE = 10 +# Reg 18: 16 hours x minimum wage x 13 weeks. +QUARTERLY_MINIMUM = MINIMUM_WAGE * 16 * 13 +INCOME_LIMIT = 100_000 + + +def simulate(families, year): + """One Simulation for many families, each its own benefit unit and household. + + A family is (people, benunit_inputs, household_inputs), where people is a + list of per-person input dicts. + """ + situation = {"people": {}, "benunits": {}, "households": {}} + names = [] + for i, (people, benunit_inputs, household_inputs) in enumerate(families): + members = [] + for j, inputs in enumerate(people): + name = f"p{i}_{j}" + situation["people"][name] = {k: {year: v} for k, v in inputs.items()} + members.append(name) + names.append((i, j)) + situation["benunits"][f"b{i}"] = { + "members": members, + **{k: {year: v} for k, v in benunit_inputs.items()}, + } + situation["households"][f"h{i}"] = { + "members": members, + **{k: {year: v} for k, v in household_inputs.items()}, + } + with patch( + "policyengine_uk.simulation.CountryTaxBenefitSystem", + side_effect=_PROPERTY_SYSTEM.clone, + ): + sim = Simulation(situation=situation) + return sim, names + + +def by_family(values, names, n_families): + out = [[] for _ in range(n_families)] + for value, (i, _) in zip(values, names): + out[i].append(value) + return out + + +def close(a, b): + return abs(a - b) <= 0.02 + 1e-6 * abs(b) + + +# 1. Care to Learn --------------------------------------------------------- + + +young_parent = st.fixed_dictionaries( + { + "age": st.integers(14, 22), + "current_education": st.sampled_from(EDUCATIONS), + "is_apprentice": st.booleans(), + } +) +child_costs = st.lists( + st.tuples(st.integers(0, 5), st.sampled_from([0, 1_000, 9_360, 10_140, 25_000])), + min_size=0, + max_size=3, +) +care_to_learn_family = st.tuples( + st.lists(young_parent, min_size=1, max_size=2), + child_costs, + st.sampled_from(["LONDON", "NORTH_EAST"]), +) + + +def care_to_learn_eligible_reference(parent, n_children): + return ( + n_children > 0 + and parent["age"] < 20 + and parent["current_education"] not in {"NOT_IN_EDUCATION", "TERTIARY"} + and not parent["is_apprentice"] + ) + + +@PROPERTY_SETTINGS +@given(st.lists(care_to_learn_family, min_size=1, max_size=6)) +def test_care_to_learn_pays_each_child_once_up_to_the_per_child_cap(families): + built = [] + for parents, children, region in families: + people = [{**p, "is_parent": True} for p in parents] + [ + {"age": age, "childcare_expenses": cost} for age, cost in children + ] + built.append((people, {}, {"country": "ENGLAND", "region": region})) + sim, names = simulate(built, 2025) + paid = by_family(sim.calculate("care_to_learn", 2025), names, len(families)) + + for (parents, children, region), amounts in zip(families, paid): + cap = (195 if region == "LONDON" else 180) * 52 + eligible = [care_to_learn_eligible_reference(p, len(children)) for p in parents] + expected = sum(min(cost, cap) for _, cost in children) if any(eligible) else 0 + assert close(sum(amounts), expected), (parents, children, region, amounts) + assert sum(amount > 0 for amount in amounts) <= 1 + assert sum(amounts) <= len(children) * cap + 0.02 + if expected > 0: + # The one payment goes to an eligible parent of the greatest age. + eldest_age = max(p["age"] for k, p in enumerate(parents) if eligible[k]) + paid_to = [k for k in range(len(parents)) if amounts[k] > 0] + assert len(paid_to) == 1 + assert eligible[paid_to[0]] + assert parents[paid_to[0]]["age"] == eldest_age + # Children are never paid. + assert all(a == 0 for a in amounts[len(parents) :]) + + +# 2. Extended childcare ---------------------------------------------------- + + +STATUS_INPUTS = { + "carers_allowance": 4_000, + "esa_contrib": 4_000, + "incapacity_benefit": 4_000, + "uc_limited_capability_for_WRA": True, + "receives_limited_capability_for_work_credits": True, +} +extended_adult = st.fixed_dictionaries( + { + "age": st.integers(20, 60), + "earnings": st.sampled_from([0, 8_316, 8_320, 20_000, 100_000, 100_001]), + "status": st.sampled_from([None, *STATUS_INPUTS]), + "pip": st.sampled_from([0, 5_000]), + } +) +extended_child = st.tuples(st.sampled_from([0.5, 0.75, 1, 2, 3, 4, 6]), st.booleans()) +extended_family = st.tuples( + st.lists(extended_adult, min_size=1, max_size=2), + st.lists(extended_child, min_size=0, max_size=2), +) +YOUNG_CHILD_MINIMUM_AGE = {2023: 3, 2024: 2, 2025: 0.75, 2026: 0.75} + + +def meets_work_and_income(adult): + earnings = adult["earnings"] + return ( + earnings > 0 and earnings / 4 >= QUARTERLY_MINIMUM and earnings <= INCOME_LIMIT + ) + + +@PROPERTY_SETTINGS +@given( + st.sampled_from([2023, 2024, 2025, 2026]), + st.lists(extended_family, min_size=1, max_size=6), +) +def test_extended_childcare_eligibility_matches_regs_13_to_15(year, families): + built = [] + for adults, children in families: + people = [] + for adult in adults: + inputs = { + "age": adult["age"], + "is_parent": bool(children), + "employment_income": adult["earnings"], + "adjusted_net_income": adult["earnings"], + "minimum_wage": MINIMUM_WAGE, + "pip": adult["pip"], + } + if adult["status"]: + inputs[adult["status"]] = STATUS_INPUTS[adult["status"]] + people.append(inputs) + for age, looked_after in children: + people.append( + {"age": age, "is_looked_after_by_local_authority": looked_after} + ) + built.append((people, {}, {"country": "ENGLAND"})) + sim, _ = simulate(built, year) + eligible = sim.calculate("extended_childcare_entitlement_eligible", year) + + minimum_age = YOUNG_CHILD_MINIMUM_AGE[year] + for (adults, children), result in zip(families, eligible): + has_young_child = any( + minimum_age <= age < 5 and not looked_after + for age, looked_after in children + ) + meets = [meets_work_and_income(a) for a in adults] + ok = [ + meets[k] + or ( + adults[k]["status"] is not None + and any(meets[m] for m in range(len(adults)) if m != k) + ) + for k in range(len(adults)) + ] + assert bool(result) == (has_young_child and all(ok)), ( + year, + adults, + children, + ) + + +# 3. Tax-Free Childcare ---------------------------------------------------- + + +REG_13_BENEFITS = { + "carers_allowance": 4_000, + "incapacity_benefit": 4_000, + "sda": 4_000, + "esa_contrib": 4_000, + "carer_support_payment": 4_000, + "receives_limited_capability_for_work_credits": True, +} +NOT_REG_13 = {"dla": 4_000, "pip": 4_000} +tfc_adult = st.fixed_dictionaries( + { + "in_work": st.booleans(), + "benefit": st.sampled_from([None, *REG_13_BENEFITS]), + "other": st.sampled_from([None, *NOT_REG_13]), + } +) +tfc_family = st.tuples(st.lists(tfc_adult, min_size=1, max_size=2), st.booleans()) + + +@PROPERTY_SETTINGS +@given(st.lists(tfc_family, min_size=1, max_size=8)) +def test_tax_free_childcare_work_condition_matches_reg_13(families): + built = [] + for adults, income_related_esa in families: + people = [] + for adult in adults: + inputs = { + "age": 35, + "in_work": adult["in_work"], + "adjusted_net_income": 20_000, + "minimum_wage": MINIMUM_WAGE, + } + if adult["benefit"]: + inputs[adult["benefit"]] = REG_13_BENEFITS[adult["benefit"]] + if adult["other"]: + inputs[adult["other"]] = NOT_REG_13[adult["other"]] + people.append(inputs) + people.append({"age": 3}) + benunit = {"esa_income": 4_000} if income_related_esa else {} + built.append((people, benunit, {"country": "ENGLAND"})) + sim, names = simulate(built, 2025) + work = by_family( + sim.calculate("tax_free_childcare_work_condition", 2025), + names, + len(families), + ) + regarded = by_family( + sim.calculate("tax_free_childcare_regarded_as_in_paid_work", 2025), + names, + len(families), + ) + meets_income = by_family( + sim.calculate("tax_free_childcare_meets_income_requirements", 2025), + names, + len(families), + ) + + for (adults, _), work_values, regarded_values, income_values in zip( + families, work, regarded, meets_income + ): + has_benefit = [a["benefit"] is not None for a in adults] + reference_regarded = [ + has_benefit[k] + and any( + adults[m]["in_work"] and not has_benefit[m] + for m in range(len(adults)) + if m != k + ) + for k in range(len(adults)) + ] + family_meets = all( + adults[k]["in_work"] or reference_regarded[k] for k in range(len(adults)) + ) + n = len(adults) + assert [bool(v) for v in regarded_values[:n]] == reference_regarded + assert [bool(v) for v in work_values[:n]] == [family_meets] * n + assert not work_values[n] # the child + # Reg 13(2)(b): regarded as having the minimum income. + for k in range(n): + if reference_regarded[k]: + assert income_values[k] + + +# 4. Maintenance loan household income --------------------------------------- + + +student_household = st.fixed_dictionaries( + { + "parent_age": st.integers(35, 70), + "parent_income": st.sampled_from([0, 15_000, 40_000, 90_000]), + "student_age": st.integers(18, 35), + "student_income": st.sampled_from([0, 5_000, 12_000]), + } +) + + +@PROPERTY_SETTINGS +@given(st.lists(student_household, min_size=1, max_size=6)) +def test_maintenance_loan_household_income_applies_the_age_25_test(households): + situation = {"people": {}, "benunits": {}, "households": {}} + year = 2025 + for i, h in enumerate(households): + parent, student = f"parent{i}", f"student{i}" + situation["people"][parent] = { + "age": {year: h["parent_age"]}, + "current_education": {year: "NOT_IN_EDUCATION"}, + "adjusted_net_income": {year: h["parent_income"]}, + "is_household_head": {year: True}, + } + situation["people"][student] = { + "age": {year: h["student_age"]}, + "current_education": {year: "TERTIARY"}, + "adjusted_net_income": {year: h["student_income"]}, + "is_household_head": {year: False}, + } + situation["benunits"][f"pb{i}"] = {"members": [parent]} + situation["benunits"][f"sb{i}"] = {"members": [student]} + situation["households"][f"h{i}"] = { + "members": [parent, student], + "country": {year: "ENGLAND"}, + } + with patch( + "policyengine_uk.simulation.CountryTaxBenefitSystem", + side_effect=_PROPERTY_SYSTEM.clone, + ): + sim = Simulation(situation=situation) + income = sim.calculate("maintenance_loan_household_income", year).reshape(-1, 2) + + for h, (parent_value, student_value) in zip(households, income): + age, parent_age = h["student_age"], h["parent_age"] + has_sponsor = parent_age >= 29 and age + 10 <= parent_age <= age + 35 + dependent = age < 25 and has_sponsor + expected = h["student_income"] + dependent * h["parent_income"] + assert close(student_value, expected), h + assert close(parent_value, h["parent_income"]), h + # Independence never adds the parents' income. + if age >= 25: + assert close(student_value, h["student_income"]), h + assert student_value >= h["student_income"] - 0.02 From 3567464b8538a11d71d51ec0c80aeb228d1a7550 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Wed, 30 Sep 2026 09:14:44 -0400 Subject: [PATCH 3/9] Attribute the UC carer element to the carer on an award; keep reg 13(3) to (1)(b) benefits - Extended childcare: reg 11A(1)(c) is the carer element of a Universal Credit award, so count it for the carer only, and only where the benefit unit's UC award includes it (receives_uc_carer_element), not for both partners of any benefit unit with a carer. - Tax-Free Childcare: reg 13(3) excludes a working partner who receives a reg 13(1)(b) benefit, not one on carer's leave under 13(1)(c). Move carer's leave out of the benefit list into its own dated switch. Co-Authored-By: Claude Opus 5.5 --- .../disability_criteria.yaml | 4 +- .../carers_leave_qualifies.yaml | 14 ++++ .../caring_or_incapacity_benefits.yaml | 13 +--- ..._childcare_entitlement_work_condition.yaml | 67 +++++++++++++++++-- .../tax_free_childcare_work_condition.yaml | 20 ++++++ ...fe_childcare_student_support_properties.py | 6 +- ...limited_capability_or_specified_benefit.py | 6 +- .../receives_uc_carer_element.py | 24 +++++++ ..._childcare_caring_or_incapacity_benefit.py | 13 ++-- ...free_childcare_regarded_as_in_paid_work.py | 34 ++++++---- 10 files changed, 159 insertions(+), 42 deletions(-) create mode 100644 policyengine_uk/parameters/gov/hmrc/tax_free_childcare/carers_leave_qualifies.yaml create mode 100644 policyengine_uk/variables/gov/dwp/universal_credit/carer_element/receives_uc_carer_element.py diff --git a/policyengine_uk/parameters/gov/dfe/extended_childcare_entitlement/disability_criteria.yaml b/policyengine_uk/parameters/gov/dfe/extended_childcare_entitlement/disability_criteria.yaml index 9ebcc5d7c2..6b2244d2e9 100644 --- a/policyengine_uk/parameters/gov/dfe/extended_childcare_entitlement/disability_criteria.yaml +++ b/policyengine_uk/parameters/gov/dfe/extended_childcare_entitlement/disability_criteria.yaml @@ -18,7 +18,7 @@ values: - carers_allowance # (iv): carer's allowance - esa_contrib # (v): contributory employment and support allowance - receives_limited_capability_for_work_credits # (vi): credits for incapacity for work or limited capability for work - - uc_carer_element # (vii): Universal Credit carer element + - receives_uc_carer_element # (vii): the carer element of Universal Credit - uc_limited_capability_for_WRA # (viii): limited capability for work and work-related activity # SI 2022/1134 reg 14(4)(b) and the specified benefits in reg 14(5) as made, # moved to reg 11A from 30 March 2023 by SI 2023/276. @@ -26,7 +26,7 @@ values: - uc_limited_capability_for_WRA # 14(4)(b)(i)-(ii): limited capability for work, or for work and work-related activity - carers_allowance # 11A(1)(a): carer's allowance - carer_support_payment # 11A(1)(b): carer's assistance under the Social Security (Scotland) Act 2018 s.28 - - uc_carer_element # 11A(1)(c): Universal Credit carer element + - receives_uc_carer_element # 11A(1)(c): the Universal Credit carer element (an award including it; reg 14(5)(a) as made) - receives_limited_capability_for_work_credits # 11A(1)(d): credits for incapacity for work or limited capability for work - esa_contrib # 11A(1)(e): employment and support allowance (contribution-based) - esa_income # 11A(1)(e): employment and support allowance (income-related) diff --git a/policyengine_uk/parameters/gov/hmrc/tax_free_childcare/carers_leave_qualifies.yaml b/policyengine_uk/parameters/gov/hmrc/tax_free_childcare/carers_leave_qualifies.yaml new file mode 100644 index 0000000000..3d96814ccc --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/tax_free_childcare/carers_leave_qualifies.yaml @@ -0,0 +1,14 @@ +description: HMRC regards a person on carer's leave whose partner is in qualifying paid work as in qualifying paid work themselves, for Tax-Free Childcare, if this is true. +metadata: + reference: + - title: The Childcare Payments (Eligibility) Regulations 2015 - Regulation 13(1)(c) + href: https://www.legislation.gov.uk/uksi/2015/448/regulation/13 + - title: The Carer's Leave (Consequential Amendments to Subordinate Legislation) Regulations 2024 - Regulation 8(2) + href: https://www.legislation.gov.uk/uksi/2024/266/regulation/8/made + period: year + unit: bool + label: Tax-Free Childcare carer's leave counts as caring +values: + 2015-01-01: false + # SI 2024/266 reg 8(2) inserted 13(1)(c) from 6 April 2024. + 2024-04-06: true diff --git a/policyengine_uk/parameters/gov/hmrc/tax_free_childcare/caring_or_incapacity_benefits.yaml b/policyengine_uk/parameters/gov/hmrc/tax_free_childcare/caring_or_incapacity_benefits.yaml index c5e84d0680..632aca5c6b 100644 --- a/policyengine_uk/parameters/gov/hmrc/tax_free_childcare/caring_or_incapacity_benefits.yaml +++ b/policyengine_uk/parameters/gov/hmrc/tax_free_childcare/caring_or_incapacity_benefits.yaml @@ -1,12 +1,10 @@ -description: HMRC regards a person whose partner is in qualifying paid work as in qualifying paid work themselves, for Tax-Free Childcare, while they receive or are entitled to any of these benefits, allowances or credits, or are on carer's leave. +description: HMRC regards a person whose partner is in qualifying paid work as in qualifying paid work themselves, for Tax-Free Childcare, while they are paid or entitled to any of these benefits, allowances or credits. metadata: reference: - title: The Childcare Payments (Eligibility) Regulations 2015 - Regulation 13(1) href: https://www.legislation.gov.uk/uksi/2015/448/regulation/13 - title: The Childcare Payments (Miscellaneous Amendments) Regulations 2022 - Regulation 2(6) href: https://www.legislation.gov.uk/uksi/2022/1148/regulation/2/made - - title: The Carer's Leave (Consequential Amendments to Subordinate Legislation) Regulations 2024 - Regulation 8(2) - href: https://www.legislation.gov.uk/uksi/2024/266/regulation/8/made period: year unit: program label: Tax-Free Childcare caring or incapacity benefits @@ -25,12 +23,3 @@ values: - esa_contrib - receives_limited_capability_for_work_credits - carer_support_payment # 13(1)(b)(vii): carer's assistance under the Social Security (Scotland) Act 2018 s.28 - # SI 2024/266 reg 8(2) inserted 13(1)(c) from 6 April 2024. - 2024-04-06: - - incapacity_benefit - - sda - - carers_allowance - - esa_contrib - - receives_limited_capability_for_work_credits - - carer_support_payment - - tax_free_childcare_on_carers_leave # 13(1)(c): carer's leave under the Employment Rights Act 1996 s.80J diff --git a/policyengine_uk/tests/policy/baseline/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement_work_condition.yaml b/policyengine_uk/tests/policy/baseline/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement_work_condition.yaml index 713a204129..57113d373a 100644 --- a/policyengine_uk/tests/policy/baseline/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement_work_condition.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement_work_condition.yaml @@ -77,9 +77,10 @@ output: extended_childcare_entitlement_work_condition: [true, true, false] -# Reg 11A(1)(c): the Universal Credit carer element. It is a benefit-unit -# amount, so it counts for both members of the couple. -- name: One parent working, the family has the UC carer element - both meet the condition +# Reg 11A(1)(c): the Universal Credit carer element, meaning an award of +# Universal Credit that includes it (reg 14(5)(a) as made). It belongs to the +# carer. +- name: One parent working, the other the carer on a UC award with the carer element - both meet the condition period: 2025 input: people: @@ -92,16 +93,74 @@ parent2: age: 38 is_parent: true + is_carer_for_benefits: true minimum_wage: 10 child: age: 4 benunits: benunit: members: [parent1, parent2, child] - uc_carer_element: 100 + universal_credit: 3_000 + uc_carer_element: 2_400 output: + receives_uc_carer_element: [false, true, false] extended_childcare_entitlement_work_condition: [true, true, false] +# The earner is the carer, so the carer element does not make the non-working +# partner a person entitled to a specified benefit. +- name: The earner is the carer on the UC award - the non-working partner does not meet the condition + period: 2025 + input: + people: + parent1: + age: 40 + is_parent: true + is_carer_for_benefits: true + employment_income: 20_000 + adjusted_net_income: 20_000 + minimum_wage: 10 + parent2: + age: 38 + is_parent: true + minimum_wage: 10 + child: + age: 4 + benunits: + benunit: + members: [parent1, parent2, child] + universal_credit: 3_000 + uc_carer_element: 2_400 + output: + receives_uc_carer_element: [true, false, false] + extended_childcare_entitlement_work_condition: [true, false, false] + +# Without a Universal Credit award there is no carer element to be entitled to. +- name: A carer with no UC award - does not meet the condition through the carer element + period: 2025 + input: + people: + parent1: + age: 40 + is_parent: true + employment_income: 20_000 + adjusted_net_income: 20_000 + minimum_wage: 10 + parent2: + age: 38 + is_parent: true + is_carer_for_benefits: true + minimum_wage: 10 + child: + age: 4 + benunits: + benunit: + members: [parent1, parent2, child] + universal_credit: 0 + uc_carer_element: 2_400 + output: + receives_uc_carer_element: [false, false, false] + extended_childcare_entitlement_work_condition: [true, false, false] + # Reg 11A(1)(e): employment and support allowance under WRA 2007 s.1, which # includes income-related ESA. - name: One parent working, the family has income-related ESA in 2025 - both meet the condition diff --git a/policyengine_uk/tests/policy/baseline/gov/hmrc/tax_free_childcare/tax_free_childcare_work_condition.yaml b/policyengine_uk/tests/policy/baseline/gov/hmrc/tax_free_childcare/tax_free_childcare_work_condition.yaml index 85efbe37a0..0510e5839f 100644 --- a/policyengine_uk/tests/policy/baseline/gov/hmrc/tax_free_childcare/tax_free_childcare_work_condition.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/hmrc/tax_free_childcare/tax_free_childcare_work_condition.yaml @@ -512,6 +512,26 @@ output: tax_free_childcare_work_condition: [false, false] +# Reg 13(3) excludes a working partner who receives a reg 13(1)(b) benefit, not +# one on carer's leave under reg 13(1)(c): the spouse on Carer's Allowance is +# still regarded as in qualifying paid work. +- name: Working partner on carer's leave does not stop the other partner qualifying under reg 13 + period: 2025 + input: + people: + person: + in_work: true + tax_free_childcare_on_carers_leave: true + spouse: + in_work: false + carers_allowance: 4_000 + benunits: + benunit: + members: [person, spouse] + output: + tax_free_childcare_regarded_as_in_paid_work: [false, true] + tax_free_childcare_work_condition: true + - name: A working lone parent with an 18-year-old and a toddler meets the work condition # Default inputs: the 18-year-old is the parent's child, not a partner who # would also have to work. diff --git a/policyengine_uk/tests/test_dfe_childcare_student_support_properties.py b/policyengine_uk/tests/test_dfe_childcare_student_support_properties.py index a6bb6ee815..e748fe4ca4 100644 --- a/policyengine_uk/tests/test_dfe_childcare_student_support_properties.py +++ b/policyengine_uk/tests/test_dfe_childcare_student_support_properties.py @@ -19,8 +19,10 @@ Each claimant or partner must also meet reg 14(3)/15(3), meaning earnings of at least 16 x minimum wage x 13 a quarter and adjusted net income of at most £100,000, or meet reg 14(4)/15(4): a specified benefit or limited - capability for work, with a partner who meets reg 14(3)/15(3). PIP never - matters. + capability for work, with a partner who meets reg 14(3)/15(3). PIP itself + never matters here. In datasets, reported DLA/PIP can still reach the + condition through uc_limited_capability_for_WRA's default + (is_disabled_for_benefits), which these families leave false. 3. Tax-Free Childcare work condition (SI 2015/448 reg 13). Each applicant or partner is in work, or receives a reg 13(1)(b) benefit and has a partner in work who receives none (reg 13(3)). DLA, PIP and income-related ESA never diff --git a/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/conditions/extended_childcare_entitlement_limited_capability_or_specified_benefit.py b/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/conditions/extended_childcare_entitlement_limited_capability_or_specified_benefit.py index 93b9e00441..79846e1c91 100644 --- a/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/conditions/extended_childcare_entitlement_limited_capability_or_specified_benefit.py +++ b/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/conditions/extended_childcare_entitlement_limited_capability_or_specified_benefit.py @@ -12,9 +12,9 @@ class extended_childcare_entitlement_limited_capability_or_specified_benefit(Var "regs 11A, 14(4)(b) and 15(4); SI 2016/1257 reg 9(1)(b) before " "1 December 2022). A parent or partner in this position meets the " "parent and partner conditions without the work or income conditions " - "when the other meets them. A benefit-unit-level benefit in the list, " - "such as the Universal Credit carer element, counts for both members " - "of a couple." + "when the other meets them. A benefit-unit-level benefit in the list " + "(income-related ESA) counts for both members of a couple; the " + "Universal Credit carer element counts for the carer only." ) definition_period = YEAR reference = ( diff --git a/policyengine_uk/variables/gov/dwp/universal_credit/carer_element/receives_uc_carer_element.py b/policyengine_uk/variables/gov/dwp/universal_credit/carer_element/receives_uc_carer_element.py new file mode 100644 index 0000000000..4ef487bd6c --- /dev/null +++ b/policyengine_uk/variables/gov/dwp/universal_credit/carer_element/receives_uc_carer_element.py @@ -0,0 +1,24 @@ +from policyengine_uk.model_api import * + + +class receives_uc_carer_element(Variable): + value_type = bool + entity = Person + label = "receives the Universal Credit carer element" + documentation = ( + "Whether this person is a carer in a benefit unit whose Universal " + "Credit award includes the carer element (Universal Credit " + "Regulations 2013 reg 29). The carer element is a benefit-unit " + "amount; this attributes it to the carer, and requires an award, " + "since uc_carer_element is calculated for any benefit unit with a " + "carer." + ) + definition_period = YEAR + reference = "https://www.legislation.gov.uk/uksi/2013/376/regulation/29" + + def formula(person, period, parameters): + benunit = person.benunit + award_includes_carer_element = (benunit("universal_credit", period) > 0) & ( + benunit("uc_carer_element", period) > 0 + ) + return person("is_carer_for_benefits", period) & award_includes_carer_element diff --git a/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_caring_or_incapacity_benefit.py b/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_caring_or_incapacity_benefit.py index 2666284b3d..36dbd2460a 100644 --- a/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_caring_or_incapacity_benefit.py +++ b/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_caring_or_incapacity_benefit.py @@ -8,12 +8,13 @@ class tax_free_childcare_caring_or_incapacity_benefit(Variable): documentation = ( "Whether this person is paid or entitled to a benefit, allowance or " "credit listed in regulation 13(1)(b) of the Childcare Payments " - "(Eligibility) Regulations 2015, or is on carer's leave (regulation " - "13(1)(c)). The list is incapacity benefit, severe disablement " - "allowance, carer's allowance, contributory employment and support " - "allowance, credits for incapacity or limited capability for work, " - "and Scottish carer's assistance. Disability Living Allowance and " - "Personal Independence Payment are not on it." + "(Eligibility) Regulations 2015: incapacity benefit, severe " + "disablement allowance, carer's allowance, contributory employment " + "and support allowance, credits for incapacity or limited capability " + "for work, and Scottish carer's assistance. Disability Living " + "Allowance and Personal Independence Payment are not on the list. " + "Carer's leave (regulation 13(1)(c)) is handled separately, because " + "regulation 13(3) refers to paragraph (1)(b) only." ) definition_period = YEAR reference = "https://www.legislation.gov.uk/uksi/2015/448/regulation/13" diff --git a/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_regarded_as_in_paid_work.py b/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_regarded_as_in_paid_work.py index 68632c343b..1e2b2ed534 100644 --- a/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_regarded_as_in_paid_work.py +++ b/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_regarded_as_in_paid_work.py @@ -9,32 +9,40 @@ class tax_free_childcare_regarded_as_in_paid_work(Variable): "Whether regulation 13 of the Childcare Payments (Eligibility) " "Regulations 2015 regards this person as in paid work, with expected " "income equal to the minimum weekly income. It applies while the " - "person receives a caring or incapacity benefit (reg 13(1)(b)-(c)) " - "and has a partner in qualifying paid work (reg 13(1)(a)). The partner " - "does not count as in qualifying paid work while they receive such a " - "benefit themselves (reg 13(3)). A lone parent cannot qualify this " - "way. The partner's own minimum income is tested by the income " - "condition." + "person receives a caring or incapacity benefit (reg 13(1)(b)) or, " + "from 6 April 2024, is on carer's leave (reg 13(1)(c)), and has a " + "partner in qualifying paid work (reg 13(1)(a)). The partner does not " + "count as in qualifying paid work while they receive a reg 13(1)(b) " + "benefit themselves (reg 13(3)); carer's leave does not have that " + "effect. A lone parent cannot qualify this way. The partner's own " + "minimum income is tested by the income condition." ) definition_period = YEAR reference = "https://www.legislation.gov.uk/uksi/2015/448/regulation/13" def formula(person, period, parameters): + p = parameters(period).gov.hmrc.tax_free_childcare claimant_or_partner = person("is_claimant_or_partner", period) - caring_or_incapacity = person( + caring_or_incapacity_benefit = person( "tax_free_childcare_caring_or_incapacity_benefit", period ) + on_qualifying_carers_leave = ( + person("tax_free_childcare_on_carers_leave", period) + & p.carers_leave_qualifies + ) # Reg 13(1)(a) and (3): in paid work, and not paid or entitled to a - # caring or incapacity benefit. - in_work_without_caring_or_incapacity = ( + # reg 13(1)(b) benefit. + in_work_without_caring_or_incapacity_benefit = ( claimant_or_partner & person("tax_free_childcare_treated_as_in_work", period) - & ~caring_or_incapacity + & ~caring_or_incapacity_benefit ) partner_in_qualifying_paid_work = ( - person.benunit.sum(in_work_without_caring_or_incapacity) - - in_work_without_caring_or_incapacity + person.benunit.sum(in_work_without_caring_or_incapacity_benefit) + - in_work_without_caring_or_incapacity_benefit ) > 0 return ( - claimant_or_partner & caring_or_incapacity & partner_in_qualifying_paid_work + claimant_or_partner + & (caring_or_incapacity_benefit | on_qualifying_carers_leave) + & partner_in_qualifying_paid_work ) From 3bcf1026c2504e22c3923dc41bcd736143432b4f Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Wed, 30 Sep 2026 11:13:24 -0400 Subject: [PATCH 4/9] Property-test the carer element's attribution and reg 13(3)'s reach; tighten citations Co-Authored-By: Claude Opus 5.5 --- .../disability_criteria.yaml | 2 +- ...fe_childcare_student_support_properties.py | 40 +++++++++++++------ .../tax_free_childcare_on_carers_leave.py | 4 +- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/policyengine_uk/parameters/gov/dfe/extended_childcare_entitlement/disability_criteria.yaml b/policyengine_uk/parameters/gov/dfe/extended_childcare_entitlement/disability_criteria.yaml index 6b2244d2e9..abd6c0723c 100644 --- a/policyengine_uk/parameters/gov/dfe/extended_childcare_entitlement/disability_criteria.yaml +++ b/policyengine_uk/parameters/gov/dfe/extended_childcare_entitlement/disability_criteria.yaml @@ -26,7 +26,7 @@ values: - uc_limited_capability_for_WRA # 14(4)(b)(i)-(ii): limited capability for work, or for work and work-related activity - carers_allowance # 11A(1)(a): carer's allowance - carer_support_payment # 11A(1)(b): carer's assistance under the Social Security (Scotland) Act 2018 s.28 - - receives_uc_carer_element # 11A(1)(c): the Universal Credit carer element (an award including it; reg 14(5)(a) as made) + - receives_uc_carer_element # 11A(1)(c): the carer element under UC Regs reg 29, on an award (reg 14(5)(a) as made: "an award of universal credit [...] that includes the carer element") - receives_limited_capability_for_work_credits # 11A(1)(d): credits for incapacity for work or limited capability for work - esa_contrib # 11A(1)(e): employment and support allowance (contribution-based) - esa_income # 11A(1)(e): employment and support allowance (income-related) diff --git a/policyengine_uk/tests/test_dfe_childcare_student_support_properties.py b/policyengine_uk/tests/test_dfe_childcare_student_support_properties.py index e748fe4ca4..ce8fb478c5 100644 --- a/policyengine_uk/tests/test_dfe_childcare_student_support_properties.py +++ b/policyengine_uk/tests/test_dfe_childcare_student_support_properties.py @@ -24,8 +24,10 @@ condition through uc_limited_capability_for_WRA's default (is_disabled_for_benefits), which these families leave false. 3. Tax-Free Childcare work condition (SI 2015/448 reg 13). Each applicant or - partner is in work, or receives a reg 13(1)(b) benefit and has a partner in - work who receives none (reg 13(3)). DLA, PIP and income-related ESA never + partner is in work, or receives a reg 13(1)(b) benefit or is on carer's + leave (13(1)(c)) and has a partner in work who receives no (1)(b) benefit + (reg 13(3)). In extended childcare, the Universal Credit carer element + counts only for the carer on an award that includes it (reg 11A(1)(c)). DLA, PIP and income-related ESA never matter. Reg 13(2)(b) deems the minimum income for anyone regarded as in paid work. 4. Maintenance loan household income (SI 2011/1986 Sch 4 para 2(1)(a)). A @@ -196,14 +198,18 @@ def test_care_to_learn_pays_each_child_once_up_to_the_per_child_cap(families): { "age": st.integers(20, 60), "earnings": st.sampled_from([0, 8_316, 8_320, 20_000, 100_000, 100_001]), - "status": st.sampled_from([None, *STATUS_INPUTS]), + "status": st.sampled_from([None, "carer", *STATUS_INPUTS]), "pip": st.sampled_from([0, 5_000]), } ) +# (universal_credit, uc_carer_element) for the benefit unit. Reg 11A(1)(c): the +# carer element of a Universal Credit award, which belongs to the carer. +UC_AWARDS = [(0, 0), (3_000, 0), (3_000, 2_400), (0, 2_400)] extended_child = st.tuples(st.sampled_from([0.5, 0.75, 1, 2, 3, 4, 6]), st.booleans()) extended_family = st.tuples( st.lists(extended_adult, min_size=1, max_size=2), st.lists(extended_child, min_size=0, max_size=2), + st.sampled_from(UC_AWARDS), ) YOUNG_CHILD_MINIMUM_AGE = {2023: 3, 2024: 2, 2025: 0.75, 2026: 0.75} @@ -222,47 +228,53 @@ def meets_work_and_income(adult): ) def test_extended_childcare_eligibility_matches_regs_13_to_15(year, families): built = [] - for adults, children in families: + for adults, children, (uc, carer_element) in families: people = [] for adult in adults: inputs = { "age": adult["age"], "is_parent": bool(children), + "is_carer_for_benefits": adult["status"] == "carer", "employment_income": adult["earnings"], "adjusted_net_income": adult["earnings"], "minimum_wage": MINIMUM_WAGE, "pip": adult["pip"], } - if adult["status"]: + if adult["status"] in STATUS_INPUTS: inputs[adult["status"]] = STATUS_INPUTS[adult["status"]] people.append(inputs) for age, looked_after in children: people.append( {"age": age, "is_looked_after_by_local_authority": looked_after} ) - built.append((people, {}, {"country": "ENGLAND"})) + benunit = {"universal_credit": uc, "uc_carer_element": carer_element} + built.append((people, benunit, {"country": "ENGLAND"})) sim, _ = simulate(built, year) eligible = sim.calculate("extended_childcare_entitlement_eligible", year) minimum_age = YOUNG_CHILD_MINIMUM_AGE[year] - for (adults, children), result in zip(families, eligible): + for (adults, children, (uc, carer_element)), result in zip(families, eligible): has_young_child = any( minimum_age <= age < 5 and not looked_after for age, looked_after in children ) meets = [meets_work_and_income(a) for a in adults] + status = [ + a["status"] in STATUS_INPUTS + or (a["status"] == "carer" and uc > 0 and carer_element > 0) + for a in adults + ] ok = [ meets[k] - or ( - adults[k]["status"] is not None - and any(meets[m] for m in range(len(adults)) if m != k) - ) + or (status[k] and any(meets[m] for m in range(len(adults)) if m != k)) for k in range(len(adults)) ] assert bool(result) == (has_young_child and all(ok)), ( year, adults, children, + uc, + carer_element, ) @@ -283,6 +295,7 @@ def test_extended_childcare_eligibility_matches_regs_13_to_15(year, families): "in_work": st.booleans(), "benefit": st.sampled_from([None, *REG_13_BENEFITS]), "other": st.sampled_from([None, *NOT_REG_13]), + "carers_leave": st.booleans(), } ) tfc_family = st.tuples(st.lists(tfc_adult, min_size=1, max_size=2), st.booleans()) @@ -298,6 +311,7 @@ def test_tax_free_childcare_work_condition_matches_reg_13(families): inputs = { "age": 35, "in_work": adult["in_work"], + "tax_free_childcare_on_carers_leave": adult["carers_leave"], "adjusted_net_income": 20_000, "minimum_wage": MINIMUM_WAGE, } @@ -330,8 +344,10 @@ def test_tax_free_childcare_work_condition_matches_reg_13(families): families, work, regarded, meets_income ): has_benefit = [a["benefit"] is not None for a in adults] + # Reg 13(1)(c): carer's leave counts from 6 April 2024 (so in 2025), but + # reg 13(3) excludes only a partner with a (1)(b) benefit. reference_regarded = [ - has_benefit[k] + (has_benefit[k] or adults[k]["carers_leave"]) and any( adults[m]["in_work"] and not has_benefit[m] for m in range(len(adults)) diff --git a/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_on_carers_leave.py b/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_on_carers_leave.py index 2ca6a85527..7395c6554c 100644 --- a/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_on_carers_leave.py +++ b/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_on_carers_leave.py @@ -9,7 +9,9 @@ class tax_free_childcare_on_carers_leave(Variable): "Whether this person is absent from work on carer's leave under " "section 80J of the Employment Rights Act 1996, which regulation " "13(1)(c) of the Childcare Payments (Eligibility) Regulations 2015 " - "treats like the caring and incapacity benefits from 6 April 2024." + "treats like the caring and incapacity benefits from 6 April 2024, " + "in England and Wales and Scotland only (carer's leave does not " + "exist in Northern Ireland)." ) definition_period = YEAR default_value = False From 257b051c5b25eaa5633af39f63aab5f41bde5591 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Wed, 30 Sep 2026 11:14:53 -0400 Subject: [PATCH 5/9] Pin the carer-element attribution cases as explicit examples Co-Authored-By: Claude Opus 5.5 --- ...dfe_childcare_student_support_properties.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/policyengine_uk/tests/test_dfe_childcare_student_support_properties.py b/policyengine_uk/tests/test_dfe_childcare_student_support_properties.py index ce8fb478c5..4202d88b7e 100644 --- a/policyengine_uk/tests/test_dfe_childcare_student_support_properties.py +++ b/policyengine_uk/tests/test_dfe_childcare_student_support_properties.py @@ -55,7 +55,7 @@ from unittest.mock import patch import numpy as np -from hypothesis import HealthCheck, given, settings +from hypothesis import HealthCheck, example, given, settings from hypothesis import strategies as st from policyengine_uk import Simulation @@ -221,11 +221,27 @@ def meets_work_and_income(adult): ) +def _adult(earnings, status=None): + return {"age": 35, "earnings": earnings, "status": status, "pip": 0} + + +# Explicit cases for the carer element's attribution (reg 11A(1)(c)): the +# earner is the carer; the carer has no Universal Credit award; neither +# partner is the carer. In each, the non-earner must not qualify through it. @PROPERTY_SETTINGS @given( st.sampled_from([2023, 2024, 2025, 2026]), st.lists(extended_family, min_size=1, max_size=6), ) +@example( + 2025, + [ + ([_adult(20_000, "carer"), _adult(0)], [(3, False)], (3_000, 2_400)), + ([_adult(20_000), _adult(0, "carer")], [(3, False)], (0, 2_400)), + ([_adult(20_000), _adult(0)], [(3, False)], (3_000, 2_400)), + ([_adult(20_000), _adult(0, "carer")], [(3, False)], (3_000, 2_400)), + ], +) def test_extended_childcare_eligibility_matches_regs_13_to_15(year, families): built = [] for adults, children, (uc, carer_element) in families: From 42da7d2bf413daa65822c0cfa6a2d456c40bd8f0 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sat, 3 Oct 2026 18:07:48 -0400 Subject: [PATCH 6/9] Test carer's allowance entitlement, not payment, in the TFC and extended childcare lists SI 2015/448 reg 13(1)(b) and SI 2016/1257 reg 9(1)(b) say "paid or entitled to", and SI 2022/1134 regs 14(4)/15(4) ask about entitlement. #1994 reduces Carer's Allowance and Carer Support Payment by overlapping benefits, so the payable amount can be nil while entitlement remains. Use carers_allowance_pre_overlap/receives_carers_allowance before 1 December 2022 (no Scottish carer's assistance yet) and is_entitled_to_carer_benefit from then, as #1994 did for extended childcare. Co-Authored-By: Claude Opus 5.5 --- .../tax_free_childcare/caring_or_incapacity_benefits.yaml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/policyengine_uk/parameters/gov/hmrc/tax_free_childcare/caring_or_incapacity_benefits.yaml b/policyengine_uk/parameters/gov/hmrc/tax_free_childcare/caring_or_incapacity_benefits.yaml index 632aca5c6b..fb3890f82f 100644 --- a/policyengine_uk/parameters/gov/hmrc/tax_free_childcare/caring_or_incapacity_benefits.yaml +++ b/policyengine_uk/parameters/gov/hmrc/tax_free_childcare/caring_or_incapacity_benefits.yaml @@ -9,17 +9,19 @@ metadata: unit: program label: Tax-Free Childcare caring or incapacity benefits values: + # Reg 13(1)(b): "paid or entitled to", so an allowance reduced to nil by an + # overlapping benefit still counts. 2015-01-01: - incapacity_benefit # 13(1)(b)(i) and (iii): incapacity benefit and long-term incapacity benefit - sda # 13(1)(b)(ii): severe disablement allowance - - carers_allowance # 13(1)(b)(iv): carer's allowance + - carers_allowance_pre_overlap # 13(1)(b)(iv): entitlement to carer's allowance before overlapping benefits + - receives_carers_allowance # 13(1)(b)(iv): carer's allowance supplied as received - esa_contrib # 13(1)(b)(v): contributory employment and support allowance - receives_limited_capability_for_work_credits # 13(1)(b)(vi): credits for incapacity or limited capability for work # SI 2022/1148 reg 2(6)(b) inserted 13(1)(b)(vii) from 1 December 2022. 2022-12-01: - incapacity_benefit - sda - - carers_allowance + - is_entitled_to_carer_benefit # 13(1)(b)(iv) and (vii): carer's allowance, or carer's assistance under the Social Security (Scotland) Act 2018 s.28 - esa_contrib - receives_limited_capability_for_work_credits - - carer_support_payment # 13(1)(b)(vii): carer's assistance under the Social Security (Scotland) Act 2018 s.28 From ed741972c6ba39bebb3ec8c18f0cc7fac62295cf Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sat, 3 Oct 2026 22:04:19 -0400 Subject: [PATCH 7/9] Give #1994's childcare case a working parent who meets reg 14(3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Case 21 checks that a parent entitled to Carer's Allowance reduced to nil still meets the extended childcare work condition. With regs 14(4)/15(4) applied, that holds only when the other parent meets reg 14(3): qualifying paid work with the reg 18 minimum income. The case's working parent had in_work but no earnings, so give them £20,000 of earnings at a £10 minimum wage. The expected [1, 1, 0] is unchanged. Co-Authored-By: Claude Opus 5.5 --- .../gov/dwp/carers_allowance_overlapping_benefits.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/policyengine_uk/tests/policy/baseline/gov/dwp/carers_allowance_overlapping_benefits.yaml b/policyengine_uk/tests/policy/baseline/gov/dwp/carers_allowance_overlapping_benefits.yaml index 3ba85424d0..72cf06ab25 100644 --- a/policyengine_uk/tests/policy/baseline/gov/dwp/carers_allowance_overlapping_benefits.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/dwp/carers_allowance_overlapping_benefits.yaml @@ -370,6 +370,12 @@ age: 40 in_work: true is_parent: true + # Reg 14(3)/15(3): the other parent must be in qualifying paid work + # with at least the reg 18 minimum income (16 x £10 x 13 = £2,080 a + # quarter) and adjusted net income of at most £100,000. + employment_income: 20_000 + adjusted_net_income: 20_000 + minimum_wage: 10 parent2: age: 38 in_work: false From 7375f2d4095960887a77460d980331eb2bf0a064 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sun, 4 Oct 2026 07:16:27 -0400 Subject: [PATCH 8/9] Apply reg 13(3)'s payment test and the pre-2022 extended childcare limits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Tax-Free Childcare: reg 13(3) excludes a working partner who is "paid" a reg 13(1)(b) benefit or allowance (or entitled to a credit), not one merely entitled to it. A partner whose Carer's Allowance is overlapped to nil still counts as the partner in qualifying paid work. New caring_or_incapacity_benefits_in_payment list; 13(1)(b) itself keeps "paid or entitled to". - Extended childcare before 1 December 2022 (SI 2016/1257): reg 9 deemed only qualifying paid work, so the £100,000 limit (reg 4(5), (7)) still applied to the person using it, and reg 9(3) did not count a working partner paid or entitled to a listed benefit. Dated parameters switch both off when SI 2022/1134 takes over. Co-Authored-By: Claude Opus 5.5 --- .../exemption/income_limit_applies.yaml | 16 +++ .../exemption/partner_exclusion_criteria.yaml | 24 +++++ ...ing_or_incapacity_benefits_in_payment.yaml | 29 +++++ ..._childcare_entitlement_work_condition.yaml | 102 ++++++++++++++++++ .../tax_free_childcare_income_condition.yaml | 1 + .../tax_free_childcare_work_condition.yaml | 51 +++++++++ ...ed_childcare_entitlement_work_condition.py | 28 ++++- ...free_childcare_regarded_as_in_paid_work.py | 16 +-- 8 files changed, 258 insertions(+), 9 deletions(-) create mode 100644 policyengine_uk/parameters/gov/dfe/extended_childcare_entitlement/exemption/income_limit_applies.yaml create mode 100644 policyengine_uk/parameters/gov/dfe/extended_childcare_entitlement/exemption/partner_exclusion_criteria.yaml create mode 100644 policyengine_uk/parameters/gov/hmrc/tax_free_childcare/caring_or_incapacity_benefits_in_payment.yaml diff --git a/policyengine_uk/parameters/gov/dfe/extended_childcare_entitlement/exemption/income_limit_applies.yaml b/policyengine_uk/parameters/gov/dfe/extended_childcare_entitlement/exemption/income_limit_applies.yaml new file mode 100644 index 0000000000..3879865146 --- /dev/null +++ b/policyengine_uk/parameters/gov/dfe/extended_childcare_entitlement/exemption/income_limit_applies.yaml @@ -0,0 +1,16 @@ +description: The Department for Education applies the extended childcare entitlement income limit to a parent or partner who meets the conditions through limited capability for work or a listed benefit, if this is true. +metadata: + reference: + - title: The Childcare (Free of Charge for Working Parents) (England) Regulations 2016 - Regulations 4(5), 4(7) and 9 + href: https://www.legislation.gov.uk/uksi/2016/1257/regulation/4/made + - title: The Childcare (Free of Charge for Working Parents) (England) Regulations 2022 - Regulations 14(4) and 15(4) + href: https://www.legislation.gov.uk/uksi/2022/1134/regulation/14 + period: year + unit: bool + label: Extended childcare entitlement income limit applies to exempt parent or partner +values: + # SI 2016/1257 reg 4(5) and (7): the parent and any partner must not expect + # adjusted net income above £100,000; reg 9 deems only qualifying paid work. + 2015-01-01: true + # SI 2022/1134 regs 14(4) and 15(4) carry no income condition. + 2022-12-01: false diff --git a/policyengine_uk/parameters/gov/dfe/extended_childcare_entitlement/exemption/partner_exclusion_criteria.yaml b/policyengine_uk/parameters/gov/dfe/extended_childcare_entitlement/exemption/partner_exclusion_criteria.yaml new file mode 100644 index 0000000000..1ed5bf72e7 --- /dev/null +++ b/policyengine_uk/parameters/gov/dfe/extended_childcare_entitlement/exemption/partner_exclusion_criteria.yaml @@ -0,0 +1,24 @@ +description: The Department for Education does not count a working partner as in qualifying paid work, for the other member of the couple's limited capability or benefit route to the extended childcare entitlement, while the working partner is paid or entitled to any of these benefits or credits. +metadata: + reference: + - title: The Childcare (Free of Charge for Working Parents) (England) Regulations 2016 - Regulation 9(3) + href: https://www.legislation.gov.uk/uksi/2016/1257/regulation/9/made + - title: The Childcare (Free of Charge for Working Parents) (England) Regulations 2022 - Regulations 14(4) and 15(4) + href: https://www.legislation.gov.uk/uksi/2022/1134/regulation/14 + period: year + unit: program + label: Extended childcare entitlement partner exclusion criteria +values: + # SI 2016/1257 reg 9(3): "paid or entitled to a benefit or an allowance, or is + # entitled to a credit, described in paragraph (1)(b)". The reg 9(1)(b)(viii) + # determination of limited capability is not a benefit, allowance or credit. + 2015-01-01: + - incapacity_benefit + - sda + - carers_allowance_pre_overlap + - receives_carers_allowance + - esa_contrib + - receives_limited_capability_for_work_credits + - receives_uc_carer_element + # SI 2022/1134 regs 14(4) and 15(4) have no such exclusion. + 2022-12-01: [] diff --git a/policyengine_uk/parameters/gov/hmrc/tax_free_childcare/caring_or_incapacity_benefits_in_payment.yaml b/policyengine_uk/parameters/gov/hmrc/tax_free_childcare/caring_or_incapacity_benefits_in_payment.yaml new file mode 100644 index 0000000000..b1797fd836 --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/tax_free_childcare/caring_or_incapacity_benefits_in_payment.yaml @@ -0,0 +1,29 @@ +description: HMRC does not count a partner as in qualifying paid work, for another person's Tax-Free Childcare caring or incapacity route, while that partner is paid any of these benefits or allowances, or entitled to these credits. +metadata: + reference: + - title: The Childcare Payments (Eligibility) Regulations 2015 - Regulation 13(3) + href: https://www.legislation.gov.uk/uksi/2015/448/regulation/13 + - title: The Childcare Payments (Miscellaneous Amendments) Regulations 2022 - Regulation 2(6) + href: https://www.legislation.gov.uk/uksi/2022/1148/regulation/2/made + period: year + unit: program + label: Tax-Free Childcare caring or incapacity benefits in payment +values: + # Reg 13(3): "paid a benefit or an allowance, or is entitled to a credit, + # described in paragraph (1)(b)". Payment, not entitlement, for benefits and + # allowances, so an allowance reduced to nil by an overlapping benefit does + # not exclude the partner. + 2015-01-01: + - incapacity_benefit # 13(1)(b)(i) and (iii) + - sda # 13(1)(b)(ii) + - carers_allowance # 13(1)(b)(iv): the amount payable after overlapping benefits + - esa_contrib # 13(1)(b)(v) + - receives_limited_capability_for_work_credits # 13(1)(b)(vi): entitled to a credit + # SI 2022/1148 reg 2(6)(b) inserted 13(1)(b)(vii) from 1 December 2022. + 2022-12-01: + - incapacity_benefit + - sda + - carers_allowance + - esa_contrib + - receives_limited_capability_for_work_credits + - carer_support_payment # 13(1)(b)(vii): the amount payable after overlapping benefits diff --git a/policyengine_uk/tests/policy/baseline/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement_work_condition.yaml b/policyengine_uk/tests/policy/baseline/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement_work_condition.yaml index 57113d373a..34c7d5cce6 100644 --- a/policyengine_uk/tests/policy/baseline/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement_work_condition.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement_work_condition.yaml @@ -370,3 +370,105 @@ members: [person1, person2] output: extended_childcare_entitlement_work_condition: [true, true] + +# Before 1 December 2022, SI 2016/1257 reg 9 deemed only qualifying paid work, +# so the £100,000 limit in reg 4(5) and (7) still applied to the partner on +# Carer's Allowance. SI 2022/1134 regs 14(4)/15(4) carry no income condition. +- name: 2022, partner on Carer's Allowance with adjusted net income above £100,000 - does not meet the condition + period: 2022 + input: + people: + parent1: + age: 40 + is_parent: true + employment_income: 20_000 + adjusted_net_income: 20_000 + minimum_wage: 10 + parent2: + age: 38 + is_parent: true + carers_allowance: 4_000 + adjusted_net_income: 120_000 + minimum_wage: 10 + child: + age: 4 + benunits: + benunit: + members: [parent1, parent2, child] + output: + extended_childcare_entitlement_work_condition: [true, false, false] + +- name: 2025, partner on Carer's Allowance with adjusted net income above £100,000 - meets the condition + period: 2025 + input: + people: + parent1: + age: 40 + is_parent: true + employment_income: 20_000 + adjusted_net_income: 20_000 + minimum_wage: 10 + parent2: + age: 38 + is_parent: true + carers_allowance: 4_000 + adjusted_net_income: 120_000 + minimum_wage: 10 + child: + age: 4 + benunits: + benunit: + members: [parent1, parent2, child] + output: + extended_childcare_entitlement_work_condition: [true, true, false] + +# SI 2016/1257 reg 9(3), before 1 December 2022: a working partner paid or +# entitled to a listed benefit (here Carer's Allowance) is not in qualifying +# paid work for the other's reg 9 route. SI 2022/1134 has no such exclusion. +- name: 2022, working partner also on Carer's Allowance - the partner on contributory ESA does not meet the condition + period: 2022 + input: + people: + parent1: + age: 40 + is_parent: true + employment_income: 20_000 + adjusted_net_income: 20_000 + carers_allowance: 4_000 + minimum_wage: 10 + parent2: + age: 38 + is_parent: true + esa_contrib: 4_000 + minimum_wage: 10 + child: + age: 4 + benunits: + benunit: + members: [parent1, parent2, child] + output: + extended_childcare_entitlement_work_condition: [true, false, false] + +- name: 2025, working partner also on Carer's Allowance - the partner on contributory ESA meets the condition + period: 2025 + input: + people: + parent1: + age: 40 + is_parent: true + employment_income: 20_000 + adjusted_net_income: 20_000 + carers_allowance: 4_000 + minimum_wage: 10 + parent2: + age: 38 + is_parent: true + esa_contrib: 4_000 + minimum_wage: 10 + child: + age: 4 + benunits: + benunit: + members: [parent1, parent2, child] + output: + extended_childcare_entitlement_work_condition: [true, true, false] diff --git a/policyengine_uk/tests/policy/baseline/gov/hmrc/tax_free_childcare/tax_free_childcare_income_condition.yaml b/policyengine_uk/tests/policy/baseline/gov/hmrc/tax_free_childcare/tax_free_childcare_income_condition.yaml index 53cce376ea..fe5124376c 100644 --- a/policyengine_uk/tests/policy/baseline/gov/hmrc/tax_free_childcare/tax_free_childcare_income_condition.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/hmrc/tax_free_childcare/tax_free_childcare_income_condition.yaml @@ -150,6 +150,7 @@ output: tax_free_childcare_regarded_as_in_paid_work: [false, true] tax_free_childcare_meets_income_requirements: [true, false] + # 2023-24 thresholds use the 1 April 2023 rates (S.I. 2023/354): 16 hours x 13 # weeks at £10.42 (23 or over) is £2,167.36, and at £10.18 (21 or 22) is # £2,117.44. The April 2022 rates gave £1,976 and £1,909.44. diff --git a/policyengine_uk/tests/policy/baseline/gov/hmrc/tax_free_childcare/tax_free_childcare_work_condition.yaml b/policyengine_uk/tests/policy/baseline/gov/hmrc/tax_free_childcare/tax_free_childcare_work_condition.yaml index 0510e5839f..b755579027 100644 --- a/policyengine_uk/tests/policy/baseline/gov/hmrc/tax_free_childcare/tax_free_childcare_work_condition.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/hmrc/tax_free_childcare/tax_free_childcare_work_condition.yaml @@ -554,3 +554,54 @@ members: [parent, student, toddler] output: tax_free_childcare_work_condition: [true, false, false] + +# Reg 13(3) excludes a working partner who is "paid" a (1)(b) benefit or +# allowance. Maternity allowance overlaps the worker's Carer's Allowance to nil, +# so the worker is entitled to it but not paid it, and still counts as the +# partner in qualifying paid work for the spouse on Carer's Allowance. +- name: Working partner entitled to Carer's Allowance reduced to nil does not stop the other qualifying under reg 13 + period: 2025 + input: + people: + worker: + in_work: true + care_hours: 35 + maternity_allowance_reported: 5_000 + spouse: + in_work: false + carers_allowance: 4_000 + benunits: + benunit: + members: [worker, spouse] + households: + household: + members: [worker, spouse] + country: ENGLAND + output: + carers_allowance: [0, 4_000] + tax_free_childcare_regarded_as_in_paid_work: [false, true] + tax_free_childcare_work_condition: true + +# Reg 13(1)(b)(iv): "paid or entitled to" carer's allowance. Entitlement reduced +# to nil by maternity allowance still regards the carer as in paid work. +- name: Carer entitled to Carer's Allowance reduced to nil is regarded as in paid work under reg 13 + period: 2025 + input: + people: + worker: + in_work: true + carer: + in_work: false + care_hours: 35 + maternity_allowance_reported: 5_000 + benunits: + benunit: + members: [worker, carer] + households: + household: + members: [worker, carer] + country: ENGLAND + output: + carers_allowance: [0, 0] + tax_free_childcare_regarded_as_in_paid_work: [false, true] + tax_free_childcare_work_condition: true diff --git a/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/conditions/extended_childcare_entitlement_work_condition.py b/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/conditions/extended_childcare_entitlement_work_condition.py index a1c571c904..9b2eb0398e 100644 --- a/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/conditions/extended_childcare_entitlement_work_condition.py +++ b/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/conditions/extended_childcare_entitlement_work_condition.py @@ -12,7 +12,11 @@ class extended_childcare_entitlement_work_condition(Variable): "or 15(4) instead: limited capability for work or a specified " "benefit, with a partner who meets reg 14(3) or 15(3). Under reg " "14(4) or 15(4) a person needs neither the work nor the income " - "condition, and a lone parent cannot qualify that way." + "condition, and a lone parent cannot qualify that way. Before " + "1 December 2022, SI 2016/1257 reg 9 deemed only qualifying paid " + "work, so the £100,000 limit still applied to that person (reg 4(5) " + "and (7)), and a working partner paid or entitled to a listed benefit " + "did not count (reg 9(3))." ) definition_period = YEAR defined_for = "is_claimant_or_partner" @@ -21,9 +25,12 @@ class extended_childcare_entitlement_work_condition(Variable): "https://www.legislation.gov.uk/uksi/2022/1134/regulation/14", "https://www.legislation.gov.uk/uksi/2022/1134/regulation/15", "https://www.legislation.gov.uk/uksi/2022/1134/regulation/18", + "https://www.legislation.gov.uk/uksi/2016/1257/regulation/4/made", + "https://www.legislation.gov.uk/uksi/2016/1257/regulation/9/made", ) def formula(person, period, parameters): + p = parameters(period).gov.dfe.extended_childcare_entitlement claimant_or_partner = person("is_claimant_or_partner", period) # Reg 14(3)/15(3): in qualifying paid work (the minimum income @@ -34,12 +41,26 @@ def formula(person, period, parameters): & person("extended_childcare_entitlement_meets_income_requirements", period) ) + # SI 2016/1257 reg 9(3), before 1 December 2022: a working partner paid + # or entitled to a listed benefit does not count as in qualifying paid + # work for the other's reg 9 route. + exclusion_criteria = list(p.exemption.partner_exclusion_criteria) + partner_excluded = ( + add(person, period, exclusion_criteria) > 0 if exclusion_criteria else False + ) + counts_as_working_partner = meets_work_and_income_conditions & ~partner_excluded + # Reg 14(4)/15(4): limited capability for work or a specified benefit, # with a partner who meets reg 14(3)/15(3). partner_meets_work_and_income_conditions = ( - person.benunit.sum(meets_work_and_income_conditions) - - meets_work_and_income_conditions + person.benunit.sum(counts_as_working_partner) - counts_as_working_partner ) > 0 + # SI 2016/1257 reg 4(5) and (7), before 1 December 2022: the £100,000 + # limit still applies to the person using this route. + within_income_limit = person("adjusted_net_income", period) <= p.income.limit + meets_income_limit_if_applies = within_income_limit | ( + not p.exemption.income_limit_applies + ) exempt_through_partner = ( claimant_or_partner & person( @@ -47,6 +68,7 @@ def formula(person, period, parameters): period, ) & partner_meets_work_and_income_conditions + & meets_income_limit_if_applies ) return meets_work_and_income_conditions | exempt_through_partner diff --git a/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_regarded_as_in_paid_work.py b/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_regarded_as_in_paid_work.py index 1e2b2ed534..007a5b4032 100644 --- a/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_regarded_as_in_paid_work.py +++ b/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_regarded_as_in_paid_work.py @@ -12,9 +12,10 @@ class tax_free_childcare_regarded_as_in_paid_work(Variable): "person receives a caring or incapacity benefit (reg 13(1)(b)) or, " "from 6 April 2024, is on carer's leave (reg 13(1)(c)), and has a " "partner in qualifying paid work (reg 13(1)(a)). The partner does not " - "count as in qualifying paid work while they receive a reg 13(1)(b) " - "benefit themselves (reg 13(3)); carer's leave does not have that " - "effect. A lone parent cannot qualify this way. The partner's own " + "count as in qualifying paid work while they are paid a reg 13(1)(b) " + "benefit or allowance, or entitled to a reg 13(1)(b) credit (reg " + "13(3)); entitlement to an allowance reduced to nil by an overlapping " + "benefit, and carer's leave, do not have that effect. A lone parent cannot qualify this way. The partner's own " "minimum income is tested by the income condition." ) definition_period = YEAR @@ -30,12 +31,15 @@ def formula(person, period, parameters): person("tax_free_childcare_on_carers_leave", period) & p.carers_leave_qualifies ) - # Reg 13(1)(a) and (3): in paid work, and not paid or entitled to a - # reg 13(1)(b) benefit. + # Reg 13(1)(a) and (3): in paid work, and not paid a reg 13(1)(b) + # benefit or allowance or entitled to a reg 13(1)(b) credit. + paid_caring_or_incapacity_benefit = ( + add(person, period, p.caring_or_incapacity_benefits_in_payment) > 0 + ) in_work_without_caring_or_incapacity_benefit = ( claimant_or_partner & person("tax_free_childcare_treated_as_in_work", period) - & ~caring_or_incapacity_benefit + & ~paid_caring_or_incapacity_benefit ) partner_in_qualifying_paid_work = ( person.benunit.sum(in_work_without_caring_or_incapacity_benefit) From 787d83ad2a0b0ea1796efbf1f097b25c7783b636 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sun, 4 Oct 2026 07:30:25 -0400 Subject: [PATCH 9/9] Address the delta review's low findings - Guard the empty reg 9(3) list with a boolean zero array, not ~False. - Count a carer benefit supplied as received in the reg 13(3) payment list (receives_carers_allowance; receives_carer_benefit from 1 December 2022), since an input flag means it is paid. - Pin the two choices that separate SI 2016/1257 reg 9(3) from reg 13(3): an allowance overlapped to nil still excludes the working partner ("entitled to"), and an LCWRA determination does not. - Rewrap a docstring line. Co-Authored-By: Claude Opus 5.5 --- ...ing_or_incapacity_benefits_in_payment.yaml | 2 + ..._childcare_entitlement_work_condition.yaml | 62 +++++++++++++++++++ .../tax_free_childcare_work_condition.yaml | 19 ++++++ ...ed_childcare_entitlement_work_condition.py | 4 +- ...free_childcare_regarded_as_in_paid_work.py | 5 +- 5 files changed, 89 insertions(+), 3 deletions(-) diff --git a/policyengine_uk/parameters/gov/hmrc/tax_free_childcare/caring_or_incapacity_benefits_in_payment.yaml b/policyengine_uk/parameters/gov/hmrc/tax_free_childcare/caring_or_incapacity_benefits_in_payment.yaml index b1797fd836..f6d00da0bb 100644 --- a/policyengine_uk/parameters/gov/hmrc/tax_free_childcare/caring_or_incapacity_benefits_in_payment.yaml +++ b/policyengine_uk/parameters/gov/hmrc/tax_free_childcare/caring_or_incapacity_benefits_in_payment.yaml @@ -17,6 +17,7 @@ values: - incapacity_benefit # 13(1)(b)(i) and (iii) - sda # 13(1)(b)(ii) - carers_allowance # 13(1)(b)(iv): the amount payable after overlapping benefits + - receives_carers_allowance # 13(1)(b)(iv): carer's allowance supplied as received - esa_contrib # 13(1)(b)(v) - receives_limited_capability_for_work_credits # 13(1)(b)(vi): entitled to a credit # SI 2022/1148 reg 2(6)(b) inserted 13(1)(b)(vii) from 1 December 2022. @@ -27,3 +28,4 @@ values: - esa_contrib - receives_limited_capability_for_work_credits - carer_support_payment # 13(1)(b)(vii): the amount payable after overlapping benefits + - receives_carer_benefit # 13(1)(b)(iv) and (vii): a carer benefit supplied as received diff --git a/policyengine_uk/tests/policy/baseline/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement_work_condition.yaml b/policyengine_uk/tests/policy/baseline/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement_work_condition.yaml index 34c7d5cce6..ef56a091ad 100644 --- a/policyengine_uk/tests/policy/baseline/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement_work_condition.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement_work_condition.yaml @@ -472,3 +472,65 @@ members: [parent1, parent2, child] output: extended_childcare_entitlement_work_condition: [true, true, false] + +# SI 2016/1257 reg 9(3) covers "a benefit or an allowance, or [...] a credit". +# The reg 9(1)(b)(viii) determination of limited capability for work and +# work-related activity is none of these, so a working partner with that +# determination still counts as the partner in qualifying paid work. +- name: 2022, working partner with limited capability for work - the partner on contributory ESA meets the condition + period: 2022 + input: + people: + parent1: + age: 40 + is_parent: true + employment_income: 20_000 + adjusted_net_income: 20_000 + uc_limited_capability_for_WRA: true + minimum_wage: 10 + parent2: + age: 38 + is_parent: true + esa_contrib: 4_000 + minimum_wage: 10 + child: + age: 4 + benunits: + benunit: + members: [parent1, parent2, child] + output: + extended_childcare_entitlement_work_condition: [true, true, false] + +# Reg 9(3) says "paid or entitled to", unlike Tax-Free Childcare reg 13(3). +# The working partner provides 35 hours of care and their Carer's Allowance is +# overlapped to nil by maternity allowance: entitled but not paid, so still +# excluded. +- name: 2022, working partner entitled to Carer's Allowance overlapped to nil - the partner on contributory ESA does not meet the condition + period: 2022 + input: + people: + parent1: + age: 40 + is_parent: true + employment_income: 20_000 + adjusted_net_income: 20_000 + care_hours: 35 + maternity_allowance_reported: 5_000 + minimum_wage: 10 + parent2: + age: 38 + is_parent: true + esa_contrib: 4_000 + minimum_wage: 10 + child: + age: 4 + benunits: + benunit: + members: [parent1, parent2, child] + households: + household: + members: [parent1, parent2, child] + country: ENGLAND + output: + carers_allowance: [0, 0, 0] + extended_childcare_entitlement_work_condition: [true, false, false] diff --git a/policyengine_uk/tests/policy/baseline/gov/hmrc/tax_free_childcare/tax_free_childcare_work_condition.yaml b/policyengine_uk/tests/policy/baseline/gov/hmrc/tax_free_childcare/tax_free_childcare_work_condition.yaml index b755579027..7dfba5abde 100644 --- a/policyengine_uk/tests/policy/baseline/gov/hmrc/tax_free_childcare/tax_free_childcare_work_condition.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/hmrc/tax_free_childcare/tax_free_childcare_work_condition.yaml @@ -605,3 +605,22 @@ carers_allowance: [0, 0] tax_free_childcare_regarded_as_in_paid_work: [false, true] tax_free_childcare_work_condition: true + +# Reg 13(3): a working partner supplied as receiving Carer's Allowance, with no +# amount, is paid it, so the spouse on contributory ESA cannot use reg 13. +- name: Working partner supplied as receiving Carer's Allowance excludes the other under reg 13(3) + period: 2025 + input: + people: + worker: + in_work: true + receives_carers_allowance: true + spouse: + in_work: false + esa_contrib: 4_000 + benunits: + benunit: + members: [worker, spouse] + output: + tax_free_childcare_regarded_as_in_paid_work: [false, false] + tax_free_childcare_work_condition: false diff --git a/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/conditions/extended_childcare_entitlement_work_condition.py b/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/conditions/extended_childcare_entitlement_work_condition.py index 9b2eb0398e..ba3fe7ad88 100644 --- a/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/conditions/extended_childcare_entitlement_work_condition.py +++ b/policyengine_uk/variables/gov/dfe/extended_childcare_entitlement/conditions/extended_childcare_entitlement_work_condition.py @@ -46,7 +46,9 @@ def formula(person, period, parameters): # work for the other's reg 9 route. exclusion_criteria = list(p.exemption.partner_exclusion_criteria) partner_excluded = ( - add(person, period, exclusion_criteria) > 0 if exclusion_criteria else False + add(person, period, exclusion_criteria) > 0 + if exclusion_criteria + else np.zeros_like(meets_work_and_income_conditions, dtype=bool) ) counts_as_working_partner = meets_work_and_income_conditions & ~partner_excluded diff --git a/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_regarded_as_in_paid_work.py b/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_regarded_as_in_paid_work.py index 007a5b4032..73c201dc8d 100644 --- a/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_regarded_as_in_paid_work.py +++ b/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_regarded_as_in_paid_work.py @@ -15,8 +15,9 @@ class tax_free_childcare_regarded_as_in_paid_work(Variable): "count as in qualifying paid work while they are paid a reg 13(1)(b) " "benefit or allowance, or entitled to a reg 13(1)(b) credit (reg " "13(3)); entitlement to an allowance reduced to nil by an overlapping " - "benefit, and carer's leave, do not have that effect. A lone parent cannot qualify this way. The partner's own " - "minimum income is tested by the income condition." + "benefit, and carer's leave, do not have that effect. A lone parent " + "cannot qualify this way. The partner's own minimum income is tested " + "by the income condition." ) definition_period = YEAR reference = "https://www.legislation.gov.uk/uksi/2015/448/regulation/13"