Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.
from typing import Sequence
from .dates_add_days import add_days, days_between ← from dates.add-days ^1.0.0 · built alongside by fune
from .dates_business_days_between import business_days_between ← from dates.business-days-between ^1.0.0 · built alongside by fune
from .math_round_div import round_div ← from math.round-div ^1.0.0 · built alongside by fune
from .money_amount import Money, money ← from money.amount ^1.0.0 · built alongside by fune
from .payroll_pro_rata_salary_types import ProRata, ProRataMethod
def _count_days(start: str, end: str, method: str, holidays: Sequence[str]) -> int:
if method == "calendar-days":
return days_between(start, end) + 1
if method == "working-days":
return business_days_between(start, add_days(end, 1), holidays)
raise ValueError('unknown pro-rata method "%s"' % (method,))
def pro_rata_salary(
period_salary: Money,
fte_basis_points: int,
period_start: str,
period_end: str,
worked_from: str,
worked_to: str,
method: ProRataMethod,
holidays: Sequence[str],
) -> ProRata:
"""Pro-rate a period's salary by time employed and FTE, rounding once."""
if isinstance(fte_basis_points, bool) or not isinstance(fte_basis_points, int) or not 1 <= fte_basis_points <= 10000:
raise ValueError("fteBasisPoints must be a whole number from 1 to 10000, received %s" % (fte_basis_points,))
if days_between(period_start, period_end) < 0:
raise ValueError("periodEnd is before periodStart")
if days_between(worked_from, worked_to) < 0:
raise ValueError("workedTo is before workedFrom")
if worked_from < period_start or worked_to > period_end:
raise ValueError("the worked dates must fall inside the pay period")
days_in_period = _count_days(period_start, period_end, method, holidays)
if days_in_period == 0:
raise ValueError("the pay period has no working days to pro-rate over")
days_counted = _count_days(worked_from, worked_to, method, holidays)
minor = round_div(period_salary.minor * fte_basis_points * days_counted, 10000 * days_in_period, "half-up")
return ProRata(pay=money(minor, period_salary.currency), days_counted=days_counted, days_in_period=days_in_period)