diff --git a/changelog.d/1887.fixed.md b/changelog.d/1887.fixed.md new file mode 100644 index 0000000000..34002dea94 --- /dev/null +++ b/changelog.d/1887.fixed.md @@ -0,0 +1 @@ +- Fix Class 2 National Insurance for 2015-16 to 2023-24 against s.11 SSCBA 1992: charge £3.45 a week in 2023-24; from 2022-23 charge only profits above the Class 2 lower profits threshold (£11,908, then £12,570), with profits from the small profits threshold up to it treated as paid; keep the small profits threshold at £6,725 in 2023-24 and 2024-25 and correct it to £5,965 in 2015-16 and 2016-17; date the abolition 6 April 2024. Class 2 now tests its thresholds on the profits Class 4 is charged on (s.11(3)), after capital allowances, the trading allowance and loss relief, not on self-employment income. A full year of Class 2 is every contribution week in it, so 53 weeks in 2019-20. The Universal Credit minimum income floor's notional Class 2 follows the same rule, so it deducts no Class 2 in 2022-23 and 2023-24 on a threshold the lower profits threshold covers. Every value now cites its amending instrument. diff --git a/changelog.d/1968.fixed.md b/changelog.d/1968.fixed.md new file mode 100644 index 0000000000..7aaf2acabd --- /dev/null +++ b/changelog.d/1968.fixed.md @@ -0,0 +1 @@ +- Fixed Class 4 NICs against s.15 SSCBA 1992: the 2023-24 lower profits limit is £12,570 (it was £11,908), the 2022-23 rates are 9.73% and 2.73% for the whole year (they were 10.25% and 3.5%), the 2023-24 additional rate is 2% (it was 3.5%), and the 2015-16 upper profits limit is £42,385. Every Class 4 limit and rate from 2015-16 to 2025-26 now cites its legal source. diff --git a/docs/book/policy/model-baseline.md b/docs/book/policy/model-baseline.md index 0bbfc62b5a..6b777b0855 100644 --- a/docs/book/policy/model-baseline.md +++ b/docs/book/policy/model-baseline.md @@ -28,7 +28,7 @@ Annual benefit uprating applied 4.1% increases to state pensions and 1.7% to wor ### Autumn Statement 2023 -The government announced further National Insurance cuts, reducing the [employee main rate from 10% to 8%](https://github.com/PolicyEngine/policyengine-uk/blob/master/policyengine_uk/parameters/gov/hmrc/national_insurance/class_1/rates/employee/main.yaml#L24-L29) and the [self-employed Class 4 rate from 9% to 6%](https://github.com/PolicyEngine/policyengine-uk/blob/master/policyengine_uk/parameters/gov/hmrc/national_insurance/class_4/rates/main.yaml#L16-L21) in fiscal year 2024-25. [Class 2 National Insurance contributions were abolished](https://github.com/PolicyEngine/policyengine-uk/blob/master/policyengine_uk/parameters/gov/hmrc/national_insurance/class_2/flat_rate.yaml#L14-L19) for self-employed people, with the flat rate set to £0 in fiscal year 2024-25. +The government announced further National Insurance cuts, reducing the [employee main rate from 10% to 8%](https://github.com/PolicyEngine/policyengine-uk/blob/master/policyengine_uk/parameters/gov/hmrc/national_insurance/class_1/rates/employee/main.yaml#L24-L29) and the [self-employed Class 4 rate from 9% to 6%](https://github.com/PolicyEngine/policyengine-uk/blob/master/policyengine_uk/parameters/gov/hmrc/national_insurance/class_4/rates/main.yaml#L26-L33) in fiscal year 2024-25. [Class 2 National Insurance contributions were abolished](https://github.com/PolicyEngine/policyengine-uk/blob/master/policyengine_uk/parameters/gov/hmrc/national_insurance/class_2/flat_rate.yaml#L51-L56) for self-employed people, with the flat rate set to £0 in fiscal year 2024-25. ### Capital gains tax changes (Autumn Budget 2024) diff --git a/docs/book/programs/gov/hmrc/national-insurance.ipynb b/docs/book/programs/gov/hmrc/national-insurance.ipynb index 9b15f48f22..c64696002a 100644 --- a/docs/book/programs/gov/hmrc/national-insurance.ipynb +++ b/docs/book/programs/gov/hmrc/national-insurance.ipynb @@ -20,7 +20,7 @@ "NI has four main classes:\n", "\n", "- **Class 1**: Paid by employees and their employers. This is based on the employee's earnings and is deducted directly from wages.\n", - "- **Class 2**: Paid by self-employed people with profits above a certain threshold.\n", + "- **Class 2**: A flat weekly contribution paid by self-employed people with profits above a certain threshold. It stopped being compulsory on 6 April 2024.\n", "- **Class 3**: Voluntary contributions, often made by people who want to fill gaps in their National Insurance record.\n", "- **Class 4**: Paid by self-employed people with profits above a certain threshold (in addition to Class 2 NICs before April 2024)." ] @@ -56,78 +56,8 @@ "execution_count": 1, "metadata": {}, "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
ClassMethodology & BasisThresholds & LimitsRate ApplicationReference
0Class 1Based on employment income. \\n- Monthly and an...Primary Threshold, Upper Earnings LimitMain and Additional ratesSocial Security Contributions and Benefits Act...
1Class 2Based on self-employment income. \\n- Weekly fl...Small Profits ThresholdFlat rateSocial Security Contributions and Benefits Act...
2Class 3Voluntary contributions for those filling gaps...None (voluntary)Flat rateSocial Security Contributions and Benefits Act...
3Class 4Based on self-employment profits. \\n- Annual m...Lower Profits Limit, Upper Profits LimitMain and Additional ratesSocial Security Contributions and Benefits Act...
\n", - "
" - ], - "text/plain": [ - " Class ... Reference\n", - "0 Class 1 ... Social Security Contributions and Benefits Act...\n", - "1 Class 2 ... Social Security Contributions and Benefits Act...\n", - "2 Class 3 ... Social Security Contributions and Benefits Act...\n", - "3 Class 4 ... Social Security Contributions and Benefits Act...\n", - "\n", - "[4 rows x 5 columns]" - ] + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
ClassMethodology & BasisThresholds & LimitsRate ApplicationReference
0Class 1Based on employment income. \\n- Monthly and an...Primary Threshold, Upper Earnings LimitMain and Additional ratesSocial Security Contributions and Benefits Act...
1Class 2Based on self-employment income. \\n- Weekly fl...Small Profits Threshold; lower profits thresho...Flat rateSocial Security Contributions and Benefits Act...
2Class 3Voluntary contributions for those filling gaps...None (voluntary)Flat rateSocial Security Contributions and Benefits Act...
3Class 4Based on self-employment profits. \\n- Annual m...Lower Profits Limit, Upper Profits LimitMain and Additional ratesSocial Security Contributions and Benefits Act...
\n
", + "text/plain": " Class Methodology & Basis \\\n0 Class 1 Based on employment income. \\n- Monthly and an... \n1 Class 2 Based on self-employment income. \\n- Weekly fl... \n2 Class 3 Voluntary contributions for those filling gaps... \n3 Class 4 Based on self-employment profits. \\n- Annual m... \n\n Thresholds & Limits \\\n0 Primary Threshold, Upper Earnings Limit \n1 Small Profits Threshold; lower profits thresho... \n2 None (voluntary) \n3 Lower Profits Limit, Upper Profits Limit \n\n Rate Application \\\n0 Main and Additional rates \n1 Flat rate \n2 Flat rate \n3 Main and Additional rates \n\n Reference \n0 Social Security Contributions and Benefits Act... \n1 Social Security Contributions and Benefits Act... \n2 Social Security Contributions and Benefits Act... \n3 Social Security Contributions and Benefits Act... " } } ], @@ -142,11 +72,11 @@ " \"Based on employment income. \\n- Monthly and annual calculations.\",\n", " \"Based on self-employment income. \\n- Weekly flat rate.\",\n", " \"Voluntary contributions for those filling gaps in their NI record. \\n- Weekly flat rate.\",\n", - " \"Based on self-employment profits. \\n- Annual maximum (reg 100) where Class 1 is also paid.\",\n", + " \"Based on self-employment profits. \\n- Annual maximum (reg 100) where Class 1, or before 2024-25 Class 2, is also paid.\",\n", " ],\n", " \"Thresholds & Limits\": [\n", " \"Primary Threshold, Upper Earnings Limit\",\n", - " \"Small Profits Threshold\",\n", + " \"Small Profits Threshold; lower profits threshold (2022-23 and 2023-24)\",\n", " \"None (voluntary)\",\n", " \"Lower Profits Limit, Upper Profits Limit\",\n", " ],\n", @@ -171,7 +101,7 @@ { "cell_type": "markdown", "metadata": {}, - "source": "## How PolicyEngine computes National Insurance liability\n\nFor each person, PolicyEngine computes NI contributions class-by-class:\n\n- **Class 1 employee** (`ni_class_1_employee`): the sum of `ni_class_1_employee_primary` (main rate on earnings between the Primary Threshold and the Upper Earnings Limit) and `ni_class_1_employee_additional` (additional rate on earnings above the UEL). These primary contributions are due from age 16 until state pension age (`ni_liable`): SSCBA 1992 s.6(3) ends them at pensionable age.\n- **Class 1 employer** (`ni_class_1_employer`): paid on earnings above the Secondary Threshold; surfaced through the `ni_employer` variable. These secondary contributions are due on earners over 16 with no upper age limit (`ni_class_1_secondary_liable`), so employers keep paying them for employees over state pension age (SSCBA 1992 s.6(1)(b) and s.6(3)).\n- **Class 2** (`ni_class_2`): a flat weekly rate paid by the self-employed with profits above the Small Profits Threshold.\n- **Class 3** (`ni_class_3`): a voluntary flat weekly rate; the variable is exposed but defaults to zero unless explicitly set.\n- **Class 4** (`ni_class_4`): main rate between the Lower and Upper Profits Limits plus additional rate above the UPL, charged on `ni_class_4_profits`. Those are the trade profits chargeable to income tax under ITTOIA 2005 Part 2 Chapter 2 (`ni_class_4_profits_before_losses`: self-employment profit after capital allowances and the trading allowance), less trading losses as SSCBA 1992 Schedule 2 paragraph 3 allows (`ni_class_4_loss_relief`). A loss reduces only trade profits for Class 4: each year's losses (those brought forward, then the year's own loss, `ni_class_4_trading_loss`) are set against that year's trade profits, and the rest is carried forward until used (`ni_class_4_losses_brought_forward`, `ni_class_4_losses_carried_forward`). A year's own loss is the `trading_loss` entered for that year, so a loss entered once is relieved once: it is not counted again in the later years that `trading_loss` carries into. Carry-back claims and the paragraph 3(5) deductions for trade interest and royalties are not modelled. Where the person also pays primary Class 1 contributions (or, before 6 April 2024, Class 2 contributions), liability is capped at the annual maximum in regulation 100 of the Social Security (Contributions) Regulations 2001 (`ni_class_4_maximum`). Class 4 is due from age 16 until the first tax year that begins on or after the day the person reaches state pension age (`ni_class_4_liable`): regulation 91(a) excepts anyone over pensionable age at the beginning of the tax year, so a person who reaches it during a year pays for that whole year.\n\nThe individual total `national_insurance` sums the four employee and self-employed components directly \u2014 `ni_class_1_employee + ni_class_2 + ni_class_3 + ni_class_4` \u2014 so voluntary Class 3 contributions are included in the household-side liability. The convenience aggregates `ni_employee` (Class 1 employee only) and `ni_self_employed` (Class 2 + Class 4) are also exposed for reporting. The Class 1 *employer* charge (`ni_class_1_employer`, surfaced as `ni_employer`) is an employer-side cost rather than part of the individual's `national_insurance`, so it is tracked separately and feeds the government revenue aggregates on its own.\n\nParameters live in `policyengine_uk/parameters/gov/hmrc/national_insurance/` and the per-class formulas in `policyengine_uk/variables/gov/hmrc/national_insurance/`." + "source": "## How PolicyEngine computes National Insurance liability\n\nFor each person, PolicyEngine computes NI contributions class-by-class:\n\n- **Class 1 employee** (`ni_class_1_employee`): the sum of `ni_class_1_employee_primary` (main rate on earnings between the Primary Threshold and the Upper Earnings Limit) and `ni_class_1_employee_additional` (additional rate on earnings above the UEL). These primary contributions are due from age 16 until state pension age (`ni_liable`): SSCBA 1992 s.6(3) ends them at pensionable age.\n- **Class 1 employer** (`ni_class_1_employer`): paid on earnings above the Secondary Threshold; surfaced through the `ni_employer` variable. These secondary contributions are due on earners over 16 with no upper age limit (`ni_class_1_secondary_liable`), so employers keep paying them for employees over state pension age (SSCBA 1992 s.6(1)(b) and s.6(3)).\n- **Class 2** (`ni_class_2`): a flat weekly rate for the self-employed, for each contribution week in the tax year (53 in 2019-20, otherwise 52 up to 2023-24). Its thresholds apply to relevant profits, which are the profits Class 4 is charged on (`ni_class_4_profits`; SSCBA 1992 s.11(3)). Before 2022-23 it is payable on relevant profits at or above the Small Profits Threshold. In 2022-23 and 2023-24 it is payable only on relevant profits above the Class 2 lower profits threshold; relevant profits from the Small Profits Threshold up to it are treated as paid and cost nothing. Compulsory Class 2 ended on 6 April 2024; voluntary Class 2 is not modelled.\n- **Class 3** (`ni_class_3`): a voluntary flat weekly rate; the variable is exposed but defaults to zero unless explicitly set.\n- **Class 4** (`ni_class_4`): main rate between the Lower and Upper Profits Limits plus additional rate above the UPL, charged on `ni_class_4_profits`. Those are the trade profits chargeable to income tax under ITTOIA 2005 Part 2 Chapter 2 (`ni_class_4_profits_before_losses`: self-employment profit after capital allowances and the trading allowance), less trading losses as SSCBA 1992 Schedule 2 paragraph 3 allows (`ni_class_4_loss_relief`). A loss reduces only trade profits for Class 4: each year's losses (those brought forward, then the year's own loss, `ni_class_4_trading_loss`) are set against that year's trade profits, and the rest is carried forward until used (`ni_class_4_losses_brought_forward`, `ni_class_4_losses_carried_forward`). A year's own loss is the `trading_loss` entered for that year, so a loss entered once is relieved once: it is not counted again in the later years that `trading_loss` carries into. Carry-back claims and the paragraph 3(5) deductions for trade interest and royalties are not modelled. Where the person also pays primary Class 1 contributions (or, before 6 April 2024, Class 2 contributions), liability is capped at the annual maximum in regulation 100 of the Social Security (Contributions) Regulations 2001 (`ni_class_4_maximum`). Class 4 is due from age 16 until the first tax year that begins on or after the day the person reaches state pension age (`ni_class_4_liable`): regulation 91(a) excepts anyone over pensionable age at the beginning of the tax year, so a person who reaches it during a year pays for that whole year.\n\nThe individual total `national_insurance` sums the four employee and self-employed components directly \u2014 `ni_class_1_employee + ni_class_2 + ni_class_3 + ni_class_4` \u2014 so voluntary Class 3 contributions are included in the household-side liability. The convenience aggregates `ni_employee` (Class 1 employee only) and `ni_self_employed` (Class 2 + Class 4) are also exposed for reporting. The Class 1 *employer* charge (`ni_class_1_employer`, surfaced as `ni_employer`) is an employer-side cost rather than part of the individual's `national_insurance`, so it is tracked separately and feeds the government revenue aggregates on its own.\n\nParameters live in `policyengine_uk/parameters/gov/hmrc/national_insurance/` and the per-class formulas in `policyengine_uk/variables/gov/hmrc/national_insurance/`." }, { "cell_type": "markdown", @@ -200,8 +130,8 @@ }, "data": [ { - "hovertemplate": "Label=NI Lower Earnings Limit
Instant=%{x}
Value=%{y}", - "legendgroup": "NI Lower Earnings Limit", + "hovertemplate": "Label=NI lower earnings limit
Instant=%{x}
Value=%{y}", + "legendgroup": "NI lower earnings limit", "line": { "color": "#636efa", "dash": "solid", @@ -211,7 +141,7 @@ "symbol": "circle" }, "mode": "lines", - "name": "NI Lower Earnings Limit", + "name": "NI lower earnings limit", "orientation": "v", "showlegend": true, "type": "scatter", @@ -233,26 +163,26 @@ ], "xaxis": "x", "y": [ - 120, - 120, - 123, - 123, - 123, - 123, - 123, - 123, - 123, - 123, - 123, - 123, - 123, - 123 + 120.0, + 120.0, + 123.0, + 123.0, + 123.0, + 125.0, + 129.0, + 131.57979643487917, + 134.2112670927332, + 136.8951949163344, + 139.63314579122738, + 142.42590266018465, + 145.27424846597842, + 148.17974909415344 ], "yaxis": "y" }, { - "hovertemplate": "Label=NI Primary Threshold
Instant=%{x}
Value=%{y}", - "legendgroup": "NI Primary Threshold", + "hovertemplate": "Label=NI primary threshold
Instant=%{x}
Value=%{y}", + "legendgroup": "NI primary threshold", "line": { "color": "#EF553B", "dash": "solid", @@ -262,7 +192,7 @@ "symbol": "circle" }, "mode": "lines", - "name": "NI Primary Threshold", + "name": "NI primary threshold", "orientation": "v", "showlegend": true, "type": "scatter", @@ -284,9 +214,9 @@ ], "xaxis": "x", "y": [ - 183, - 184, - 190, + 183.0, + 184.0, + 190.0, 241.73, 241.73, 241.73, @@ -295,15 +225,15 @@ 241.73, 241.73, 241.73, - 241.73, - 241.73, - 241.73 + 246.56476264971067, + 251.49575971156867, + 256.52570201408514 ], "yaxis": "y" }, { - "hovertemplate": "Label=NI Upper Earnings Limit
Instant=%{x}
Value=%{y}", - "legendgroup": "NI Upper Earnings Limit", + "hovertemplate": "Label=NI upper earnings limit
Instant=%{x}
Value=%{y}", + "legendgroup": "NI upper earnings limit", "line": { "color": "#00cc96", "dash": "solid", @@ -313,7 +243,7 @@ "symbol": "circle" }, "mode": "lines", - "name": "NI Upper Earnings Limit", + "name": "NI upper earnings limit", "orientation": "v", "showlegend": true, "type": "scatter", @@ -335,9 +265,7 @@ ], "xaxis": "x", "y": [ - 962, - 966.73, - 966.73, + 962.0, 966.73, 966.73, 966.73, @@ -348,13 +276,15 @@ 966.73, 966.73, 966.73, - 966.73 + 986.0652504709999, + 1005.7853629502536, + 1025.901178621092 ], "yaxis": "y" }, { - "hovertemplate": "Label=NI Secondary Threshold
Instant=%{x}
Value=%{y}", - "legendgroup": "NI Secondary Threshold", + "hovertemplate": "Label=NI secondary threshold
Instant=%{x}
Value=%{y}", + "legendgroup": "NI secondary threshold", "line": { "color": "#ab63fa", "dash": "solid", @@ -364,7 +294,7 @@ "symbol": "circle" }, "mode": "lines", - "name": "NI Secondary Threshold", + "name": "NI secondary threshold", "orientation": "v", "showlegend": true, "type": "scatter", @@ -386,26 +316,26 @@ ], "xaxis": "x", "y": [ - 169, - 170, - 175, - 175, - 175, - 175, - 175, - 175, - 175, - 175, - 175, - 175, - 175, - 175 + 169.0, + 170.0, + 175.0, + 175.0, + 175.0, + 96.0, + 96.0, + 96.0, + 96.0, + 96.0, + 96.0, + 97.92006459426726, + 99.8783474633293, + 101.87592517830709 ], "yaxis": "y" }, { - "hovertemplate": "Label=NI Class 2 Small Profits Threshold
Instant=%{x}
Value=%{y}", - "legendgroup": "NI Class 2 Small Profits Threshold", + "hovertemplate": "Label=NI class 2 small profits threshold
Instant=%{x}
Value=%{y}", + "legendgroup": "NI class 2 small profits threshold", "line": { "color": "#FFA15A", "dash": "solid", @@ -415,7 +345,7 @@ "symbol": "circle" }, "mode": "lines", - "name": "NI Class 2 Small Profits Threshold", + "name": "NI class 2 small profits threshold", "orientation": "v", "showlegend": true, "type": "scatter", @@ -437,26 +367,26 @@ ], "xaxis": "x", "y": [ - 6475, - 6515, - 6725, - 6725, - 6725, - 6725, - 6725, - 6725, - 6725, - 6725, - 6725, - 6725, - 6725, - 6725 + 6475.0, + 6515.0, + 6725.0, + 6725.0, + 6725.0, + 6845.0, + 7105.0, + 7247.088788138113, + 7392.0236642935615, + 7539.84775101206, + 7690.647293385044, + 7844.465413958232, + 8001.345235277337, + 8161.373002433799 ], "yaxis": "y" }, { - "hovertemplate": "Label=NI Lower Profits Limit
Instant=%{x}
Value=%{y}", - "legendgroup": "NI Lower Profits Limit", + "hovertemplate": "Label=NI lower profits limit
Instant=%{x}
Value=%{y}", + "legendgroup": "NI lower profits limit", "line": { "color": "#19d3f3", "dash": "solid", @@ -466,7 +396,7 @@ "symbol": "circle" }, "mode": "lines", - "name": "NI Lower Profits Limit", + "name": "NI lower profits limit", "orientation": "v", "showlegend": true, "type": "scatter", @@ -488,26 +418,26 @@ ], "xaxis": "x", "y": [ - 9500, - 9568, - 11908, - 11908, - 11908, - 11908, - 12570, - 12570, - 12570, - 12570, - 12570, - 12570, - 12570, - 12570 + 9500.0, + 9568.0, + 11908.0, + 12570.0, + 12570.0, + 12570.0, + 12570.0, + 12570.0, + 12570.0, + 12570.0, + 12570.0, + 12821.408457811869, + 13077.821120979681, + 13339.378953034586 ], "yaxis": "y" }, { - "hovertemplate": "Label=NI Upper Profits Limit
Instant=%{x}
Value=%{y}", - "legendgroup": "NI Upper Profits Limit", + "hovertemplate": "Label=NI upper profits limit
Instant=%{x}
Value=%{y}", + "legendgroup": "NI upper profits limit", "line": { "color": "#FF6692", "dash": "solid", @@ -517,7 +447,7 @@ "symbol": "circle" }, "mode": "lines", - "name": "NI Upper Profits Limit", + "name": "NI upper profits limit", "orientation": "v", "showlegend": true, "type": "scatter", @@ -539,20 +469,20 @@ ], "xaxis": "x", "y": [ - 50000, - 50270, - 50270, - 50270, - 50270, - 50270, - 50270, - 50270, - 50270, - 50270, - 50270, - 50270, - 50270, - 50270 + 50000.0, + 50270.0, + 50270.0, + 50270.0, + 50270.0, + 50270.0, + 50270.0, + 50270.0, + 50270.0, + 50270.0, + 50270.0, + 51275.43382451891, + 52300.8804893913, + 53346.903736598935 ], "yaxis": "y" } @@ -565,10 +495,10 @@ "height": 600, "images": [ { - "sizex": 0.2, - "sizey": 0.2, + "sizex": 0.15, + "sizey": 0.15, "source": "https://raw.githubusercontent.com/PolicyEngine/policyengine-app/master/src/images/logos/policyengine/blue.png", - "x": 1, + "x": 1.1, "xanchor": "right", "xref": "paper", "y": -0.15, @@ -670,7 +600,7 @@ }, "colorscale": [ [ - 0, + 0.0, "#0d0887" ], [ @@ -706,7 +636,7 @@ "#fdca26" ], [ - 1, + 1.0, "#f0f921" ] ], @@ -730,7 +660,7 @@ }, "colorscale": [ [ - 0, + 0.0, "#0d0887" ], [ @@ -766,7 +696,7 @@ "#fdca26" ], [ - 1, + 1.0, "#f0f921" ] ], @@ -781,7 +711,7 @@ }, "colorscale": [ [ - 0, + 0.0, "#0d0887" ], [ @@ -817,7 +747,7 @@ "#fdca26" ], [ - 1, + 1.0, "#f0f921" ] ], @@ -844,7 +774,7 @@ }, "colorscale": [ [ - 0, + 0.0, "#0d0887" ], [ @@ -880,7 +810,7 @@ "#fdca26" ], [ - 1, + 1.0, "#f0f921" ] ], @@ -895,7 +825,7 @@ }, "colorscale": [ [ - 0, + 0.0, "#0d0887" ], [ @@ -931,7 +861,7 @@ "#fdca26" ], [ - 1, + 1.0, "#f0f921" ] ], @@ -1076,7 +1006,7 @@ }, "colorscale": [ [ - 0, + 0.0, "#0d0887" ], [ @@ -1112,7 +1042,7 @@ "#fdca26" ], [ - 1, + 1.0, "#f0f921" ] ], @@ -1203,7 +1133,7 @@ ], "sequential": [ [ - 0, + 0.0, "#0d0887" ], [ @@ -1239,13 +1169,13 @@ "#fdca26" ], [ - 1, + 1.0, "#f0f921" ] ], "sequentialminus": [ [ - 0, + 0.0, "#0d0887" ], [ @@ -1281,7 +1211,7 @@ "#fdca26" ], [ - 1, + 1.0, "#f0f921" ] ] @@ -1417,8 +1347,8 @@ "xaxis": { "anchor": "y", "domain": [ - 0, - 1 + 0.0, + 1.0 ], "title": { "text": "Instant" @@ -1427,8 +1357,8 @@ "yaxis": { "anchor": "x", "domain": [ - 0, - 1 + 0.0, + 1.0 ], "title": { "text": "Value" @@ -1463,7 +1393,7 @@ " for param in ni.get_descendants()\n", " if param not in threshold_parameters\n", " and isinstance(param, Parameter)\n", - " and param.metadata.get(\"unit\") != \"bool\"\n", + " and param.metadata.get(\"unit\") == \"/1\"\n", "]\n", "\n", "instants = [f\"{2020 + i}-04-06\" for i in range(0, 14)]\n", @@ -1548,8 +1478,8 @@ }, "data": [ { - "hovertemplate": "Label=NI Class 4 additional rate
Instant=%{x}
Value=%{y}", - "legendgroup": "NI Class 4 additional rate", + "hovertemplate": "Label=NI class 1 additional rate
Instant=%{x}
Value=%{y}", + "legendgroup": "NI class 1 additional rate", "line": { "color": "#636efa", "dash": "solid", @@ -1559,7 +1489,7 @@ "symbol": "circle" }, "mode": "lines", - "name": "NI Class 4 additional rate", + "name": "NI class 1 additional rate", "orientation": "v", "showlegend": true, "type": "scatter", @@ -1583,24 +1513,24 @@ "y": [ 0.02, 0.02, - 0.035, - 0.035, - 0.035, - 0.035, - 0.035, - 0.035, - 0.035, - 0.035, - 0.035, - 0.035, - 0.035, - 0.035 + 0.0325, + 0.0325, + 0.02, + 0.02, + 0.02, + 0.02, + 0.02, + 0.02, + 0.02, + 0.02, + 0.02, + 0.02 ], "yaxis": "y" }, { - "hovertemplate": "Label=NI Class 4 main rate
Instant=%{x}
Value=%{y}", - "legendgroup": "NI Class 4 main rate", + "hovertemplate": "Label=NI class 1 main rate
Instant=%{x}
Value=%{y}", + "legendgroup": "NI class 1 main rate", "line": { "color": "#EF553B", "dash": "solid", @@ -1610,7 +1540,7 @@ "symbol": "circle" }, "mode": "lines", - "name": "NI Class 4 main rate", + "name": "NI class 1 main rate", "orientation": "v", "showlegend": true, "type": "scatter", @@ -1632,26 +1562,26 @@ ], "xaxis": "x", "y": [ - 0.09, - 0.09, - 0.1025, - 0.09, - 0.09, - 0.09, - 0.09, - 0.09, - 0.09, - 0.09, - 0.09, - 0.09, - 0.09, - 0.09 + 0.12, + 0.12, + 0.1325, + 0.12, + 0.08, + 0.08, + 0.08, + 0.08, + 0.08, + 0.08, + 0.08, + 0.08, + 0.08, + 0.08 ], "yaxis": "y" }, { - "hovertemplate": "Label=NI Class 1 additional rate
Instant=%{x}
Value=%{y}", - "legendgroup": "NI Class 1 additional rate", + "hovertemplate": "Label=NI employer rate
Instant=%{x}
Value=%{y}", + "legendgroup": "NI employer rate", "line": { "color": "#00cc96", "dash": "solid", @@ -1661,7 +1591,7 @@ "symbol": "circle" }, "mode": "lines", - "name": "NI Class 1 additional rate", + "name": "NI employer rate", "orientation": "v", "showlegend": true, "type": "scatter", @@ -1683,26 +1613,26 @@ ], "xaxis": "x", "y": [ - 0.02, - 0.02, - 0.0325, - 0.0325, - 0.0325, - 0.0325, - 0.0325, - 0.0325, - 0.0325, - 0.0325, - 0.0325, - 0.0325, - 0.0325, - 0.0325 + 0.138, + 0.138, + 0.138, + 0.138, + 0.138, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15 ], "yaxis": "y" }, { - "hovertemplate": "Label=NI Class 1 main rate
Instant=%{x}
Value=%{y}", - "legendgroup": "NI Class 1 main rate", + "hovertemplate": "Label=NI class 4 additional rate
Instant=%{x}
Value=%{y}", + "legendgroup": "NI class 4 additional rate", "line": { "color": "#ab63fa", "dash": "solid", @@ -1712,7 +1642,7 @@ "symbol": "circle" }, "mode": "lines", - "name": "NI Class 1 main rate", + "name": "NI class 4 additional rate", "orientation": "v", "showlegend": true, "type": "scatter", @@ -1734,26 +1664,26 @@ ], "xaxis": "x", "y": [ - 0.12, - 0.12, - 0.1325, - 0.12, - 0.12, - 0.12, - 0.12, - 0.12, - 0.12, - 0.12, - 0.12, - 0.12, - 0.12, - 0.12 + 0.02, + 0.02, + 0.0273, + 0.02, + 0.02, + 0.02, + 0.02, + 0.02, + 0.02, + 0.02, + 0.02, + 0.02, + 0.02, + 0.02 ], "yaxis": "y" }, { - "hovertemplate": "Label=NI Employer rate
Instant=%{x}
Value=%{y}", - "legendgroup": "NI Employer rate", + "hovertemplate": "Label=NI class 4 main rate
Instant=%{x}
Value=%{y}", + "legendgroup": "NI class 4 main rate", "line": { "color": "#FFA15A", "dash": "solid", @@ -1763,7 +1693,7 @@ "symbol": "circle" }, "mode": "lines", - "name": "NI Employer rate", + "name": "NI class 4 main rate", "orientation": "v", "showlegend": true, "type": "scatter", @@ -1785,20 +1715,20 @@ ], "xaxis": "x", "y": [ - 0.138, - 0.138, - 0.138, - 0.138, - 0.138, - 0.138, - 0.138, - 0.138, - 0.138, - 0.138, - 0.138, - 0.138, - 0.138, - 0.138 + 0.09, + 0.09, + 0.0973, + 0.09, + 0.06, + 0.06, + 0.06, + 0.06, + 0.06, + 0.06, + 0.06, + 0.06, + 0.06, + 0.06 ], "yaxis": "y" } @@ -1811,10 +1741,10 @@ "height": 600, "images": [ { - "sizex": 0.2, - "sizey": 0.2, + "sizex": 0.15, + "sizey": 0.15, "source": "https://raw.githubusercontent.com/PolicyEngine/policyengine-app/master/src/images/logos/policyengine/blue.png", - "x": 1, + "x": 1.1, "xanchor": "right", "xref": "paper", "y": -0.15, @@ -1916,7 +1846,7 @@ }, "colorscale": [ [ - 0, + 0.0, "#0d0887" ], [ @@ -1952,7 +1882,7 @@ "#fdca26" ], [ - 1, + 1.0, "#f0f921" ] ], @@ -1976,7 +1906,7 @@ }, "colorscale": [ [ - 0, + 0.0, "#0d0887" ], [ @@ -2012,7 +1942,7 @@ "#fdca26" ], [ - 1, + 1.0, "#f0f921" ] ], @@ -2027,7 +1957,7 @@ }, "colorscale": [ [ - 0, + 0.0, "#0d0887" ], [ @@ -2063,7 +1993,7 @@ "#fdca26" ], [ - 1, + 1.0, "#f0f921" ] ], @@ -2090,7 +2020,7 @@ }, "colorscale": [ [ - 0, + 0.0, "#0d0887" ], [ @@ -2126,7 +2056,7 @@ "#fdca26" ], [ - 1, + 1.0, "#f0f921" ] ], @@ -2141,7 +2071,7 @@ }, "colorscale": [ [ - 0, + 0.0, "#0d0887" ], [ @@ -2177,7 +2107,7 @@ "#fdca26" ], [ - 1, + 1.0, "#f0f921" ] ], @@ -2322,7 +2252,7 @@ }, "colorscale": [ [ - 0, + 0.0, "#0d0887" ], [ @@ -2358,7 +2288,7 @@ "#fdca26" ], [ - 1, + 1.0, "#f0f921" ] ], @@ -2449,7 +2379,7 @@ ], "sequential": [ [ - 0, + 0.0, "#0d0887" ], [ @@ -2485,13 +2415,13 @@ "#fdca26" ], [ - 1, + 1.0, "#f0f921" ] ], "sequentialminus": [ [ - 0, + 0.0, "#0d0887" ], [ @@ -2527,7 +2457,7 @@ "#fdca26" ], [ - 1, + 1.0, "#f0f921" ] ] @@ -2663,8 +2593,8 @@ "xaxis": { "anchor": "y", "domain": [ - 0, - 1 + 0.0, + 1.0 ], "title": { "text": "Instant" @@ -2673,8 +2603,8 @@ "yaxis": { "anchor": "x", "domain": [ - 0, - 1 + 0.0, + 1.0 ], "title": { "text": "Value" @@ -2689,7 +2619,7 @@ ], "source": [ "fig = px.line(\n", - " df[(df[\"Threshold\"] == False) & (df[\"Value\"] < 1)], # Don't plot the flat rate,\n", + " df[df[\"Threshold\"] == False],\n", " x=\"Instant\",\n", " y=\"Value\",\n", " color=\"Label\",\n", diff --git a/policyengine_uk/parameters/gov/hmrc/national_insurance/class_2/flat_rate.yaml b/policyengine_uk/parameters/gov/hmrc/national_insurance/class_2/flat_rate.yaml index ff37748484..8f0acf62ac 100644 --- a/policyengine_uk/parameters/gov/hmrc/national_insurance/class_2/flat_rate.yaml +++ b/policyengine_uk/parameters/gov/hmrc/national_insurance/class_2/flat_rate.yaml @@ -1,25 +1,65 @@ -description: Flat rate National Insurance contribution for self-employed earners. +description: Weekly Class 2 National Insurance contribution that self-employed earners are liable to pay under section 11(2) of the Social Security Contributions and Benefits Act 1992. Compulsory Class 2 ended on 6 April 2024; voluntary Class 2 is not modelled. values: - 2015-04-01: 2.8 - 2017-04-01: 2.85 - 2018-04-01: 2.95 - 2019-04-01: 3 - 2020-04-01: 3.05 + 2015-04-06: + value: 2.8 + metadata: + reference: + - title: National Insurance Contributions Act 2015 Sch 1 para 3 (substituting s 11(2) of the Social Security Contributions and Benefits Act 1992) + href: https://www.legislation.gov.uk/ukpga/2015/5/schedule/1/paragraph/3/enacted + - title: Social Security Contributions and Benefits Act 1992 s 11(2) (as at 6 April 2016, unchanged for 2016-17) + href: https://www.legislation.gov.uk/ukpga/1992/4/section/11/2016-04-06 + 2017-04-06: + value: 2.85 + metadata: + reference: + - title: The Social Security (Contributions) (Rates, Limits and Thresholds Amendments and National Insurance Funds Payments) Regulations 2017 reg 3(a) + href: https://www.legislation.gov.uk/uksi/2017/415/regulation/3/made + 2018-04-06: + value: 2.95 + metadata: + reference: + - title: The Social Security (Contributions) (Rates, Limits and Thresholds Amendments and National Insurance Funds Payments) Regulations 2018 reg 3(a) + href: https://www.legislation.gov.uk/uksi/2018/337/regulation/3/made + 2019-04-06: + value: 3 + metadata: + reference: + - title: The Social Security (Contributions) (Rates, Limits and Thresholds Amendments and National Insurance Funds Payments) Regulations 2019 reg 3(a) + href: https://www.legislation.gov.uk/uksi/2019/262/regulation/3/made + 2020-04-06: + value: 3.05 + metadata: + reference: + - title: The Social Security (Contributions) (Rates, Limits and Thresholds Amendments and National Insurance Funds Payments) Regulations 2020 reg 3(a) + href: https://www.legislation.gov.uk/uksi/2020/299/regulation/3/made + - title: Social Security Contributions and Benefits Act 1992 s 11(2) (as at 6 April 2021, unchanged for 2021-22) + href: https://www.legislation.gov.uk/ukpga/1992/4/section/11/2021-04-06 2022-04-06: value: 3.15 metadata: reference: - - title: The Social Security (Contributions) (Rates, Limits and Thresholds Amendments and National Insurance Funds Payments) Regulations 2022(3)(a) - href: https://www.legislation.gov.uk/uksi/2022/232/regulation/3/made#regulation-3-a - 2024-01-01: + - title: The Social Security (Contributions) (Rates, Limits and Thresholds Amendments and National Insurance Funds Payments) Regulations 2022 reg 3(a) + href: https://www.legislation.gov.uk/uksi/2022/232/regulation/3/made + 2023-04-06: + value: 3.45 + metadata: + reference: + - title: The Social Security (Contributions) (Rates, Limits and Thresholds Amendments and National Insurance Funds Payments) Regulations 2023 reg 3(a) + href: https://www.legislation.gov.uk/uksi/2023/236/regulation/3/made + - title: Social Security Contributions and Benefits Act 1992 s 11(2) (as at 6 April 2023) + href: https://www.legislation.gov.uk/ukpga/1992/4/section/11/2023-04-06 + 2024-04-06: value: 0 metadata: reference: - - title: "Autumn Statement 2023: National Insurance Factsheet" - href: https://www.gov.uk/government/publications/autumn-statement-2023-national-insurance-factsheet/autumn-statement-2023-national-insurance-factsheet + - title: National Insurance Contributions (Reduction in Rates) Act 2023 s 3(1)(a) and (3) (omitting s 11(2) of the Social Security Contributions and Benefits Act 1992 from 6 April 2024) + href: https://www.legislation.gov.uk/ukpga/2023/57/section/3/enacted metadata: unit: currency-GBP + period: week label: NI class 2 flat rate reference: - - https://assets.publishing.service.gov.uk/government/uploads/system/uploads/attachment_data/file/882271/Table-a4.pdf - - https://www.gov.uk/government/publications/rates-and-allowances-national-insurance-contributions/rates-and-allowances-national-insurance-contributions + - title: Social Security Contributions and Benefits Act 1992 s 11 + href: https://www.legislation.gov.uk/ukpga/1992/4/section/11 + - title: "GOV.UK | Rates and allowances: National Insurance contributions" + href: https://www.gov.uk/government/publications/rates-and-allowances-national-insurance-contributions/rates-and-allowances-national-insurance-contributions diff --git a/policyengine_uk/parameters/gov/hmrc/national_insurance/class_2/lower_profits_threshold.yaml b/policyengine_uk/parameters/gov/hmrc/national_insurance/class_2/lower_profits_threshold.yaml new file mode 100644 index 0000000000..b0354aa651 --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/national_insurance/class_2/lower_profits_threshold.yaml @@ -0,0 +1,21 @@ +description: Lower profits threshold for Class 2 National Insurance contributions under section 11(4)(a) of the Social Security Contributions and Benefits Act 1992. In 2022-23 and 2023-24 self-employed earners were liable for Class 2 only on profits above it. Section 11(4)(a) was omitted from 6 April 2024, when compulsory Class 2 ended; the 2023-24 value applies to reforms that restore a Class 2 rate. +values: + 2022-04-06: + value: 11_908 + metadata: + reference: + - title: The Social Security (Class 2 National Insurance Contributions Increase of Threshold) Regulations 2022 reg 2(3) + href: https://www.legislation.gov.uk/uksi/2022/1329/regulation/2/made + 2023-04-06: + value: 12_570 + metadata: + reference: + - title: The Social Security (Contributions) (Rates, Limits and Thresholds Amendments and National Insurance Funds Payments) Regulations 2023 reg 3(b) + href: https://www.legislation.gov.uk/uksi/2023/236/regulation/3/made +metadata: + unit: currency-GBP + period: year + label: NI class 2 lower profits threshold + reference: + - title: Social Security Contributions and Benefits Act 1992 s 11(2), (4) and (5A) (as at 6 April 2023) + href: https://www.legislation.gov.uk/ukpga/1992/4/section/11/2023-04-06 diff --git a/policyengine_uk/parameters/gov/hmrc/national_insurance/class_2/lower_profits_threshold_applies.yaml b/policyengine_uk/parameters/gov/hmrc/national_insurance/class_2/lower_profits_threshold_applies.yaml new file mode 100644 index 0000000000..3d96ec8e74 --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/national_insurance/class_2/lower_profits_threshold_applies.yaml @@ -0,0 +1,21 @@ +description: Class 2 National Insurance liability starts above the lower profits threshold rather than at the small profits threshold. In 2022-23 and 2023-24 profits from the small profits threshold up to the lower profits threshold were treated as paid. Compulsory Class 2 ended on 6 April 2024; the switch stays on so that a reform restoring a Class 2 rate uses the 2023-24 rule. +values: + 2015-04-06: + value: false + metadata: + reference: + - title: Social Security Contributions and Benefits Act 1992 s 11(2) (as at 6 April 2021) + href: https://www.legislation.gov.uk/ukpga/1992/4/section/11/2021-04-06 + 2022-04-06: + value: true + metadata: + reference: + - title: The Social Security (Class 2 National Insurance Contributions Increase of Threshold) Regulations 2022 regs 1 and 2(2) + href: https://www.legislation.gov.uk/uksi/2022/1329/regulation/2/made +metadata: + unit: bool + period: year + label: Class 2 liability starts above the lower profits threshold + reference: + - title: Social Security Contributions and Benefits Act 1992 s 11(2), (5A) and (5B) (as at 6 April 2023) + href: https://www.legislation.gov.uk/ukpga/1992/4/section/11/2023-04-06 diff --git a/policyengine_uk/parameters/gov/hmrc/national_insurance/class_2/small_profits_threshold.yaml b/policyengine_uk/parameters/gov/hmrc/national_insurance/class_2/small_profits_threshold.yaml index 25af299979..e41baf8e24 100644 --- a/policyengine_uk/parameters/gov/hmrc/national_insurance/class_2/small_profits_threshold.yaml +++ b/policyengine_uk/parameters/gov/hmrc/national_insurance/class_2/small_profits_threshold.yaml @@ -1,35 +1,80 @@ -description: Small profits National Insurance threshold for self-employed earners. +description: Small profits threshold for Class 2 National Insurance contributions under section 11(4) of the Social Security Contributions and Benefits Act 1992. Before 2022-23 self-employed earners with profits at or above it were liable for Class 2; in 2022-23 and 2023-24 profits from this threshold up to the lower profits threshold were treated as paid. values: - 2015-04-06: 3_965 - 2017-04-06: 6_025 - 2018-04-06: 6_205 - 2019-04-06: 6_365 - 2020-04-06: 6_475 - 2021-04-06: 6_515 + 2015-04-06: + value: 5_965 + metadata: + reference: + - title: National Insurance Contributions Act 2015 Sch 1 para 3 (substituting s 11(4) of the Social Security Contributions and Benefits Act 1992) + href: https://www.legislation.gov.uk/ukpga/2015/5/schedule/1/paragraph/3/enacted + - title: Social Security Contributions and Benefits Act 1992 s 11(4) (as at 6 April 2016, unchanged for 2016-17) + href: https://www.legislation.gov.uk/ukpga/1992/4/section/11/2016-04-06 + 2017-04-06: + value: 6_025 + metadata: + reference: + - title: The Social Security (Contributions) (Rates, Limits and Thresholds Amendments and National Insurance Funds Payments) Regulations 2017 reg 3(b) + href: https://www.legislation.gov.uk/uksi/2017/415/regulation/3/made + 2018-04-06: + value: 6_205 + metadata: + reference: + - title: The Social Security (Contributions) (Rates, Limits and Thresholds Amendments and National Insurance Funds Payments) Regulations 2018 reg 3(b) + href: https://www.legislation.gov.uk/uksi/2018/337/regulation/3/made + 2019-04-06: + value: 6_365 + metadata: + reference: + - title: The Social Security (Contributions) (Rates, Limits and Thresholds Amendments and National Insurance Funds Payments) Regulations 2019 reg 3(b) + href: https://www.legislation.gov.uk/uksi/2019/262/regulation/3/made + 2020-04-06: + value: 6_475 + metadata: + reference: + - title: The Social Security (Contributions) (Rates, Limits and Thresholds Amendments and National Insurance Funds Payments) Regulations 2020 reg 3(b) + href: https://www.legislation.gov.uk/uksi/2020/299/regulation/3/made + 2021-04-06: + value: 6_515 + metadata: + reference: + - title: The Social Security (Contributions) (Rates, Limits and Thresholds Amendments and National Insurance Funds Payments) Regulations 2021 reg 3 + href: https://www.legislation.gov.uk/uksi/2021/157/regulation/3/made 2022-04-06: value: 6_725 metadata: reference: - - title: The Social Security (Contributions) (Rates, Limits and Thresholds Amendments and National Insurance Funds Payments) Regulations 2022(3)(b) - href: https://www.legislation.gov.uk/uksi/2022/232/regulation/3/made#regulation-3-b + - title: The Social Security (Contributions) (Rates, Limits and Thresholds Amendments and National Insurance Funds Payments) Regulations 2022 reg 3(b) + href: https://www.legislation.gov.uk/uksi/2022/232/regulation/3/made + 2023-04-06: + value: 6_725 + metadata: + reference: + - title: Social Security Contributions and Benefits Act 1992 s 11(4)(b) (as at 6 April 2023) + href: https://www.legislation.gov.uk/ukpga/1992/4/section/11/2023-04-06 + 2024-04-06: + value: 6_725 + metadata: + reference: + - title: Social Security Contributions and Benefits Act 1992 s 11(4)(b) (as at 6 April 2024) + href: https://www.legislation.gov.uk/ukpga/1992/4/section/11/2024-04-06 2025-04-06: value: 6_845 metadata: reference: - - title: "GOV.UK | Rates and allowances: National Insurance contributions" - href: https://www.gov.uk/government/publications/rates-and-allowances-national-insurance-contributions/rates-and-allowances-national-insurance-contributions + - title: The Social Security (Contributions) (Rates, Limits and Thresholds Amendments, National Insurance Funds Payments and Extension of Veteran's Relief) Regulations 2025 reg 3(a) + href: https://www.legislation.gov.uk/uksi/2025/288/regulation/3/made 2026-04-06: value: 7_105 metadata: reference: - - title: "GOV.UK | Rates and allowances: National Insurance contributions" - href: https://www.gov.uk/government/publications/rates-and-allowances-national-insurance-contributions/rates-and-allowances-national-insurance-contributions + - title: The Social Security (Contributions) (Rates, Limits and Thresholds Amendments, National Insurance Funds Payments and Extension of Veteran's Relief) Regulations 2026 reg 3(a) + href: https://www.legislation.gov.uk/uksi/2026/231/regulation/3/made metadata: unit: currency-GBP + period: year label: NI class 2 small profits threshold - uprating: - parameter: gov.economic_assumptions.indices.obr.consumer_price_index - start_instant: 2022-04-06 + uprating: gov.economic_assumptions.indices.obr.consumer_price_index reference: - - https://assets.publishing.service.gov.uk/government/uploads/system/uploads/attachment_data/file/882271/Table-a4.pdf - - https://www.gov.uk/government/publications/rates-and-allowances-national-insurance-contributions/rates-and-allowances-national-insurance-contributions + - title: Social Security Contributions and Benefits Act 1992 s 11 + href: https://www.legislation.gov.uk/ukpga/1992/4/section/11 + - title: "GOV.UK | Rates and allowances: National Insurance contributions" + href: https://www.gov.uk/government/publications/rates-and-allowances-national-insurance-contributions/rates-and-allowances-national-insurance-contributions diff --git a/policyengine_uk/parameters/gov/hmrc/national_insurance/class_4/rates/additional.yaml b/policyengine_uk/parameters/gov/hmrc/national_insurance/class_4/rates/additional.yaml index 5326d9ae35..81d3c7d5c6 100644 --- a/policyengine_uk/parameters/gov/hmrc/national_insurance/class_4/rates/additional.yaml +++ b/policyengine_uk/parameters/gov/hmrc/national_insurance/class_4/rates/additional.yaml @@ -1,19 +1,33 @@ description: The additional National Insurance rate paid above the Upper Profits Limit for self-employed profits. values: - 2015-04-01: 0.02 - 2022-04-01: - value: 0.035 + 2015-04-06: + value: 0.02 + metadata: + reference: + - title: National Insurance Contributions Act 2011 s 2(1)(b) (additional Class 4 percentage of 2% from 6 April 2011) + href: https://www.legislation.gov.uk/ukpga/2011/3/section/2/enacted + - title: Social Security Contributions and Benefits Act 1992 s 15(3ZA)(b) (as at 6 April 2015) + href: https://www.legislation.gov.uk/ukpga/1992/4/section/15/2015-04-06 + # Class 4 is charged on the year's profits, so 2022-23 has one rate for the + # whole tax year. The Health and Social Care Levy (Repeal) Act 2022 replaced + # the 3.25% that the Health and Social Care Levy Act 2021 s 5(2) had set. + 2022-04-06: + value: 0.0273 metadata: reference: - - title: Autumn Budget and Spending Review 2022 - href: https://assets.publishing.service.gov.uk/government/uploads/system/uploads/attachment_data/file/1043689/Budget_AB2021_Web_Accessible.pdf - 2024-01-01: + - title: Health and Social Care Levy (Repeal) Act 2022 s 2(2)(b) (additional Class 4 percentage of 2.73% for the tax year 2022-23) + href: https://www.legislation.gov.uk/ukpga/2022/43/section/2 + 2023-04-06: value: 0.02 metadata: reference: - - title: National Insurance Contributions (Reduction in Rates) Act 2024 s 1 - href: https://www.legislation.gov.uk/ukpga/2024/5/section/1 + - title: Social Security Contributions and Benefits Act 1992 s 15(3ZA)(b) (as at 6 April 2023) + href: https://www.legislation.gov.uk/ukpga/1992/4/section/15/2023-04-06 metadata: label: NI class 4 additional rate unit: /1 - reference: https://assets.publishing.service.gov.uk/government/uploads/system/uploads/attachment_data/file/882271/Table-a4.pdf + reference: + - title: Social Security Contributions and Benefits Act 1992 s 15(3ZA) + href: https://www.legislation.gov.uk/ukpga/1992/4/section/15 + - title: "GOV.UK | Rates and allowances: National Insurance contributions" + href: https://www.gov.uk/government/publications/rates-and-allowances-national-insurance-contributions/rates-and-allowances-national-insurance-contributions diff --git a/policyengine_uk/parameters/gov/hmrc/national_insurance/class_4/rates/main.yaml b/policyengine_uk/parameters/gov/hmrc/national_insurance/class_4/rates/main.yaml index 1ef51cea61..5f3dab92c3 100644 --- a/policyengine_uk/parameters/gov/hmrc/national_insurance/class_4/rates/main.yaml +++ b/policyengine_uk/parameters/gov/hmrc/national_insurance/class_4/rates/main.yaml @@ -1,25 +1,41 @@ description: The main National Insurance rate paid between the Lower and Upper Profits Limits for self-employed profits. values: - 2015-04-01: 0.09 - 2022-04-01: - value: 0.1025 + 2015-04-06: + value: 0.09 metadata: reference: - - title: Autumn Budget and Spending Review 2022 - href: https://assets.publishing.service.gov.uk/government/uploads/system/uploads/attachment_data/file/1043689/Budget_AB2021_Web_Accessible.pdf - 2022-11-06: - value: 0.09 + - title: National Insurance Contributions Act 2011 s 2(1)(a) (main Class 4 percentage of 9% from 6 April 2011) + href: https://www.legislation.gov.uk/ukpga/2011/3/section/2/enacted + - title: Social Security Contributions and Benefits Act 1992 s 15(3ZA)(a) (as at 6 April 2015) + href: https://www.legislation.gov.uk/ukpga/1992/4/section/15/2015-04-06 + # Class 4 is charged on the year's profits, so 2022-23 has one rate for the + # whole tax year. The Health and Social Care Levy (Repeal) Act 2022 replaced + # the 10.25% that the Health and Social Care Levy Act 2021 s 5(2) had set. + 2022-04-06: + value: 0.0973 metadata: reference: - - title: Health and Social Care Levy Act (Repeal) 2022 + - title: Health and Social Care Levy (Repeal) Act 2022 s 2(2)(a) (main Class 4 percentage of 9.73% for the tax year 2022-23) href: https://www.legislation.gov.uk/ukpga/2022/43/section/2 - 2024-04-04: + 2023-04-06: + value: 0.09 + metadata: + reference: + - title: Social Security Contributions and Benefits Act 1992 s 15(3ZA)(a) (as at 6 April 2023) + href: https://www.legislation.gov.uk/ukpga/1992/4/section/15/2023-04-06 + 2024-04-06: value: 0.06 metadata: reference: - - title: National Insurance Contributions (Reduction in Rates) Act 2024 s 1 - href: https://www.legislation.gov.uk/ukpga/2024/5/section/1 + - title: National Insurance Contributions (Reduction in Rates) Act 2024 ss 1(3)(a) and 3(1) + href: https://www.legislation.gov.uk/ukpga/2024/5/section/1/enacted + - title: Social Security Contributions and Benefits Act 1992 s 15(3ZA)(a) (as at 6 April 2024) + href: https://www.legislation.gov.uk/ukpga/1992/4/section/15/2024-04-06 metadata: label: NI class 4 main rate unit: /1 - reference: https://assets.publishing.service.gov.uk/government/uploads/system/uploads/attachment_data/file/882271/Table-a4.pdf + reference: + - title: Social Security Contributions and Benefits Act 1992 s 15(3ZA) + href: https://www.legislation.gov.uk/ukpga/1992/4/section/15 + - title: "GOV.UK | Rates and allowances: National Insurance contributions" + href: https://www.gov.uk/government/publications/rates-and-allowances-national-insurance-contributions/rates-and-allowances-national-insurance-contributions diff --git a/policyengine_uk/parameters/gov/hmrc/national_insurance/class_4/thresholds/lower_profits_limit.yaml b/policyengine_uk/parameters/gov/hmrc/national_insurance/class_4/thresholds/lower_profits_limit.yaml index b36a83b7ba..89f9a4587a 100644 --- a/policyengine_uk/parameters/gov/hmrc/national_insurance/class_4/thresholds/lower_profits_limit.yaml +++ b/policyengine_uk/parameters/gov/hmrc/national_insurance/class_4/thresholds/lower_profits_limit.yaml @@ -4,24 +4,60 @@ description: The Lower Profits Limit is the threshold at which self-employed ear # keeping it until April 2031. CPI uprating from 2031-32 is a modelling # assumption. values: - 2015-04-06: 8_060 - 2017-04-06: 8_164 - 2018-04-06: 8_424 - 2019-04-06: 8_632 - 2020-04-06: 9_500 - 2021-04-06: 9_568 + 2015-04-06: + value: 8_060 + metadata: + reference: + - title: The Social Security (Contributions) (Re-rating and National Insurance Funds Payments) Order 2015 art 3(a) + href: https://www.legislation.gov.uk/uksi/2015/588/article/3/made + - title: Social Security Contributions and Benefits Act 1992 s 15(3)(a) (as at 6 April 2016, unchanged for 2016-17) + href: https://www.legislation.gov.uk/ukpga/1992/4/section/15/2016-04-06 + 2017-04-06: + value: 8_164 + metadata: + reference: + - title: The Social Security (Contributions) (Rates, Limits and Thresholds Amendments and National Insurance Funds Payments) Regulations 2017 reg 5(a) + href: https://www.legislation.gov.uk/uksi/2017/415/regulation/5/made + 2018-04-06: + value: 8_424 + metadata: + reference: + - title: The Social Security (Contributions) (Rates, Limits and Thresholds Amendments and National Insurance Funds Payments) Regulations 2018 reg 5(a) + href: https://www.legislation.gov.uk/uksi/2018/337/regulation/5/made + 2019-04-06: + value: 8_632 + metadata: + reference: + - title: The Social Security (Contributions) (Rates, Limits and Thresholds Amendments and National Insurance Funds Payments) Regulations 2019 reg 5(a) + href: https://www.legislation.gov.uk/uksi/2019/262/regulation/5/made + 2020-04-06: + value: 9_500 + metadata: + reference: + - title: The Social Security (Contributions) (Rates, Limits and Thresholds Amendments and National Insurance Funds Payments) Regulations 2020 reg 5 + href: https://www.legislation.gov.uk/uksi/2020/299/regulation/5/made + 2021-04-06: + value: 9_568 + metadata: + reference: + - title: The Social Security (Contributions) (Rates, Limits and Thresholds Amendments and National Insurance Funds Payments) Regulations 2021 reg 5(1) + href: https://www.legislation.gov.uk/uksi/2021/157/regulation/5/made + # SI 2022/232 reg 5 first set £9,880 for 2022-23; the 2022 Act replaced it + # with £11,908 for the whole year. 2022-04-06: value: 11_908 metadata: reference: - - title: National Insurance Contributions (Increase of Thresholds) Act 2022 + - title: National Insurance Contributions (Increase of Thresholds) Act 2022 s 2(1) and (2) href: https://www.legislation.gov.uk/ukpga/2022/16/section/2/enacted - 2024-01-01: + 2023-04-06: value: 12_570 metadata: reference: - - title: National Insurance Contributions (Increase of Thresholds) Act 2022 + - title: National Insurance Contributions (Increase of Thresholds) Act 2022 s 2(3) and (4) href: https://www.legislation.gov.uk/ukpga/2022/16/section/2/enacted + - title: Social Security Contributions and Benefits Act 1992 s 15(3)(a) (as at 6 April 2023) + href: https://www.legislation.gov.uk/ukpga/1992/4/section/15/2023-04-06 2026-04-06: value: 12_570 metadata: diff --git a/policyengine_uk/parameters/gov/hmrc/national_insurance/class_4/thresholds/upper_profits_limit.yaml b/policyengine_uk/parameters/gov/hmrc/national_insurance/class_4/thresholds/upper_profits_limit.yaml index 37fa1a7b67..b415b7f89e 100644 --- a/policyengine_uk/parameters/gov/hmrc/national_insurance/class_4/thresholds/upper_profits_limit.yaml +++ b/policyengine_uk/parameters/gov/hmrc/national_insurance/class_4/thresholds/upper_profits_limit.yaml @@ -4,13 +4,44 @@ description: The Upper Profits Limit is the threshold at which self-employed ear # keeping it until April 2031. CPI uprating from 2031-32 is a modelling # assumption. values: - 2015-04-06: 42_386 - 2015-06-05: 43_000 - 2017-04-06: 45_000 - 2018-04-06: 46_350 - 2019-04-06: 50_000 - 2020-04-06: 50_000 - 2021-04-06: 50_270 + 2015-04-06: + value: 42_385 + metadata: + reference: + - title: The Social Security (Contributions) (Re-rating and National Insurance Funds Payments) Order 2015 art 3(b) + href: https://www.legislation.gov.uk/uksi/2015/588/article/3/made + 2016-04-06: + value: 43_000 + metadata: + reference: + - title: The Social Security (Contributions) (Limits and Thresholds Amendments and National Insurance Funds Payments) Regulations 2016 reg 2 + href: https://www.legislation.gov.uk/uksi/2016/343/regulation/2/made + 2017-04-06: + value: 45_000 + metadata: + reference: + - title: The Social Security (Contributions) (Rates, Limits and Thresholds Amendments and National Insurance Funds Payments) Regulations 2017 reg 5(b) + href: https://www.legislation.gov.uk/uksi/2017/415/regulation/5/made + 2018-04-06: + value: 46_350 + metadata: + reference: + - title: The Social Security (Contributions) (Rates, Limits and Thresholds Amendments and National Insurance Funds Payments) Regulations 2018 reg 5(b) + href: https://www.legislation.gov.uk/uksi/2018/337/regulation/5/made + 2019-04-06: + value: 50_000 + metadata: + reference: + - title: The Social Security (Contributions) (Rates, Limits and Thresholds Amendments and National Insurance Funds Payments) Regulations 2019 reg 5(b) + href: https://www.legislation.gov.uk/uksi/2019/262/regulation/5/made + - title: Social Security Contributions and Benefits Act 1992 s 15(3) (as at 6 April 2020, unchanged for 2020-21) + href: https://www.legislation.gov.uk/ukpga/1992/4/section/15/2020-04-06 + 2021-04-06: + value: 50_270 + metadata: + reference: + - title: The Social Security (Contributions) (Rates, Limits and Thresholds Amendments and National Insurance Funds Payments) Regulations 2021 reg 5(2) + href: https://www.legislation.gov.uk/uksi/2021/157/regulation/5/made 2026-04-06: value: 50_270 metadata: diff --git a/policyengine_uk/tests/policy/baseline/finance/benefit/family/universal_credit/income/income_floor/uc_minimum_income_floor.yaml b/policyengine_uk/tests/policy/baseline/finance/benefit/family/universal_credit/income/income_floor/uc_minimum_income_floor.yaml index 939c0389e0..3568e6e7e5 100644 --- a/policyengine_uk/tests/policy/baseline/finance/benefit/family/universal_credit/income/income_floor/uc_minimum_income_floor.yaml +++ b/policyengine_uk/tests/policy/baseline/finance/benefit/family/universal_credit/income/income_floor/uc_minimum_income_floor.yaml @@ -149,6 +149,86 @@ # 7.20 x 35 x 52. uc_minimum_income_floor_gross: 13_104 +# The notional Class 2 follows s.11(2) SSCBA 1992 as ni_class_2 does. In +# 2022-23 and 2023-24 profits from the small profits threshold up to the +# lower profits threshold (11,908, then 12,570) are treated as paid and cost +# nothing (s.11(5A)-(5B)). A full year is 53 contribution weeks in 2019-20 +# (HMRC NIM70200). +- name: Net floor in 2023-24 deducts no Class 2 on profits treated as paid + period: 2023 + absolute_error_margin: 0.01 + input: + people: + parent: + age: 30 + child: + age: 3 + households: + household: + members: [parent, child] + region: NORTH_EAST + output: + # A lone parent of a child aged 3: 16 hours at the 2023-24 National + # Living Wage, 10.42 x 16 x 52. + uc_minimum_income_floor_gross: [8_669.44, 0] + uc_minimum_income_floor_income_tax: [0, 0] + # 8,669.44 is above the 6,725 small profits threshold but not above the + # 12,570 lower profits threshold, so Class 2 is treated as paid; Class 4 + # starts at 12,570. + uc_minimum_income_floor_national_insurance: [0, 0] + uc_minimum_income_floor: [8_669.44, 0] + +- name: Net floor in 2022-23 deducts no Class 2 on profits treated as paid + period: 2022 + absolute_error_margin: 0.01 + input: + people: + parent: + age: 30 + child: + age: 3 + households: + household: + members: [parent, child] + region: NORTH_EAST + output: + # 9.50 x 16 x 52: above the 6,725 small profits threshold, not above the + # 11,908 lower profits threshold or Class 4 lower profits limit. + uc_minimum_income_floor_gross: [7_904, 0] + uc_minimum_income_floor_national_insurance: [0, 0] + uc_minimum_income_floor: [7_904, 0] + +- name: Net floor in 2023-24 deducts Class 2 above the lower profits threshold + period: 2023 + absolute_error_margin: 0.01 + input: + age: 30 + region: NORTH_EAST + output: + # 10.42 x 35 x 52. + uc_minimum_income_floor_gross: 18_964.40 + # (18,964.40 - 12,570) x 20%. + uc_minimum_income_floor_income_tax: 1_278.88 + # Class 2: 3.45 x 52 = 179.40. Class 4: (18,964.40 - 12,570) x 9% = 575.50. + uc_minimum_income_floor_national_insurance: 754.90 + uc_minimum_income_floor: 16_930.62 + +- name: Net floor in 2019-20 deducts 53 weeks of Class 2 + period: 2019 + absolute_error_margin: 0.01 + input: + age: 30 + region: NORTH_EAST + output: + # 8.21 x 35 x 52. + uc_minimum_income_floor_gross: 14_942.20 + # (14,942.20 - 12,500) x 20%. + uc_minimum_income_floor_income_tax: 488.44 + # Class 2: 2019-20 has 53 contribution weeks (Sundays 7 April 2019 to 5 + # April 2020), 3.00 x 53 = 159. Class 4: (14,942.20 - 8,632) x 9% = 567.92. + uc_minimum_income_floor_national_insurance: 726.92 + uc_minimum_income_floor: 13_726.84 + # Individual thresholds by work-related group and expected hours. Reg. 90(2): # "(a) 16 hours per week, in the case of a claimant who would otherwise fall # within section 20 ... or section 21 ...; or (b) the expected number of hours diff --git a/policyengine_uk/tests/policy/baseline/gov/hmrc/national_insurance/class_2/ni_class_2.yaml b/policyengine_uk/tests/policy/baseline/gov/hmrc/national_insurance/class_2/ni_class_2.yaml index 3a458e7faa..916ab75b8f 100644 --- a/policyengine_uk/tests/policy/baseline/gov/hmrc/national_insurance/class_2/ni_class_2.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/hmrc/national_insurance/class_2/ni_class_2.yaml @@ -1,13 +1,239 @@ -- name: NI Class 2 - under LPL. +# Expected values come from s.11 SSCBA 1992 as in force for each tax year +# (legislation.gov.uk point-in-time text) and the SIs that set its figures. + +# 2023-24: £3.45 a week (SI 2023/236 reg 3(a)) on profits that exceed the +# £12,570 lower profits threshold (reg 3(b)). Profits from the £6,725 small +# profits threshold up to it are treated as paid (s.11(5A)-(5B)). +- name: NI Class 2 - 2023-24, below the small profits threshold. period: 2023 input: self_employment_income: 5_000 output: ni_class_2: 0 -- name: NI Class 2 - over LPL. +- name: NI Class 2 - 2023-24, at the small profits threshold, treated as paid. + period: 2023 + input: + self_employment_income: 6_725 + output: + ni_class_2: 0 + +- name: NI Class 2 - 2023-24, between the thresholds, treated as paid. + period: 2023 + input: + self_employment_income: 10_000 + output: + ni_class_2: 0 + +- name: NI Class 2 - 2023-24, at the lower profits threshold, not liable. + period: 2023 + input: + self_employment_income: 12_570 + output: + ni_class_2: 0 + +- name: NI Class 2 - 2023-24, just above the lower profits threshold. + period: 2023 + input: + self_employment_income: 12_571 + output: + ni_class_2: 3.45 * 52 + +- name: NI Class 2 - 2023-24, above the lower profits threshold. period: 2023 input: self_employment_income: 15_000 + output: + ni_class_2: 3.45 * 52 + +- name: NI Class 2 - 2023-24, above the upper profits limit. + period: 2023 + input: + self_employment_income: 60_000 + output: + ni_class_2: 179.4 + +- name: NI Class 2 - 2023-24, over State Pension age. + period: 2023 + input: + age: 70 + self_employment_income: 60_000 + output: + ni_class_2: 0 + +# 2022-23: £3.15 a week (SI 2022/232 reg 3(a)) on profits that exceed the +# £11,908 lower profits threshold, with effect from 6 April 2022 +# (SI 2022/1329 regs 1 and 2). +- name: NI Class 2 - 2022-23, between the thresholds, treated as paid. + period: 2022 + input: + self_employment_income: 8_000 + output: + ni_class_2: 0 + +- name: NI Class 2 - 2022-23, at the lower profits threshold, not liable. + period: 2022 + input: + self_employment_income: 11_908 + output: + ni_class_2: 0 + +- name: NI Class 2 - 2022-23, above the lower profits threshold. + period: 2022 + input: + self_employment_income: 11_909 output: ni_class_2: 3.15 * 52 + +# 2021-22: £3.05 a week (unchanged from SI 2020/299) on profits of, or +# exceeding, the £6,515 small profits threshold (SI 2021/157 reg 3). +- name: NI Class 2 - 2021-22, just below the small profits threshold. + period: 2021 + input: + self_employment_income: 6_514 + output: + ni_class_2: 0 + +- name: NI Class 2 - 2021-22, at the small profits threshold. + period: 2021 + input: + self_employment_income: 6_515 + output: + ni_class_2: 3.05 * 52 + +# 2020-21: £3.05 a week from £6,475 (SI 2020/299 reg 3). +- name: NI Class 2 - 2020-21, at the small profits threshold. + period: 2020 + input: + self_employment_income: 6_475 + output: + ni_class_2: 3.05 * 52 + +# 2015-16: £2.80 a week from £5,965 (NICA 2015 Sch 1 para 3). +- name: NI Class 2 - 2015-16, just below the small profits threshold. + period: 2015 + input: + self_employment_income: 5_964 + output: + ni_class_2: 0 + +- name: NI Class 2 - 2015-16, at the small profits threshold. + period: 2015 + input: + self_employment_income: 5_965 + output: + ni_class_2: 2.8 * 52 + +# 2024-25: s.11(2) omitted from 6 April 2024 (NICs (Reduction in Rates) Act +# 2023 s.3); no compulsory Class 2. +- name: NI Class 2 - 2024-25, abolished. + period: 2024 + input: + self_employment_income: 60_000 + output: + ni_class_2: 0 + +# Relevant profits (s.11(3)) are the profits on which Class 4 is payable +# under s.15, computed under Schedule 2: after capital allowances (CAA 2001 +# s.247), the trading allowance (ITTOIA 2005 s.783AI) and loss relief (Sch 2 +# para 3). The thresholds are tested on those profits, not on +# self_employment_income. +- name: NI Class 2 - 2023-24, capital allowances take profits to the lower profits threshold. + period: 2023 + input: + self_employment_income: 13_570 + capital_allowances: 1_000 + output: + # 13,570 - 1,000 = 12,570, which does not exceed £12,570. + ni_class_4_profits: 12_570 + ni_class_2: 0 + +- name: NI Class 2 - 2023-24, capital allowances leave profits above the lower profits threshold. + period: 2023 + input: + self_employment_income: 13_571 + capital_allowances: 1_000 + output: + ni_class_4_profits: 12_571 + ni_class_2: 3.45 * 52 + +- name: NI Class 2 - 2023-24, the trading allowance takes profits below the lower profits threshold. + period: 2023 + input: + # No expenses, so the £1,000 allowance is deducted from receipts instead. + self_employment_gross_receipts: 13_000 + self_employment_income: 13_000 + output: + ni_class_4_profits: 12_000 + ni_class_2: 0 + +- name: NI Class 2 - 2023-24, a loss brought forward takes profits below the lower profits threshold. + period: 2023 + input: + self_employment_income: + 2022: 0 + 2023: 13_000 + trading_loss: + 2022: 1_000 + 2023: 0 + output: + ni_class_4_losses_brought_forward: 1_000 + ni_class_4_profits: 12_000 + ni_class_2: 0 + +- name: NI Class 2 - 2022-23, capital allowances take profits below the lower profits threshold. + period: 2022 + input: + self_employment_income: 12_500 + capital_allowances: 1_000 + output: + # 11,500 does not exceed £11,908. + ni_class_4_profits: 11_500 + ni_class_2: 0 + +- name: NI Class 2 - 2021-22, capital allowances take profits below the small profits threshold. + period: 2021 + input: + self_employment_income: 7_514 + capital_allowances: 1_000 + output: + ni_class_4_profits: 6_514 + ni_class_2: 0 + +- name: NI Class 2 - 2021-22, capital allowances leave profits at the small profits threshold. + period: 2021 + input: + self_employment_income: 7_515 + capital_allowances: 1_000 + output: + ni_class_4_profits: 6_515 + ni_class_2: 3.05 * 52 + +- name: NI Class 2 - 2015-16, the year's own trading loss takes profits below the small profits threshold. + period: 2015 + input: + self_employment_income: 6_464 + trading_loss: 500 + output: + ni_class_4_profits: 5_964 + ni_class_2: 0 + +# A full year is every contribution week in it. A contribution week starts at +# midnight between Saturday and Sunday (SI 2001/1004 reg. 1(2)), and the year's +# first week starts on the first Sunday after 5 April (HMRC NIM70200), so +# 2019-20 has 53: Sundays from 7 April 2019 to 5 April 2020. +- name: NI Class 2 - 2019-20, 53 contribution weeks. + period: 2019 + input: + self_employment_income: 10_000 + output: + # SI 2019/262 reg 3: £3.00 a week from £6,365. + ni_class_2: 3 * 53 + +- name: NI Class 2 - 2020-21, 52 contribution weeks. + period: 2020 + input: + self_employment_income: 10_000 + output: + # Sundays from 12 April 2020 to 4 April 2021. + ni_class_2: 3.05 * 52 diff --git a/policyengine_uk/tests/policy/baseline/gov/hmrc/national_insurance/class_4/ni_class_4.yaml b/policyengine_uk/tests/policy/baseline/gov/hmrc/national_insurance/class_4/ni_class_4.yaml index 7e59dec612..269e59e34f 100644 --- a/policyengine_uk/tests/policy/baseline/gov/hmrc/national_insurance/class_4/ni_class_4.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/hmrc/national_insurance/class_4/ni_class_4.yaml @@ -1,10 +1,75 @@ +# Expected values come from s.15(3) and (3ZA) SSCBA 1992 as in force for +# each tax year and, where Class 1 or Class 2 is also payable, the regulation +# 100 annual maximum of SI 2001/1004 (worked through below; it never binds in +# these sole-trader cases). + - name: NI Class 4 - under UPL. + # 2023-24: 9% between £12,570 and £50,270 (s.15(3)(a), (3ZA)(a) as at + # 6 April 2023). (30,000 - 12,570) x 9% = 1,568.70. + # Reg 100: Class 2 is 52 x £3.45 = £179.40. Step 4 = 37,700 x 9% + # + 53 x 3.45 - 179.40 = 3,396.45, which exceeds 179.40 + 1,568.70, so + # Case 1 caps Class 4 at 3,396.45; it does not bind. period: 2023 - absolute_error_margin: 1 + absolute_error_margin: 0.01 + input: + self_employment_income: 30_000 + output: + ni_class_4: 1_568.70 + +- name: NI Class 4 - 2022-23 main rate of 9.73% on profits over £11,908. + # Health and Social Care Levy (Repeal) Act 2022 s.2(2)(a); NICs (Increase + # of Thresholds) Act 2022 s.2(1). (30,000 - 11,908) x 9.73% = 1,760.35. + # Reg 100 (as modified for 2022-23): Class 2 is 52 x £3.15 = £163.80. + # Step 4 = 38,362 x 9.73% + 53 x 3.15 - 163.80 = 3,735.77, more than + # 163.80 + 1,760.35, so Case 1 caps at 3,735.77; it does not bind. + period: 2022 + absolute_error_margin: 0.01 input: self_employment_income: 30_000 output: - ni_class_4: 1628 + ni_class_4: 1_760.35 + +- name: NI Class 4 - 2022-23 additional rate of 2.73% over the UPL. + # s.2(2)(b) of the 2022 Repeal Act. 38,362 x 9.73% + 9,730 x 2.73% + # = 3,732.62 + 265.63 = 3,998.25. + # Reg 100: Step 4 = 3,735.77 does not exceed 163.80 + 3,732.62 (Case 2). + # Step 5 = 3,735.77 / 9.73% = 38,394.37, more than Step 6 (38,362), so + # Steps 7 and 8 are 0. Step 9 = 9,730 x 2.73% = 265.63. Maximum + # = 3,735.77 + 265.63 = 4,001.40, which does not bind. + period: 2022 + absolute_error_margin: 0.01 + input: + self_employment_income: 60_000 + output: + ni_class_4: 3_998.25 + +- name: NI Class 4 - 2015-16 upper profits limit of £42,385. + # SI 2015/588 art 3: limits £8,060 and £42,385; rates 9% and 2%. + # (42,385 - 8,060) x 9% + (50,000 - 42,385) x 2% = 3,089.25 + 152.30 + # = 3,241.55. + # Reg 100: Class 2 is 52 x £2.80 = £145.60. Step 4 = 3,089.25 + # + 53 x 2.80 - 145.60 = 3,092.05, below 145.60 + 3,089.25 (Case 2). + # Step 5 = 34,356.11 exceeds Step 6 (34,325), so Step 8 is 0. Step 9 + # = 7,615 x 2% = 152.30. Maximum 3,244.35, which does not bind. + period: 2015 + absolute_error_margin: 0.01 + input: + self_employment_income: 50_000 + output: + ni_class_4: 3_241.55 + +- name: NI Class 4 - 2016-17 upper profits limit of £43,000. + # SI 2016/343 reg 2. (43,000 - 8,060) x 9% + 7,000 x 2% = 3,144.60 + # + 140 = 3,284.60. + # Reg 100: Step 4 = 3,144.60 + 148.40 - 145.60 = 3,147.40 (Case 2). + # Step 5 = 34,971.11 exceeds Step 6 (34,940); Step 9 = 140. Maximum + # 3,287.40, which does not bind. + period: 2016 + absolute_error_margin: 0.01 + input: + self_employment_income: 50_000 + output: + ni_class_4: 3_284.60 - name: NI Class 4 - 2026 lower profits limit is frozen. period: 2026 diff --git a/policyengine_uk/tests/policy/baseline/gov/hmrc/national_insurance/class_4/ni_class_4_main.yaml b/policyengine_uk/tests/policy/baseline/gov/hmrc/national_insurance/class_4/ni_class_4_main.yaml index c4189d2a66..a4c4d5e375 100644 --- a/policyengine_uk/tests/policy/baseline/gov/hmrc/national_insurance/class_4/ni_class_4_main.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/hmrc/national_insurance/class_4/ni_class_4_main.yaml @@ -1,7 +1,20 @@ - name: NI Class 4 - over UPL has maximum capped. + # 2023-24: 9% of profits between £12,570 and £50,270 (SSCBA 1992 + # s.15(3)(a) and (3ZA)(a) as at 6 April 2023). (50,270 - 12,570) x 9% + # = 3,393. period: 2023 - absolute_error_margin: 1 + absolute_error_margin: 0.01 input: self_employment_income: 100_000 output: - ni_class_4_main: 3452 + ni_class_4_main: 3_393 + +- name: NI Class 4 - 2022-23 main band at 9.73%. + # Health and Social Care Levy (Repeal) Act 2022 s.2(2)(a); NICs (Increase + # of Thresholds) Act 2022 s.2(1). (50,270 - 11,908) x 9.73% = 3,732.62. + period: 2022 + absolute_error_margin: 0.01 + input: + self_employment_income: 100_000 + output: + ni_class_4_main: 3_732.62 diff --git a/policyengine_uk/tests/policy/baseline/gov/hmrc/national_insurance/class_4/ni_class_4_maximum.yaml b/policyengine_uk/tests/policy/baseline/gov/hmrc/national_insurance/class_4/ni_class_4_maximum.yaml index f1f8ea9999..b4d76c29ec 100644 --- a/policyengine_uk/tests/policy/baseline/gov/hmrc/national_insurance/class_4/ni_class_4_maximum.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/hmrc/national_insurance/class_4/ni_class_4_maximum.yaml @@ -1,8 +1,44 @@ - name: NI Class 4 with employment and self-employment income - over UPL has maximum capped. + # SI 2001/1004 reg 100(3) as at 6 April 2023, with the 2023-24 SSCBA 1992 + # amounts: lower profits limit £12,570, upper £50,270, main 9%, + # additional 2% (s.15(3), (3ZA)) and Class 2 of £3.45 a week (s.11(2)). + # Step 1: 50,270 - 12,570 = 37,700. Step 2: 37,700 x 9% = 3,393. + # Step 3: 3,393 + 53 x 3.45 = 3,575.85. + # Step 4: less Class 2 of 52 x 3.45 = 179.40 and primary Class 1 at the + # main percentage on £100,000 of pay. With pay spread over the year that is + # at least 10% (the lowest main primary percentage in 2023-24; a director's + # annual rate was 11.5%) of the £37,700 between the primary threshold and + # the upper earnings limit, £3,770, so Step 4 is negative: Case 3, treated + # as nil. The model charges 12%, £4,524. + # Step 5: 0. Step 6: min(50,270, 100,000) - 12,570 = 37,700. + # Step 7: 37,700 - 0 = 37,700. Step 8: 37,700 x 2% = 754. + # Step 9: (100,000 - 50,270) x 2% = 994.60. + # Maximum (Steps 4 + 8 + 9): 0 + 754 + 994.60 = 1,748.60. period: 2023 - absolute_error_margin: 1 + absolute_error_margin: 0.01 input: self_employment_income: 100_000 employment_income: 100_000 output: - ni_class_4_maximum: 3_083.22 + ni_class_4_maximum: 1_748.60 + ni_class_4: 1_748.60 + +- name: NI Class 4 maximum in 2022-23 uses the 2.73% additional rate. + # Reg 100 as modified for 2022-23 by the Health and Social Care Levy + # (Repeal) Act 2022 Sch para 6(2): 9.73% in Step 2, 100/9.73 in Step 5, + # 2.73% in Steps 8 and 9. Limits £11,908 and £50,270. + # Step 3: 38,362 x 9.73% + 53 x 3.15 = 3,899.57. Step 4 less Class 2 of + # 52 x 3.15 = 163.80 and primary Class 1 on £100,000 of pay, at least + # 12% of the £37,700 between £12,570 and £50,270 (£4,524), is negative: + # Case 3, nil. + # Step 7 = Step 6 = 50,270 - 11,908 = 38,362. Step 8: 38,362 x 2.73% + # = 1,047.28. Step 9: 49,730 x 2.73% = 1,357.63. + # Maximum: 0 + 1,047.28 + 1,357.63 = 2,404.91. + period: 2022 + absolute_error_margin: 0.01 + input: + self_employment_income: 100_000 + employment_income: 100_000 + output: + ni_class_4_maximum: 2_404.91 + ni_class_4: 2_404.91 diff --git a/policyengine_uk/tests/test_ni_class_2.py b/policyengine_uk/tests/test_ni_class_2.py new file mode 100644 index 0000000000..bae597bddf --- /dev/null +++ b/policyengine_uk/tests/test_ni_class_2.py @@ -0,0 +1,288 @@ +"""Class 2 National Insurance against s.11 SSCBA 1992, tax year by tax year. + +STATUTE holds each tax year's figures as enacted, read from legislation.gov.uk +(the amending instrument's made text and the point-in-time text of s.11), +independently of the parameter files. CONTRIBUTION_WEEKS holds each year's +contribution weeks, counted from the calendar: a contribution week starts at +midnight between Saturday and Sunday (SI 2001/1004 reg. 1(2)) and the year's +first week on the first Sunday after 5 April (HMRC NIM70200). + +The thresholds apply to relevant profits: the profits on which Class 4 is +payable under s.15, computed under Schedule 2 (s.11(3)). Here the inputs are +profit, whole-pound capital allowances (CAA 2001 s.247) and a whole-pound +trading loss made in the same year (Sch 2 para 3), with no gross receipts, so +relevant profits are profit less both. A profit of £1,000 or less is treated +as covered by the trading allowance from 2017-18, when the allowance starts, +and then gives nil relevant profits; that never changes liability, because +every threshold is far above £1,000. The trading allowance with gross +receipts, and losses brought forward, are covered by the YAML cases. + +Invariants, for every model year 2015-2030, profits >= 0, capital allowances +>= 0 and in-year trading losses >= 0, all whole pounds apart from profits: + +1. Differential: ni_class_2 is the statutory weekly rate for each contribution + week in the year when s.11(2) makes the earner liable, and 0 otherwise. + Before 2022-23 the earner is liable on relevant profits of, or exceeding, + the small profits threshold. In 2022-23 and 2023-24 only relevant profits + that exceed the lower profits threshold are liable; relevant profits from + the small profits threshold up to it are treated as paid (s.11(5A)-(5B)), + which costs nothing. From 2024-25 s.11(2) is omitted and no one is liable. +2. ni_class_2 is either 0 or a full year at the weekly rate. +3. ni_class_2 is non-decreasing in relevant profits, so non-decreasing in + profit and non-increasing in capital allowances and losses. +4. Shared base: ni_class_2 is the s.11(2) rule applied to the model's own + ni_class_4_profits, the base Class 4 is charged on. + +Profits are stored as float32, so the reference is evaluated on the float32 +value. Allowances and losses are whole pounds, so subtracting them from a +float32 profit is exact in float32. +""" + +from fractions import Fraction + +import numpy as np +import pytest +from hypothesis import HealthCheck, given, settings +from hypothesis import strategies as st + +from policyengine_uk import Simulation +from policyengine_uk.system import system +from policyengine_uk.utils.class_2 import class_2_contribution_weeks + +# Tax year starting in April of the key: (weekly rate under s.11(2), small +# profits threshold, lower profits threshold or None where s.11(2) keys on the +# small profits threshold). A rate of 0 means s.11(2) is omitted. +STATUTE = { + 2015: ("2.80", 5_965, None), # NICA 2015 Sch 1 para 3 + 2016: ("2.80", 5_965, None), # unchanged (s.11 as at 6 April 2016) + 2017: ("2.85", 6_025, None), # SI 2017/415 reg 3 + 2018: ("2.95", 6_205, None), # SI 2018/337 reg 3 + 2019: ("3.00", 6_365, None), # SI 2019/262 reg 3 + 2020: ("3.05", 6_475, None), # SI 2020/299 reg 3 + 2021: ("3.05", 6_515, None), # SI 2021/157 reg 3; rate unchanged + 2022: ("3.15", 6_725, 11_908), # SI 2022/232 reg 3; SI 2022/1329 reg 2 + 2023: ("3.45", 6_725, 12_570), # SI 2023/236 reg 3; SPT unchanged + 2024: ("0", 6_725, None), # s.11(2) omitted: NICRRA 2023 (c. 57) s.3 + 2025: ("0", 6_845, None), # SI 2025/288 reg 3(a) + 2026: ("0", 7_105, None), # SI 2026/231 reg 3(a) +} +# Contribution weeks: one per Sunday from 6 April to the next 5 April. A year +# has 53 when 6 April is a Sunday, or when 6 April is a Saturday and the year +# has 366 days. 2019-20 runs from Sunday 7 April 2019 to Sunday 5 April 2020 +# (29 February 2020 included); 2025-26 from Sunday 6 April 2025 to Sunday 5 +# April 2026. Every other year from 2015-16 to 2030-31 has 52; 2024-25, for +# one, runs from Sunday 7 April 2024 to Sunday 30 March 2025. +CONTRIBUTION_WEEKS = {2019: 53, 2025: 53} +MODEL_YEARS = list(range(2015, 2031)) +PROPERTY_SETTINGS = settings( + max_examples=10, + deadline=None, + derandomize=True, + suppress_health_check=[HealthCheck.too_slow, HealthCheck.data_too_large], +) + + +def statute(year): + # Class 2 stays abolished after the last tabulated year. + return STATUTE[min(year, max(STATUTE))] + + +def weeks(year): + return CONTRIBUTION_WEEKS.get(year, 52) + + +def relevant_profits(profits, capital_allowances=0, trading_loss=0): + # s.11(3): the Class 4 profits, here profit less capital allowances and + # the year's trading loss. + exact = Fraction(float(np.float32(profits))) - capital_allowances - trading_loss + return max(exact, Fraction(0)) + + +def statutory_class_2(year, profits, capital_allowances=0, trading_loss=0): + rate, small_profits_threshold, lower_profits_threshold = statute(year) + profits = relevant_profits(profits, capital_allowances, trading_loss) + if lower_profits_threshold is None: + liable = profits >= small_profits_threshold + else: + liable = profits > lower_profits_threshold + return weeks(year) * Fraction(rate) if liable else Fraction(0) + + +# Every threshold s.11 has used, with points either side of each. +THRESHOLD_PROFITS = sorted( + {0.0} + | { + float(threshold) + offset + for _, spt, lpt in STATUTE.values() + for threshold in filter(None, (spt, lpt)) + for offset in (-1, -0.01, 0, 0.01, 1) + } +) + + +# Whole-pound capital allowances and trading losses that move profits across +# each threshold. +CAPITAL_ALLOWANCES = [0, 500, 1_000, 2_500] +TRADING_LOSSES = [0, 750] + + +def simulate(cases): + # One person per (profits, capital allowances, trading loss) case, with + # the same values in every model year, so a single simulation covers every + # year. Each year's loss is no more than its profits after allowances, so + # none is carried forward, except where a profit of £1,000 or less is + # relieved by the trading allowance from 2017-18: that loss carries + # forward, but those cases stay below every threshold. + people = { + f"p{i}": { + "age": {year: 40 for year in MODEL_YEARS}, + "self_employment_income": {year: profits for year in MODEL_YEARS}, + "capital_allowances": {year: allowances for year in MODEL_YEARS}, + "trading_loss": {year: loss for year in MODEL_YEARS}, + } + for i, (profits, allowances, loss) in enumerate(cases) + } + return Simulation( + situation={ + "people": people, + "benunits": {f"b{i}": {"members": [f"p{i}"]} for i in range(len(people))}, + "households": {f"h{i}": {"members": [f"p{i}"]} for i in range(len(people))}, + } + ) + + +def gross(relevant, allowances=0, loss=0): + # The profit whose relevant profits are `relevant`. + return (float(relevant) + allowances + loss, allowances, loss) + + +def assert_invariants(cases): + cases = [ + tuple(case) + (0,) * (3 - len(case)) + if isinstance(case, tuple) + else (case, 0, 0) + for case in cases + ] + sim = simulate(cases) + relevant = [relevant_profits(*case) for case in cases] + order = sorted(range(len(cases)), key=lambda i: relevant[i]) + for year in MODEL_YEARS: + class_2 = sim.calculate("ni_class_2", year) + class_4_profits = sim.calculate("ni_class_4_profits", year) + full_year = weeks(year) * float(statute(year)[0]) + for i, case in enumerate(cases): + expected = float(statutory_class_2(year, *case)) + assert class_2[i] == pytest.approx(expected, abs=0.01), (year, case) + assert class_2[i] == 0 or class_2[i] == pytest.approx(full_year, abs=0.01) + shared_base = float(statutory_class_2(year, class_4_profits[i])) + assert class_2[i] == pytest.approx(shared_base, abs=0.01), (year, case) + assert np.all(np.diff(class_2[order]) >= 0), (year, cases, class_2) + + +@pytest.mark.parametrize("year", sorted(STATUTE)) +def test_class_2_parameters_match_statute(year): + class_2 = system.parameters(f"{year}-01-01").gov.hmrc.national_insurance.class_2 + rate, small_profits_threshold, lower_profits_threshold = STATUTE[year] + + assert class_2.flat_rate == pytest.approx(float(rate)) + assert class_2.small_profits_threshold == small_profits_threshold + if Fraction(rate) > 0: + assert class_2.lower_profits_threshold_applies == ( + lower_profits_threshold is not None + ) + if lower_profits_threshold is not None: + assert class_2.lower_profits_threshold == lower_profits_threshold + + +@pytest.mark.parametrize("year", MODEL_YEARS) +def test_contribution_weeks_follow_the_calendar(year): + assert class_2_contribution_weeks(year) == weeks(year) + + +def test_contribution_weeks_match_hmrc_example(): + # NIM70200: "The first contribution week of the 2021 to 2022 tax year + # starts on Sunday, 11 April 2021 and the last contribution week of that + # year ends on Saturday, 9 April 2022": 364 days, 52 weeks. + assert class_2_contribution_weeks(2021) == 52 + + +def test_ni_class_2_matches_statute_at_every_threshold(): + rng = np.random.default_rng(1_992) + spread = list(rng.uniform(0, 200_000, 200).round(2)) + assert_invariants(THRESHOLD_PROFITS + spread + [60_000.0, 1_000_000.0]) + + +def test_ni_class_2_tests_thresholds_on_profits_after_deductions(): + # Profits set so that profit less capital allowances and the year's loss + # lands on, and either side of, every threshold s.11 has used. + assert_invariants( + [ + gross(relevant, allowances, loss) + for relevant in THRESHOLD_PROFITS + for allowances in CAPITAL_ALLOWANCES + for loss in TRADING_LOSSES + if allowances or loss + ] + ) + + +@PROPERTY_SETTINGS +@given( + st.lists( + st.builds( + gross, + st.one_of( + st.sampled_from(THRESHOLD_PROFITS), + st.floats(0, 200_000, allow_nan=False, allow_infinity=False), + st.integers(0, 200_000).map(float), + ), + st.one_of(st.sampled_from(CAPITAL_ALLOWANCES), st.integers(0, 20_000)), + st.one_of(st.sampled_from(TRADING_LOSSES), st.integers(0, 20_000)), + ), + min_size=1, + max_size=24, + ) +) +def test_ni_class_2_properties(cases): + # Relevant profits are drawn first, so threshold points stay on their + # thresholds whatever allowances and losses are drawn with them. + assert_invariants(cases) + + +def test_2023_annual_maximum_uses_the_2023_24_class_2_rate(): + # Regulation 100 of SI 2001/1004 for 2023-24, at default parameters: + # Class 2 at £3.45 a week and the 2023-24 Class 4 limits and rates + # (s.15(3) and (3ZA) SSCBA 1992). Profits £60,000; primary Class 1 £3,000. + # Step 3: 9% x (50,270 - 12,570) + 53 x 3.45 = 3,393 + 182.85 + # Step 4: 3,575.85 - 179.40 (Class 2) - 3,000 (Class 1) = 396.45 + # Case 2: 396.45 + 2% x (37,700 - 396.45 / 9%) + 2% x 9,730 + year = 2023 + sim = Simulation( + situation={ + "people": { + "person": { + "age": {year: 40}, + "self_employment_income": {year: 60_000}, + "ni_class_1_employee_primary": { + f"{year}-{month:02d}": 250 for month in range(1, 13) + }, + } + }, + "benunits": {"benunit": {"members": ["person"]}}, + "households": {"household": {"members": ["person"]}}, + }, + ) + + step_4 = Fraction("0.09") * 37_700 + 53 * Fraction("3.45") - Fraction("179.40") + step_4 -= 3_000 + step_5 = step_4 / Fraction("0.09") + maximum = step_4 + Fraction("0.02") * (37_700 - step_5) + Fraction("0.02") * 9_730 + + assert sim.calculate("ni_class_2", year)[0] == pytest.approx(179.40, abs=0.01) + assert float(maximum) == pytest.approx(1_256.95, abs=0.005) + assert sim.calculate("ni_class_4_maximum", year)[0] == pytest.approx( + float(maximum), abs=0.01 + ) + assert sim.calculate("ni_class_4", year)[0] == pytest.approx( + float(maximum), abs=0.01 + ) diff --git a/policyengine_uk/tests/test_ni_class_4_properties.py b/policyengine_uk/tests/test_ni_class_4_properties.py index 64178ccc94..15d6ba4fa7 100644 --- a/policyengine_uk/tests/test_ni_class_4_properties.py +++ b/policyengine_uk/tests/test_ni_class_4_properties.py @@ -14,15 +14,18 @@ implementation of s.15(3) SSCBA 1992 capped by the literal regulation 100 steps (with the Case 1 comparison done exactly). The one exception is a Case 1 tie that holds in real numbers but not in binary (before April - 2024: 53 x weekly Class 2 = 2 x (Class 1 + Class 2), UPL below the small - profits threshold); the model then follows the real-valued tie. + 2024: 53 x weekly Class 2 = 2 x (Class 1 + Class 2), UPL below the profits + at which Class 2 becomes payable); the model then follows the real-valued + tie. 3. The maximum only ever reduces liability: 0 <= ni_class_4 <= the pre-maximum amount. 4. Monotonicity: with employment income held fixed, ni_class_4 is non-decreasing in self-employment profits wherever Class 2 does not change. Before April 2024 regulation 100 subtracts Class 2, so crossing - the small profits threshold can lower Class 4; Class 2 + Class 4 is then - still non-decreasing when the main rate is at least the additional rate. + the profits at which Class 2 becomes payable (the small profits threshold, + or from 2022-23 the Class 2 lower profits threshold) can lower Class 4; + Class 2 + Class 4 is then still non-decreasing when the main rate is at + least the additional rate. Class 2 counts in regulation 100 only before 6 April 2024 (SI 2024/377). diff --git a/policyengine_uk/tests/test_ni_class_4_statute.py b/policyengine_uk/tests/test_ni_class_4_statute.py new file mode 100644 index 0000000000..c352ef9687 --- /dev/null +++ b/policyengine_uk/tests/test_ni_class_4_statute.py @@ -0,0 +1,361 @@ +"""Class 4 National Insurance against s.15 SSCBA 1992 and regulation 100 of +SI 2001/1004, tax year by tax year. + +CLASS_4 and CLASS_2 hold each tax year's figures as enacted, read from +legislation.gov.uk (the amending instrument's made or enacted text and the +point-in-time text of s.11 and s.15), independently of the parameter files. + +Invariants, for every tax year from 2015-16 to 2026-27, profits >= 0 and +primary Class 1 contributions >= 0: + +1. Parameters: the model's Class 4 limits and rates are the statutory ones. +2. Differential: ni_class_4 equals an exact-rational reference. That is the + s.15(3) amount on the full profits, capped by the regulation 100 maximum + where primary Class 1 or, before 2024-25, Class 2 contributions are + payable. Regulation 100's percentages are the year's Class 4 rates: 9% and + 2%, but 9.73% and 2.73% in 2022-23 (Health and Social Care Levy (Repeal) + Act 2022 Sch para 6(2)); from 2024-25, 6% and 100/6 in Steps Two and Five + (National Insurance Contributions (Reduction in Rates) Act 2024 s 2(3)) + with Steps Eight and Nine still at 2%. Before 2024-25 Step Three adds 53 + weekly Class 2 contributions and Step Four subtracts the Class 2 paid. +3. Bounds: 0 <= ni_class_4 <= the s.15(3) amount. +4. ni_class_4_main is the main-rate band of s.15(3)(a) alone. + +The model stores amounts as float32, so the reference reads profits and +Class 1 back from the simulation and comparisons allow a few float32 ulps. +""" + +from fractions import Fraction + +import numpy as np +import pytest +from hypothesis import HealthCheck, given, settings +from hypothesis import strategies as st + +from policyengine_uk import Simulation +from policyengine_uk.system import system + +# Tax year starting in April of the key: (lower profits limit, upper profits +# limit, main Class 4 percentage, additional Class 4 percentage). +CLASS_4 = { + 2015: (8_060, 42_385, "0.09", "0.02"), # SI 2015/588 art 3; NICA 2011 s.2 + 2016: (8_060, 43_000, "0.09", "0.02"), # SI 2016/343 reg 2 + 2017: (8_164, 45_000, "0.09", "0.02"), # SI 2017/415 reg 5 + 2018: (8_424, 46_350, "0.09", "0.02"), # SI 2018/337 reg 5 + 2019: (8_632, 50_000, "0.09", "0.02"), # SI 2019/262 reg 5 + 2020: (9_500, 50_000, "0.09", "0.02"), # SI 2020/299 reg 5 + 2021: (9_568, 50_270, "0.09", "0.02"), # SI 2021/157 reg 5 + # NICs (Increase of Thresholds) Act 2022 s.2(1)-(2); Health and Social + # Care Levy (Repeal) Act 2022 s.2(2). + 2022: (11_908, 50_270, "0.0973", "0.0273"), + 2023: ( + 12_570, + 50_270, + "0.09", + "0.02", + ), # NICs (Increase of Thresholds) Act 2022 s.2(3) + 2024: (12_570, 50_270, "0.06", "0.02"), # NICs (Reduction in Rates) Act 2024 s.1(3) + 2025: (12_570, 50_270, "0.06", "0.02"), + 2026: (12_570, 50_270, "0.06", "0.02"), +} +# Class 2 under s.11(2), which regulation 100 counts before 2024-25: +# (weekly rate, threshold, True where liability needs profits that exceed the +# lower profits threshold rather than profits of, or exceeding, the small +# profits threshold). From 2024-25 s.11(2) is omitted (NICs (Reduction in +# Rates) Act 2023 s.3) and Class 2 leaves regulation 100 (SI 2024/377 reg 6(5)). +CLASS_2 = { + 2015: ("2.80", 5_965, False), # NICA 2015 Sch 1 para 3 + 2016: ("2.80", 5_965, False), + 2017: ("2.85", 6_025, False), # SI 2017/415 reg 3 + 2018: ("2.95", 6_205, False), # SI 2018/337 reg 3 + 2019: ("3.00", 6_365, False), # SI 2019/262 reg 3 + 2020: ("3.05", 6_475, False), # SI 2020/299 reg 3 + 2021: ("3.05", 6_515, False), # SI 2021/157 reg 3 + 2022: ("3.15", 11_908, True), # SI 2022/232 reg 3; SI 2022/1329 reg 2 + 2023: ("3.45", 12_570, True), # SI 2023/236 reg 3 +} +YEARS = sorted(CLASS_4) +# A full year of Class 2 is one weekly contribution per contribution week: +# one per Sunday from 6 April to the next 5 April (SI 2001/1004 reg 1(2); +# HMRC NIM70200). 2019-20 has 53 (Sundays 7 April 2019 to 5 April 2020); the +# other years with Class 2 have 52. +CONTRIBUTION_WEEKS = {2019: 53} +PROPERTY_SETTINGS = settings( + max_examples=6, + deadline=None, + derandomize=True, + suppress_health_check=[HealthCheck.too_slow, HealthCheck.data_too_large], +) + + +def exact(x): + return Fraction(float(x)) + + +def statutory_class_2(year, profits): + if year not in CLASS_2: + return Fraction(0) + rate, threshold, exceed = CLASS_2[year] + liable = profits > threshold if exceed else profits >= threshold + weeks = CONTRIBUTION_WEEKS.get(year, 52) + return weeks * Fraction(rate) if liable else Fraction(0) + + +def statutory_class_4(year, profits, class_1): + """Class 4 for `year` on `profits` with `class_1` primary Class 1. + + Returns every amount regulation 100 allows: two where Step Four equals + the Case 1 aggregate to within float32 noise, one otherwise. + """ + lpl, upl, main, additional = CLASS_4[year] + main, additional = Fraction(main), Fraction(additional) + main_band = main * min(max(profits - lpl, 0), upl - lpl) + s15_amount = main_band + additional * max(profits - upl, 0) + class_2 = statutory_class_2(year, profits) + if not (class_1 > 0 or class_2 > 0): + return s15_amount, {s15_amount} + + step_3 = (upl - lpl) * main + if year in CLASS_2: + step_3 += 53 * Fraction(CLASS_2[year][0]) + step_4 = step_3 - class_2 - class_1 + aggregate = class_1 + class_2 + main_band + + def case_2_or_3(): + floored = max(step_4, 0) + step_7 = max(min(upl, profits) - lpl - floored / main, 0) + return floored + step_7 * additional + max(profits - upl, 0) * additional + + maxima = set() + if step_4 > 0 and step_4 >= aggregate - Fraction(1, 10**6): + maxima.add(step_4) # Case 1 + if not (step_4 > 0 and step_4 > aggregate + Fraction(1, 10**6)): + maxima.add(case_2_or_3()) + return s15_amount, {min(s15_amount, maximum) for maximum in maxima} + + +def tolerance(*amounts): + return 0.01 + 4e-7 * max(abs(float(a)) for a in amounts) + + +def simulate(people, years=YEARS): + """One person per (profits, annual primary Class 1) pair, the same in + every year, so one simulation covers every tax year. Class 1 is entered + in January so the annual sum is exact.""" + return Simulation( + situation={ + "people": { + f"p{i}": { + "age": {year: 40 for year in years}, + "self_employment_income": {year: profits for year in years}, + "ni_class_1_employee_primary": { + f"{year}-01": class_1 for year in years + }, + } + for i, (profits, class_1) in enumerate(people) + }, + "benunits": {f"b{i}": {"members": [f"p{i}"]} for i in range(len(people))}, + "households": {f"h{i}": {"members": [f"p{i}"]} for i in range(len(people))}, + } + ) + + +@pytest.mark.parametrize("year", YEARS) +def test_class_4_parameters_match_statute(year): + class_4 = system.parameters(f"{year}-01-01").gov.hmrc.national_insurance.class_4 + lpl, upl, main, additional = CLASS_4[year] + + assert class_4.thresholds.lower_profits_limit == lpl + assert class_4.thresholds.upper_profits_limit == upl + assert class_4.rates.main == pytest.approx(float(main), abs=1e-12) + assert class_4.rates.additional == pytest.approx(float(additional), abs=1e-12) + assert class_4.annual_maximum.includes_class_2 == (year in CLASS_2) + + +# Hand-derived liabilities, with regulation 100 Cases 1, 2 and 3 in each +# regime (to 2021-22, 2022-23, 2023-24 and from 2024-25). Class 1 is the +# year's primary Class 1 at the main percentage. Amounts in pounds; +# regulation 100 steps are numbered as in reg 100(3) and "max" is the reg 100 +# maximum. +HAND_DERIVED = [ + # 2015-16. s.15(3): 9% x (42,385 - 8,060) + 2% x (50,000 - 42,385) + # = 3,089.25 + 152.30 = 3,241.55. Class 2 52 x 2.80 = 145.60. + # Step 4 = 3,089.25 + 53 x 2.80 - 145.60 = 3,092.05 < 145.60 + 3,089.25 + # (Case 2); Step 5 = 34,356.11 > Step 6 = 34,325, so max = 3,092.05 + # + 2% x 7,615 = 3,244.35. Not binding. + (2015, 50_000, 0, 145.60, 3_241.55), + # 2016-17. 9% x (43,000 - 8,060) + 2% x 7,000 = 3,144.60 + 140 + # = 3,284.60. Max = 3,147.40 + 140 = 3,287.40. + (2016, 50_000, 0, 145.60, 3_284.60), + # 2017-18. 9% x (30,000 - 8,164) = 1,965.24. Class 2 52 x 2.85 + # = 148.20. Step 4 = 9% x 36,836 + 53 x 2.85 - 148.20 = 3,318.09 + # exceeds 148.20 + 1,965.24 (Case 1). Not binding. + (2017, 30_000, 0, 148.20, 1_965.24), + # 2018-19. 9% x (46,350 - 8,424) + 2% x (60,000 - 46,350) = 3,413.34 + # + 273 = 3,686.34. Class 2 52 x 2.95 = 153.40. Step 4 = 3,413.34 + # + 156.35 - 153.40 = 3,416.29 (Case 2); Step 5 = 37,958.78 > 37,926; + # max = 3,416.29 + 273 = 3,689.29. Not binding. + (2018, 60_000, 0, 153.40, 3_686.34), + # 2019-20 with £2,000 of Class 1. s.15(3): 9% x (50,000 - 8,632) + # = 3,723.12. Class 2 53 x 3 = 159 (53 contribution weeks). Step 4 + # = 3,723.12 + 159 - 159 - 2,000 = 1,723.12 (Case 2). Step 5 = 1,723.12 + # / 9% = 19,145.78; Step 7 = 41,368 - 19,145.78 = 22,222.22; Step 8 + # = 444.44. Max = 1,723.12 + 444.44 = 2,167.56. Binding. + (2019, 50_000, 2_000, 159.00, 2_167.56), + # 2019-20 with £6,000 of Class 1. Step 4 = 3,723.12 + 159 - 159 - 6,000 + # < 0 (Case 3, nil). Step 7 = Step 6 = 50,000 - 8,632 = 41,368; + # Step 8 = 2% x 41,368 = 827.36; Step 9 = 0. Max = 827.36. Binding. + (2019, 50_000, 6_000, 159.00, 827.36), + # 2020-21. 9% x (20,000 - 9,500) = 945. Class 2 52 x 3.05 = 158.60. + (2020, 20_000, 0, 158.60, 945.00), + # 2021-22 at the lower profits limit: Class 2 (profits of, or exceeding, + # £6,515) but no Class 4. + (2021, 9_568, 0, 158.60, 0), + # 2022-23 at £11,908: Class 2 needs profits that exceed the lower + # profits threshold, and Class 4 profits above the limit. + (2022, 11_908, 0, 0, 0), + # 2022-23. 9.73% x (30,000 - 11,908) = 1,760.35. Class 2 52 x 3.15 + # = 163.80. Step 4 = 9.73% x 38,362 + 53 x 3.15 - 163.80 = 3,735.77 + # (Case 1). Not binding. + (2022, 30_000, 0, 163.80, 1_760.35), + # 2022-23. 9.73% x 38,362 + 2.73% x 9,730 = 3,732.62 + 265.63 + # = 3,998.25. Step 4 = 3,735.77 does not exceed 163.80 + 3,732.62 + # (Case 2). Step 5 = 3,735.77 / 9.73% = 38,394.37 exceeds Step 6 + # (38,362), so Step 8 is 0; Step 9 = 265.63. Max = 4,001.40. + (2022, 60_000, 0, 163.80, 3_998.25), + # 2022-23 with £6,000 of Class 1. Step 4 = 3,899.57 - 163.80 - 6,000 < 0 + # (Case 3). Max = 2.73% x 38,362 + 2.73% x 49,730 = 1,047.28 + # + 1,357.63 = 2,404.91. + (2022, 100_000, 6_000, 163.80, 2_404.91), + # 2023-24. 9% x (30,000 - 12,570) = 1,568.70. Class 2 52 x 3.45 + # = 179.40. Case 1, not binding. + (2023, 30_000, 0, 179.40, 1_568.70), + # 2023-24 at £12,570: no Class 2 (not exceeding) and no Class 4. + (2023, 12_570, 0, 0, 0), + # 2023-24 with £3,000 of Class 1. Step 4 = 3,393 + 182.85 - 179.40 + # - 3,000 = 396.45 (Case 2). Step 5 = 4,405; Step 7 = 37,700 - 4,405 + # = 33,295; Step 8 = 665.90; Step 9 = 2% x 9,730 = 194.60. + # Max = 396.45 + 665.90 + 194.60 = 1,256.95. Binding. + (2023, 60_000, 3_000, 179.40, 1_256.95), + # 2023-24 with £6,000 of Class 1. Step 4 = 3,575.85 - 179.40 - 6,000 + # < 0 (Case 3, nil). Max = 2% x 37,700 + 2% x 49,730 = 754 + 994.60 + # = 1,748.60. Binding (s.15(3): 3,393 + 994.60 = 4,387.60). + (2023, 100_000, 6_000, 179.40, 1_748.60), + # 2024-25 with £1,000 of Class 1. s.15(3): 6% x 37,700 + 2% x 9,730 + # = 2,262 + 194.60 = 2,456.60. No Class 2 and no Step Three. + # Step 4 = 2,262 - 1,000 = 1,262 (Case 2). Step 5 = 21,033.33; + # Step 7 = 16,666.67; Step 8 = 333.33. Max = 1,262 + 333.33 + 194.60 + # = 1,789.93. Binding. + (2024, 60_000, 1_000, 0, 1_789.93), + # 2024-25 with £200 of Class 1. 6% x 7,430 = 445.80. Step 4 = 2,062 + # exceeds 200 + 445.80 (Case 1). Not binding. + (2024, 20_000, 200, 0, 445.80), + # 2025-26, no Class 1: regulation 100 does not apply. + # 6% x (30,000 - 12,570) = 1,045.80. + (2025, 30_000, 0, 0, 1_045.80), + # 2026-27 with £6,000 of Class 1. Step 4 = 2,262 - 6,000 < 0 (Case 3). + # Max = 2% x 37,700 + 2% x 49,730 = 754 + 994.60 = 1,748.60. + (2026, 100_000, 6_000, 0, 1_748.60), +] + + +@pytest.fixture(scope="module") +def hand_derived_simulation(): + # One person per row, with the row's inputs in every year; each case + # reads its own person in its own year. + return simulate([(profits, class_1) for _, profits, class_1, _, _ in HAND_DERIVED]) + + +@pytest.mark.parametrize( + "row", + range(len(HAND_DERIVED)), + ids=[ + f"{year}-{profits}-{class_1}" for year, profits, class_1, _, _ in HAND_DERIVED + ], +) +def test_class_2_and_class_4_hand_derived(hand_derived_simulation, row): + year, profits, class_1, class_2, class_4 = HAND_DERIVED[row] + sim = hand_derived_simulation + assert sim.calculate("ni_class_1_employee_primary", year)[row] == class_1 + assert sim.calculate("ni_class_2", year)[row] == pytest.approx(class_2, abs=0.01) + assert sim.calculate("ni_class_4", year)[row] == pytest.approx(class_4, abs=0.01) + # The table is independent arithmetic; the reference must agree with it. + _, allowed = statutory_class_4(year, Fraction(profits), Fraction(class_1)) + assert any(abs(float(a) - class_4) < 0.005 for a in allowed), allowed + + +def assert_matches_statute(people): + sim = simulate(people) + for year in YEARS: + lpl, upl, main, _ = CLASS_4[year] + profits = sim.calculate("self_employment_income", year) + class_1 = sim.calculate("ni_class_1_employee_primary", year) + class_2 = sim.calculate("ni_class_2", year) + class_4 = sim.calculate("ni_class_4", year) + class_4_main = sim.calculate("ni_class_4_main", year) + for i in range(len(people)): + p, c1 = exact(profits[i]), exact(class_1[i]) + s15_amount, allowed = statutory_class_4(year, p, c1) + tol = tolerance(p, upl, s15_amount) + assert float(class_2[i]) == pytest.approx( + float(statutory_class_2(year, p)), abs=0.01 + ), (year, people[i]) + assert any(abs(float(class_4[i]) - float(a)) <= tol for a in allowed), ( + year, + people[i], + float(class_4[i]), + [float(a) for a in allowed], + ) + assert -tol <= float(class_4[i]) <= float(s15_amount) + tol + main_band = Fraction(main) * min(max(p - lpl, 0), upl - lpl) + assert abs(float(class_4_main[i]) - float(main_band)) <= tol + + +# Every limit and threshold used from 2015-16 to 2026-27, with points either +# side, each with no Class 1 and with Class 1 that reaches each case. +THRESHOLD_PROFITS = sorted( + {0.0, 100_000.0} + | { + float(limit) + offset + for lpl, upl, _, _ in CLASS_4.values() + for limit in (lpl, upl) + for offset in (-1, -0.01, 0, 0.01, 1) + } + | { + float(threshold) + offset + for _, threshold, _ in CLASS_2.values() + for offset in (-0.01, 0, 0.01) + } +) + + +def test_class_4_matches_statute_at_every_limit(): + assert_matches_statute( + [ + (profits, class_1) + for profits in THRESHOLD_PROFITS + for class_1 in (0, 250, 1_500, 6_000) + ] + ) + + +@PROPERTY_SETTINGS +@given( + st.lists( + st.tuples( + st.one_of( + st.floats(0, 300_000, allow_nan=False, allow_infinity=False), + st.integers(0, 300_000).map(float), + st.sampled_from(THRESHOLD_PROFITS), + ), + st.one_of( + st.just(0.0), + st.integers(0, 800_000).map(lambda pence: pence / 100), + ), + ), + min_size=1, + max_size=16, + ) +) +def test_class_4_matches_statute_property(people): + assert_matches_statute(people) diff --git a/policyengine_uk/tests/test_uc_minimum_income_floor_properties.py b/policyengine_uk/tests/test_uc_minimum_income_floor_properties.py index efb2dd4f19..0f7b5eeb53 100644 --- a/policyengine_uk/tests/test_uc_minimum_income_floor_properties.py +++ b/policyengine_uk/tests/test_uc_minimum_income_floor_properties.py @@ -61,9 +61,10 @@ derandomize=True, suppress_health_check=[HealthCheck.too_slow, HealthCheck.data_too_large], ) -# 2020 has 12% Class 1 NI and the temporary UC uplift; 2026 current rates; -# 2027 the Finance Act 2026 rates. -YEARS = [2020, 2026, 2027] +# 2019 has 53 Class 2 contribution weeks; 2020 has 12% Class 1 NI and the +# temporary UC uplift; 2022 and 2023 have the Class 2 lower profits +# threshold; 2026 current rates; 2027 the Finance Act 2026 rates. +YEARS = [2019, 2020, 2022, 2023, 2026, 2027] TENURES = ["RENT_FROM_COUNCIL", "RENT_PRIVATELY", "OWNED_OUTRIGHT"] REGIONS = ["LONDON", "NORTH_EAST", "WALES", "SCOTLAND"] WORKING_AGE = st.integers(18, 64) @@ -320,6 +321,28 @@ def test_matches_closed_form_of_regulation_62(units, year): ] +# A lone parent of a child aged 3 has a 16-hour threshold, which in 2022-23 +# and 2023-24 lies between the Class 2 small profits threshold and the lower +# profits threshold: Class 2 is treated as paid and costs nothing. +LONE_PARENT_16_HOURS = [ + dict( + adults=[ + dict( + age=30, + self_employment_income=3_000.0, + employment_income=0.0, + pension_contributions=0.0, + uc_is_in_startup_period=False, + ) + ], + children=[3], + tenure="RENT_PRIVATELY", + rent=7_200.0, + region="NORTH_EAST", + ) +] + + @PROPERTY_SETTINGS @given( units=populations, @@ -328,6 +351,9 @@ def test_matches_closed_form_of_regulation_62(units, year): ) @example(units=SPA_DURING_2026, year=2026, self_employed=True) @example(units=SPA_DURING_2026, year=2026, self_employed=False) +@example(units=LONE_PARENT_16_HOURS, year=2022, self_employed=True) +@example(units=LONE_PARENT_16_HOURS, year=2023, self_employed=True) +@example(units=LONE_PARENT_16_HOURS, year=2019, self_employed=True) def test_notional_deductions_equal_tax_on_threshold_as_only_income( units, year, self_employed ): diff --git a/policyengine_uk/utils/class_2.py b/policyengine_uk/utils/class_2.py new file mode 100644 index 0000000000..e15c279d74 --- /dev/null +++ b/policyengine_uk/utils/class_2.py @@ -0,0 +1,49 @@ +"""Class 2 National Insurance rules shared by ni_class_2 and by the notional +Class 2 that the Universal Credit minimum income floor deducts. + +Both charge a whole tax year of self-employment, so they share the s.11(2) +liability test and the number of contribution weeks in the year. +""" + +import datetime + +import numpy as np + + +def class_2_contribution_weeks(year: int) -> int: + """Contribution weeks in the tax year that starts on 6 April of ``year``. + + A contribution week is "a period of seven days beginning with midnight + between Saturday and Sunday" (SI 2001/1004 reg. 1(2)), and the first week + of a contribution year starts on the first Sunday after 5 April (HMRC + NIM70200). A year therefore has one week for each Sunday from 6 April to + the following 5 April: 53 in 2019-20 and 2025-26, 52 in the other years + from 2015-16 to 2026-27. NIM70200: "a person who is self-employed for the + full year will be liable for all 53 weeks." + """ + start = datetime.date(year, 4, 6) + end = datetime.date(year + 1, 4, 5) + # date.weekday() is 6 on a Sunday. + first_sunday = start + datetime.timedelta(days=(6 - start.weekday()) % 7) + return (end - first_sunday).days // 7 + 1 + + +def class_2_liable(relevant_profits, class_2): + """Whether relevant profits meet the s.11(2) SSCBA 1992 profit condition + for the year. + + From 2022-23 only relevant profits that exceed the lower profits threshold + are liable; those from the small profits threshold up to it are treated as + paid (s.11(5A)-(5B)) and cost nothing. Before then liability started at + the small profits threshold ("of, or exceeding"). ``class_2`` is the + gov.hmrc.national_insurance.class_2 parameter node for the year. + + This is the threshold condition only. Callers multiply by the flat rate, + which is nil from 2024-25, when s.11(2) is omitted; the retained + thresholds then apply only to a reform that restores a rate. + """ + return np.where( + class_2.lower_profits_threshold_applies, + relevant_profits > class_2.lower_profits_threshold, + relevant_profits >= class_2.small_profits_threshold, + ) diff --git a/policyengine_uk/variables/gov/dwp/universal_credit/income/income_floor/uc_minimum_income_floor_national_insurance.py b/policyengine_uk/variables/gov/dwp/universal_credit/income/income_floor/uc_minimum_income_floor_national_insurance.py index 88bc10ec15..19025089f2 100644 --- a/policyengine_uk/variables/gov/dwp/universal_credit/income/income_floor/uc_minimum_income_floor_national_insurance.py +++ b/policyengine_uk/variables/gov/dwp/universal_credit/income/income_floor/uc_minimum_income_floor_national_insurance.py @@ -1,4 +1,5 @@ from policyengine_uk.model_api import * +from policyengine_uk.utils.class_2 import class_2_contribution_weeks, class_2_liable class uc_minimum_income_floor_national_insurance(Variable): @@ -41,11 +42,13 @@ def formula(person, period, parameters): ) + class_1.rates.employee.additional * max_( 0, threshold - upper_earnings_limit ) - # Class 2 and Class 4 on profits equal to the threshold. + # Class 2 and Class 4 on profits equal to the threshold, by the same + # s.11(2) test and contribution weeks as ni_class_2: from 2022-23 + # profits up to the lower profits threshold are treated as paid. class_2 = ( - (threshold >= ni.class_2.small_profits_threshold) + class_2_liable(threshold, ni.class_2) * ni.class_2.flat_rate - * WEEKS_IN_YEAR + * class_2_contribution_weeks(period.start.year) ) class_4 = ni.class_4 class_4_amount = class_4.rates.main * max_( diff --git a/policyengine_uk/variables/gov/hmrc/national_insurance/class_2/ni_class_2.py b/policyengine_uk/variables/gov/hmrc/national_insurance/class_2/ni_class_2.py index a36358bb4d..7737b27751 100644 --- a/policyengine_uk/variables/gov/hmrc/national_insurance/class_2/ni_class_2.py +++ b/policyengine_uk/variables/gov/hmrc/national_insurance/class_2/ni_class_2.py @@ -1,18 +1,43 @@ from policyengine_uk.model_api import * +from policyengine_uk.utils.class_2 import class_2_contribution_weeks, class_2_liable class ni_class_2(Variable): value_type = float entity = Person label = "NI Class 2 contributions" + documentation = ( + "Compulsory Class 2 contributions under s.11(2) SSCBA 1992 for a full " + "year of self-employment: the weekly rate for each contribution week " + "in the tax year (53 in 2019-20, otherwise 52 to 2023-24). Liability " + "is tested on relevant profits, the profits on which Class 4 is " + "payable under s.15 (s.11(3)), as modelled in ni_class_4_profits." + ) definition_period = YEAR - reference = "Social Security and Benefits Act 1992 s. 11" unit = GBP defined_for = "ni_liable" - reference = "https://www.legislation.gov.uk/ukpga/1992/4/section/11" + reference = [ + dict( + title="Social Security Contributions and Benefits Act 1992, s. 11", + href="https://www.legislation.gov.uk/ukpga/1992/4/section/11", + ), + dict( + title="HMRC National Insurance Manual NIM70650", + href="https://www.gov.uk/hmrc-internal-manuals/national-insurance-manual/nim70650", + ), + dict( + title="HMRC National Insurance Manual NIM70200", + href="https://www.gov.uk/hmrc-internal-manuals/national-insurance-manual/nim70200", + ), + ] def formula(person, period, parameters): class_2 = parameters(period).gov.hmrc.national_insurance.class_2 - profits = person("self_employment_income", period) - over_threshold = profits >= class_2.small_profits_threshold - return over_threshold * class_2.flat_rate * WEEKS_IN_YEAR + # Section 11(3) SSCBA 1992: "relevant profits" are the profits in + # respect of which Class 4 is payable under s.15 (or would be, if they + # exceeded the lower profits limit), which s.15(3) computes under + # Schedule 2. Class 2 and Class 4 therefore share one profit base. + profits = person("ni_class_4_profits", period) + # The flat rate is 0 once s.11(2) is omitted in 2024-25. + weeks = class_2_contribution_weeks(period.start.year) + return class_2_liable(profits, class_2) * class_2.flat_rate * weeks diff --git a/policyengine_uk/variables/gov/hmrc/national_insurance/class_4/ni_class_4_maximum.py b/policyengine_uk/variables/gov/hmrc/national_insurance/class_4/ni_class_4_maximum.py index b9e61c8aad..f599002047 100644 --- a/policyengine_uk/variables/gov/hmrc/national_insurance/class_4/ni_class_4_maximum.py +++ b/policyengine_uk/variables/gov/hmrc/national_insurance/class_4/ni_class_4_maximum.py @@ -14,6 +14,14 @@ def formula(person, period, parameters): upl = ni.class_4.thresholds.upper_profits_limit lpl = ni.class_4.thresholds.lower_profits_limit step_1 = upl - lpl + # Regulation 100 writes its percentages out, but in every year from + # 2015-16 they match the Class 4 rates: 9% and 2% (Steps Two, Five, + # Eight and Nine) to 2021-22 and in 2023-24; 9.73% and 2.73% for + # 2022-23 (Health and Social Care Levy (Repeal) Act 2022 Sch para + # 6(2)); from 2024-25, 6% and 100/6 in Steps Two and Five (National + # Insurance Contributions (Reduction in Rates) Act 2024 s 2(3)) with + # Steps Eight and Nine still at 2%. So the steps read the rate + # parameters. main_rate = ni.class_4.rates.main add_rate = ni.class_4.rates.additional step_2 = step_1 * main_rate