Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.
from .dates_add_days import days_between, parse_iso_date ← from dates.add-days ^1.0.0 · built alongside by fune
from .dates_uk_tax_year import uk_tax_year ← from dates.uk-tax-year ^1.0.0 · built alongside by fune
from .payroll_tax_period_types import PayFrequency, TaxPeriod
def tax_period(pay_date: str, frequency: PayFrequency) -> TaxPeriod:
"""The tax week, tax month and payroll period a pay date falls in.
The tax year is 365 or 366 days, which is 52 weeks and one or two days over.
Those spare days are week 53, and they are the reason ``period`` exists:
HMRC numbers the extra payday 53, 54 or 56 by frequency and taxes it
non-cumulatively, so a payroll that just counts weeks gets it wrong.
"""
if frequency not in ("weekly", "fortnightly", "four-weekly", "monthly"):
raise ValueError('unknown pay frequency "%s"' % (frequency,))
year = uk_tax_year(pay_date)
week = days_between(year.start, pay_date) // 7 + 1
# Tax months run from the 6th to the 5th, so the calendar month moves on
# five days before the tax month does.
date = parse_iso_date(pay_date)
month = date.month - 3 if date.day >= 6 else date.month - 4
if month <= 0:
month += 12
if frequency == "monthly":
period = month
elif week < 53:
period = week
else:
period = {"weekly": 53, "fortnightly": 54, "four-weekly": 56}[frequency]
return TaxPeriod(tax_year=year.label, tax_year_start=year.start, week=week, month=month, period=period)