diff --git a/resources/Products/ProductController.js b/resources/Products/ProductController.js index 5553fb2..ed85c84 100644 --- a/resources/Products/ProductController.js +++ b/resources/Products/ProductController.js @@ -4,59 +4,123 @@ import { v4 as uuidv4 } from "uuid"; import { CategoryModel } from "../Category/CategoryModel.js"; export const createProduct = async (req, res) => { try { - if (!req.files) { - return res.status(400).json({ - msg: " PLease Provide Product image", - }); - } - let images = []; - let Allfiles = req.files.image; - if (typeof Allfiles.tempFilePath === "string") { - let filepath = Allfiles.tempFilePath; + let findProduct = ""; + let product = { _id: "" }; - images.push(filepath); + 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 { - Allfiles.map((item) => { - images.push(item.tempFilePath); - }); + 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); } - - const imagesLinks = []; - for (let i = 0; i < images.length; i++) { - const result = await cloudinary.v2.uploader.upload(images[i], { - folder: "smellica/product", - }); - - imagesLinks.push({ - public_id: result.public_id, - url: result.secure_url, - }); - } - - req.body.image = imagesLinks; - req.body.addedBy = req.user._id; - const newUniquid = uuidv4(); - req.body.uniqueId = newUniquid.replace(/-/g, "").substring(0, 10); - - const data = await Product.create({ ...req.body }); res.status(201).json({ - success: true, - data, - msg: " create Product Successfully!!", + message: "Product details added successfully!", + product_id: product._id, }); } catch (error) { res.status(500).json({ - success: false, - msg: error.message, + 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) { + // req.body.addedBy = req.user.id; + // const image_file = req.files.image; + // console.log("req.files", 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: "smellica/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 getAllProduct = async (req, res) => { try { const product = await Product.find() .populate({ - path: "category gst addedBy", + path: "category addedBy variants.gst_Id", select: "name categoryName tax", }) .sort({ @@ -75,6 +139,28 @@ export const getAllProduct = async (req, res) => { }); } }; +//get One Product +export const getOneProduct = async (req, res) => { + try { + const data = await Product.findById(req.params.id).populate({ + path: "category addedBy 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 { @@ -121,27 +207,6 @@ export const getAllProductsDevicesFirst = async (req, res) => { }); } }; -//get One Product -export const getOneProduct = async (req, res) => { - try { - const product = await Product.findById(req.params.id).populate({ - path: "category gst addedBy", - select: "name categoryName tax", - }); - if (product) { - return res.status(200).json({ - success: true, - product, - }); - } - } catch (error) { - // console.log(error) - res.status(500).json({ - success: false, - msg: error.message ? error.message : "Something went wrong!", - }); - } -}; // 3.update Product // export const updateProduct = async (req, res) => { @@ -236,88 +301,88 @@ export const getOneProduct = async (req, res) => { // }); // } // }; -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, - })); +// 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; +// let updatedImages = AllImages; - if (req.files && req.files.newImages) { - const newUploadImages = Array.isArray(req.files.newImages) - ? req.files.newImages - : [req.files.newImages]; +// if (req.files && req.files.newImages) { +// const newUploadImages = Array.isArray(req.files.newImages) +// ? req.files.newImages +// : [req.files.newImages]; - const imagesLinks = []; +// const imagesLinks = []; - for (let i = 0; i < newUploadImages.length; i++) { - const result = await cloudinary.v2.uploader.upload( - newUploadImages[i].tempFilePath, - { - folder: "smellica/product", - } - ); +// for (let i = 0; i < newUploadImages.length; i++) { +// const result = await cloudinary.v2.uploader.upload( +// newUploadImages[i].tempFilePath, +// { +// folder: "smellica/product", +// } +// ); - imagesLinks.push({ - public_id: result.public_id, - url: result.secure_url, - }); - } +// imagesLinks.push({ +// public_id: result.public_id, +// url: result.secure_url, +// }); +// } - // Combine the existing images and the newly uploaded images - updatedImages = [...AllImages, ...imagesLinks]; - } +// // 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 } - ); +// // 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" }); - } +// 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!", - }); - } -}; +// 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; @@ -360,8 +425,10 @@ export const deleteProduct = async (req, res) => { }); } // Deleting Images From Cloudinary - for (let i = 0; i < getProduct.image.length; i++) { - await cloudinary.v2.uploader.destroy(getProduct.image[i].public_id); + if (getProduct?.image?.length > 0) { + for (let i = 0; i < getProduct.image.length; i++) { + await cloudinary.v2.uploader.destroy(getProduct.image[i].public_id); + } } //-------------------------// diff --git a/resources/Products/ProductModel.js b/resources/Products/ProductModel.js index 8d048b8..ce6c44f 100644 --- a/resources/Products/ProductModel.js +++ b/resources/Products/ProductModel.js @@ -9,45 +9,58 @@ const productSchema = new Schema( required: [true, "Please Enter product Name"], trim: true, }, - uniqueId: { - type: String, - required: true, - }, + // uniqueId: { + // type: String, + // required: true, + // }, description: { type: String, maxLength: [400, "description cannot exceed 100 characters"], required: [true, "Please Enter product Description"], }, - price: { - type: Number, - required: [true, "Please Enter product Price"], - maxLength: [8, "Price can not exceed 8 characters"], - }, + category: { type: Schema.Types.ObjectId, ref: "CategoryModel", }, - gst: { - type: Schema.Types.ObjectId, - ref: "Tax", - }, - total_amount: { - type: Number, - required: true, - }, - gst_amount: { - type: Number, - required: true, + // gst: { + // type: Schema.Types.ObjectId, + // ref: "Tax", + // }, + // total_amount: { + // type: Number, + // required: true, + // }, + // gst_amount: { + // type: Number, + // required: true, + // }, + special_instructions: { + type: String, }, + variants: [ + { + variant_Name: { type: String, default: "" }, + weight: { type: Number, default: 0 }, + volume: { type: Number, default: 0 }, + price: { type: String, default: "" }, + // gst_Name: { type: String, default: "" }, + // gst_Rate: { type: String, default: "" }, + gst_Id: { + type: mongoose.Schema.ObjectId, + ref: "Tax", + }, + }, + ], image: [ { public_id: { type: String, - required: true, + // required: true, }, url: { type: String, - required: true, + // required: true, }, }, ], @@ -58,6 +71,7 @@ const productSchema = new Schema( }, addedBy: { type: Schema.Types.ObjectId, + required: true, ref: "User", }, }, diff --git a/resources/Products/ProductRoute.js b/resources/Products/ProductRoute.js index 2159d1f..32cdca7 100644 --- a/resources/Products/ProductRoute.js +++ b/resources/Products/ProductRoute.js @@ -15,7 +15,9 @@ router .route("/product/create/") .post(isAuthenticatedUser, authorizeRoles("admin"), createProduct); router.route("/product/getAll/").get(getAllProduct); -router.route("/product/getAllProductsDevicesFrist/").get(getAllProductsDevicesFirst); +router + .route("/product/getAllProductsDevicesFrist/") + .get(getAllProductsDevicesFirst); router.route("/product/getOne/:id").get(getOneProduct); router .route("/product/update/:id")