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