From b6445573925ddbdd4c9aa5aa023abf604ed1b4af Mon Sep 17 00:00:00 2001 From: Atallah Date: Sat, 4 Nov 2023 21:35:36 +0200 Subject: [PATCH] made relatedProducts service --- controllers/orderController.js | 6 ++-- controllers/productController.js | 6 ++-- services/productServices.js | 55 ++++++++++++++++++++++++++++---- 3 files changed, 56 insertions(+), 11 deletions(-) diff --git a/controllers/orderController.js b/controllers/orderController.js index f5cc9d1..529cb26 100644 --- a/controllers/orderController.js +++ b/controllers/orderController.js @@ -1,5 +1,5 @@ // imports -const { Cart, Order, OrderItem, Discount, Tax } = require('../models'); +const { Cart, Order, OrderItem, /*Discount,*/ Tax } = require('../models'); const { asyncWrapper } = require('../middleware'); const { createCustomError } = require('../utils/errors/custom-error'); const { @@ -72,8 +72,8 @@ const createOrder = asyncWrapper(async (req, res, next) => { // Call the function to update product stock in the cart await updateProductStockInCart(cartId); - const tax = await Tax.findByPk(taxId); - + const tax = await Tax.findByPk(taxId); + // updating the total price of order based on the taxes and delivery fees const totalPrice = Number(cart.totalPrice) + Number(tax.taxRate) + deliveryFee; // creating the order diff --git a/controllers/productController.js b/controllers/productController.js index c43238b..aa45b45 100644 --- a/controllers/productController.js +++ b/controllers/productController.js @@ -174,6 +174,8 @@ const getProduct = asyncWrapper(async (req, res, next) => { where: { productId: id }, }); + // Fetch related products + const relatedProducts = await ProductService.fetchRelatedProductsByProduct(id); // Send a response with product and associated ratingReviews return res.status(200).json({ success: true, @@ -181,6 +183,7 @@ const getProduct = asyncWrapper(async (req, res, next) => { data: { product: product, ratingReviews, + relatedProducts }, }); } else { @@ -406,8 +409,7 @@ const searchProducts = asyncWrapper(async (req, res, next) => { // Log the products matching the keyword, category, or brand, and send a response console.log( - `Products matching ${{ ...req.query }} have been called, products length= ${ - products.length + `Products matching ${{ ...req.query }} have been called, products length= ${products.length }` ); res.status(200).json({ diff --git a/services/productServices.js b/services/productServices.js index 3d58b24..a632999 100644 --- a/services/productServices.js +++ b/services/productServices.js @@ -1,6 +1,8 @@ const { Product, Category, Brand } = require('../models'); const { development } = require('../config/config'); const { Op } = require('sequelize'); +const sequelize = require('../utils/dataBaseConnection'); + /** * Retrieve a product's rating summary, including the total rating and rating count. @@ -13,11 +15,11 @@ const getProductRatingSummary = async (product) => { const rating = reviews ? (reviews - .map((review) => review.rating) - .reduce((acc, current) => acc + current, 0) / - reviews.length / - 5) * - 5 + .map((review) => review.rating) + .reduce((acc, current) => acc + current, 0) / + reviews.length / + 5) * + 5 : 0; const totalRating = Math.round(rating * 10) / 10; const ratingCount = reviews ? reviews.length : 0; @@ -122,7 +124,13 @@ const fetchProducts = async (options, page, itemsPerPage) => { * @returns {Promise} A structured response object containing product details and rating summary. */ const fetchProductById = async (id, options) => { - const product = await Product.findByPk(id, options); + const product = await Product.findByPk(id, { + ...options, + include: [ + { model: Category, attributes: ['name'] }, + { model: Brand, attributes: ['name'] }, + ], + }); return await generateProductResponse(product); }; @@ -140,9 +148,44 @@ const fetchHandPickedProducts = async (options) => { return handPickedProducts; }; + +/** + * Fetch related products by the category of a given product. + * + * @param {number} productId - The ID of the product to fetch related products for. + * @returns {Promise} An object containing related products. + */ +const fetchRelatedProductsByProduct = async (productId, limit = 3) => { + const product = await Product.findByPk(productId); + + if (!product) { + // Handle the case where the product is not found + throw new Error(`No product with id: ${productId} is found`); + } + + const category = await Category.findByPk(product.categoryId); + + if (!category) { + // Handle the case where the category is not found + throw new Error(`No category with id: ${product.categoryId} is found`); + } + + const relatedProducts = await Product.findAll({ + where: { + id: { [Op.not]: productId }, + categoryId: category.id + }, + order: sequelize.literal('RAND()'), // Order randomly + limit + }); + + return relatedProducts; +}; + module.exports = { fetchProducts, fetchProductsWithCount, fetchProductById, fetchHandPickedProducts, + fetchRelatedProductsByProduct };