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 = dictdef 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