Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.
from .inventory_stock_turnover_types import StockTurnover
from .math_round_div import round_div ← from math.round-div ^1.0.0 · built alongside by fune
from .money_amount import Money, assert_same_currency, money ← from money.amount ^1.0.0 · built alongside by fune
def _not_negative(name: str, amount: Money) -> None:
if amount.minor < 0:
raise ValueError("%s must not be negative, received %d" % (name, amount.minor))
def stock_turnover(opening_stock: Money, closing_stock: Money, cost_of_sales: Money, period_days: int) -> StockTurnover:
"""Turns, days inventory outstanding and days of cover. Each is one exact
division rounded half-up, then made a float, so every language agrees.
"""
assert_same_currency(opening_stock, closing_stock)
assert_same_currency(opening_stock, cost_of_sales)
_not_negative("openingStock", opening_stock)
_not_negative("closingStock", closing_stock)
_not_negative("costOfSales", cost_of_sales)
if isinstance(period_days, bool) or not isinstance(period_days, int) or period_days < 1:
raise ValueError("periodDays must be a whole number of days, at least 1, received %r" % (period_days,))
both = opening_stock.minor + closing_stock.minor
cogs = cost_of_sales.minor
return StockTurnover(
average_stock=money(round_div(both, 2, "half-up"), opening_stock.currency),
turns=None if both == 0 else round_div(cogs * 200, both, "half-up") / 100,
days_inventory_outstanding=None
if cogs == 0
else round_div(both * period_days * 10, cogs * 2, "half-up") / 10,
days_of_cover=None if cogs == 0 else round_div(closing_stock.minor * period_days * 10, cogs, "half-up") / 10,
)