diff --git a/src/modules/orders/orders.controller.ts b/src/modules/orders/orders.controller.ts index 12e1ae0..d44ab16 100644 --- a/src/modules/orders/orders.controller.ts +++ b/src/modules/orders/orders.controller.ts @@ -19,7 +19,7 @@ export class OrdersController { @ApiResponse({ status: 400, description: 'Bad request - cart validation failed' }) @ApiResponse({ status: 404, description: 'Cart, user, restaurant, address, or payment method not found' }) create(@UserId() userId: string, @RestId() restaurantId: string) { - return this.ordersService.create(userId, restaurantId); + return this.ordersService.checkout(userId, restaurantId); } @Get('public/orders') diff --git a/src/modules/orders/orders.service.ts b/src/modules/orders/orders.service.ts index 5e14b5e..83582c4 100644 --- a/src/modules/orders/orders.service.ts +++ b/src/modules/orders/orders.service.ts @@ -25,14 +25,23 @@ export class OrdersService { // private readonly paymentGatewayService: PaymentGatewayService, ) {} - async create(userId: string, restaurantId: string) { - console.log('create order', userId, restaurantId); - // Get cart + async checkout(userId: string, restaurantId: string) { const cart = await this.cartService.findOne(userId, restaurantId); - // Validate cart and prepare order data - const validationResult = await this.validateCartForOrder(userId, restaurantId, cart); + const { order } = await this.create(userId, restaurantId, cart); + await this.cartService.clearCart(userId, restaurantId); + + if (!order.paymentMethod) { + throw new BadRequestException('Payment method is required for checkout'); + } + + const { paymentUrl } = await this.paymentsService.initializePayment(order.paymentMethod.id, order.total, order.id); + return { order, paymentUrl }; + } + + async create(userId: string, restaurantId: string, cart: Cart) { + const validationResult = await this.validateCartForOrder(userId, restaurantId, cart); // Create order within a transaction return this.em.transactional(async em => { // Create order entity @@ -58,6 +67,12 @@ export class OrdersService { // Create order items and update stock for (const itemData of validationResult.orderItemsData) { const { food, quantity, unitPrice, discount } = itemData; + + // Stock check + if (food.stock < quantity) { + throw new BadRequestException(`${food.title} is out of stock`); + } + const totalPrice = (unitPrice - discount) * quantity; const orderItem = em.create(OrderItem, { @@ -78,25 +93,7 @@ export class OrdersService { // Flush all changes await em.flush(); - let paymentUrl: string | null = null; - // Check if payment method is online and redirect to payment gateway - if (validationResult.paymentMethod.paymentMethod.isOnline) { - const result = await this.paymentsService.initializePayment( - validationResult.paymentMethod.id, - order.total, - order.id, - ); - // await this.cartService.clearCart(userId, restaurantId); - - // Return order with redirect URL for online payment - paymentUrl = result.paymentUrl; - } else { - // await this.cartService.clearCart(userId, restaurantId); - // For offline payment methods (cash on delivery, etc.), order is created and pending - // Payment status will be updated when payment is confirmed - // TODO: Implement offline payment confirmation flow if needed - } - return { order, paymentUrl }; + return { order }; }); } diff --git a/src/modules/payments/services/payments.service.ts b/src/modules/payments/services/payments.service.ts index c3f8491..c606d85 100644 --- a/src/modules/payments/services/payments.service.ts +++ b/src/modules/payments/services/payments.service.ts @@ -14,7 +14,7 @@ export class PaymentsService { restaurantPaymentMethodId: string, amount: number, orderId: string, - ): Promise<{ paymentUrl: string }> { + ): Promise<{ paymentUrl: string | null }> { // Validate amount if (amount <= 0) { throw new BadRequestException('Amount must be greater than zero'); @@ -37,7 +37,7 @@ export class PaymentsService { } if (!restaurantPaymentMethod.paymentMethod?.isOnline) { - throw new BadRequestException('Payment method is not online'); + return { paymentUrl: null }; } if (!restaurantPaymentMethod.callbackUrl) {