From b67f00a919fc36a5be1482e4bed66dad6cdad8c2 Mon Sep 17 00:00:00 2001 From: morteza-mortezai Date: Wed, 3 Dec 2025 09:05:35 +0330 Subject: [PATCH] set delivery --- .../cart/controllers/cart.controller.ts | 12 +++++ .../cart/dto/set-delivery-method.dto.ts | 10 ++++ src/modules/cart/interfaces/cart.interface.ts | 1 + src/modules/cart/providers/cart.service.ts | 52 ++++++++++++++++++- 4 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 src/modules/cart/dto/set-delivery-method.dto.ts diff --git a/src/modules/cart/controllers/cart.controller.ts b/src/modules/cart/controllers/cart.controller.ts index 2d2993e..e245cbf 100644 --- a/src/modules/cart/controllers/cart.controller.ts +++ b/src/modules/cart/controllers/cart.controller.ts @@ -5,6 +5,7 @@ import { UpdateItemQuantityDto } from '../dto/update-item.dto'; import { ApplyCouponDto } from '../dto/apply-coupon.dto'; import { SetAddressDto } from '../dto/set-address.dto'; import { SetPaymentMethodDto } from '../dto/set-payment-method.dto'; +import { SetDeliveryMethodDto } from '../dto/set-delivery-method.dto'; import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth, ApiBody, ApiParam } from '@nestjs/swagger'; import { AuthGuard } from '../../auth/guards/auth.guard'; import { UserId } from 'src/common/decorators/user-id.decorator'; @@ -129,4 +130,15 @@ export class CartController { ) { return this.cartService.setPaymentMethod(userId, restaurantId, setPaymentMethodDto); } + + @Patch('delivery-method') + @ApiOperation({ summary: 'Set delivery method for cart' }) + @ApiBody({ type: SetDeliveryMethodDto }) + setDeliveryMethod( + @UserId() userId: string, + @RestId() restaurantId: string, + @Body() setDeliveryMethodDto: SetDeliveryMethodDto, + ) { + return this.cartService.setDeliveryMethod(userId, restaurantId, setDeliveryMethodDto); + } } diff --git a/src/modules/cart/dto/set-delivery-method.dto.ts b/src/modules/cart/dto/set-delivery-method.dto.ts new file mode 100644 index 0000000..b3cb20e --- /dev/null +++ b/src/modules/cart/dto/set-delivery-method.dto.ts @@ -0,0 +1,10 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { IsNotEmpty, IsString } from 'class-validator'; + +export class SetDeliveryMethodDto { + @ApiProperty({ description: 'Delivery method ID', example: '01ARZ3NDEKTSV4RRFFQ69G5FAV' }) + @IsNotEmpty() + @IsString() + deliveryMethodId!: string; +} + diff --git a/src/modules/cart/interfaces/cart.interface.ts b/src/modules/cart/interfaces/cart.interface.ts index 6d7cf5e..f8196e6 100644 --- a/src/modules/cart/interfaces/cart.interface.ts +++ b/src/modules/cart/interfaces/cart.interface.ts @@ -21,6 +21,7 @@ export interface Cart { coupon?: CartCoupon; addressId?: string; paymentMethodId?: string; + deliveryMethodId?: string; couponDiscount: number; itemsDiscount: number; totalDiscount: number; diff --git a/src/modules/cart/providers/cart.service.ts b/src/modules/cart/providers/cart.service.ts index a67d239..1df7d3e 100644 --- a/src/modules/cart/providers/cart.service.ts +++ b/src/modules/cart/providers/cart.service.ts @@ -9,8 +9,10 @@ import { UpdateItemQuantityDto } from '../dto/update-item.dto'; import { ApplyCouponDto } from '../dto/apply-coupon.dto'; import { SetAddressDto } from '../dto/set-address.dto'; import { SetPaymentMethodDto } from '../dto/set-payment-method.dto'; +import { SetDeliveryMethodDto } from '../dto/set-delivery-method.dto'; import { UserAddress } from '../../users/entities/user-address.entity'; import { PaymentMethod } from '../../payments/entities/payment-method.entity'; +import { Delivery } from '../../delivery/entities/delivery.entity'; import { Cart, CartItem, CartCoupon } from '../interfaces/cart.interface'; @Injectable() @@ -452,6 +454,46 @@ export class CartService { return cart; } + /** + * Set delivery method for cart + */ + async setDeliveryMethod( + userId: string, + restaurantId: string, + setDeliveryMethodDto: SetDeliveryMethodDto, + ): Promise { + const cart = await this.findOne(userId, restaurantId); + + // Find and validate delivery method belongs to restaurant + const deliveryMethod = await this.em.findOne( + Delivery, + { + id: setDeliveryMethodDto.deliveryMethodId, + restaurant: { id: restaurantId }, + }, + { populate: ['restaurant'] }, + ); + + if (!deliveryMethod) { + throw new NotFoundException( + `Delivery method with ID ${setDeliveryMethodDto.deliveryMethodId} not found for restaurant ${restaurantId}`, + ); + } + + // Verify delivery method is enabled + if (!deliveryMethod.enabled) { + throw new BadRequestException('Delivery method is not enabled for this restaurant'); + } + + cart.deliveryMethodId = setDeliveryMethodDto.deliveryMethodId; + + // Recalculate cart totals (this will update shipmentFee based on delivery method) + await this.recalculateCartTotals(cart); + await this.saveCart(cart); + + return cart; + } + /** * Recalculate cart totals (including coupon discount and tax) */ @@ -500,8 +542,14 @@ export class CartService { cart.tax = tax; // Shipment fee is calculated separately via delivery method - // For now, it's set to 0. It should be set when a delivery method is selected - cart.shipmentFee = 0; + let shipmentFee = 0; + if (cart.deliveryMethodId) { + const deliveryMethod = await this.em.findOne(Delivery, { id: cart.deliveryMethodId }); + if (deliveryMethod && deliveryMethod.enabled) { + shipmentFee = Number(deliveryMethod.deliveryFee) || 0; + } + } + cart.shipmentFee = shipmentFee; // Calculate total: total = subtotal – totalDiscount + tax + shipmentFee cart.total = subTotal - cart.totalDiscount + tax + cart.shipmentFee;