'''
建造者模式（Builder Pattern）允许构建一个复杂对象的各个部分，然后一步一步地返回这个对象的完整版本。
将建造者模式应用于网购的下单和出库过程时，我们可以设计一个Order类来表示订单，
以及一个OrderBuilder类来构建订单的各个部分。
此外，我们还可以引入一个ShoppingCart类来表示购物车，以及一个Inventory类来处理库存和出库逻辑。
'''

######################################################################
# Order类，它包含订单的基本信息，如下单时间、用户信息、订单项列表
######################################################################
from datetime import datetime  
  
class OrderItem:  
    def __init__(self, product_id, quantity):  
        self.product_id = product_id  
        self.quantity = quantity  
  
class Order:  
    def __init__(self, user_id, order_items, order_time=None):  
        self.user_id = user_id  
        self.order_items = order_items  
        self.order_time = order_time or datetime.now()  
        self.status = "PLACED"  # 初始状态为已下单  
  
    def __str__(self):  
        return f"Order for user {self.user_id} placed at {self.order_time}. Status: {self.status}"  
  
    def fulfill(self, inventory):  
        # 出库逻辑，这里简化处理  
        for item in self.order_items:  
            if not inventory.deduct_stock(item.product_id, item.quantity):  
                return False  
        self.status = "FULFILLED"  
        return True

######################################################################
# OrderBuilder类，用于构建订单
######################################################################
class OrderBuilder:  
    def __init__(self):  
        self.reset()  
  
    def reset(self):  
        self._user_id = None  
        self._order_items = []  
  
    def for_user(self, user_id):  
        self._user_id = user_id  
        return self  
  
    def add_item(self, product_id, quantity):  
        self._order_items.append(OrderItem(product_id, quantity))  
        return self  
  
    def build(self):  
        if not self._user_id or not self._order_items:  
            raise ValueError("Order cannot be built without user and items.")  
        return Order(self._user_id, self._order_items)


######################################################################
# 购物车和库存类
######################################################################
class ShoppingCart:  
    def __init__(self, user_id):  
        self.user_id = user_id  
        self.items = {}  # {product_id: quantity}  
  
    def add_to_cart(self, product_id, quantity):  
        self.items[product_id] = self.items.get(product_id, 0) + quantity  
  
    def checkout(self):  
        order_items = [OrderItem(product_id, quantity) for product_id, quantity in self.items.items()]  
        self.items.clear()  # 清空购物车  
        return order_items  
  
class Inventory:  
    def __init__(self):  
        self.stock = {}  # {product_id: quantity}  
  
    def add_stock(self, product_id, quantity):  
        self.stock[product_id] = self.stock.get(product_id, 0) + quantity  
  
    def deduct_stock(self, product_id, quantity):  
        if self.stock.get(product_id, 0) >= quantity:  
            self.stock[product_id] -= quantity  
            return True  
        return False

######################################################################
# 模拟整个下单和出库过程
######################################################################
# 初始化库存和购物车  
inventory = Inventory()  
inventory.add_stock("book1", 10)  
inventory.add_stock("book2", 5)  
  
cart = ShoppingCart(user_id="user123")  
cart.add_to_cart("book1", 2)  
cart.add_to_cart("book2", 1)  
  
# 使用OrderBuilder构建订单  
order_items = cart.checkout()  # 结账，获取订单项列表并清空购物车  
order_builder = OrderBuilder().for_user("user123")  
for item in order_items:  
    order_builder.add_item(item.product_id, item.quantity)  
order = order_builder.build()  # 构建订单对象  
print(order)  # 输出订单信息  
  
# 出库处理  
if order.fulfill(inventory):  
    print("Order has been fulfilled.")  
else:  
    print("Order fulfillment failed due to insufficient stock.")