Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions changelog.d/salary-sacrifice-needs-pay.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Counted salary sacrifice pension contributions only for people with pay, so from 2029 the excess over the £2,000 cap no longer gives employment income to people without pay.
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,10 @@ def test_full_excess_redirected(reform_simulation):
The broad-base haircut reduces ALL workers' employment income,
but the full excess above cap is redirected to regular pension contributions.
"""
# Get weighted totals using map_to for proper aggregation
# Get weighted totals using map_to for proper aggregation. Only people
# with pay have a salary sacrifice, so the excess is measured on that.
ss_contributions = reform_simulation.calculate(
"pension_contributions_via_salary_sacrifice",
"pension_contributions_via_salary_sacrifice_from_pay",
POLICY_YEAR,
map_to="person",
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
# Salary sacrifice counts only for people with pay
# (employment_income_before_lsr > 0). This runner does not copy an
# employment_income input there (policyengine_uk.Simulation does), so each
# case sets both.
- name: No employee NI charge when salary sacrifice below £2,000 cap
period: 2025
absolute_error_margin: 0.01
input:
employment_income: 40_000
employment_income_before_lsr: 40_000
pension_contributions_via_salary_sacrifice: 1_500
gov.hmrc.national_insurance.salary_sacrifice_pension_cap: 2_000
gov.contrib.behavioral_responses.salary_sacrifice_broad_base_haircut_rate: 0
Expand All @@ -14,6 +19,7 @@
absolute_error_margin: 0.01
input:
employment_income: 45_000
employment_income_before_lsr: 45_000
pension_contributions_via_salary_sacrifice: 2_250
gov.hmrc.national_insurance.salary_sacrifice_pension_cap: 2_000
gov.contrib.behavioral_responses.salary_sacrifice_broad_base_haircut_rate: 0
Expand All @@ -26,6 +32,7 @@
absolute_error_margin: 0.01
input:
employment_income: 50_000
employment_income_before_lsr: 50_000
pension_contributions_via_salary_sacrifice: 10_000
gov.hmrc.national_insurance.salary_sacrifice_pension_cap: 2_000
gov.contrib.behavioral_responses.salary_sacrifice_broad_base_haircut_rate: 0
Expand All @@ -38,6 +45,7 @@
absolute_error_margin: 0.01
input:
employment_income: 125_000
employment_income_before_lsr: 125_000
pension_contributions_via_salary_sacrifice: 25_000
gov.hmrc.national_insurance.salary_sacrifice_pension_cap: 2_000
gov.contrib.behavioral_responses.salary_sacrifice_broad_base_haircut_rate: 0
Expand All @@ -50,6 +58,7 @@
absolute_error_margin: 0.01
input:
employment_income: 80_000
employment_income_before_lsr: 80_000
pension_contributions_via_salary_sacrifice: 5_000
gov.hmrc.national_insurance.salary_sacrifice_pension_cap: 2_000
gov.contrib.behavioral_responses.salary_sacrifice_broad_base_haircut_rate: 0
Expand All @@ -62,6 +71,7 @@
absolute_error_margin: 0.01
input:
employment_income: 60_000
employment_income_before_lsr: 60_000
pension_contributions_via_salary_sacrifice: 2_000
gov.hmrc.national_insurance.salary_sacrifice_pension_cap: 2_000
gov.contrib.behavioral_responses.salary_sacrifice_broad_base_haircut_rate: 0
Expand All @@ -73,6 +83,7 @@
absolute_error_margin: 0.01
input:
employment_income: 35_000
employment_income_before_lsr: 35_000
pension_contributions_via_salary_sacrifice: 2_100
gov.hmrc.national_insurance.salary_sacrifice_pension_cap: 2_000
gov.contrib.behavioral_responses.salary_sacrifice_broad_base_haircut_rate: 0
Expand All @@ -85,6 +96,7 @@
absolute_error_margin: 0.01
input:
employment_income: 45_000
employment_income_before_lsr: 45_000
pension_contributions_via_salary_sacrifice: 3_000
gov.hmrc.national_insurance.salary_sacrifice_pension_cap: 2_000
gov.contrib.behavioral_responses.salary_sacrifice_broad_base_haircut_rate: 0
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
# Salary sacrifice counts only for people with pay
# (employment_income_before_lsr > 0). This runner does not copy an
# employment_income input there (policyengine_uk.Simulation does), so each
# case sets both.
- name: No employer NI charge when salary sacrifice below £2,000 cap
period: 2025
absolute_error_margin: 0.01
input:
employment_income: 40_000
employment_income_before_lsr: 40_000
pension_contributions_via_salary_sacrifice: 1_500
gov.hmrc.national_insurance.salary_sacrifice_pension_cap: 2_000
gov.contrib.behavioral_responses.salary_sacrifice_broad_base_haircut_rate: 0
Expand All @@ -14,6 +19,7 @@
absolute_error_margin: 0.01
input:
employment_income: 45_000
employment_income_before_lsr: 45_000
pension_contributions_via_salary_sacrifice: 2_250
gov.hmrc.national_insurance.salary_sacrifice_pension_cap: 2_000
gov.contrib.behavioral_responses.salary_sacrifice_broad_base_haircut_rate: 0
Expand All @@ -26,6 +32,7 @@
absolute_error_margin: 0.01
input:
employment_income: 125_000
employment_income_before_lsr: 125_000
pension_contributions_via_salary_sacrifice: 25_000
gov.hmrc.national_insurance.salary_sacrifice_pension_cap: 2_000
gov.contrib.behavioral_responses.salary_sacrifice_broad_base_haircut_rate: 0
Expand All @@ -38,6 +45,7 @@
absolute_error_margin: 0.01
input:
employment_income: 80_000
employment_income_before_lsr: 80_000
pension_contributions_via_salary_sacrifice: 15_000
gov.hmrc.national_insurance.salary_sacrifice_pension_cap: 2_000
gov.contrib.behavioral_responses.salary_sacrifice_broad_base_haircut_rate: 0
Expand All @@ -50,6 +58,7 @@
absolute_error_margin: 0.01
input:
employment_income: 60_000
employment_income_before_lsr: 60_000
pension_contributions_via_salary_sacrifice: 2_000
gov.hmrc.national_insurance.salary_sacrifice_pension_cap: 2_000
gov.contrib.behavioral_responses.salary_sacrifice_broad_base_haircut_rate: 0
Expand All @@ -61,6 +70,7 @@
absolute_error_margin: 0.01
input:
employment_income: 35_000
employment_income_before_lsr: 35_000
pension_contributions_via_salary_sacrifice: 2_100
gov.hmrc.national_insurance.salary_sacrifice_pension_cap: 2_000
gov.contrib.behavioral_responses.salary_sacrifice_broad_base_haircut_rate: 0
Expand All @@ -73,6 +83,7 @@
absolute_error_margin: 0.01
input:
employment_income: 30_000
employment_income_before_lsr: 30_000
pension_contributions_via_salary_sacrifice: 5_000
gov.hmrc.national_insurance.salary_sacrifice_pension_cap: 2_000
gov.contrib.behavioral_responses.salary_sacrifice_broad_base_haircut_rate: 0
Expand All @@ -85,6 +96,7 @@
absolute_error_margin: 0.01
input:
employment_income: 45_000
employment_income_before_lsr: 45_000
pension_contributions_via_salary_sacrifice: 3_000
gov.hmrc.national_insurance.salary_sacrifice_pension_cap: 2_000
gov.contrib.behavioral_responses.salary_sacrifice_broad_base_haircut_rate: 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
employee_pension_contributions_reported: 5_000
personal_pension_contributions: 0
employer_pension_contributions: 2_000
employment_income_before_lsr: 60_000
pension_contributions_via_salary_sacrifice: 8_000
output:
# employee_pension_contributions = 5_000 + 0 (no excess) = 5_000
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
- name: A sacrifice within pay is kept in full
period: 2029
input:
employment_income_before_lsr: 40_000
pension_contributions_via_salary_sacrifice: 5_000
output:
pension_contributions_via_salary_sacrifice_from_pay: 5_000

- name: A whole-bonus sacrifice above the remaining salary is kept in full
period: 2029
input:
# £40,000 salary kept, £50,000 bonus sacrificed (HMRC allows this while
# cash pay stays above the National Minimum Wage).
employment_income_before_lsr: 40_000
pension_contributions_via_salary_sacrifice: 50_000
output:
pension_contributions_via_salary_sacrifice_from_pay: 50_000

- name: A person without pay sacrifices nothing
period: 2029
input:
pension_contributions_via_salary_sacrifice: 27_000
output:
pension_contributions_via_salary_sacrifice_from_pay: 0

- name: Negative pay supports no sacrifice
period: 2029
input:
employment_income_before_lsr: -1_000
pension_contributions_via_salary_sacrifice: 27_000
output:
pension_contributions_via_salary_sacrifice_from_pay: 0

- name: A negative sacrifice input counts as none
period: 2029
input:
employment_income_before_lsr: 40_000
pension_contributions_via_salary_sacrifice: -500
output:
pension_contributions_via_salary_sacrifice_from_pay: 0

- name: The condition applies before the cap exists, 2028
period: 2028
input:
pension_contributions_via_salary_sacrifice: 27_000
output:
pension_contributions_via_salary_sacrifice_from_pay: 0
pension_contributions_via_salary_sacrifice_adjusted: 0
salary_sacrifice_returned_to_income: 0
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# From 6 April 2029 the salary sacrifice above the £2,000 cap returns to
# employment income. Only people with pay have a salary sacrifice, so the cap
# never gives pay to a person who has none.

- name: No pay and a salary sacrifice input gives no employment income, 2029
period: 2029
absolute_error_margin: 0.01
input:
pension_contributions_via_salary_sacrifice: 27_000
output:
salary_sacrifice_returned_to_income: 0
pension_contributions_via_salary_sacrifice_adjusted: 0
employment_income: 0
salary_sacrifice_pension_ni_employee: 0
salary_sacrifice_pension_ni_employer: 0
employee_pension_contributions: 0

- name: No pay and a salary sacrifice input gives no employment income, 2030
period: 2030
absolute_error_margin: 0.01
input:
pension_contributions_via_salary_sacrifice: 27_000
output:
salary_sacrifice_returned_to_income: 0
employment_income: 0

- name: Self-employed person with no pay gets no employment income, 2029
period: 2029
absolute_error_margin: 0.01
input:
self_employment_income: 30_000
pension_contributions_via_salary_sacrifice: 27_000
output:
salary_sacrifice_returned_to_income: 0
employment_income: 0

- name: Pay above the sacrifice returns the excess over the cap, 2029
period: 2029
absolute_error_margin: 0.01
input:
employment_income_before_lsr: 40_000
pension_contributions_via_salary_sacrifice: 5_000
gov.contrib.behavioral_responses.salary_sacrifice_broad_base_haircut_rate: 0
output:
# 5,000 - 2,000 cap
salary_sacrifice_returned_to_income: 3_000
pension_contributions_via_salary_sacrifice_adjusted: 2_000
employment_income: 43_000

- name: A whole-bonus sacrifice above the remaining salary returns its full excess, 2030
period: 2030
absolute_error_margin: 0.01
input:
employment_income_before_lsr: 40_000
pension_contributions_via_salary_sacrifice: 50_000
gov.contrib.behavioral_responses.salary_sacrifice_broad_base_haircut_rate: 0
output:
# 50,000 - 2,000 cap
salary_sacrifice_returned_to_income: 48_000
pension_contributions_via_salary_sacrifice_adjusted: 2_000
employment_income: 88_000

- name: Low pay with a large sacrifice still returns the excess over the cap, 2029
period: 2029
absolute_error_margin: 0.01
input:
employment_income_before_lsr: 1_500
pension_contributions_via_salary_sacrifice: 30_000
gov.contrib.behavioral_responses.salary_sacrifice_broad_base_haircut_rate: 0
output:
salary_sacrifice_returned_to_income: 28_000
pension_contributions_via_salary_sacrifice_adjusted: 2_000
employment_income: 29_500

- name: Nothing returns before the cap starts, 2028
period: 2028
absolute_error_margin: 0.01
input:
employment_income_before_lsr: 40_000
pension_contributions_via_salary_sacrifice: 5_000
output:
salary_sacrifice_returned_to_income: 0
pension_contributions_via_salary_sacrifice_adjusted: 5_000
employment_income: 40_000
Loading
Loading