This commit is contained in:
ROSHAN GARG 2024-08-09 11:07:26 +05:30
commit 45d957241e
5 changed files with 316 additions and 29 deletions

View File

@ -69,19 +69,10 @@ export const AddshippingAddressByAdmin = async (req, res) => {
tradeName,
gstNumber,
} = req.body;
// console.log(req.body);
// console.log(req.params._id);
// Validate required fields
if (!street || !city || !state || !postalCode || !panNumber) {
return res
.status(400)
.json({ msg: "Please provide all required fields" });
}
// Validate PAN number format
const panNumberRegex = /^[A-Z]{5}[0-9]{4}[A-Z]{1}$/;
if (!panNumberRegex.test(panNumber)) {
return res.status(400).json({ message: "Invalid PAN number format" });
return res.status(400).json({ msg: "Please provide all required fields" });
}
// Create shipping address object
@ -96,17 +87,28 @@ export const AddshippingAddressByAdmin = async (req, res) => {
gstNumber,
user: req.params._id, // Assuming req.params._id contains the correct user ID
});
// console.log(newAddress);
res.status(201).json({
success: true,
address: newAddress,
message: "Shipping address added successfully",
});
} catch (error) {
console.error("Error creating shipping address:", error.message);
// console.error("Error creating shipping address:", error.message);
// Check for validation errors
if (error.name === 'ValidationError') {
const errorMessages = Object.values(error.errors).map(err => err.message);
return res.status(400).json({
success: false,
message: errorMessages.join(", "),
});
}
// General error
res.status(500).json({
success: false,
message: error.message ? error.message : "Something went wrong",
message: error.message || "Something went wrong",
});
}
};

View File

@ -28,7 +28,12 @@ const shippingAddressSchema = new mongoose.Schema(
type: String,
required: true,
trim: true,
match: /^\d{6}$/,
validate: {
validator: function (v) {
return /^\d{6}$/.test(v);
},
message: "Postal code must be a 6-digit number",
},
},
country: {
type: String,
@ -37,22 +42,27 @@ const shippingAddressSchema = new mongoose.Schema(
panNumber: {
type: String,
required: true,
set: v => v.toUpperCase(), // Convert to uppercase before saving
validate: {
validator: function (v) {
return /^[A-Z]{5}[0-9]{4}[A-Z]{1}$/.test(v);
},
message: props => `${props.value} is not a valid PAN number!`,
},
},
tradeName: {
type: String,
required: true,
},
gstNumber: {
type: String,
required: true,
set: v => v.toUpperCase(),
validate: {
validator: function (v) {
// Check if gstNumber is provided before applying validation
if (v && v.trim().length > 0) {
return /^(\d{2}[A-Z]{5}\d{4}[A-Z]{1}\d[Z]{1}[A-Z\d]{1})$/.test(v);
}
// If gstNumber is not provided, it's considered valid
return true;
return /^(\d{2}[A-Z]{5}\d{4}[A-Z]{1}\d[Z]{1}[A-Z\d]{1})$/.test(v);
},
message: (props) => `${props.value} is not a valid GST number!`,
message: props => `${props.value} is not a valid GST number!`,
},
},
isDefault: {

View File

@ -16,7 +16,7 @@ router
.route("/admin/new/:_id")
.post(
isAuthenticatedUser,
authorizeRoles("admin", "Employee"),
authorizeRoles("admin"),
AddshippingAddressByAdmin
);

View File

@ -9,6 +9,273 @@ import password from "secure-random-password";
import { Order } from "../Orders/orderModel.js";
import { RegisterEmail } from "../EmailCMS/RegisterEmail/registerEmailModal.js";
import { Config } from "../setting/Configration/Config_model.js";
import XLSX from "xlsx";
import fs from "fs";
import path from "path";
import validator from 'validator';
import ShippingAddress from "../ShippingAddresses/ShippingAddressModel.js";
const generatePassword = (name, email) => {
// Combine name and email, and convert to lowercase
const combinedStr = (name + email).toLowerCase();
// Define character pools
const specialChars = "@#*";
const numbers = "0123456789";
const alphaLower = combinedStr.match(/[a-z]/g) || [];
const alphaUpper = combinedStr.match(/[A-Z]/g) || [];
// Ensure at least one character from each category
const specialChar = specialChars.charAt(
Math.floor(Math.random() * specialChars.length)
);
const numberChar = numbers.charAt(Math.floor(Math.random() * numbers.length));
const lowerChar =
alphaLower.length > 0
? alphaLower[Math.floor(Math.random() * alphaLower.length)]
: String.fromCharCode(Math.floor(Math.random() * 26) + 97);
const upperChar =
alphaUpper.length > 0
? alphaUpper[Math.floor(Math.random() * alphaUpper.length)]
: String.fromCharCode(Math.floor(Math.random() * 26) + 65);
// Combine required characters
let passwordChars = [specialChar, numberChar, lowerChar, upperChar];
// Fill remaining positions with random characters from the combined string
const allChars = combinedStr + specialChars + numbers;
while (passwordChars.length < 8) {
passwordChars.push(
allChars.charAt(Math.floor(Math.random() * allChars.length))
);
}
// Shuffle characters to ensure randomness
passwordChars = passwordChars.sort(() => Math.random() - 0.5);
// Generate password of length 8
const password = passwordChars.slice(0, 8).join("");
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 = {
"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 processedUsers = [];
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.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({
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";
const currentYear = new Date().getFullYear().toString().slice(-2);
const randomChars = crypto.randomBytes(4).toString("hex").toUpperCase();
item.uniqueId = `${currentYear}-${randomChars}`;
// Check for existing user
let user = await User.findOne({ email: item.email });
if (user) {
// Update existing user details
user.name = item.name;
user.phone = item.phone;
await user.save();
} else {
// Create a new user
user = new User({
name: item.name,
email: item.email,
phone: item.phone,
password,
role: item.role,
uniqueId: item.uniqueId,
});
await user.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.
<br/>Name: <strong>${item.name}</strong><br/>
<br/>Mobile Number: <strong>${item.phone}</strong><br/>
<br/>Password: <strong>${password}</strong><br/><br/>
<a href="${process.env.PD_APP_URL}/login">Click here to login</a><br/><br/>
If you have not requested this email, please ignore it.
`,
});
}
// Create or update shipping address
const addressData = {
street: item.street,
city: item.city,
state: item.state,
postalCode: item.postalCode,
country: "India", // Default country
panNumber: item.panNumber,
tradeName: item.tradeName,
gstNumber: item.gstNumber,
user: user._id,
};
let existingAddress = await ShippingAddress.findOne({ user: user._id });
if (existingAddress) {
// Update existing address
await ShippingAddress.updateOne({ user: user._id }, addressData);
} else {
// Create new address
await ShippingAddress.create(addressData);
}
processedUsers.push({
...user._doc,
...addressData,
});
}
fs.unlinkSync(filePath); // Clean up uploaded file
res.status(201).json({
message:
errors.length > 0
? "File processed with errors!"
: "File processed successfully!",
processedUsers: processedUsers.length, // Total processed users
errors,
});
} catch (error) {
console.error("Error:", error);
res.status(500).json({ message: error.message || "Something went wrong!" });
}
};
// 1.Register a User
// export const registerUser = async (req, res) => {
// try {
@ -85,21 +352,23 @@ import { Config } from "../setting/Configration/Config_model.js";
// };
export const registerUser = async (req, res) => {
try {
const { name, email, password, phone, accessTo, role } = req.body;
const { name, email, phone, accessTo, role } = req.body;
// console.log(req.body);
const password = generatePassword(name, email);
// console.log(password);
// Check if user already exists
let user = await User.findOne({ email });
if (user) {
// If user exists, update their details if needed
user.name = name;
user.password = password; // In a real application, you should hash this
// user.password = password; // In a real application, you should hash this
user.phone = phone;
user.role = role;
user.accessTo = accessTo;
// Save updates
await user.save();
// console.log("finduser", user);
// Respond with success and userId
return res.status(200).json({
success: true,
@ -117,7 +386,7 @@ export const registerUser = async (req, res) => {
role,
accessTo,
});
// console.log(user);
// Generate uniqueId
const currentYear = new Date().getFullYear().toString().slice(-2);
const randomChars = crypto.randomBytes(4).toString("hex").toUpperCase();

View File

@ -14,6 +14,7 @@ import {
getAllEmployee,
deleteEmployeeById,
updateEmployeeById,
uploadPrincipaldistributors,
} from "./userController.js";
import { isAuthenticatedUser, authorizeRoles } from "../../middlewares/auth.js";
@ -30,7 +31,12 @@ router.route("/user/password/reset/:token").put(resetPassword);
router.route("/user/logout").get(logout);
router.route("/user/details").get(isAuthenticatedUser, getUserDetails);
router
.route('/principaldistributor/upload').post(
isAuthenticatedUser,
authorizeRoles('admin'),
uploadPrincipaldistributors
);
router
.route("/admin/users")
.get(isAuthenticatedUser, authorizeRoles("admin", "Employee"), getAllUser);