From 5031e34064a7acc9a1f482b115897799963584bc Mon Sep 17 00:00:00 2001 From: morteza-mortezai Date: Mon, 26 Jan 2026 10:27:34 +0330 Subject: [PATCH] order item --- .../order/controllers/order.controller.ts | 109 +++++++----------- .../order/dto/update-order-item.dto.ts | 5 +- .../order/interface/order.interface.ts | 5 +- src/modules/order/providers/order.service.ts | 67 +++++++++-- 4 files changed, 101 insertions(+), 85 deletions(-) diff --git a/src/modules/order/controllers/order.controller.ts b/src/modules/order/controllers/order.controller.ts index 34cea1f..79b6eae 100644 --- a/src/modules/order/controllers/order.controller.ts +++ b/src/modules/order/controllers/order.controller.ts @@ -4,11 +4,11 @@ import { OrderService } from '../providers/order.service'; import { AuthGuard } from '../../auth/guards/auth.guard'; import { UserId } from '../../../common/decorators/user-id.decorator'; import { FindOrdersDto } from '../dto/find-orders.dto'; -import { CreateOrderDto, CreateOrderItemAsUserDto } from '../dto/create-order.dto'; +import { CreateOrderDto, CreateOrderItemAsUserDto, CreateOrderItemDtoAsAdmin } from '../dto/create-order.dto'; import { AdminId } from 'src/common/decorators/admin-id.decorator'; import { CreateOrderAsAdminDto } from '../dto/create-order-as-admin.dto'; import { AssignDesignerDto } from '../dto/assign-designer.dto'; -import { UpdateOrderItemDto } from '../dto/update-order-item.dto'; +import { UpdateOrderItemDtoAsAdmin, UpdateOrderItemDtoAsUser } from '../dto/update-order-item.dto'; @ApiTags('orders') @ApiBearerAuth() @@ -26,8 +26,8 @@ export class OrderController { @Patch('public/order/:id/item/:itemId') @UseGuards(AuthGuard) @ApiOperation({ summary: 'Update order item as user' }) - updateOrder(@Param('id') orderId: string, @Param(':itemId') itemId: string, @Body() body: UpdateOrderItemDto) { - return this.orderService.updateOrderItemAsUser(orderId, itemId, body); + updateOrder(@Param('id') orderId: string, @UserId() userId: string, @Param(':itemId') itemId: string, @Body() body: UpdateOrderItemDtoAsUser) { + return this.orderService.updateOrderItemAsUser(userId, orderId, itemId, body); } @Delete('public/order/:id') @@ -40,8 +40,8 @@ export class OrderController { @Patch('public/order/:id/item') @UseGuards(AuthGuard) @ApiOperation({ summary: 'add item to order as user' }) - addOrderItem(@Param('id') orderId: string, @Body() body: CreateOrderItemAsUserDto) { - return this.orderService.addOrderItemAsUser(orderId, body); + addOrderItem(@Param('id') orderId: string, @UserId() userId: string, @Body() body: CreateOrderItemAsUserDto) { + return this.orderService.addOrderItemAsUser(userId, orderId, body); } @@ -64,6 +64,16 @@ export class OrderController { return this.orderService.confirmOrderItem(userId, orderId, +orderItemId); } + @Delete('public/orders/:orderId/items/:orderItemId') + @UseGuards(AuthGuard) + @ApiOperation({ summary: 'Remove order Item By User' }) + removeOrderItem( + @Param('orderId') orderId: string, + @Param('orderItemId') orderItemId: string, + @UserId() userId: string + ) { + return this.orderService.removeOrderItemAsUser(userId, orderId, orderItemId); + } /*========================== Admin Routes =====================*/ @@ -81,79 +91,38 @@ export class OrderController { return this.orderService.hardDeleteOrder(orderId); } - // @Post('admin/orders/:orderId/add-item') - // @UseGuards(AuthGuard) - // @ApiOperation({ summary: 'add item to Order ' }) - // addItem(@Param('orderId') orderId: string, @Body() body: AddOrderItemDto) { - // return this.orderService.addOrderItem(orderId, body); - // } - // @Post('admin/orders/:orderId/create-invoice') - // @UseGuards(AuthGuard) - // @ApiOperation({ summary: 'Create invoice for new order' }) - // createInvoice(@Param('orderId') orderId: string, @Body() body: CreateInvoiceDto) { - // return this.orderService.calculateOrder(orderId, body); - // } - - @Post('admin/orders/:orderId/assign-designer') + @Post('admin/orders/:orderId/designer') @UseGuards(AuthGuard) @ApiOperation({ summary: 'Assign Order Designer ' }) assignDesigner(@Param('orderId') orderId: string, @Body() body: AssignDesignerDto) { return this.orderService.assignDesigner(orderId, body.designerId); } + @Patch('admin/order/:id/item') + @UseGuards(AuthGuard) + @ApiOperation({ summary: 'add item to order By Admin' }) + addOrderItemAsAdmin(@Param('id') orderId: string, @Body() body: CreateOrderItemDtoAsAdmin) { + return this.orderService.addOrderItemAsAdmin(orderId, body); + } - // @UseGuards(AdminAuthGuard) - // @Permissions(Permission.MANAGE_ORDERS) - // @Get('admin/orders') - // @ApiOperation({ summary: 'Get all orders with pagination and filters' }) - // findAllAdmin(, @Query() dto: FindOrdersDto) { - // return this.ordersService.findAllForAdmin(, dto); - // } - // @UseGuards(AdminAuthGuard) - // @Permissions(Permission.MANAGE_ORDERS) - // @ApiOperation({ summary: 'Get an order By id for User' }) - // @ApiParam({ name: 'orderId', description: 'Order ID' }) - // @Get('admin/orders/:orderId') - // findOneAsAdmin(@Param('orderId') orderId: string,) { - // return this.ordersService.findOne(orderId,); - // } + @Delete('admin/orders/:orderId/items/:orderItemId') + @UseGuards(AuthGuard) + @ApiOperation({ summary: 'Remove order Item By Admin' }) + removeOrderItemAdAdmin( + @Param('orderId') orderId: string, + @Param('orderItemId') orderItemId: string, + ) { + return this.orderService.removeOrderItemAsAdmin(orderId, orderItemId); + } - // @UseGuards(AdminAuthGuard) - // @Permissions(Permission.MANAGE_ORDERS) - // @Patch('admin/orders/:orderId/:status') - // @ApiOperation({ summary: 'Update an order status' }) - // @ApiParam({ name: 'orderId', description: 'Order ID' }) - // @ApiBody({ type: UpdateOrderStatusDto }) - // @ApiParam({ - // name: 'status', - // description: 'Order status', - // enum: OrderStatus, - // }) - // updateStatus( - // @Param('orderId') orderId: string, - // @Body() dto: UpdateOrderStatusDto, - // @Param('status') status: OrderStatus, - // , - // ) { - // return this.ordersService.changeOrderStatus(orderId, , status, 'admin', dto?.desc); - // } + @Patch('admin/order/:id/item/:itemId') + @UseGuards(AuthGuard) + @ApiOperation({ summary: 'Update order item' }) + updateOrderAsAdmin(@Param('id') orderId: string, @Param(':itemId') itemId: string, + @Body() body: UpdateOrderItemDtoAsAdmin) { + return this.orderService.updateOrderItemAsAdmin(orderId, itemId, body); + } - // @UseGuards(AdminAuthGuard) - // @Permissions(Permission.VIEW_REPORTS) - // @ApiOperation({ summary: 'Get Stats for report page' }) - // @Get('admin/orders/stats') - // findStats() { - // return this.ordersService.getStats(); - // } - - // @UseGuards(AdminAuthGuard) - // @Permissions(Permission.VIEW_REPORTS) - // @ApiOperation({ summary: 'Get product sales pie chart data for last month' }) - - // @Get('admin/orders/product-sales-pie-chart') - // getproductSalesPieChart() { - // return this.ordersService.getproductSalesPieChart(); - // } } diff --git a/src/modules/order/dto/update-order-item.dto.ts b/src/modules/order/dto/update-order-item.dto.ts index 5b4fc79..41de503 100644 --- a/src/modules/order/dto/update-order-item.dto.ts +++ b/src/modules/order/dto/update-order-item.dto.ts @@ -1,6 +1,7 @@ import { PartialType } from '@nestjs/swagger'; -import { CreateOrderItemAsUserDto } from './create-order.dto'; +import { CreateOrderItemAsUserDto, CreateOrderItemDtoAsAdmin } from './create-order.dto'; -export class UpdateOrderItemDto extends PartialType(CreateOrderItemAsUserDto) { } +export class UpdateOrderItemDtoAsUser extends PartialType(CreateOrderItemAsUserDto) { } +export class UpdateOrderItemDtoAsAdmin extends PartialType(CreateOrderItemDtoAsAdmin) { } diff --git a/src/modules/order/interface/order.interface.ts b/src/modules/order/interface/order.interface.ts index 6ffe67e..1ba2f5d 100644 --- a/src/modules/order/interface/order.interface.ts +++ b/src/modules/order/interface/order.interface.ts @@ -34,4 +34,7 @@ export interface AddOrderItem { attachments: { url: string, type: string }[] unitPrice?: number discount?: number -} \ No newline at end of file +} + +export type UpdateOrderItem = Partial + diff --git a/src/modules/order/providers/order.service.ts b/src/modules/order/providers/order.service.ts index 575a771..48eff23 100644 --- a/src/modules/order/providers/order.service.ts +++ b/src/modules/order/providers/order.service.ts @@ -6,7 +6,7 @@ import { FindOrdersDto } from '../dto/find-orders.dto'; import { EventEmitter2 } from '@nestjs/event-emitter'; import { CreateOrderDto, CreateOrderItemAsUserDto, CreateOrderItemDtoAsAdmin } from '../dto/create-order.dto'; import { UserService } from 'src/modules/user/providers/user.service'; -import { AddOrderItem, OrderStatusEnum } from '../interface/order.interface'; +import { AddOrderItem, OrderStatusEnum, UpdateOrderItem } from '../interface/order.interface'; import { OrderItemRepository } from '../repositories/order-item.repository'; import { ProductService } from 'src/modules/product/providers/product.service'; import { ProductRepository } from 'src/modules/product/repositories/product.repository'; @@ -16,7 +16,7 @@ import { AdminRepository } from 'src/modules/admin/repositories/admin.repository import { CreateOrderAsAdminDto } from '../dto/create-order-as-admin.dto'; import { Order } from '../entities/order.entity'; import { PaymentRepository } from 'src/modules/payment/repositories/payment.repository'; -import { UpdateOrderItemDto } from '../dto/update-order-item.dto'; +import { UpdateOrderItemDtoAsAdmin, UpdateOrderItemDtoAsUser } from '../dto/update-order-item.dto'; import { UpdateOrderDto } from '../dto/update-order.dto'; @@ -97,7 +97,7 @@ export class OrderService { return order } - async addOrderItemAsUser(orderId: string, dto: CreateOrderItemAsUserDto) { + async addOrderItemAsUser(userId: string, orderId: string, dto: CreateOrderItemAsUserDto) { const order = await this.findOneOrFail(orderId) @@ -105,6 +105,10 @@ export class OrderService { throw new BadRequestException(`You can not update when status is ${order.status}`) } + if (order.user.id !== userId) { + throw new BadRequestException(`This order doest belongs to you!`) + } + const orderItem = this.persistOrderItem(order, dto) await this.em.flush() @@ -157,19 +161,35 @@ export class OrderService { return orderItem } - async updateOrderItemAsUser(orderId: string, itemId: string, dto: UpdateOrderItemDto) { - const { attributesValues, description, productId, quantity, attachments } = dto + async updateOrderItemAsUser(userId: string, orderId: string, itemId: string, dto: UpdateOrderItemDtoAsUser) { const order = await this.findOneOrFail(orderId) - if (!order) { - throw new BadRequestException(`Order not found`) + if (order.user.id !== userId) { + throw new BadRequestException(`This order doesnt belongs to you`) } if (order.status !== OrderStatusEnum.CREATED) { throw new BadRequestException(`You can not update when status is ${order.status}`) } + const orderItem = await this.updateOrderItem(itemId, dto) + + return orderItem + } + + async updateOrderItemAsAdmin(orderId: string, itemId: string, dto: UpdateOrderItemDtoAsAdmin) { + + const order = await this.findOneOrFail(orderId) + + const orderItem = await this.updateOrderItem(itemId, dto) + + return orderItem + } + + async updateOrderItem(itemId: string, dto: UpdateOrderItem) { + const { attributesValues, description, productId, quantity, attachments, discount, unitPrice } = dto + const orderItem = await this.orderItemRepository.findOne({ id: itemId }) @@ -202,23 +222,47 @@ export class OrderService { if (attachments) { orderItem.attachments = attachments } + if (discount) { + orderItem.discount = discount + } + if (unitPrice) { + orderItem.unitPrice = unitPrice + } + + await this.em.flush() return orderItem } - async removeOrderItem(orderId: string, itemId: string) { + async removeOrderItemAsAdmin(orderId: string, itemId: string) { const order = await this.findOneOrFail(orderId) - if (!order) { - throw new BadRequestException(`Order not found`) + await this.removeOrderItem(itemId) + + return true + } + + async removeOrderItemAsUser(userId: string, orderId: string, itemId: string) { + + const order = await this.findOneOrFail(orderId) + + if (order.user.id !== userId) { + throw new BadRequestException(`this order is not belongs to you`) } if (order.status !== OrderStatusEnum.CREATED) { throw new BadRequestException(`You can not update when status is ${order.status}`) } + await this.removeOrderItem(itemId) + + return true + } + + async removeOrderItem(itemId: string) { + const orderItem = await this.orderItemRepository.findOne({ id: itemId }) @@ -229,8 +273,7 @@ export class OrderService { await this.em.removeAndFlush(orderItem) - - return orderItem + return true } async createOrderAsAdmin(adminId: string, dto: CreateOrderAsAdminDto) {