from .dates_add_days import add_days from .dates_add_months import add_months from .dates_age import age from .hr_length_of_service import length_of_service from .math_round_div import round_div from .money_amount import Money, money from .payroll_redundancy_pay_data import WEEK_PAY_CAPS, WEEK_PAY_CAPS_HISTORY from .payroll_redundancy_pay_types import RedundancyPay def _week_pay_cap(relevant_date: str) -> int: for row in WEEK_PAY_CAPS: if relevant_date >= row.valid_from and (row.valid_to is None or relevant_date <= row.valid_to): return row.cap_minor if WEEK_PAY_CAPS_HISTORY != "full": earliest = min((row.valid_from for row in WEEK_PAY_CAPS), default=None) if earliest is not None and relevant_date < earliest: raise ValueError( "no statutory week's pay cap for %s: this build was installed with history=%s, " "so it only carries caps from %s. Reinstall with history=full for older dismissals." % (relevant_date, WEEK_PAY_CAPS_HISTORY, earliest) ) raise ValueError("no statutory week's pay cap for %s" % (relevant_date,)) def statutory_redundancy_pay(birth_date: str, start_date: str, relevant_date: str, weekly_pay: Money) -> RedundancyPay: """ERA 1996 s.162 redundancy pay. Years are reckoned backwards from the relevant date and each is priced by the age on its first day, so the rate steps up only for years spent wholly at 22 or 41 and over. """ if weekly_pay.minor < 0: raise ValueError("weeklyPay must not be negative, received %s" % (weekly_pay.minor,)) cap = _week_pay_cap(relevant_date) weekly_pay_used = money(min(weekly_pay.minor, cap), weekly_pay.currency) service_years = length_of_service(start_date, relevant_date).years eligible = service_years >= 2 years_counted = min(service_years, 20) if eligible else 0 half_weeks = 0 for k in range(1, years_counted + 1): first_day = add_days(add_months(relevant_date, -12 * k), 1) age_then = age(birth_date, first_day) half_weeks += 3 if age_then >= 41 else 2 if age_then >= 22 else 1 amount = money(round_div(half_weeks * weekly_pay_used.minor, 2, "half-up"), weekly_pay.currency) return RedundancyPay( eligible=eligible, service_years=service_years, years_counted=years_counted, half_weeks=half_weeks, weekly_pay_used=weekly_pay_used, amount=amount, )