Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Targeted childcare entitlement #1013

Draft
wants to merge 47 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 46 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
adf96a0
Implement tax free childcare
vahid-ahmadi Jan 10, 2025
ee24d61
Parameterize values
vahid-ahmadi Jan 13, 2025
12d24be
Reformatting to pass the tests
vahid-ahmadi Jan 13, 2025
235fd08
Reformatting with black
vahid-ahmadi Jan 13, 2025
b3b1967
Reformatting with black
vahid-ahmadi Jan 13, 2025
55ce6c3
Format code with black
vahid-ahmadi Jan 13, 2025
9952ed9
Format code with black using 79-char line length
vahid-ahmadi Jan 13, 2025
d6b22e5
Fix YAML structure
vahid-ahmadi Jan 13, 2025
b06a47c
Fix age condition YAML file
vahid-ahmadi Jan 13, 2025
90eb823
Fix age condition YAML file
vahid-ahmadi Jan 13, 2025
0c871a5
Fix other YAML files
vahid-ahmadi Jan 13, 2025
b28b5f8
Edit parameterization
vahid-ahmadi Jan 13, 2025
ff1f456
Fix formatting
vahid-ahmadi Jan 13, 2025
d3ad685
Edit age in YAML files
vahid-ahmadi Jan 13, 2025
5c6d359
Replace if with where
vahid-ahmadi Jan 13, 2025
e0221f8
Format with black
vahid-ahmadi Jan 13, 2025
fc83a03
Edit for test passing
vahid-ahmadi Jan 13, 2025
4421154
Edit format with black
vahid-ahmadi Jan 13, 2025
b4e8d1a
Edit format of benefit py file
vahid-ahmadi Jan 13, 2025
cf7f6e6
Edit child as not being boolean
vahid-ahmadi Jan 13, 2025
d4ff3b2
Change if to where
vahid-ahmadi Jan 14, 2025
0058402
Change disability definition
vahid-ahmadi Jan 14, 2025
37c7228
Solve .values problem
vahid-ahmadi Jan 14, 2025
af96f3a
Edit .values error
vahid-ahmadi Jan 14, 2025
e96bc2e
Edit vectorization problem
vahid-ahmadi Jan 14, 2025
153c2f6
Change folder from hmrc to dwp
vahid-ahmadi Jan 14, 2025
c9fbd0c
Use is_disabled_for_benefits variable
vahid-ahmadi Jan 14, 2025
a2f73d2
Add .astype(bool) to fix error
vahid-ahmadi Jan 14, 2025
a061877
Fix bitwise AND operation error
vahid-ahmadi Jan 14, 2025
a9ca8a7
Add .astype(bool) to conditions
vahid-ahmadi Jan 14, 2025
c7c6762
Add unit tests
vahid-ahmadi Jan 14, 2025
59e1b78
Reformat with black
vahid-ahmadi Jan 14, 2025
cebaace
Fix the folders
vahid-ahmadi Jan 15, 2025
c1a5cf0
Fix the folders
vahid-ahmadi Jan 15, 2025
49ec556
Merge branch 'tax-free-childcare-new' of https://github.com/policyeng…
vahid-ahmadi Jan 15, 2025
4a5cad5
Implement free childcare program
vahid-ahmadi Jan 15, 2025
4432db2
Format with black
vahid-ahmadi Jan 15, 2025
c7c1998
Change tests
vahid-ahmadi Jan 15, 2025
789f676
Edit format based on Pavel's comments
vahid-ahmadi Jan 17, 2025
cd3ff72
Implement universal 15-hours free childcare
vahid-ahmadi Jan 17, 2025
e792de8
Edit folders
vahid-ahmadi Jan 24, 2025
aacf564
Edit codes and labels
vahid-ahmadi Jan 24, 2025
d736589
Format with black
vahid-ahmadi Jan 24, 2025
10bfdb3
Create targeted childcare entitlement files
vahid-ahmadi Jan 24, 2025
3bc607d
Add eligibility conditions
vahid-ahmadi Jan 24, 2025
4353765
Add unit tests and improve the code
vahid-ahmadi Jan 29, 2025
ffea941
Merge branch 'master' into targeted-childcare-entitlement
vahid-ahmadi Feb 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
description: The Department for Education provides targeted childcare entitlement in England for specific age brackets
metadata:
type: single_amount
threshold_unit: year
reference:
- title: The Local Authority (Duty to Secure Early Years Provision Free of Charge) Regulations 2014 - regulation 3
href: https://www.legislation.gov.uk/uksi/2014/2147/regulation/3/made
- title: Document for 15 hours free education and childcare for 2-year old
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

title should always be as close as possible to just the official title, like you have above. GOV.UK | Claim benefits for free childcare etc

href: https://www.gov.uk/help-with-childcare-costs/free-childcare-2-year-olds-claim-benefits?step-by-step-nav=f237ec8e-e82c-4ffa-8fba-2a88a739783b
brackets:
- threshold:
2015-01-01: 0
amount:
values:
2015-01-01: false
- threshold:
2015-01-01: 2
amount:
values:
2015-01-01: true
- threshold:
2015-01-01: 3
amount:
values:
2015-01-01: false
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
description: The Department for Education provides targeted childcare entitlement in England, offering specific hours per year.
metadata:
unit: hour
period: year
label: Annual targeted childcare entitlement hours
reference:
- title: The Local Authority (Duty to Secure Early Years Provision Free of Charge) Regulations 2014 - regulation 4
href: https://www.legislation.gov.uk/uksi/2014/2147/regulation/4/made
- title: Document for 15 hours free education and childcare for 2-year old
href: https://www.gov.uk/help-with-childcare-costs/free-childcare-2-year-olds-claim-benefits?step-by-step-nav=f237ec8e-e82c-4ffa-8fba-2a88a739783b
values:
2015-01-01: 570
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
description: The Department for Education sets an income threshold for Tax Credits recipients to be eligible for 15 hours free education and childcare for 2-year old.
metadata:
unit: GBP
period: year
label: Income threshold for tax Credits recipients
reference:
- title: The Local Authority (Duty to Secure Early Years Provision Free of Charge) Regulations 2014, part 1.2.b
href: https://www.legislation.gov.uk/uksi/2014/2147/regulation/1/made
- title: Document for 15 hours free education and childcare for 2-year old
href: https://www.gov.uk/help-with-childcare-costs/free-childcare-2-year-olds-claim-benefits?step-by-step-nav=f237ec8e-e82c-4ffa-8fba-2a88a739783b
values:
2015-01-01: 16_190

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
description: The Department for Education sets an income threshold for Universal Credit recipients to be eligible 15 hours free education and childcare for 2-year old.
# The threshold is set by statutory guidance, not legislation. A 2018 Department for Education response introduced this net earnings limit for free childcare eligibility.
metadata:
unit: GBP
period: year
label: Income threshold for Universal Credit recipients
reference:
- title: Document for Eligibility for free school meals, the early years pupil premium and the free early education entitlement for two-year-olds under Universal Credit - page 5
href: https://assets.publishing.service.gov.uk/media/5ab270baed915d4f2d097124/Government_response_FSM_and_EY_entitlements_under_Universal_Credit.pdf?utm_source=chatgpt.com
- title: Document for 15 hours free education and childcare for 2-year old
href: https://www.gov.uk/help-with-childcare-costs/free-childcare-2-year-olds-claim-benefits?step-by-step-nav=f237ec8e-e82c-4ffa-8fba-2a88a739783b
values:
2015-01-01: 15_400
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
description: List of qualifying benefits for targeted childcare entitlement eligibility assessment
metadata:
reference:
- title: Local Authority (Duty to Secure Early Years Provision Free of Charge) Regulations 2014 - 1.a to 1.g
href: https://www.legislation.gov.uk/uksi/2014/2147/regulation/1/made#f00009
period: year
unit: program
label: Qualifying benefits for targeted childcare entitlement (childcare for 2 year olds)
values:
2015-01-01:
- jsa_income
- esa_income
- universal_credit
- is_guarantee_credit_eligible
- child_tax_credit
- working_tax_credit
- dla
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
- name: eligible with JSA income
period: 2025
input:
people:
adult:
total_income: 10000
social_security_income: 5000
dla: 0
benunits:
benunit:
members: [adult]
jsa_income: 100
esa_income: 0
universal_credit: 0
is_guarantee_credit_eligible: false
child_tax_credit: 0
working_tax_credit: 0
output:
targeted_childcare_entitlement_combine_benefits: true

- name: eligible with universal credit low income
period: 2025
input:
people:
adult:
total_income: 15000
social_security_income: 0
dla: 0
benunits:
benunit:
members: [adult]
jsa_income: 0
esa_income: 0
universal_credit: 100
is_guarantee_credit_eligible: false
child_tax_credit: 0
working_tax_credit: 0
output:
targeted_childcare_entitlement_combine_benefits: true

- name: eligible with tax credits low income
period: 2025
input:
people:
adult:
total_income: 16000
social_security_income: 0
dla: 0
benunits:
benunit:
members: [adult]
jsa_income: 0
esa_income: 0
universal_credit: 0
is_guarantee_credit_eligible: false
child_tax_credit: 100
working_tax_credit: 0
output:
targeted_childcare_entitlement_combine_benefits: true

- name: ineligible high income with universal credit
period: 2025
input:
people:
adult:
total_income: 20000
social_security_income: 4600 # Setting this to ensure adjusted_income > threshold
dla: 0
benunits:
benunit:
members: [adult]
jsa_income: 0
esa_income: 0
universal_credit: 0 # No UC receipt
is_guarantee_credit_eligible: false
child_tax_credit: 0
working_tax_credit: 0
output:
targeted_childcare_entitlement_combine_benefits: false

- name: ineligible with no qualifying benefits
period: 2025
input:
people:
adult:
total_income: 10000
social_security_income: 0
dla: 0
benunits:
benunit:
members: [adult]
jsa_income: 0
esa_income: 0
universal_credit: 0
is_guarantee_credit_eligible: false
child_tax_credit: 0
working_tax_credit: 0
output:
targeted_childcare_entitlement_combine_benefits: false
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
- name: eligible child age 2
period: 2025
input:
people:
parent:
age: 30
is_child: false
child:
age: 2
is_child: true
benunits:
benunit:
members: [parent, child]
output:
targeted_childcare_entitlement_eligibility: true

- name: ineligible child age 1
period: 2025
input:
people:
parent:
age: 30
is_child: false
child:
age: 1
is_child: true
benunits:
benunit:
members: [parent, child]
output:
targeted_childcare_entitlement_eligibility: false

- name: ineligible child age 4
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capitalise etc

period: 2025
input:
people:
parent:
age: 30
is_child: false
child:
age: 4
is_child: true
benunits:
benunit:
members: [parent, child]
output:
targeted_childcare_entitlement_eligibility: false

- name: multiple children one eligible
period: 2025
input:
people:
parent:
age: 30
is_child: false
child1:
age: 2
is_child: true
child2:
age: 4
is_child: true
benunits:
benunit:
members: [parent, child1, child2]
output:
targeted_childcare_entitlement_eligibility: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
- name: fully eligible
period: 2025
input:
targeted_childcare_entitlement_eligibility: true
targeted_childcare_entitlement_combine_benefits: true
output:
targeted_childcare_entitlement_hours: 570

- name: age eligible only
period: 2025
input:
targeted_childcare_entitlement_eligibility: true
targeted_childcare_entitlement_combine_benefits: false
output:
targeted_childcare_entitlement_hours: 570

- name: benefits eligible only
period: 2025
input:
targeted_childcare_entitlement_eligibility: false
targeted_childcare_entitlement_combine_benefits: true
output:
targeted_childcare_entitlement_hours: 570

- name: not eligible
period: 2025
input:
targeted_childcare_entitlement_eligibility: false
targeted_childcare_entitlement_combine_benefits: false
output:
targeted_childcare_entitlement_hours: 0
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
from policyengine_uk.model_api import *


class targeted_childcare_entitlement_combine_benefits(Variable):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A rule of thumb to exercise here is 'if I take out underscores and replace with spaces', this should fit natural into "I'm going to calculate this household's {variable name}".

This one doesn't

value_type = bool
entity = BenUnit
label = "Eligible for Targeted childcare entitlement based on benefits"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Grammar

definition_period = YEAR
# details for implementation: https://www.gov.uk/help-with-childcare-costs/free-childcare-2-year-olds-claim-benefits?step-by-step-nav=f237ec8e-e82c-4ffa-8fba-2a88a739783b

def formula(benunit, period, parameters):
# Calculate total income for the benefit unit
benunit_income = benunit.sum(benunit.members("total_income", period))
# Calculate benefits income to exclude from Universal Credit calculation
benefits_income = benunit.sum(
benunit.members("social_security_income", period)
)
# Income excluding benefits for Universal Credit threshold check
adjusted_income = benunit_income - benefits_income

p = parameters(period).gov.dwp.targeted_childcare_entitlement

# Check if receiving any qualifying benefits
qualifying_benefits = add(
benunit,
period,
p.qualifying_benefits,
)

# Get universal credit receipt specifically for income test
receives_universal_credit = benunit("universal_credit", period) > 0

# Get tax credits receipt specifically for income test
receives_child_tax_credit = benunit("child_tax_credit", period) > 0
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
receives_child_tax_credit = benunit("child_tax_credit", period) > 0
ctc_wtc = add(benunit, period, ["child_tax_credit", "working_tax_credit"])
receives_ctc_wtc = ctc_wtc > 0

receives_working_tax_credit = benunit("working_tax_credit", period) > 0

# Check Universal Credit with income threshold
meets_universal_credit_income = receives_universal_credit & (
adjusted_income <= p.income_threshold_with_universal_credit
)

# Check Tax Credits with income threshold
meets_tax_credits_income = (
receives_child_tax_credit | receives_working_tax_credit
) & (benunit_income <= p.income_threshold_with_tax_credits)

return (
(qualifying_benefits > 0) # Any qualifying benefit
| meets_universal_credit_income # Universal Credit with income threshold
| meets_tax_credits_income # Tax Credits with income threshold
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from policyengine_uk.model_api import *


class targeted_childcare_entitlement_eligibility(Variable):
value_type = bool
entity = BenUnit
label = "targeted childcare entitlement eligibility"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No notes on this file- clean, follows style rules, well documented!

documentation = "Whether the benefit unit has any children eligible for targeted childcare entitlement"
definition_period = YEAR

def formula(benunit, period, parameters):
# Get parameters
p = parameters(period).gov.dwp.targeted_childcare_entitlement

# Get ages of all members in the benefit unit
age = benunit.members("age", period)

# Check if they are children
is_child = benunit.members("is_child", period)

# Check if age is eligible using the bracket calculation
is_eligible_age = p.child_age_eligible.calc(age)

return benunit.any(is_child & is_eligible_age)
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from policyengine_uk.model_api import *


class targeted_childcare_entitlement_hours(Variable):
value_type = float
entity = BenUnit
label = "targeted childcare entitlement hours per year"
documentation = "Number of free childcare hours per year the benefit unit is entitled to"
definition_period = YEAR

def formula(benunit, period, parameters):
# Get age eligibility status for targeted entitlement
targeted_eligible_age = benunit(
"targeted_childcare_entitlement_eligibility", period
)

# Get eligibility status for targeted entitlement
targeted_eligible = benunit(
"targeted_childcare_entitlement_combine_benefits", # Changed this line
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"targeted_childcare_entitlement_combine_benefits", # Changed this line
"targeted_childcare_entitlement_combine_benefits",

period,
)

# Use hours directly from parameters file
p = parameters(period).gov.dwp.targeted_childcare_entitlement

# Return hours if either eligible, 0 if not
return where(
targeted_eligible_age | targeted_eligible, p.hours_per_year, 0
)
Loading