import { Product } from "./ProductModel.js"; import cloudinary from "../../Utils/cloudinary.js"; import { v4 as uuidv4 } from "uuid"; import { CategoryModel } from "../Category/CategoryModel.js"; export const createProduct = async (req, res) => { try { let findProduct = ""; let product = { _id: "" }; if (req.body?.product_id) { findProduct = await Product.findById(req.body.product_id); } const name = req.body?.name; if (!findProduct) { const data = await Product.findOne({ name: { $regex: new RegExp(`^${name}$`, "ig") }, }).exec(); if (data) return res .status(400) .json({ message: "Product name already exists!" }); req.body.addedBy = req.user._id; product = await Product.create(req.body); } else { const data = await Product.findOne({ _id: { $ne: findProduct._id }, name: { $regex: new RegExp(`^${name}$`, "ig") }, }).exec(); if (data) return res .status(400) .json({ message: "Product name already exists!" }); product = await Product.findByIdAndUpdate(req.body.product_id, req.body); } res.status(201).json({ message: "Product details added successfully!", product_id: product._id, }); } catch (error) { res.status(500).json({ message: error.message ? error.message : "Something went wrong!", }); } }; /////////////////////////////////////////////////////////////////////////////////////// export const updateProduct = async (req, res) => { try { if (req.body?.variants) { const vars = req.body.variants || []; // Default to an empty array if req.body.variants is undefined or null const product = await Product.findByIdAndUpdate( req.params.id, { variants: vars }, { new: true } // Return the updated document ); // Send a JSON response back to the client return res.status(201).json({ message: "Product variant saved successfully", variants: product?.variants || [], // Return the updated variants or an empty array if product is undefined }); } if (req.files) { const getProduct = await Product.findById(req.params.id); if (getProduct.image?.length > 0) { // Deleting Images From Cloudinary for (let i = 0; i < getProduct.image.length; i++) { await cloudinary.v2.uploader.destroy(getProduct.image[i].public_id); } } let images = []; let Allfiles = req.files.image; if (typeof Allfiles.tempFilePath === "string") { let filepath = Allfiles.tempFilePath; images.push(filepath); } else { Allfiles.map((item) => { images.push(item.tempFilePath); }); } const imagesLinks = []; for (let i = 0; i < images.length; i++) { const result = await cloudinary.v2.uploader.upload(images[i], { folder: "chemiNova/product", }); imagesLinks.push({ public_id: result.public_id, url: result.secure_url, }); } let product = await Product.findByIdAndUpdate( req.params.id, { image: imagesLinks }, { new: true } // Return the updated document ); return res.status(201).json({ message: "Product image saved successfully", images: product?.image || [], // Return the updated variants or an empty array if product is undefined }); } } catch (error) { console.log(error); res.status(500).json({ message: error.message ? error.message : "Something went wrong!", }); } }; //////////////////////////////////////////////////////////////////////////// //get All Product export const getAllProductAdmin = async (req, res) => { try { const PAGE_SIZE = parseInt(req.query?.show || "10"); const page = parseInt(req.query?.page - 1 || "0"); let obj = {}; if (req.query?.name) obj.name = { $regex: new RegExp(req.query.name), $options: "i", }; if (req.query?.category) obj.category = req.query.category; if (req.query?.FeatureProduct) obj.featured_Product = req.query.FeatureProduct; const total = await Product.countDocuments(obj); const product = await Product.find(obj) .populate({ path: "category addedBy master_GST variants.gst_Id", select: "name categoryName tax", }) .limit(PAGE_SIZE) .skip(PAGE_SIZE * page) // .sort("name") .sort({ featured_Product: -1, createdAt: -1, }) .exec(); if (product) { return res.status(200).json({ success: true, total_data: total, total_pages: Math.ceil(total / PAGE_SIZE), product, }); } } catch (error) { res.status(500).json({ success: false, msg: error.message ? error.message : "Something went wrong!", }); } }; //get All Product User(website) export const getAllProductUser = async (req, res) => { try { const PAGE_SIZE = parseInt(req.query?.show || "10"); const page = parseInt(req.query?.page - 1 || "0"); let obj = {}; if (req.query?.name) obj.name = { $regex: new RegExp(req.query.name), $options: "i", }; if (req.query?.category) obj.category = req.query.category; if (req.query?.FeatureProduct) obj.featured_Product = req.query.FeatureProduct; obj.product_Status = "Active"; const total = await Product.countDocuments(obj); const product = await Product.find(obj) .populate({ path: "category addedBy master_GST variants.gst_Id", select: "name categoryName tax", }) .limit(PAGE_SIZE) .skip(PAGE_SIZE * page) // .sort("name") .sort({ featured_Product: -1, createdAt: -1, }) .exec(); if (product) { return res.status(200).json({ success: true, total_data: total, total_pages: Math.ceil(total / PAGE_SIZE), product, }); } } catch (error) { res.status(500).json({ success: false, msg: error.message ? error.message : "Something went wrong!", }); } }; //Change Product status export const ChangeProductStatus = async (req, res) => { try { const data = await Product.findById(req.params.id); if (data) { if (data?.product_Status === "Active") { let product = await Product.findByIdAndUpdate( req.params.id, { product_Status: "inActive" }, { new: true } // Return the updated document ); return res.status(200).json({ success: true, msg: "Changed status inActive", }); } else { let product = await Product.findByIdAndUpdate( req.params.id, { product_Status: "Active" }, { new: true } // Return the updated document ); return res.status(200).json({ success: true, msg: "Changed status Active", }); } } } catch (error) { res.status(500).json({ success: false, msg: error.message ? error.message : "Something went wrong!", }); } }; //Change Product status export const ChangeFeatueProductStatus = async (req, res) => { try { const data = await Product.findById(req.params.id); if (data) { if (data?.featured_Product === false) { const totalFeatueProduct = await Product.countDocuments({ featured_Product: true, }); if (totalFeatueProduct > 2) { return res.status(400).json({ success: false, msg: "Maximum 3 Featue Product can be..", }); } let product = await Product.findByIdAndUpdate( req.params.id, { featured_Product: true }, { new: true } // Return the updated document ); return res.status(200).json({ success: true, msg: "Changed status as Featue Product", }); } else { let product = await Product.findByIdAndUpdate( req.params.id, { featured_Product: false }, { new: true } // Return the updated document ); return res.status(200).json({ success: true, msg: "Changed status as not Featue Product", }); } } } catch (error) { res.status(500).json({ success: false, msg: error.message ? error.message : "Something went wrong!", }); } }; //get One Product export const getOneProduct = async (req, res) => { try { const data = await Product.findById(req.params.id).populate({ path: "category addedBy master_GST variants.gst_Id", select: "name categoryName tax", }); if (data) { return res.status(200).json({ success: true, data, }); } } catch (error) { // console.log(error) res.status(500).json({ success: false, msg: error.message ? error.message : "Something went wrong!", }); } }; // get all product with device products first export const getAllProductsDevicesFirst = async (req, res) => { try { // we want products with category name Device to be displayed first, so i have first found the products with category name Devices then made another request to find all products and filtered products with category devices , then merged both arrays so we get devices first then all other categories const categoryName = "Devices"; // Find the category object by name first const category = await CategoryModel.findOne({ categoryName }); if (!category) { throw new Error("Category not found"); } // products with device category const deviceProducts = await Product.find({ category: category._id, }).populate("category"); // all products const allProducts = await Product.find() .populate({ path: "category gst addedBy", select: "name categoryName tax", }) .sort({ createdAt: -1, }); // filtering out products with device category const filteredProducts = allProducts.filter((ele) => { return ele.category?.categoryName !== categoryName; }); // merging both deviceProcuts and filtered products const product = deviceProducts.concat(filteredProducts); if (product) { return res.status(200).json({ success: true, product, }); } } catch (error) { res.status(500).json({ success: false, msg: error.message ? error.message : "Something went wrong!", }); } }; // 3.update Product // export const updateProduct = async (req, res) => { // const { // name, // description, // price, // category, // image, // gst_amount, // gst, // total_amount, // } = req.body; // console.log(gst_amount, gst, total_amount); // try { // // Prepare an array for the images // const jsonArray = JSON.parse(image); // const AllImages = jsonArray.map(({ public_id, url }) => ({ // public_id, // url, // })); // if (req.files && req.files.newImages) { // const newuploadImages = Array.isArray(req.files.newImages) // ? req.files.newImages // : [req.files.newImages]; // const imagesLinks = []; // for (let i = 0; i < newuploadImages.length; i++) { // const result = await cloudinary.v2.uploader.upload( // newuploadImages[i].tempFilePath, // { // folder: "chemiNova/product", // } // ); // imagesLinks.push({ // public_id: result.public_id, // url: result.secure_url, // }); // } // // Combine the existing images and the newly uploaded images // const updatedImages = [...AllImages, ...imagesLinks]; // // Perform the product update // const ModifyProduct = await Product.findOneAndUpdate( // { _id: req.params.id }, // { // $set: { // name, // description, // price, // category, // image: updatedImages, // gst, // gst_amount, // total_amount, // }, // }, // { new: true } // ); // return res.status(200).json({ // success: true, // ModifyProduct, // }); // } else { // const ModifyProduct = await Product.findOneAndUpdate( // { _id: req.params.id }, // { // $set: { // name, // description, // price, // category, // image: AllImages, // }, // }, // { new: true } // ); // return res.status(200).json({ // success: true, // ModifyProduct, // }); // } // } catch (error) { // res.status(500).json({ // success: false, // msg: error.message ? error.message : "Something went wrong!", // }); // } // }; // export const updateProduct = async (req, res) => { // const { // name, // description, // price, // category, // image, // gst_amount, // product_Status, // gst, // total_amount, // } = req.body; // try { // // Prepare an array for the images // const jsonArray = JSON.parse(image); // const AllImages = jsonArray.map(({ public_id, url }) => ({ // public_id, // url, // })); // let updatedImages = AllImages; // if (req.files && req.files.newImages) { // const newUploadImages = Array.isArray(req.files.newImages) // ? req.files.newImages // : [req.files.newImages]; // const imagesLinks = []; // for (let i = 0; i < newUploadImages.length; i++) { // const result = await cloudinary.v2.uploader.upload( // newUploadImages[i].tempFilePath, // { // folder: "chemiNova/product", // } // ); // imagesLinks.push({ // public_id: result.public_id, // url: result.secure_url, // }); // } // // Combine the existing images and the newly uploaded images // updatedImages = [...AllImages, ...imagesLinks]; // } // // Perform the product update // const updatedProduct = await Product.findOneAndUpdate( // { _id: req.params.id }, // { // $set: { // name, // description, // product_Status, // price, // category, // image: updatedImages, // gst, // gst_amount, // total_amount, // }, // }, // { new: true } // ); // if (!updatedProduct) { // return res.status(404).json({ success: false, msg: "Product not found" }); // } // return res.status(200).json({ // success: true, // updatedProduct, // }); // } catch (error) { // console.error("Error updating product:", error); // res.status(500).json({ // success: false, // msg: error.message ? error.message : "Something went wrong!", // }); // } // }; export const deleteImageFromCloudinary = async (req, res) => { const { public_id } = req.params; try { if (!public_id) { return res.status(400).json({ success: false, msg: "Please Provide Product ID!", }); } const response = await cloudinary.v2.uploader.destroy(public_id); if (response) { res.status(200).json({ success: true, msg: "Product Deleted Successfully!!", }); } } catch (error) { res.status(500).json({ success: false, msg: error.message ? error.message : "Something went wrong!", }); } }; //delete one Product export const deleteProduct = async (req, res) => { try { if (!req.params.id) { return res.status(400).json({ success: false, message: "Please Provide Product ID!", }); } const getProduct = await Product.findById(req.params.id); if (!getProduct) { return res.status(404).json({ success: false, message: "Product not Found!", }); } // Deleting Images From Cloudinary if (getProduct?.image?.length > 0) { for (let i = 0; i < getProduct.image.length; i++) { await cloudinary.v2.uploader.destroy(getProduct.image[i].public_id); } } //-------------------------// const product = await Product.findByIdAndDelete(req.params.id); if (!product) { return res.status(404).json({ message: "Product Not Found" }); } await product.remove(); res.status(200).json({ success: true, message: "Product Deleted Successfully!!", }); } catch (error) { res.status(500).json({ success: false, msg: error.message ? error.message : "Something went wrong!", }); } }; export const getProductsByCategory = async (req, res) => { const { categoryName } = req.params; // Assuming category name is in the route // console.log(categoryName); try { // Find the category object by name first const category = await CategoryModel.findOne({ categoryName }); if (!category) { throw new Error("Category not found"); } const products = await Product.find({ category: category._id }).populate( "category" ); // console.log(products); if (products && products.length > 0) { return res.status(200).json({ success: true, products, }); } else { return res.status(404).json({ success: false, msg: "No products found for this category", }); } } catch (error) { res.status(500).json({ success: false, msg: error.message ? error.message : "Something went wrong!", }); } };