Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.
import re
from typing import Optional
from .money_amount import money ← from money.amount ^1.0.0 · built alongside by fune
from .payroll_tax_code_parse_types import TaxCode
# The basis marker may be written with or without a space: "1257L W1", "1257LM1", "1257L X".
BASIS = re.compile(r"^(.*?)\s*(W1|M1|X)$")
ALLOWANCE = re.compile(r"^(0|[1-9][0-9]{0,5})([LMNT])$")
K_CODE = re.compile(r"^K([1-9][0-9]{0,5})$")
D_CODE = re.compile(r"^D([0-9])$")
def parse_tax_code(code: str) -> TaxCode:
"""Take a UK PAYE tax code apart into its region, kind, allowance and basis.
The annual allowance is number x 10 + 9 pounds, not number x 10: a code
covers a 10-pound band of allowances and HMRC's routines give the employee
the top of it, so 1257L is worth 12,579 pounds a year to the payroll.
"""
original = code
text = code.strip().upper()
if text == "":
raise ValueError('unrecognised tax code "%s"' % (original,))
cumulative = True
basis = BASIS.match(text)
if basis is not None and basis.group(1) != "":
text = basis.group(1)
cumulative = False
region = "rest-of-uk"
body = text
if text.startswith("S"):
region = "scotland"
body = text[1:]
elif text.startswith("C"):
region = "wales"
body = text[1:]
number = 0
suffix: Optional[str] = None
allowance_pounds = 0
allowance = ALLOWANCE.match(body)
k = K_CODE.match(body)
d = D_CODE.match(body)
if body == "NT":
if region != "rest-of-uk":
raise ValueError('there is no Scottish or Welsh NT code: "%s"' % (original,))
kind = "no-tax"
elif body == "BR":
kind = "basic-rate"
elif d is not None:
kind = "d-rate"
number = int(d.group(1))
elif k is not None:
kind = "negative-allowance"
number = int(k.group(1))
allowance_pounds = -(number * 10 + 9)
elif allowance is not None:
number = int(allowance.group(1))
suffix = allowance.group(2)
if number == 0 and suffix != "T":
raise ValueError('unrecognised tax code "%s": a zero allowance is only issued as 0T' % (original,))
kind = "allowance"
allowance_pounds = 0 if number == 0 else number * 10 + 9
else:
raise ValueError('unrecognised tax code "%s"' % (original,))
prefix = "S" if region == "scotland" else "C" if region == "wales" else ""
return TaxCode(
code=prefix + body,
region=region,
kind=kind,
number=number,
suffix=suffix,
annual_allowance=money(allowance_pounds * 100, "GBP"),
cumulative=cumulative,
)