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/fix-abolish-council-tax-net.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Include `council_tax_benefit` in `household_benefits`, `gov_spending`, `hbai_household_net_income`, and `pre_budget_change_household_benefits`. Previously CTR was absent from these aggregates, so abolishing council tax via `gov.contrib.abolish_council_tax` refunded the gross billed amount to households (and removed gross revenue from the government balance) rather than the net out-of-pocket amount, overstating household savings by about £4 billion in aggregate.
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,48 @@ def test_abolish_council_tax_removes_budget_impact():
assert reform_household_tax == baseline_household_tax - 2000
assert reform_gov_balance == baseline_gov_balance - 2000
assert reform_hbai == baseline_hbai + 2000


CTR_SITUATION = {
"people": {
"person": {
"age": {YEAR: 40},
"employment_income": {YEAR: 8000},
"council_tax_benefit_reported": {YEAR: 800},
}
},
"benunits": {"benunit": {"members": ["person"]}},
"households": {
"household": {
"members": ["person"],
"council_tax": {YEAR: 2000},
"council_tax_band": {YEAR: "C"},
}
},
}


@pytest.mark.microsimulation
def test_abolish_council_tax_nets_out_council_tax_benefit():
"""CTR recipient should see net-CT saving, not gross-CT saving.

Pre-reform: household pays £2,000 gross council tax and receives £800
CTR, so out-of-pocket is £1,200 (the net bill). Abolishing council
tax saves them the £1,200, not the £2,000 — because the £800 CTR
rebate disappears alongside the council tax it was rebating.
"""
baseline = Microsimulation(situation=CTR_SITUATION)
reform = Microsimulation(
situation=CTR_SITUATION,
reform={"gov.contrib.abolish_council_tax": True},
)

baseline_hbai = baseline.calculate("hbai_household_net_income", YEAR).sum()
reform_hbai = reform.calculate("hbai_household_net_income", YEAR).sum()
baseline_gov_balance = baseline.calculate("gov_balance", YEAR).sum()
reform_gov_balance = reform.calculate("gov_balance", YEAR).sum()

# Net council tax = £2,000 - £800 CTR = £1,200 saving.
assert reform_hbai == pytest.approx(baseline_hbai + 1200, abs=1)
# Government loses net council tax revenue (gross - CTR forgone).
assert reform_gov_balance == pytest.approx(baseline_gov_balance - 1200, abs=1)
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class pre_budget_change_household_benefits(Variable):
unit = GBP
adds = [
"child_benefit",
"council_tax_benefit",
"esa_income",
"housing_benefit",
"income_support",
Expand Down
8 changes: 8 additions & 0 deletions policyengine_uk/variables/gov/gov_spending.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class gov_spending(Variable):
unit = GBP
adds = [
"child_benefit",
"council_tax_benefit",
"esa_income",
"esa_contrib",
"housing_benefit",
Expand Down Expand Up @@ -57,3 +58,10 @@ class gov_spending(Variable):
"nhs_spending",
"carer_support_payment",
]

def formula(household, period, parameters):
variables = list(gov_spending.adds)
abolish_council_tax = parameters.gov.contrib.abolish_council_tax(period)
if abolish_council_tax:
variables = [v for v in variables if v != "council_tax_benefit"]
return add(household, period, variables)
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class hbai_household_net_income(Variable):
"free_school_milk",
"free_tv_licence_value",
"child_benefit",
"council_tax_benefit",
"esa_income",
"esa_contrib",
"housing_benefit",
Expand Down Expand Up @@ -74,15 +75,13 @@ class hbai_household_net_income(Variable):
def formula(household, period, parameters):
abolish_council_tax = parameters.gov.contrib.abolish_council_tax(period)
if abolish_council_tax:
return add(
household,
period,
hbai_household_net_income.adds,
) - add(
household,
period,
[s for s in hbai_household_net_income.subtracts if s != "council_tax"],
)
adds = [
a for a in hbai_household_net_income.adds if a != "council_tax_benefit"
]
subtracts = [
s for s in hbai_household_net_income.subtracts if s != "council_tax"
]
return add(household, period, adds) - add(household, period, subtracts)
return add(household, period, hbai_household_net_income.adds) - add(
household, period, hbai_household_net_income.subtracts
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class household_benefits(Variable):
unit = GBP
adds = [
"child_benefit",
"council_tax_benefit",
"esa_income",
"esa_contrib",
"housing_benefit",
Expand Down