From 7aee650ac692459f98e270b3bd3c886ea5c44f47 Mon Sep 17 00:00:00 2001 From: morteza-mortezai Date: Mon, 22 Dec 2025 15:12:05 +0330 Subject: [PATCH] array of statuses for fin orders --- src/modules/orders/dto/find-orders.dto.ts | 111 ++++++------------ .../orders/providers/orders.service.ts | 4 +- .../orders/repositories/order.repository.ts | 24 +++- 3 files changed, 54 insertions(+), 85 deletions(-) diff --git a/src/modules/orders/dto/find-orders.dto.ts b/src/modules/orders/dto/find-orders.dto.ts index 44714f6..1ab7404 100644 --- a/src/modules/orders/dto/find-orders.dto.ts +++ b/src/modules/orders/dto/find-orders.dto.ts @@ -1,126 +1,83 @@ -import { IsOptional, IsString, IsNumber, Min, IsIn, IsEnum, IsDateString } from 'class-validator'; -import { Type } from 'class-transformer'; +import { + IsOptional, + IsString, + IsNumber, + Min, + IsIn, + IsEnum, + IsDateString, + IsArray, +} from 'class-validator'; +import { Type, Transform } from 'class-transformer'; import { ApiPropertyOptional } from '@nestjs/swagger'; import { OrderStatus } from '../interface/order.interface'; import { PaymentStatusEnum } from '../../payments/interface/payment'; -// Define the valid sort directions const sortOrderOptions = ['asc', 'desc'] as const; type SortOrder = (typeof sortOrderOptions)[number]; export class FindOrdersDto { - /** - * The page number to retrieve. - * @default 1 - */ - @ApiPropertyOptional({ - description: 'Page number', - type: Number, - default: 1, - minimum: 1, - }) + @ApiPropertyOptional({ default: 1, minimum: 1 }) @IsOptional() + @Type(() => Number) @IsNumber() @Min(1) - @Type(() => Number) - page?: number = 1; + page: number = 1; - /** - * The number of items per page. - * @default 10 - */ - @ApiPropertyOptional({ - description: 'Number of items per page', - type: Number, - default: 10, - minimum: 1, - }) + @ApiPropertyOptional({ default: 10, minimum: 1 }) @IsOptional() + @Type(() => Number) @IsNumber() @Min(1) - @Type(() => Number) - limit?: number = 10; + limit: number = 10; /** - * Filter by order status + * ?statuses=paid,confirmed + * ?statuses=paid&statuses=confirmed */ @ApiPropertyOptional({ - description: 'Filter by order status', + description: 'Filter by order statuses', enum: OrderStatus, + isArray: true, }) @IsOptional() - @IsEnum(OrderStatus) - status?: OrderStatus; + @Transform(({ value }) => + Array.isArray(value) ? value : value?.split(',') + ) + @IsArray() + @IsEnum(OrderStatus, { each: true }) + statuses?: OrderStatus[]; - /** - * Filter by payment status - */ - @ApiPropertyOptional({ - description: 'Filter by payment status', - enum: PaymentStatusEnum, - }) + @ApiPropertyOptional({ enum: PaymentStatusEnum }) @IsOptional() @IsEnum(PaymentStatusEnum) paymentStatus?: PaymentStatusEnum; - /** - * Search by order number or user information - */ - @ApiPropertyOptional({ - description: 'Search by order number or user information', - type: String, - }) + @ApiPropertyOptional() @IsOptional() @IsString() search?: string; - /** - * Filter orders from this date (ISO date string) - */ - @ApiPropertyOptional({ - description: 'Filter orders from this date (ISO date string)', - type: String, - format: 'date-time', - }) + @ApiPropertyOptional({ format: 'date-time' }) @IsOptional() @IsDateString() startDate?: string; - /** - * Filter orders until this date (ISO date string) - */ - @ApiPropertyOptional({ - description: 'Filter orders until this date (ISO date string)', - type: String, - format: 'date-time', - }) + @ApiPropertyOptional({ format: 'date-time' }) @IsOptional() @IsDateString() endDate?: string; - /** - * The field to sort the results by. - * @default "createdAt" - */ - @ApiPropertyOptional({ - description: 'Field to sort by (createdAt, total, orderNumber)', - type: String, - default: 'createdAt', - }) + @ApiPropertyOptional({ default: 'createdAt' }) @IsOptional() @IsString() - orderBy?: string = 'createdAt'; + orderBy: string = 'createdAt'; - /** - * The direction to sort the results. - * @default "desc" - */ @ApiPropertyOptional({ - description: 'Sort direction (asc or desc)', enum: sortOrderOptions, default: 'desc', }) @IsOptional() @IsIn(sortOrderOptions) - order?: SortOrder = 'desc'; + order: SortOrder = 'desc'; } diff --git a/src/modules/orders/providers/orders.service.ts b/src/modules/orders/providers/orders.service.ts index f1dc4d2..fa9c3a9 100644 --- a/src/modules/orders/providers/orders.service.ts +++ b/src/modules/orders/providers/orders.service.ts @@ -177,7 +177,7 @@ export class OrdersService { const result = await this.orderRepository.findAllPaginated(restId, { page: dto.page, limit: dto.limit, - status: dto.status, + statuses: dto.statuses, paymentStatus: dto.paymentStatus, search: dto.search, startDate: dto.startDate, @@ -194,7 +194,7 @@ export class OrdersService { const result = await this.orderRepository.findAllPaginated(restId, { page: dto.page, limit: dto.limit, - status: dto.status, + statuses: dto.statuses, paymentStatus: dto.paymentStatus, search: dto.search, startDate: dto.startDate, diff --git a/src/modules/orders/repositories/order.repository.ts b/src/modules/orders/repositories/order.repository.ts index 85880d0..aca555e 100644 --- a/src/modules/orders/repositories/order.repository.ts +++ b/src/modules/orders/repositories/order.repository.ts @@ -10,7 +10,7 @@ import { Review } from '../../review/entities/review.entity'; type FindOrdersOpts = { page?: number; limit?: number; - status?: OrderStatus; + statuses?: OrderStatus[]; paymentStatus?: PaymentStatusEnum; search?: string; startDate?: string; @@ -28,13 +28,13 @@ export class OrderRepository extends EntityRepository { /** * Find orders with pagination and optional filters. - * Supports: status, paymentStatus, search (orderNumber), date range, ordering. + * Supports: statuses, paymentStatus, search (orderNumber), date range, ordering. */ async findAllPaginated(restId: string, opts: FindOrdersOpts = {}): Promise> { const { page = 1, limit = 10, - status, + statuses, search, startDate, endDate, @@ -47,9 +47,21 @@ export class OrderRepository extends EntityRepository { const where: FilterQuery = { restaurant: { id: restId } }; - // Filter by status - if (status) { - where.status = status; + // Filter by statuses + if (statuses) { + // Ensure statuses is always an array and normalize it + const normalizedStatuses = Array.isArray(statuses) ? statuses : [statuses]; + // Filter out any empty values + const validStatuses = normalizedStatuses.filter((s): s is OrderStatus => !!s); + + if (validStatuses.length > 0) { + // Use direct equality for single value, $in for multiple values to avoid SQL generation issues + if (validStatuses.length === 1) { + where.status = validStatuses[0]; + } else { + where.status = { $in: validStatuses }; + } + } } if (userId) {