This commit is contained in:
2026-02-03 16:35:17 +03:30
parent c43ee29afe
commit 14eeba4cfd
5 changed files with 187 additions and 15 deletions
@@ -14,6 +14,7 @@ import { UpdateOrderItemDtoAsAdmin, UpdateOrderItemDtoAsUser } from '../dto/upda
import { UpdateOrderAsAdminDto } from '../dto/update-order.dto';
import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard';
import { CreatePrintFormDto } from '../dto/create-print-form.dto';
import { FindOrderItemsDto } from '../dto/find-order-items.dto';
@ApiTags('orders')
@ApiBearerAuth()
@@ -98,11 +99,19 @@ export class OrderController {
return this.orderService.createOrderAsAdmin(adminId, body);
}
@Get('admin/orders')
@Get('admin/orders/request')
@UseGuards(AdminAuthGuard)
@ApiOperation({ summary: 'Get all orders with pagination and filters' })
findAllAsAdmin(@Query() dto: FindOrdersDto) {
return this.orderService.findOrdersAsAdmin(dto);
@ApiOperation({ summary: 'Get all order requests with pagination and filters' })
findOrderRequestAsAdmin(@Query() dto: FindOrdersDto) {
return this.orderService.findOrderRequestsAsAdmin(dto);
}
@Get('admin/orders/invoiced')
@UseGuards(AdminAuthGuard)
@ApiOperation({ summary: 'Get all invoiced orders with pagination and filters' })
findInvoicedOrdersAsAdmin(@Query() dto: FindOrdersDto) {
return this.orderService.findOrderRequestsAsAdmin(dto);
}
@Get('admin/orders/:id')
@@ -112,6 +121,13 @@ export class OrderController {
return this.orderService.findOrderOrFail(orderId);
}
@Get('admin/orders/item/print')
@UseGuards(AdminAuthGuard)
@ApiOperation({ summary: 'get print orders' })
getPrintOrders(@Body() dto: FindOrderItemsDto) {
return this.orderService.findPrintOrderItemsAsAdmin(dto);
}
@Get('admin/orders/item/:id')
@UseGuards(AdminAuthGuard)
@ApiOperation({ summary: 'order item detail' })
@@ -119,7 +135,12 @@ export class OrderController {
return this.orderService.findOrderItemOrFailByItemId(+itemId);
}
@Get('admin/orders/item/:id/print')
@UseGuards(AdminAuthGuard)
@ApiOperation({ summary: 'create order item print' })
createOrderItemPrint(@Param('id') itemId: string) {
// return this.orderService.findOrderItemOrFailByItemId(+itemId);
}
// @Patch('admin/orders/:orderId')
// @UseGuards(AdminAuthGuard)
// @ApiOperation({ summary: 'Update Order ' })
@@ -0,0 +1,53 @@
import {
IsOptional,
IsString,
IsNumber,
Min,
IsIn,
IsEnum,
IsDateString,
IsArray,
} from 'class-validator';
import { Type, Transform } from 'class-transformer';
import { ApiPropertyOptional } from '@nestjs/swagger';
import { OrderStatusEnum } from '../interface/order.interface';
import { PaymentStatusEnum } from '../../payment/interface/payment';
const sortOrderOptions = ['asc', 'desc'] as const;
type SortOrder = (typeof sortOrderOptions)[number];
export class FindOrderItemsDto {
@ApiPropertyOptional({ default: 1, minimum: 1 })
@IsOptional()
@Type(() => Number)
@IsNumber()
@Min(1)
page: number = 1;
@ApiPropertyOptional({ default: 10, minimum: 1 })
@IsOptional()
@Type(() => Number)
@IsNumber()
@Min(1)
limit: number = 10;
@ApiPropertyOptional()
@IsOptional()
@IsString()
search?: string;
@ApiPropertyOptional({ default: 'createdAt' })
@IsOptional()
@IsString()
orderBy: string = 'createdAt';
@ApiPropertyOptional({
enum: sortOrderOptions,
default: 'desc',
})
@IsOptional()
@IsIn(sortOrderOptions)
order: SortOrder = 'desc';
}
+17 -2
View File
@@ -31,6 +31,7 @@ import { OrderItem } from '../entities/order-item.entity';
import { UpdateOrderAsAdminDto } from '../dto/update-order.dto';
import { CreatePrintFormDto } from '../dto/create-print-form.dto';
import { Product } from 'src/modules/product/entities/product.entity';
import { FindOrderItemsDto } from '../dto/find-order-items.dto';
@Injectable()
@@ -285,11 +286,21 @@ export class OrderService {
return orders
}
async findOrdersAsAdmin(dto: FindOrdersDto) {
const orders = await this.orderRepository.findAllPaginated(dto)
async findOrderRequestsAsAdmin(dto: FindOrdersDto) {
const orders = await this.orderRepository.findAllPaginated({ ...dto, isInvoiced: false })
return orders
}
async findInvoicedOrdersAsAdmin(dto: FindOrdersDto) {
const orders = await this.orderRepository.findAllPaginated({ ...dto, isInvoiced: true, })
return orders
}
async findPrintOrderItemsAsAdmin(dto: FindOrderItemsDto) {
const orderItems = await this.orderItemRepository.findAllPaginated({ ...dto, isPrintFormAdded: true, })
return orderItems
}
async findPrints(dto: FindOrdersDto) {
const orders = await this.orderRepository.findAllPaginated({ ...dto, statuses: [] })
return orders
@@ -524,6 +535,10 @@ export class OrderService {
if (status != undefined) {
order.status = status
if (status === OrderStatusEnum.INVOICED && !order.invoicedAt) {
order.invoicedAt = new Date()
}
}
@@ -1,6 +1,13 @@
import { Injectable } from '@nestjs/common';
import { EntityManager, EntityRepository } from '@mikro-orm/postgresql';
import { EntityManager, EntityRepository, FilterQuery } from '@mikro-orm/postgresql';
import { OrderItem } from '../entities/order-item.entity';
import { PaginatedResult } from 'src/common/interfaces/pagination.interface';
import { FindOrderItemsDto } from '../dto/find-order-items.dto';
class FindOrderItemsOpts extends FindOrderItemsDto {
userId?: string;
isPrintFormAdded?: boolean
};
@Injectable()
@@ -8,4 +15,74 @@ export class OrderItemRepository extends EntityRepository<OrderItem> {
constructor(readonly em: EntityManager) {
super(em, OrderItem);
}
async findAllPaginated(opts: FindOrderItemsOpts): Promise<PaginatedResult<OrderItem>> {
const {
page = 1,
limit = 10,
search,
orderBy = 'createdAt',
order = 'desc',
userId,
isPrintFormAdded
} = opts;
const offset = (page - 1) * limit;
const where: FilterQuery<OrderItem> = {};
if (userId) {
where.order = { user: { id: userId } };
}
if (isPrintFormAdded != undefined) {
if (isPrintFormAdded == true) {
where.printFormCreatedAt = { $not: null }
} else {
where.printFormCreatedAt = null
}
}
// Search by order number or user information
if (search) {
const searchPattern = `%${search}%`;
const searchConditions: any[] = [
{ user: { firstName: { $ilike: searchPattern } } },
{ user: { lastName: { $ilike: searchPattern } } },
{ user: { phone: { $ilike: searchPattern } } },
];
// If search is numeric, also search by orderNumber
const numericSearch = Number(search);
if (!isNaN(numericSearch) && isFinite(numericSearch)) {
searchConditions.push({ orderNumber: numericSearch });
}
where.$or = searchConditions;
}
// First, fetch orders without reviews
const [data, total] = await this.findAndCount(where, {
limit,
offset,
orderBy: { [orderBy]: order.toLowerCase() as 'asc' | 'desc' },
populate: ['designer', 'product'],
});
const totalPages = Math.ceil(total / limit);
return {
data,
meta: {
total,
page,
limit,
totalPages,
},
};
}
}
@@ -9,6 +9,7 @@ import { FindOrdersDto } from '../dto/find-orders.dto';
class FindOrdersOpts extends FindOrdersDto {
userId?: string;
isInvoiced?: boolean;
};
@Injectable()
@@ -17,10 +18,6 @@ export class OrderRepository extends EntityRepository<Order> {
super(em, Order);
}
/**
* Find orders with pagination and optional filters.
* Supports: statuses, paymentStatus, search (orderNumber), date range, ordering.
*/
async findAllPaginated(opts: FindOrdersOpts): Promise<PaginatedResult<Order>> {
const {
page = 1,
@@ -31,7 +28,8 @@ export class OrderRepository extends EntityRepository<Order> {
order = 'desc',
userId,
from,
to
to,
isInvoiced
} = opts;
const offset = (page - 1) * limit;
@@ -59,6 +57,14 @@ export class OrderRepository extends EntityRepository<Order> {
where.user = { id: userId };
}
if (isInvoiced != undefined) {
if (isInvoiced == true) {
where.invoicedAt = { $not: null }
}else{
where.invoicedAt = null
}
}
// Filter by date range
if (from || to) {
where.createdAt = {};