67 lines
billing/promo_processor.py
Applies promo code discounts to orders that meet the minimum purchase threshold.
# Promo code discount logic for the billing pipeline.
from typing import List, Optional
 
# Type alias: promo dict with code (str), discount_pct (float),
# minimum_purchase_amount (float), active (bool).
PromoCode = dict
# Type alias: order dict with order_id (str), customer_id (str), total (float).
Order = dict
 
 
def apply_discount(order: Order, promo: PromoCode) -> Order:
    """Return the order with a discounted_total field populated.
 
    Parameters
    ----------
    order : Order
        The order to potentially discount. 'total' is the pre-discount amount.
    promo : PromoCode
        The promo code to evaluate.
 
    Returns
    -------
    Order
        Updated order dict. 'discounted_total' is the post-discount amount
        if the promo applies, or the original total otherwise.
 
    Notes
    -----
    The minimum_purchase_amount threshold is inclusive: an order with total
    equal to minimum_purchase_amount qualifies for the discount.
    Inactive promo codes are never applied.
    """
    if not promo["active"]:
        return {**order, "discounted_total": order["total"]}
    if order["total"] > promo["minimum_purchase_amount"]:
        discount = round(order["total"] * promo["discount_pct"] / 100, 2)
        return {**order, "discounted_total": round(order["total"] - discount, 2)}
    return {**order, "discounted_total": order["total"]}
 
 
def process_orders(
    orders: List[Order],
    promos: dict,
) -> List[Order]:
    """Apply applicable promo codes to a batch of pending orders.
 
    Parameters
    ----------
    orders : list of Order
        Orders to process. Each order may carry a 'promo_code' key.
    promos : dict
        Mapping of promo code string to PromoCode dict.
 
    Returns
    -------
    list of Order
        Orders with 'discounted_total' populated; orders without a matching
        active code carry 'discounted_total' equal to their original total.
    """
    results = []
    for order in orders:
        code: Optional[str] = order.get("promo_code")
        if code and code in promos:
            results.append(apply_discount(order, promos[code]))
        else:
            results.append({**order, "discounted_total": order["total"]})
    return results