ppob-backend/src/product/product.service.ts
2021-12-17 02:26:57 +07:00

298 lines
8.0 KiB
TypeScript

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<Product>,
@InjectRepository(ProductHistoryPrice)
private productHistoryPrice: Repository<ProductHistoryPrice>,
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.andWhere('product.sub_categories_id = :id', {
id: subCategories,
});
}
// if (categories != 'null' && categories) {
// baseQuery.andWhere('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);
}
}