import { inject, injectable } from "inversify"; import slugify from "slugify"; import { BrandRepository } from "./brand.repository"; import { BrandSearchQueryDTO } from "./DTO/brand-search.dto"; import { CreateBrandDTO, CreateGlobalBrand } from "./DTO/createBrand.dto"; import { FindBrandQueryDTO } from "./DTO/findBrandQuery.dto"; import { UpdateBrandDTO } from "./DTO/updateBrand.dto"; import { BrandMessage, CategoryMessage, CommonMessage } from "../../common/enums/message.enum"; import { StatusEnum } from "../../common/enums/status.enum"; import { BadRequestError } from "../../core/app/app.errors"; import { IOCTYPES } from "../../IOC/ioc.types"; import { CategoryRepository } from "../category/category.repository"; import { ICategory } from "../category/models/Abstraction/ICategory"; import { ProductDTO } from "../product/DTO/product.dto"; import { IProduct } from "../product/models/Abstraction/IProduct"; import { ProductRepository } from "../product/Repository/product"; @injectable() class BrandService { @inject(IOCTYPES.BrandRepository) brandRepo: BrandRepository; @inject(IOCTYPES.ProductRepository) productRepo: ProductRepository; @inject(IOCTYPES.CategoryRepository) categoryRepo: CategoryRepository; async createBrand(createDto: CreateBrandDTO) { createDto.title_en = slugify(createDto.title_en); const existBrand = await this.brandRepo.model.findOne({ title_en: createDto.title_en, category: createDto.category }); if (existBrand) throw new BadRequestError(BrandMessage.Exist); const newBrand = await this.brandRepo.model.create(createDto); return { message: BrandMessage.Created, newBrand, }; } //######################## async createGlobalBrand(createDto: CreateGlobalBrand) { createDto.title_en = slugify(createDto.title_en); const existBrand = await this.brandRepo.model.findOne({ title_en: createDto.title_en }); if (existBrand) throw new BadRequestError(BrandMessage.Exist); const newBrand = await this.brandRepo.model.create(createDto); return { message: BrandMessage.Created, newBrand, }; } //######################## async getAllS(queryDto: FindBrandQueryDTO) { let category: ICategory | null = null; if (queryDto.categoryId) { category = await this.categoryRepo.findById(queryDto.categoryId); if (!category) throw new BadRequestError(CategoryMessage.NotFound); } const { count, docs } = await this.brandRepo.getAllBrand(queryDto, category?.hierarchy); return { count, docs }; } async deleteById(id: string) { const deletedBrand = await this.brandRepo.model.findByIdAndUpdate(id, { deleted: true }, { new: true }); if (!deletedBrand) throw new BadRequestError(CommonMessage.NotValidId); return { message: CommonMessage.Deleted, deletedBrand, }; } async updateById(id: string, updateDto: UpdateBrandDTO) { if (updateDto.title_en) { updateDto.title_en = slugify(updateDto.title_en); const existBrand = await this.brandRepo.model.findOne({ title_en: updateDto.title_en, category: updateDto.category, _id: { $ne: id }, }); if (existBrand) throw new BadRequestError(BrandMessage.Exist); } const updatedBrand = await this.brandRepo.model.findByIdAndUpdate(id, updateDto, { new: true }); if (!updatedBrand) throw new BadRequestError(CommonMessage.NotValidId); return { message: CommonMessage.Updated, updatedBrand, }; } async getProductsOfBrand(name: string, queries: BrandSearchQueryDTO, userId?: string) { const brand = await this.brandRepo.findWithName(name); if (!brand) throw new BadRequestError(BrandMessage.NotFound); const category = await this.categoryRepo.findById(brand.category.toString()); const priceRange = await this.productRepo.getPriceRangeByBrand(brand._id.toString()); const { docs, count } = await this.productRepo.getProductsWithBrand(brand._id.toString(), queries, userId); const products = docs.map((doc: IProduct) => ProductDTO.transformProduct(doc)); return { brand, products, count, filters: { priceRange }, category }; } async approve(id: string) { const updatedBrand = await this.brandRepo.model.findByIdAndUpdate(id, { status: StatusEnum.Approved }, { new: true }); if (!updatedBrand) throw new BadRequestError(CommonMessage.NotValidId); return { message: CommonMessage.Updated, updatedBrand, }; } async getPendingBrandsCount() { return await this.brandRepo.getPendingBrandsCount(); } async getBrandDetail(id: number) { const brand = await this.brandRepo.model.findOne({ _id: id }); if (brand) throw new BadRequestError(BrandMessage.Exist); return { brand, }; } } export { BrandService };