Functional Weave
Code in Rust

insurance.excess-apply@1.0.1

impl/python.py

2,158 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 typing import Optional

from .insurance_excess_apply_types import ExcessSettlement
from .money_amount import Money, assert_same_currency, money  ← from money.amount ^1.0.0 · built alongside by fune


def apply_excess(
    loss: Money,
    compulsory_excess: Money,
    voluntary_excess: Money,
    policy_limit: Optional[Money],
    excess_within_limit: bool,
) -> ExcessSettlement:
    """The claim payout after the excess, capped at the policy limit.

    The excess is the compulsory and voluntary excess together, and a loss
    smaller than it pays nothing. Where the limit sits relative to the excess
    is a policy wording question, so the caller says which: by default the
    limit caps what is paid after the excess; with excess_within_limit the
    excess is taken off the loss after the limit, so it erodes the limit.
    """
    assert_same_currency(loss, compulsory_excess)
    assert_same_currency(loss, voluntary_excess)
    if policy_limit is not None:
        assert_same_currency(loss, policy_limit)
    if loss.minor < 0:
        raise ValueError("loss must not be negative, received %d" % (loss.minor,))
    if compulsory_excess.minor < 0 or voluntary_excess.minor < 0:
        raise ValueError("excess must not be negative")
    if policy_limit is not None and policy_limit.minor < 0:
        raise ValueError("policyLimit must not be negative, received %d" % (policy_limit.minor,))
    excess = compulsory_excess.minor + voluntary_excess.minor
    limit_applied = False
    if excess_within_limit:
        covered = loss.minor
        if policy_limit is not None and policy_limit.minor < covered:
            covered = policy_limit.minor
            limit_applied = True
        payout = max(covered - excess, 0)
    else:
        payout = max(loss.minor - excess, 0)
        if policy_limit is not None and policy_limit.minor < payout:
            payout = policy_limit.minor
            limit_applied = True
    c = loss.currency
    return ExcessSettlement(
        total_excess=money(excess, c),
        excess_applied=money(min(excess, loss.minor), c),
        payout=money(payout, c),
        limit_applied=limit_applied,
        uninsured=money(loss.minor - payout, c),
    )