array of statuses for fin orders

This commit is contained in:
2025-12-22 15:12:05 +03:30
parent 2a6d53b04d
commit 7aee650ac6
3 changed files with 54 additions and 85 deletions
+34 -77
View File
@@ -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';
}
@@ -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,
@@ -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<Order> {
/**
* 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<PaginatedResult<Order>> {
const {
page = 1,
limit = 10,
status,
statuses,
search,
startDate,
endDate,
@@ -47,9 +47,21 @@ export class OrderRepository extends EntityRepository<Order> {
const where: FilterQuery<Order> = { 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) {