diff --git a/src/modules/cart/controllers/cart.controller.ts b/src/modules/cart/controllers/cart.controller.ts index 7fa07eb..b3a1e66 100644 --- a/src/modules/cart/controllers/cart.controller.ts +++ b/src/modules/cart/controllers/cart.controller.ts @@ -7,6 +7,7 @@ import { SetAddressDto } from '../dto/set-address.dto'; import { SetPaymentMethodDto } from '../dto/set-payment-method.dto'; import { SetDeliveryMethodDto } from '../dto/set-delivery-method.dto'; import { SetDescriptionDto } from '../dto/set-description.dto'; +import { SetTableNumberDto } from '../dto/set-table-number.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'; @@ -132,4 +133,15 @@ export class CartController { ) { return this.cartService.setDescription(userId, restaurantId, setDescriptionDto); } + + @Patch('table-number') + @ApiOperation({ summary: 'Set table number for cart (required when delivery method is DineIn)' }) + @ApiBody({ type: SetTableNumberDto }) + setTableNumber( + @UserId() userId: string, + @RestId() restaurantId: string, + @Body() setTableNumberDto: SetTableNumberDto, + ) { + return this.cartService.setTableNumber(userId, restaurantId, setTableNumberDto); + } } diff --git a/src/modules/cart/dto/set-table-number.dto.ts b/src/modules/cart/dto/set-table-number.dto.ts new file mode 100644 index 0000000..6dca46f --- /dev/null +++ b/src/modules/cart/dto/set-table-number.dto.ts @@ -0,0 +1,10 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { IsNotEmpty, IsString, ValidateIf } from 'class-validator'; + +export class SetTableNumberDto { + @ApiPropertyOptional({ description: 'Table number', example: '5' }) + @ValidateIf((o, value) => value !== null && value !== undefined) + @IsString() + tableNumber?: string; +} + diff --git a/src/modules/cart/interfaces/cart.interface.ts b/src/modules/cart/interfaces/cart.interface.ts index 5587039..a4390ad 100644 --- a/src/modules/cart/interfaces/cart.interface.ts +++ b/src/modules/cart/interfaces/cart.interface.ts @@ -20,6 +20,7 @@ export interface Cart { paymentMethodId?: string; deliveryMethodId?: string; description?: string; + tableNumber?: string; deliveryFee: number; subTotal: number; diff --git a/src/modules/cart/providers/cart.service.ts b/src/modules/cart/providers/cart.service.ts index d6cb382..cff9140 100644 --- a/src/modules/cart/providers/cart.service.ts +++ b/src/modules/cart/providers/cart.service.ts @@ -11,10 +11,12 @@ import { SetAddressDto } from '../dto/set-address.dto'; import { SetPaymentMethodDto } from '../dto/set-payment-method.dto'; import { SetDeliveryMethodDto } from '../dto/set-delivery-method.dto'; import { SetDescriptionDto } from '../dto/set-description.dto'; +import { SetTableNumberDto } from '../dto/set-table-number.dto'; import { UserAddress } from '../../users/entities/user-address.entity'; import { User } from '../../users/entities/user.entity'; import { PaymentMethod } from '../../payments/entities/payment-method.entity'; import { Delivery } from '../../delivery/entities/delivery.entity'; +import { DeliveryMethodEnum } from '../../delivery/interface/delivery'; import { Cart, CartItem } from '../interfaces/cart.interface'; import { CouponService } from 'src/modules/coupons/providers/coupon.service'; import { OrderCouponDetail } from 'src/modules/orders/interface/order-status'; @@ -608,6 +610,38 @@ export class CartService { return cart; } + /** + * Set table number for cart + */ + async setTableNumber( + userId: string, + restaurantId: string, + setTableNumberDto: SetTableNumberDto, + ): Promise { + const cart = await this.findOneOrFail(userId, restaurantId); + + // If delivery method is set, validate that table number is required for DineIn + if (cart.deliveryMethodId) { + const deliveryMethod = await this.em.findOne(Delivery, { + id: cart.deliveryMethodId, + restaurant: { id: restaurantId }, + }); + + if (deliveryMethod && deliveryMethod.method === DeliveryMethodEnum.DineIn) { + if (!setTableNumberDto.tableNumber || setTableNumberDto.tableNumber.trim() === '') { + throw new BadRequestException('Table number is required when delivery method is DineIn'); + } + } + } + + cart.tableNumber = setTableNumberDto.tableNumber; + cart.updatedAt = new Date().toISOString(); + + await this.saveCart(cart); + + return cart; + } + /** * Recalculate cart totals (including coupon discount and tax) */ diff --git a/src/modules/orders/entities/order.entity.ts b/src/modules/orders/entities/order.entity.ts index 6813474..00a57df 100644 --- a/src/modules/orders/entities/order.entity.ts +++ b/src/modules/orders/entities/order.entity.ts @@ -77,6 +77,9 @@ export class Order extends BaseEntity { @Property({ type: 'text', nullable: true }) description?: string; + @Property({ nullable: true }) + tableNumber?: string; + @Enum(() => OrderStatus) status!: OrderStatus; diff --git a/src/modules/orders/orders.service.ts b/src/modules/orders/orders.service.ts index 628e103..d4dc1fa 100644 --- a/src/modules/orders/orders.service.ts +++ b/src/modules/orders/orders.service.ts @@ -68,6 +68,7 @@ export class OrdersService { total: cart.total || 0, totalItems: cart.totalItems || 0, description: cart.description, + tableNumber: cart.tableNumber, status: OrderStatus.Pending, paymentStatus: PaymentStatusEnum.Pending, }); @@ -163,6 +164,13 @@ export class OrdersService { ); } + // Validate table number is required for DineIn + if (delivery.method === DeliveryMethodEnum.DineIn) { + if (!cart.tableNumber || cart.tableNumber.trim() === '') { + throw new BadRequestException('Table number is required when delivery method is DineIn'); + } + } + if (delivery.method === DeliveryMethodEnum.DeliveryCourier && !cart.addressId) { throw new BadRequestException('Address is required. Please set a delivery address before creating an order.'); }