dodil/erp-brick-ar

DODIL ERP brick: accounts receivable

src/brick_ar/domain/money.py

"""Money arithmetic: exact Decimals, rounded half up to the cent ONCE per line (NUMERIC(18,2) on the wire and in storage)."""
from decimal import ROUND_HALF_UP, Decimal

CENT = Decimal("0.01")
ZERO = Decimal("0.00")


def money(v) -> Decimal:
    return Decimal(str(v)).quantize(CENT, ROUND_HALF_UP)


def line_net(quantity, unit_price, discount_pct, per=1) -> Decimal:
    """quantity x price / per x (100 - discount)/100, rounded once (v7: `per` is the count the price is per, 100 in 2.4500 per 100). An
    unfilled quantity (a usage line) is worth nothing yet."""
    if quantity is None:
        return ZERO
    return money(Decimal(str(quantity)) * Decimal(str(unit_price)) / Decimal(str(per or 1)) * (Decimal(100) - Decimal(str(discount_pct or 0))) / 100)