import { BadGatewayException, Injectable, NotFoundException } from '@nestjs/common'; import { EntityManager } from '@mikro-orm/postgresql'; import { RequiredEntityData } from '@mikro-orm/core'; import { AttributeRepository } from '../repositories/attribute.repository'; import { CreateAttributeDto } from '../dto/create-attribute.dto'; import { Attribute } from '../entities/attribute.entity'; import { ProductRepository } from '../repositories/product.repository'; import { UpdateAttributeDto } from '../dto/update-attribute.dto'; @Injectable() export class AttributeService { constructor( private readonly attributeRepository: AttributeRepository, private readonly productRepository: ProductRepository, private readonly em: EntityManager, ) { } async create(productId: number, dto: CreateAttributeDto) { let parent: null | Attribute = null const product = await this.productRepository.findOne({ id: productId }) if (!product) { throw new BadGatewayException('Product not found') } if (dto.parentId) { parent = await this.attributeRepository.findOne({ id: dto.parentId }) if (!parent) { throw new BadGatewayException('Parent attribute not found') } } const data: RequiredEntityData = { product, name: dto.name, isRequired: dto.isRequired, order: dto.order, type: dto.type, parent }; const category = this.attributeRepository.create(data) await this.em.persistAndFlush(category) return category } async update(attributeId: number, dto: UpdateAttributeDto) { const attribute = await this.attributeRepository.findOne({ id: attributeId }) if (!attribute) { throw new NotFoundException('Attribute not found'); } if (dto.parentId) { const parent = await this.attributeRepository.findOne({ id: dto.parentId }) if (!parent) { throw new NotFoundException('parent attribute not found'); } this.attributeRepository.assign(attribute, { parent }) } this.attributeRepository.assign(attribute, dto) this.em.persistAndFlush(attribute) return attribute } findAll(productId: number) { return this.attributeRepository.find({ product: { id: productId } }); } async findById(attributeId: number): Promise { const attribute = await this.attributeRepository.findOne({ id: attributeId }, { populate: ['children', 'product'] }); if (!attribute) throw new NotFoundException('Attribute not found'); return attribute; } async remove(id: number): Promise { const attribute = await this.findById(id); if (!attribute) { throw new NotFoundException('attribute not found'); } if (attribute.children && attribute.children.length > 0) { throw new NotFoundException('attribute has children'); } attribute.deletedAt = new Date(); return await this.em.persistAndFlush(attribute); } }