diff --git a/src/modules/cart/providers/cart.service.ts b/src/modules/cart/providers/cart.service.ts index d032a61..56e462b 100644 --- a/src/modules/cart/providers/cart.service.ts +++ b/src/modules/cart/providers/cart.service.ts @@ -17,7 +17,7 @@ import { Delivery } from '../../delivery/entities/delivery.entity'; 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'; -import { CouponType } from 'src/modules/coupons/entities/coupon.entity'; +import { CouponType } from 'src/modules/coupons/interface/coupon'; @Injectable() export class CartService { @@ -489,7 +489,8 @@ export class CartService { */ async setAddress(userId: string, restaurantId: string, setAddressDto: SetAddressDto): Promise { const cart = await this.findOneOrFail(userId, restaurantId); - + + if (!cart.deliveryMethodId) throw new BadRequestException('Delivery method must be set before setting address'); // Find and validate address belongs to user const address = await this.em.findOne(UserAddress, { id: setAddressDto.addressId }, { populate: ['user'] }); if (!address) { diff --git a/src/modules/coupons/controllers/coupon.controller.ts b/src/modules/coupons/controllers/coupon.controller.ts index 8c8d4f3..729b318 100644 --- a/src/modules/coupons/controllers/coupon.controller.ts +++ b/src/modules/coupons/controllers/coupon.controller.ts @@ -81,6 +81,8 @@ export class CouponController { return this.couponService.remove(id); } + @UseGuards(AdminAuthGuard) + @ApiBearerAuth() @Get('admin/coupons/generate-code') @ApiOperation({ summary: 'generate a coupon code' }) generateCouponCode(@RestId() restId: string) { diff --git a/src/modules/coupons/dto/create-coupon.dto.ts b/src/modules/coupons/dto/create-coupon.dto.ts index 9ec3a1e..05e2174 100644 --- a/src/modules/coupons/dto/create-coupon.dto.ts +++ b/src/modules/coupons/dto/create-coupon.dto.ts @@ -1,7 +1,17 @@ -import { IsNotEmpty, IsString, IsEnum, IsNumber, IsOptional, IsBoolean, IsDateString, Min, IsArray } from 'class-validator'; +import { + IsNotEmpty, + IsString, + IsEnum, + IsNumber, + IsOptional, + IsBoolean, + IsDateString, + Min, + IsArray, +} from 'class-validator'; import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { Type } from 'class-transformer'; -import { CouponType } from '../entities/coupon.entity'; +import { CouponType } from '../interface/coupon'; export class CreateCouponDto { @IsNotEmpty() @@ -78,29 +88,28 @@ export class CreateCouponDto { @IsOptional() @IsArray() @IsString({ each: true }) - @ApiPropertyOptional({ - example: ['category-id-1', 'category-id-2'], + @ApiPropertyOptional({ + example: ['category-id-1', 'category-id-2'], description: 'Array of food category IDs. If empty, coupon applies to all categories.', - type: [String] + type: [String], }) foodCategories?: string[]; @IsOptional() @IsArray() @IsString({ each: true }) - @ApiPropertyOptional({ - example: ['food-id-1', 'food-id-2'], + @ApiPropertyOptional({ + example: ['food-id-1', 'food-id-2'], description: 'Array of food IDs. If empty, coupon applies to all foods.', - type: [String] + type: [String], }) foods?: string[]; @IsOptional() @IsString() - @ApiPropertyOptional({ - example: '09123456789', + @ApiPropertyOptional({ + example: '09123456789', description: 'Phone number of the user who can use this coupon. If empty, coupon can be used by any user.', }) userPhone?: string; } - diff --git a/src/modules/coupons/dto/find-coupons.dto.ts b/src/modules/coupons/dto/find-coupons.dto.ts index 4f7c707..35f0be4 100644 --- a/src/modules/coupons/dto/find-coupons.dto.ts +++ b/src/modules/coupons/dto/find-coupons.dto.ts @@ -1,7 +1,7 @@ import { IsOptional, IsString, IsBoolean, IsNumber, IsEnum } from 'class-validator'; import { ApiPropertyOptional } from '@nestjs/swagger'; import { Type } from 'class-transformer'; -import { CouponType } from '../entities/coupon.entity'; +import { CouponType } from '../interface/coupon'; export class FindCouponsDto { @IsOptional() diff --git a/src/modules/coupons/entities/coupon.entity.ts b/src/modules/coupons/entities/coupon.entity.ts index f53c06c..199733f 100644 --- a/src/modules/coupons/entities/coupon.entity.ts +++ b/src/modules/coupons/entities/coupon.entity.ts @@ -2,11 +2,7 @@ import { Entity, ManyToOne, Property, Enum, Unique } from '@mikro-orm/core'; import { BaseEntity } from '../../../common/entities/base.entity'; import { Restaurant } from '../../restaurants/entities/restaurant.entity'; import { normalizePhone } from '../../utils/phone.util'; - -export enum CouponType { - PERCENTAGE = 'PERCENTAGE', - FIXED = 'FIXED', -} +import { CouponType } from '../interface/coupon'; @Entity({ tableName: 'coupons' }) @Unique({ properties: ['code', 'restaurant'] }) diff --git a/src/modules/coupons/interface/coupon.ts b/src/modules/coupons/interface/coupon.ts new file mode 100644 index 0000000..098f26a --- /dev/null +++ b/src/modules/coupons/interface/coupon.ts @@ -0,0 +1,4 @@ +export enum CouponType { + PERCENTAGE = 'PERCENTAGE', + FIXED = 'FIXED', +} diff --git a/src/modules/coupons/providers/coupon.service.ts b/src/modules/coupons/providers/coupon.service.ts index a658711..62a04ed 100644 --- a/src/modules/coupons/providers/coupon.service.ts +++ b/src/modules/coupons/providers/coupon.service.ts @@ -6,7 +6,8 @@ import { CouponRepository } from '../repositories/coupon.repository'; import { RestRepository } from '../../restaurants/repositories/rest.repository'; import { EntityManager } from '@mikro-orm/postgresql'; import { RequiredEntityData } from '@mikro-orm/core'; -import { Coupon, CouponType } from '../entities/coupon.entity'; +import { Coupon } from '../entities/coupon.entity'; +import { CouponType } from '../interface/coupon'; import { CouponMessage, RestMessage } from 'src/common/enums/message.enum'; import { randomBytes } from 'node:crypto'; diff --git a/src/modules/coupons/repositories/coupon.repository.ts b/src/modules/coupons/repositories/coupon.repository.ts index c81c649..221b3b1 100644 --- a/src/modules/coupons/repositories/coupon.repository.ts +++ b/src/modules/coupons/repositories/coupon.repository.ts @@ -1,7 +1,8 @@ import { Injectable } from '@nestjs/common'; import { EntityManager, EntityRepository } from '@mikro-orm/postgresql'; import { FilterQuery } from '@mikro-orm/core'; -import { Coupon, CouponType } from '../entities/coupon.entity'; +import { Coupon } from '../entities/coupon.entity'; +import { CouponType } from '../interface/coupon'; import { PaginatedResult } from 'src/common/interfaces/pagination.interface'; type FindCouponsOpts = { diff --git a/src/modules/orders/interface/order-status.ts b/src/modules/orders/interface/order-status.ts index d0e42dd..73bb19a 100644 --- a/src/modules/orders/interface/order-status.ts +++ b/src/modules/orders/interface/order-status.ts @@ -1,4 +1,4 @@ -import type { CouponType } from 'src/modules/coupons/entities/coupon.entity'; +import type { CouponType } from 'src/modules/coupons/interface/coupon'; export enum OrderStatus { Pending = 'pending', diff --git a/src/seeders/data/coupons.data.ts b/src/seeders/data/coupons.data.ts index 9926105..07dfcd2 100644 --- a/src/seeders/data/coupons.data.ts +++ b/src/seeders/data/coupons.data.ts @@ -1,4 +1,4 @@ -import { CouponType } from '../../modules/coupons/entities/coupon.entity'; +import { CouponType } from '../../modules/coupons/interface/coupon'; export interface CouponData { restaurantSlug: string;