|
|
|
@ -1,74 +1,97 @@ |
|
|
|
|
import { Injectable } from "@nestjs/common"; |
|
|
|
|
import { InjectModel } from "@nestjs/sequelize"; |
|
|
|
|
import { Product } from "./entities/product.entity"; |
|
|
|
|
import { CreateProductDto } from "./dto/create-product.dto"; |
|
|
|
|
import { UpdateProductDto } from "./dto/update-product.dto"; |
|
|
|
|
import { Op } from "sequelize"; |
|
|
|
|
import { HttpException, HttpStatus } from "@nestjs/common"; |
|
|
|
|
|
|
|
|
|
@Injectable() |
|
|
|
|
export class ProductsService { |
|
|
|
|
constructor(@InjectModel(Product) private readonly productModel: typeof Product) {} |
|
|
|
|
|
|
|
|
|
async create(name: string, description: string, price: number): Promise<Product> { |
|
|
|
|
try { |
|
|
|
|
if (!name || !description || price <= 0) { |
|
|
|
|
throw new Error("Invalid input data"); |
|
|
|
|
} |
|
|
|
|
const product = await this.productModel.create({ name, description, price }); |
|
|
|
|
return product; |
|
|
|
|
} catch (error) { |
|
|
|
|
throw new Error("Error creating product"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
async findAll(search?: string, priceMin?: number, priceMax?: number): Promise<Product[]> { |
|
|
|
|
const where: any = {}; |
|
|
|
|
|
|
|
|
|
// create a new product
|
|
|
|
|
async create(createProductDto: CreateProductDto): Promise<Product> { |
|
|
|
|
try { |
|
|
|
|
if (search) { |
|
|
|
|
where.name = { |
|
|
|
|
[Op.iLike]: `%${search}%`, |
|
|
|
|
}; |
|
|
|
|
const existingProduct = await this.productModel.findOne({ |
|
|
|
|
where: { name: createProductDto.name }, |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
if (existingProduct) { |
|
|
|
|
throw new HttpException( |
|
|
|
|
'Product with this name already exists.', |
|
|
|
|
HttpStatus.BAD_REQUEST, |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (priceMin || priceMax) { |
|
|
|
|
where.price = {}; |
|
|
|
|
if (priceMin) where.price[Op.gte] = priceMin; |
|
|
|
|
if (priceMax) where.price[Op.lte] = priceMax; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const products = await this.productModel.findAll({ where }); |
|
|
|
|
|
|
|
|
|
if (!products || products.length === 0) { |
|
|
|
|
throw new HttpException("No products found matching the given criteria.", HttpStatus.NOT_FOUND); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return products; |
|
|
|
|
const product = await this.productModel.create(createProductDto); |
|
|
|
|
return product; |
|
|
|
|
} catch (error) { |
|
|
|
|
if (error instanceof HttpException) { |
|
|
|
|
throw error; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
throw new HttpException("An error occurred while retrieving products.", HttpStatus.INTERNAL_SERVER_ERROR); |
|
|
|
|
console.error(error); |
|
|
|
|
throw new HttpException( |
|
|
|
|
'An error occurred while creating the product.', |
|
|
|
|
HttpStatus.INTERNAL_SERVER_ERROR, |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// find a product by id
|
|
|
|
|
async findOne(id: string): Promise<Product> { |
|
|
|
|
try { |
|
|
|
|
const product = await this.productModel.findByPk(id); |
|
|
|
|
|
|
|
|
|
if (!product) { |
|
|
|
|
throw new HttpException("Product not found with the given id.", HttpStatus.NOT_FOUND); |
|
|
|
|
throw new HttpException( |
|
|
|
|
'Product not found with the given id.', |
|
|
|
|
HttpStatus.NOT_FOUND, |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return product; |
|
|
|
|
} catch (error) { |
|
|
|
|
if (error instanceof HttpException) { |
|
|
|
|
throw error; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
throw new HttpException("An error occurred while retrieving the product.", HttpStatus.INTERNAL_SERVER_ERROR); |
|
|
|
|
console.error(error); |
|
|
|
|
throw new HttpException( |
|
|
|
|
error.response, |
|
|
|
|
HttpStatus.INTERNAL_SERVER_ERROR, |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
async update(id: string, name?: string, description?: string, price?: number): Promise<Product> { |
|
|
|
|
|
|
|
|
|
// list of all product
|
|
|
|
|
async findAll( |
|
|
|
|
search?: string, |
|
|
|
|
priceMin?: number, |
|
|
|
|
priceMax?: number, |
|
|
|
|
): Promise<Product[]> { |
|
|
|
|
try { |
|
|
|
|
// ساخت شرطهای جستجو و فیلتر
|
|
|
|
|
const where: any = {}; |
|
|
|
|
if (search) { |
|
|
|
|
where.name = { [Op.like]: `%${search}%` }; // جستجوی نام محصول به صورت جزئی
|
|
|
|
|
} |
|
|
|
|
if (priceMin !== undefined) { |
|
|
|
|
where.price = { ...(where.price || {}), [Op.gte]: priceMin }; // فیلتر حداقل قیمت
|
|
|
|
|
} |
|
|
|
|
if (priceMax !== undefined) { |
|
|
|
|
where.price = { ...(where.price || {}), [Op.lte]: priceMax }; // فیلتر حداکثر قیمت
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const products = await this.productModel.findAll({ where }); |
|
|
|
|
|
|
|
|
|
if (!products || products.length === 0) { |
|
|
|
|
throw new HttpException('No products found.', HttpStatus.NOT_FOUND); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return products; |
|
|
|
|
} catch (error) { |
|
|
|
|
console.error(error); |
|
|
|
|
throw new HttpException( |
|
|
|
|
'An error occurred while retrieving products.', |
|
|
|
|
HttpStatus.INTERNAL_SERVER_ERROR, |
|
|
|
|
); |
|
|
|
|
}} |
|
|
|
|
// update a product info
|
|
|
|
|
async update(id: string, updateProductDto: UpdateProductDto): Promise<Product> { |
|
|
|
|
try { |
|
|
|
|
const product = await this.productModel.findByPk(id); |
|
|
|
|
|
|
|
|
@ -76,21 +99,26 @@ export class ProductsService { |
|
|
|
|
throw new HttpException("Product not found.", HttpStatus.NOT_FOUND); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const { name, description, price, imageUrl, tags, quantity, brand, color, category } = updateProductDto; |
|
|
|
|
if (name) product.name = name; |
|
|
|
|
if (description) product.description = description; |
|
|
|
|
if (price) product.price = price; |
|
|
|
|
if (imageUrl) product.imageUrl = imageUrl; |
|
|
|
|
if (tags) product.tags = tags; |
|
|
|
|
if (quantity) product.quantity = quantity; |
|
|
|
|
if (brand) product.brand = brand; |
|
|
|
|
if (color) product.color = color; |
|
|
|
|
if (category) product.category = category; |
|
|
|
|
|
|
|
|
|
await product.save(); |
|
|
|
|
|
|
|
|
|
return product; |
|
|
|
|
} catch (error) { |
|
|
|
|
if (error instanceof HttpException) { |
|
|
|
|
throw error; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
throw new HttpException("An error occurred while updating the product.", HttpStatus.INTERNAL_SERVER_ERROR); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// delete a product
|
|
|
|
|
async remove(id: string): Promise<{ message: string }> { |
|
|
|
|
try { |
|
|
|
|
const product = await this.productModel.findByPk(id); |
|
|
|
@ -103,10 +131,6 @@ export class ProductsService { |
|
|
|
|
|
|
|
|
|
return { message: "Product deleted successfully." }; |
|
|
|
|
} catch (error) { |
|
|
|
|
if (error instanceof HttpException) { |
|
|
|
|
throw error; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
throw new HttpException("An error occurred while deleting the product.", HttpStatus.INTERNAL_SERVER_ERROR); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|