Functional Weave
Code in Python

payroll.tax-code-parse@1.0.1

README.md

2,493 bytes · view raw

# payroll.tax-code-parse

Takes a UK PAYE tax code apart. It does not calculate tax; `payroll.income-tax`
does that, using this.

What a code is made of:

- An optional country prefix: `S` for a Scottish taxpayer, `C` for a Welsh one,
  nothing for England and Northern Ireland (`rest-of-uk`).
- The code proper, one of:
  - a number and a suffix letter, `1257L`, `1100M`, `1385N`, `0T`: a tax-free
    allowance. The number is the allowance divided by ten, so the annual
    allowance HMRC's routines use is **number x £10 + £9**: 1257L is £12,579,
    not £12,570, because the code covers a £10 range and the routines give the
    employee the top of it. `0T` means no allowance at all.
  - `K` and a number, `K475`: a negative allowance, pay to be *added* to
    taxable pay (£4,759 a year for K475). There is no K0.
  - `BR`: all pay at the basic rate. `D0`, `D1` (and `SD0` to `SD3` in
    Scotland): all pay at the rate one, two, three or four bands above basic.
  - `NT`: no tax. There is no Scottish or Welsh NT, so `SNT` is refused.
- An optional basis marker, `W1`, `M1` or `X`, meaning the code is operated on
  a week 1 / month 1 (non-cumulative) basis. It may follow the code with or
  without a space: `1257L W1`, `1257LM1`, `1257L X`.

Suffix letters L, M, N and T do not change the calculation (M and N are the
marriage allowance, T means HMRC wants to review the code); they are returned
so a payroll can apply HMRC's bulk code uplifts, which are made by suffix.
Withdrawn suffixes (P, V, Y, retired in 2016) and anything else unrecognised
are errors rather than guesses. Leading zeros (`01257L`) are refused, since
HMRC never issues them and they usually mean a keying error.

Sources: HMRC, "Tax codes" (https://www.gov.uk/tax-codes, and its "What your
tax code means" page, https://www.gov.uk/tax-codes/what-your-tax-code-means);
HMRC, "Specification for PAYE tax table routines" v24.0 (February 2026),
paragraphs 4.3.1 (the £10 x number + £9 annual value, K codes, 0T), 7 and 11
(NT has no S or C version), 8 (week 1 / month 1 basis),
https://www.gov.uk/government/publications/payroll-technical-specifications-income-tax.

1.0.1 fixes Python accepting a trailing newline in code (its patterns now use
fullmatch), and trims the same whitespace in every language: spaces, tabs,
line breaks and Unicode space separators. Before, Python also trimmed U+001C to
U+001F and U+0085, Rust U+0085 and TypeScript U+FEFF; each is now refused as
part of the code. Adds tests.