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/council-tax-reduction-oxford.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add Oxford working-age Council Tax Reduction.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
description: Maximum Council Tax Reduction rate by weekly income band under the Oxford working-age scheme.
brackets:
- threshold:
2026-04-01: 0
amount:
2026-04-01: 1
- threshold:
2026-04-01: 480.01
amount:
2026-04-01: 0.75
- threshold:
2026-04-01: 530.01
amount:
2026-04-01: 0.5
- threshold:
2026-04-01: 580.01
amount:
2026-04-01: 0.25
- threshold:
2026-04-01: 660.01
amount:
2026-04-01: 0
metadata:
amount_unit: /1
period: week
threshold_unit: currency-GBP
type: single_amount
label: Oxford Council Tax Reduction weekly income-band maximum support rate
reference:
- title: Oxford City Council Council Tax Reduction Scheme 2026 to 2027
href: https://www.oxford.gov.uk/council-tax-reduction/council-tax-reduction-scheme-2026-27
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
description: Capital limit for working-age households under the Oxford Council Tax Reduction scheme.
values:
2026-04-01: 16_000
metadata:
unit: currency-GBP
period: year
label: Oxford Council Tax Reduction capital limit
reference:
- title: Oxford City Council Council Tax Reduction Scheme 2026 to 2027
href: https://www.oxford.gov.uk/council-tax-reduction/council-tax-reduction-scheme-2026-27
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
description: Amount of capital above the tariff threshold that is treated as one weekly pound of income under the Oxford Council Tax Reduction scheme.
values:
2026-04-01: 250
metadata:
unit: currency-GBP
period: year
label: Oxford Council Tax Reduction tariff income capital step
reference:
- title: Oxford City Council Council Tax Reduction Scheme 2026 to 2027
href: https://www.oxford.gov.uk/council-tax-reduction/council-tax-reduction-scheme-2026-27
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
description: Capital threshold above which tariff income applies under the Oxford Council Tax Reduction scheme.
values:
2026-04-01: 6_000
metadata:
unit: currency-GBP
period: year
label: Oxford Council Tax Reduction tariff income capital threshold
reference:
- title: Oxford City Council Council Tax Reduction Scheme 2026 to 2027
href: https://www.oxford.gov.uk/council-tax-reduction/council-tax-reduction-scheme-2026-27
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
description: Weekly working-age non-dependant deduction schedule under the Oxford Council Tax Reduction scheme.
brackets:
- threshold:
2026-04-01: 0
amount:
2026-04-01: 5.2
- threshold:
2026-04-01: 279
amount:
2026-04-01: 10.6
- threshold:
2026-04-01: 485
amount:
2026-04-01: 13.3
- threshold:
2026-04-01: 605
amount:
2026-04-01: 15.95
metadata:
amount_unit: currency-GBP
period: week
threshold_unit: currency-GBP
type: single_amount
label: Oxford Council Tax Reduction working-age non-dependant deduction schedule
reference:
- title: Oxford City Council Council Tax Reduction Scheme 2026 to 2027
href: https://www.oxford.gov.uk/council-tax-reduction/council-tax-reduction-scheme-2026-27
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
description: Weekly hours threshold for remunerative work under Oxford's Council Tax Reduction non-dependant deduction schedule.
values:
2026-04-01: 16
metadata:
unit: hour
period: week
label: Oxford Council Tax Reduction non-dependant remunerative work hours threshold
reference:
- title: Oxford City Council Council Tax Reduction Scheme 2026 to 2027
href: https://www.oxford.gov.uk/council-tax-reduction/council-tax-reduction-scheme-2026-27
Original file line number Diff line number Diff line change
Expand Up @@ -722,3 +722,202 @@
output:
uc_assessable_capital: 0
council_tax_reduction: 1_800

- name: Oxford working-age claimant can receive full support
period: 2026
absolute_error_margin: 0.01
input:
people:
claimant:
age: 35
benunits:
benunit:
members: [claimant]
would_claim_uc: false
claims_all_entitled_benefits: true
households:
household:
members: [claimant]
country: ENGLAND
local_authority: OXFORD
council_tax: 1_800
savings: 0
output:
council_tax_reduction_scheme_supported: true
simulated_council_tax_reduction_benunit: 1_800
council_tax_reduction: 1_800

- name: Oxford applies the 75 percent band above 480 weekly income
period: 2026
absolute_error_margin: 0.01
input:
people:
claimant:
age: 35
benunits:
benunit:
members: [claimant]
would_claim_uc: false
claims_all_entitled_benefits: true
council_tax_reduction_applicable_income: 25_001
households:
household:
members: [claimant]
country: ENGLAND
local_authority: OXFORD
council_tax: 1_800
savings: 0
output:
council_tax_reduction: 1_350

- name: Oxford disregards Child Benefit before selecting the income band
period: 2026
absolute_error_margin: 0.01
input:
people:
claimant:
age: 35
benunits:
benunit:
members: [claimant]
would_claim_uc: false
claims_all_entitled_benefits: true
council_tax_reduction_applicable_income: 25_200
child_benefit: 1_000
households:
household:
members: [claimant]
country: ENGLAND
local_authority: OXFORD
council_tax: 1_800
savings: 0
output:
council_tax_reduction: 1_800

- name: Oxford tariff income rounds up partial 250 pound capital blocks
period: 2026
absolute_error_margin: 0.01
input:
people:
claimant:
age: 35
benunits:
benunit:
members: [claimant]
would_claim_uc: false
claims_all_entitled_benefits: true
council_tax_reduction_applicable_income: 24_960
households:
household:
members: [claimant]
country: ENGLAND
local_authority: OXFORD
council_tax: 1_800
savings: 6_001
output:
council_tax_reduction: 1_350

- name: Oxford UC claimant does not add local tariff income to the UC income band
period: 2026
absolute_error_margin: 0.01
input:
people:
claimant:
age: 35
benunits:
benunit:
members: [claimant]
would_claim_uc: true
claims_all_entitled_benefits: true
uc_maximum_amount: 24_960
uc_income_reduction: 0
council_tax_reduction_applicable_income: 24_960
households:
household:
members: [claimant]
country: ENGLAND
local_authority: OXFORD
council_tax: 1_800
savings: 6_001
output:
council_tax_reduction: 1_800

- name: Oxford working-age claimant above capital limit gets no local support
period: 2026
absolute_error_margin: 0
input:
people:
claimant:
age: 35
council_tax_benefit_reported: 500
benunits:
benunit:
members: [claimant]
claims_all_entitled_benefits: true
households:
household:
members: [claimant]
country: ENGLAND
local_authority: OXFORD
council_tax: 1_800
savings: 16_001
output:
council_tax_reduction_scheme_supported: true
council_tax_benefit: 0
council_tax_reduction: 0

- name: Oxford applies its gross-income non-dependant deduction schedule
period: 2026
absolute_error_margin: 0.01
input:
people:
claimant:
age: 35
non_dep:
age: 25
employment_income: 5_200
private_pension_income: 26_260
weekly_hours: 16
benunits:
claimant_benunit:
members: [claimant]
would_claim_uc: false
claims_all_entitled_benefits: true
non_dep_benunit:
members: [non_dep]
households:
household:
members: [claimant, non_dep]
country: ENGLAND
local_authority: OXFORD
council_tax: 1_800
savings: 0
output:
council_tax_reduction: 970.60

- name: Oxford does not exempt working-age income-based benefit non-dependants
period: 2026
absolute_error_margin: 0.01
input:
people:
claimant:
age: 35
non_dep:
age: 25
benunits:
claimant_benunit:
members: [claimant]
would_claim_uc: false
claims_all_entitled_benefits: true
non_dep_benunit:
members: [non_dep]
income_support: 1
households:
household:
members: [claimant, non_dep]
country: ENGLAND
local_authority: OXFORD
council_tax: 1_800
savings: 0
output:
council_tax_reduction: 1_529.60
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ def is_westminster_working_age(local_authority, country, has_pensioner):
)


def is_oxford(local_authority):
return local_authority == LocalAuthority.OXFORD


def is_oxford_working_age(local_authority, country, has_pensioner):
return (country == Country.ENGLAND) & ~has_pensioner & is_oxford(local_authority)


def is_supported_scheme(country, has_pensioner, local_authority):
return (
is_england_pensioner_scheme(country, has_pensioner)
Expand All @@ -62,4 +70,5 @@ def is_supported_scheme(country, has_pensioner, local_authority):
| is_kingston_upon_thames_working_age(local_authority, country, has_pensioner)
| is_newham_working_age(local_authority, country, has_pensioner)
| is_westminster_working_age(local_authority, country, has_pensioner)
| is_oxford_working_age(local_authority, country, has_pensioner)
)
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"kingston_upon_thames_council_tax_reduction",
"newham_council_tax_reduction",
"westminster_council_tax_reduction",
"oxford_council_tax_reduction",
]


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
from policyengine_uk.model_api import *
import numpy as np
from policyengine_uk.variables.gov.local_authorities.council_tax_reduction.config import (
is_oxford_working_age,
)


class oxford_council_tax_reduction(Variable):
value_type = float
entity = BenUnit
label = "Oxford Council Tax Reduction"
definition_period = YEAR
unit = GBP

def formula(benunit, period, parameters):
ctr = parameters(period).gov.local_authorities.oxford.council_tax_reduction
household = benunit.household
working_age = is_oxford_working_age(
household("local_authority", period),
household("country", period),
household("council_tax_reduction_household_has_pensioner", period),
)
is_household_head_benunit = benunit("benunit_contains_household_head", period)
would_claim = benunit("would_claim_council_tax_reduction", period)
universal_credit = benunit("universal_credit", period)
has_uc_award = universal_credit > 0

capital = household("savings", period)
capital_eligible = capital <= ctr.means_test.capital_limit
weekly_tariff_income = np.ceil(
max_(0, capital - ctr.means_test.tariff_income_threshold)
/ ctr.means_test.tariff_income_step
)

annual_income = benunit("council_tax_reduction_applicable_income", period)
child_benefit = benunit("child_benefit", period)
weekly_income = max_(0, annual_income - child_benefit) / WEEKS_IN_YEAR
weekly_income += where(has_uc_award, 0, weekly_tariff_income)
relevant_income_based_benefit = benunit(
"council_tax_reduction_relevant_income_based_benefit",
period,
)
weekly_income = where(
relevant_income_based_benefit & ~has_uc_award, 0, weekly_income
)

support_rate = ctr.income_band.maximum_support_rate.calc(weekly_income)
liability = household(
"council_tax_reduction_maximum_eligible_liability", period
)
non_dep_deductions = benunit(
"oxford_council_tax_reduction_non_dep_deductions", period
)
award = max_(0, liability * support_rate - non_dep_deductions)
return (
working_age
* is_household_head_benunit
* would_claim
* capital_eligible
* award
)
Loading