diff --git a/public/temp/tmp-1-1738667597480 b/public/temp/tmp-1-1738667597480 new file mode 100644 index 0000000..d63e96b Binary files /dev/null and b/public/temp/tmp-1-1738667597480 differ diff --git a/public/temp/tmp-1-1738668038634 b/public/temp/tmp-1-1738668038634 new file mode 100644 index 0000000..3d2d6c3 Binary files /dev/null and b/public/temp/tmp-1-1738668038634 differ diff --git a/public/temp/tmp-1-1738668306693 b/public/temp/tmp-1-1738668306693 new file mode 100644 index 0000000..3d2d6c3 Binary files /dev/null and b/public/temp/tmp-1-1738668306693 differ diff --git a/public/temp/tmp-1-1738675087236 b/public/temp/tmp-1-1738675087236 new file mode 100644 index 0000000..3d2d6c3 Binary files /dev/null and b/public/temp/tmp-1-1738675087236 differ diff --git a/public/temp/tmp-1-1738728732726 b/public/temp/tmp-1-1738728732726 new file mode 100644 index 0000000..d63e96b Binary files /dev/null and b/public/temp/tmp-1-1738728732726 differ diff --git a/public/temp/tmp-2-1738675114739 b/public/temp/tmp-2-1738675114739 new file mode 100644 index 0000000..3d2d6c3 Binary files /dev/null and b/public/temp/tmp-2-1738675114739 differ diff --git a/public/temp/tmp-2-1738728760262 b/public/temp/tmp-2-1738728760262 new file mode 100644 index 0000000..3d2d6c3 Binary files /dev/null and b/public/temp/tmp-2-1738728760262 differ diff --git a/resources/Brands/BrandsController.js b/resources/Brands/BrandsController.js index f3fe3cb..6c4b5ae 100644 --- a/resources/Brands/BrandsController.js +++ b/resources/Brands/BrandsController.js @@ -1,36 +1,6 @@ import mongoose from "mongoose"; import { BrandModel } from "./BrandsModel.js"; - -// Add new Brand -export const addBrand = async (req, res) => { - const { brandName } = req.body; - - if (!req?.user) { - return res.status(400).json({ message: "Please login!" }); - } - - try { - if (!mongoose.Types.ObjectId.isValid(req.user._id)) { - return res.status(400).json({ message: "Please login again." }); - } - - if (!brandName) { - return res.status(400).json({ message: "Please provide a brand name" }); - } - - const brand = await BrandModel.create({ - brandName, - addedBy: req.user._id, - }); - - return res.status(201).json({ success: true, brand, message: "Brand added successfully" }); - } catch (error) { - res.status(500).json({ - success: false, - message: error.message || "Something went wrong", - }); - } -}; +import cloudinary from "../../Utils/cloudinary.js"; // Get all Brands export const getBrands = async (req, res) => { @@ -73,11 +43,155 @@ export const getBrands = async (req, res) => { }); } }; +// Add new Brand +// export const addBrand = async (req, res) => { +// const { brandName } = req.body; + +// if (!req?.user) { +// return res.status(400).json({ message: "Please login!" }); +// } + +// try { +// if (!mongoose.Types.ObjectId.isValid(req.user._id)) { +// return res.status(400).json({ message: "Please login again." }); +// } + +// if (!brandName) { +// return res.status(400).json({ message: "Please provide a brand name" }); +// } + +// const brand = await BrandModel.create({ +// brandName, +// addedBy: req.user._id, +// }); + +// return res.status(201).json({ success: true, brand, message: "Brand added successfully" }); +// } catch (error) { +// res.status(500).json({ +// success: false, +// message: error.message || "Something went wrong", +// }); +// } +// }; + +// // Update Brand +// export const updateBrand = async (req, res) => { +// const { _id } = req.params; +// const { brandName } = req.body; + +// if (!req?.user) { +// return res.status(400).json({ message: "Please login!" }); +// } + +// if (!mongoose.Types.ObjectId.isValid(_id)) { +// return res.status(404).json({ message: "Invalid brand ID" }); +// } + +// try { +// const updatedBrand = await BrandModel.findByIdAndUpdate( +// _id, +// { brandName }, +// { new: true, runValidators: true } +// ); + +// if (!updatedBrand) { +// return res.status(404).json({ message: "Brand not found" }); +// } + +// res.status(200).json({ success: true, updatedBrand, message: "Brand updated successfully" }); +// } catch (error) { +// res.status(500).json({ +// success: false, +// message: error.message || "Something went wrong", +// }); +// } +// }; + +// // Delete Brand +// export const deleteBrand = async (req, res) => { +// const { _id } = req.params; + +// if (!req?.user) { +// return res.status(400).json({ message: "Please login!" }); +// } + +// if (!mongoose.Types.ObjectId.isValid(_id)) { +// return res.status(404).json({ message: "Invalid brand ID" }); +// } + +// try { +// const deletedBrand = await BrandModel.findByIdAndDelete(_id); + +// if (!deletedBrand) { +// return res.status(404).json({ message: "Brand not found" }); +// } + +// res.status(200).json({ success: true, deletedBrand, message: "Brand deleted successfully" }); +// } catch (error) { +// res.status(500).json({ +// success: false, +// message: error.message || "Something went wrong", +// }); +// } +// }; + +export const addBrand = async (req, res) => { + const { brandName } = req.body; + const file = req.files?.image; // Assuming image is sent as a file + + if (!req?.user) { + return res.status(400).json({ message: "Please login!" }); + } + + try { + if (!mongoose.Types.ObjectId.isValid(req.user._id)) { + return res.status(400).json({ message: "Please login again." }); + } + + if (!brandName) { + return res.status(400).json({ message: "Please provide a brand name" }); + } + + let image = {}; + if (file) { + try { + const result = await cloudinary.v2.uploader.upload(file.tempFilePath, { + folder: "chemiNova/brand", + }); + image = { + public_id: result.public_id, + url: result.secure_url, + }; + } catch (uploadError) { + console.error("Error uploading image:", uploadError); + return res.status(500).json({ + message: "Failed to upload image", + error: uploadError.message, + }); + } + } + + const brand = await BrandModel.create({ + brandName, + image: image ? [image] : [], + addedBy: req.user._id, + }); + + return res + .status(201) + .json({ success: true, brand, message: "Brand added successfully" }); + } catch (error) { + res.status(500).json({ + success: false, + message: error.message || "Something went wrong", + }); + } +}; -// Update Brand export const updateBrand = async (req, res) => { const { _id } = req.params; const { brandName } = req.body; + const file = req.files?.image; if (!req?.user) { return res.status(400).json({ message: "Please login!" }); @@ -88,26 +202,45 @@ export const updateBrand = async (req, res) => { } try { - const updatedBrand = await BrandModel.findByIdAndUpdate( - _id, - { brandName }, - { new: true, runValidators: true } - ); - - if (!updatedBrand) { + const brand = await BrandModel.findById(_id); + if (!brand) { return res.status(404).json({ message: "Brand not found" }); } - res.status(200).json({ success: true, updatedBrand, message: "Brand updated successfully" }); + let image = brand.image; + if (file) { + if (image.length > 0) { + await cloudinary.v2.uploader.destroy(image[0].public_id); + } + const result = await cloudinary.v2.uploader.upload(file.tempFilePath, { + folder: "chemiNova/brand", + }); + image = [{ public_id: result.public_id, url: result.secure_url }]; + } + + const updatedBrand = await BrandModel.findByIdAndUpdate( + _id, + { brandName, image }, + { new: true, runValidators: true } + ); + + res + .status(200) + .json({ + success: true, + updatedBrand, + message: "Brand updated successfully", + }); } catch (error) { - res.status(500).json({ - success: false, - message: error.message || "Something went wrong", - }); + res + .status(500) + .json({ + success: false, + message: error.message || "Something went wrong", + }); } }; -// Delete Brand export const deleteBrand = async (req, res) => { const { _id } = req.params; @@ -120,17 +253,82 @@ export const deleteBrand = async (req, res) => { } try { - const deletedBrand = await BrandModel.findByIdAndDelete(_id); - - if (!deletedBrand) { + const brand = await BrandModel.findById(_id); + if (!brand) { return res.status(404).json({ message: "Brand not found" }); } - res.status(200).json({ success: true, deletedBrand, message: "Brand deleted successfully" }); + if (brand.image.length > 0) { + await cloudinary.v2.uploader.destroy(brand.image[0].public_id); + } + + await BrandModel.findByIdAndDelete(_id); + res + .status(200) + .json({ success: true, message: "Brand deleted successfully" }); } catch (error) { - res.status(500).json({ + res + .status(500) + .json({ + success: false, + message: error.message || "Something went wrong", + }); + } +}; + +export const deleteImageFromCloudinary = async (req, res) => { + const { public_id } = req.params; + + // Ensure public_id is not empty + if (!public_id) { + return res.status(400).json({ success: false, - message: error.message || "Something went wrong", + msg: "Public ID is required!", + }); + } + + const decodedPublicId = decodeURIComponent(public_id); + + try { + // Step 1: Delete image from Cloudinary + const response = await cloudinary.v2.uploader.destroy(decodedPublicId); + + if (response.result === "ok") { + // Step 2: Find the brand containing the image and update the database + const brand = await BrandModel.findOne({ + "image.public_id": decodedPublicId, + }); + + if (!brand) { + return res.status(404).json({ + success: false, + msg: "Brand not found with the given image!", + }); + } + + // Remove the image from the brand's image array + brand.image = brand.image.filter( + (img) => img.public_id !== decodedPublicId + ); + + // Step 3: Save the updated brand document + await brand.save(); + + return res.status(200).json({ + success: true, + msg: "Image Deleted Successfully and removed from database!", + }); + } else { + return res.status(400).json({ + success: false, + msg: "Image deletion failed in Cloudinary!", + }); + } + } catch (error) { + console.error("Error deleting image:", error); // Log error for debugging + return res.status(500).json({ + success: false, + msg: error.message || "Something went wrong!", }); } }; diff --git a/resources/Brands/BrandsModel.js b/resources/Brands/BrandsModel.js index c1343b7..f02fc57 100644 --- a/resources/Brands/BrandsModel.js +++ b/resources/Brands/BrandsModel.js @@ -6,6 +6,18 @@ const BrandSchema = new mongoose.Schema( type: String, required: [true, "Name of brand required"], }, + image: [ + { + public_id: { + type: String, + // required: true, + }, + url: { + type: String, + // required: true, + }, + }, + ], addedBy: { type: mongoose.Schema.ObjectId, ref: "User", diff --git a/resources/Brands/BrandsRoutes.js b/resources/Brands/BrandsRoutes.js index 6a0f869..580bfbb 100644 --- a/resources/Brands/BrandsRoutes.js +++ b/resources/Brands/BrandsRoutes.js @@ -3,6 +3,7 @@ import { isAuthenticatedUser, authorizeRoles } from "../../middlewares/auth.js"; import { addBrand, deleteBrand, + deleteImageFromCloudinary, getBrands, updateBrand, } from "./BrandsController.js"; @@ -23,4 +24,12 @@ router .route("/delete/:_id") .delete(isAuthenticatedUser, authorizeRoles("admin"), deleteBrand); +router + .route("/deleteImage/:public_id") + .delete( + isAuthenticatedUser, + authorizeRoles("admin"), + deleteImageFromCloudinary + ); + export default router; diff --git a/resources/Products/ProductController.js b/resources/Products/ProductController.js index df701e5..ad8badb 100644 --- a/resources/Products/ProductController.js +++ b/resources/Products/ProductController.js @@ -482,7 +482,7 @@ export const getAllProductAdmin = async (req, res) => { const products = await Product.find(filter) .populate({ path: "category addedBy brand", - select: "categoryName name brandName", + select: "categoryName name brandName image", }) .limit(PAGE_SIZE) .skip(skip) @@ -551,7 +551,7 @@ export const getAllProductUser = async (req, res) => { const products = await Product.find(filter) .populate({ path: "category addedBy brand", - select: "categoryName name brandName", + select: "categoryName name brandName image", }) .limit(PAGE_SIZE) .skip(PAGE_SIZE * page) @@ -611,7 +611,7 @@ export const getOneProduct = async (req, res) => { try { const data = await Product.findById(req.params.id).populate({ path: "category addedBy brand", - select: "categoryName name brandName", + select: "categoryName name brandName image", }); if (data) { return res.status(200).json({ diff --git a/resources/Stock/StockController.js b/resources/Stock/StockController.js index 851dc5f..e1f1fb7 100644 --- a/resources/Stock/StockController.js +++ b/resources/Stock/StockController.js @@ -470,6 +470,7 @@ export const getProductsAndStockByPD = async (req, res) => { $project: { category: { $arrayElemAt: ["$categoryDetails.categoryName", 0] }, brand: { $arrayElemAt: ["$brandDetails.brandName", 0] }, + brandImage: { $arrayElemAt: ["$brandDetails.image", 0] }, GST: 1, HSN_Code: 1, SKU: 1, @@ -580,6 +581,7 @@ export const getProductsAndStockByRD = async (req, res) => { $project: { category: { $arrayElemAt: ["$categoryDetails.categoryName", 0] }, brand: { $arrayElemAt: ["$brandDetails.brandName", 0] }, + brandImage: { $arrayElemAt: ["$brandDetails.image", 0] }, GST: 1, HSN_Code: 1, SKU: 1,