Functional Weave
Code in Python

insurance.sum-insured-average@1.0.1

impl/python.py

2,135 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 .insurance_sum_insured_average_types import AverageSettlement
from .math_round_div import RoundingMode, 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 average_clause_settlement(
    loss: Money, sum_insured: Money, value_at_risk: Money, condition_basis_points: int, mode: RoundingMode
) -> AverageSettlement:
    """Settle a claim under an average clause.

    A property insured for less than it is worth is paid only the share of
    the loss that the sum insured bears to the value at risk: insured for 75%
    of its value, it is paid 75% of any loss. With a special condition of
    average the clause only applies once the sum insured falls below that
    share of the value. The payout never exceeds the loss or the sum insured.
    """
    assert_same_currency(loss, sum_insured)
    assert_same_currency(loss, value_at_risk)
    if value_at_risk.minor <= 0:
        raise ValueError("valueAtRisk must be more than zero, received %d" % (value_at_risk.minor,))
    if loss.minor < 0:
        raise ValueError("loss must not be negative, received %d" % (loss.minor,))
    if sum_insured.minor < 0:
        raise ValueError("sumInsured must not be negative, received %d" % (sum_insured.minor,))
    if loss.minor > value_at_risk.minor:
        raise ValueError("loss must not exceed the value at risk")
    cbp = condition_basis_points
    if isinstance(cbp, bool) or not isinstance(cbp, int) or cbp < 1 or cbp > 10000:
        raise ValueError("conditionBasisPoints must be from 1 to 10000, received %s" % (cbp,))
    average_applied = sum_insured.minor * 10000 < value_at_risk.minor * cbp
    if average_applied:
        payout = round_div(loss.minor * sum_insured.minor, value_at_risk.minor, mode)
    else:
        payout = loss.minor
    payout = min(payout, loss.minor, sum_insured.minor)
    c = loss.currency
    return AverageSettlement(
        payout=money(payout, c),
        average_applied=average_applied,
        insured_proportion_basis_points=min(round_div(sum_insured.minor * 10000, value_at_risk.minor, "down"), 10000),
        shortfall=money(loss.minor - payout, c),
    )