hospitality.occupancy-adr-revpar@1.0.0
impl/python.py
1,848 bytes · the Python implementation · view raw
Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.
from .hospitality_occupancy_adr_revpar_types import HotelPerformance
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
def _whole(value: object) -> bool:
return isinstance(value, int) and not isinstance(value, bool)
def occupancy_adr_revpar(room_nights_available: int, room_nights_sold: int, room_revenue: Money) -> HotelPerformance:
"""Occupancy, ADR and RevPAR for a period.
Each figure is divided out of the raw totals and rounded half-up once.
RevPAR is revenue over available rooms, not ADR times occupancy:
multiplying two figures that were each rounded already can be a penny out.
"""
if not _whole(room_nights_available) or room_nights_available < 1:
raise ValueError("roomNightsAvailable must be at least 1, received %s" % (room_nights_available,))
if not _whole(room_nights_sold) or room_nights_sold < 0:
raise ValueError("roomNightsSold must not be negative, received %s" % (room_nights_sold,))
if room_nights_sold > room_nights_available:
raise ValueError(
"roomNightsSold (%d) cannot exceed roomNightsAvailable (%d)" % (room_nights_sold, room_nights_available)
)
if room_revenue.minor < 0:
raise ValueError("roomRevenue must not be negative, received %d" % (room_revenue.minor,))
return HotelPerformance(
room_nights_available=room_nights_available,
room_nights_sold=room_nights_sold,
room_revenue=room_revenue,
occupancy_basis_points=round_div(room_nights_sold * 10000, room_nights_available, "half-up"),
adr=None
if room_nights_sold == 0
else money(round_div(room_revenue.minor, room_nights_sold, "half-up"), room_revenue.currency),
revpar=money(round_div(room_revenue.minor, room_nights_available, "half-up"), room_revenue.currency),
)