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 40cedba10c..b8e1b7da16 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,37 @@ -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): "paid or entitled to", so an allowance reduced to + # nil by an overlapping benefit still counts. 2015-09-01: - - is_entitled_to_carer_benefit # 11A(1)(a)-(b): Carer's allowance under Section 70 of Social Security Contributions and Benefits Act 1992, or Scottish carer's assistance; regs 14(4) and 15 ask whether a person is entitled to it, so an allowance reduced to nil by an overlapping benefit still counts - - 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_pre_overlap # (iv): entitlement to carer's allowance before overlapping benefits + - receives_carers_allowance # (iv): carer's allowance supplied as received + - 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 + - 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. Regs 14(4) and 15(4) ask + # whether a person is entitled to a specified benefit, so an allowance reduced + # to nil by an overlapping benefit still counts. + 2022-12-01: + - uc_limited_capability_for_WRA # 14(4)(b)(i)-(ii): limited capability for work, or for work and work-related activity + - is_entitled_to_carer_benefit # 11A(1)(a)-(b): carer's allowance, or carer's assistance under the Social Security (Scotland) Act 2018 s.28 + - 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) + - 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/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/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/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 new file mode 100644 index 0000000000..fb3890f82f --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/tax_free_childcare/caring_or_incapacity_benefits.yaml @@ -0,0 +1,27 @@ +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 + period: year + 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_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 + - 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 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..f6d00da0bb --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/tax_free_childcare/caring_or_incapacity_benefits_in_payment.yaml @@ -0,0 +1,31 @@ +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 + - 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. + 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 + - 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/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..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 @@ -1,126 +1,536 @@ -- 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 - 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] -- name: Couple with children, one working one with Carer's Allowance - eligible +# 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: 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: 1 + is_carer_for_benefits: true + minimum_wage: 10 child: age: 4 - is_parent: false benunits: benunit: members: [parent1, parent2, child] - family_type: COUPLE_WITH_CHILDREN + universal_credit: 3_000 + uc_carer_element: 2_400 output: - extended_childcare_entitlement_work_condition: [1, 1, 0] + receives_uc_carer_element: [false, true, false] + extended_childcare_entitlement_work_condition: [true, true, false] -- name: Couple with children one working one not - ineligible +# 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 - in_work: true is_parent: true + is_carer_for_benefits: true + employment_income: 20_000 + adjusted_net_income: 20_000 + minimum_wage: 10 parent2: age: 38 - in_work: false is_parent: true + minimum_wage: 10 child: age: 4 - is_parent: false benunits: benunit: members: [parent1, parent2, child] - family_type: COUPLE_WITH_CHILDREN + universal_credit: 3_000 + uc_carer_element: 2_400 output: - extended_childcare_entitlement_work_condition: [0, 0, 0] + receives_uc_carer_element: [true, false, false] + extended_childcare_entitlement_work_condition: [true, false, false] -- name: Couple without children both working - ineligible +# 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 + 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] + +# 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 + is_parent: true + carers_allowance: 4_000 + minimum_wage: 10 + parent2: + age: 38 + 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: [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] + +# 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 + is_parent: true + employment_income: 120_000 + adjusted_net_income: 120_000 + minimum_wage: 10 + parent2: + age: 38 + 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: [false, false, false] + +# 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] + +# 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] + +# 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/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/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 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 19410296a0..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 @@ -85,6 +85,72 @@ 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] + # 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 b0f8195c60..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 @@ -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,217 @@ 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] + +# 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. @@ -340,3 +554,73 @@ 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 + +# 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/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..4202d88b7e --- /dev/null +++ b/policyengine_uk/tests/test_dfe_childcare_student_support_properties.py @@ -0,0 +1,442 @@ +"""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 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 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 + 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, example, 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, "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} + + +def meets_work_and_income(adult): + earnings = adult["earnings"] + return ( + earnings > 0 and earnings / 4 >= QUARTERLY_MINIMUM and earnings <= INCOME_LIMIT + ) + + +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: + 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"] 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} + ) + 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, (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 (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, + ) + + +# 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]), + "carers_leave": st.booleans(), + } +) +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"], + "tax_free_childcare_on_carers_leave": adult["carers_leave"], + "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] + # 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] or adults[k]["carers_leave"]) + 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 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..79846e1c91 --- /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 " + "(income-related ESA) counts for both members of a couple; the " + "Universal Credit carer element counts for the carer only." + ) + 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..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 @@ -4,60 +4,73 @@ 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. 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_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", + "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): - 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 - ] + claimant_or_partner = person("is_claimant_or_partner", period) - 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 + # 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) + # 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 np.zeros_like(meets_work_and_income_conditions, dtype=bool) ) + counts_as_working_partner = meets_work_and_income_conditions & ~partner_excluded - # 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(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( + "extended_childcare_entitlement_limited_capability_or_specified_benefit", + period, + ) + & partner_meets_work_and_income_conditions + & meets_income_limit_if_applies ) - 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/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 new file mode 100644 index 0000000000..36dbd2460a --- /dev/null +++ b/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_caring_or_incapacity_benefit.py @@ -0,0 +1,24 @@ +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: 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" + + 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..7395c6554c --- /dev/null +++ b/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_on_carers_leave.py @@ -0,0 +1,18 @@ +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, " + "in England and Wales and Scotland only (carer's leave does not " + "exist in Northern Ireland)." + ) + 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..73c201dc8d --- /dev/null +++ b/policyengine_uk/variables/gov/hmrc/tax_free_childcare/conditions/tax_free_childcare_regarded_as_in_paid_work.py @@ -0,0 +1,53 @@ +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)) 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 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 + 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_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 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) + & ~paid_caring_or_incapacity_benefit + ) + partner_in_qualifying_paid_work = ( + 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_benefit | on_qualifying_carers_leave) + & 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)