From 692a69ee61b05bbcd8d647f63fa99ffd88ed6bf3 Mon Sep 17 00:00:00 2001 From: Sibunnayak Date: Fri, 23 Aug 2024 11:27:07 +0530 Subject: [PATCH] PD updated with add new field SBU --- app.js | 3 - public/uploads/Add-PD.xlsx | Bin 0 -> 11808 bytes resources/Products/ProductController.js | 263 --------------- resources/Tax/tax_controller.js | 77 ----- resources/Tax/tax_model.js | 14 - resources/Tax/tax_routes.js | 23 -- resources/user/userController.js | 418 ++++++++++++++++++------ resources/user/userModel.js | 5 +- 8 files changed, 317 insertions(+), 486 deletions(-) create mode 100644 public/uploads/Add-PD.xlsx delete mode 100644 resources/Tax/tax_controller.js delete mode 100644 resources/Tax/tax_model.js delete mode 100644 resources/Tax/tax_routes.js diff --git a/app.js b/app.js index 2a5385c..b7b75de 100644 --- a/app.js +++ b/app.js @@ -163,7 +163,6 @@ import CurrencyRoute from "./resources/Currency/CurrencyRoute.js"; import ConfigRouter from "./resources/setting/Configration/Config_routes.js"; -import TaxRouter from "./resources/Tax/tax_routes.js"; //specialties import SpecialtiesRouter from "./resources/Specialties/SpecialtiesRoute.js"; import ShippingAddressRoute from "./resources/ShippingAddresses/ShippingAddressRoute.js"; @@ -233,8 +232,6 @@ app.use("/api/language", LanguageRoute); //Purpose app.use("/api/purpose", PurposeRoute); app.use("/api/business", orderRoute); -//Tax -app.use("/api/tax", TaxRouter); //Currency Route app.use("/api/currency", CurrencyRoute); //config diff --git a/public/uploads/Add-PD.xlsx b/public/uploads/Add-PD.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..572c93135685fd38078c5f7d2166a451439bb21a GIT binary patch literal 11808 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 literal 0 HcmV?d00001 diff --git a/resources/Products/ProductController.js b/resources/Products/ProductController.js index dde518e..b4d91e7 100644 --- a/resources/Products/ProductController.js +++ b/resources/Products/ProductController.js @@ -3,275 +3,12 @@ import cloudinary from "../../Utils/cloudinary.js"; import { v4 as uuidv4 } from "uuid"; 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 XLSX from "xlsx"; import fs from "fs"; import path from "path"; import mongoose from "mongoose"; // 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) => { try { if (!req.files || !req.files.file) { diff --git a/resources/Tax/tax_controller.js b/resources/Tax/tax_controller.js deleted file mode 100644 index 15fcf38..0000000 --- a/resources/Tax/tax_controller.js +++ /dev/null @@ -1,77 +0,0 @@ -import { Tax } from "./tax_model.js"; - -export const addTax = async (req, res) => { - if (!req.user) { - return res.status(400).json({ message: "User Not Found" }); - } - const tax = new Tax({ - name: req.body.name, - tax: req.body.tax, - hsn_code: req.body.hsn_code, - }); - try { - const data = await tax.save(); - res.status(201).json({ message: "Success", data: data }); - } catch (error) { - res.status(500).json({ message: error.message ? error.message : "Something went Wrong" }); - } -}; - -export const updateTax = async (req, res) => { - if (!req.user) { - return res.status(400).json({ message: "User Not Found" }); - } - const id = req.params.id; - const queryObj = req.body; - - try { - const data = await Tax.findByIdAndUpdate(id, queryObj, { - new: true, - }); - res.status(200).json({ message: "Success", data: data }); - } catch (error) { - res.status(500).json({ message: error.message, message: "failed" }); - } -}; - -export const deleteTax = async (req, res) => { - if (!req.user) { - return res.status(400).json({ message: "User Not Found" }); - } - const id = req.params.id; - try { - const data = await Tax.findByIdAndDelete(id); - res.status(200).json({ message: "Success" }); - } catch (error) { - res.status(500).json({ message: error.message, message: "failed" }); - } -}; - -export const getTaxes = async (req, res) => { - if (!req.user) { - return res.status(400).json({ message: "User Not Found" }); - } - - try { - const data = await Tax.find().sort({ createdAt: -1 }); - res.status(200).json(data); - } catch (error) { - res.status(500).json({ message: error.message, message: "failed" }); - } -}; - -export const getTax = async (req, res) => { - if (!req.user) { - return res.status(400).json({ message: "User Not Found" }); - } - try { - let { id } = req.params; - const tax = await Tax.findById({ _id: id }); - return res.status(200).json(tax); - } catch (error) { - return res.status(504).json({ - status: "failed", - error, - }); - } -}; diff --git a/resources/Tax/tax_model.js b/resources/Tax/tax_model.js deleted file mode 100644 index fe6af8e..0000000 --- a/resources/Tax/tax_model.js +++ /dev/null @@ -1,14 +0,0 @@ -import mongoose from "mongoose"; - -const { Schema, model } = mongoose; - -const TaxSchema = new Schema( - { - name: String, - hsn_code: Number, - tax: Number, - }, - { timestamps: true } -); - -export const Tax = model("Tax", TaxSchema); diff --git a/resources/Tax/tax_routes.js b/resources/Tax/tax_routes.js deleted file mode 100644 index 7bcae6a..0000000 --- a/resources/Tax/tax_routes.js +++ /dev/null @@ -1,23 +0,0 @@ -import { Router } from "express"; -import { authorizeRoles, isAuthenticatedUser } from "../../middlewares/auth.js"; -import { - addTax, - updateTax, - deleteTax, - getTaxes, - getTax, -} from "./tax_controller.js"; -const router = Router(); - -router - .route("/add_tax") - .post(isAuthenticatedUser, authorizeRoles("admin", "Employee"), addTax); -router - .route("/update_tax/:id") - .patch(isAuthenticatedUser, authorizeRoles("admin", "Employee"), updateTax); -router - .route("/delete_tax/:id") - .delete(isAuthenticatedUser, authorizeRoles("admin", "Employee"), deleteTax); -router.route("/view_tax/:id").get(isAuthenticatedUser, getTax); -router.route("/view_tax").get(isAuthenticatedUser, getTaxes); -export default router; diff --git a/resources/user/userController.js b/resources/user/userController.js index d4eab78..5e64cef 100644 --- a/resources/user/userController.js +++ b/resources/user/userController.js @@ -59,6 +59,278 @@ const generatePassword = (name, email) => { return password; }; +// export const uploadPrincipaldistributors = 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 = { +// "PD ID (From SAP)": "uniqueId", +// "SBU":"SBU", +// "Principal Distributor Name": "name", +// "Email": "email", +// "Phone Number": "phone", +// "PAN Number": "panNumber", +// "Trade Name": "tradeName", +// "GST Number": "gstNumber", +// "State": "state", +// "City": "city", +// "Street": "street", +// "Pincode": "postalCode", +// }; + +// 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 updatedDistributors = []; + +// 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 validationErrors = new Set(); + +// // Validate required fields +// if (!item.uniqueId) missingFields.add("uniqueId"); +// if(!item.SBU) missingFields.add("SBU"); +// if (!item.name) missingFields.add("name"); +// if (!item.email) missingFields.add("email"); +// if (!item.phone) missingFields.add("phone"); +// if (!item.panNumber) missingFields.add("panNumber"); +// if (!item.tradeName) missingFields.add("tradeName"); +// if (!item.gstNumber) missingFields.add("gstNumber"); +// if (!item.state) missingFields.add("state"); +// if (!item.city) missingFields.add("city"); +// if (!item.street) missingFields.add("street"); +// if (!item.postalCode) missingFields.add("postalCode"); + +// // Check email validity +// if (item.email && !validator.isEmail(item.email)) { +// validationErrors.add("incorrect mail"); +// } + +// // Validate mobile number +// if (item.phone && !/^\d{10}$/.test(item.phone)) { +// validationErrors.add("Invalid Mobile Number (should be 10 digits)"); +// } + +// // Check GST, PAN, and postal code validation +// item.panNumber = item.panNumber ? item.panNumber.toUpperCase() : ""; +// item.gstNumber = item.gstNumber ? item.gstNumber.toUpperCase() : ""; + +// // Validate PAN Number +// if (item.panNumber && !/^[A-Z]{5}[0-9]{4}[A-Z]{1}$/.test(item.panNumber)) { +// validationErrors.add("Invalid PAN Number"); +// } + +// // Validate GST Number +// if (item.gstNumber && !/^(\d{2}[A-Z]{5}\d{4}[A-Z]{1}\d[Z]{1}[A-Z\d]{1})$/.test(item.gstNumber)) { +// validationErrors.add("Invalid GST Number"); +// } + +// // Validate Postal Code +// if (item.postalCode && !/^\d{6}$/.test(item.postalCode)) { +// validationErrors.add("Invalid Postal Code"); +// } + +// // Combine all errors into a single message +// let errorMessage = ""; +// if (missingFields.size > 0) { +// errorMessage += `Missing fields: ${Array.from(missingFields).join(", ")}. `; +// } +// if (validationErrors.size > 0) { +// errorMessage += `Validation errors: ${Array.from(validationErrors).join(", ")}.`; +// } + +// // If there are errors, push them to the errors array +// if (errorMessage.trim()) { +// errors.push({ +// uniqueId: item.uniqueId || "N/A", +// SBU:item.SBU || "N/A", +// name: item.name || "N/A", +// email: item.email || "N/A", +// phone: item.phone || "N/A", +// panNumber: item.panNumber || "N/A", +// gstNumber: item.gstNumber || "N/A", +// message: errorMessage.trim(), +// }); +// continue; +// } + +// // Generate a password +// const password = generatePassword(item.name, item.email); +// item.role = "principal-Distributor"; + +// // Check for existing user by uniqueId +// let distributor = await User.findOne({ uniqueId: item.uniqueId }); + +// if (distributor) { +// // Track updated fields +// const updatedFields = []; +// const addressFields = ['panNumber', 'gstNumber', 'state', 'city', 'street', 'tradeName', 'postalCode']; +// const existingAddress = await ShippingAddress.findOne({ user: distributor._id }); + +// // Check for changes in user details +// let userUpdated = false; +// if (distributor.name !== item.name) { +// updatedFields.push("name"); +// distributor.name = item.name; +// userUpdated = true; +// } +// if (distributor.email !== item.email) { +// updatedFields.push("email"); +// distributor.email = item.email; +// userUpdated = true; +// } +// if(distributor.SBU !== item.SBU){ +// updatedFields.push("SBU"); +// distributor.SBU = item.SBU; +// userUpdated = true; +// } +// if (distributor.phone !== item.phone.toString()) { +// updatedFields.push("phone"); +// distributor.phone = item.phone; +// userUpdated = true; +// } + +// // Update user +// if (userUpdated) { +// await distributor.save(); +// } + +// // Check for changes in address details +// const addressData = { +// street: item.street, +// city: item.city, +// state: item.state, +// postalCode: item.postalCode.toString(), +// country: "India", // Default country +// panNumber: item.panNumber, +// tradeName: item.tradeName, +// gstNumber: item.gstNumber, +// user: distributor._id, +// }; + +// let addressUpdated = false; +// if (existingAddress) { +// const addressUpdates = []; +// addressFields.forEach(field => { +// if (existingAddress[field] !== addressData[field]) { +// addressUpdates.push(field); +// addressUpdated = true; +// } +// }); + +// if (addressUpdated) { +// await ShippingAddress.updateOne({ user: distributor._id }, addressData); +// if (addressUpdates.length > 0) { +// updatedFields.push(`Address fields: ${addressUpdates.join(", ")}`); +// } +// } +// } else { +// // Create new address +// await ShippingAddress.create(addressData); +// updatedFields.push("New address created"); +// } + +// // Add to updatedDistributors only if there are updated fields +// if (updatedFields.length > 0) { +// updatedDistributors.push({ +// ...distributor._doc, +// updatedFields: updatedFields.join(", ") +// }); +// } +// } else { +// // Create a new user +// distributor = new User({ +// name: item.name, +// SBU:item.SBU, +// email: item.email, +// phone: item.phone, +// password, +// role: item.role, +// uniqueId: item.uniqueId, +// }); +// await distributor.save(); + +// // Send email with the new user details +// await sendEmail({ +// to: item.email, +// from: process.env.SEND_EMAIL_FROM, +// subject: `Cheminova Account Created`, +// html: ` +// Your Principal Distributor Account is created successfully. +//
Name: ${item.name}
+//
Mobile Number: ${item.phone}
+//
Password: ${password}

+// Click here to login

+// If you have not requested this email, please ignore it. +// `, +// }); + +// newlyCreated.push(distributor._doc); +// } +// } + +// fs.unlinkSync(filePath); // Clean up uploaded file + +// res.status(201).json({ +// message: +// errors.length > 0 +// ? "File processed with errors!" +// : "File processed successfully!", +// processedUsers: { +// newlyCreated: newlyCreated.length, +// updatedDistributors: updatedDistributors.length +// }, +// errors, +// newlyCreated, +// updatedDistributors +// }); +// } catch (error) { +// console.error("Error processing file:", error); +// res.status(500).json({ message: "Error processing file", error: error.message }); +// } +// }; export const uploadPrincipaldistributors = async (req, res) => { try { if (!req.files || !req.files.file) { @@ -92,6 +364,7 @@ export const uploadPrincipaldistributors = async (req, res) => { // Map headers from the Excel file to your schema const headerMapping = { "PD ID (From SAP)": "uniqueId", + "SBU":"SBU", "Principal Distributor Name": "name", "Email": "email", "Phone Number": "phone", @@ -130,6 +403,7 @@ export const uploadPrincipaldistributors = async (req, res) => { // Validate required fields if (!item.uniqueId) missingFields.add("uniqueId"); + if(!item.SBU) missingFields.add("SBU"); if (!item.name) missingFields.add("name"); if (!item.email) missingFields.add("email"); if (!item.phone) missingFields.add("phone"); @@ -183,6 +457,7 @@ export const uploadPrincipaldistributors = async (req, res) => { if (errorMessage.trim()) { errors.push({ uniqueId: item.uniqueId || "N/A", + SBU:item.SBU || "N/A", name: item.name || "N/A", email: item.email || "N/A", phone: item.phone || "N/A", @@ -213,6 +488,16 @@ export const uploadPrincipaldistributors = async (req, res) => { distributor.name = item.name; userUpdated = true; } + if (distributor.email !== item.email) { + updatedFields.push("email"); + distributor.email = item.email; + userUpdated = true; + } + if(distributor.SBU !== item.SBU){ + updatedFields.push("SBU"); + distributor.SBU = item.SBU; + userUpdated = true; + } if (distributor.phone !== item.phone.toString()) { updatedFields.push("phone"); distributor.phone = item.phone; @@ -270,6 +555,7 @@ export const uploadPrincipaldistributors = async (req, res) => { // Create a new user distributor = new User({ name: item.name, + SBU: item.SBU, email: item.email, phone: item.phone, password, @@ -278,123 +564,44 @@ export const uploadPrincipaldistributors = async (req, res) => { }); await distributor.save(); - // Send email with the new user details - await sendEmail({ - to: item.email, - from: process.env.SEND_EMAIL_FROM, - subject: `Cheminova Account Created`, - html: ` - Your Principal Distributor Account is created successfully. -
Name: ${item.name}
-
Mobile Number: ${item.phone}
-
Password: ${password}

- Click here to login

- If you have not requested this email, please ignore it. - `, - }); + // Now create the address for the new user + const addressData = { + street: item.street, + city: item.city, + state: item.state, + postalCode: item.postalCode.toString(), + country: "India", // Default country + panNumber: item.panNumber, + tradeName: item.tradeName, + gstNumber: item.gstNumber, + user: distributor._id, // Use the saved user's ID + }; + const newAddress = await ShippingAddress.create(addressData); - newlyCreated.push(distributor._doc); + // Push both the distributor and the addressData to the newlyCreated array + newlyCreated.push({ + distributor, + address: newAddress, + }); } } - fs.unlinkSync(filePath); // Clean up uploaded file - - res.status(201).json({ - message: - errors.length > 0 - ? "File processed with errors!" - : "File processed successfully!", - processedUsers: { - newlyCreated: newlyCreated.length, - updatedDistributors: updatedDistributors.length - }, - errors, + res.status(200).json({ + message: "File processed successfully", newlyCreated, - updatedDistributors + updatedDistributors, + errors, }); } catch (error) { - console.error("Error processing file:", error); - res.status(500).json({ message: "Error processing file", error: error.message }); + console.error(error); + res.status(500).json({ message: "Internal Server Error" }); } }; // 1.Register a User -// export const registerUser = async (req, res) => { -// try { -// const { name, email, password, phone, accessTo, role } = req.body; -// // console.log("this is the password ", password, name, req.body); - -// let findUser = await User.findOne({ email }); -// if (findUser) { -// return res -// .status(400) -// .json({ success: false, message: "User already exists" }); -// } -// if (req.files) { -// const files = req.files.avatar; -// const myCloud = await cloudinary.uploader.upload( -// files.tempFilePath, -// { -// folder: "Cheminova/user-image", -// }, -// function (error, result) { -// result, error; -// } -// ); -// } - -// const user = await User.create({ -// name, -// email, -// password, -// phone, -// role, -// accessTo, -// // avatar: { -// // public_id: myCloud.public_id, -// // url: myCloud.secure_url, -// // }, -// }); -// // const emailData = await RegisterEmail.find(); -// // let emailSubject = emailData[0]?.subject; -// // let emailDescription = emailData[0]?.description; -// const config = await Config.find(); -// let appName = config[0]?.appName; - -// // await sendEmail({ -// // to: `${email}`, // Change to your recipient - -// // from: `${process.env.SEND_EMAIL_FROM}`, // Change to your verified sender - -// // subject: `Welcome to Cheminova - Let the Shopping Begin!`, -// // html: `

Welcome to ${appName} - Let the Shopping Begin!

-// // Hey ${name}, - -// //

- -// // Welcome to Cheminova - Let the Shopping Begin! -// //

-// //
-// //

You can login into :${role === "Employee" || role === "admin" -// // ? `https://admin.smellika.com/` -// // : `https://smellika.com` -// // }

-// //
-// //

Below are your login credentials:

-// //

Email: ${email}

-// //

Password: ${password}

-// // Happy shopping,
- -// // Team ${appName}`, -// // }); -// sendToken(user, 201, res); -// } catch (e) { -// return res.status(400).json({ success: false, message: e.message }); -// } -// }; export const registerUser = async (req, res) => { try { - const { name, email, phone, accessTo, role,PD_ID } = req.body; + const { name, email, phone, accessTo, role,PD_ID,SBU } = req.body; // console.log(req.body); const password = generatePassword(name, email); // console.log(password); @@ -408,7 +615,7 @@ export const registerUser = async (req, res) => { user.phone = phone; user.role = role; user.accessTo = accessTo; - + user.SBU=SBU; // Save updates await user.save(); // console.log("finduser", user); @@ -423,6 +630,7 @@ export const registerUser = async (req, res) => { // Create a new user if not found user = new User({ uniqueId: PD_ID, + SBU, name, email, password, diff --git a/resources/user/userModel.js b/resources/user/userModel.js index b79422d..fbe6c36 100644 --- a/resources/user/userModel.js +++ b/resources/user/userModel.js @@ -13,11 +13,14 @@ const userSchema = new mongoose.Schema( unique: true, required: true, }, + SBU: { + type: String, + required: [true, "Please Enter Your SBU"], + }, name: { type: String, required: [true, "Please Enter Your Name"], maxLength: [30, "Name cannot exceed 30 characters"], - minLength: [4, "Name should have more than 4 characters"], }, email: { type: String,