category and product updated and brand created
This commit is contained in:
parent
b8e525e774
commit
69dc2cb1b4
3
app.js
3
app.js
@ -151,6 +151,7 @@ import SalesCoOrdinatorRoute from "./resources/SalesCoOrdinators/SalesCoOrdinato
|
|||||||
import TerritoryManagerRoute from "./resources/TerritoryManagers/TerritoryManagerRoute.js";
|
import TerritoryManagerRoute from "./resources/TerritoryManagers/TerritoryManagerRoute.js";
|
||||||
// category Route
|
// category Route
|
||||||
import categoryRoute from "./resources/Category/categoryRoutes.js";
|
import categoryRoute from "./resources/Category/categoryRoutes.js";
|
||||||
|
import brandroute from "./resources/Brands/BrandsRoutes.js";
|
||||||
import RegistrationImageRoute from "./resources/RegistrationImage/RegistrationImageRoute.js";
|
import RegistrationImageRoute from "./resources/RegistrationImage/RegistrationImageRoute.js";
|
||||||
import loginImageRoute from "./resources/LoginImage/LoginImageRoute.js";
|
import loginImageRoute from "./resources/LoginImage/LoginImageRoute.js";
|
||||||
import shopImageRoute from "./resources/ShopPageImage/ShopPageImageRoute.js";
|
import shopImageRoute from "./resources/ShopPageImage/ShopPageImageRoute.js";
|
||||||
@ -199,6 +200,8 @@ app.use("/api", ProductRouter);
|
|||||||
|
|
||||||
// Category
|
// Category
|
||||||
app.use("/api/category", categoryRoute);
|
app.use("/api/category", categoryRoute);
|
||||||
|
//Brand
|
||||||
|
app.use("/api/brand", brandroute);
|
||||||
// registration image
|
// registration image
|
||||||
app.use("/api/registerImage", RegistrationImageRoute);
|
app.use("/api/registerImage", RegistrationImageRoute);
|
||||||
app.use("/api/loginImage", loginImageRoute);
|
app.use("/api/loginImage", loginImageRoute);
|
||||||
|
BIN
public/temp/tmp-1-1724319327212
Normal file
BIN
public/temp/tmp-1-1724319327212
Normal file
Binary file not shown.
111
resources/Brands/BrandsController.js
Normal file
111
resources/Brands/BrandsController.js
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
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",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get all Brands
|
||||||
|
export const getBrands = async (req, res) => {
|
||||||
|
try {
|
||||||
|
const brands = await BrandModel.find().sort({ createdAt: -1 });
|
||||||
|
if (!brands.length) {
|
||||||
|
return res.status(404).json({ message: "No brands found" });
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(200).json({ success: true, brands });
|
||||||
|
} 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",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
18
resources/Brands/BrandsModel.js
Normal file
18
resources/Brands/BrandsModel.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import mongoose from "mongoose";
|
||||||
|
|
||||||
|
const BrandSchema = new mongoose.Schema(
|
||||||
|
{
|
||||||
|
brandName: {
|
||||||
|
type: String,
|
||||||
|
required: [true, "Name of brand required"],
|
||||||
|
},
|
||||||
|
addedBy: {
|
||||||
|
type: mongoose.Schema.ObjectId,
|
||||||
|
ref: "User",
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ timestamps: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
export const BrandModel = mongoose.model("BrandModel", BrandSchema);
|
26
resources/Brands/BrandsRoutes.js
Normal file
26
resources/Brands/BrandsRoutes.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import express from "express";
|
||||||
|
import { isAuthenticatedUser, authorizeRoles } from "../../middlewares/auth.js";
|
||||||
|
import {
|
||||||
|
addBrand,
|
||||||
|
deleteBrand,
|
||||||
|
getBrands,
|
||||||
|
updateBrand,
|
||||||
|
} from "./BrandsController.js";
|
||||||
|
|
||||||
|
const router = express.Router();
|
||||||
|
|
||||||
|
router
|
||||||
|
.route("/add")
|
||||||
|
.post(isAuthenticatedUser, authorizeRoles("admin"), addBrand);
|
||||||
|
|
||||||
|
router.route("/getBrands").get(getBrands);
|
||||||
|
|
||||||
|
router
|
||||||
|
.route("/update/:_id")
|
||||||
|
.patch(isAuthenticatedUser, authorizeRoles("admin"), updateBrand);
|
||||||
|
|
||||||
|
router
|
||||||
|
.route("/delete/:_id")
|
||||||
|
.delete(isAuthenticatedUser, authorizeRoles("admin"), deleteBrand);
|
||||||
|
|
||||||
|
export default router;
|
@ -6,7 +6,6 @@ const CategorySchema = new mongoose.Schema(
|
|||||||
type: String,
|
type: String,
|
||||||
required: [true, "Name of category required "],
|
required: [true, "Name of category required "],
|
||||||
},
|
},
|
||||||
categoryImage: {},
|
|
||||||
addedBy: {
|
addedBy: {
|
||||||
type: mongoose.Schema.ObjectId,
|
type: mongoose.Schema.ObjectId,
|
||||||
ref: "User",
|
ref: "User",
|
||||||
|
@ -1,53 +1,43 @@
|
|||||||
import mongoose from "mongoose";
|
import mongoose from "mongoose";
|
||||||
import { CategoryModel } from "./CategoryModel.js";
|
import { CategoryModel } from "./CategoryModel.js";
|
||||||
import cloudinary from "../../Utils/cloudinary.js";
|
|
||||||
|
|
||||||
// Add new Category
|
// Add new Category
|
||||||
export const addCategory = async (req, res) => {
|
export const addCategory = async (req, res) => {
|
||||||
const { categoryName } = req.body;
|
const { categoryName } = req.body;
|
||||||
const { categoryImage } = req.files;
|
|
||||||
// console.log(categoryName, categoryImage);
|
|
||||||
|
|
||||||
if (!req?.user) return res.status(400).json({ message: "please login !" });
|
if (!req?.user) {
|
||||||
|
return res.status(400).json({ message: "Please login!" });
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!mongoose.Types.ObjectId.isValid(req.user._id)) {
|
if (!mongoose.Types.ObjectId.isValid(req.user._id)) {
|
||||||
return res.status(400).json({ message: "please login again " });
|
return res.status(400).json({ message: "Please login again." });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!categoryName) {
|
||||||
|
return res.status(400).json({ message: "Please provide a category name" });
|
||||||
}
|
}
|
||||||
const result = await cloudinary.v2.uploader.upload(
|
|
||||||
categoryImage.tempFilePath,
|
|
||||||
{
|
|
||||||
folder: "GetSygnal/category",
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
if (result) {
|
|
||||||
const category = await CategoryModel.create({
|
const category = await CategoryModel.create({
|
||||||
categoryName,
|
categoryName,
|
||||||
categoryImage: result,
|
|
||||||
addedBy: req.user._id,
|
addedBy: req.user._id,
|
||||||
});
|
});
|
||||||
if (category) {
|
|
||||||
return res
|
return res.status(201).json({ success: true, category, message: "Category added successfully" });
|
||||||
.status(201)
|
|
||||||
.json({ success: true, category, message: "category Added" });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
success: false,
|
success: false,
|
||||||
message: error.message ? error.message : "Something went Wrong",
|
message: error.message || "Something went wrong",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Get all Categories
|
||||||
export const getCategories = async (req, res) => {
|
export const getCategories = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
// if (!req?.user) return res.status(400).json({ message: "please login !" });
|
const categories = await CategoryModel.find().sort({ createdAt: -1 });
|
||||||
const categories = await CategoryModel.find().sort({
|
|
||||||
createdAt: -1,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!categories) {
|
if (!categories.length) {
|
||||||
return res.status(404).json({ message: "No categories found" });
|
return res.status(404).json({ message: "No categories found" });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,96 +45,68 @@ export const getCategories = async (req, res) => {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
success: false,
|
success: false,
|
||||||
message: error.message ? error.message : "Something went wrong",
|
message: error.message || "Something went wrong",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Update Category
|
||||||
export const updateCategory = async (req, res) => {
|
export const updateCategory = async (req, res) => {
|
||||||
try {
|
|
||||||
if (!req?.user) return res.status(400).json({ message: "please login !" });
|
|
||||||
const { _id } = req.params;
|
const { _id } = req.params;
|
||||||
const { categoryName } = req.body;
|
const { categoryName } = req.body;
|
||||||
const olderImage = req.body?.olderImage;
|
|
||||||
const categoryImag = req.files?.categoryImage;
|
if (!req?.user) {
|
||||||
|
return res.status(400).json({ message: "Please login!" });
|
||||||
|
}
|
||||||
|
|
||||||
if (!mongoose.Types.ObjectId.isValid(_id)) {
|
if (!mongoose.Types.ObjectId.isValid(_id)) {
|
||||||
return res.status(404).json({ error: "Can not find the document " });
|
return res.status(404).json({ message: "Invalid category ID" });
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the document with the id to delete the image from cloudinary
|
|
||||||
if (JSON.parse(olderImage).length == 0) {
|
|
||||||
const deletefromCloudinary = await CategoryModel.findOne({ _id: _id });
|
|
||||||
|
|
||||||
const deleteresponse = await cloudinary.v2.uploader.destroy(
|
|
||||||
deletefromCloudinary.categoryImage.public_id
|
|
||||||
);
|
|
||||||
if (deleteresponse) {
|
|
||||||
const result = await cloudinary.v2.uploader.upload(
|
|
||||||
categoryImag.tempFilePath,
|
|
||||||
{
|
|
||||||
folder: "GetSygnal/category",
|
|
||||||
}
|
|
||||||
);
|
|
||||||
const update = await CategoryModel.findOneAndUpdate(
|
|
||||||
{ _id: _id },
|
|
||||||
{ categoryName: categoryName, categoryImage: result }, // Provide the updated categoryName
|
|
||||||
{ new: true } // To return the updated document
|
|
||||||
);
|
|
||||||
if (!update) {
|
|
||||||
return res
|
|
||||||
.status(404)
|
|
||||||
.json({ message: "Can not update document, something went wrong" });
|
|
||||||
} else {
|
|
||||||
return res.status(200).json({ success: true, update });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const update = await CategoryModel.findOneAndUpdate(
|
|
||||||
{ _id: _id },
|
|
||||||
{ categoryName: categoryName, categoryImage: JSON.parse(olderImage) }, // Provide the updated categoryName
|
|
||||||
{ new: true } // To return the updated document
|
|
||||||
);
|
|
||||||
if (update) {
|
|
||||||
return res.status(200).json({ success: true, update });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
res.status(500).json({
|
|
||||||
success: false,
|
|
||||||
message: error.message ? error.message : "Something went wrong",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const deleteCategory = async (req, res) => {
|
|
||||||
try {
|
try {
|
||||||
if (!req?.user) return res.status(400).json({ message: "please login !" });
|
const updatedCategory = await CategoryModel.findByIdAndUpdate(
|
||||||
const { _id } = req.params;
|
_id,
|
||||||
if (!mongoose.Types.ObjectId.isValid(_id)) {
|
{ categoryName },
|
||||||
return res.status(404).json({ error: "Can not find the document " });
|
{ new: true, runValidators: true }
|
||||||
}
|
|
||||||
|
|
||||||
const deletefromCloudinary = await CategoryModel.findOne({ _id: _id });
|
|
||||||
|
|
||||||
const deleteresponse = await cloudinary.v2.uploader.destroy(
|
|
||||||
deletefromCloudinary.categoryImage.public_id
|
|
||||||
);
|
);
|
||||||
if (deleteresponse) {
|
|
||||||
const deleteCategory = await CategoryModel.findOneAndDelete({ _id: _id });
|
if (!updatedCategory) {
|
||||||
if (!deleteCategory) {
|
return res.status(404).json({ message: "Category not found" });
|
||||||
return res.status(404).json({
|
|
||||||
error: "Can not find the document with the provided id to delete ",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
res.status(200).json({ success: true, deleteCategory });
|
|
||||||
} else {
|
|
||||||
return res.status(404).json({ error: "can not delete the category " });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
res.status(200).json({ success: true, updatedCategory, message: "Category updated successfully" });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
success: false,
|
success: false,
|
||||||
message: error.message ? error.message : "Something went wrong",
|
message: error.message || "Something went wrong",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Delete Category
|
||||||
|
export const deleteCategory = 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 category ID" });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const deletedCategory = await CategoryModel.findByIdAndDelete(_id);
|
||||||
|
|
||||||
|
if (!deletedCategory) {
|
||||||
|
return res.status(404).json({ message: "Category not found" });
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(200).json({ success: true, deletedCategory, message: "Category deleted successfully" });
|
||||||
|
} catch (error) {
|
||||||
|
res.status(500).json({
|
||||||
|
success: false,
|
||||||
|
message: error.message || "Something went wrong",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -10,20 +10,20 @@ const router = express.Router();
|
|||||||
|
|
||||||
router
|
router
|
||||||
.route("/add")
|
.route("/add")
|
||||||
.post(isAuthenticatedUser, authorizeRoles("admin", "Employee"), addCategory);
|
.post(isAuthenticatedUser, authorizeRoles("admin"), addCategory);
|
||||||
router.route("/getCategories").get(getCategories);
|
router.route("/getCategories").get(getCategories);
|
||||||
router
|
router
|
||||||
.route("/update/:_id")
|
.route("/update/:_id")
|
||||||
.patch(
|
.patch(
|
||||||
isAuthenticatedUser,
|
isAuthenticatedUser,
|
||||||
authorizeRoles("admin", "Employee"),
|
authorizeRoles("admin"),
|
||||||
updateCategory
|
updateCategory
|
||||||
);
|
);
|
||||||
router
|
router
|
||||||
.route("/delete/:_id")
|
.route("/delete/:_id")
|
||||||
.delete(
|
.delete(
|
||||||
isAuthenticatedUser,
|
isAuthenticatedUser,
|
||||||
authorizeRoles("admin", "Employee"),
|
authorizeRoles("admin"),
|
||||||
deleteCategory
|
deleteCategory
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -79,8 +79,6 @@ export const getDistributors = async (req, res) => {
|
|||||||
export const getAllInventories = async (req, res) => {
|
export const getAllInventories = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { page = 1, show = 10, startDate, endDate, name } = req.query;
|
const { page = 1, show = 10, startDate, endDate, name } = req.query;
|
||||||
|
|
||||||
// Build query for date filtering
|
|
||||||
const query = {};
|
const query = {};
|
||||||
|
|
||||||
if (startDate && endDate) {
|
if (startDate && endDate) {
|
||||||
@ -98,18 +96,17 @@ export const getAllInventories = async (req, res) => {
|
|||||||
$lte: new Date(end).setDate(end.getDate() + 1),
|
$lte: new Date(end).setDate(end.getDate() + 1),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} else if (startDate) {
|
} else if (startDate && endDate==='') {
|
||||||
query.createdAt = {
|
query.createdAt = {
|
||||||
$gte: new Date(startDate),
|
$gte: new Date(startDate),
|
||||||
$lte: new Date(),
|
$lte: new Date(),
|
||||||
};
|
};
|
||||||
} else if (endDate) {
|
} else if (endDate && startDate==='') {
|
||||||
query.createdAt = {
|
query.createdAt = {
|
||||||
$lte: new Date(endDate),
|
$lte: new Date(endDate),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch all matching documents (without pagination) to calculate total data
|
|
||||||
const allInventories = await Inventory.find(query).sort({ createdAt: -1 });
|
const allInventories = await Inventory.find(query).sort({ createdAt: -1 });
|
||||||
|
|
||||||
// Populate additional details
|
// Populate additional details
|
||||||
@ -127,6 +124,7 @@ export const getAllInventories = async (req, res) => {
|
|||||||
|
|
||||||
if (inventory.addedFor === "PrincipalDistributor") {
|
if (inventory.addedFor === "PrincipalDistributor") {
|
||||||
addedForData = await User.findById(inventory.addedForId);
|
addedForData = await User.findById(inventory.addedForId);
|
||||||
|
if (addedForData) {
|
||||||
const shippingAddress = await ShippingAddress.findOne({
|
const shippingAddress = await ShippingAddress.findOne({
|
||||||
user: addedForData._id,
|
user: addedForData._id,
|
||||||
});
|
});
|
||||||
@ -134,7 +132,9 @@ export const getAllInventories = async (req, res) => {
|
|||||||
...addedForData.toObject(),
|
...addedForData.toObject(),
|
||||||
shippingAddress,
|
shippingAddress,
|
||||||
};
|
};
|
||||||
tradeName = addedForData.shippingAddress?.tradeName?.toLowerCase() || "";
|
tradeName =
|
||||||
|
addedForData.shippingAddress?.tradeName?.toLowerCase() || "";
|
||||||
|
}
|
||||||
} else if (inventory.addedFor === "RetailDistributor") {
|
} else if (inventory.addedFor === "RetailDistributor") {
|
||||||
addedForData = await KYC.findById(inventory.addedForId);
|
addedForData = await KYC.findById(inventory.addedForId);
|
||||||
tradeName = addedForData?.trade_name?.toLowerCase() || "";
|
tradeName = addedForData?.trade_name?.toLowerCase() || "";
|
||||||
@ -149,11 +149,13 @@ export const getAllInventories = async (req, res) => {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
// Apply name filter
|
// Apply name filter if the name parameter is provided
|
||||||
let filteredInventories = populatedInventories;
|
let filteredInventories = populatedInventories;
|
||||||
if (name) {
|
if (name) {
|
||||||
filteredInventories = filteredInventories.filter(
|
filteredInventories = filteredInventories.filter(
|
||||||
(inventory) => inventory.tradeName && inventory.tradeName.includes(name.toLowerCase())
|
(inventory) =>
|
||||||
|
inventory.tradeName &&
|
||||||
|
inventory.tradeName.includes(name.toLowerCase())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,8 +163,10 @@ export const getAllInventories = async (req, res) => {
|
|||||||
const total_data = filteredInventories.length;
|
const total_data = filteredInventories.length;
|
||||||
|
|
||||||
// Apply pagination after filtering
|
// Apply pagination after filtering
|
||||||
const paginatedInventories = filteredInventories
|
const paginatedInventories = filteredInventories.slice(
|
||||||
.slice((page - 1) * show, page * show);
|
(page - 1) * show,
|
||||||
|
page * show
|
||||||
|
);
|
||||||
|
|
||||||
// Calculate total pages
|
// Calculate total pages
|
||||||
const total_pages = Math.ceil(total_data / show);
|
const total_pages = Math.ceil(total_data / show);
|
||||||
@ -171,10 +175,11 @@ export const getAllInventories = async (req, res) => {
|
|||||||
res.status(200).json({
|
res.status(200).json({
|
||||||
total_data,
|
total_data,
|
||||||
total_pages,
|
total_pages,
|
||||||
current_page: page,
|
current_page: Number(page),
|
||||||
inventories: paginatedInventories,
|
inventories: paginatedInventories,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.error("Error in getAllInventories:", error);
|
||||||
res.status(500).json({ message: error.message });
|
res.status(500).json({ message: error.message });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -2,6 +2,8 @@ import { Product } from "./ProductModel.js";
|
|||||||
import cloudinary from "../../Utils/cloudinary.js";
|
import cloudinary from "../../Utils/cloudinary.js";
|
||||||
import { v4 as uuidv4 } from "uuid";
|
import { v4 as uuidv4 } from "uuid";
|
||||||
import { CategoryModel } from "../Category/CategoryModel.js";
|
import { CategoryModel } from "../Category/CategoryModel.js";
|
||||||
|
import { BrandModel } from "../Brands/BrandsModel.js";
|
||||||
|
import User from "../user/userModel.js";
|
||||||
import { Tax } from "../Tax/tax_model.js";
|
import { Tax } from "../Tax/tax_model.js";
|
||||||
import XLSX from "xlsx";
|
import XLSX from "xlsx";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
@ -9,6 +11,267 @@ import path from "path";
|
|||||||
import mongoose from "mongoose";
|
import mongoose from "mongoose";
|
||||||
|
|
||||||
// Function to handle product upload
|
// Function to handle product upload
|
||||||
|
// export const uploadProducts = async (req, res) => {
|
||||||
|
// try {
|
||||||
|
// if (!req.files || !req.files.file) {
|
||||||
|
// return res.status(400).json({ message: "No file uploaded" });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const file = req.files.file;
|
||||||
|
// const filePath = path.join("public", "uploads", file.name);
|
||||||
|
|
||||||
|
// // Ensure 'uploads' directory exists
|
||||||
|
// if (!fs.existsSync(path.dirname(filePath))) {
|
||||||
|
// fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Move the file from temp to the uploads directory
|
||||||
|
// await file.mv(filePath);
|
||||||
|
|
||||||
|
// // Process the file
|
||||||
|
// const fileBuffer = fs.readFileSync(filePath);
|
||||||
|
// const workbook = XLSX.read(fileBuffer, { type: "buffer" });
|
||||||
|
// const sheetName = workbook.SheetNames[0];
|
||||||
|
// const worksheet = workbook.Sheets[sheetName];
|
||||||
|
// const data = XLSX.utils.sheet_to_json(worksheet, { header: 1 });
|
||||||
|
|
||||||
|
// if (data.length <= 1) {
|
||||||
|
// return res.status(400).json({ message: "Empty spreadsheet or no data found" });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const headers = data[0];
|
||||||
|
|
||||||
|
// // Map headers from the Excel file to your schema
|
||||||
|
// const headerMapping = {
|
||||||
|
// SKU: "SKU",
|
||||||
|
// "Product Name": "name",
|
||||||
|
// "Category Name": "category",
|
||||||
|
// "Brand Name": "brand",
|
||||||
|
// Price: "price",
|
||||||
|
// "GST (in %)": "GST",
|
||||||
|
// "HSN Code": "HSN_Code",
|
||||||
|
// "Description (Optional)": "description",
|
||||||
|
// };
|
||||||
|
|
||||||
|
// const requiredHeaders = Object.keys(headerMapping);
|
||||||
|
|
||||||
|
// if (!requiredHeaders.every((header) => headers.includes(header))) {
|
||||||
|
// return res.status(400).json({ message: "Missing required columns in spreadsheet" });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const errors = [];
|
||||||
|
// const newlyCreated = [];
|
||||||
|
// const updatedProducts = [];
|
||||||
|
|
||||||
|
// for (let i = 1; i < data.length; i++) {
|
||||||
|
// const row = data[i];
|
||||||
|
// const item = {};
|
||||||
|
|
||||||
|
// headers.forEach((header, index) => {
|
||||||
|
// if (headerMapping[header]) {
|
||||||
|
// item[headerMapping[header]] = row[index] !== undefined ? row[index] : "";
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
// // Initialize error tracking for each item
|
||||||
|
// const missingFields = new Set();
|
||||||
|
// const notFoundErrors = new Set();
|
||||||
|
|
||||||
|
// let { SKU, name, category, brand, price, GST, HSN_Code, description } = item;
|
||||||
|
|
||||||
|
// // Trim leading and trailing spaces from product name and GST
|
||||||
|
// name = name ? name.trim() : "";
|
||||||
|
|
||||||
|
// // Validate required fields
|
||||||
|
// if (!SKU) missingFields.add("SKU");
|
||||||
|
// if (!name) missingFields.add("name");
|
||||||
|
// if (!category) missingFields.add("category");
|
||||||
|
// if (!brand) missingFields.add("brand");
|
||||||
|
// if (price === undefined || price === "") missingFields.add("price");
|
||||||
|
// if (!GST) missingFields.add("GST");
|
||||||
|
// if (!HSN_Code) missingFields.add("HSN_Code");
|
||||||
|
|
||||||
|
// // Validate or create category
|
||||||
|
// let categoryName = "";
|
||||||
|
// if (category) {
|
||||||
|
// let categoryDoc = await CategoryModel.findOne({
|
||||||
|
// categoryName: { $regex: new RegExp(`^${category.trim()}$`, "i") },
|
||||||
|
// }).exec();
|
||||||
|
// if (!categoryDoc) {
|
||||||
|
// // If category not found, create a new one
|
||||||
|
// categoryDoc = await CategoryModel.create({
|
||||||
|
// categoryName: category.trim(),
|
||||||
|
// addedBy: req.user._id,
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// item.category = categoryDoc._id;
|
||||||
|
// categoryName = categoryDoc.categoryName;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Validate or create brand
|
||||||
|
// let brandName = "";
|
||||||
|
// if (brand) {
|
||||||
|
// let brandDoc = await BrandModel.findOne({
|
||||||
|
// brandName: { $regex: new RegExp(`^${brand.trim()}$`, "i") },
|
||||||
|
// }).exec();
|
||||||
|
// if (!brandDoc) {
|
||||||
|
// // If brand not found, create a new one
|
||||||
|
// brandDoc = await BrandModel.create({
|
||||||
|
// brandName: brand.trim(),
|
||||||
|
// addedBy: req.user._id,
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// item.brand = brandDoc._id;
|
||||||
|
// brandName = brandDoc.brandName;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Combine all errors into a single message
|
||||||
|
// let errorMessage = "";
|
||||||
|
// if (missingFields.size > 0) {
|
||||||
|
// errorMessage += `Missing fields: ${Array.from(missingFields).join(", ")}. `;
|
||||||
|
// }
|
||||||
|
// if (notFoundErrors.size > 0) {
|
||||||
|
// errorMessage += `Not found: ${Array.from(notFoundErrors).join(", ")}.`;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // If there are errors, push them to the errors array
|
||||||
|
// if (errorMessage.trim()) {
|
||||||
|
// errors.push({
|
||||||
|
// SKU: SKU || "N/A",
|
||||||
|
// productName: name || "N/A",
|
||||||
|
// category: category || "N/A",
|
||||||
|
// brand: brand || "N/A",
|
||||||
|
// GST: GST || "N/A",
|
||||||
|
// HSN_Code: HSN_Code || "N/A",
|
||||||
|
// price: price || "N/A",
|
||||||
|
// message: errorMessage.trim(),
|
||||||
|
// });
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Ensure fields are set to empty strings if not provided
|
||||||
|
// description = description !== undefined ? description : "";
|
||||||
|
|
||||||
|
// // Check for existing product by SKU
|
||||||
|
// let existingProduct = await Product.findOne({ SKU }).exec();
|
||||||
|
|
||||||
|
// if (existingProduct) {
|
||||||
|
// // Track changes
|
||||||
|
// const updatedFields = [];
|
||||||
|
// let updatedProduct = { ...existingProduct._doc };
|
||||||
|
|
||||||
|
// // Fetch existing category name and brand name
|
||||||
|
// const existingCategory = await CategoryModel.findById(existingProduct.category).exec();
|
||||||
|
// const existingBrand = await BrandModel.findById(existingProduct.brand).exec();
|
||||||
|
|
||||||
|
// // Update product fields if they have changed
|
||||||
|
// if (name !== existingProduct.name) {
|
||||||
|
// updatedFields.push("name");
|
||||||
|
// updatedProduct.name = name;
|
||||||
|
// }
|
||||||
|
// if (category && existingProduct.category.toString() !== item.category.toString()) {
|
||||||
|
// updatedFields.push("category");
|
||||||
|
// updatedProduct.category = categoryName;
|
||||||
|
// } else {
|
||||||
|
// updatedProduct.category = existingCategory ? existingCategory.categoryName : "";
|
||||||
|
// }
|
||||||
|
// if (price !== undefined && price !== "" && existingProduct.price !== price) {
|
||||||
|
// updatedFields.push("price");
|
||||||
|
// updatedProduct.price = price;
|
||||||
|
// }
|
||||||
|
// if (brand && existingProduct.brand.toString() !== item.brand.toString()) {
|
||||||
|
// updatedFields.push("brand");
|
||||||
|
// updatedProduct.brand = brandName;
|
||||||
|
// } else {
|
||||||
|
// updatedProduct.brand = existingBrand ? existingBrand.brandName : "";
|
||||||
|
// }
|
||||||
|
// if (HSN_Code !== existingProduct.HSN_Code) {
|
||||||
|
// updatedFields.push("HSN_Code");
|
||||||
|
// updatedProduct.HSN_Code = HSN_Code;
|
||||||
|
// }
|
||||||
|
// if (GST !== existingProduct.GST) {
|
||||||
|
// updatedFields.push("GST");
|
||||||
|
// updatedProduct.GST = GST;
|
||||||
|
// }
|
||||||
|
// if (description !== existingProduct.description) {
|
||||||
|
// updatedFields.push("description");
|
||||||
|
// updatedProduct.description = description;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Only update if there are changes
|
||||||
|
// if (updatedFields.length > 0) {
|
||||||
|
// try {
|
||||||
|
// await Product.updateOne(
|
||||||
|
// { SKU: existingProduct.SKU },
|
||||||
|
// {
|
||||||
|
// $set: {
|
||||||
|
// category: item.category || existingProduct.category,
|
||||||
|
// price: price !== undefined && price !== "" ? price : existingProduct.price,
|
||||||
|
// GST: GST || existingProduct.GST,
|
||||||
|
// HSN_Code: HSN_Code || existingProduct.HSN_Code,
|
||||||
|
// name: name,
|
||||||
|
// description: description,
|
||||||
|
// product_Status: item.product_Status || existingProduct.product_Status || "Active",
|
||||||
|
// },
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
// updatedProducts.push({
|
||||||
|
// ...updatedProduct,
|
||||||
|
// updatedFields: updatedFields.join(", "), // Track updated fields
|
||||||
|
// });
|
||||||
|
// } catch (error) {
|
||||||
|
// errors.push({
|
||||||
|
// SKU,
|
||||||
|
// message: "Failed to update product",
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Create new product
|
||||||
|
// if (item.category && item.brand) {
|
||||||
|
// const productData = {
|
||||||
|
// SKU,
|
||||||
|
// name,
|
||||||
|
// category: item.category,
|
||||||
|
// brand: item.brand,
|
||||||
|
// price,
|
||||||
|
// GST,
|
||||||
|
// HSN_Code,
|
||||||
|
// description: description,
|
||||||
|
// product_Status: item.product_Status || "Active",
|
||||||
|
// addedBy: req.user._id,
|
||||||
|
// };
|
||||||
|
// try {
|
||||||
|
// const newProduct = await Product.create(productData);
|
||||||
|
// newlyCreated.push({
|
||||||
|
// ...newProduct._doc,
|
||||||
|
// category: categoryName,
|
||||||
|
// brand: brandName,
|
||||||
|
// });
|
||||||
|
// } catch (error) {
|
||||||
|
// errors.push({
|
||||||
|
// SKU,
|
||||||
|
// message: "Failed to create product",
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fs.unlinkSync(filePath); // Clean up uploaded file
|
||||||
|
|
||||||
|
// res.status(201).json({
|
||||||
|
// message: errors.length > 0 ? "Products processed with errors!" : "Products processed successfully!",
|
||||||
|
// newlyCreated: newlyCreated,
|
||||||
|
// updatedProducts: updatedProducts,
|
||||||
|
// errors,
|
||||||
|
// });
|
||||||
|
// } catch (error) {
|
||||||
|
// console.error("Error:", error);
|
||||||
|
// res.status(500).json({ message: "Internal server error" });
|
||||||
|
// }
|
||||||
|
// };
|
||||||
export const uploadProducts = async (req, res) => {
|
export const uploadProducts = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
if (!req.files || !req.files.file) {
|
if (!req.files || !req.files.file) {
|
||||||
@ -45,11 +308,12 @@ export const uploadProducts = async (req, res) => {
|
|||||||
const headerMapping = {
|
const headerMapping = {
|
||||||
SKU: "SKU",
|
SKU: "SKU",
|
||||||
"Product Name": "name",
|
"Product Name": "name",
|
||||||
"category Name": "category",
|
"Category Name": "category",
|
||||||
price: "price",
|
"Brand Name": "brand",
|
||||||
"GST Name": "GST",
|
Price: "price",
|
||||||
description: "description",
|
"GST (in %)": "GST",
|
||||||
special_instructions: "special_instructions",
|
"HSN Code": "HSN_Code",
|
||||||
|
"Description (Optional)": "description",
|
||||||
};
|
};
|
||||||
|
|
||||||
const requiredHeaders = Object.keys(headerMapping);
|
const requiredHeaders = Object.keys(headerMapping);
|
||||||
@ -64,6 +328,12 @@ export const uploadProducts = async (req, res) => {
|
|||||||
const newlyCreated = [];
|
const newlyCreated = [];
|
||||||
const updatedProducts = [];
|
const updatedProducts = [];
|
||||||
|
|
||||||
|
const capitalizeWords = (str) =>
|
||||||
|
str
|
||||||
|
.toLowerCase()
|
||||||
|
.replace(/\b\w/g, (char) => char.toUpperCase())
|
||||||
|
.trim();
|
||||||
|
|
||||||
for (let i = 1; i < data.length; i++) {
|
for (let i = 1; i < data.length; i++) {
|
||||||
const row = data[i];
|
const row = data[i];
|
||||||
const item = {};
|
const item = {};
|
||||||
@ -75,61 +345,66 @@ export const uploadProducts = async (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Check if the row has meaningful data, skip if it's mostly empty
|
||||||
|
const hasValidData = Object.values(item).some((value) => value && value.trim());
|
||||||
|
if (!hasValidData) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize error tracking for each item
|
// Initialize error tracking for each item
|
||||||
const missingFields = new Set();
|
const missingFields = new Set();
|
||||||
const notFoundErrors = new Set();
|
|
||||||
|
|
||||||
let {
|
let { SKU, name, category, brand, price, GST, HSN_Code, description } =
|
||||||
SKU,
|
item;
|
||||||
name,
|
|
||||||
category,
|
|
||||||
price,
|
|
||||||
GST,
|
|
||||||
description,
|
|
||||||
special_instructions,
|
|
||||||
} = item;
|
|
||||||
|
|
||||||
// Trim leading and trailing spaces from product name and GST
|
// Trim leading and trailing spaces and apply case formatting
|
||||||
name = name ? name.trim() : "";
|
name = name ? name.trim() : "";
|
||||||
GST = GST ? GST.toString().trim() : "";
|
category = category ? capitalizeWords(category) : "";
|
||||||
|
brand = brand ? capitalizeWords(brand) : "";
|
||||||
|
|
||||||
// Validate required fields
|
// Validate required fields
|
||||||
if (!SKU) missingFields.add("SKU");
|
if (!SKU) missingFields.add("SKU");
|
||||||
if (!name) missingFields.add("name");
|
if (!name) missingFields.add("name");
|
||||||
if (!category) missingFields.add("category");
|
if (!category) missingFields.add("category");
|
||||||
|
if (!brand) missingFields.add("brand");
|
||||||
if (price === undefined || price === "") missingFields.add("price");
|
if (price === undefined || price === "") missingFields.add("price");
|
||||||
if (!GST) missingFields.add("GST");
|
if (!GST) missingFields.add("GST");
|
||||||
|
if (!HSN_Code) missingFields.add("HSN_Code");
|
||||||
|
|
||||||
// Validate category
|
// Validate or create category
|
||||||
let categoryName = "";
|
let categoryDoc = null;
|
||||||
|
let categoryname = "";
|
||||||
if (category) {
|
if (category) {
|
||||||
const categoryDoc = await CategoryModel.findOne({
|
categoryDoc = await CategoryModel.findOne({
|
||||||
categoryName: { $regex: new RegExp(`^${category.trim()}$`, "i") },
|
categoryName: { $regex: new RegExp(`^${category}$`, "i") },
|
||||||
}).exec();
|
}).exec();
|
||||||
if (categoryDoc) {
|
|
||||||
item.category = categoryDoc._id;
|
if (!categoryDoc) {
|
||||||
categoryName = categoryDoc.categoryName;
|
categoryDoc = await CategoryModel.create({
|
||||||
} else {
|
categoryName: category,
|
||||||
notFoundErrors.add("category");
|
addedBy: req.user._id,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else {
|
categoryname = categoryDoc.categoryName;
|
||||||
missingFields.add("category");
|
item.category = categoryDoc._id;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate GST
|
// Validate or create brand
|
||||||
let gstName = "";
|
let brandDoc = null;
|
||||||
if (GST) {
|
let brandname = "";
|
||||||
const gstDoc = await Tax.findOne({
|
if (brand) {
|
||||||
name: { $regex: new RegExp(`^${GST}$`, "i") },
|
brandDoc = await BrandModel.findOne({
|
||||||
|
brandName: { $regex: new RegExp(`^${brand}$`, "i") },
|
||||||
}).exec();
|
}).exec();
|
||||||
if (gstDoc) {
|
|
||||||
item.GST = gstDoc._id;
|
if (!brandDoc) {
|
||||||
gstName = gstDoc.name;
|
brandDoc = await BrandModel.create({
|
||||||
} else {
|
brandName: brand,
|
||||||
notFoundErrors.add("GST");
|
addedBy: req.user._id,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else {
|
brandname = brandDoc.brandName;
|
||||||
missingFields.add("GST");
|
item.brand = brandDoc._id;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Combine all errors into a single message
|
// Combine all errors into a single message
|
||||||
@ -139,17 +414,16 @@ export const uploadProducts = async (req, res) => {
|
|||||||
", "
|
", "
|
||||||
)}. `;
|
)}. `;
|
||||||
}
|
}
|
||||||
if (notFoundErrors.size > 0) {
|
|
||||||
errorMessage += `Not found: ${Array.from(notFoundErrors).join(", ")}.`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there are errors, push them to the errors array
|
// If there are errors, push them to the errors array
|
||||||
if (errorMessage.trim()) {
|
if (errorMessage.trim()) {
|
||||||
errors.push({
|
errors.push({
|
||||||
SKU: SKU || "N/A",
|
SKU: SKU || "N/A",
|
||||||
productName: name || "N/A",
|
productName: name || "N/A",
|
||||||
category: category || "N/A",
|
category: categoryname || "N/A",
|
||||||
|
brand: brandname || "N/A",
|
||||||
GST: GST || "N/A",
|
GST: GST || "N/A",
|
||||||
|
HSN_Code: HSN_Code || "N/A",
|
||||||
price: price || "N/A",
|
price: price || "N/A",
|
||||||
message: errorMessage.trim(),
|
message: errorMessage.trim(),
|
||||||
});
|
});
|
||||||
@ -158,8 +432,6 @@ export const uploadProducts = async (req, res) => {
|
|||||||
|
|
||||||
// Ensure fields are set to empty strings if not provided
|
// Ensure fields are set to empty strings if not provided
|
||||||
description = description !== undefined ? description : "";
|
description = description !== undefined ? description : "";
|
||||||
special_instructions =
|
|
||||||
special_instructions !== undefined ? special_instructions : "";
|
|
||||||
|
|
||||||
// Check for existing product by SKU
|
// Check for existing product by SKU
|
||||||
let existingProduct = await Product.findOne({ SKU }).exec();
|
let existingProduct = await Product.findOne({ SKU }).exec();
|
||||||
@ -169,22 +441,19 @@ export const uploadProducts = async (req, res) => {
|
|||||||
const updatedFields = [];
|
const updatedFields = [];
|
||||||
let updatedProduct = { ...existingProduct._doc };
|
let updatedProduct = { ...existingProduct._doc };
|
||||||
|
|
||||||
// Fetch existing category name and GST name
|
// Update product fields if they have changed
|
||||||
const existingCategory = await CategoryModel.findById(
|
if (name !== existingProduct.name) {
|
||||||
existingProduct.category
|
updatedFields.push("name");
|
||||||
).exec();
|
updatedProduct.name = name;
|
||||||
const existingGST = await Tax.findById(existingProduct.GST).exec();
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
category &&
|
categoryDoc &&
|
||||||
existingProduct.category.toString() !== item.category.toString()
|
existingProduct.category.toString() !== item.category.toString()
|
||||||
) {
|
) {
|
||||||
updatedFields.push("category");
|
updatedFields.push("category");
|
||||||
updatedProduct.category = categoryName;
|
updatedProduct.category = categoryname;
|
||||||
} else {
|
} else {
|
||||||
updatedProduct.category = existingCategory
|
updatedProduct.category = categoryDoc.categoryName;
|
||||||
? existingCategory.categoryName
|
|
||||||
: "";
|
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
price !== undefined &&
|
price !== undefined &&
|
||||||
@ -194,20 +463,27 @@ export const uploadProducts = async (req, res) => {
|
|||||||
updatedFields.push("price");
|
updatedFields.push("price");
|
||||||
updatedProduct.price = price;
|
updatedProduct.price = price;
|
||||||
}
|
}
|
||||||
if (GST && existingProduct.GST.toString() !== item.GST.toString()) {
|
if (
|
||||||
updatedFields.push("GST");
|
brandDoc &&
|
||||||
updatedProduct.GST = gstName;
|
existingProduct.brand.toString() !== item.brand.toString()
|
||||||
|
) {
|
||||||
|
updatedFields.push("brand");
|
||||||
|
updatedProduct.brand = brandname;
|
||||||
} else {
|
} else {
|
||||||
updatedProduct.GST = existingGST ? existingGST.name : "";
|
updatedProduct.brand = brandDoc.brandName;
|
||||||
|
}
|
||||||
|
if (HSN_Code !== existingProduct.HSN_Code) {
|
||||||
|
updatedFields.push("HSN_Code");
|
||||||
|
updatedProduct.HSN_Code = HSN_Code;
|
||||||
|
}
|
||||||
|
if (GST !== existingProduct.GST) {
|
||||||
|
updatedFields.push("GST");
|
||||||
|
updatedProduct.GST = GST;
|
||||||
}
|
}
|
||||||
if (description !== existingProduct.description) {
|
if (description !== existingProduct.description) {
|
||||||
updatedFields.push("description");
|
updatedFields.push("description");
|
||||||
updatedProduct.description = description;
|
updatedProduct.description = description;
|
||||||
}
|
}
|
||||||
if (special_instructions !== existingProduct.special_instructions) {
|
|
||||||
updatedFields.push("special_instructions");
|
|
||||||
updatedProduct.special_instructions = special_instructions;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only update if there are changes
|
// Only update if there are changes
|
||||||
if (updatedFields.length > 0) {
|
if (updatedFields.length > 0) {
|
||||||
@ -217,13 +493,15 @@ export const uploadProducts = async (req, res) => {
|
|||||||
{
|
{
|
||||||
$set: {
|
$set: {
|
||||||
category: item.category || existingProduct.category,
|
category: item.category || existingProduct.category,
|
||||||
|
brand: item.brand || existingProduct.brand,
|
||||||
price:
|
price:
|
||||||
price !== undefined && price !== ""
|
price !== undefined && price !== ""
|
||||||
? price
|
? price
|
||||||
: existingProduct.price,
|
: existingProduct.price,
|
||||||
GST: item.GST || existingProduct.GST,
|
GST: GST || existingProduct.GST,
|
||||||
|
HSN_Code: HSN_Code || existingProduct.HSN_Code,
|
||||||
|
name: name,
|
||||||
description: description,
|
description: description,
|
||||||
special_instructions: special_instructions,
|
|
||||||
product_Status:
|
product_Status:
|
||||||
item.product_Status ||
|
item.product_Status ||
|
||||||
existingProduct.product_Status ||
|
existingProduct.product_Status ||
|
||||||
@ -246,15 +524,16 @@ export const uploadProducts = async (req, res) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create new product
|
// Create new product
|
||||||
if (item.category && item.GST) {
|
if (item.category && item.brand) {
|
||||||
const productData = {
|
const productData = {
|
||||||
SKU,
|
SKU,
|
||||||
name,
|
name,
|
||||||
category: item.category,
|
category: item.category,
|
||||||
|
brand: item.brand,
|
||||||
price,
|
price,
|
||||||
GST: item.GST,
|
GST,
|
||||||
|
HSN_Code,
|
||||||
description: description,
|
description: description,
|
||||||
special_instructions: special_instructions,
|
|
||||||
product_Status: item.product_Status || "Active",
|
product_Status: item.product_Status || "Active",
|
||||||
addedBy: req.user._id,
|
addedBy: req.user._id,
|
||||||
};
|
};
|
||||||
@ -262,8 +541,8 @@ export const uploadProducts = async (req, res) => {
|
|||||||
const newProduct = await Product.create(productData);
|
const newProduct = await Product.create(productData);
|
||||||
newlyCreated.push({
|
newlyCreated.push({
|
||||||
...newProduct._doc,
|
...newProduct._doc,
|
||||||
category: categoryName,
|
category: categoryDoc.categoryName,
|
||||||
GST: gstName,
|
brand: brandDoc.brandName,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
errors.push({
|
errors.push({
|
||||||
@ -286,8 +565,8 @@ export const uploadProducts = async (req, res) => {
|
|||||||
errors,
|
errors,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error:", error);
|
console.error("Error uploading products:", error);
|
||||||
res.status(500).json({ message: error.message || "Something went wrong!" });
|
res.status(500).json({ message: "Server error" });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -296,7 +575,7 @@ export const createProduct = async (req, res) => {
|
|||||||
let findProduct = "";
|
let findProduct = "";
|
||||||
let product = { _id: "" };
|
let product = { _id: "" };
|
||||||
const sku = req.body?.SKU;
|
const sku = req.body?.SKU;
|
||||||
|
// console.log(req.body);
|
||||||
if (!sku) {
|
if (!sku) {
|
||||||
return res.status(400).json({ message: "SKU is required!" });
|
return res.status(400).json({ message: "SKU is required!" });
|
||||||
}
|
}
|
||||||
@ -450,13 +729,16 @@ export const getAllProductAdmin = async (req, res) => {
|
|||||||
if (req.query.category) {
|
if (req.query.category) {
|
||||||
filter.category = mongoose.Types.ObjectId(req.query.category);
|
filter.category = mongoose.Types.ObjectId(req.query.category);
|
||||||
}
|
}
|
||||||
|
if (req.query.brand) {
|
||||||
|
filter.brand = mongoose.Types.ObjectId(req.query.brand);
|
||||||
|
}
|
||||||
|
|
||||||
const total = await Product.countDocuments(filter);
|
const total = await Product.countDocuments(filter);
|
||||||
|
|
||||||
const products = await Product.find(filter)
|
const products = await Product.find(filter)
|
||||||
.populate({
|
.populate({
|
||||||
path: "category addedBy GST",
|
path: "category addedBy brand",
|
||||||
select: "categoryName name tax",
|
select: "categoryName name brandName",
|
||||||
})
|
})
|
||||||
.limit(PAGE_SIZE)
|
.limit(PAGE_SIZE)
|
||||||
.skip(skip)
|
.skip(skip)
|
||||||
@ -488,7 +770,9 @@ export const getAllProductUser = async (req, res) => {
|
|||||||
|
|
||||||
// Filter by category name
|
// Filter by category name
|
||||||
if (req.query?.category) {
|
if (req.query?.category) {
|
||||||
const category = await CategoryModel.findOne({ categoryName: req.query.category });
|
const category = await CategoryModel.findOne({
|
||||||
|
categoryName: req.query.category,
|
||||||
|
});
|
||||||
if (category) {
|
if (category) {
|
||||||
filter.category = category._id;
|
filter.category = category._id;
|
||||||
} else {
|
} else {
|
||||||
@ -498,7 +782,9 @@ export const getAllProductUser = async (req, res) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (req.query.brand) {
|
||||||
|
filter.brand = mongoose.Types.ObjectId(req.query.brand);
|
||||||
|
}
|
||||||
// Filter by SKU
|
// Filter by SKU
|
||||||
if (req.query?.SKU) {
|
if (req.query?.SKU) {
|
||||||
filter.SKU = req.query.SKU;
|
filter.SKU = req.query.SKU;
|
||||||
@ -507,7 +793,7 @@ export const getAllProductUser = async (req, res) => {
|
|||||||
// Filter by product name using regex for case-insensitive partial matching
|
// Filter by product name using regex for case-insensitive partial matching
|
||||||
if (req.query?.name) {
|
if (req.query?.name) {
|
||||||
filter.name = {
|
filter.name = {
|
||||||
$regex: new RegExp(req.query.name, 'i'),
|
$regex: new RegExp(req.query.name, "i"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -520,8 +806,8 @@ export const getAllProductUser = async (req, res) => {
|
|||||||
// Retrieve products with pagination, filtering, and sorting
|
// Retrieve products with pagination, filtering, and sorting
|
||||||
const products = await Product.find(filter)
|
const products = await Product.find(filter)
|
||||||
.populate({
|
.populate({
|
||||||
path: "category addedBy GST",
|
path: "category addedBy brand",
|
||||||
select: "categoryName name tax",
|
select: "categoryName name brandName",
|
||||||
})
|
})
|
||||||
.limit(PAGE_SIZE)
|
.limit(PAGE_SIZE)
|
||||||
.skip(PAGE_SIZE * page)
|
.skip(PAGE_SIZE * page)
|
||||||
@ -588,8 +874,8 @@ export const ChangeProductStatus = async (req, res) => {
|
|||||||
export const getOneProduct = async (req, res) => {
|
export const getOneProduct = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const data = await Product.findById(req.params.id).populate({
|
const data = await Product.findById(req.params.id).populate({
|
||||||
path: "category addedBy GST",
|
path: "category addedBy brand",
|
||||||
select: "name categoryName tax",
|
select: "categoryName name brandName",
|
||||||
});
|
});
|
||||||
if (data) {
|
if (data) {
|
||||||
return res.status(200).json({
|
return res.status(200).json({
|
||||||
|
@ -20,24 +20,27 @@ const productSchema = new Schema(
|
|||||||
type: Schema.Types.ObjectId,
|
type: Schema.Types.ObjectId,
|
||||||
ref: "CategoryModel",
|
ref: "CategoryModel",
|
||||||
},
|
},
|
||||||
|
brand: {
|
||||||
|
type: Schema.Types.ObjectId,
|
||||||
|
ref: "BrandModel",
|
||||||
|
},
|
||||||
price: {
|
price: {
|
||||||
type: Number,
|
type: Number,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
GST: {
|
GST: {
|
||||||
type: mongoose.Schema.ObjectId,
|
type: Number,
|
||||||
ref: "Tax",
|
required: true,
|
||||||
|
},
|
||||||
|
HSN_Code: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
},
|
},
|
||||||
description: {
|
description: {
|
||||||
type: String,
|
type: String,
|
||||||
maxLength: [400, "description cannot exceed 100 characters"],
|
maxLength: [400, "description cannot exceed 100 characters"],
|
||||||
// required: [true, "Please Enter product Description"],
|
// required: [true, "Please Enter product Description"],
|
||||||
},
|
},
|
||||||
|
|
||||||
special_instructions: {
|
|
||||||
type: String,
|
|
||||||
},
|
|
||||||
image: [
|
image: [
|
||||||
{
|
{
|
||||||
public_id: {
|
public_id: {
|
||||||
|
Loading…
Reference in New Issue
Block a user