diff --git a/.github/workflows/test-suite.yaml b/.github/workflows/test-suite.yaml index 18b02696ec..0ea9cd70c6 100644 --- a/.github/workflows/test-suite.yaml +++ b/.github/workflows/test-suite.yaml @@ -84,9 +84,13 @@ jobs: # (two more were cancelled by newer pushes). In merge-queue run # 40541059060 the cancelled job failed Result once the shards had # finished, which took that pull request out of the queue. 45 minutes - # leaves room for a slow runner and still stops a hung job; Result - # waits about an hour for the shards anyway. - timeout-minutes: 45 + # was then not enough either: on 29 October jobs were cancelled at it + # after every test had passed, with the process still alive 11 and 18 + # minutes after pytest's summary (runs 40895005971 and 40917254004). + # The runner most likely runs short of memory, because every case's + # simulation is kept to the end (#2741). 75 minutes matches the Python + # shards, which Result waits for anyway, until the cases are released. + timeout-minutes: 75 steps: - name: Checkout repo uses: actions/checkout@v6 diff --git a/changelog.d/2749.added.md b/changelog.d/2749.added.md new file mode 100644 index 0000000000..0ef3999318 --- /dev/null +++ b/changelog.d/2749.added.md @@ -0,0 +1 @@ +Added the company car and car fuel benefits in kind from 2020-21 (ITEPA 2003 ss. 120 to 152), with the s. 139 appropriate percentages to 2029-30, person inputs for the company car, and Class 1A NICs on both benefits in `ni_employer` and `total_national_insurance`; the benefits are taxed through `taxable_employment_income` and kept out of Class 1 earnings, means-tested earnings and student loan repayment income, and the `company_car_tax_rise_2030` scenario applies Budget 2026's one-point rise for 2030-31. diff --git a/docs/book/assumptions/employer-ni-incidence.md b/docs/book/assumptions/employer-ni-incidence.md index 78fadb32a6..01187806c3 100644 --- a/docs/book/assumptions/employer-ni-incidence.md +++ b/docs/book/assumptions/employer-ni-incidence.md @@ -62,6 +62,19 @@ The response amounts enter `household_tax`; those same variables are not added t and [capital](https://github.com/PolicyEngine/policyengine-uk/blob/b4dbaf57a4ebb1d1f0ba5f7a384795422828db75/policyengine_uk/variables/contrib/policyengine/employer_ni/employer_ni_response_capital_incidence.py) allocation formulas. +## Secondary Class 1 only + +All three channels cover secondary Class 1 contributions. `ni_employer` also +holds Class 1A contributions on benefits in kind (`ni_class_1a`), but +`employer_cost`, `baseline_employer_cost` and `adjusted_employer_cost` leave +them out, as they leave out the benefits themselves. No household bears +Class 1A or a change in it, whether the change comes from the benefits (as +with a rise in the company car appropriate percentages) or from the employer +rate, which Class 1A follows (SSCBA 1992 s. 10(5)). Such a reform raises +`gov_tax` by its Class 1A change on top of what households pay. Passing +Class 1A through these channels is +[#2752](https://github.com/PolicyEngine/policyengine-uk/issues/2752). + ## Measures and aggregation Report these quantities separately: diff --git a/docs/book/programs/gov/hmrc/company-car-benefit.md b/docs/book/programs/gov/hmrc/company-car-benefit.md new file mode 100644 index 0000000000..cd17d0b8f3 --- /dev/null +++ b/docs/book/programs/gov/hmrc/company-car-benefit.md @@ -0,0 +1,149 @@ +# Company car and car fuel benefits + +A car an employer makes available for an employee's private use is a +benefit in kind: its cash equivalent is taxed as employment income +([ITEPA 2003 s. 120][s120]), and so is fuel provided for its private use +([s. 149][s149]). The employer pays Class 1A National Insurance on both +([SSCBA 1992 s. 10][sscba10]). The model calculates both benefits from +2020-21. + +## Inputs + +Each person can have one company car. The inputs default to no car, so a +simulation that sets none of them is unchanged. + +| Input | Meaning | +| --- | --- | +| `company_car_list_price` | List price of the car and its accessories; zero means no company car | +| `company_car_capital_contributions` | Capital sums the employee has contributed, this year and earlier | +| `company_car_co2_emissions` | CO2 emissions figure in g/km (0 for a car that cannot emit CO2) | +| `company_car_electric_range` | Electric range figure in miles | +| `company_car_fuel_type` | Fuel type (the `CarFuelType` enum also used for vehicle excise duty) | +| `company_car_registered_from_6_april_2020` | First registered on or after 6 April 2020 (matters in 2020-21 and 2021-22 only) | +| `company_car_availability` | Share of the tax year the car is available (default 1) | +| `company_car_private_use_payments` | Payments for private use | +| `company_car_private_fuel_provided` | Fuel provided for private use and not made good in full | + +The `car_*` inputs describe the person's own car for vehicle excise duty +and play no part here. + +Data that fills these inputs needs to know three things: + +- **Set the CO2 figure with the list price.** The model cannot tell a + missing figure from 0 g/km, so a car with a list price and no CO2 figure is + taxed at the zero-emission rate. A car of the `ELECTRIC` fuel type is taken + to emit 0 g/km whatever figure is entered. +- **Keep the benefits out of pay.** `employment_income` must not also hold + them, or they are taxed twice and wrongly bear employee NICs. The SPI's + EPB (expenses payments and benefits in kind) includes them, so a dataset + that adds EPB to pay, as policyengine-uk-data's SPI records do, must take + the car and car fuel benefits out of it. +- **Projected years.** The list price, capital contributions and payments + for private use grow with CPI when a dataset is projected to later years. + CPI stands in for a new-car price index, which the OBR does not forecast. + +## Calculation + +`company_car_appropriate_percentage` applies [s. 139][s139]: a rate for +0 g/km, rates for 1 to 50 g/km by electric range (one rate from 2028-29), +a rate for each band from 51-54 to 70-74 g/km (65-74 g/km from 2028-29), +and from 75 g/km a base rate plus one point for each full 5 g/km, up to the +maximum. A diesel car not meeting the Euro 6d (RDE2) standard adds 4 points, +within the maximum ([s. 141][s141]); a car that cannot emit CO2 takes no +supplement. In 2020-21 and 2021-22 a car first registered on or after +6 April 2020 takes the lower rates of s. 139A (Finance Act 2020 ss. 9 and +10). The appropriate percentage is zero for a person without a company car +(`has_company_car`). + +`company_car_benefit` follows the steps of [s. 121][s121]: the price, less +capital contributions up to £5,000, times the appropriate percentage, +reduced in proportion to the days the car is unavailable, less payments for +private use, and never below zero. `car_fuel_benefit` is the appropriate +percentage of the car fuel benefit charge multiplier ([s. 150][s150]), +reduced in proportion to the days the car is unavailable. It is nil for a +car that cannot emit CO2. `benefits_in_kind` adds the two. + +## Where the benefits go + +- **Income tax.** `taxable_employment_income` adds `benefits_in_kind`, so the + benefits reach income tax, at Scottish rates for a Scottish taxpayer, and + adjusted net income: the personal allowance taper, the High Income Child + Benefit Charge, and the £100,000 limits of Tax-Free Childcare and the + extended childcare entitlement. They count as relevant UK earnings for the + limit on pension tax relief (HMRC PTM044100). +- **Not student loan income.** Student loan repayments and the Plan 2 + interest rate leave the benefits out: Self Assessment excludes Chapter 6 + car benefits ([SI 2009/470 reg. 29(4)(e)][sl29]), and PAYE deducts + repayments from Class 1 earnings (reg. 41). +- **Not earnings for Class 1 or the means tests.** The benefits are not in + `employment_income` or `employment_benefits`, so employee Class 1 NICs and + the earnings of Universal Credit ([UC Regulations 2013 reg. 55(2)(a)][uc55]), + Housing Benefit (HB Regulations 2006 reg. 35(2)(a)) and Council Tax + Reduction leave them out. Those tests still deduct the income tax on them, + which is tax paid in respect of the employment (reg. 55(5)(b)) and which + PAYE collects from pay. Universal Credit takes earnings as the lowest slice + of income, so it deducts all of that tax. Housing Benefit and Council Tax + Reduction deduct earnings' share of the person's tax, and count the + benefits with pay in that share; with other income, part of the tax on the + benefits falls on the other income, as part of the tax on pay does. The + Childcare Offer for Wales's gross income lists its sources one by one, and + benefits in kind are not among them. +- **Employer National Insurance.** `ni_class_1a` is the Class 1A percentage + of `benefits_in_kind`, and `ni_employer` adds it to secondary Class 1, so it + reaches `gov_tax`. The Class 1A percentage is the secondary percentage for + the year, except 14.53% in 2022-23. +- **No household bears Class 1A.** `employer_cost`, and the employer NI + incidence variables that recompute it, cover pay and secondary Class 1 + only. So the fixed-cost pay response and the capital and consumer + channels leave out Class 1A and any change in it: it stays with employers + as revenue. A reform that changes Class 1A, such as the 2030-31 rise below + or a rise in the employer rate, raises `gov_tax` by more than it lowers + household incomes. Passing Class 1A through like secondary Class 1 is + [#2752](https://github.com/PolicyEngine/policyengine-uk/issues/2752). + +## 2030-31 + +Finance Act 2025 s. 6 sets the rates for 2029-30 and subsequent tax years, +so the baseline keeps them for 2030-31: 9% for 0 g/km, 19% for 1 to 50 g/km +and a 39% maximum. Budget 2026 raises every rate for 2030-31 by one point, to +a maximum of 40%, to be legislated in Finance Bill 2026-27. The +`company_car_tax_rise_2030` scenario applies that rise: + +```python +from policyengine_uk import Simulation +from policyengine_uk.scenarios import company_car_tax_rise_2030 + +reformed = Simulation(situation=situation, scenario=company_car_tax_rise_2030) +``` + +`policyengine_uk.scenarios.company_car_tax_rise_2030.COMPANY_CAR_TAX_RISE_2030` +holds the same changes as a parameter-changes dictionary. + +The car fuel benefit charge multiplier is in the baseline for 2027-28 at the +£30,200 Budget 2026 announced, before the Treasury order is made. That is the +annual CPI uprating, which the Budget does not score, so a pre-Budget +baseline has it too; the 2030-31 rise is a policy decision Budget 2026 scores +(Table 6.1, row 86). The fuel part of the rise depends on the multiplier. + +## Not modelled + +- Vans and van fuel (ITEPA 2003 s. 154 onwards). +- Optional remuneration arrangements (s. 120A), shared cars (s. 148) and + pool cars (s. 167). +- Classic cars (s. 147), cars without a CO2 emissions figure (s. 140) and + cars first registered before 1 January 1998 (s. 142). +- Fuel provided for only part of the year (s. 152(2)). +- Other benefits in kind. + +The survey data does not fill these inputs yet, so a population run scores +the company car benefits at zero until a dataset does. + +[s120]: https://www.legislation.gov.uk/ukpga/2003/1/section/120 +[s121]: https://www.legislation.gov.uk/ukpga/2003/1/section/121 +[s139]: https://www.legislation.gov.uk/ukpga/2003/1/section/139 +[s141]: https://www.legislation.gov.uk/ukpga/2003/1/section/141 +[s149]: https://www.legislation.gov.uk/ukpga/2003/1/section/149 +[s150]: https://www.legislation.gov.uk/ukpga/2003/1/section/150 +[sscba10]: https://www.legislation.gov.uk/ukpga/1992/4/section/10 +[sl29]: https://www.legislation.gov.uk/uksi/2009/470/regulation/29 +[uc55]: https://www.legislation.gov.uk/uksi/2013/376/regulation/55 diff --git a/policyengine_uk/data/fiscal_partition.yaml b/policyengine_uk/data/fiscal_partition.yaml index f242470b4a..1a9744700e 100644 --- a/policyengine_uk/data/fiscal_partition.yaml +++ b/policyengine_uk/data/fiscal_partition.yaml @@ -743,6 +743,7 @@ exclusions: - {variable: employer_ni_fixed_employer_cost_change, kind: change_measure, head: nics_employer, note: "The wage change from an employer NI reform; employment_income already adds it."} - {variable: salary_sacrifice_broad_base_haircut, kind: change_measure, head: nics_employer, note: "A wage change employment_income already adds."} - {variable: ni_class_1_employer, kind: component, head: nics_employer} + - {variable: ni_class_1a, kind: component, head: nics_employer} - {variable: salary_sacrifice_pension_ni_employee, kind: measure_within, head: nics_individual, note: "The excess sacrifice is added back to ni_class_1_income, so Class 1 already charges it."} - {variable: salary_sacrifice_pension_ni_employer, kind: measure_within, head: nics_employer, note: "As above, for employer Class 1."} - {variable: tax, kind: composite, spans: [income_tax, nics_individual]} diff --git a/policyengine_uk/data/uprating_indices.yaml b/policyengine_uk/data/uprating_indices.yaml index ee591c95de..5e28db57dd 100644 --- a/policyengine_uk/data/uprating_indices.yaml +++ b/policyengine_uk/data/uprating_indices.yaml @@ -46,6 +46,11 @@ gov.economic_assumptions.yoy_growth.obr.consumer_price_index: - childcare_expenses - clothing_and_footwear_consumption - communication_consumption +# Company car prices and the payments that go with them. CPI stands in for +# a new-car price index, which the OBR does not forecast. +- company_car_capital_contributions +- company_car_list_price +- company_car_private_use_payments - education_consumption - esa_contrib_reported - esa_income_reported diff --git a/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/README.md b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/README.md new file mode 100644 index 0000000000..b8ccc9c907 --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/README.md @@ -0,0 +1 @@ +# Benefits in kind diff --git a/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/car_fuel/README.md b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/car_fuel/README.md new file mode 100644 index 0000000000..624e1ad42a --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/car_fuel/README.md @@ -0,0 +1 @@ +# Car fuel diff --git a/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/car_fuel/multiplier.yaml b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/car_fuel/multiplier.yaml new file mode 100644 index 0000000000..97e9c97cfa --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/car_fuel/multiplier.yaml @@ -0,0 +1,64 @@ +description: Amount to which the company car's appropriate percentage is applied to give the cash equivalent of fuel provided for its private use (the car fuel benefit charge multiplier). +# The Treasury sets this by order under ITEPA 2003 s. 170(5); no statute +# indexes it. The 2027-28 figure is announced: Budget 2026 OOTLAR paragraph +# 2.6 gives £30,200 (September CPI uprating), and the Treasury order is not +# yet made. It is in the baseline although the Budget 2026 rise in the +# appropriate percentages for 2030-31 is not: that rise is a policy decision +# Budget 2026 scores (Table 6.1, row 86), while this is the annual CPI +# uprating, which the Budget lists among its other announcements and does +# not score, so a pre-Budget baseline has it too. From 2028-29 the values +# are a CPI projection, as the government has uprated the figure by +# September CPI each year; none is announced. +values: + 2020-04-06: + value: 24_500 + metadata: + reference: + - title: The Van Benefit and Car and Van Fuel Benefit Order 2020 (SI 2020/199) art. 2 + href: https://www.legislation.gov.uk/uksi/2020/199/article/2/made + 2021-04-06: + value: 24_600 + metadata: + reference: + - title: The Van Benefit and Car and Van Fuel Benefit Order 2021 (SI 2021/248) art. 2 + href: https://www.legislation.gov.uk/uksi/2021/248/article/2/made + 2022-04-06: + value: 25_300 + metadata: + reference: + - title: The Van Benefit and Car and Van Fuel Benefit (No. 2) Order 2021 (SI 2021/1422) art. 2 + href: https://www.legislation.gov.uk/uksi/2021/1422/article/2/made + 2023-04-06: + value: 27_800 + metadata: + reference: + - title: The Van Benefit and Car and Fuel Benefit Order 2022 (SI 2022/1288) art. 2 (tax year 2023-24 and subsequent tax years) + href: https://www.legislation.gov.uk/uksi/2022/1288/article/2/made + 2025-04-06: + value: 28_200 + metadata: + reference: + - title: The Van Benefit and Car and Van Fuel Benefit Order 2024 (SI 2024/1349) art. 2(2) + href: https://www.legislation.gov.uk/uksi/2024/1349/article/2/made + 2026-04-06: + value: 29_200 + metadata: + reference: + - title: The Van Benefit and Car and Van Fuel Benefit Order 2025 (SI 2025/1254) art. 2(2) + href: https://www.legislation.gov.uk/uksi/2025/1254/article/2/made + 2027-04-06: + value: 30_200 + metadata: + reference: + - title: Budget 2026, overview of tax legislation and rates, paragraph 2.6 + href: https://www.gov.uk/government/publications/budget-2026-overview-of-tax-legislation-and-rates-ootlar/budget-2026-overview-of-tax-legislation-and-rates-ootlar +metadata: + unit: currency-GBP + period: year + label: Car fuel benefit charge multiplier + uprating: gov.economic_assumptions.indices.obr.consumer_price_index + reference: + - title: Income Tax (Earnings and Pensions) Act 2003 s. 150(1) + href: https://www.legislation.gov.uk/ukpga/2003/1/section/150 + - title: Income Tax (Earnings and Pensions) Act 2003 s. 170(5) + href: https://www.legislation.gov.uk/ukpga/2003/1/section/170 diff --git a/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/README.md b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/README.md new file mode 100644 index 0000000000..b335b878d6 --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/README.md @@ -0,0 +1 @@ +# Company car diff --git a/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/README.md b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/README.md new file mode 100644 index 0000000000..36786a1ddb --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/README.md @@ -0,0 +1 @@ +# Appropriate percentage diff --git a/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/co2_band.yaml b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/co2_band.yaml new file mode 100644 index 0000000000..88c601b42b --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/co2_band.yaml @@ -0,0 +1,78 @@ +description: Appropriate percentage for a company car with a CO2 emissions figure of 51 to 74 g/km, by that figure rounded down to a whole number. +# Finance Act 2025 s. 5 merges the 65-69 and 70-74 bands into one 65-74 band +# from 2028-29, so the last two brackets have the same amount from then. +# For 2020-21 and 2021-22 these are the rates for cars first registered +# before 6 April 2020; registered_from_6_april_2020 holds the s. 139A rates. +# The tax year 2030-31 keeps 2029-30's rates. Budget 2026 announced one +# point more in every band; the company_car_tax_rise_2030 scenario applies it. +metadata: + type: single_amount + threshold_unit: g/km + amount_unit: /1 + period: year + label: Company car appropriate percentage by CO2 emissions, 51 to 74 g/km + reference: + - title: Income Tax (Earnings and Pensions) Act 2003 s. 139(1) and (2)(a) + href: https://www.legislation.gov.uk/ukpga/2003/1/section/139 + - title: Finance (No. 2) Act 2017 s. 2(2) (tax years 2020-21 to 2024-25) + href: https://www.legislation.gov.uk/ukpga/2017/32/section/2/enacted + - title: Finance Act 2023 s. 11 (tax years 2025-26, 2026-27 and 2027-28) + href: https://www.legislation.gov.uk/ukpga/2023/1/section/11/enacted + - title: Finance Act 2025 s. 5(2) (tax year 2028-29) + href: https://www.legislation.gov.uk/ukpga/2025/8/section/5/enacted + - title: Finance Act 2025 s. 6(2) (tax year 2029-30 and subsequent tax years) + href: https://www.legislation.gov.uk/ukpga/2025/8/section/6/enacted + - title: "HMRC 480 Appendix 2: appropriate percentages for 2020-21 to 2026-27" + href: https://www.gov.uk/guidance/company-car-benefit-the-appropriate-percentage-480-appendix-2 +brackets: + # 51 to 54 g/km. + - threshold: + 2020-04-06: 51 + amount: + 2020-04-06: 0.15 + 2025-04-06: 0.16 + 2026-04-06: 0.17 + 2027-04-06: 0.18 + 2028-04-06: 0.19 + 2029-04-06: 0.20 + # 55 to 59 g/km. + - threshold: + 2020-04-06: 55 + amount: + 2020-04-06: 0.16 + 2025-04-06: 0.17 + 2026-04-06: 0.18 + 2027-04-06: 0.19 + 2028-04-06: 0.20 + 2029-04-06: 0.21 + # 60 to 64 g/km. + - threshold: + 2020-04-06: 60 + amount: + 2020-04-06: 0.17 + 2025-04-06: 0.18 + 2026-04-06: 0.19 + 2027-04-06: 0.20 + 2028-04-06: 0.21 + 2029-04-06: 0.22 + # 65 to 69 g/km. + - threshold: + 2020-04-06: 65 + amount: + 2020-04-06: 0.18 + 2025-04-06: 0.19 + 2026-04-06: 0.20 + 2027-04-06: 0.21 + 2028-04-06: 0.22 + 2029-04-06: 0.23 + # 70 to 74 g/km. In 2027-28 Finance Act 2023 s. 11(7) keeps it at 21%, + # level with 65-69 g/km and with the 75 g/km rate. + - threshold: + 2020-04-06: 70 + amount: + 2020-04-06: 0.19 + 2025-04-06: 0.20 + 2026-04-06: 0.21 + 2027-04-06: 0.21 + 2028-04-06: 0.22 + 2029-04-06: 0.23 diff --git a/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/diesel_supplement.yaml b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/diesel_supplement.yaml new file mode 100644 index 0000000000..04bf928a30 --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/diesel_supplement.yaml @@ -0,0 +1,12 @@ +description: Percentage points added to the appropriate percentage of a company car propelled solely by diesel that does not meet the Euro 6d (RDE2) emissions standard, up to the maximum appropriate percentage. +values: + 2020-04-06: 0.04 +metadata: + unit: /1 + period: year + label: Company car diesel supplement + reference: + - title: Income Tax (Earnings and Pensions) Act 2003 s. 141 + href: https://www.legislation.gov.uk/ukpga/2003/1/section/141 + - title: Finance Act 2018 s. 9(3)(b) (4 percentage points from 2018-19) + href: https://www.legislation.gov.uk/ukpga/2018/3/section/9/enacted diff --git a/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/electric_range.yaml b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/electric_range.yaml new file mode 100644 index 0000000000..8958993a9b --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/electric_range.yaml @@ -0,0 +1,81 @@ +description: Appropriate percentage for a company car with a CO2 emissions figure of 1 to 50 g/km, by its electric range figure in miles (the distance it can be driven in electric mode without recharging), rounded up to a whole number. +# Finance Act 2025 s. 5 replaces the electric range bands with one rate for +# 1 to 50 g/km from 2028-29 (18%, then 19% from 2029-30 under s. 6), so +# every bracket has the same amount from then. s. 5(10) and (11) omit the +# electric range figure from s. 139 from 2028-29. +# For 2020-21 and 2021-22 these are the rates for cars first registered +# before 6 April 2020; registered_from_6_april_2020 holds the s. 139A rates. +# The tax year 2030-31 keeps 2029-30's 19%. Budget 2026 announced 20%; the +# company_car_tax_rise_2030 scenario applies it. +metadata: + type: single_amount + threshold_unit: mile + amount_unit: /1 + period: year + label: Company car appropriate percentage by electric range + reference: + - title: Income Tax (Earnings and Pensions) Act 2003 s. 139(1) and (2)(b) + href: https://www.legislation.gov.uk/ukpga/2003/1/section/139 + - title: Finance (No. 2) Act 2017 s. 2(2) (tax years 2020-21 to 2024-25) + href: https://www.legislation.gov.uk/ukpga/2017/32/section/2/enacted + - title: Finance Act 2020 s. 8(4)(a) (electric range figure rounded up, from 2020-21) + href: https://www.legislation.gov.uk/ukpga/2020/14/section/8/enacted + - title: Finance Act 2023 s. 11 (tax years 2025-26, 2026-27 and 2027-28) + href: https://www.legislation.gov.uk/ukpga/2023/1/section/11/enacted + - title: Finance Act 2025 s. 5(2) (tax year 2028-29) + href: https://www.legislation.gov.uk/ukpga/2025/8/section/5/enacted + - title: Finance Act 2025 s. 6(2) (tax year 2029-30 and subsequent tax years) + href: https://www.legislation.gov.uk/ukpga/2025/8/section/6/enacted + - title: "HMRC 480 Appendix 2: appropriate percentages for 2020-21 to 2026-27" + href: https://www.gov.uk/guidance/company-car-benefit-the-appropriate-percentage-480-appendix-2 +brackets: + # Electric range figure of less than 30 miles. + - threshold: + 2020-04-06: 0 + amount: + 2020-04-06: 0.14 + 2025-04-06: 0.15 + 2026-04-06: 0.16 + 2027-04-06: 0.17 + 2028-04-06: 0.18 + 2029-04-06: 0.19 + # 30 to 39 miles. + - threshold: + 2020-04-06: 30 + amount: + 2020-04-06: 0.12 + 2025-04-06: 0.13 + 2026-04-06: 0.14 + 2027-04-06: 0.15 + 2028-04-06: 0.18 + 2029-04-06: 0.19 + # 40 to 69 miles. + - threshold: + 2020-04-06: 40 + amount: + 2020-04-06: 0.08 + 2025-04-06: 0.09 + 2026-04-06: 0.10 + 2027-04-06: 0.11 + 2028-04-06: 0.18 + 2029-04-06: 0.19 + # 70 to 129 miles. + - threshold: + 2020-04-06: 70 + amount: + 2020-04-06: 0.05 + 2025-04-06: 0.06 + 2026-04-06: 0.07 + 2027-04-06: 0.08 + 2028-04-06: 0.18 + 2029-04-06: 0.19 + # 130 miles or more. + - threshold: + 2020-04-06: 130 + amount: + 2020-04-06: 0.02 + 2025-04-06: 0.03 + 2026-04-06: 0.04 + 2027-04-06: 0.05 + 2028-04-06: 0.18 + 2029-04-06: 0.19 diff --git a/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/electric_range_co2_limit.yaml b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/electric_range_co2_limit.yaml new file mode 100644 index 0000000000..88ed3e0c70 --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/electric_range_co2_limit.yaml @@ -0,0 +1,12 @@ +description: Highest CO2 emissions figure, rounded down to a whole number, at which a company car's appropriate percentage is the rate for 1 to 50 g/km, set by its electric range to 2027-28 and a single rate from 2028-29. +values: + 2020-04-06: 50 +metadata: + unit: g/km + period: year + label: Company car CO2 limit for the 1 to 50 g/km band + reference: + - title: Income Tax (Earnings and Pensions) Act 2003 s. 139(1) + href: https://www.legislation.gov.uk/ukpga/2003/1/section/139 + - title: Finance (No. 2) Act 2017 s. 2(2) + href: https://www.legislation.gov.uk/ukpga/2017/32/section/2/enacted diff --git a/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/graduated/README.md b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/graduated/README.md new file mode 100644 index 0000000000..e8e7b6d294 --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/graduated/README.md @@ -0,0 +1 @@ +# Cars emitting 75 g/km or more diff --git a/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/graduated/base_rate.yaml b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/graduated/base_rate.yaml new file mode 100644 index 0000000000..aee4bc3084 --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/graduated/base_rate.yaml @@ -0,0 +1,37 @@ +description: Appropriate percentage for a company car with a CO2 emissions figure at the graduated threshold of 75 g/km, before the rise for each step of emissions above it. +# For 2020-21 and 2021-22 this is the rate for cars first registered before +# 6 April 2020; registered_from_6_april_2020 holds the s. 139A rate. +# The tax year 2030-31 keeps 2029-30's 23%. Budget 2026 announced 24%; the +# company_car_tax_rise_2030 scenario applies it. +values: + 2020-04-06: + value: 0.2 + metadata: + reference: + - title: Finance (No. 2) Act 2017 s. 2(2), substituting ITEPA 2003 s. 139(3)(a) + href: https://www.legislation.gov.uk/ukpga/2017/32/section/2/enacted + 2025-04-06: + value: 0.21 + metadata: + reference: + - title: Finance Act 2023 s. 11(3) and (4) (tax year 2025-26 and subsequent tax years) + href: https://www.legislation.gov.uk/ukpga/2023/1/section/11/enacted + 2028-04-06: + value: 0.22 + metadata: + reference: + - title: Finance Act 2025 s. 5(3)(a) and (9) (tax year 2028-29) + href: https://www.legislation.gov.uk/ukpga/2025/8/section/5/enacted + 2029-04-06: + value: 0.23 + metadata: + reference: + - title: Finance Act 2025 s. 6(3)(a) and (9) (tax year 2029-30 and subsequent tax years) + href: https://www.legislation.gov.uk/ukpga/2025/8/section/6/enacted +metadata: + unit: /1 + period: year + label: Company car graduated appropriate percentage base rate + reference: + - title: Income Tax (Earnings and Pensions) Act 2003 s. 139(3)(a) + href: https://www.legislation.gov.uk/ukpga/2003/1/section/139 diff --git a/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/graduated/increment.yaml b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/graduated/increment.yaml new file mode 100644 index 0000000000..b998a32305 --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/graduated/increment.yaml @@ -0,0 +1,10 @@ +description: Rise in a company car's appropriate percentage for each full step of CO2 emissions above the graduated threshold. +values: + 2020-04-06: 0.01 +metadata: + unit: /1 + period: year + label: Company car graduated appropriate percentage increment + reference: + - title: Income Tax (Earnings and Pensions) Act 2003 s. 139(3)(a) + href: https://www.legislation.gov.uk/ukpga/2003/1/section/139 diff --git a/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/graduated/step.yaml b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/graduated/step.yaml new file mode 100644 index 0000000000..be1c636caa --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/graduated/step.yaml @@ -0,0 +1,10 @@ +description: Width of each step of CO2 emissions above the graduated threshold that raises a company car's appropriate percentage; the emissions figure is rounded down to a multiple of it. +values: + 2020-04-06: 5 +metadata: + unit: g/km + period: year + label: Company car graduated appropriate percentage step + reference: + - title: Income Tax (Earnings and Pensions) Act 2003 s. 139(3)(a) and (4) + href: https://www.legislation.gov.uk/ukpga/2003/1/section/139 diff --git a/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/graduated/threshold.yaml b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/graduated/threshold.yaml new file mode 100644 index 0000000000..c81d52b811 --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/graduated/threshold.yaml @@ -0,0 +1,12 @@ +description: CO2 emissions figure from which a company car's appropriate percentage is the base rate plus a rise for each step of emissions above it, rather than a rate from the table for lower emissions. +values: + 2020-04-06: 75 +metadata: + unit: g/km + period: year + label: Company car graduated appropriate percentage threshold + reference: + - title: Income Tax (Earnings and Pensions) Act 2003 s. 139(1) and (3) + href: https://www.legislation.gov.uk/ukpga/2003/1/section/139 + - title: Finance (No. 2) Act 2017 s. 2(2) + href: https://www.legislation.gov.uk/ukpga/2017/32/section/2/enacted diff --git a/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/maximum.yaml b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/maximum.yaml new file mode 100644 index 0000000000..506217b3c5 --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/maximum.yaml @@ -0,0 +1,45 @@ +description: Maximum appropriate percentage for a company car, which caps both the graduated rate and a diesel car's rate after its supplement. +# Two provisions set this figure: s. 139(3)(b) for the graduated rate and +# s. 141(2) step 3(b) for a diesel car. They have moved together, so the +# model holds one figure. For s. 141, legislation.gov.uk prints 35%: Finance +# Act 2015 s. 9 substituted 37% for the tax year 2015-16 only, when Finance +# Act 2014 s. 24(11) was to omit s. 141 from 2016-17, and Finance Act 2016 +# s. 10 then kept s. 141 without restating the cap. Finance Act 2025 s. 5(6) +# substitutes 38% "for '37%'" in step 3, and HMRC 480 (paragraph 12.29, note +# 2) applies the 37% maximum to diesel cars from 2015-16, so the model uses +# 37% for both to 2027-28. +# The tax year 2030-31 keeps 2029-30's 39%. Budget 2026 announced 40%, for +# s. 139(3)(b) and s. 141 alike; the company_car_tax_rise_2030 scenario +# applies it. +values: + 2020-04-06: + value: 0.37 + metadata: + reference: + - title: Finance (No. 2) Act 2017 s. 2(2), substituting ITEPA 2003 s. 139(3)(b) + href: https://www.legislation.gov.uk/ukpga/2017/32/section/2/enacted + - title: Finance Act 2015 s. 9 (ITEPA 2003 s. 141(2) step 3, 37% for 2015-16) + href: https://www.legislation.gov.uk/ukpga/2015/11/section/9/enacted + - title: "HMRC 480 Chapter 12, paragraph 12.29, note 2: overall maximum of 37% from 2015-16" + href: https://www.gov.uk/guidance/how-to-work-out-the-benefit-of-a-company-car-480-chapter-12 + 2028-04-06: + value: 0.38 + metadata: + reference: + - title: Finance Act 2025 s. 5(3)(b), (6) and (9) (tax year 2028-29) + href: https://www.legislation.gov.uk/ukpga/2025/8/section/5/enacted + 2029-04-06: + value: 0.39 + metadata: + reference: + - title: Finance Act 2025 s. 6(3)(b), (6) and (9) (tax year 2029-30 and subsequent tax years) + href: https://www.legislation.gov.uk/ukpga/2025/8/section/6/enacted +metadata: + unit: /1 + period: year + label: Company car maximum appropriate percentage + reference: + - title: Income Tax (Earnings and Pensions) Act 2003 s. 139(3)(b) + href: https://www.legislation.gov.uk/ukpga/2003/1/section/139 + - title: Income Tax (Earnings and Pensions) Act 2003 s. 141(2), step 3(b) + href: https://www.legislation.gov.uk/ukpga/2003/1/section/141 diff --git a/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/registered_from_6_april_2020/README.md b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/registered_from_6_april_2020/README.md new file mode 100644 index 0000000000..ac269a7dc9 --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/registered_from_6_april_2020/README.md @@ -0,0 +1 @@ +# Cars first registered on or after 6 April 2020 diff --git a/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/registered_from_6_april_2020/co2_band.yaml b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/registered_from_6_april_2020/co2_band.yaml new file mode 100644 index 0000000000..262c37cd43 --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/registered_from_6_april_2020/co2_band.yaml @@ -0,0 +1,43 @@ +description: Appropriate percentage under ITEPA 2003 s. 139A for a company car first registered on or after 6 April 2020 with a CO2 emissions figure of 51 to 74 g/km, while s. 139A is in effect. +metadata: + type: single_amount + threshold_unit: g/km + amount_unit: /1 + period: year + label: Appropriate percentage by CO2 emissions, cars first registered from 6 April 2020 + reference: + - title: Finance Act 2020 s. 9(3) (tax year 2020-21) + href: https://www.legislation.gov.uk/ukpga/2020/14/section/9/enacted + - title: Finance Act 2020 s. 10(3) (tax year 2021-22) + href: https://www.legislation.gov.uk/ukpga/2020/14/section/10/enacted +brackets: + # 51 to 54 g/km. + - threshold: + 2020-04-06: 51 + amount: + 2020-04-06: 0.13 + 2021-04-06: 0.14 + # 55 to 59 g/km. + - threshold: + 2020-04-06: 55 + amount: + 2020-04-06: 0.14 + 2021-04-06: 0.15 + # 60 to 64 g/km. + - threshold: + 2020-04-06: 60 + amount: + 2020-04-06: 0.15 + 2021-04-06: 0.16 + # 65 to 69 g/km. + - threshold: + 2020-04-06: 65 + amount: + 2020-04-06: 0.16 + 2021-04-06: 0.17 + # 70 to 74 g/km. + - threshold: + 2020-04-06: 70 + amount: + 2020-04-06: 0.17 + 2021-04-06: 0.18 diff --git a/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/registered_from_6_april_2020/electric_range.yaml b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/registered_from_6_april_2020/electric_range.yaml new file mode 100644 index 0000000000..77b922480f --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/registered_from_6_april_2020/electric_range.yaml @@ -0,0 +1,43 @@ +description: Appropriate percentage under ITEPA 2003 s. 139A for a company car first registered on or after 6 April 2020 with a CO2 emissions figure of 1 to 50 g/km, by its electric range figure in miles, while s. 139A is in effect. +metadata: + type: single_amount + threshold_unit: mile + amount_unit: /1 + period: year + label: Appropriate percentage by electric range, cars first registered from 6 April 2020 + reference: + - title: Finance Act 2020 s. 9(3) (tax year 2020-21) + href: https://www.legislation.gov.uk/ukpga/2020/14/section/9/enacted + - title: Finance Act 2020 s. 10(3) (tax year 2021-22) + href: https://www.legislation.gov.uk/ukpga/2020/14/section/10/enacted +brackets: + # Electric range figure of less than 30 miles. + - threshold: + 2020-04-06: 0 + amount: + 2020-04-06: 0.12 + 2021-04-06: 0.13 + # 30 to 39 miles. + - threshold: + 2020-04-06: 30 + amount: + 2020-04-06: 0.1 + 2021-04-06: 0.11 + # 40 to 69 miles. + - threshold: + 2020-04-06: 40 + amount: + 2020-04-06: 0.06 + 2021-04-06: 0.07 + # 70 to 129 miles. + - threshold: + 2020-04-06: 70 + amount: + 2020-04-06: 0.03 + 2021-04-06: 0.04 + # 130 miles or more. + - threshold: + 2020-04-06: 130 + amount: + 2020-04-06: 0 + 2021-04-06: 0.01 diff --git a/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/registered_from_6_april_2020/graduated_base_rate.yaml b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/registered_from_6_april_2020/graduated_base_rate.yaml new file mode 100644 index 0000000000..3b3caacd81 --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/registered_from_6_april_2020/graduated_base_rate.yaml @@ -0,0 +1,23 @@ +description: Appropriate percentage under ITEPA 2003 s. 139A for a company car first registered on or after 6 April 2020 with a CO2 emissions figure of 75 g/km, before the rise for each step of emissions above it, while s. 139A is in effect. The maximum appropriate percentage is unchanged. +values: + 2020-04-06: + value: 0.18 + metadata: + reference: + - title: Finance Act 2020 s. 9(3) (tax year 2020-21) + href: https://www.legislation.gov.uk/ukpga/2020/14/section/9/enacted + 2021-04-06: + value: 0.19 + metadata: + reference: + - title: Finance Act 2020 s. 10(3) (tax year 2021-22) + href: https://www.legislation.gov.uk/ukpga/2020/14/section/10/enacted +metadata: + unit: /1 + period: year + label: Graduated appropriate percentage base rate, cars first registered from 6 April 2020 + reference: + - title: Income Tax (Earnings and Pensions) Act 2003 s. 139A(b), inserted for 2020-21 by Finance Act 2020 s. 9(3) + href: https://www.legislation.gov.uk/ukpga/2020/14/section/9/enacted + - title: Income Tax (Earnings and Pensions) Act 2003 s. 139A(b), inserted for 2021-22 by Finance Act 2020 s. 10(3) + href: https://www.legislation.gov.uk/ukpga/2020/14/section/10/enacted diff --git a/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/registered_from_6_april_2020/in_effect.yaml b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/registered_from_6_april_2020/in_effect.yaml new file mode 100644 index 0000000000..c9df564da0 --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/registered_from_6_april_2020/in_effect.yaml @@ -0,0 +1,16 @@ +description: Whether ITEPA 2003 s. 139A gives a company car first registered on or after 6 April 2020 its own, lower appropriate percentages. Finance Act 2020 inserted s. 139A for 2020-21 (s. 9(3)) and again for 2021-22 (s. 10(3)); from 2022-23 every car takes the s. 139 rates. +values: + 0000-01-01: false + 2020-04-06: true + 2022-04-06: false +metadata: + unit: bool + period: year + label: Separate appropriate percentages for cars first registered from 6 April 2020 + reference: + - title: Finance Act 2020 s. 9(3) (tax year 2020-21) + href: https://www.legislation.gov.uk/ukpga/2020/14/section/9/enacted + - title: Finance Act 2020 s. 10(3) (tax year 2021-22) + href: https://www.legislation.gov.uk/ukpga/2020/14/section/10/enacted + - title: "HMRC 480 Appendix 2: NEDC and WLTP columns for 2020-21 and 2021-22" + href: https://www.gov.uk/guidance/company-car-benefit-the-appropriate-percentage-480-appendix-2 diff --git a/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/zero_emission.yaml b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/zero_emission.yaml new file mode 100644 index 0000000000..b63c4517ce --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/appropriate_percentage/zero_emission.yaml @@ -0,0 +1,62 @@ +description: Appropriate percentage for a company car with a CO2 emissions figure of 0, the share of the car's price taxed each year as its benefit. +# The tax year 2030-31 keeps 2029-30's 9%. Budget 2026 announced 10% for +# 2030-31, to be legislated in Finance Bill 2026-27; the +# company_car_tax_rise_2030 scenario applies it. +values: + 2020-04-06: + value: 0 + metadata: + reference: + - title: Finance Act 2020 s. 9(2)(a) (tax year 2020-21) + href: https://www.legislation.gov.uk/ukpga/2020/14/section/9/enacted + 2021-04-06: + value: 0.01 + metadata: + reference: + - title: Finance Act 2020 s. 10(2)(a) (tax year 2021-22) + href: https://www.legislation.gov.uk/ukpga/2020/14/section/10/enacted + 2022-04-06: + value: 0.02 + metadata: + reference: + - title: Finance (No. 2) Act 2017 s. 2(2), substituting ITEPA 2003 s. 139(1) + href: https://www.legislation.gov.uk/ukpga/2017/32/section/2/enacted + 2025-04-06: + value: 0.03 + metadata: + reference: + - title: Finance Act 2023 s. 11(1) and (2) (tax year 2025-26) + href: https://www.legislation.gov.uk/ukpga/2023/1/section/11/enacted + 2026-04-06: + value: 0.04 + metadata: + reference: + - title: Finance Act 2023 s. 11(5) and (6) (tax year 2026-27) + href: https://www.legislation.gov.uk/ukpga/2023/1/section/11/enacted + 2027-04-06: + value: 0.05 + metadata: + reference: + - title: Finance Act 2023 s. 11(7) and (8) (tax year 2027-28) + href: https://www.legislation.gov.uk/ukpga/2023/1/section/11/enacted + 2028-04-06: + value: 0.07 + metadata: + reference: + - title: Finance Act 2025 s. 5(2) and (9) (tax year 2028-29) + href: https://www.legislation.gov.uk/ukpga/2025/8/section/5/enacted + 2029-04-06: + value: 0.09 + metadata: + reference: + - title: Finance Act 2025 s. 6(2) and (9) (tax year 2029-30 and subsequent tax years) + href: https://www.legislation.gov.uk/ukpga/2025/8/section/6/enacted +metadata: + unit: /1 + period: year + label: Zero-emission company car appropriate percentage + reference: + - title: Income Tax (Earnings and Pensions) Act 2003 s. 139(1) + href: https://www.legislation.gov.uk/ukpga/2003/1/section/139 + - title: "HMRC 480 Appendix 2: appropriate percentages for 2020-21 to 2026-27" + href: https://www.gov.uk/guidance/company-car-benefit-the-appropriate-percentage-480-appendix-2 diff --git a/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/capital_contribution_cap.yaml b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/capital_contribution_cap.yaml new file mode 100644 index 0000000000..5f531821a8 --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/income_tax/benefits_in_kind/company_car/capital_contribution_cap.yaml @@ -0,0 +1,10 @@ +description: Maximum deduction from a company car's price for capital sums the employee has contributed, in the year and earlier years, to the car and its accessories. +values: + 2003-04-06: 5_000 +metadata: + unit: currency-GBP + period: year + label: Company car capital contribution cap + reference: + - title: Income Tax (Earnings and Pensions) Act 2003 s. 132(3)(b) + href: https://www.legislation.gov.uk/ukpga/2003/1/section/132 diff --git a/policyengine_uk/parameters/gov/hmrc/national_insurance/class_1a/README.md b/policyengine_uk/parameters/gov/hmrc/national_insurance/class_1a/README.md new file mode 100644 index 0000000000..30f1be9de4 --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/national_insurance/class_1a/README.md @@ -0,0 +1 @@ +# Class 1A diff --git a/policyengine_uk/parameters/gov/hmrc/national_insurance/class_1a/percentage_2022_23/README.md b/policyengine_uk/parameters/gov/hmrc/national_insurance/class_1a/percentage_2022_23/README.md new file mode 100644 index 0000000000..bc41cad93b --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/national_insurance/class_1a/percentage_2022_23/README.md @@ -0,0 +1 @@ +# Class 1A percentage for 2022-23 diff --git a/policyengine_uk/parameters/gov/hmrc/national_insurance/class_1a/percentage_2022_23/in_effect.yaml b/policyengine_uk/parameters/gov/hmrc/national_insurance/class_1a/percentage_2022_23/in_effect.yaml new file mode 100644 index 0000000000..c2f3aa3403 --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/national_insurance/class_1a/percentage_2022_23/in_effect.yaml @@ -0,0 +1,12 @@ +description: Whether the Class 1A percentage is the fixed rate the Health and Social Care Levy (Repeal) Act 2022 sets for 2022-23, rather than the secondary Class 1 percentage it equals in other tax years. +values: + 0000-01-01: false + 2022-04-06: true + 2023-04-06: false +metadata: + unit: bool + period: year + label: Fixed Class 1A percentage for 2022-23 + reference: + - title: Health and Social Care Levy (Repeal) Act 2022 Schedule paragraph 1 + href: https://www.legislation.gov.uk/ukpga/2022/43/schedule/paragraph/1/enacted diff --git a/policyengine_uk/parameters/gov/hmrc/national_insurance/class_1a/percentage_2022_23/rate.yaml b/policyengine_uk/parameters/gov/hmrc/national_insurance/class_1a/percentage_2022_23/rate.yaml new file mode 100644 index 0000000000..113eb1cda8 --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/national_insurance/class_1a/percentage_2022_23/rate.yaml @@ -0,0 +1,10 @@ +description: Class 1A percentage for 2022-23, which applies to the whole year's benefits in kind although the secondary Class 1 percentage fell from 15.05% to 13.8% on 6 November 2022. +values: + 2022-04-06: 0.1453 +metadata: + unit: /1 + period: year + label: Class 1A percentage for 2022-23 + reference: + - title: Health and Social Care Levy (Repeal) Act 2022 Schedule paragraph 1(2) + href: https://www.legislation.gov.uk/ukpga/2022/43/schedule/paragraph/1/enacted diff --git a/policyengine_uk/programs.yaml b/policyengine_uk/programs.yaml index 734a227b56..ed22040b61 100644 --- a/policyengine_uk/programs.yaml +++ b/policyengine_uk/programs.yaml @@ -50,7 +50,7 @@ programs: variable: income_tax parameter_prefix: gov.hmrc.income_tax verified_start_year: 2019 - notes: Includes Scottish rates via devolved tax bands, the high income child benefit charge and, from 2025-26, the winter fuel payment charge + notes: Includes Scottish rates via devolved tax bands, the high income child benefit charge, from 2025-26 the winter fuel payment charge, and from 2020-21 the company car and car fuel benefits in kind (no other benefits in kind, and no vans) - id: national_insurance name: National Insurance @@ -62,7 +62,7 @@ programs: variable: national_insurance parameter_prefix: gov.hmrc.national_insurance verified_start_year: 2019 - notes: Classes 1, 2, 3, and 4 + notes: Classes 1, 2, 3, and 4, and Class 1A on the company car and car fuel benefits - id: capital_gains_tax name: Capital gains tax diff --git a/policyengine_uk/scenarios/__init__.py b/policyengine_uk/scenarios/__init__.py index 4be5973b03..e206fa2af7 100644 --- a/policyengine_uk/scenarios/__init__.py +++ b/policyengine_uk/scenarios/__init__.py @@ -1,4 +1,5 @@ from .abolish_benefit_cap import abolish_benefit_cap +from .company_car_tax_rise_2030 import company_car_tax_rise_2030 from .no_economic_assumptions import no_economic_assumptions from .pip_reform import reform_pip_phase_in from .reindex_benefit_cap import reindex_benefit_cap diff --git a/policyengine_uk/scenarios/company_car_tax_rise_2030.py b/policyengine_uk/scenarios/company_car_tax_rise_2030.py new file mode 100644 index 0000000000..cc1679e3d0 --- /dev/null +++ b/policyengine_uk/scenarios/company_car_tax_rise_2030.py @@ -0,0 +1,44 @@ +"""Budget 2026's company car tax rates for 2030-31. + +Budget 2026 sets every company car appropriate percentage for 2030-31 one +point above 2029-30's, zero-emission cars included, and raises the maximum +from 39% to 40% (ITEPA 2003 s. 139(1), (3)(a) and (3)(b), and the diesel +cap in s. 141(2) step 3). Finance Bill 2026-27 is to legislate it, so the +baseline keeps 2029-30's rates for 2030-31 and this scenario applies the +rise from 6 April 2030. Table 6.1 of Budget 2026 (row 86) costs it at ++£310m in 2030-31 and +£345m in 2031-32. + +Sources: Budget 2026, overview of tax legislation and rates, paragraph 1.25; +HMRC, "Taxation of company cars: the appropriate percentage for tax years +2030 to 2031 and 2031 to 2032" (28 October 2026). +""" + +from policyengine_uk.model_api import Scenario + +APPROPRIATE_PERCENTAGE = ( + "gov.hmrc.income_tax.benefits_in_kind.company_car.appropriate_percentage" +) +FROM_2030_31 = "2030-04-06.2100-12-31" + +# Each rate is 2029-30's (Finance Act 2025 s. 6) plus one point. +COMPANY_CAR_TAX_RISE_2030 = { + f"{APPROPRIATE_PERCENTAGE}.zero_emission": {FROM_2030_31: 0.10}, + # 1 to 50 g/km, one rate whatever the electric range. + **{ + f"{APPROPRIATE_PERCENTAGE}.electric_range[{bracket}].amount": { + FROM_2030_31: 0.20 + } + for bracket in range(5) + }, + # 51-54, 55-59, 60-64, 65-69 and 70-74 g/km. + f"{APPROPRIATE_PERCENTAGE}.co2_band[0].amount": {FROM_2030_31: 0.21}, + f"{APPROPRIATE_PERCENTAGE}.co2_band[1].amount": {FROM_2030_31: 0.22}, + f"{APPROPRIATE_PERCENTAGE}.co2_band[2].amount": {FROM_2030_31: 0.23}, + f"{APPROPRIATE_PERCENTAGE}.co2_band[3].amount": {FROM_2030_31: 0.24}, + f"{APPROPRIATE_PERCENTAGE}.co2_band[4].amount": {FROM_2030_31: 0.24}, + # 75 g/km, and one point more for each 5 g/km above it. + f"{APPROPRIATE_PERCENTAGE}.graduated.base_rate": {FROM_2030_31: 0.24}, + f"{APPROPRIATE_PERCENTAGE}.maximum": {FROM_2030_31: 0.40}, +} + +company_car_tax_rise_2030 = Scenario(parameter_changes=COMPANY_CAR_TAX_RISE_2030) diff --git a/policyengine_uk/tests/policy/baseline/gov/hmrc/income_tax/benefits_in_kind/benefits_in_kind_interactions.yaml b/policyengine_uk/tests/policy/baseline/gov/hmrc/income_tax/benefits_in_kind/benefits_in_kind_interactions.yaml new file mode 100644 index 0000000000..8b9d782e1c --- /dev/null +++ b/policyengine_uk/tests/policy/baseline/gov/hmrc/income_tax/benefits_in_kind/benefits_in_kind_interactions.yaml @@ -0,0 +1,239 @@ +# Where the company car benefit goes. A person paid £20,000 in 2026-27 has +# a zero-emission company car with a list price of £75,000, so a benefit of +# £75,000 x 4% = £3,000. The benefit is employment income for income tax +# (ITEPA 2003 s. 120) and so counts in adjusted net income. It is not +# earnings for employee Class 1 NICs, nor for Universal Credit (UC +# Regulations 2013 reg. 55(2)(a)), Housing Benefit (HB Regulations 2006 +# reg. 35(2)(a)) or Council Tax Reduction. Those earnings tests do deduct the +# income tax on it, which is tax paid in respect of the employment (UC reg. +# 55(5)(b)); PAYE collects it from the person's pay. + +- name: Without the company car + period: 2026 + absolute_error_margin: 0.01 + input: + age: 40 + employment_income: 20_000 + output: + taxable_employment_income: 20_000 + adjusted_net_income: 20_000 + # (£20,000 - £12,570) x 20% = £1,486. + income_tax: 1_486 + # (£20,000 - £12,570) x 8% = £594.40. + ni_class_1_employee: 594.4 + uc_income_tax_on_earnings: 1_486 + # £20,000 - £1,486 - £594.40 = £17,919.60. + uc_individual_earned_income_before_mif: 17_919.6 + housing_benefit_net_earnings: 17_919.6 + council_tax_reduction_net_earnings: 17_919.6 + # (£20,000 - £5,000) x 15% = £2,250. + ni_employer: 2_250 + +- name: With the company car + period: 2026 + absolute_error_margin: 0.01 + input: + age: 40 + employment_income: 20_000 + company_car_list_price: 75_000 + company_car_co2_emissions: 0 + company_car_fuel_type: ELECTRIC + output: + company_car_benefit: 3_000 + # Income tax and adjusted net income include the benefit. + taxable_employment_income: 23_000 + adjusted_net_income: 23_000 + # (£23,000 - £12,570) x 20% = £2,086. + income_tax: 2_086 + # Pay, statutory pay and Class 1 earnings leave the benefit out. + employment_income: 20_000 + employment_benefits: 0 + ni_class_1_income: 20_000 + ni_class_1_employee: 594.4 + # The earnings tests leave the benefit out and deduct the income tax on + # it: £20,000 - £2,086 - £594.40 = £17,319.60. + uc_income_tax_on_earnings: 2_086 + uc_individual_earned_income_before_mif: 17_319.6 + housing_benefit_net_earnings: 17_319.6 + council_tax_reduction_net_earnings: 17_319.6 + # Class 1A of £3,000 x 15% = £450 on top of secondary Class 1. + ni_class_1a: 450 + ni_employer: 2_700 + +- name: The benefit reaches the personal allowance taper + period: 2026 + absolute_error_margin: 0.01 + input: + age: 40 + employment_income: 100_000 + company_car_list_price: 40_000 + company_car_co2_emissions: 120 + output: + # 120 g/km is 30%: a £12,000 benefit takes adjusted net income to + # £112,000, so the allowance falls by £12,000 / 2 to £6,570 + # (Income Tax Act 2007 s. 35). + adjusted_net_income: 112_000 + personal_allowance: 6_570 + +- name: The benefit counts towards the High Income Child Benefit Charge + period: 2026 + absolute_error_margin: 0.01 + input: + people: + parent: + age: 40 + employment_income: 58_000 + company_car_list_price: 40_000 + company_car_co2_emissions: 120 + child: + age: 5 + benunits: + benunit: + members: [parent, child] + would_claim_child_benefit: true + households: + household: + members: [parent, child] + output: + # Adjusted net income of £70,000 is above the £60,000 to £80,000 taper + # midpoint, so the charge is half the Child Benefit + # (Income Tax (Earnings and Pensions) Act 2003 s. 681C). + adjusted_net_income: [70_000, 0] + # Child Benefit of £27.05 a week for 52 weeks is £1,406.60, rounded + # down to £1,406; half of it is £703 (s. 681C(3)). + CB_HITC: [703, 0] + +- name: Student loan repayments leave the benefit out + period: 2026 + absolute_error_margin: 0.01 + input: + age: 30 + employment_income: 40_000 + student_loan_plan: PLAN_2 + company_car_list_price: 30_000 + company_car_co2_emissions: 120 + output: + # A £9,000 benefit (30% of £30,000) is in net income, but not in the + # income repayments are due on: Self Assessment leaves out Chapter 6 car + # benefits (SI 2009/470 reg. 29(4)(e)) and PAYE deducts repayments from + # Class 1 earnings (reg. 41). 9% of (£40,000 - £29,385) = £955.35. + net_income: 49_000 + student_loan_repayment: 955.35 + +- name: Student loans leave out only the part of the benefit that deductions leave in income + period: 2026 + absolute_error_margin: 0.01 + input: + age: 30 + employment_income: 10_000 + employment_expenses: 15_000 + private_pension_income: 30_000 + student_loan_plan: PLAN_2 + company_car_list_price: 30_000 + company_car_co2_emissions: 120 + output: + # Allowable expenses of £15,000 come off pay and the £9,000 benefit + # together (ITEPA 2003 s. 11): taxable employment income is £4,000, and + # would be nil without the car. So net income of £34,000 holds £4,000 + # of the benefit, and repayment income is £30,000, the pension: + # 9% of (£30,000 - £29,385) = £55.35. + taxable_employment_income: 4_000 + net_income: 34_000 + student_loan_repayment: 55.35 + +- name: The pension relief limit counts the benefit as relevant UK earnings + period: 2026 + absolute_error_margin: 0.01 + input: + age: 40 + employment_income: 10_000 + personal_pension_contributions: 14_000 + company_car_list_price: 20_000 + company_car_co2_emissions: 120 + output: + # Taxable benefits in kind are employment income chargeable to tax, so + # relevant UK earnings (Finance Act 2004 s. 189(2)(a); HMRC PTM044100): + # £10,000 + £6,000 = £16,000 is above the £14,000 contributed, so all of + # it is relieved. Without the car the limit would be £10,000. + pension_contributions_relief: 14_000 + +- name: A Scottish taxpayer pays Scottish rates on the benefit + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person: + age: 40 + employment_income: 35_000 + company_car_list_price: 75_000 + company_car_co2_emissions: 0 + company_car_fuel_type: ELECTRIC + benunits: + benunit: + members: [person] + households: + household: + members: [person] + region: SCOTLAND + output: + # Taxable income of £35,000 + £3,000 - £12,570 = £25,430, all within + # the intermediate band (21%) above £16,956: 19% of £3,967, 20% of + # £12,989 and 21% of £8,474 = £5,131.07, of which 21% of the £3,000 + # benefit is £630. + income_tax: 5_131.07 + +- name: The benefit counts towards the £100,000 limits of Tax-Free Childcare and the extended entitlement + period: 2026 + absolute_error_margin: 0 + input: + age: 40 + employment_income: 95_000 + company_car_list_price: 40_000 + company_car_co2_emissions: 120 + output: + # Adjusted net income of £95,000 + £12,000 is above £100,000 (SI + # 2015/448 reg. 15; SI 2022/1134 regs. 14(3)(c)(i) and 15(3)(b)(i)). + adjusted_net_income: 107_000 + tax_free_childcare_meets_income_requirements: false + extended_childcare_entitlement_meets_income_requirements: false + +- name: Earnings tests with other income, without the company car + period: 2026 + absolute_error_margin: 0.01 + input: + age: 40 + employment_income: 20_000 + private_pension_income: 20_000 + output: + # (£40,000 - £12,570) x 20% = £5,486. + income_tax: 5_486 + # UC takes earnings as the lowest slice: (£20,000 - £12,570) x 20%. + uc_income_tax_on_earnings: 1_486 + uc_individual_earned_income_before_mif: 17_919.6 + # HB and CTR take earnings' share of the tax: £5,486 x 20/40 = £2,743; + # £20,000 - £2,743 - £594.40 = £16,662.60. + housing_benefit_net_earnings: 16_662.6 + council_tax_reduction_net_earnings: 16_662.6 + +- name: Earnings tests with other income, with the company car + period: 2026 + absolute_error_margin: 0.01 + input: + age: 40 + employment_income: 20_000 + private_pension_income: 20_000 + company_car_list_price: 75_000 + company_car_co2_emissions: 0 + company_car_fuel_type: ELECTRIC + output: + # The £3,000 benefit adds £600 of tax: (£43,000 - £12,570) x 20%. + income_tax: 6_086 + # UC deducts all £600 from earnings, as the benefit is in the lowest + # slice with pay. + uc_income_tax_on_earnings: 2_086 + uc_individual_earned_income_before_mif: 17_319.6 + # HB and CTR count the benefit with pay in earnings' share of the tax, + # though not in the earnings: £6,086 x 23/43 = £3,255.30, so + # £20,000 - £3,255.30 - £594.40 = £16,150.30. + housing_benefit_net_earnings: 16_150.29 + council_tax_reduction_net_earnings: 16_150.29 diff --git a/policyengine_uk/tests/policy/baseline/gov/hmrc/income_tax/benefits_in_kind/car_fuel_benefit.yaml b/policyengine_uk/tests/policy/baseline/gov/hmrc/income_tax/benefits_in_kind/car_fuel_benefit.yaml new file mode 100644 index 0000000000..7c919c6207 --- /dev/null +++ b/policyengine_uk/tests/policy/baseline/gov/hmrc/income_tax/benefits_in_kind/car_fuel_benefit.yaml @@ -0,0 +1,131 @@ +# The car fuel benefit (ITEPA 2003 ss. 149 to 152). HMRC 480 Chapter 13 +# gives the worked example for 2021-22: +# https://www.gov.uk/guidance/taxable-fuel-provided-for-company-cars-and-vans-480-chapter-13 + +- name: HMRC 480 paragraph 13.6, a petrol car first registered on or after 6 April 2020, in 2021-22 + period: 2021 + absolute_error_margin: 0.01 + input: + company_car_list_price: 30_000 + company_car_co2_emissions: 160 + company_car_registered_from_6_april_2020: true + company_car_private_fuel_provided: true + output: + # The appropriate percentage for the car is 36%, and the 2021-22 car + # fuel benefit charge is £24,600 x 36% = £8,856. + company_car_appropriate_percentage: 0.36 + car_fuel_benefit: 8_856 + +- name: Diesel car not meeting RDE2 with private fuel, in 2026-27 + period: 2026 + absolute_error_margin: 0.01 + input: + company_car_list_price: 15_000 + company_car_co2_emissions: 156 + company_car_fuel_type: DIESEL_NON_RDE2 + company_car_private_fuel_provided: true + output: + # The car's 37% of the £29,200 multiplier (SI 2025/1254): £10,804. + car_fuel_benefit: 10_804 + +- name: 2027-28 uses the multiplier announced at Budget 2026 + period: 2027 + absolute_error_margin: 0.01 + input: + company_car_list_price: 40_000 + company_car_co2_emissions: 120 + company_car_private_fuel_provided: true + output: + # 120 g/km is 30% in 2027-28 (HMRC future rates table). OOTLAR + # paragraph 2.6 gives a £30,200 multiplier: £30,200 x 30% = £9,060. + car_fuel_benefit: 9_060 + +- name: No fuel benefit when private fuel is made good in full + period: 2026 + absolute_error_margin: 0 + input: + company_car_list_price: 15_000 + company_car_co2_emissions: 156 + company_car_private_fuel_provided: false + output: + # s. 151, condition A. + car_fuel_benefit: 0 + +- name: No fuel benefit for a car that cannot emit CO2 + period: 2026 + absolute_error_margin: 0 + input: + company_car_list_price: 40_000 + company_car_co2_emissions: 0 + company_car_fuel_type: ELECTRIC + company_car_private_fuel_provided: true + output: + # s. 149(4): energy for such a car is not fuel. + car_fuel_benefit: 0 + +- name: Fuel benefit is reduced for days the car is unavailable + period: 2026 + absolute_error_margin: 0.01 + input: + company_car_list_price: 15_000 + company_car_co2_emissions: 156 + company_car_fuel_type: DIESEL_NON_RDE2 + company_car_private_fuel_provided: true + company_car_availability: 0.5 + output: + # s. 152(1): £10,804 x 0.5 = £5,402. + car_fuel_benefit: 5_402 + +- name: Payments for private use and capital contributions do not reduce the fuel benefit + period: 2026 + absolute_error_margin: 0.01 + input: + company_car_list_price: 15_000 + company_car_capital_contributions: 5_000 + company_car_co2_emissions: 156 + company_car_fuel_type: DIESEL_NON_RDE2 + company_car_private_fuel_provided: true + company_car_private_use_payments: 10_000 + output: + # HMRC 480 paragraph 13.1: a fuel benefit arises even where these + # reduce the car benefit to nil. + company_car_benefit: 0 + car_fuel_benefit: 10_804 + +- name: No fuel benefit without a company car + period: 2026 + absolute_error_margin: 0 + input: + company_car_co2_emissions: 120 + company_car_private_fuel_provided: true + output: + car_fuel_benefit: 0 + +- name: Fuel benefit for a 1-50 g/km hybrid, in 2026-27 + period: 2026 + absolute_error_margin: 0.01 + input: + company_car_list_price: 32_000 + company_car_co2_emissions: 40 + company_car_electric_range: 35 + company_car_private_fuel_provided: true + output: + # 30-39 miles is 14% (HMRC 480 Appendix 2, 2026-27): the petrol it + # burns is fuel, the electricity is not (s. 149(4)). + # £29,200 x 14% = £4,088. + car_fuel_benefit: 4_088 + +- name: Fuel benefit under the s. 139A rates, in 2021-22 + period: 2021 + absolute_error_margin: 0.01 + input: + company_car_list_price: 22_000 + company_car_co2_emissions: 50 + company_car_electric_range: 65 + company_car_registered_from_6_april_2020: true + company_car_private_fuel_provided: true + output: + # WLTP, 40-69 miles: 7% (HMRC 480 Appendix 2, 2021-22). + # £24,600 x 7% = £1,722. + company_car_appropriate_percentage: 0.07 + car_fuel_benefit: 1_722 diff --git a/policyengine_uk/tests/policy/baseline/gov/hmrc/income_tax/benefits_in_kind/company_car_benefit.yaml b/policyengine_uk/tests/policy/baseline/gov/hmrc/income_tax/benefits_in_kind/company_car_benefit.yaml new file mode 100644 index 0000000000..83901092d5 --- /dev/null +++ b/policyengine_uk/tests/policy/baseline/gov/hmrc/income_tax/benefits_in_kind/company_car_benefit.yaml @@ -0,0 +1,398 @@ +# The company car benefit (ITEPA 2003 s. 121). HMRC 480 Appendix 1 (company +# car benefit examples) gives worked results for 2020-21 in Examples 6 and 7, +# tested here. Its Examples 3 to 5 are for 2018-19, before the model's first +# year, so the cases below that reuse their cars are not HMRC's worked +# results: they value those cars with the rates in HMRC 480 Appendix 2's +# 2026-27 table, and so test the transcribed rates. +# https://www.gov.uk/guidance/company-car-benefit-examples-480-appendix-1 +# https://www.gov.uk/guidance/company-car-benefit-the-appropriate-percentage-480-appendix-2 + +- name: No company car gives no benefit + period: 2026 + absolute_error_margin: 0 + input: + employment_income: 40_000 + output: + has_company_car: false + company_car_appropriate_percentage: 0 + company_car_benefit: 0 + car_fuel_benefit: 0 + benefits_in_kind: 0 + taxable_employment_income: 40_000 + +- name: HMRC 480 Appendix 1 Example 6, a hybrid first registered before 6 April 2020, in 2020-21 + period: 2020 + absolute_error_margin: 0.01 + input: + company_car_list_price: 32_000 + company_car_co2_emissions: 50 + company_car_electric_range: 77 + output: + # First registered on 22 March 2020, so the NEDC figures: 1-50 g/km + # with an electric range of 70-129 miles is 5%. £32,000 x 5% = £1,600. + company_car_appropriate_percentage: 0.05 + company_car_benefit: 1_600 + +- name: HMRC 480 Appendix 1 Example 7, a hybrid first registered on 6 April 2020, in 2020-21 + period: 2020 + absolute_error_margin: 0.01 + input: + company_car_list_price: 22_000 + company_car_co2_emissions: 50 + company_car_electric_range: 65 + company_car_registered_from_6_april_2020: true + output: + # WLTP figures, so the s. 139A rates: 40-69 miles is 6%. + # £22,000 x 6% = £1,320. + company_car_appropriate_percentage: 0.06 + company_car_benefit: 1_320 + +- name: The s. 139A rates end after 2021-22 + period: 2022 + absolute_error_margin: 0.01 + input: + company_car_list_price: 22_000 + company_car_co2_emissions: 50 + company_car_electric_range: 65 + company_car_registered_from_6_april_2020: true + output: + # HMRC 480 Appendix 2, 2022-23: 40-69 miles is 8% for NEDC and WLTP + # cars alike. £22,000 x 8% = £1,760. + company_car_appropriate_percentage: 0.08 + company_car_benefit: 1_760 + +- name: Petrol car at 100 g/km (the car in HMRC 480 Appendix 1 Example 5) at 2026-27 rates + period: 2026 + absolute_error_margin: 0.01 + input: + company_car_list_price: 18_000 + company_car_co2_emissions: 104 + output: + # 104 rounds down to 100 g/km: 26% (Appendix 2, 2026-27). + # £18,000 x 26% = £4,680. + company_car_appropriate_percentage: 0.26 + company_car_benefit: 4_680 + +- name: Petrol car at the maximum (the car in HMRC 480 Appendix 1 Example 3) at 2026-27 rates + period: 2026 + absolute_error_margin: 0.01 + input: + company_car_list_price: 15_000 + company_car_co2_emissions: 173 + output: + # 173 rounds down to 170 g/km: 37% (Appendix 2, 2026-27, 170 and + # above). £15,000 x 37% = £5,550. + company_car_appropriate_percentage: 0.37 + company_car_benefit: 5_550 + +- name: Diesel car not meeting RDE2 takes the 4-point supplement, in 2026-27 + period: 2026 + absolute_error_margin: 0.01 + input: + company_car_list_price: 18_000 + company_car_co2_emissions: 104 + company_car_fuel_type: DIESEL_NON_RDE2 + output: + # 26% for 100 g/km plus the 4-point diesel supplement (HMRC 480 + # paragraph 12.29). £18,000 x 30% = £5,400. + company_car_appropriate_percentage: 0.3 + company_car_benefit: 5_400 + +- name: Diesel car meeting RDE2 takes no supplement, in 2026-27 + period: 2026 + absolute_error_margin: 0.01 + input: + company_car_list_price: 18_000 + company_car_co2_emissions: 104 + company_car_fuel_type: DIESEL_RDE2 + output: + company_car_appropriate_percentage: 0.26 + company_car_benefit: 4_680 + +- name: Diesel supplement stops at the maximum (the car in HMRC 480 Appendix 1 Example 4) at 2026-27 rates + period: 2026 + absolute_error_margin: 0.01 + input: + company_car_list_price: 15_000 + company_car_co2_emissions: 156 + company_car_fuel_type: DIESEL_NON_RDE2 + output: + # 156 rounds down to 155 g/km: 37% (Appendix 2, 2026-27). Adding 4 + # points would pass the 37% maximum (paragraph 12.29, note 2). + # £15,000 x 37% = £5,550. + company_car_appropriate_percentage: 0.37 + company_car_benefit: 5_550 + +- name: 1-50 g/km cars in each electric range band, in 2026-27 + period: 2026 + absolute_error_margin: 0.01 + input: + people: + range_130: + company_car_list_price: 32_000 + company_car_co2_emissions: 50 + company_car_electric_range: 130 + range_77: + company_car_list_price: 32_000 + company_car_co2_emissions: 50 + company_car_electric_range: 77 + range_65: + company_car_list_price: 32_000 + company_car_co2_emissions: 50 + company_car_electric_range: 65 + range_35: + company_car_list_price: 32_000 + company_car_co2_emissions: 50 + company_car_electric_range: 35 + range_20: + company_car_list_price: 32_000 + company_car_co2_emissions: 50 + company_car_electric_range: 20 + range_29_point_2: + company_car_list_price: 32_000 + company_car_co2_emissions: 50 + company_car_electric_range: 29.2 + benunits: + benunit: + members: [range_130, range_77, range_65, range_35, range_20, range_29_point_2] + households: + household: + members: [range_130, range_77, range_65, range_35, range_20, range_29_point_2] + output: + # Appendix 2, 2026-27: 130 and above 4%, 70-129 7%, 40-69 10%, + # 30-39 14%, less than 30 16%. 29.2 miles rounds up to 30 (s. 139(2)(b)). + company_car_appropriate_percentage: [0.04, 0.07, 0.1, 0.14, 0.16, 0.14] + company_car_benefit: [1_280, 2_240, 3_200, 4_480, 5_120, 4_480] + +- name: 1-50 g/km cars take one rate from 2028-29 whatever their electric range + period: 2029 + absolute_error_margin: 0.01 + input: + people: + range_130: + company_car_list_price: 32_000 + company_car_co2_emissions: 50 + company_car_electric_range: 130 + range_20: + company_car_list_price: 32_000 + company_car_co2_emissions: 1 + company_car_electric_range: 20 + benunits: + benunit: + members: [range_130, range_20] + households: + household: + members: [range_130, range_20] + output: + # Finance Act 2025 s. 6(2): 19% for 1-50 g/km in 2029-30. + company_car_appropriate_percentage: [0.19, 0.19] + company_car_benefit: [6_080, 6_080] + +- name: Zero-emission car in 2026-27 + period: 2026 + absolute_error_margin: 0.01 + input: + company_car_list_price: 40_000 + company_car_co2_emissions: 0 + company_car_fuel_type: ELECTRIC + output: + # Appendix 2, 2026-27: 4%. £40,000 x 4% = £1,600. + company_car_appropriate_percentage: 0.04 + company_car_benefit: 1_600 + +- name: 2029-30 rates, the baseline for 2030-31 + period: 2029 + absolute_error_margin: 0.01 + input: + people: + electric: + company_car_list_price: 40_000 + company_car_co2_emissions: 0 + band_65_74: + company_car_list_price: 40_000 + company_car_co2_emissions: 74 + band_75: + company_car_list_price: 40_000 + company_car_co2_emissions: 79 + high: + company_car_list_price: 40_000 + company_car_co2_emissions: 200 + benunits: + benunit: + members: [electric, band_65_74, band_75, high] + households: + household: + members: [electric, band_65_74, band_75, high] + output: + # Finance Act 2025 s. 6: 9% for 0 g/km, 23% for 65-74 g/km, 23% at + # 75-79 g/km, and a 39% maximum. + company_car_appropriate_percentage: [0.09, 0.23, 0.23, 0.39] + company_car_benefit: [3_600, 9_200, 9_200, 15_600] + +- name: 2030-31 keeps 2029-30's rates in the baseline + period: 2030 + absolute_error_margin: 0.01 + input: + people: + electric: + company_car_list_price: 40_000 + company_car_co2_emissions: 0 + hybrid: + company_car_list_price: 40_000 + company_car_co2_emissions: 30 + company_car_electric_range: 40 + high: + company_car_list_price: 40_000 + company_car_co2_emissions: 200 + benunits: + benunit: + members: [electric, hybrid, high] + households: + household: + members: [electric, hybrid, high] + output: + company_car_appropriate_percentage: [0.09, 0.19, 0.39] + +- name: Capital contributions above £5,000 are capped + period: 2026 + absolute_error_margin: 0.01 + input: + company_car_list_price: 40_000 + company_car_capital_contributions: 7_000 + company_car_co2_emissions: 120 + output: + # s. 132(3): the deduction is the lesser of the contributions and + # £5,000. 120 g/km is 30% (Appendix 2, 2026-27). + # (£40,000 - £5,000) x 30% = £10,500. + company_car_benefit: 10_500 + +- name: Capital contributions below the cap are deducted in full + period: 2026 + absolute_error_margin: 0.01 + input: + company_car_list_price: 40_000 + company_car_capital_contributions: 3_000 + company_car_co2_emissions: 120 + output: + # (£40,000 - £3,000) x 30% = £11,100. + company_car_benefit: 11_100 + +- name: Car available for part of the year + period: 2026 + absolute_error_margin: 0.01 + input: + company_car_list_price: 40_000 + company_car_co2_emissions: 120 + company_car_availability: 0.5 + output: + # s. 143(3) deducts A x U / Y: £12,000 x 0.5 = £6,000. + company_car_benefit: 6_000 + +- name: Payments for private use come off after the reduction for unavailability + period: 2026 + absolute_error_margin: 0.01 + input: + company_car_list_price: 40_000 + company_car_co2_emissions: 120 + company_car_availability: 0.5 + company_car_private_use_payments: 1_200 + output: + # Steps 7 then 8 of s. 121(1): £12,000 x 0.5 - £1,200 = £4,800. + company_car_benefit: 4_800 + +- name: Payments for private use above the benefit reduce it to nil + period: 2026 + absolute_error_margin: 0 + input: + company_car_list_price: 40_000 + company_car_co2_emissions: 120 + company_car_private_use_payments: 13_000 + output: + # s. 144(2). + company_car_benefit: 0 + +- name: No benefit before 2020-21, the model's first year + period: 2019 + absolute_error_margin: 0 + input: + company_car_list_price: 40_000 + company_car_co2_emissions: 120 + output: + company_car_benefit: 0 + +- name: Out-of-range amounts are floored at zero and availability is kept between 0 and 1 + period: 2026 + absolute_error_margin: 0.01 + input: + people: + negative_price: + company_car_list_price: -40_000 + company_car_co2_emissions: 120 + negative_amounts: + company_car_list_price: 40_000 + company_car_co2_emissions: 120 + company_car_capital_contributions: -5_000 + company_car_private_use_payments: -1_200 + availability_above_one: + company_car_list_price: 40_000 + company_car_co2_emissions: 120 + company_car_availability: 1.5 + availability_below_zero: + company_car_list_price: 40_000 + company_car_co2_emissions: 120 + company_car_availability: -0.5 + negative_figures: + company_car_list_price: 40_000 + company_car_co2_emissions: -10 + company_car_electric_range: -10 + benunits: + benunit: + members: [negative_price, negative_amounts, availability_above_one, availability_below_zero, negative_figures] + households: + household: + members: [negative_price, negative_amounts, availability_above_one, availability_below_zero, negative_figures] + output: + # A negative price is no car; negative contributions and payments are + # none; availability is capped at the whole year and floored at none. + # Negative CO2 and electric range figures are 0: the zero-emission rate. + has_company_car: [false, true, true, true, true] + company_car_appropriate_percentage: [0, 0.3, 0.3, 0.3, 0.04] + company_car_benefit: [0, 12_000, 12_000, 0, 1_600] + +- name: An electric car is zero-emission whatever CO2 figure is entered + period: 2026 + absolute_error_margin: 0.01 + input: + company_car_list_price: 40_000 + company_car_co2_emissions: 150 + company_car_fuel_type: ELECTRIC + company_car_private_fuel_provided: true + output: + # As for vehicle excise duty, the ELECTRIC fuel type gives a CO2 figure + # of 0: 4% in 2026-27, and no car fuel benefit (s. 149(4)). + company_car_appropriate_percentage: 0.04 + company_car_benefit: 1_600 + car_fuel_benefit: 0 + +- name: A car at 0 g/km takes no diesel supplement + period: 2026 + absolute_error_margin: 0.01 + input: + company_car_list_price: 40_000 + company_car_co2_emissions: 0 + company_car_fuel_type: DIESEL_NON_RDE2 + output: + # A car that cannot emit CO2 is not propelled by diesel (s. 141(3)). + company_car_appropriate_percentage: 0.04 + company_car_benefit: 1_600 + +- name: A CO2 figure that rounds down to 0 is zero-emission for both benefits + period: 2026 + absolute_error_margin: 0 + input: + company_car_list_price: 40_000 + company_car_co2_emissions: 0.5 + company_car_private_fuel_provided: true + output: + company_car_appropriate_percentage: 0.04 + car_fuel_benefit: 0 diff --git a/policyengine_uk/tests/policy/baseline/gov/hmrc/national_insurance/class_1a/ni_class_1a.yaml b/policyengine_uk/tests/policy/baseline/gov/hmrc/national_insurance/class_1a/ni_class_1a.yaml new file mode 100644 index 0000000000..0e452d55a5 --- /dev/null +++ b/policyengine_uk/tests/policy/baseline/gov/hmrc/national_insurance/class_1a/ni_class_1a.yaml @@ -0,0 +1,98 @@ +# Class 1A contributions on benefits in kind (SSCBA 1992 s. 10). The Class +# 1A percentage is the secondary Class 1 percentage for the year (s. 10(5)): +# 13.8% to 2024-25 and 15% from 2025-26, except 14.53% for 2022-23 (Health +# and Social Care Levy (Repeal) Act 2022 Schedule paragraph 1(2)). Each case +# has a petrol car with a list price of £40,000 emitting 120 g/km, whose +# appropriate percentage is 29% to 2024-25 and 30% from 2025-26 (HMRC 480 +# Appendix 2), so its benefit is £11,600, then £12,000. + +- name: Class 1A at 13.8% in 2021-22 + period: 2021 + absolute_error_margin: 0.01 + input: + company_car_list_price: 40_000 + company_car_co2_emissions: 120 + output: + # £11,600 x 13.8% = £1,600.80. + ni_class_1a: 1_600.8 + +- name: Class 1A at the 2022-23 rate of 14.53%, not the secondary percentage at 30 April + period: 2022 + absolute_error_margin: 0.01 + input: + company_car_list_price: 40_000 + company_car_co2_emissions: 120 + output: + # £11,600 x 14.53% = £1,685.48. + ni_class_1a: 1_685.48 + +- name: Class 1A back at 13.8% in 2023-24 + period: 2023 + absolute_error_margin: 0.01 + input: + company_car_list_price: 40_000 + company_car_co2_emissions: 120 + output: + ni_class_1a: 1_600.8 + +- name: Class 1A at 15% from 2025-26 + period: 2025 + absolute_error_margin: 0.01 + input: + company_car_list_price: 40_000 + company_car_co2_emissions: 120 + output: + # £12,000 x 15% = £1,800. + ni_class_1a: 1_800 + +- name: Class 1A on the car and car fuel benefits together + period: 2026 + absolute_error_margin: 0.01 + input: + company_car_list_price: 40_000 + company_car_co2_emissions: 120 + company_car_private_fuel_provided: true + output: + # Car £12,000 plus fuel £29,200 x 30% = £8,760: £20,760 x 15% = £3,114. + benefits_in_kind: 20_760 + ni_class_1a: 3_114 + +- name: Class 1A reaches employer NI alongside secondary Class 1 + period: 2026 + absolute_error_margin: 0.01 + input: + age: 40 + employment_income: 40_000 + company_car_list_price: 40_000 + company_car_co2_emissions: 120 + output: + # Secondary Class 1: (£40,000 - £5,000) x 15% = £5,250, on pay only. + ni_class_1_employer: 5_250 + ni_class_1a: 1_800 + ni_employer: 7_050 + +- name: Class 1A is due for an earner under 21, whose pay is zero-rated for secondary Class 1 + period: 2026 + absolute_error_margin: 0.01 + input: + age: 20 + employment_income: 30_000 + company_car_list_price: 40_000 + company_car_co2_emissions: 120 + output: + ni_class_1_employer: 0 + ni_class_1a: 1_800 + ni_employer: 1_800 + +- name: Total National Insurance includes Class 1A + period: 2026 + absolute_error_margin: 0.01 + input: + age: 40 + employment_income: 40_000 + company_car_list_price: 40_000 + company_car_co2_emissions: 120 + output: + # Employee Class 1: (£40,000 - £12,570) x 8% = £2,194.40, on pay only. + ni_class_1_employee: 2_194.4 + total_national_insurance: 2_194.4 + 7_050 diff --git a/policyengine_uk/tests/test_company_car_benefit.py b/policyengine_uk/tests/test_company_car_benefit.py new file mode 100644 index 0000000000..8c4be71795 --- /dev/null +++ b/policyengine_uk/tests/test_company_car_benefit.py @@ -0,0 +1,409 @@ +"""The company car benefit against HMRC's published rates, and its reforms. + +1. Published rates: for every tax year from 2020-21 to 2029-30, the + appropriate percentage at both ends of each band equals the rate HMRC + publishes for it: HMRC 480 Appendix 2 for 2020-21 to 2026-27 (its + 2022-23 table holds to 2024-25), HMRC's future rates table for 2027-28, + and the tables in Finance Act 2025 ss. 5 and 6 for 2028-29 and 2029-30. + In 2020-21 and 2021-22 cars first registered before 6 April 2020 take + the NEDC column and later cars the WLTP column (ITEPA 2003 s. 139A). + A diesel car not meeting RDE2 adds 4 points, up to the maximum. +2. Budget 2026: the company_car_tax_rise_2030 scenario raises every + appropriate percentage for 2030-31 by one point, to a maximum of 40%. It + changes a company car holder's income tax and their employer's Class 1A, + nothing else (their student loan repayment included), and nobody else's + tax; 2029-30 is unchanged. COMPANY_CAR_TAX_RISE_2030 passed as a reform + dict gives the same results. +3. Employer NI: Class 1A follows the secondary percentage (SSCBA 1992 + s. 10(5)), so an employer rate reform moves it. The employer NI + incidence covers secondary Class 1 only, so no household bears Class 1A: + the fixed-employer-cost pay response and the employer cost change that + the capital and consumer channels spread leave it out. And + baseline_employer_cost and adjusted_employer_cost still equal each + simulation's employer_cost for a company car holder, as they do for + everyone else. + +Comparisons allow float32 rounding. +""" + +import numpy as np +import pytest + +from policyengine_uk import Simulation +from policyengine_uk.scenarios import company_car_tax_rise_2030 +from policyengine_uk.scenarios.company_car_tax_rise_2030 import ( + COMPANY_CAR_TAX_RISE_2030, +) + +pytestmark = pytest.mark.usefixtures("cloned_uk_tax_benefit_system") + +# Each table, in percentage points: the rate for 0 g/km; for 1 to 50 g/km by +# electric range (130 miles or more, 70-129, 40-69, 30-39, under 30); for +# 51-54, 55-59, 60-64, 65-69 and 70-74 g/km; and for each 5 g/km band from +# 75-79 to 165-169 g/km, then 170 g/km and above. +NEDC_2020 = ( + 0, + [2, 5, 8, 12, 14], + [15, 16, 17, 18, 19], + [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 37], +) +WLTP_2020 = ( + 0, + [0, 3, 6, 10, 12], + [13, 14, 15, 16, 17], + [18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37], +) +NEDC_2021 = ( + 1, + [2, 5, 8, 12, 14], + [15, 16, 17, 18, 19], + [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 37], +) +WLTP_2021 = ( + 1, + [1, 4, 7, 11, 13], + [14, 15, 16, 17, 18], + [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37], +) +ALL_CARS_2022 = ( + 2, + [2, 5, 8, 12, 14], + [15, 16, 17, 18, 19], + [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 37], +) +ALL_CARS_2025 = ( + 3, + [3, 6, 9, 13, 15], + [16, 17, 18, 19, 20], + [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 37, 37], +) +ALL_CARS_2026 = ( + 4, + [4, 7, 10, 14, 16], + [17, 18, 19, 20, 21], + [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 37, 37], +) +ALL_CARS_2027 = ( + 5, + [5, 8, 11, 15, 17], + [18, 19, 20, 21, 21], + [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 37, 37], +) +# Finance Act 2025 ss. 5 and 6: one rate for 1 to 50 g/km, a 65-74 g/km +# band, and from 75 g/km 22% (then 23%) plus one point for each 5 g/km, up +# to 38% (then 39%). +ALL_CARS_2028 = ( + 7, + [18] * 5, + [19, 20, 21, 22, 22], + [22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 38, 38, 38], +) +ALL_CARS_2029 = ( + 9, + [19] * 5, + [20, 21, 22, 23, 23], + [23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 39, 39, 39], +) +# Budget 2026 for 2030-31: one point above 2029-30 in every band, up to 40%. +BUDGET_2026_2030 = ( + 10, + [20] * 5, + [21, 22, 23, 24, 24], + [24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 40, 40, 40], +) + +# (year, first registered on or after 6 April 2020, table) +PUBLISHED = [ + (2020, False, NEDC_2020), + (2020, True, WLTP_2020), + (2021, False, NEDC_2021), + (2021, True, WLTP_2021), + (2022, False, ALL_CARS_2022), + (2022, True, ALL_CARS_2022), + (2023, True, ALL_CARS_2022), + (2024, False, ALL_CARS_2022), + (2025, False, ALL_CARS_2025), + (2026, True, ALL_CARS_2026), + (2027, False, ALL_CARS_2027), + (2028, False, ALL_CARS_2028), + (2029, False, ALL_CARS_2029), +] + +RANGE_BANDS = [(130, 300), (70, 129), (40, 69), (30, 39), (0, 29)] +CO2_BANDS = [(51, 54), (55, 59), (60, 64), (65, 69), (70, 74)] +GRADUATED_BANDS = [(low, low + 4) for low in range(75, 170, 5)] + [(170, 250)] + + +def band_points(table): + """(CO2 g/km, electric range in miles, expected rate) at each band's ends.""" + zero, by_range, by_co2, graduated = table + points = [(0, 0, zero)] + for (low, high), rate in zip(RANGE_BANDS, by_range): + for co2 in (1, 50): + points += [(co2, low, rate), (co2, high, rate)] + for bands, rates in ((CO2_BANDS, by_co2), (GRADUATED_BANDS, graduated)): + for (low, high), rate in zip(bands, rates): + points += [(low, 0, rate), (high, 0, rate)] + return points + + +def situation(year, cars): + """One person per car, each with the given company car inputs.""" + people = { + f"person_{i}": { + "age": {year: 40}, + "employment_income": {year: 40_000}, + **{name: {year: value} for name, value in car.items()}, + } + for i, car in enumerate(cars) + } + return { + "people": people, + "benunits": {f"benunit_{name}": {"members": [name]} for name in people}, + "households": {f"household_{name}": {"members": [name]} for name in people}, + } + + +def values(simulation, variable, year): + return np.asarray(simulation.calculate(variable, year), dtype=float) + + +def appropriate_percentages(year, cars, **kwargs): + simulation = Simulation(situation=situation(year, cars), **kwargs) + return values(simulation, "company_car_appropriate_percentage", year) + + +def cars_at(points, registered, fuel_type="PETROL"): + return [ + { + "company_car_list_price": 30_000, + "company_car_co2_emissions": co2, + "company_car_electric_range": electric_range, + "company_car_registered_from_6_april_2020": registered, + "company_car_fuel_type": fuel_type, + } + for co2, electric_range, _ in points + ] + + +@pytest.mark.parametrize("year, registered, table", PUBLISHED) +def test_appropriate_percentages_match_published_rates(year, registered, table): + points = band_points(table) + actual = appropriate_percentages(year, cars_at(points, registered)) + expected = np.array([rate for *_, rate in points]) / 100 + np.testing.assert_allclose(actual, expected, atol=1e-6) + + +@pytest.mark.parametrize("year, registered, table", PUBLISHED) +def test_diesel_supplement_adds_four_points_up_to_the_maximum(year, registered, table): + # HMRC 480 paragraph 12.29: a diesel car not meeting RDE2 adds 4 points, + # subject to the overall maximum, which is the table's highest rate. + points = [point for point in band_points(table) if point[0] > 0] + maximum = max(table[3]) + actual = appropriate_percentages( + year, cars_at(points, registered, "DIESEL_NON_RDE2") + ) + expected = np.minimum(np.array([rate for *_, rate in points]) + 4, maximum) / 100 + np.testing.assert_allclose(actual, expected, atol=1e-6) + + +def test_figures_are_rounded_as_section_139_rounds_them(): + # s. 139(2): CO2 down to a whole number, electric range up; s. 139(4): + # from 75 g/km, CO2 down to a multiple of 5. 2026-27 rates. + cars = [ + { + "company_car_list_price": 30_000, + "company_car_co2_emissions": co2, + "company_car_electric_range": electric_range, + } + for co2, electric_range in [(50.9, 130), (49, 29.1), (74.9, 0), (79.9, 0)] + ] + actual = appropriate_percentages(2026, cars) + np.testing.assert_allclose(actual, [0.04, 0.14, 0.21, 0.21], atol=1e-6) + + +def test_2030_31_rise_sets_the_budget_2026_rates(): + points = band_points(BUDGET_2026_2030) + cars = cars_at(points, registered=False) + baseline = appropriate_percentages(2030, cars) + reformed = appropriate_percentages(2030, cars, scenario=company_car_tax_rise_2030) + expected = np.array([rate for *_, rate in points]) / 100 + np.testing.assert_allclose(reformed, expected, atol=1e-6) + # The baseline keeps 2029-30's rates. + expected_baseline = np.array([rate for *_, rate in band_points(ALL_CARS_2029)]) + np.testing.assert_allclose(baseline, expected_baseline / 100, atol=1e-6) + + +# A company car holder with private fuel and a Plan 2 student loan, and an +# employee without a car. +HOLDER = { + "company_car_list_price": 40_000, + "company_car_co2_emissions": 120, + "company_car_private_fuel_provided": True, + "student_loan_plan": "PLAN_2", +} +UNCHANGED_FOR_HOLDER = [ + "ni_class_1_employer", + "ni_class_1_employee", + "employment_income", + "employer_ni_fixed_employer_cost_change", + "student_loan_repayment", + "plan_2_interest_rate", +] +TAX_AND_INCOME = [ + "income_tax", + "ni_class_1a", + "uc_individual_earned_income_before_mif", +] + UNCHANGED_FOR_HOLDER + + +@pytest.mark.parametrize("year", [2029, 2030, 2031]) +def test_2030_31_rise_changes_only_holders_income_tax_and_class_1a(year): + cars = [HOLDER, {}] + baseline = Simulation(situation=situation(year, cars)) + reformed = Simulation( + situation=situation(year, cars), scenario=company_car_tax_rise_2030 + ) + change = { + variable: values(reformed, variable, year) - values(baseline, variable, year) + for variable in TAX_AND_INCOME + ["benefits_in_kind", "gov_tax"] + } + benefit_change = change["benefits_in_kind"][0] + if year == 2029: + # The rise starts on 6 April 2030. + for variable, difference in change.items(): + np.testing.assert_allclose(difference, 0, atol=1e-2, err_msg=variable) + return + # One point on the car (£40,000) and on the fuel multiplier. + multiplier = baseline.tax_benefit_system.parameters( + f"{year}-01-01" + ).gov.hmrc.income_tax.benefits_in_kind.car_fuel.multiplier + assert benefit_change == pytest.approx(0.01 * (40_000 + multiplier), abs=0.05) + # Pay of £40,000 plus about £23,000 of car and fuel benefits is in the + # higher rate band, and below the personal allowance taper. + assert change["income_tax"][0] == pytest.approx(0.4 * benefit_change, abs=0.05) + assert change["ni_class_1a"][0] == pytest.approx(0.15 * benefit_change, abs=0.05) + assert change["gov_tax"][0] == pytest.approx( + change["income_tax"][0] + change["ni_class_1a"][0], abs=0.05 + ) + # UC earnings lose the extra income tax and nothing else. + assert change["uc_individual_earned_income_before_mif"][0] == pytest.approx( + -change["income_tax"][0], abs=0.05 + ) + for variable in UNCHANGED_FOR_HOLDER: + np.testing.assert_allclose(change[variable][0], 0, atol=1e-6, err_msg=variable) + # Nothing changes for the employee without a car. + for variable, difference in change.items(): + np.testing.assert_allclose(difference[1], 0, atol=1e-2, err_msg=variable) + + +def test_a_company_car_raises_gov_tax_by_its_income_tax_and_class_1a(): + # The same employee, with the same student loan, without the car. + without_the_car = { + name: value for name, value in HOLDER.items() if not name.startswith("company") + } + with_car = Simulation(situation=situation(2026, [HOLDER])) + without_car = Simulation(situation=situation(2026, [without_the_car])) + + def change(variable): + return (values(with_car, variable, 2026) - values(without_car, variable, 2026))[ + 0 + ] + + assert change("ni_class_1a") > 0 + # Student loan repayments are in gov_tax but leave the benefit out. + assert change("student_loan_repayment") == 0 + assert change("gov_tax") == pytest.approx( + change("income_tax") + change("ni_class_1a"), abs=0.05 + ) + # The benefit is not cash: household income falls by the tax on it. + assert change("household_net_income") == pytest.approx( + -change("income_tax"), abs=0.05 + ) + + +EMPLOYER_RATE = "gov.hmrc.national_insurance.class_1.employer_scale[1].rate" + + +def test_class_1a_follows_an_employer_rate_reform_outside_the_fixed_cost_response(): + reform = {EMPLOYER_RATE: {"2026-04-06.2100-12-31": 0.16}} + cars = [HOLDER, {}] + baseline = Simulation(situation=situation(2026, cars)) + reformed = Simulation(situation=situation(2026, cars), reform=reform) + benefits = values(baseline, "benefits_in_kind", 2026) + # SSCBA 1992 s. 10(5): the Class 1A percentage is the secondary + # percentage for the year. + np.testing.assert_allclose( + values(reformed, "ni_class_1a", 2026), 0.16 * benefits, rtol=1e-6 + ) + # The pay response holds employer cost before Class 1A, so the holder's + # pay moves exactly as the other employee's does, and so does the cost + # change the capital and consumer channels would spread. + pay_change = values(reformed, "employer_ni_fixed_employer_cost_change", 2026) + assert pay_change[0] < 0 + assert pay_change[0] == pytest.approx(pay_change[1], abs=0.01) + cost_change = values(reformed, "adjusted_employer_cost", 2026) - values( + reformed, "baseline_employer_cost", 2026 + ) + assert cost_change[0] == pytest.approx(cost_change[1], abs=0.01) + # Agreement: the incidence variables' costs equal employer_cost in each + # simulation, for the holder too. + np.testing.assert_allclose( + values(reformed, "baseline_employer_cost", 2026), + values(reformed.baseline, "employer_cost", 2026), + atol=0.01, + ) + np.testing.assert_allclose( + values(reformed, "adjusted_employer_cost", 2026), + values(reformed, "employer_cost", 2026), + atol=0.01, + ) + + +@pytest.mark.parametrize("year", [2030, 2031, 2035]) +def test_the_parameter_changes_as_a_reform_dict_match_the_scenario(year): + cars = [HOLDER, {}] + from_scenario = Simulation( + situation=situation(year, cars), scenario=company_car_tax_rise_2030 + ) + from_dict = Simulation( + situation=situation(year, cars), reform=COMPANY_CAR_TAX_RISE_2030 + ) + for variable in ["company_car_appropriate_percentage", "income_tax", "gov_tax"]: + np.testing.assert_allclose( + values(from_dict, variable, year), + values(from_scenario, variable, year), + atol=1e-6, + err_msg=variable, + ) + + +INCIDENCE = "gov.contrib.policyengine.employer_ni" + + +def test_no_household_bears_the_class_1a_on_the_2030_31_rise(): + # With half of an employer NI change borne by employees, the rest would + # go to capital and consumers through adjusted_employer_cost less + # baseline_employer_cost. Neither covers Class 1A, so the rise's Class 1A + # moves no pay and leaves nothing for those channels to spread. + reform = { + **COMPANY_CAR_TAX_RISE_2030, + f"{INCIDENCE}.employee_incidence": {"2030-04-06.2100-12-31": 0.5}, + } + simulation = Simulation(situation=situation(2030, [HOLDER]), reform=reform) + class_1a_change = values(simulation, "ni_class_1a", 2030) - values( + simulation.baseline, "ni_class_1a", 2030 + ) + assert class_1a_change[0] > 0 + for variable in ["employer_ni_fixed_employer_cost_change", "employment_income"]: + np.testing.assert_allclose( + values(simulation, variable, 2030), + values(simulation.baseline, variable, 2030), + atol=1e-6, + err_msg=variable, + ) + np.testing.assert_allclose( + values(simulation, "adjusted_employer_cost", 2030), + values(simulation, "baseline_employer_cost", 2030), + atol=0.01, + ) diff --git a/policyengine_uk/utils/company_car.py b/policyengine_uk/utils/company_car.py new file mode 100644 index 0000000000..0bc876ffc3 --- /dev/null +++ b/policyengine_uk/utils/company_car.py @@ -0,0 +1,27 @@ +"""Inputs of the company car and car fuel benefits, as the formulas read them.""" + +from policyengine_core.model_api import max_, min_, where +import numpy as np + + +def co2_emissions_figure(person, period): + """The company car's CO2 emissions figure for ITEPA 2003 s. 139. + + Rounded down to a whole number (s. 139(2)(a)). A car of the ELECTRIC + fuel type (electric or other zero emission) is taken to have a figure of + 0 whatever CO2 figure is entered, as for vehicle excise duty, so a car is + zero-emission for both the appropriate percentage and the car fuel + benefit (s. 149(4)) exactly when this is 0. + """ + fuel_type = person("company_car_fuel_type", period) + co2 = np.floor(max_(person("company_car_co2_emissions", period), 0)) + return where(fuel_type == fuel_type.possible_values.ELECTRIC, 0, co2) + + +def share_of_year_available(person, period): + """The share of the tax year the company car is available, from 0 to 1. + + Both benefits are reduced in proportion to the days the car is + unavailable (ITEPA 2003 ss. 143(3) and 152(1)). + """ + return min_(max_(person("company_car_availability", period), 0), 1) diff --git a/policyengine_uk/utils/pensions.py b/policyengine_uk/utils/pensions.py index be14ef3e7c..ea9ef772a3 100644 --- a/policyengine_uk/utils/pensions.py +++ b/policyengine_uk/utils/pensions.py @@ -27,9 +27,10 @@ def relevant_uk_earnings(person, period, hmrc): """FA 2004 s.189(2) relevant UK earnings. Employment income chargeable to income tax is net taxable earnings - (ITEPA 2003 ss.9(2) and 11): pay and employer-paid taxable SSP, SMP and - SPP (employment_benefits), which the model holds separately from wages, - less the allowable expenses in s.327(3). s.327(5) also lists the deductions for pension contributions + (ITEPA 2003 ss.9(2) and 11): pay, employer-paid taxable SSP, SMP and + SPP (employment_benefits) and taxable benefits in kind (benefits_in_kind, + HMRC PTM044100), which the model holds separately from wages, less the + allowable expenses in s.327(3). s.327(5) also lists the deductions for pension contributions (FA 2004 ss.188-194), but those are the relief that these earnings limit, so they are not taken off; the limit would otherwise depend on itself. Trading income is the profit chargeable under ITTOIA 2005 Part 2, before diff --git a/policyengine_uk/utils/student_loans.py b/policyengine_uk/utils/student_loans.py new file mode 100644 index 0000000000..845850f0ac --- /dev/null +++ b/policyengine_uk/utils/student_loans.py @@ -0,0 +1,24 @@ +"""The income on which student loan repayments and interest are worked out.""" + +from policyengine_core.model_api import max_, min_ + + +def student_loan_income(person, period): + """Net income less the benefits in kind it holds. + + Benefits in kind are not repayment income: Self Assessment leaves out + the car benefits of ITEPA 2003 Part 3 Chapter 6 (SI 2009/470 reg. + 29(4)(e)), and PAYE deducts repayments from Class 1 earnings only + (reg. 41). Plan 2 interest income is the same income (reg. 21A(11)). + + Allowable deductions come off pay and benefits together (ITEPA 2003 + s. 11), so where they exceed pay, taxable employment income holds only + part of the benefits. Taxable employment income is the pay and benefits + less deductions, floored at zero, so it holds the smaller of itself and + the benefits: only that much comes off. + """ + benefits_in_net_income = min_( + person("taxable_employment_income", period), + person("benefits_in_kind", period), + ) + return max_(person("net_income", period) - benefits_in_net_income, 0) diff --git a/policyengine_uk/variables/contrib/policyengine/employer_ni/employer_cost.py b/policyengine_uk/variables/contrib/policyengine/employer_ni/employer_cost.py index 98ca7b95ea..659dbacdf6 100644 --- a/policyengine_uk/variables/contrib/policyengine/employer_ni/employer_cost.py +++ b/policyengine_uk/variables/contrib/policyengine/employer_ni/employer_cost.py @@ -3,6 +3,14 @@ class employer_cost(Variable): label = "employer cost" + documentation = ( + "Pay, statutory sick, maternity and paternity pay, employer pension " + "contributions and the secondary Class 1 contributions on them. " + "Benefits in kind and the Class 1A contributions on them are left " + "out, as baseline_employer_cost and adjusted_employer_cost leave " + "them out, so a fixed-employer-cost response to an employer NI " + "reform holds this cost." + ) entity = Person definition_period = YEAR value_type = float @@ -20,7 +28,7 @@ def formula(person, period, parameters): ) return ( person("employment_income", period) - + person("ni_employer", period) + + person("ni_class_1_employer", period) + person("employer_pension_contributions", period) + benefits ) diff --git a/policyengine_uk/variables/gov/dwp/housing_benefit/applicable_income/_net_earnings.py b/policyengine_uk/variables/gov/dwp/housing_benefit/applicable_income/_net_earnings.py index 993bfd0a45..82088a86be 100644 --- a/policyengine_uk/variables/gov/dwp/housing_benefit/applicable_income/_net_earnings.py +++ b/policyengine_uk/variables/gov/dwp/housing_benefit/applicable_income/_net_earnings.py @@ -40,7 +40,10 @@ def person_net_earnings( The existing tax-attribution approximation uses earnings' share of an explicit raw income base including statutory pay, before losses, and tax before the Winter Fuel Payment charge. This is independent of the income - tax definition of total_income and its component list. Housing Benefit + tax definition of total_income and its component list. Benefits in kind + are not earnings (reg 35(2)(a)), but PAYE collects the tax on them from + the employment's pay, so they count with earnings in that share and in + the base, though not in the earnings themselves. Housing Benefit (housing_benefit_net_earnings), Council Tax Reduction (council_tax_reduction_net_earnings) and Income Support (income_support_net_earnings) use these deductions. @@ -73,10 +76,14 @@ def person_net_earnings( "taxable_miscellaneous_income", ] ) + # Benefits in kind are taxed with the pay but are not earnings. + benefits_in_kind = person("benefits_in_kind", period) + income_before_losses = income_before_losses + benefits_in_kind + taxed_with_earnings = earnings + benefits_in_kind earnings_share = np.divide( - earnings, + taxed_with_earnings, income_before_losses, - out=np.zeros_like(earnings), + out=np.zeros_like(taxed_with_earnings), where=income_before_losses > 0, ) # Tax before the winter fuel payment charge: the charge recovers a diff --git a/policyengine_uk/variables/gov/hmrc/income_tax/bases/taxable_employment_income.py b/policyengine_uk/variables/gov/hmrc/income_tax/bases/taxable_employment_income.py index cb82e8af7f..44e95a173d 100644 --- a/policyengine_uk/variables/gov/hmrc/income_tax/bases/taxable_employment_income.py +++ b/policyengine_uk/variables/gov/hmrc/income_tax/bases/taxable_employment_income.py @@ -16,4 +16,8 @@ def formula(person, period, parameters): taxable_earnings = person("employment_income", period) deductions = add(person, period, ["employment_deductions"]) benefits = person("employment_benefits", period) - return max_(0, taxable_earnings + benefits - deductions) + # Benefits code earnings (ITEPA 2003 s. 63), held apart from pay and + # statutory pay because Class 1 NICs and the means tests' earnings + # leave them out. + benefits_in_kind = person("benefits_in_kind", period) + return max_(0, taxable_earnings + benefits + benefits_in_kind - deductions) diff --git a/policyengine_uk/variables/gov/hmrc/income_tax/benefits_in_kind/benefits_in_kind.py b/policyengine_uk/variables/gov/hmrc/income_tax/benefits_in_kind/benefits_in_kind.py new file mode 100644 index 0000000000..355ce17718 --- /dev/null +++ b/policyengine_uk/variables/gov/hmrc/income_tax/benefits_in_kind/benefits_in_kind.py @@ -0,0 +1,41 @@ +from policyengine_uk.model_api import * + + +class benefits_in_kind(Variable): + value_type = float + entity = Person + label = "Taxable benefits in kind" + documentation = ( + "Benefits the person's employment provides that the benefits code " + "(ITEPA 2003 s. 63) treats as earnings: the company car and car " + "fuel benefits. Income tax charges them through " + "taxable_employment_income, and employers pay Class 1A NICs on them. " + "They are not earnings for Class 1 NICs, nor for the earnings tests " + "of Universal Credit (UC Regulations 2013 reg. 55(2)(a)), Housing " + "Benefit (HB Regulations 2006 reg. 35(2)(a)) and Council Tax " + "Reduction, so they are kept out of employment_income and " + "employment_benefits; those tests do deduct the income tax on them. " + "Student loan repayments and the Plan 2 interest rate leave them " + "out too (SI 2009/470 regs. 29(4)(e) and 41). Other benefits in kind " + "and vans are not modelled." + ) + definition_period = YEAR + unit = GBP + reference = [ + dict( + title="Income Tax (Earnings and Pensions) Act 2003 s. 63 (the benefits code)", + href="https://www.legislation.gov.uk/ukpga/2003/1/section/63", + ), + dict( + title="Universal Credit Regulations 2013 reg. 55(2)(a)", + href="https://www.legislation.gov.uk/uksi/2013/376/regulation/55", + ), + dict( + title="Housing Benefit Regulations 2006 reg. 35(2)(a)", + href="https://www.legislation.gov.uk/uksi/2006/213/regulation/35", + ), + ] + adds = [ + "company_car_benefit", + "car_fuel_benefit", + ] diff --git a/policyengine_uk/variables/gov/hmrc/income_tax/benefits_in_kind/car_fuel_benefit.py b/policyengine_uk/variables/gov/hmrc/income_tax/benefits_in_kind/car_fuel_benefit.py new file mode 100644 index 0000000000..285bc3723f --- /dev/null +++ b/policyengine_uk/variables/gov/hmrc/income_tax/benefits_in_kind/car_fuel_benefit.py @@ -0,0 +1,52 @@ +from policyengine_uk.model_api import * +from policyengine_uk.utils.company_car import ( + co2_emissions_figure, + share_of_year_available, +) + + +class car_fuel_benefit(Variable): + value_type = float + entity = Person + label = "Car fuel benefit" + documentation = ( + "The cash equivalent of fuel provided for private use of the " + "person's company car, treated as earnings from their employment " + "(ITEPA 2003 s. 149): the car's appropriate percentage of the car " + "fuel benefit charge multiplier (s. 150), reduced in proportion to " + "the days the car is unavailable (s. 152(1)). It is nil where the " + "person makes good the whole cost of private fuel (s. 151), and for " + "a car that cannot emit CO2, whose energy is not fuel (s. 149(4)). " + "Payments for private use and capital contributions do not reduce " + "it. Calculated from 2020-21." + ) + definition_period = YEAR + unit = GBP + defined_for = "has_company_car" + reference = [ + dict( + title="Income Tax (Earnings and Pensions) Act 2003 s. 149", + href="https://www.legislation.gov.uk/ukpga/2003/1/section/149", + ), + dict( + title="Income Tax (Earnings and Pensions) Act 2003 s. 150", + href="https://www.legislation.gov.uk/ukpga/2003/1/section/150", + ), + dict( + title="Income Tax (Earnings and Pensions) Act 2003 s. 152", + href="https://www.legislation.gov.uk/ukpga/2003/1/section/152", + ), + dict( + title="HMRC 480 Chapter 13: taxable fuel provided for company cars and vans", + href="https://www.gov.uk/guidance/taxable-fuel-provided-for-company-cars-and-vans-480-chapter-13", + ), + ] + + def formula_2020(person, period, parameters): + p = parameters(period).gov.hmrc.income_tax.benefits_in_kind.car_fuel + fuel_provided = person("company_car_private_fuel_provided", period) + # s. 149(4): the same test as the zero-emission rate in s. 139. + can_emit_co2 = co2_emissions_figure(person, period) > 0 + full_year = p.multiplier * person("company_car_appropriate_percentage", period) + availability = share_of_year_available(person, period) + return fuel_provided * can_emit_co2 * full_year * availability diff --git a/policyengine_uk/variables/gov/hmrc/income_tax/benefits_in_kind/company_car_appropriate_percentage.py b/policyengine_uk/variables/gov/hmrc/income_tax/benefits_in_kind/company_car_appropriate_percentage.py new file mode 100644 index 0000000000..bb9b07b21d --- /dev/null +++ b/policyengine_uk/variables/gov/hmrc/income_tax/benefits_in_kind/company_car_appropriate_percentage.py @@ -0,0 +1,97 @@ +from policyengine_uk.model_api import * +from policyengine_uk.utils.company_car import co2_emissions_figure + + +class company_car_appropriate_percentage(Variable): + value_type = float + entity = Person + label = "Appropriate percentage of the person's company car" + documentation = ( + "The share of the company car's price taxed each year as its " + "benefit, which the car fuel benefit also uses (ITEPA 2003 s. 139). " + "A car emitting 0 g/km takes the zero-emission rate, one emitting 1 " + "to 50 g/km a rate by its electric range, and one emitting 51 to " + "74 g/km a rate from the table. From 75 g/km the rate is the base " + "rate plus one point for each full 5 g/km above 75, up to the " + "maximum. A car of the ELECTRIC fuel type is taken to emit 0 g/km. " + "A diesel car not meeting the Euro 6d (RDE2) standard adds the " + "diesel supplement, within the maximum (s. 141). In 2020-21 and " + "2021-22 a car first registered on or after 6 April 2020 takes the " + "s. 139A rates. Zero for a person without a company car. Cars " + "without a CO2 emissions figure (s. 140) and cars first registered " + "before 1 January 1998 (s. 142) are not modelled. Calculated from " + "2020-21." + ) + definition_period = YEAR + unit = "/1" + defined_for = "has_company_car" + reference = [ + dict( + title="Income Tax (Earnings and Pensions) Act 2003 s. 139", + href="https://www.legislation.gov.uk/ukpga/2003/1/section/139", + ), + dict( + title="Income Tax (Earnings and Pensions) Act 2003 s. 141", + href="https://www.legislation.gov.uk/ukpga/2003/1/section/141", + ), + dict( + title="Finance Act 2020 ss. 9 and 10 (s. 139A for 2020-21 and 2021-22)", + href="https://www.legislation.gov.uk/ukpga/2020/14/section/9/enacted", + ), + ] + + def formula_2020(person, period, parameters): + p = parameters( + period + ).gov.hmrc.income_tax.benefits_in_kind.company_car.appropriate_percentage + # s. 139(2): the CO2 emissions figure is rounded down to a whole + # number and the electric range figure up. + co2 = co2_emissions_figure(person, period) + electric_range = np.ceil(max_(person("company_car_electric_range", period), 0)) + from_april_2020 = p.registered_from_6_april_2020 + takes_s139a_rates = from_april_2020.in_effect & person( + "company_car_registered_from_6_april_2020", period + ) + electric_range_rate = where( + takes_s139a_rates, + from_april_2020.electric_range.calc(electric_range), + p.electric_range.calc(electric_range), + ) + co2_band_rate = where( + takes_s139a_rates, + from_april_2020.co2_band.calc(co2), + p.co2_band.calc(co2), + ) + # s. 139(3) and (4): from the threshold, the base rate plus the + # increment for each full step above it, up to the maximum. + graduated = p.graduated + base_rate = where( + takes_s139a_rates, + from_april_2020.graduated_base_rate, + graduated.base_rate, + ) + steps = np.floor((co2 - graduated.threshold) / graduated.step) + graduated_rate = min_( + base_rate + graduated.increment * max_(steps, 0), p.maximum + ) + # Finance Act 2020 ss. 9(2)(a) and 10(2)(a) give the s. 139 table the + # s. 139A rate for 0 g/km, so both schedules use the one + # zero-emission rate. + zero_emission = co2 == 0 + rate = select( + [ + zero_emission, + co2 <= p.electric_range_co2_limit, + co2 < graduated.threshold, + ], + [p.zero_emission, electric_range_rate, co2_band_rate], + default=graduated_rate, + ) + # s. 141: a diesel car not meeting the Euro 6d standard adds the + # supplement, up to the maximum. A car that cannot emit CO2 is not + # propelled by diesel (s. 141(3)). + fuel_type = person("company_car_fuel_type", period) + diesel = (fuel_type == fuel_type.possible_values.DIESEL_NON_RDE2) & ~( + zero_emission + ) + return where(diesel, min_(rate + p.diesel_supplement, p.maximum), rate) diff --git a/policyengine_uk/variables/gov/hmrc/income_tax/benefits_in_kind/company_car_benefit.py b/policyengine_uk/variables/gov/hmrc/income_tax/benefits_in_kind/company_car_benefit.py new file mode 100644 index 0000000000..68663af5d7 --- /dev/null +++ b/policyengine_uk/variables/gov/hmrc/income_tax/benefits_in_kind/company_car_benefit.py @@ -0,0 +1,55 @@ +from policyengine_uk.model_api import * +from policyengine_uk.utils.company_car import share_of_year_available + + +class company_car_benefit(Variable): + value_type = float + entity = Person + label = "Company car benefit" + documentation = ( + "The cash equivalent of the benefit of the person's company car, " + "treated as earnings from their employment (ITEPA 2003 s. 120), " + "following the steps of s. 121(1): the price of the car and its " + "accessories, less capital contributions up to the cap (s. 132), " + "times the appropriate percentage, reduced in proportion to the " + "days the car is unavailable (s. 143), less payments for private " + "use, and nil if those payments are at least that amount (s. 144). " + "Not modelled: optional remuneration arrangements (s. 120A), " + "classic cars (s. 147), shared and pool cars (ss. 148 and 167), and " + "vans (s. 154 onwards). Calculated from 2020-21." + ) + definition_period = YEAR + unit = GBP + defined_for = "has_company_car" + reference = [ + dict( + title="Income Tax (Earnings and Pensions) Act 2003 s. 120", + href="https://www.legislation.gov.uk/ukpga/2003/1/section/120", + ), + dict( + title="Income Tax (Earnings and Pensions) Act 2003 s. 121", + href="https://www.legislation.gov.uk/ukpga/2003/1/section/121", + ), + dict( + title="HMRC 480 Chapter 12: how to work out the benefit of a company car", + href="https://www.gov.uk/guidance/how-to-work-out-the-benefit-of-a-company-car-480-chapter-12", + ), + ] + + def formula_2020(person, period, parameters): + p = parameters(period).gov.hmrc.income_tax.benefits_in_kind.company_car + # Steps 1 and 2: the price of the car and its accessories. + price = max_(person("company_car_list_price", period), 0) + # Step 3: capital contributions, up to the cap (s. 132(3)). + contributions = min_( + max_(person("company_car_capital_contributions", period), 0), + p.capital_contribution_cap, + ) + interim_sum = max_(price - contributions, 0) + # Steps 5 and 6: the appropriate percentage of the interim sum. + full_year = interim_sum * person("company_car_appropriate_percentage", period) + # Step 7: s. 143(3) deducts A x U / Y for the days unavailable. + provisional_sum = full_year * share_of_year_available(person, period) + # Step 8: payments for private use (s. 144). + payments = max_(person("company_car_private_use_payments", period), 0) + return max_(provisional_sum - payments, 0) diff --git a/policyengine_uk/variables/gov/hmrc/income_tax/benefits_in_kind/has_company_car.py b/policyengine_uk/variables/gov/hmrc/income_tax/benefits_in_kind/has_company_car.py new file mode 100644 index 0000000000..fa79a93491 --- /dev/null +++ b/policyengine_uk/variables/gov/hmrc/income_tax/benefits_in_kind/has_company_car.py @@ -0,0 +1,21 @@ +from policyengine_uk.model_api import * + + +class has_company_car(Variable): + value_type = bool + entity = Person + label = "Has a company car" + documentation = ( + "Whether the person has a company car available for private use, " + "which the model takes from a positive company_car_list_price. The " + "appropriate percentage and the company car and car fuel benefits " + "are zero without one." + ) + definition_period = YEAR + reference = dict( + title="Income Tax (Earnings and Pensions) Act 2003 s. 114", + href="https://www.legislation.gov.uk/ukpga/2003/1/section/114", + ) + + def formula(person, period, parameters): + return person("company_car_list_price", period) > 0 diff --git a/policyengine_uk/variables/gov/hmrc/national_insurance/class_1a/ni_class_1a.py b/policyengine_uk/variables/gov/hmrc/national_insurance/class_1a/ni_class_1a.py new file mode 100644 index 0000000000..e66484baf7 --- /dev/null +++ b/policyengine_uk/variables/gov/hmrc/national_insurance/class_1a/ni_class_1a.py @@ -0,0 +1,41 @@ +from policyengine_uk.model_api import * + + +class ni_class_1a(Variable): + value_type = float + entity = Person + label = "NI Class 1A contributions" + documentation = ( + "Class 1A contributions the employer pays on the person's taxable " + "benefits in kind, which Class 1 leaves out of earnings (SSCBA 1992 " + "s. 10(1) and (4)). The Class 1A percentage equals the secondary " + "Class 1 percentage for the year (s. 10(5)), except in 2022-23, when " + "the Health and Social Care Levy (Repeal) Act 2022 fixes it at " + "14.53%. Unlike secondary Class 1, it has no threshold and no zero " + "rate for earners under 21 or apprentices under 25, and the " + "Employment Allowance cannot be set against it. The employer NI " + "incidence variables cover secondary Class 1 only, so no household " + "bears Class 1A or a change in it: it stays with the employer as " + "revenue in gov_tax." + ) + definition_period = YEAR + unit = GBP + reference = [ + dict( + title="Social Security Contributions and Benefits Act 1992 s. 10", + href="https://www.legislation.gov.uk/ukpga/1992/4/section/10", + ), + dict( + title="Health and Social Care Levy (Repeal) Act 2022 Schedule paragraph 1", + href="https://www.legislation.gov.uk/ukpga/2022/43/schedule/paragraph/1/enacted", + ), + ] + + def formula(person, period, parameters): + ni = parameters(period).gov.hmrc.national_insurance + fixed = ni.class_1a.percentage_2022_23 + if fixed.in_effect: + rate = fixed.rate + else: + rate = ni.class_1.employer_scale.components[1].rate + return rate * person("benefits_in_kind", period) diff --git a/policyengine_uk/variables/gov/hmrc/national_insurance/ni_employer.py b/policyengine_uk/variables/gov/hmrc/national_insurance/ni_employer.py index 063dc1e014..073b87e60e 100644 --- a/policyengine_uk/variables/gov/hmrc/national_insurance/ni_employer.py +++ b/policyengine_uk/variables/gov/hmrc/national_insurance/ni_employer.py @@ -5,8 +5,13 @@ class ni_employer(Variable): value_type = float entity = Person label = "employer-side National Insurance" + documentation = ( + "Secondary Class 1 contributions on the person's earnings and Class " + "1A contributions on their benefits in kind." + ) definition_period = YEAR unit = GBP adds = [ "ni_class_1_employer", + "ni_class_1a", ] diff --git a/policyengine_uk/variables/gov/hmrc/national_insurance/total_national_insurance.py b/policyengine_uk/variables/gov/hmrc/national_insurance/total_national_insurance.py index e972224314..8e28743a1d 100644 --- a/policyengine_uk/variables/gov/hmrc/national_insurance/total_national_insurance.py +++ b/policyengine_uk/variables/gov/hmrc/national_insurance/total_national_insurance.py @@ -10,5 +10,5 @@ class total_national_insurance(Variable): unit = GBP adds = [ "national_insurance", - "ni_class_1_employer", + "ni_employer", ] diff --git a/policyengine_uk/variables/gov/hmrc/pensions/pension_contributions_relief.py b/policyengine_uk/variables/gov/hmrc/pensions/pension_contributions_relief.py index 3ba60f7cd9..a048506d79 100644 --- a/policyengine_uk/variables/gov/hmrc/pensions/pension_contributions_relief.py +++ b/policyengine_uk/variables/gov/hmrc/pensions/pension_contributions_relief.py @@ -18,7 +18,8 @@ class pension_contributions_relief(Variable): "contributions as relief at source and employee contributions as a " "net pay arrangement. The annual allowance does not limit relief. " "Relevant UK earnings (s. 189(2)) are employment income, including " - "employer-paid taxable statutory pay, less allowable expenses but " + "employer-paid taxable statutory pay and taxable benefits in kind, " + "less allowable expenses but " "before pension deductions, and trading profits after capital " "allowances and the trading allowance but before losses. " "Contributions above it can be relieved here and separately attract " diff --git a/policyengine_uk/variables/gov/hmrc/student_loans/plan_2_interest_rate.py b/policyengine_uk/variables/gov/hmrc/student_loans/plan_2_interest_rate.py index ec5a2f2b5e..709ed627cd 100644 --- a/policyengine_uk/variables/gov/hmrc/student_loans/plan_2_interest_rate.py +++ b/policyengine_uk/variables/gov/hmrc/student_loans/plan_2_interest_rate.py @@ -1,4 +1,5 @@ from policyengine_uk.model_api import * +from policyengine_uk.utils.student_loans import student_loan_income import numpy as np @@ -16,7 +17,9 @@ class plan_2_interest_rate(Variable): reference = "https://www.legislation.gov.uk/uksi/2012/1309/regulation/10" def formula(person, period, parameters): - income = person("net_income", period) + # Interest income is the repayment income (SI 2009/470 reg. 21A(11)), + # which leaves out benefits in kind (regs. 29(4)(e) and 41). + income = student_loan_income(person, period) p = parameters(period).gov.hmrc.student_loans rpi = parameters(period).gov.economic_assumptions.yoy_growth.obr.rpi diff --git a/policyengine_uk/variables/gov/hmrc/student_loans/student_loan_repayment.py b/policyengine_uk/variables/gov/hmrc/student_loans/student_loan_repayment.py index f086a65126..cd24f7df64 100644 --- a/policyengine_uk/variables/gov/hmrc/student_loans/student_loan_repayment.py +++ b/policyengine_uk/variables/gov/hmrc/student_loans/student_loan_repayment.py @@ -1,4 +1,5 @@ from policyengine_uk.model_api import * +from policyengine_uk.utils.student_loans import student_loan_income from policyengine_uk.variables.gov.hmrc.student_loans.student_loan_plan import ( StudentLoanPlan, ) @@ -19,7 +20,8 @@ class student_loan_repayment(Variable): def formula(person, period, parameters): plan = person("student_loan_plan", period) - income = person("net_income", period) + # Net income less benefits in kind (SI 2009/470 regs. 29(4)(e), 41). + income = student_loan_income(person, period) balance = max_(0, person("student_loan_balance", period)) p = parameters(period).gov.hmrc.student_loans diff --git a/policyengine_uk/variables/household/marginal_tax_rate_wrt_employer_cost.py b/policyengine_uk/variables/household/marginal_tax_rate_wrt_employer_cost.py index 5be93cbc6a..dda3336e72 100644 --- a/policyengine_uk/variables/household/marginal_tax_rate_wrt_employer_cost.py +++ b/policyengine_uk/variables/household/marginal_tax_rate_wrt_employer_cost.py @@ -12,8 +12,8 @@ class marginal_tax_rate_wrt_employer_cost(Variable): label = "Marginal tax rate with respect to employer cost" documentation = ( "Percent of a marginal increase in the employer's cost of employment " - "(gross pay plus employer NI, employer pension contributions and " - "statutory sick/maternity/paternity pay) that does not flow to " + "(gross pay plus secondary Class 1 NI, employer pension contributions " + "and statutory sick/maternity/paternity pay) that does not flow to " "household net income. Gross pay rises by " "gov.simulation.marginal_tax_rate_delta, or 0.1% of employment income " "where that is larger, so that float32 rounding stays negligible at any " diff --git a/policyengine_uk/variables/input/company_car/company_car_availability.py b/policyengine_uk/variables/input/company_car/company_car_availability.py new file mode 100644 index 0000000000..f49cd2d09b --- /dev/null +++ b/policyengine_uk/variables/input/company_car/company_car_availability.py @@ -0,0 +1,28 @@ +from policyengine_uk.model_api import * + + +class company_car_availability(Variable): + value_type = float + entity = Person + label = "Share of the tax year the person's company car is available" + documentation = ( + "The share of the tax year's days on which the company car is " + "available to the person: 1 less the share of days on which it is " + "unavailable, which are days before it is first available, after it " + "is last available, and within a period of 30 days or more when it " + "is not available (ITEPA 2003 s. 143(2)). The company car and car " + "fuel benefits are reduced in proportion (ss. 143(3) and 152(1))." + ) + definition_period = YEAR + unit = "/1" + default_value = 1 + reference = [ + dict( + title="Income Tax (Earnings and Pensions) Act 2003 s. 143", + href="https://www.legislation.gov.uk/ukpga/2003/1/section/143", + ), + dict( + title="Income Tax (Earnings and Pensions) Act 2003 s. 152", + href="https://www.legislation.gov.uk/ukpga/2003/1/section/152", + ), + ] diff --git a/policyengine_uk/variables/input/company_car/company_car_capital_contributions.py b/policyengine_uk/variables/input/company_car/company_car_capital_contributions.py new file mode 100644 index 0000000000..bb0b1249a7 --- /dev/null +++ b/policyengine_uk/variables/input/company_car/company_car_capital_contributions.py @@ -0,0 +1,21 @@ +from policyengine_uk.model_api import * + + +class company_car_capital_contributions(Variable): + value_type = float + entity = Person + label = "Capital contributions to the person's company car" + documentation = ( + "Capital sums the person has contributed, in this and earlier tax " + "years, to the cost of their company car and its accessories. The " + "company car benefit deducts them up to the cap " + "(ITEPA 2003 s. 132(3))." + ) + definition_period = YEAR + unit = GBP + uprating = "gov.economic_assumptions.indices.obr.consumer_price_index" + quantity_type = STOCK + reference = dict( + title="Income Tax (Earnings and Pensions) Act 2003 s. 132", + href="https://www.legislation.gov.uk/ukpga/2003/1/section/132", + ) diff --git a/policyengine_uk/variables/input/company_car/company_car_co2_emissions.py b/policyengine_uk/variables/input/company_car/company_car_co2_emissions.py new file mode 100644 index 0000000000..f73a2b76ae --- /dev/null +++ b/policyengine_uk/variables/input/company_car/company_car_co2_emissions.py @@ -0,0 +1,32 @@ +from policyengine_uk.model_api import * + + +class company_car_co2_emissions(Variable): + value_type = float + entity = Person + label = "CO2 emissions figure of the person's company car" + documentation = ( + "The CO2 emissions figure of the person's company car in grams per " + "kilometre, as on its certificate of conformity: 0 for a car that " + "cannot emit CO2 by being driven, and taken as 0 for a car of the " + "ELECTRIC fuel type. Set it whenever company_car_list_price is set: " + "the model cannot tell a missing figure from 0 g/km, and taxes both " + "at the zero-emission rate. For a car first registered on or after " + "6 April 2020 it is the WLTP figure (ITEPA 2003 s. 136(2B)). " + "The model treats every company car as having a CO2 emissions " + "figure; cars without one (s. 140) and cars first registered before " + "1 January 1998 (s. 142) are not modelled." + ) + definition_period = YEAR + unit = "g/km" + quantity_type = STOCK + reference = [ + dict( + title="Income Tax (Earnings and Pensions) Act 2003 s. 136", + href="https://www.legislation.gov.uk/ukpga/2003/1/section/136", + ), + dict( + title="Income Tax (Earnings and Pensions) Act 2003 s. 139", + href="https://www.legislation.gov.uk/ukpga/2003/1/section/139", + ), + ] diff --git a/policyengine_uk/variables/input/company_car/company_car_electric_range.py b/policyengine_uk/variables/input/company_car/company_car_electric_range.py new file mode 100644 index 0000000000..a8c8a0f696 --- /dev/null +++ b/policyengine_uk/variables/input/company_car/company_car_electric_range.py @@ -0,0 +1,20 @@ +from policyengine_uk.model_api import * + + +class company_car_electric_range(Variable): + value_type = float + entity = Person + label = "Electric range figure of the person's company car" + documentation = ( + "The distance in miles the person's company car can be driven in " + "electric mode without recharging, as on its certificate of " + "conformity (ITEPA 2003 s. 139(5)). Only cars with a CO2 emissions " + "figure of 1 to 50 g/km use it, and only to 2027-28." + ) + definition_period = YEAR + unit = "mile" + quantity_type = STOCK + reference = dict( + title="Income Tax (Earnings and Pensions) Act 2003 s. 139", + href="https://www.legislation.gov.uk/ukpga/2003/1/section/139", + ) diff --git a/policyengine_uk/variables/input/company_car/company_car_fuel_type.py b/policyengine_uk/variables/input/company_car/company_car_fuel_type.py new file mode 100644 index 0000000000..7398bbd5a9 --- /dev/null +++ b/policyengine_uk/variables/input/company_car/company_car_fuel_type.py @@ -0,0 +1,20 @@ +from policyengine_uk.model_api import * +from policyengine_uk.variables.input.vehicle.car_fuel_type import CarFuelType + + +class company_car_fuel_type(Variable): + value_type = Enum + possible_values = CarFuelType + default_value = CarFuelType.PETROL + entity = Person + label = "Fuel type of the person's company car" + documentation = ( + "A car propelled solely by diesel that does not meet the Euro 6d " + "(RDE2) emissions standard takes the diesel supplement (ITEPA 2003 " + "s. 141). A diesel hybrid is not propelled solely by diesel." + ) + definition_period = YEAR + reference = dict( + title="Income Tax (Earnings and Pensions) Act 2003 s. 141", + href="https://www.legislation.gov.uk/ukpga/2003/1/section/141", + ) diff --git a/policyengine_uk/variables/input/company_car/company_car_list_price.py b/policyengine_uk/variables/input/company_car/company_car_list_price.py new file mode 100644 index 0000000000..2661d2a73f --- /dev/null +++ b/policyengine_uk/variables/input/company_car/company_car_list_price.py @@ -0,0 +1,33 @@ +from policyengine_uk.model_api import * + + +class company_car_list_price(Variable): + value_type = float + entity = Person + label = "List price of the person's company car, with its accessories" + documentation = ( + "The list price of a car made available to the person by reason of " + "their employment and for their private use, on the day before its " + "first registration, plus the price of its qualifying accessories " + "(ITEPA 2003 s. 121(1) steps 1 and 2). Zero means the person has no " + "company car. Set company_car_co2_emissions with it: a CO2 figure of " + "0 means a car that cannot emit CO2. The benefits it gives must not " + "also be in employment_income, or they are taxed twice; a dataset " + "whose pay includes benefits in kind, as the SPI's EPB does, must take " + "the car and car fuel benefits out of it. This is not car_list_price, " + "which describes the person's own car for vehicle excise duty." + ) + definition_period = YEAR + unit = GBP + uprating = "gov.economic_assumptions.indices.obr.consumer_price_index" + quantity_type = STOCK + reference = [ + dict( + title="Income Tax (Earnings and Pensions) Act 2003 s. 121", + href="https://www.legislation.gov.uk/ukpga/2003/1/section/121", + ), + dict( + title="Income Tax (Earnings and Pensions) Act 2003 s. 123", + href="https://www.legislation.gov.uk/ukpga/2003/1/section/123", + ), + ] diff --git a/policyengine_uk/variables/input/company_car/company_car_private_fuel_provided.py b/policyengine_uk/variables/input/company_car/company_car_private_fuel_provided.py new file mode 100644 index 0000000000..c75c31c2f6 --- /dev/null +++ b/policyengine_uk/variables/input/company_car/company_car_private_fuel_provided.py @@ -0,0 +1,26 @@ +from policyengine_uk.model_api import * + + +class company_car_private_fuel_provided(Variable): + value_type = bool + entity = Person + label = "Fuel provided for private use of the person's company car" + documentation = ( + "Whether fuel is provided for the company car by reason of the " + "person's employment and its cost for private use is not made good " + "in full (ITEPA 2003 ss. 149 and 151). Electricity is not fuel " + "(s. 149(4)). Part-year provision of fuel (s. 152(2)) is not " + "modelled; the car fuel benefit is reduced only for days the car is " + "unavailable." + ) + definition_period = YEAR + reference = [ + dict( + title="Income Tax (Earnings and Pensions) Act 2003 s. 149", + href="https://www.legislation.gov.uk/ukpga/2003/1/section/149", + ), + dict( + title="Income Tax (Earnings and Pensions) Act 2003 s. 151", + href="https://www.legislation.gov.uk/ukpga/2003/1/section/151", + ), + ] diff --git a/policyengine_uk/variables/input/company_car/company_car_private_use_payments.py b/policyengine_uk/variables/input/company_car/company_car_private_use_payments.py new file mode 100644 index 0000000000..82b32647a9 --- /dev/null +++ b/policyengine_uk/variables/input/company_car/company_car_private_use_payments.py @@ -0,0 +1,21 @@ +from policyengine_uk.model_api import * + + +class company_car_private_use_payments(Variable): + value_type = float + entity = Person + label = "Payments for private use of the person's company car" + documentation = ( + "Amounts the person is required to pay, and pays by 6 July after the " + "tax year, as a condition of the company car being available for " + "private use (ITEPA 2003 s. 144). Payments for fuel or insurance are " + "not payments for private use." + ) + definition_period = YEAR + unit = GBP + uprating = "gov.economic_assumptions.indices.obr.consumer_price_index" + quantity_type = FLOW + reference = dict( + title="Income Tax (Earnings and Pensions) Act 2003 s. 144", + href="https://www.legislation.gov.uk/ukpga/2003/1/section/144", + ) diff --git a/policyengine_uk/variables/input/company_car/company_car_registered_from_6_april_2020.py b/policyengine_uk/variables/input/company_car/company_car_registered_from_6_april_2020.py new file mode 100644 index 0000000000..7ba9c394e3 --- /dev/null +++ b/policyengine_uk/variables/input/company_car/company_car_registered_from_6_april_2020.py @@ -0,0 +1,24 @@ +from policyengine_uk.model_api import * + + +class company_car_registered_from_6_april_2020(Variable): + value_type = bool + entity = Person + label = "Company car first registered on or after 6 April 2020" + documentation = ( + "In 2020-21 and 2021-22 a car first registered on or after 6 April " + "2020 has lower appropriate percentages (ITEPA 2003 s. 139A, " + "inserted for each year by Finance Act 2020 ss. 9 and 10). From " + "2022-23 every car takes the same rates and this has no effect." + ) + definition_period = YEAR + reference = [ + dict( + title="Finance Act 2020 s. 9", + href="https://www.legislation.gov.uk/ukpga/2020/14/section/9/enacted", + ), + dict( + title="Finance Act 2020 s. 10", + href="https://www.legislation.gov.uk/ukpga/2020/14/section/10/enacted", + ), + ]