diff --git a/changelog.d/1818.fixed.md b/changelog.d/1818.fixed.md new file mode 100644 index 0000000000..58264dbc8e --- /dev/null +++ b/changelog.d/1818.fixed.md @@ -0,0 +1 @@ +- Added Universal Credit benefit cap earnings exception regression tests (Universal Credit Regulations 2013 reg. 82), including the per-claimant earned income cases (tax on pension income, one partner's pension contributions, contributions after 75), and cited regs. 55 and 57 and Finance Act 2004 s. 188 on `is_uc_benefit_cap_exempt_earnings`. diff --git a/policyengine_uk/tests/policy/baseline/gov/dwp/benefit_cap/benefit_cap_specified_benefits.yaml b/policyengine_uk/tests/policy/baseline/gov/dwp/benefit_cap/benefit_cap_specified_benefits.yaml index a33fcf4574..082ac4d353 100644 --- a/policyengine_uk/tests/policy/baseline/gov/dwp/benefit_cap/benefit_cap_specified_benefits.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/dwp/benefit_cap/benefit_cap_specified_benefits.yaml @@ -1106,6 +1106,88 @@ is_uc_benefit_cap_exempt_specified_benefit: false is_housing_benefit_benefit_cap_exempt_specified_benefit: true +- name: A dependent young person's AFIP does not lift the Universal Credit cap, so the award is capped + # For Universal Credit, AFIP is within "attendance allowance" (UC Regs + # 2013 reg 2), and reg 83(1)(c) excepts only where "a claimant is + # receiving" it. The 17-year-old is a qualifying young person, not a + # claimant, so the family's Universal Credit is capped at the London + # family rate of 25,323 a year. AFIP also earns no disabled child + # addition (reg 24(2) lists DLA, PIP and the Scottish equivalents, and + # blindness for the higher rate), so the maximum amount is the standard + # allowance, three child elements and the 30,000 housing costs element. + period: 2026 + input: + people: + parent: + age: 45 + young_person: + age: 17 + current_education: UPPER_SECONDARY + armed_forces_independence_payment: 5_740 + child1: + age: 10 + child2: + age: 8 + benunits: + benunit: + members: [parent, young_person, child1, child2] + households: + household: + members: [parent, young_person, child1, child2] + region: LONDON + tenure_type: RENT_FROM_COUNCIL + rent: 30_000 + output: + is_qualifying_young_person_for_child_benefit: [false, true, false, false] + is_uc_assessed_claimant: [true, false, false, false] + is_uc_benefit_cap_exempt_specified_benefit: false + is_uc_benefit_cap_exempt: false + uc_benefit_cap: 25_323 + uc_disability_elements: 0 + universal_credit_pre_benefit_cap: 46_615.92 + uc_benefit_cap_reduction: 24_561.12 + universal_credit: 22_054.80 + absolute_error_margin: 1 + +- name: A dependent young person's AFIP lifts the Housing Benefit cap, so the award is paid in full + # HB Regs 2006 reg 75F(1)(ea) names "the claimant, the claimant's partner + # or a young person for whom the claimant or the claimant's partner is + # responsible". The same family on legacy Housing Benefit (an existing + # award, no Universal Credit claim) is outside the cap, so its Housing + # Benefit is paid in full. + period: 2026 + input: + people: + parent: + age: 45 + housing_benefit_reported: 10_000 + young_person: + age: 17 + current_education: UPPER_SECONDARY + armed_forces_independence_payment: 5_740 + child1: + age: 10 + child2: + age: 8 + benunits: + benunit: + members: [parent, young_person, child1, child2] + would_claim_uc: false + households: + household: + members: [parent, young_person, child1, child2] + region: LONDON + tenure_type: RENT_FROM_COUNCIL + rent: 30_000 + output: + universal_credit_pre_benefit_cap: 0 + is_housing_benefit_benefit_cap_exempt_specified_benefit: true + is_housing_benefit_benefit_cap_exempt: true + housing_benefit_benefit_cap_reduction: 0 + housing_benefit_pre_benefit_cap: 30_000 + housing_benefit: 30_000 + absolute_error_margin: 1 + - name: A 16-year-old out of education with armed forces independence payment does not lift the cap period: 2025 input: diff --git a/policyengine_uk/tests/policy/baseline/gov/dwp/benefit_cap/is_uc_benefit_cap_exempt_earnings.yaml b/policyengine_uk/tests/policy/baseline/gov/dwp/benefit_cap/is_uc_benefit_cap_exempt_earnings.yaml new file mode 100644 index 0000000000..dacaa41c45 --- /dev/null +++ b/policyengine_uk/tests/policy/baseline/gov/dwp/benefit_cap/is_uc_benefit_cap_exempt_earnings.yaml @@ -0,0 +1,229 @@ +# Universal Credit benefit cap earnings exception, Universal Credit +# Regulations 2013 reg. 82. +# https://www.legislation.gov.uk/uksi/2013/376/regulation/82 +# https://www.gov.uk/benefit-cap/when-youre-not-affected + +# --- Earnings exception: only tax on the earnings is deducted (reg. 55(5)) --- + +- name: Unearned income does not reduce net earnings for the earnings exception + # Regulation 55(5) deducts the income tax paid "in respect of the + # employment", not the claimant's whole income tax liability. Property + # income of 40,000 pushes total income tax to over 8,000, but the tax + # attributable to the 13,000 of earnings is under 100, so net earnings stay + # well above the 846/month threshold and the exception applies. + period: 2025 + input: + people: + person: + age: 35 + employment_income: 13_000 + property_income: 40_000 + benunits: + benunit: + members: [person] + output: + is_uc_benefit_cap_exempt_earnings: true + is_uc_benefit_cap_exempt: true + +- name: Earnings below the threshold do not except, even with large unearned income + # The same unearned income with earnings of 8,000 leaves net earnings below + # 846 x 12 = 10,152, so the exception does not apply. + period: 2025 + input: + people: + person: + age: 35 + employment_income: 8_000 + property_income: 40_000 + benunits: + benunit: + members: [person] + output: + is_uc_benefit_cap_exempt_earnings: false + +- name: A couple's earnings are combined for the earnings exception + # Reg. 82(1)(a) applies to "the claimant's and their partner's combined + # earned income". Neither partner alone reaches 10,152; together they do. + period: 2025 + input: + people: + person1: + age: 35 + employment_income: 6_000 + person2: + age: 35 + employment_income: 6_000 + benunits: + benunit: + members: [person1, person2] + output: + is_uc_benefit_cap_exempt_earnings: true + +- name: Relievable pension contributions reduce earned income + # Reg. 55(5)(a) deducts relievable pension contributions from employed + # earnings, so a contribution that takes net earnings below the threshold + # removes the exception. + period: 2025 + input: + people: + person: + age: 35 + employment_income: 11_000 + employee_pension_contributions: 1_500 + benunits: + benunit: + members: [person] + output: + is_uc_benefit_cap_exempt_earnings: false + +- name: Tax on private pension income does not reduce earned income for the earnings exception + # Reg. 55(5)(b) deducts only income tax paid "in respect of the + # employment". The 5,000 private pension uses up the personal allowance, + # so earned_income_tax (tax on non-savings, non-dividend income) is 546, + # but none of it is in respect of the 10,300 of wages. Earned income is + # 10,300, which clears 846 x 12 = 10,152, so the cap does not reduce the + # family's Universal Credit. + period: 2025 + input: + people: + parent: + age: 35 + employment_income: 10_300 + private_pension_income: 5_000 + child1: + age: 5 + child2: + age: 8 + benunits: + benunit: + members: [parent, child1, child2] + households: + household: + members: [parent, child1, child2] + region: LONDON + tenure_type: RENT_FROM_COUNCIL + rent: 30_000 + output: + earned_income_tax: [546, 0, 0] + uc_income_tax_on_earnings: [0, 0, 0] + is_uc_benefit_cap_exempt_earnings: true + benefit_cap_reduction: 0 + universal_credit: 33_876.72 + absolute_error_margin: 1 + +- name: One partner's pension contributions do not reduce the other partner's earnings + # Reg. 82(1)(a) adds the couple's earned income, and each person's earned + # income is their own earnings less their own deductions. The + # self-employed partner's 100 of profit less 3,000 of relievable pension + # contributions is nil, not minus 2,900 (reg. 57(2), steps 3 and 4). + # Combined earned income is 10,600, which clears 881 x 12 = 10,572. + period: 2026 + input: + people: + employee: + age: 35 + employment_income: 10_600 + self_employed: + age: 35 + self_employment_income: 100 + personal_pension_contributions: 3_000 + child1: + age: 5 + child2: + age: 8 + benunits: + benunit: + members: [employee, self_employed, child1, child2] + households: + household: + members: [employee, self_employed, child1, child2] + region: LONDON + tenure_type: RENT_FROM_COUNCIL + rent: 30_000 + output: + uc_individual_earned_income_before_mif: [10_600, 0, 0, 0] + is_uc_benefit_cap_exempt_earnings: true + benefit_cap_reduction: 0 + universal_credit: 31_074.08 + absolute_error_margin: 1 + +- name: Pension contributions after 75 are not deducted from earned income + # Contributions paid after the individual reaches 75 are not relievable + # (Finance Act 2004 s. 188(3)(a)), so reg. 55(5)(a) does not deduct them. + # The mixed-age couple's Universal Credit award is capped like any other + # (reg. 3(2)(a); no age exception reaches it), and the older partner's + # 11,000 of earnings clears 881 x 12 = 10,572 before and after the + # 1,000 contribution. + period: 2026 + input: + people: + older_partner: + age: 76 + employment_income: 11_000 + employee_pension_contributions: 1_000 + younger_partner: + age: 40 + child1: + age: 5 + child2: + age: 8 + benunits: + benunit: + members: [older_partner, younger_partner, child1, child2] + households: + household: + members: [older_partner, younger_partner, child1, child2] + region: LONDON + tenure_type: RENT_FROM_COUNCIL + rent: 30_000 + output: + is_uc_assessed_claimant: [true, true, false, false] + housing_benefit_pension_age_regulations_apply: false + uc_individual_earned_income_before_mif: [11_000, 0, 0, 0] + is_uc_benefit_cap_exempt_earnings: true + benefit_cap_reduction: 0 + universal_credit: 42_066.40 + absolute_error_margin: 1 + +# --- Earnings threshold follows the national living wage, not a fixed 10,152 --- + +- name: The 2025-26 earnings threshold is 846 a month + period: 2025 + input: + people: + person: + age: 35 + employment_income: 10_300 + benunits: + benunit: + members: [person] + output: + # 10,300 clears 846 x 12 = 10,152. + is_uc_benefit_cap_exempt_earnings: true + +- name: The 2026-27 earnings threshold rises to 881 a month + period: 2026 + input: + people: + person: + age: 35 + employment_income: 10_300 + benunits: + benunit: + members: [person] + output: + # The same earnings fall short of 881 x 12 = 10,572. + is_uc_benefit_cap_exempt_earnings: false + +- name: Earnings above the 2026-27 threshold except from the cap + period: 2026 + input: + people: + person: + age: 35 + employment_income: 10_600 + benunits: + benunit: + members: [person] + output: + is_uc_benefit_cap_exempt_earnings: true diff --git a/policyengine_uk/tests/test_uc_single_claim_properties.py b/policyengine_uk/tests/test_uc_single_claim_properties.py index f7dbea924e..83b0fbe164 100644 --- a/policyengine_uk/tests/test_uc_single_claim_properties.py +++ b/policyengine_uk/tests/test_uc_single_claim_properties.py @@ -118,6 +118,7 @@ "pip_dl": 0.0, "afcs": 0.0, "esa_contrib": 0.0, + "armed_forces_independence_payment": 0.0, } @@ -132,6 +133,7 @@ def adult(draw, ages): pip_dl=draw(pip), afcs=draw(sometimes_paid), esa_contrib=draw(sometimes_paid), + armed_forces_independence_payment=draw(sometimes_paid), ) @@ -160,6 +162,7 @@ def adult_inputs(age, **inputs): pip_dl=0.0, afcs=0.0, esa_contrib=0.0, + armed_forces_independence_payment=0.0, ) values.update(inputs) return values @@ -259,6 +262,16 @@ def example_families(): tenure="RENT_FROM_COUNCIL", region="NORTH_EAST", ), + # An other member with armed forces independence payment and nothing + # else. + dict( + claimant=adult_inputs(40), + partner=adult_inputs(40, armed_forces_independence_payment=5_000.0), + children=[], + rent=0.0, + tenure="RENT_FROM_COUNCIL", + region="NORTH_EAST", + ), ] @@ -272,6 +285,7 @@ def example_families(): afcs_partner=6, esa_partner=7, afcs_claimant=8, + afip_partner=9, ) EXAMPLE_FAMILIES = example_families() @@ -497,12 +511,12 @@ def test_deduction_is_the_joint_claimants(families, year): @given( families=populations, year=st.sampled_from([2021, 2026]), - balances=st.lists(st.floats(0, 30_000), min_size=18, max_size=18), + balances=st.lists(st.floats(0, 30_000), min_size=20, max_size=20), ) @example( families=example_families(), year=2026, - balances=[8_000.0, 16_000.0, 0.0, 30_000.0, 2_000.0, 0.0] + [5_000.0] * 12, + balances=[8_000.0, 16_000.0, 0.0, 30_000.0, 2_000.0, 0.0] + [5_000.0] * 14, ) def test_capital_includes_the_other_members(families, year, balances): families = copy.deepcopy(families) @@ -700,6 +714,13 @@ def test_examples_reach_the_cases(): assert joint["is_uc_benefit_cap_exempt_specified_benefit"][family] assert single["is_housing_benefit_benefit_cap_exempt_specified_benefit"][family] assert single["is_uc_benefit_cap_exempt_specified_benefit"][i["afcs_claimant"]] + # Reg. 83(1)(c) with reg. 2: armed forces independence payment is + # attendance allowance, which lifts the UC cap only for a claimant. HB + # reg. 75F(1)(ea): the partner's lifts the HB cap either way. + family = i["afip_partner"] + assert not single["is_uc_benefit_cap_exempt_specified_benefit"][family] + assert joint["is_uc_benefit_cap_exempt_specified_benefit"][family] + assert single["is_housing_benefit_benefit_cap_exempt_specified_benefit"][family] # Reg. 80A(2) and Sch 4 para 28(2): single rate and shared accommodation. # HB regs. 2(1), 13D(2) and 75CA(2): a couple either way. family = i["young_renter"] diff --git a/policyengine_uk/variables/gov/dwp/universal_credit/benefit_cap/is_uc_benefit_cap_exempt_earnings.py b/policyengine_uk/variables/gov/dwp/universal_credit/benefit_cap/is_uc_benefit_cap_exempt_earnings.py index 872611b651..d94ce843dd 100644 --- a/policyengine_uk/variables/gov/dwp/universal_credit/benefit_cap/is_uc_benefit_cap_exempt_earnings.py +++ b/policyengine_uk/variables/gov/dwp/universal_credit/benefit_cap/is_uc_benefit_cap_exempt_earnings.py @@ -24,19 +24,28 @@ class is_uc_benefit_cap_exempt_earnings(Variable): reference = ( "https://www.legislation.gov.uk/uksi/2013/376/regulation/82", "https://www.legislation.gov.uk/uksi/2013/376/regulation/55", + "https://www.legislation.gov.uk/uksi/2013/376/regulation/57", + "https://www.legislation.gov.uk/ukpga/2004/12/section/188", ) def formula(benunit, period, parameters): + # UC Regs 2013 reg. 82(1)(a) excepts an award where "the claimant's + # earned income or, if the claimant is a member of a couple, the + # couple's combined earned income" reaches 16 hours a week at the + # National Living Wage. A dependant's earnings do not count. + # + # Earned income is each claimant's own, after the reg. 55(5) and + # 57(2) deductions, so one partner's deductions never come off the + # other partner's earnings, tax on pension, property, savings or + # dividend income is not deducted, and contributions paid after 75 + # are not relievable (Finance Act 2004 s. 188(3)(a)). It is read + # before the minimum income floor and the work allowance, because + # reg. 82(4) excludes earnings imputed under reg. 62. + # + # Only earned income is read, not the Universal Credit award itself, + # to avoid a circular dependency with the cap. person = benunit.members - - # Only check earned income, not the UC amount, to avoid a circular dependency. - # UC Regs 2013 reg. 82(1)(a) tests "the claimant's earned income or, - # if the claimant is a member of a couple, the couple's combined - # earned income": a dependant's earnings do not count. claimant = person("is_uc_assessed_claimant", period) - # Reg. 82(4) excludes earnings imputed under the minimum income - # floor (reg. 62). Use actual UC earnings, before both that floor - # and the work allowance, with the reg. 55 and 57 deductions. uc_earned = benunit.sum( person("uc_individual_earned_income_before_mif", period) * claimant )