Files
2026-11-02 14:58:43 +07:00

61 lines
1.5 KiB
Python

"""Modul prosedural validasi checkout (FR-ORD-02, FR-ORD-03, FR-ORD-08).
Harga diambil dari katalog, bukan dari input klien. Satu order hanya boleh
berisi produk dari satu toko. Keranjang kosong mengembalikan total 0; penolakan
keranjang kosong menjadi tanggung jawab pemanggil.
"""
from dataclasses import dataclass
class CheckoutError(Exception):
"""Kelas dasar semua kegagalan validasi checkout."""
class ProductNotFoundError(CheckoutError):
pass
class InvalidQuantityError(CheckoutError):
pass
class MultiShopError(CheckoutError):
pass
class InsufficientStockError(CheckoutError):
pass
@dataclass(frozen=True)
class CartItem:
product_id: str
quantity: int
@dataclass(frozen=True)
class CheckoutSummary:
shop_id: str | None
total_amount: int
def validate_checkout(items, products):
"""Validasi keranjang terhadap katalog lalu hitung total dalam rupiah."""
shop_id = None
total = 0
for item in items:
product = products.get(item.product_id)
if product is None:
raise ProductNotFoundError(item.product_id)
if item.quantity <= 0:
raise InvalidQuantityError(item.product_id)
if shop_id is None:
shop_id = product.shop_id
elif product.shop_id != shop_id:
raise MultiShopError(item.product_id)
if product.available < item.quantity:
raise InsufficientStockError(item.product_id)
total += product.price * item.quantity
return CheckoutSummary(shop_id, total)