Inventory
This commit is contained in:
parent
c89b57b89f
commit
01e12dedaf
6
app.js
6
app.js
@ -186,6 +186,9 @@ import attendance from "./resources/Attendance/AttandanceRoute.js";
|
|||||||
import leave from "./resources/Leaves/LeaveRoute.js";
|
import leave from "./resources/Leaves/LeaveRoute.js";
|
||||||
// Notification
|
// Notification
|
||||||
import notification from "./resources/Notification/notificationRoute.js"
|
import notification from "./resources/Notification/notificationRoute.js"
|
||||||
|
//Inventory
|
||||||
|
import InventoryRoute from "./resources/Inventory/InventoryRoute.js";
|
||||||
|
|
||||||
app.use("/api/v1", user);
|
app.use("/api/v1", user);
|
||||||
|
|
||||||
//Product
|
//Product
|
||||||
@ -253,6 +256,9 @@ app.use("/api/v1", leave);
|
|||||||
// notification route
|
// notification route
|
||||||
app.use("/api",notification)
|
app.use("/api",notification)
|
||||||
|
|
||||||
|
//Inventory
|
||||||
|
app.use("/api/inventory", InventoryRoute);
|
||||||
|
|
||||||
//config specialty
|
//config specialty
|
||||||
// app.use("/api/config/specialty", SpecialtiesRouter);
|
// app.use("/api/config/specialty", SpecialtiesRouter);
|
||||||
//specialties
|
//specialties
|
||||||
|
145
resources/Inventory/InventoryController.js
Normal file
145
resources/Inventory/InventoryController.js
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
import { Inventory } from "../Inventory/InventoryModel.js";
|
||||||
|
import User from "../user/userModel.js";
|
||||||
|
import { KYC } from "../KYC/KycModel.js";
|
||||||
|
import ShippingAddress from "../ShippingAddresses/ShippingAddressModel.js";
|
||||||
|
import TerritoryManager from "../TerritoryManagers/TerritoryManagerModel.js";
|
||||||
|
import SalesCoordinator from "../SalesCoOrdinators/SalesCoOrdinatorModel.js";
|
||||||
|
// Add inventory data
|
||||||
|
export const addInventory = async (req, res) => {
|
||||||
|
try {
|
||||||
|
const { products, addedFor, addedForId } = req.body;
|
||||||
|
const userId = req.user._id;
|
||||||
|
const userType = req.userType;
|
||||||
|
// console.log("req.user", req.user);
|
||||||
|
const newInventory = new Inventory({
|
||||||
|
userId,
|
||||||
|
userType,
|
||||||
|
addedFor,
|
||||||
|
addedForId,
|
||||||
|
products,
|
||||||
|
});
|
||||||
|
|
||||||
|
await newInventory.save();
|
||||||
|
res.status(201).json({
|
||||||
|
success: true,
|
||||||
|
message: "Inventory added successfully",
|
||||||
|
data: newInventory,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
res.status(500).json({ success: false, message: "Server error", error });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get all distributors (PD or RD)
|
||||||
|
export const getDistributors = async (req, res) => {
|
||||||
|
try {
|
||||||
|
const { type } = req.params;
|
||||||
|
|
||||||
|
if (!["PrincipalDistributor", "RetailDistributor"].includes(type)) {
|
||||||
|
return res.status(400).json({ message: "Invalid distributor type" });
|
||||||
|
}
|
||||||
|
|
||||||
|
let distributors;
|
||||||
|
// console.log("type",type);
|
||||||
|
if (type === "PrincipalDistributor") {
|
||||||
|
// Fetch all PrincipalDistributors
|
||||||
|
const principalDistributors = await User.find({ role: "principal-Distributor" });
|
||||||
|
// console.log("principalDistributors",principalDistributors);
|
||||||
|
// Map each PrincipalDistributor to include their ShippingAddress
|
||||||
|
distributors = await Promise.all(principalDistributors.map(async (distributor) => {
|
||||||
|
const shippingAddress = await ShippingAddress.findOne({ user: distributor._id });
|
||||||
|
return {
|
||||||
|
...distributor.toObject(),
|
||||||
|
shippingAddress,
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
// For RetailDistributor, fetch approved KYC documents
|
||||||
|
distributors = await KYC.find({ status: "approved" });
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(200).json(distributors);
|
||||||
|
} catch (error) {
|
||||||
|
res.status(500).json({ message: error.message });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getAllInventories = async (req, res) => {
|
||||||
|
try {
|
||||||
|
const inventories = await Inventory.find();
|
||||||
|
|
||||||
|
const populatedInventories = await Promise.all(inventories.map(async (inventory) => {
|
||||||
|
// Populate user details based on userType
|
||||||
|
let user = null;
|
||||||
|
if (inventory.userType === 'TerritoryManager') {
|
||||||
|
user = await TerritoryManager.findById(inventory.userId);
|
||||||
|
} else if (inventory.userType === 'SalesCoOrdinator') {
|
||||||
|
user = await SalesCoordinator.findById(inventory.userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Populate addedFor details based on addedFor
|
||||||
|
let addedForData = null;
|
||||||
|
if (inventory.addedFor === 'PrincipalDistributor') {
|
||||||
|
addedForData = await User.findById(inventory.addedForId);
|
||||||
|
const shippingAddress = await ShippingAddress.findOne({ user: addedForData._id });
|
||||||
|
addedForData = {
|
||||||
|
...addedForData.toObject(),
|
||||||
|
shippingAddress,
|
||||||
|
};
|
||||||
|
} else if (inventory.addedFor === 'RetailDistributor') {
|
||||||
|
addedForData = await KYC.findById(inventory.addedForId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...inventory.toObject(),
|
||||||
|
user,
|
||||||
|
addedForData,
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
|
||||||
|
res.status(200).json(populatedInventories);
|
||||||
|
} catch (error) {
|
||||||
|
res.status(500).json({ message: error.message });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getSingleInventory = async (req, res) => {
|
||||||
|
try {
|
||||||
|
const { id } = req.params;
|
||||||
|
|
||||||
|
const inventory = await Inventory.findById(id);
|
||||||
|
if (!inventory) {
|
||||||
|
return res.status(404).json({ message: "Inventory not found" });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Populate user details based on userType
|
||||||
|
let user = null;
|
||||||
|
if (inventory.userType === 'TerritoryManager') {
|
||||||
|
user = await TerritoryManager.findById(inventory.userId);
|
||||||
|
} else if (inventory.userType === 'SalesCoOrdinator') {
|
||||||
|
user = await SalesCoordinator.findById(inventory.userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Populate addedFor details based on addedFor
|
||||||
|
let addedForData = null;
|
||||||
|
if (inventory.addedFor === 'PrincipalDistributor') {
|
||||||
|
addedForData = await User.findById(inventory.addedForId);
|
||||||
|
const shippingAddress = await ShippingAddress.findOne({ user: addedForData._id });
|
||||||
|
addedForData = {
|
||||||
|
...addedForData.toObject(),
|
||||||
|
shippingAddress,
|
||||||
|
};
|
||||||
|
} else if (inventory.addedFor === 'RetailDistributor') {
|
||||||
|
addedForData = await KYC.findById(inventory.addedForId);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(200).json({
|
||||||
|
...inventory.toObject(),
|
||||||
|
user,
|
||||||
|
addedForData,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
res.status(500).json({ message: error.message });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
48
resources/Inventory/InventoryModel.js
Normal file
48
resources/Inventory/InventoryModel.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import mongoose from 'mongoose';
|
||||||
|
|
||||||
|
// Define Product record schema
|
||||||
|
const ProductRecordSchema = new mongoose.Schema({
|
||||||
|
SKU: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
ProductName: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
Sale: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
Inventory: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Define main Inventory schema
|
||||||
|
const InventorySchema = new mongoose.Schema({
|
||||||
|
userId: {
|
||||||
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
|
refPath: 'userType',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
userType: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
enum: ['SalesCoOrdinator', 'TerritoryManager'],
|
||||||
|
},
|
||||||
|
addedFor: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
enum: ['PrincipalDistributor', 'RetailDistributor'],
|
||||||
|
},
|
||||||
|
addedForId: {
|
||||||
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
|
refPath: 'addedFor',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
products: [ProductRecordSchema],
|
||||||
|
}, { timestamps: true, versionKey: false });
|
||||||
|
|
||||||
|
export const Inventory = mongoose.model('Inventory', InventorySchema);
|
36
resources/Inventory/InventoryRoute.js
Normal file
36
resources/Inventory/InventoryRoute.js
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import express from "express";
|
||||||
|
import { addInventory, getDistributors,getAllInventories,getSingleInventory } from "./InventoryController.js";
|
||||||
|
import { isAuthenticatedSalesCoOrdinator } from "../../middlewares/SalesCoOrdinatorAuth.js";
|
||||||
|
import { isAuthenticatedTerritoryManager } from "../../middlewares/TerritoryManagerAuth.js";
|
||||||
|
import { authorizeRoles, isAuthenticatedUser } from "../../middlewares/auth.js";
|
||||||
|
const router = express.Router();
|
||||||
|
|
||||||
|
// Route to add inventory data
|
||||||
|
router.post("/add-SC", isAuthenticatedSalesCoOrdinator, addInventory);
|
||||||
|
router.post("/add-TM", isAuthenticatedTerritoryManager, addInventory);
|
||||||
|
// Route to get all PD or RD names based on type
|
||||||
|
router.get(
|
||||||
|
"/distributors-SC/:type",
|
||||||
|
isAuthenticatedSalesCoOrdinator,
|
||||||
|
getDistributors
|
||||||
|
);
|
||||||
|
router.get(
|
||||||
|
"/distributors-TM/:type",
|
||||||
|
isAuthenticatedTerritoryManager,
|
||||||
|
getDistributors
|
||||||
|
);
|
||||||
|
|
||||||
|
// Admin routes
|
||||||
|
router.get(
|
||||||
|
"/all",
|
||||||
|
isAuthenticatedUser,
|
||||||
|
authorizeRoles("admin"),
|
||||||
|
getAllInventories
|
||||||
|
);
|
||||||
|
router.get(
|
||||||
|
"/:id",
|
||||||
|
isAuthenticatedUser,
|
||||||
|
authorizeRoles("admin"),
|
||||||
|
getSingleInventory
|
||||||
|
);
|
||||||
|
export default router;
|
@ -41,6 +41,7 @@ export const uploadProducts = async (req, res) => {
|
|||||||
|
|
||||||
// Map headers from the Excel file to your schema
|
// Map headers from the Excel file to your schema
|
||||||
const headerMapping = {
|
const headerMapping = {
|
||||||
|
SKU: "SKU",
|
||||||
"Product Name": "name",
|
"Product Name": "name",
|
||||||
"category Name": "category",
|
"category Name": "category",
|
||||||
price: "price",
|
price: "price",
|
||||||
@ -73,13 +74,14 @@ export const uploadProducts = async (req, res) => {
|
|||||||
const missingFields = new Set();
|
const missingFields = new Set();
|
||||||
const notFoundErrors = new Set();
|
const notFoundErrors = new Set();
|
||||||
|
|
||||||
let { name, category, price, GST, description, special_instructions } = item;
|
let { SKU, name, category, price, GST, description, special_instructions } = item;
|
||||||
|
|
||||||
// Trim leading and trailing spaces from product name and GST
|
// Trim leading and trailing spaces from product name and GST
|
||||||
name = name ? name.trim() : "";
|
name = name ? name.trim() : "";
|
||||||
GST = GST ? GST.toString().trim() : "";
|
GST = GST ? GST.toString().trim() : "";
|
||||||
|
|
||||||
// Validate required fields
|
// Validate required fields
|
||||||
|
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 (price === undefined || price === "") missingFields.add("price");
|
if (price === undefined || price === "") missingFields.add("price");
|
||||||
@ -129,6 +131,7 @@ export const uploadProducts = async (req, res) => {
|
|||||||
// 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",
|
||||||
productName: name || "N/A",
|
productName: name || "N/A",
|
||||||
category: category || "N/A",
|
category: category || "N/A",
|
||||||
GST: GST || "N/A",
|
GST: GST || "N/A",
|
||||||
@ -142,10 +145,8 @@ export const uploadProducts = async (req, res) => {
|
|||||||
description = description !== undefined ? description : "";
|
description = description !== undefined ? description : "";
|
||||||
special_instructions = special_instructions !== undefined ? special_instructions : "";
|
special_instructions = special_instructions !== undefined ? special_instructions : "";
|
||||||
|
|
||||||
// Check for existing product
|
// Check for existing product by SKU
|
||||||
let existingProduct = await Product.findOne({
|
let existingProduct = await Product.findOne({ SKU }).exec();
|
||||||
name: new RegExp(`^${name}$`, "i"),
|
|
||||||
}).exec();
|
|
||||||
|
|
||||||
if (existingProduct) {
|
if (existingProduct) {
|
||||||
// Track changes
|
// Track changes
|
||||||
@ -185,7 +186,7 @@ export const uploadProducts = async (req, res) => {
|
|||||||
if (updatedFields.length > 0) {
|
if (updatedFields.length > 0) {
|
||||||
try {
|
try {
|
||||||
await Product.updateOne(
|
await Product.updateOne(
|
||||||
{ _id: existingProduct._id },
|
{ SKU: existingProduct.SKU },
|
||||||
{
|
{
|
||||||
$set: {
|
$set: {
|
||||||
category: item.category || existingProduct.category,
|
category: item.category || existingProduct.category,
|
||||||
@ -203,7 +204,7 @@ export const uploadProducts = async (req, res) => {
|
|||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
errors.push({
|
errors.push({
|
||||||
productName: name,
|
SKU,
|
||||||
message: "Failed to update product",
|
message: "Failed to update product",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -214,6 +215,7 @@ export const uploadProducts = async (req, res) => {
|
|||||||
// Create new product
|
// Create new product
|
||||||
if (item.category && item.GST) {
|
if (item.category && item.GST) {
|
||||||
const productData = {
|
const productData = {
|
||||||
|
SKU,
|
||||||
name,
|
name,
|
||||||
category: item.category,
|
category: item.category,
|
||||||
price,
|
price,
|
||||||
@ -232,7 +234,7 @@ export const uploadProducts = async (req, res) => {
|
|||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
errors.push({
|
errors.push({
|
||||||
productName: name,
|
SKU,
|
||||||
message: "Failed to create product",
|
message: "Failed to create product",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -249,8 +251,6 @@ export const uploadProducts = async (req, res) => {
|
|||||||
newlyCreated: newlyCreated,
|
newlyCreated: newlyCreated,
|
||||||
updatedProducts: updatedProducts,
|
updatedProducts: updatedProducts,
|
||||||
errors,
|
errors,
|
||||||
newlyCreated,
|
|
||||||
updatedProducts,
|
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error:", error);
|
console.error("Error:", error);
|
||||||
@ -263,34 +263,46 @@ export const createProduct = async (req, res) => {
|
|||||||
try {
|
try {
|
||||||
let findProduct = "";
|
let findProduct = "";
|
||||||
let product = { _id: "" };
|
let product = { _id: "" };
|
||||||
// console.log("req.body", req.body);
|
const sku = req.body?.SKU;
|
||||||
|
|
||||||
|
if (!sku) {
|
||||||
|
return res.status(400).json({ message: "SKU is required!" });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if SKU exists in the request body
|
||||||
if (req.body?.product_id) {
|
if (req.body?.product_id) {
|
||||||
findProduct = await Product.findById(req.body.product_id);
|
findProduct = await Product.findById(req.body.product_id);
|
||||||
}
|
}
|
||||||
const name = req.body?.name;
|
|
||||||
if (!findProduct) {
|
if (!findProduct) {
|
||||||
const data = await Product.findOne({
|
// Check if a product with the same SKU already exists
|
||||||
name: { $regex: new RegExp(`^${name}$`, "ig") },
|
const existingProduct = await Product.findOne({
|
||||||
|
SKU: { $regex: new RegExp(`^${sku}$`, "i") },
|
||||||
}).exec();
|
}).exec();
|
||||||
if (data)
|
|
||||||
return res
|
if (existingProduct) {
|
||||||
.status(400)
|
return res.status(400).json({ message: "Product with this SKU already exists!" });
|
||||||
.json({ message: "Product name already exists!" });
|
}
|
||||||
|
|
||||||
|
// Add user ID to the request body
|
||||||
req.body.addedBy = req.user._id;
|
req.body.addedBy = req.user._id;
|
||||||
product = await Product.create(req.body);
|
product = await Product.create(req.body);
|
||||||
} else {
|
} else {
|
||||||
const data = await Product.findOne({
|
// Check if another product with the same SKU exists, excluding the current one
|
||||||
|
const existingProduct = await Product.findOne({
|
||||||
_id: { $ne: findProduct._id },
|
_id: { $ne: findProduct._id },
|
||||||
name: { $regex: new RegExp(`^${name}$`, "ig") },
|
SKU: { $regex: new RegExp(`^${sku}$`, "i") },
|
||||||
}).exec();
|
}).exec();
|
||||||
if (data)
|
|
||||||
return res
|
if (existingProduct) {
|
||||||
.status(400)
|
return res.status(400).json({ message: "Product with this SKU already exists!" });
|
||||||
.json({ message: "Product name already exists!" });
|
|
||||||
product = await Product.findByIdAndUpdate(req.body.product_id, req.body);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
product = await Product.findByIdAndUpdate(req.body.product_id, req.body, { new: true });
|
||||||
|
}
|
||||||
|
|
||||||
res.status(201).json({
|
res.status(201).json({
|
||||||
message: "Product details added successfully!",
|
message: "Product details added/updated successfully!",
|
||||||
product_id: product._id,
|
product_id: product._id,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -300,6 +312,7 @@ export const createProduct = async (req, res) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
export const updateProduct = async (req, res) => {
|
export const updateProduct = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
@ -435,14 +448,35 @@ export const getAllProductUser = async (req, res) => {
|
|||||||
const PAGE_SIZE = parseInt(req.query?.show || "10");
|
const PAGE_SIZE = parseInt(req.query?.show || "10");
|
||||||
const page = parseInt(req.query?.page - 1 || "0");
|
const page = parseInt(req.query?.page - 1 || "0");
|
||||||
let obj = {};
|
let obj = {};
|
||||||
if (req.query?.name)
|
|
||||||
|
// Filter by category
|
||||||
|
if (req.query?.category) {
|
||||||
|
const category = await CategoryModel.findOne({ name: req.query.category });
|
||||||
|
if (category) {
|
||||||
|
obj.category = category._id;
|
||||||
|
} else {
|
||||||
|
return res.status(400).json({
|
||||||
|
success: false,
|
||||||
|
msg: "Category not found!",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Filter by SKU or product name
|
||||||
|
if (req.query?.SKU) {
|
||||||
|
obj.SKU = req.query.SKU;
|
||||||
|
}
|
||||||
|
if (req.query?.name) {
|
||||||
obj.name = {
|
obj.name = {
|
||||||
$regex: new RegExp(req.query.name),
|
$regex: new RegExp(req.query.name, 'i'),
|
||||||
$options: "i",
|
|
||||||
};
|
};
|
||||||
if (req.query?.category) obj.category = req.query.category;
|
}
|
||||||
|
|
||||||
obj.product_Status = "Active";
|
obj.product_Status = "Active";
|
||||||
|
|
||||||
|
// Get total count
|
||||||
const total = await Product.countDocuments(obj);
|
const total = await Product.countDocuments(obj);
|
||||||
|
|
||||||
|
// Get filtered products
|
||||||
const product = await Product.find(obj)
|
const product = await Product.find(obj)
|
||||||
.populate({
|
.populate({
|
||||||
path: "category addedBy GST",
|
path: "category addedBy GST",
|
||||||
@ -450,10 +484,7 @@ export const getAllProductUser = async (req, res) => {
|
|||||||
})
|
})
|
||||||
.limit(PAGE_SIZE)
|
.limit(PAGE_SIZE)
|
||||||
.skip(PAGE_SIZE * page)
|
.skip(PAGE_SIZE * page)
|
||||||
// .sort("name")
|
.sort({ createdAt: -1 })
|
||||||
.sort({
|
|
||||||
createdAt: -1,
|
|
||||||
})
|
|
||||||
.exec();
|
.exec();
|
||||||
|
|
||||||
if (product) {
|
if (product) {
|
||||||
@ -463,11 +494,16 @@ export const getAllProductUser = async (req, res) => {
|
|||||||
total_pages: Math.ceil(total / PAGE_SIZE),
|
total_pages: Math.ceil(total / PAGE_SIZE),
|
||||||
product,
|
product,
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
return res.status(404).json({
|
||||||
|
success: false,
|
||||||
|
msg: "No products found!",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
success: false,
|
success: false,
|
||||||
msg: error.message ? error.message : "Something went wrong!",
|
msg: error.message || "Something went wrong!",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -3,6 +3,12 @@ const { Schema, model } = mongoose;
|
|||||||
|
|
||||||
const productSchema = new Schema(
|
const productSchema = new Schema(
|
||||||
{
|
{
|
||||||
|
SKU: {
|
||||||
|
type: String,
|
||||||
|
required: [true, "Please Enter product SKU"],
|
||||||
|
unique: true,
|
||||||
|
trim: true,
|
||||||
|
},
|
||||||
name: {
|
name: {
|
||||||
type: String,
|
type: String,
|
||||||
maxLength: [35, "name cannot exceed 25 characters"],
|
maxLength: [35, "name cannot exceed 25 characters"],
|
||||||
|
@ -91,6 +91,7 @@ export const uploadPrincipaldistributors = async (req, res) => {
|
|||||||
|
|
||||||
// Map headers from the Excel file to your schema
|
// Map headers from the Excel file to your schema
|
||||||
const headerMapping = {
|
const headerMapping = {
|
||||||
|
"PD ID (From SAP)": "uniqueId",
|
||||||
"Principal Distributor Name": "name",
|
"Principal Distributor Name": "name",
|
||||||
"Email": "email",
|
"Email": "email",
|
||||||
"Phone Number": "phone",
|
"Phone Number": "phone",
|
||||||
@ -128,6 +129,7 @@ export const uploadPrincipaldistributors = async (req, res) => {
|
|||||||
const validationErrors = new Set();
|
const validationErrors = new Set();
|
||||||
|
|
||||||
// Validate required fields
|
// Validate required fields
|
||||||
|
if (!item.uniqueId) missingFields.add("uniqueId");
|
||||||
if (!item.name) missingFields.add("name");
|
if (!item.name) missingFields.add("name");
|
||||||
if (!item.email) missingFields.add("email");
|
if (!item.email) missingFields.add("email");
|
||||||
if (!item.phone) missingFields.add("phone");
|
if (!item.phone) missingFields.add("phone");
|
||||||
@ -180,6 +182,7 @@ export const uploadPrincipaldistributors = async (req, res) => {
|
|||||||
// 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({
|
||||||
|
uniqueId: item.uniqueId || "N/A",
|
||||||
name: item.name || "N/A",
|
name: item.name || "N/A",
|
||||||
email: item.email || "N/A",
|
email: item.email || "N/A",
|
||||||
phone: item.phone || "N/A",
|
phone: item.phone || "N/A",
|
||||||
@ -193,35 +196,32 @@ export const uploadPrincipaldistributors = async (req, res) => {
|
|||||||
// Generate a password
|
// Generate a password
|
||||||
const password = generatePassword(item.name, item.email);
|
const password = generatePassword(item.name, item.email);
|
||||||
item.role = "principal-Distributor";
|
item.role = "principal-Distributor";
|
||||||
const currentYear = new Date().getFullYear().toString().slice(-2);
|
|
||||||
const randomChars = crypto.randomBytes(4).toString("hex").toUpperCase();
|
|
||||||
item.uniqueId = `${currentYear}-${randomChars}`;
|
|
||||||
|
|
||||||
// Check for existing user
|
// Check for existing user by uniqueId
|
||||||
let user = await User.findOne({ email: item.email });
|
let distributor = await User.findOne({ uniqueId: item.uniqueId });
|
||||||
|
|
||||||
if (user) {
|
if (distributor) {
|
||||||
// Track updated fields
|
// Track updated fields
|
||||||
const updatedFields = [];
|
const updatedFields = [];
|
||||||
const addressFields = ['panNumber', 'gstNumber', 'state','city', 'street', 'tradeName', 'postalCode'];
|
const addressFields = ['panNumber', 'gstNumber', 'state', 'city', 'street', 'tradeName', 'postalCode'];
|
||||||
const existingAddress = await ShippingAddress.findOne({ user: user._id });
|
const existingAddress = await ShippingAddress.findOne({ user: distributor._id });
|
||||||
|
|
||||||
// Check for changes in user details
|
// Check for changes in user details
|
||||||
let userUpdated = false;
|
let userUpdated = false;
|
||||||
if (user.name !== item.name) {
|
if (distributor.name !== item.name) {
|
||||||
updatedFields.push("name");
|
updatedFields.push("name");
|
||||||
user.name = item.name;
|
distributor.name = item.name;
|
||||||
userUpdated = true;
|
userUpdated = true;
|
||||||
}
|
}
|
||||||
if (user.phone !== item.phone.toString()) {
|
if (distributor.phone !== item.phone.toString()) {
|
||||||
updatedFields.push("phone");
|
updatedFields.push("phone");
|
||||||
user.phone = item.phone;
|
distributor.phone = item.phone;
|
||||||
userUpdated = true;
|
userUpdated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update user
|
// Update user
|
||||||
if (userUpdated) {
|
if (userUpdated) {
|
||||||
await user.save();
|
await distributor.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for changes in address details
|
// Check for changes in address details
|
||||||
@ -234,7 +234,7 @@ export const uploadPrincipaldistributors = async (req, res) => {
|
|||||||
panNumber: item.panNumber,
|
panNumber: item.panNumber,
|
||||||
tradeName: item.tradeName,
|
tradeName: item.tradeName,
|
||||||
gstNumber: item.gstNumber,
|
gstNumber: item.gstNumber,
|
||||||
user: user._id,
|
user: distributor._id,
|
||||||
};
|
};
|
||||||
|
|
||||||
let addressUpdated = false;
|
let addressUpdated = false;
|
||||||
@ -248,7 +248,7 @@ export const uploadPrincipaldistributors = async (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (addressUpdated) {
|
if (addressUpdated) {
|
||||||
await ShippingAddress.updateOne({ user: user._id }, addressData);
|
await ShippingAddress.updateOne({ user: distributor._id }, addressData);
|
||||||
if (addressUpdates.length > 0) {
|
if (addressUpdates.length > 0) {
|
||||||
updatedFields.push(`Address fields: ${addressUpdates.join(", ")}`);
|
updatedFields.push(`Address fields: ${addressUpdates.join(", ")}`);
|
||||||
}
|
}
|
||||||
@ -262,13 +262,13 @@ export const uploadPrincipaldistributors = async (req, res) => {
|
|||||||
// Add to updatedDistributors only if there are updated fields
|
// Add to updatedDistributors only if there are updated fields
|
||||||
if (updatedFields.length > 0) {
|
if (updatedFields.length > 0) {
|
||||||
updatedDistributors.push({
|
updatedDistributors.push({
|
||||||
...user._doc,
|
...distributor._doc,
|
||||||
updatedFields: updatedFields.join(", ")
|
updatedFields: updatedFields.join(", ")
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Create a new user
|
// Create a new user
|
||||||
user = new User({
|
distributor = new User({
|
||||||
name: item.name,
|
name: item.name,
|
||||||
email: item.email,
|
email: item.email,
|
||||||
phone: item.phone,
|
phone: item.phone,
|
||||||
@ -276,7 +276,7 @@ export const uploadPrincipaldistributors = async (req, res) => {
|
|||||||
role: item.role,
|
role: item.role,
|
||||||
uniqueId: item.uniqueId,
|
uniqueId: item.uniqueId,
|
||||||
});
|
});
|
||||||
await user.save();
|
await distributor.save();
|
||||||
|
|
||||||
// Send email with the new user details
|
// Send email with the new user details
|
||||||
await sendEmail({
|
await sendEmail({
|
||||||
@ -293,7 +293,7 @@ export const uploadPrincipaldistributors = async (req, res) => {
|
|||||||
`,
|
`,
|
||||||
});
|
});
|
||||||
|
|
||||||
newlyCreated.push(user._doc);
|
newlyCreated.push(distributor._doc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,7 +314,7 @@ export const uploadPrincipaldistributors = async (req, res) => {
|
|||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error processing file:", error);
|
console.error("Error processing file:", error);
|
||||||
res.status(500).json({ message: "Internal server error" });
|
res.status(500).json({ message: "Error processing file", error: error.message });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -394,12 +394,13 @@ export const uploadPrincipaldistributors = async (req, res) => {
|
|||||||
// };
|
// };
|
||||||
export const registerUser = async (req, res) => {
|
export const registerUser = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { name, email, phone, accessTo, role } = req.body;
|
const { name, email, phone, accessTo, role,PD_ID } = req.body;
|
||||||
// console.log(req.body);
|
// console.log(req.body);
|
||||||
const password = generatePassword(name, email);
|
const password = generatePassword(name, email);
|
||||||
// console.log(password);
|
// console.log(password);
|
||||||
// Check if user already exists
|
// Check if user already exists
|
||||||
let user = await User.findOne({ email });
|
let user = await User.findOne({ uniqueId: PD_ID });
|
||||||
|
// console.log(user);
|
||||||
if (user) {
|
if (user) {
|
||||||
// If user exists, update their details if needed
|
// If user exists, update their details if needed
|
||||||
user.name = name;
|
user.name = name;
|
||||||
@ -421,6 +422,7 @@ export const registerUser = async (req, res) => {
|
|||||||
|
|
||||||
// Create a new user if not found
|
// Create a new user if not found
|
||||||
user = new User({
|
user = new User({
|
||||||
|
uniqueId: PD_ID,
|
||||||
name,
|
name,
|
||||||
email,
|
email,
|
||||||
password,
|
password,
|
||||||
@ -428,11 +430,11 @@ export const registerUser = async (req, res) => {
|
|||||||
role,
|
role,
|
||||||
accessTo,
|
accessTo,
|
||||||
});
|
});
|
||||||
// console.log(user);
|
// console.log("user",user);
|
||||||
// Generate uniqueId
|
// // Generate uniqueId
|
||||||
const currentYear = new Date().getFullYear().toString().slice(-2);
|
// const currentYear = new Date().getFullYear().toString().slice(-2);
|
||||||
const randomChars = crypto.randomBytes(4).toString("hex").toUpperCase();
|
// const randomChars = crypto.randomBytes(4).toString("hex").toUpperCase();
|
||||||
user.uniqueId = `${currentYear}-${randomChars}`;
|
// user.uniqueId = `${currentYear}-${randomChars}`;
|
||||||
|
|
||||||
// Save the new user to the database
|
// Save the new user to the database
|
||||||
await user.save();
|
await user.save();
|
||||||
|
Loading…
Reference in New Issue
Block a user