Files
shop-api/src/modules/brand/brand.service.ts
T
2025-09-28 11:20:03 +03:30

132 lines
4.7 KiB
TypeScript

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 };