From 5e5eeec5be9208777f74cbe38ad6dba93cdadaa0 Mon Sep 17 00:00:00 2001 From: morteza-mortezai Date: Fri, 30 Jan 2026 21:01:20 +0330 Subject: [PATCH] update order --- src/modules/admin/providers/admin.service.ts | 10 ++ .../form-builder/provider/field.service.ts | 2 +- .../order/controllers/order.controller.ts | 17 +- src/modules/order/dto/create-order.dto.ts | 83 ++++------ src/modules/order/dto/update-order.dto.ts | 2 +- .../order/entities/order-item.entity.ts | 17 +- src/modules/order/entities/order.entity.ts | 10 +- .../order/interface/order.interface.ts | 68 ++++---- src/modules/order/providers/order.service.ts | 152 ++++++++++-------- .../product/entities/product.entity.ts | 4 - .../product/providers/category.service.ts | 4 +- .../product/providers/product.service.ts | 76 +-------- 12 files changed, 189 insertions(+), 256 deletions(-) diff --git a/src/modules/admin/providers/admin.service.ts b/src/modules/admin/providers/admin.service.ts index 97f4a4f..e59f419 100644 --- a/src/modules/admin/providers/admin.service.ts +++ b/src/modules/admin/providers/admin.service.ts @@ -121,4 +121,14 @@ export class AdminService { } return admin } + + async findByIds(adminIds: string[]) { + const admins = await this.adminRepository.find({ + id: { $in: adminIds } + }) + if (adminIds.length !== admins.length) { + throw new BadRequestException("some admins not found") + } + return admins + } } diff --git a/src/modules/form-builder/provider/field.service.ts b/src/modules/form-builder/provider/field.service.ts index ed8eed4..dc0bc70 100644 --- a/src/modules/form-builder/provider/field.service.ts +++ b/src/modules/form-builder/provider/field.service.ts @@ -75,7 +75,7 @@ export class FieldService { return this.fieldRepository.find({ entityId }, - { populate: ['options', 'options.value'] }); + { populate: ['options'] }); } async findById(fieldId: number): Promise { diff --git a/src/modules/order/controllers/order.controller.ts b/src/modules/order/controllers/order.controller.ts index ae2e463..6166344 100644 --- a/src/modules/order/controllers/order.controller.ts +++ b/src/modules/order/controllers/order.controller.ts @@ -5,7 +5,7 @@ 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, + CreateOrderAsUSerDto, CreateOrderItemAsUserDto, CreateOrderItemDtoAsAdmin, CreateOrderAsAdminDto } from '../dto/create-order.dto'; import { AdminId } from 'src/common/decorators/admin-id.decorator'; @@ -23,7 +23,7 @@ export class OrderController { @Post('public/orders') @UseGuards(AuthGuard) @ApiOperation({ summary: 'create order ' }) - createOrder(@UserId() userId: string, @Body() body: CreateOrderDto) { + createOrder(@UserId() userId: string, @Body() body: CreateOrderAsUSerDto) { return this.orderService.createOrderAsUser(userId, body); } @@ -111,6 +111,13 @@ export class OrderController { return this.orderService.updateOrderAsAdmin(orderId, dto); } + @Patch('admin/orders/:orderId/print-form') + @UseGuards(AdminAuthGuard) + @ApiOperation({ summary: 'Update Order ' }) + updateOrderForPrint(@Param('orderId') orderId: string, @Body() dto: UpdateOrderDtoAsAdmin) { + return this.orderService.updateOrderAsAdmin(orderId, dto); + } + @Delete('admin/orders/:orderId') @UseGuards(AdminAuthGuard) @ApiOperation({ summary: 'Hard Delete Order ' }) @@ -119,11 +126,11 @@ export class OrderController { } - @Post('admin/orders/:orderId/designer') + @Post('admin/orders/:orderId/item/:itemId/designer') @UseGuards(AdminAuthGuard) @ApiOperation({ summary: 'Assign Order Designer ' }) - assignDesigner(@Param('orderId') orderId: string, @Body() body: AssignDesignerDto) { - return this.orderService.assignDesigner(orderId, body.designerId); + assignDesigner(@Param('orderId') orderId: string, @Param('itemId') itemId: string, @Body() body: AssignDesignerDto) { + return this.orderService.assignDesigner(orderId, +itemId, body.designerId); } @Post('admin/orders/:orderId/invoice') diff --git a/src/modules/order/dto/create-order.dto.ts b/src/modules/order/dto/create-order.dto.ts index 9302118..8cff6ec 100644 --- a/src/modules/order/dto/create-order.dto.ts +++ b/src/modules/order/dto/create-order.dto.ts @@ -7,12 +7,12 @@ import { IsBoolean, IsEnum } from 'class-validator'; -import { ApiPropertyOptional, ApiProperty, OmitType } from '@nestjs/swagger'; +import { ApiPropertyOptional, ApiProperty } from '@nestjs/swagger'; import { Type } from 'class-transformer'; -import { IAttribute, OrderStatusEnum } from '../interface/order.interface'; +import { IAttachment, IField, OrderStatusEnum } from '../interface/order.interface'; -export class CreateOrderItemDtoAsAdmin { +export class CreateOrderItemAsUserDto { @IsInt() @ApiProperty() productId: number; @@ -23,7 +23,7 @@ export class CreateOrderItemDtoAsAdmin { @ApiProperty() @IsArray() - attributes: IAttribute[] + attributes: IField[] @ApiPropertyOptional({ example: 'توضیحات' }) @IsString() @@ -33,6 +33,22 @@ export class CreateOrderItemDtoAsAdmin { @IsArray() attachments: { url: string, type: string }[] + +} + +export class CreateOrderItemDtoAsAdmin extends CreateOrderItemAsUserDto { + @ApiPropertyOptional({ example: [] }) + @IsArray() + print?: IField[] + + @ApiPropertyOptional({ example: [] }) + @IsArray() + printAttachments?: IAttachment[] + + @IsInt() + @ApiProperty() + designerId: string; + @ApiProperty() @IsNumber() unitPrice: number @@ -43,10 +59,7 @@ export class CreateOrderItemDtoAsAdmin { } -export class CreateOrderItemAsUserDto extends OmitType(CreateOrderItemDtoAsAdmin, ['unitPrice', 'discount']) { } - - -export class CreateOrderDto { +export class CreateOrderAsUSerDto { @IsArray() @ApiProperty({ isArray: true, type: [CreateOrderItemAsUserDto], example: [ @@ -55,8 +68,8 @@ export class CreateOrderDto { quantity: 100, attributes: [ { - attributeId:1, - value:'string | boolean| number' + attributeId: 1, + value: 'string | boolean| number' } ], attachments: [ @@ -72,37 +85,6 @@ export class CreateOrderDto { items: CreateOrderItemAsUserDto[]; } -export class CreateOrderItemDto { - - @IsInt() - @ApiProperty() - productId: number; - - @ApiProperty() - @IsNumber() - quantity: number - - @ApiProperty() - @IsArray() - attributes: IAttribute[] - - @ApiProperty() - @IsNumber() - unitPrice: number - - @ApiProperty() - @IsNumber() - discount: number - - @ApiPropertyOptional({ example: 'توضیحات' }) - @IsString() - description: string - - @ApiPropertyOptional({ example: [] }) - @IsArray() - @IsString({ each: true }) - attachments: { url: string, type: string }[] -} export class CreateOrderAsAdminDto { @ApiProperty({ example: '' }) @@ -112,9 +94,12 @@ export class CreateOrderAsAdminDto { @IsArray() @ApiProperty({ - isArray: true, type: [CreateOrderItemDto], example: [ + isArray: true, type: [CreateOrderItemDtoAsAdmin], example: [ { productId: 1, + designerId: '', + print: [{ fieldId: '', value: '' }], + printAttachments: [{ url: '', type: '' }], quantity: 100, attributesValues: [] } @@ -122,19 +107,9 @@ export class CreateOrderAsAdminDto { }) @IsNotEmpty() @ArrayMinSize(1, { message: 'At least one product is required' }) - @Type(() => CreateOrderItemDto) - items: CreateOrderItemDto[]; + @Type(() => CreateOrderItemDtoAsAdmin) + items: CreateOrderItemDtoAsAdmin[]; - @ApiProperty({ example: '' }) - @IsString() - @IsNotEmpty() - designerId: string - - @ApiProperty({ example: '' }) - @IsArray() - @IsString({ each: true }) - @IsNotEmpty() - attachments: string[] @ApiProperty({}) @IsString() diff --git a/src/modules/order/dto/update-order.dto.ts b/src/modules/order/dto/update-order.dto.ts index b86918c..2e26095 100644 --- a/src/modules/order/dto/update-order.dto.ts +++ b/src/modules/order/dto/update-order.dto.ts @@ -1,5 +1,5 @@ import { OmitType, PartialType } from '@nestjs/swagger'; -import { CreateOrderAsAdminDto, CreateOrderDto } from './create-order.dto'; +import { CreateOrderAsAdminDto } from './create-order.dto'; export class UpdateOrderDtoAsAdmin extends PartialType(OmitType(CreateOrderAsAdminDto, 'items' as any)) { } diff --git a/src/modules/order/entities/order-item.entity.ts b/src/modules/order/entities/order-item.entity.ts index 547b272..2f81a39 100644 --- a/src/modules/order/entities/order-item.entity.ts +++ b/src/modules/order/entities/order-item.entity.ts @@ -2,7 +2,8 @@ import { Entity, Formula, Index, ManyToOne, OptionalProps, PrimaryKey, Property import { BaseEntity } from '../../../common/entities/base.entity'; import { Order } from './order.entity'; import { Product } from 'src/modules/product/entities/product.entity'; -import { IAttribute } from '../interface/order.interface'; +import { IAttachment, IField } from '../interface/order.interface'; +import { Admin } from 'src/modules/admin/entities/admin.entity'; // import { OrderItemStatus } from '../interface/order.interface'; @Entity({ tableName: 'order_items' }) @@ -19,8 +20,11 @@ export class OrderItem { @ManyToOne(() => Product) product!: Product; + @ManyToOne(() => Admin, { nullable: true }) + designer?: Admin + @Property({ type: 'json', nullable: true }) - attributes?: IAttribute[] + attributes?: IField[] @Property({ type: 'int' }) quantity!: number; @@ -49,7 +53,14 @@ export class OrderItem { adminDescription?: string; @Property({ type: 'json', nullable: true }) - attachments?: { type: string, url: string }[] // user attachments like voice and photos + attachments?: IAttachment[] // user attachments like voice and photos + + @Property({ type: 'json', nullable: true }) + printAttachments?: IAttachment[] + + + @Property({ type: 'json', nullable: true }) + print?: IField[] // print form selected attributes @Property({ nullable: true, columnType: 'timestamptz' }) confirmedAt?: Date; diff --git a/src/modules/order/entities/order.entity.ts b/src/modules/order/entities/order.entity.ts index e0eb160..67d4918 100644 --- a/src/modules/order/entities/order.entity.ts +++ b/src/modules/order/entities/order.entity.ts @@ -13,7 +13,7 @@ import { OptionalProps, Formula } from '@mikro-orm/core'; -import { OrderStatusEnum } from '../interface/order.interface'; +import { IField, OrderStatusEnum } from '../interface/order.interface'; import { User } from '../../user/entities/user.entity'; import { OrderItem } from './order-item.entity'; import { Payment } from 'src/modules/payment/entities/payment.entity'; @@ -52,9 +52,6 @@ export class Order { @ManyToOne(() => Admin, { nullable: true }) creator?: Admin - @ManyToOne(() => Admin, { nullable: true }) - designer?: Admin - @Property({ type: 'int', nullable: true }) orderNumber?: number; @@ -198,11 +195,6 @@ export class Order { @Enum(() => OrderStatusEnum) status!: OrderStatusEnum; - @Property({ type: 'json', nullable: true }) - attachments?: string[] - - @Property({ type: 'json', nullable: true }) - print?: { fieldId: string, value: string }[] // id of field options @Property({ type: 'string', nullable: true }) paymentMethod?: string; diff --git a/src/modules/order/interface/order.interface.ts b/src/modules/order/interface/order.interface.ts index 9f581b3..166f255 100644 --- a/src/modules/order/interface/order.interface.ts +++ b/src/modules/order/interface/order.interface.ts @@ -1,3 +1,6 @@ +import { Admin } from "src/modules/admin/entities/admin.entity" +import { Product } from "src/modules/product/entities/product.entity" + export enum OrderStatusEnum { CREATED = 'created', @@ -25,49 +28,44 @@ export enum OrderStatusEnum { CANCELED = 'canceled', } +export interface IField { fieldId: number, value: string } -export interface CreateOrderItemParam{ +export interface IAttachment { type: string, url: string } + +export interface CreateOrderItem { + productId: number, quantity: number - attributes?: IAttribute[] + attributes?: IField[] description?: string - attachments?: { url: string, type: string }[] + attachments?: IAttachment[] unitPrice?: number discount?: number -} - -export interface CreateOrderParam { - userId: string - items: Array<{ - productId: number, - quantity: number - attributes: IAttribute[] - description: string - attachments: { url: string, type: string }[] - unitPrice?: number - discount?: number - }>; - status: OrderStatusEnum - //optional - enableTax?: Boolean - attachments?: string[] - paymentMethod?: string - adminId?: string - estimatedDays?: number + print?: IField[] + printAttachments?: IAttachment[] designerId?: string } -export type UpdateOrderParam = Partial> - - -export interface UpdateOrderItem { - productId?: number, - quantity?: number - attributes?: IAttribute[] - description?: string - attachments?: { url: string, type: string }[] - unitPrice?: number - discount?: number +export type CreateOrderItemPopulated = Omit & { + product: Product, + designer?: Admin } -export interface IAttribute { attributeId: number, value: string | number | boolean } \ No newline at end of file +export interface CreateOrder { + userId: string + status: OrderStatusEnum + enableTax?: Boolean + paymentMethod?: string + adminId?: string + estimatedDays?: number +} + +export interface CreateOrderWithItems extends CreateOrder { + items: CreateOrderItem[] +} + +export type UpdateOrder = Partial + + +export type UpdateOrderItem = Partial + diff --git a/src/modules/order/providers/order.service.ts b/src/modules/order/providers/order.service.ts index 3b8ee6e..2ed34f9 100644 --- a/src/modules/order/providers/order.service.ts +++ b/src/modules/order/providers/order.service.ts @@ -4,14 +4,19 @@ import { OrderRepository } from '../repositories/order.repository'; import { FindOrdersDto } from '../dto/find-orders.dto'; import { EventEmitter2 } from '@nestjs/event-emitter'; import { - CreateOrderDto, CreateOrderItemAsUserDto, + CreateOrderAsAdminDto, + CreateOrderAsUSerDto, CreateOrderItemAsUserDto, CreateOrderItemDtoAsAdmin } from '../dto/create-order.dto'; import { UserService } from 'src/modules/user/providers/user.service'; import { - CreateOrderItemParam, - CreateOrderParam, OrderStatusEnum, - UpdateOrderItem, UpdateOrderParam + CreateOrderItem, + CreateOrder, OrderStatusEnum, + // UpdateOrderItem, + CreateOrderWithItems, + CreateOrderItemPopulated, + UpdateOrder, + UpdateOrderItem } from '../interface/order.interface'; import { OrderItemRepository } from '../repositories/order-item.repository'; import { ProductService } from 'src/modules/product/providers/product.service'; @@ -26,6 +31,7 @@ import { Admin } from 'src/modules/admin/entities/admin.entity'; import { Product } from 'src/modules/product/entities/product.entity'; import { AdminService } from 'src/modules/admin/providers/admin.service'; import { OrderItem } from '../entities/order-item.entity'; +import { UpdateOrderDtoAsAdmin } from '../dto/update-order.dto'; @Injectable() @@ -47,7 +53,7 @@ export class OrderService { private readonly paymentRepository: PaymentRepository, ) { } - async createOrderAsAdmin(adminId: string, dto: CreateOrderParam) { + async createOrderAsAdmin(adminId: string, dto: CreateOrderAsAdminDto) { const order = await this.createOrder({ ...dto, adminId }) // await this.calculateOrder(order) // this.em.flush() @@ -56,7 +62,7 @@ export class OrderService { } - async createOrderAsUser(userId: string, dto: CreateOrderDto) { + async createOrderAsUser(userId: string, dto: CreateOrderAsUSerDto) { const order = await this.createOrder({ ...dto, userId, status: OrderStatusEnum.CREATED }) this.logger.log("Order created as admin") return order @@ -64,10 +70,10 @@ export class OrderService { } - async updateOrderAsAdmin(orderId: string, param: UpdateOrderParam) { + async updateOrderAsAdmin(orderId: string, dto: UpdateOrderDtoAsAdmin) { const order = await this.findOrderOrFail(orderId) - const updateOrder = await this.updateOrder(order, param) + const updateOrder = await this.updateOrder(order, dto) // const updateOrder = await this.calculateOrder(order) @@ -92,7 +98,7 @@ export class OrderService { const product = await this.productService.findOneOrFail(dto.productId) - const orderItem = this.createOrderItem(order, product, dto) + const orderItem = this.createOrderItemEntity(order, { ...dto, product }) await this.em.flush() @@ -105,7 +111,12 @@ export class OrderService { const product = await this.productService.findOneOrFail(dto.productId) - const orderItem = this.createOrderItem(order, product, dto) + let designer: Admin | undefined + if (dto.designerId) { + designer = await this.adminService.findOrFail(dto.designerId) + } + + const orderItem = this.createOrderItemEntity(order, { ...dto, designer, product }) await this.em.flush() @@ -118,32 +129,32 @@ export class OrderService { async updateOrderItemAsUser(userId: string, orderId: string, itemId: number, dto: UpdateOrderItemDtoAsUser) { - const order = await this.findOrderOrFail(orderId) + const orderItem = await this.findOrderItemOrFail(orderId,itemId) - if (order.user.id !== userId) { + if (orderItem.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}`) + if (orderItem.order.status !== OrderStatusEnum.CREATED) { + throw new BadRequestException(`You can not update when status is ${orderItem.order.status}`) } - const orderItem = await this.updateOrderItem(itemId, dto) + const updated = await this.updateOrderItem(orderItem, dto) - return orderItem + return updated } async updateOrderItemAsAdmin(orderId: string, itemId: number, dto: UpdateOrderItemDtoAsAdmin) { - await this.findOrderItemOrFail(orderId, itemId) + const orderItem = await this.findOrderItemOrFail(orderId, itemId) - const orderItem = await this.updateOrderItem(itemId, dto) + const updated = await this.updateOrderItem(orderItem, dto) // await this.calculateOrder(undefined, orderId) // await this.em.flush() - return orderItem + return updated } async removeOrderItemAsAdmin(orderId: string, itemId: number) { @@ -237,24 +248,21 @@ export class OrderService { return orderItem } - async assignDesigner(orderId: string, designerId: string) { - const order = await this.orderRepository.findOne({ id: orderId }) - if (!order) { - throw new BadRequestException("Order not found") - } + async assignDesigner(orderId: string, orderItemId: number, designerId: string) { + + const orderItem = await this.findOrderItemOrFail(orderId, orderItemId) + const designer = await this.adminRepository.findOne({ id: designerId }) if (!designer) { throw new BadRequestException("designer not found") } - order.designer = designer - // order.status = OrderStatusEnum.IN_DESIGN + orderItem.designer = designer + await this.em.persistAndFlush(orderItem) - await this.em.persistAndFlush(order) - - return order + return orderItem } @@ -298,45 +306,51 @@ export class OrderService { // ==================== Entity Methods ==================== - private async createOrderItem(order: Order, product: Product, dto: CreateOrderItemParam, em?: EntityManager) { - const { attributes, description, quantity, attachments, discount, unitPrice } = dto + private async createOrderItemEntity(order: Order, dto: CreateOrderItemPopulated, em?: EntityManager) { + const { attributes, description, quantity, attachments, discount, + unitPrice, product, designer, print, printAttachments } = dto + const eM = em ?? this.em return eM.create( OrderItem, { + designer, order, attributes, description, quantity, attachments, - discount: discount ?? undefined, - unitPrice: unitPrice ?? undefined, - product + discount, + unitPrice, + product, + print, + printAttachments }) } // ==================== Core Logic ==================== - async createOrder(dto: CreateOrderParam) { - const { items, userId, attachments, designerId, enableTax, + async createOrder(dto: CreateOrderWithItems) { + const { items, userId, enableTax, estimatedDays, paymentMethod, status, adminId } = dto // Validate and fetch all required entities const user = await this.userService.findOrFail(userId) const admin = adminId ? await this.adminService.findOrFail(adminId) : undefined - const designer = designerId ? await this.adminService.findOrFail(designerId) : undefined const products = await this.productService.findProductsByIds(items.map(item => item.productId)) + const desiners = await this.adminService.findByIds(items.map(item => item.designerId).filter(id => id != null)) const productMap = new Map( products.map(p => [Number(p.id), p]) ); + const designerMap = new Map( + desiners.map(d => [d.id, d]) + ) return this.em.transactional(async (em) => { const order = em.create(Order, { creator: admin, user, - attachments, - designer, enableTax, estimatedDays, paymentMethod, @@ -351,8 +365,16 @@ export class OrderService { if (!product) { throw new BadRequestException("Product not found!") } + let designer: undefined | Admin = undefined - const orderItem = await this.createOrderItem(order, product, item, em) + if (item.designerId) { + designer = designerMap.get(item.designerId) + if (!designer) { + throw new BadRequestException("designer not found!") + } + } + + const orderItem = await this.createOrderItemEntity(order, { ...item, designer, product }, em) order.items.add(orderItem) } @@ -369,8 +391,8 @@ export class OrderService { } - async updateOrder(order: Order, param: UpdateOrderParam) { - const { attachments, adminId, designerId, enableTax, + async updateOrder(order: Order, param: UpdateOrder) { + const { adminId, enableTax, estimatedDays, paymentMethod, status, userId } = param @@ -386,15 +408,6 @@ export class OrderService { } - if (designerId != undefined && designerId != undefined) { - const designer = await this.adminService.findOrFail(designerId) - order.designer = designer - } - - if (attachments != undefined) { - order.attachments = attachments - } - if (enableTax != undefined) { order.enableTax = enableTax } @@ -411,36 +424,31 @@ export class OrderService { order.status = status } + + await this.em.persistAndFlush(order) return order } - async updateOrderItem(itemId: number, dto: UpdateOrderItem) { - const { attributes, description, productId, quantity, attachments, discount, unitPrice } = dto + async updateOrderItem(orderItem: OrderItem, dto: UpdateOrderItem) { + const { attributes, description, product, quantity, + attachments, discount, unitPrice, designer, print, printAttachments } = dto - const orderItem = await this.orderItemRepository.findOne({ - id: itemId - }) - - if (!orderItem) { - throw new BadRequestException(`orderItem not found`) + if (product && orderItem.product.id !== product.id) { + orderItem.product = product } - // product is changed - if (productId && Number(orderItem.product.id) !== productId) { - const product = await this.productRepository.findOne({ id: productId }) - - if (!product) { - throw new BadRequestException(`product not found`) - } - - orderItem.product = product + if (designer && orderItem.designer?.id !== designer.id) { + orderItem.designer = designer } if (attributes) { orderItem.attributes = attributes } + if (printAttachments) { + orderItem.printAttachments = printAttachments + } if (description) { orderItem.description = description } @@ -459,6 +467,14 @@ export class OrderService { orderItem.unitPrice = unitPrice } + if (print != undefined) { + orderItem.print = print + } + + if (attributes != undefined) { + orderItem.attributes = attributes + } + await this.em.flush() return orderItem diff --git a/src/modules/product/entities/product.entity.ts b/src/modules/product/entities/product.entity.ts index b638a21..e45737b 100644 --- a/src/modules/product/entities/product.entity.ts +++ b/src/modules/product/entities/product.entity.ts @@ -9,8 +9,6 @@ export class Product extends BaseEntity { @ManyToOne(() => Category) category: Category - @Property({ type: 'json', nullable: true }) - attributes?: string[] @PrimaryKey({ type: 'bigint', autoincrement: true }) id: bigint @@ -24,8 +22,6 @@ export class Product extends BaseEntity { @Property({ type: 'json' }) quantities: number[] - // @Property() - // prepareTime: number; @Property({ type: 'text', nullable: true }) linkUrl?: string; diff --git a/src/modules/product/providers/category.service.ts b/src/modules/product/providers/category.service.ts index 265f9ca..8a9b433 100644 --- a/src/modules/product/providers/category.service.ts +++ b/src/modules/product/providers/category.service.ts @@ -1,7 +1,7 @@ import { BadGatewayException, Injectable, NotFoundException } from '@nestjs/common'; import { EntityManager } from '@mikro-orm/postgresql'; import { RequiredEntityData } from '@mikro-orm/core'; - import { CategoryMessage, productMessage } from 'src/common/enums/message.enum'; +import { CategoryMessage, productMessage } from 'src/common/enums/message.enum'; import { CategoryRepository } from '../repositories/category.repository'; import { CreateCategoryDto } from '../dto/create-category.dto'; import { Category } from '../entities/category.entity'; @@ -12,7 +12,7 @@ import { UpdateCategoryDto } from '../dto/update-category.dto'; export class CategoryService { constructor( - private readonly categoryRepository: CategoryRepository, + private readonly categoryRepository: CategoryRepository, private readonly em: EntityManager, ) { } diff --git a/src/modules/product/providers/product.service.ts b/src/modules/product/providers/product.service.ts index 6857214..db55550 100644 --- a/src/modules/product/providers/product.service.ts +++ b/src/modules/product/providers/product.service.ts @@ -7,10 +7,6 @@ import { RequiredEntityData } from '@mikro-orm/core'; import { Product } from '../entities/product.entity'; import { CategoryMessage, productMessage } from 'src/common/enums/message.enum'; import { CategoryRepository } from '../repositories/category.repository'; -import { FieldService } from 'src/modules/form-builder/provider/field.service'; -import { FieldRepository } from 'src/modules/form-builder/repository/field.repository'; -import { Field } from 'src/modules/form-builder/entities/field.entity'; -import { Category } from '../entities/category.entity'; @Injectable() export class ProductService { @@ -18,7 +14,6 @@ export class ProductService { constructor( private readonly productRepository: ProductRepository, private readonly categoryRepository: CategoryRepository, - private readonly fieldRepository: FieldRepository, private readonly em: EntityManager, ) { } @@ -34,7 +29,6 @@ export class ProductService { order: rest.order ?? null, title: rest.title, desc: rest.desc, - // prepareTime: rest.prepareTime ?? 0, quantities: rest.quantities, images: rest.images ?? undefined, linkUrl: rest.linkUrl, @@ -76,81 +70,15 @@ export class ProductService { return this.productRepository.findAllPaginated(dto); } - async findById(productId: string): Promise< - Omit & { - attributes: Field[]; - category: Category; - } - > { + async findById(productId: string) { const product = await this.productRepository.findOne({ id: productId }, { populate: ['category'] }); if (!product) throw new NotFoundException(productMessage.NOT_FOUND); - const attributes = product?.attributes - - let fields: Field[] = [] - - if (attributes && attributes.length) { - fields = await this.fieldRepository.find({ - id: { $in: attributes } - }, - { populate: ['options'] }) - } - - return { ...product, attributes: fields }; + return product; } - // async update( id: string, dto: Partial): Promise { - // const { categoryId, dailyStock, ...rest } = dto; - // const product = await this.productRepository.findOne({ id, restaurant: { id: } }, { populate: ['restaurant'] }); - // if (!product) { - // throw new NotFoundException(productMessage.NOT_FOUND); - // } - - // // attach new categories if provided (adds, does not attempt to preserve/remove existing ones) - // if (categoryId) { - // const category = await this.categoryRepository.findOne({ id: categoryId, restaurant: { id: } }); - - // if (!category) { - // throw new NotFoundException(CategoryMessage.NOT_FOUND); - // } - - // this.em.assign(product, { category: category }); - // } - - // // assign other fields from DTO (excluding dailyStock handled below) - // this.em.assign(product, rest); - - // // Persist product and update/create related inventory atomically - // await this.em.transactional(async em => { - // await em.persistAndFlush(product); - - // if (typeof dailyStock !== 'undefined') { - // const inventoryRecord = await em.findOne(Inventory, { product: product }); - // if (inventoryRecord) { - // inventoryRecord.totalStock = dailyStock; - // } else { - // em.create(Inventory, { - // product: product, - // availableStock: dailyStock, - // totalStock: dailyStock, - // }); - // } - // } - - // await em.flush(); - // }); - - // // Re-load the product to ensure populated relations and stable instance - // const savedproduct = await this.productRepository.findOne({ id: product.id }, { populate: ['category', 'restaurant'] }); - - // // Invalidate cache for the restaurant if present (optional) - // // await this.invalidateRestaurantproductsCache(savedproduct?.restaurant?.slug); - - // return savedproduct ?? product; - // } - async remove(id: string): Promise { const product = await this.productRepository.findOne({ id }); if (!product) {