createOrder method

Order createOrder({
  1. required String customerId,
  2. required List<OrderItemRequest> items,
  3. Subscription? subscription,
  4. required TimeSlot timeSlot,
})

Implementation

Order createOrder({
  required String customerId,
  required List<OrderItemRequest> items,
  Subscription? subscription,
  required TimeSlot timeSlot,
}) {
  if (items.isEmpty) {
    throw ArgumentError('Order must contain at least one item');
  }

  final List<OrderItem> orderItems = [];

  for (final req in items) {
    // 1️⃣ Inventory check FIRST
    final available = inventoryPort.isAvailable(
      productId: req.productId,
      quantity: req.quantity,
    );

    if (!available) {
      throw StateError('Product ${req.productId} not available');
    }

    // 2️⃣ PRICE LOCK (ONLY ONCE)
    final unitPrice = pricingPort.getPrice(
      productId: req.productId,
      at: DateTime.now(),
      subscription: subscription,
    );

    // 3️⃣ Create immutable OrderItem
    orderItems.add(
      OrderItem(
        productId: req.productId,
        productType: req.productType,
        quantity: req.quantity,
        unit: req.unit,
        unitPrice: unitPrice,
      ),
    );
  }

  // 4️⃣ Create Order
  final order = Order(
    orderId: _generateOrderId(),
    customerId: customerId,
    items: orderItems,
    subscription: subscription,
    timeSlot: timeSlot,
    createdAt: DateTime.now(),
  );

  // 5️⃣ Reserve inventory
  for (final item in orderItems) {
    inventoryPort.reserve(
      productId: item.productId,
      quantity: item.quantity,
      orderId: order.orderId,
    );
  }

  // 6️⃣ Persist
  orderRepository.save(order);

  return order;
}