import { HttpException, HttpStatus, Injectable, UnauthorizedException, } from '@nestjs/common'; import { EntityNotFoundError, Repository } from 'typeorm'; import { Product } from './entities/product.entity'; import { InjectRepository } from '@nestjs/typeorm'; import { CreateProductDto } from './dto/product/create-product.dto'; import { ProductSubCategoriesService } from './product-sub-categories.service'; import { UpdateProductDto } from './dto/product/update-product.dto'; import { ProductHistoryPrice } from './entities/product-history-price.entity'; import { productType } from '../helper/enum-list'; import { UpdatePriceProductDto } from './dto/product/update-price-product.dto'; import { UsersService } from '../users/users.service'; import { SupplierService } from '../users/supplier/supplier.service'; import { type } from 'os'; export class ProductService { constructor( @InjectRepository(Product) private productRepository: Repository, @InjectRepository(ProductHistoryPrice) private productHistoryPrice: Repository, private productSubCategoriesService: ProductSubCategoriesService, private usersService: UsersService, private supplierService: SupplierService, ) {} async create(createProductDto: CreateProductDto) { const subCategories = await this.productSubCategoriesService.findOne( createProductDto.subCategoriesId, ); const result = await this.productRepository.insert({ name: createProductDto.name, code: createProductDto.code, status: createProductDto.status, sub_categories: subCategories, price: createProductDto.price, }); await this.productHistoryPrice.insert({ product: result.identifiers[0], type: productType.NORMAL, price: createProductDto.price, mark_up_price: createProductDto.markUpPrice, startDate: new Date(), endDate: null, }); return this.productRepository.findOneOrFail(result.identifiers[0].id); } async findAll(page, supplier, categories, subCategories) { if (supplier == 'null' || !supplier) { supplier = (await this.supplierService.findByActive()).id; } const baseQuery = this.productRepository .createQueryBuilder('product') .leftJoin('product.sub_categories', 'sub_categories') .leftJoin('sub_categories.category', 'category') .where('product.supplier_id = :supplier_id', { supplier_id: supplier, }) .leftJoinAndMapOne( 'product.currentPrice', 'product.priceHistory', 'current_price', 'current_price.partner_id is null', ); if (subCategories != 'null' && subCategories) { baseQuery.where('product.sub_categories_id = :id', { id: subCategories, }); } if (categories != 'null' && categories) { baseQuery.where('sub_categories.category_id = :id', { id: categories, }); } const data = await baseQuery .skip(page * 10) .take(10) .getMany(); const totalData = await baseQuery.getCount(); return { data, count: totalData, }; } async findAllByCategories(page, subCategories, supplier) { const baseQuery = this.productRepository .createQueryBuilder('product') .leftJoin('product.sub_categories', 'sub_categories') .where( 'sub_categories.category_id = :id and product.supplier_id = :supplier_id', { id: subCategories, supplier_id: supplier, }, ) .leftJoinAndMapOne( 'product.currentPrice', 'product.priceHistory', 'current_price', 'current_price.partner_id is null', ); const data = await baseQuery .skip(page * 10) .take(10) .getMany(); const totalData = await baseQuery.getCount(); return { data, count: totalData, }; } async findAllBySubCategories(page, subCategories, supplier) { if (supplier != 'null' && !supplier) { supplier = (await this.supplierService.findByActive()).id; } const baseQuery = this.productRepository .createQueryBuilder('product') .leftJoin('product.sub_categories', 'sub_categories') .where('product.supplier_id = :supplier_id', { supplier_id: supplier, }) .leftJoinAndMapOne( 'product.currentPrice', 'product.priceHistory', 'current_price', 'current_price.partner_id is null', ); if (subCategories != 'null' && subCategories) { baseQuery.where('product.sub_categories_id = :id', { id: subCategories, }); } const data = await baseQuery .skip(page * 10) .take(10) .getMany(); const totalData = await baseQuery.getCount(); return { data, count: totalData, }; } async findAllForPartner( page: number, pageSize: number, categories: string, username: string, ) { const user = await this.usersService.findOneByUsername(username); const supplier = await this.supplierService.findByActive(); const baseQuery = this.productRepository .createQueryBuilder('product') .leftJoin('product.sub_categories', 'sub_categories') .where( 'sub_categories.category_id = :id and product.supplier_id = :supplier_id', { id: categories, supplier_id: supplier.id, }, ) .leftJoinAndMapOne( 'product.currentPrice', 'product.priceHistory', 'current_price', 'current_price.partner_id = :id_partner and current_price.end_date is NULL', ) .setParameter('id_partner', user.partner.id); const data = await baseQuery .skip(page * pageSize) .take(pageSize) .getMany(); const totalData = await baseQuery.getCount(); return { data, count: totalData, }; } async findOne(code: string) { try { return await this.productRepository.findOneOrFail({ relations: ['supplier'], where: { code: code, }, }); } catch (e) { if (e instanceof EntityNotFoundError) { throw new HttpException( { statusCode: HttpStatus.NOT_FOUND, error: 'Product not found', }, HttpStatus.NOT_FOUND, ); } else { throw e; } } } async update(id: string, updateProductDto: UpdateProductDto) { try { await this.productRepository.findOneOrFail(id); } catch (e) { if (e instanceof EntityNotFoundError) { throw new HttpException( { statusCode: HttpStatus.NOT_FOUND, error: 'Product not found', }, HttpStatus.NOT_FOUND, ); } else { throw e; } } const subCategories = await this.productSubCategoriesService.findOne( updateProductDto.subCategoriesId, ); const result = await this.productRepository.update(id, { name: updateProductDto.name, code: updateProductDto.code, status: updateProductDto.status, sub_categories: subCategories, }); return this.productRepository.findOneOrFail(id); } async updatePrice( code: string, updatePriceProductDto: UpdatePriceProductDto, ) { const product = await this.findOne(code); await this.productHistoryPrice.insert({ product: product, type: updatePriceProductDto.type, price: updatePriceProductDto.price, mark_up_price: updatePriceProductDto.markUpPrice, startDate: updatePriceProductDto.startDate, endDate: updatePriceProductDto.endDate, }); return true; } async remove(id: string) { try { await this.productRepository.findOneOrFail(id); } catch (e) { if (e instanceof EntityNotFoundError) { throw new HttpException( { statusCode: HttpStatus.NOT_FOUND, error: 'Product not found', }, HttpStatus.NOT_FOUND, ); } else { throw e; } } await this.productRepository.delete(id); } }