product and pd multiple data upload with error handling done
This commit is contained in:
parent
1c4fce921c
commit
23b835cbf0
BIN
public/temp/tmp-1-1723179420558
Normal file
BIN
public/temp/tmp-1-1723179420558
Normal file
Binary file not shown.
BIN
public/temp/tmp-1-1723179631191
Normal file
BIN
public/temp/tmp-1-1723179631191
Normal file
Binary file not shown.
BIN
public/temp/tmp-1-1723183341603
Normal file
BIN
public/temp/tmp-1-1723183341603
Normal file
Binary file not shown.
BIN
public/temp/tmp-2-1723179559917
Normal file
BIN
public/temp/tmp-2-1723179559917
Normal file
Binary file not shown.
BIN
public/temp/tmp-2-1723179706921
Normal file
BIN
public/temp/tmp-2-1723179706921
Normal file
Binary file not shown.
BIN
public/temp/tmp-3-1723179795362
Normal file
BIN
public/temp/tmp-3-1723179795362
Normal file
Binary file not shown.
@ -56,7 +56,8 @@ export const uploadProducts = async (req, res) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const errors = [];
|
const errors = [];
|
||||||
const productsProcessed = [];
|
const newlyCreated = [];
|
||||||
|
const updatedProducts = [];
|
||||||
|
|
||||||
for (let i = 1; i < data.length; i++) {
|
for (let i = 1; i < data.length; i++) {
|
||||||
const row = data[i];
|
const row = data[i];
|
||||||
@ -85,12 +86,14 @@ export const uploadProducts = async (req, res) => {
|
|||||||
if (!GST) missingFields.add("GST");
|
if (!GST) missingFields.add("GST");
|
||||||
|
|
||||||
// Validate category
|
// Validate category
|
||||||
|
let categoryName = "";
|
||||||
if (category) {
|
if (category) {
|
||||||
const categoryDoc = await CategoryModel.findOne({
|
const categoryDoc = await CategoryModel.findOne({
|
||||||
categoryName: { $regex: new RegExp(`^${category.trim()}$`, "i") },
|
categoryName: { $regex: new RegExp(`^${category.trim()}$`, "i") },
|
||||||
}).exec();
|
}).exec();
|
||||||
if (categoryDoc) {
|
if (categoryDoc) {
|
||||||
item.category = categoryDoc._id;
|
item.category = categoryDoc._id;
|
||||||
|
categoryName = categoryDoc.categoryName;
|
||||||
} else {
|
} else {
|
||||||
notFoundErrors.add("category");
|
notFoundErrors.add("category");
|
||||||
}
|
}
|
||||||
@ -99,12 +102,14 @@ export const uploadProducts = async (req, res) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Validate GST
|
// Validate GST
|
||||||
|
let gstName = "";
|
||||||
if (GST) {
|
if (GST) {
|
||||||
const gstDoc = await Tax.findOne({
|
const gstDoc = await Tax.findOne({
|
||||||
name: { $regex: new RegExp(`^${GST}$`, "i") },
|
name: { $regex: new RegExp(`^${GST}$`, "i") },
|
||||||
}).exec();
|
}).exec();
|
||||||
if (gstDoc) {
|
if (gstDoc) {
|
||||||
item.GST = gstDoc._id;
|
item.GST = gstDoc._id;
|
||||||
|
gstName = gstDoc.name;
|
||||||
} else {
|
} else {
|
||||||
notFoundErrors.add("GST");
|
notFoundErrors.add("GST");
|
||||||
}
|
}
|
||||||
@ -127,6 +132,7 @@ export const uploadProducts = async (req, res) => {
|
|||||||
productName: name || "N/A",
|
productName: name || "N/A",
|
||||||
category: category || "N/A",
|
category: category || "N/A",
|
||||||
GST: GST || "N/A",
|
GST: GST || "N/A",
|
||||||
|
price: price || "N/A",
|
||||||
message: errorMessage.trim(),
|
message: errorMessage.trim(),
|
||||||
});
|
});
|
||||||
continue;
|
continue;
|
||||||
@ -142,24 +148,41 @@ export const uploadProducts = async (req, res) => {
|
|||||||
}).exec();
|
}).exec();
|
||||||
|
|
||||||
if (existingProduct) {
|
if (existingProduct) {
|
||||||
// Validate that the existing product can be updated
|
// Track changes
|
||||||
const updateErrors = [];
|
const updatedFields = [];
|
||||||
if (missingFields.size > 0) {
|
let updatedProduct = { ...existingProduct._doc };
|
||||||
updateErrors.push(`Missing fields: ${Array.from(missingFields).join(", ")}`);
|
|
||||||
|
// Fetch existing category name and GST name
|
||||||
|
const existingCategory = await CategoryModel.findById(existingProduct.category).exec();
|
||||||
|
const existingGST = await Tax.findById(existingProduct.GST).exec();
|
||||||
|
|
||||||
|
if (category && existingProduct.category.toString() !== item.category.toString()) {
|
||||||
|
updatedFields.push("category");
|
||||||
|
updatedProduct.category = categoryName;
|
||||||
|
} else {
|
||||||
|
updatedProduct.category = existingCategory ? existingCategory.categoryName : "";
|
||||||
}
|
}
|
||||||
if (notFoundErrors.size > 0) {
|
if (price !== undefined && price !== "" && existingProduct.price !== price) {
|
||||||
updateErrors.push(`Not found: ${Array.from(notFoundErrors).join(", ")}`);
|
updatedFields.push("price");
|
||||||
|
updatedProduct.price = price;
|
||||||
|
}
|
||||||
|
if (GST && existingProduct.GST.toString() !== item.GST.toString()) {
|
||||||
|
updatedFields.push("GST");
|
||||||
|
updatedProduct.GST = gstName;
|
||||||
|
} else {
|
||||||
|
updatedProduct.GST = existingGST ? existingGST.name : "";
|
||||||
|
}
|
||||||
|
if (description !== existingProduct.description) {
|
||||||
|
updatedFields.push("description");
|
||||||
|
updatedProduct.description = description;
|
||||||
|
}
|
||||||
|
if (special_instructions !== existingProduct.special_instructions) {
|
||||||
|
updatedFields.push("special_instructions");
|
||||||
|
updatedProduct.special_instructions = special_instructions;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updateErrors.length > 0) {
|
// Only update if there are changes
|
||||||
errors.push({
|
if (updatedFields.length > 0) {
|
||||||
productName: name,
|
|
||||||
message: updateErrors.join(". "),
|
|
||||||
});
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update existing product
|
|
||||||
try {
|
try {
|
||||||
await Product.updateOne(
|
await Product.updateOne(
|
||||||
{ _id: existingProduct._id },
|
{ _id: existingProduct._id },
|
||||||
@ -168,19 +191,23 @@ export const uploadProducts = async (req, res) => {
|
|||||||
category: item.category || existingProduct.category,
|
category: item.category || existingProduct.category,
|
||||||
price: price !== undefined && price !== "" ? price : existingProduct.price,
|
price: price !== undefined && price !== "" ? price : existingProduct.price,
|
||||||
GST: item.GST || existingProduct.GST,
|
GST: item.GST || existingProduct.GST,
|
||||||
description: description, // Ensure description is included
|
description: description,
|
||||||
special_instructions: special_instructions, // Ensure special_instructions is included
|
special_instructions: special_instructions,
|
||||||
product_Status: item.product_Status || existingProduct.product_Status || "Active",
|
product_Status: item.product_Status || existingProduct.product_Status || "Active",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
productsProcessed.push({ ...existingProduct._doc, ...item }); // Track updated product
|
updatedProducts.push({
|
||||||
|
...updatedProduct,
|
||||||
|
updatedFields: updatedFields.join(", "), // Track updated fields
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
errors.push({
|
errors.push({
|
||||||
productName: name,
|
productName: name,
|
||||||
message: "Failed to update product",
|
message: "Failed to update product",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,14 +218,18 @@ export const uploadProducts = async (req, res) => {
|
|||||||
category: item.category,
|
category: item.category,
|
||||||
price,
|
price,
|
||||||
GST: item.GST,
|
GST: item.GST,
|
||||||
description: description, // Ensure description is included
|
description: description,
|
||||||
special_instructions: special_instructions, // Ensure special_instructions is included
|
special_instructions: special_instructions,
|
||||||
product_Status: item.product_Status || "Active",
|
product_Status: item.product_Status || "Active",
|
||||||
addedBy: req.user._id,
|
addedBy: req.user._id,
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const newProduct = await Product.create(productData);
|
const newProduct = await Product.create(productData);
|
||||||
productsProcessed.push(newProduct); // Track new product
|
newlyCreated.push({
|
||||||
|
...newProduct._doc,
|
||||||
|
category: categoryName,
|
||||||
|
GST: gstName,
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
errors.push({
|
errors.push({
|
||||||
productName: name,
|
productName: name,
|
||||||
@ -215,8 +246,11 @@ export const uploadProducts = async (req, res) => {
|
|||||||
errors.length > 0
|
errors.length > 0
|
||||||
? "Products processed with errors!"
|
? "Products processed with errors!"
|
||||||
: "Products processed successfully!",
|
: "Products processed successfully!",
|
||||||
productsProcessed: productsProcessed.length, // Total processed products
|
newlyCreated: newlyCreated,
|
||||||
|
updatedProducts: updatedProducts,
|
||||||
errors,
|
errors,
|
||||||
|
newlyCreated,
|
||||||
|
updatedProducts,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error:", error);
|
console.error("Error:", error);
|
||||||
|
@ -110,7 +110,8 @@ export const uploadPrincipaldistributors = async (req, res) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const errors = [];
|
const errors = [];
|
||||||
const processedUsers = [];
|
const newlyCreated = [];
|
||||||
|
const updatedDistributors = [];
|
||||||
|
|
||||||
for (let i = 1; i < data.length; i++) {
|
for (let i = 1; i < data.length; i++) {
|
||||||
const row = data[i];
|
const row = data[i];
|
||||||
@ -195,14 +196,76 @@ export const uploadPrincipaldistributors = async (req, res) => {
|
|||||||
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();
|
||||||
item.uniqueId = `${currentYear}-${randomChars}`;
|
item.uniqueId = `${currentYear}-${randomChars}`;
|
||||||
|
|
||||||
// Check for existing user
|
// Check for existing user
|
||||||
let user = await User.findOne({ email: item.email });
|
let user = await User.findOne({ email: item.email });
|
||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
// Update existing user details
|
// Track updated fields
|
||||||
|
const updatedFields = [];
|
||||||
|
const addressFields = ['panNumber', 'gstNumber', 'state','city', 'street', 'tradeName', 'postalCode'];
|
||||||
|
const existingAddress = await ShippingAddress.findOne({ user: user._id });
|
||||||
|
|
||||||
|
// Check for changes in user details
|
||||||
|
let userUpdated = false;
|
||||||
|
if (user.name !== item.name) {
|
||||||
|
updatedFields.push("name");
|
||||||
user.name = item.name;
|
user.name = item.name;
|
||||||
|
userUpdated = true;
|
||||||
|
}
|
||||||
|
if (user.phone !== item.phone.toString()) {
|
||||||
|
updatedFields.push("phone");
|
||||||
user.phone = item.phone;
|
user.phone = item.phone;
|
||||||
|
userUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update user
|
||||||
|
if (userUpdated) {
|
||||||
await user.save();
|
await user.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: user._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: user._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({
|
||||||
|
...user._doc,
|
||||||
|
updatedFields: updatedFields.join(", ")
|
||||||
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Create a new user
|
// Create a new user
|
||||||
user = new User({
|
user = new User({
|
||||||
@ -229,35 +292,9 @@ export const uploadPrincipaldistributors = async (req, res) => {
|
|||||||
If you have not requested this email, please ignore it.
|
If you have not requested this email, please ignore it.
|
||||||
`,
|
`,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
newlyCreated.push(user._doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
fs.unlinkSync(filePath); // Clean up uploaded file
|
||||||
@ -267,12 +304,17 @@ export const uploadPrincipaldistributors = async (req, res) => {
|
|||||||
errors.length > 0
|
errors.length > 0
|
||||||
? "File processed with errors!"
|
? "File processed with errors!"
|
||||||
: "File processed successfully!",
|
: "File processed successfully!",
|
||||||
processedUsers: processedUsers.length, // Total processed users
|
processedUsers: {
|
||||||
|
newlyCreated: newlyCreated.length,
|
||||||
|
updatedDistributors: updatedDistributors.length
|
||||||
|
},
|
||||||
errors,
|
errors,
|
||||||
|
newlyCreated,
|
||||||
|
updatedDistributors
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error:", error);
|
console.error("Error processing file:", error);
|
||||||
res.status(500).json({ message: error.message || "Something went wrong!" });
|
res.status(500).json({ message: "Internal server error" });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user