diff --git a/app.js b/app.js index 12e65de..c5a134b 100644 --- a/app.js +++ b/app.js @@ -169,6 +169,7 @@ import ConfigRouter from "./resources/setting/Configration/Config_routes.js"; //specialties import SpecialtiesRouter from "./resources/Specialties/SpecialtiesRoute.js"; import ShippingAddressRoute from "./resources/ShippingAddresses/ShippingAddressRoute.js"; +import RdShippingAddressRoute from "./resources/ShippingAddressesRD/RDShippingAddressRoute.js"; import stripeRoute from "./resources/StripePayment/stripeRoute.js"; import SeoRoute from "./resources/SEO&Analytics/SEORouter.js"; @@ -230,6 +231,8 @@ app.use("/api/content", ContentRoute); // User Address app.use("/api/user-address", UserAddressRoute); app.use("/api/shipping/address", ShippingAddressRoute); +//Shipping Address of RD +app.use("/api/rd/shipping/address", RdShippingAddressRoute); //SalesCoOrdinator Routes app.use("/api/salescoordinator", SalesCoOrdinatorRoute); // Kyc Routes diff --git a/public/temp/tmp-1-1729057335683 b/public/temp/tmp-1-1729057335683 new file mode 100644 index 0000000..37d3563 Binary files /dev/null and b/public/temp/tmp-1-1729057335683 differ diff --git a/public/temp/tmp-2-1729057335686 b/public/temp/tmp-2-1729057335686 new file mode 100644 index 0000000..37d3563 Binary files /dev/null and b/public/temp/tmp-2-1729057335686 differ diff --git a/public/temp/tmp-3-1729057335689 b/public/temp/tmp-3-1729057335689 new file mode 100644 index 0000000..37d3563 Binary files /dev/null and b/public/temp/tmp-3-1729057335689 differ diff --git a/public/temp/tmp-4-1729057335692 b/public/temp/tmp-4-1729057335692 new file mode 100644 index 0000000..37d3563 Binary files /dev/null and b/public/temp/tmp-4-1729057335692 differ diff --git a/public/temp/tmp-5-1729057335695 b/public/temp/tmp-5-1729057335695 new file mode 100644 index 0000000..37d3563 Binary files /dev/null and b/public/temp/tmp-5-1729057335695 differ diff --git a/public/temp/tmp-6-1729057335698 b/public/temp/tmp-6-1729057335698 new file mode 100644 index 0000000..37d3563 Binary files /dev/null and b/public/temp/tmp-6-1729057335698 differ diff --git a/public/uploads/Add-PD.xlsx b/public/uploads/Add-PD.xlsx index b17fe24..eb4aded 100644 Binary files a/public/uploads/Add-PD.xlsx and b/public/uploads/Add-PD.xlsx differ diff --git a/public/uploads/Add-RD.xlsx b/public/uploads/Add-RD.xlsx index 38576dd..3c9f1f3 100644 Binary files a/public/uploads/Add-RD.xlsx and b/public/uploads/Add-RD.xlsx differ diff --git a/resources/KYC/KycController.js b/resources/KYC/KycController.js index 943f109..62c52d7 100644 --- a/resources/KYC/KycController.js +++ b/resources/KYC/KycController.js @@ -9,6 +9,7 @@ import { Notification } from "../Notification/notificationModal.js"; import RetailDistributor from "../RetailDistributor/RetailDistributorModel.js"; import { generatePassword } from "../../Utils/generatepassword.js"; import sendEmail, { sendOtp } from "../../Utils/sendEmail.js"; +import ShippingAddressRD from "../ShippingAddressesRD/RDShippingAddressModel.js"; export const createKyc = async (req, res) => { const { name, @@ -244,7 +245,22 @@ export const createretaildistributor = async (req, res) => { password, }; const retailDistributor = new RetailDistributor(retailDistributorData); - await retailDistributor.save(); + const newRd = await retailDistributor.save(); + // Now create the address for the new user + const addressData = { + Name: name, + phoneNumber: mobile_number, + street: address, + city: city, + state: state, + postalCode: pincode, + district: district, + country: "India", // Default country + tradeName: trade_name, + user: newRd._id, // Use the saved user's ID + isDefault: true, + }; + await ShippingAddressRD.create(addressData); // Send email with the new password await sendEmail({ to: `${email}`, // Change to your recipient @@ -442,8 +458,22 @@ export const updateKycStatus = async (req, res) => { }; const retailDistributor = new RetailDistributor(retailDistributorData); - await retailDistributor.save(); - + const newRd = await retailDistributor.save(); + // Now create the address for the new user + const addressData = { + Name: kyc.name, + phoneNumber: kyc.mobile_number, + street: kyc.address, + city: kyc.city, + state: kyc.state, + postalCode: kyc.pincode, + district: kyc.district, + country: "India", // Default country + tradeName: kyc.trade_name, + user: newRd._id, // Use the saved user's ID + isDefault: true, + }; + await ShippingAddressRD.create(addressData); // Send email with the new password await sendEmail({ to: kyc.email, diff --git a/resources/Orders/CheckoutController.js b/resources/Orders/CheckoutController.js index b7eb5b4..b4790ae 100644 --- a/resources/Orders/CheckoutController.js +++ b/resources/Orders/CheckoutController.js @@ -110,9 +110,8 @@ export const createOrderCheckout = async (req, res) => { })); let addss = await ShippingAddress.findById(address); let shipping = { - first_Name: addss.first_Name, - last_Name: addss.last_Name, - phone_Number: addss.phone_Number, + Name: addss.Name, + phoneNumber: addss.phoneNumber, street: addss.street, city: addss.city, state: addss.state, diff --git a/resources/Orders/PosCheckoutController.js b/resources/Orders/PosCheckoutController.js index fd1ee6b..c9cd38b 100644 --- a/resources/Orders/PosCheckoutController.js +++ b/resources/Orders/PosCheckoutController.js @@ -43,9 +43,8 @@ export const poscreateOrderCheckout = async (req, res) => { let addss = await ShippingAddress.findById(address); let shipping = { - first_Name: addss.first_Name, - last_Name: addss?.last_Name, - phone_Number: addss?.phone_Number, + Name: addss.Name, + phoneNumber: addss?.phoneNumber, street: addss?.street, city: addss?.city, state: addss?.state, diff --git a/resources/Orders/RazerPayCheckoutController.js b/resources/Orders/RazerPayCheckoutController.js index 883dd06..2ea55ca 100644 --- a/resources/Orders/RazerPayCheckoutController.js +++ b/resources/Orders/RazerPayCheckoutController.js @@ -180,9 +180,8 @@ export const checkout = async (req, res) => { let addss = await ShippingAddress.findById(address); let shipping = { - first_Name: addss.first_Name, - last_Name: addss?.last_Name, - phone_Number: addss?.phone_Number, + Name: addss.Name, + phoneNumber: addss?.phoneNumber, street: addss?.street, city: addss?.city, state: addss?.state, @@ -662,9 +661,8 @@ export const handlePayment = async (req, res) => { let addss = await ShippingAddress.findById(address); // console.log(addss?.postalCode); let shipping = { - first_Name: addss.first_Name, - last_Name: addss.last_Name, - phone_Number: addss.phone_Number, + Name: addss.Name, + phoneNumber: addss.phoneNumber, street: addss.street, city: addss.city, state: addss.state, diff --git a/resources/Orders/StripeCheckOutController.js b/resources/Orders/StripeCheckOutController.js index f08784b..c992303 100644 --- a/resources/Orders/StripeCheckOutController.js +++ b/resources/Orders/StripeCheckOutController.js @@ -51,9 +51,8 @@ export const handlePayment = async (req, res) => { let addss = await ShippingAddress.findById(address); let shipping = { - first_Name: addss.first_Name, - last_Name: addss.last_Name, - phone_Number: addss.phone_Number, + Name: addss.Name, + phoneNumber: addss.phoneNumber, street: addss.street, city: addss.city, state: addss.state, diff --git a/resources/Products/ProductController.js b/resources/Products/ProductController.js index b4d91e7..a9b881c 100644 --- a/resources/Products/ProductController.js +++ b/resources/Products/ProductController.js @@ -73,6 +73,10 @@ export const uploadProducts = async (req, res) => { for (let i = 1; i < data.length; i++) { const row = data[i]; + // Skip the row if it's completely empty + if (row.every((cell) => cell === undefined || cell === "")) { + continue; + } const item = {}; headers.forEach((header, index) => { @@ -83,7 +87,9 @@ 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()); + const hasValidData = Object.values(item).some( + (value) => value && value.trim() + ); if (!hasValidData) { continue; } diff --git a/resources/RetailDistributor/RetailDistributorController.js b/resources/RetailDistributor/RetailDistributorController.js index 40ddb9a..488234d 100644 --- a/resources/RetailDistributor/RetailDistributorController.js +++ b/resources/RetailDistributor/RetailDistributorController.js @@ -10,6 +10,7 @@ import { generatePassword } from "../../Utils/generatepassword.js"; import XLSX from "xlsx"; import fs from "fs"; import path from "path"; +import ShippingAddressRD from "../ShippingAddressesRD/RDShippingAddressModel.js"; export const uploadRetaildistributors = async (req, res) => { try { @@ -76,6 +77,10 @@ export const uploadRetaildistributors = async (req, res) => { for (let i = 1; i < data.length; i++) { const row = data[i]; + // Skip the row if it's completely empty + if (row.every((cell) => cell === undefined || cell === "")) { + continue; + } const item = {}; headers.forEach((header, index) => { @@ -179,31 +184,85 @@ export const uploadRetaildistributors = async (req, res) => { let Retaildistributor = await RetailDistributor.findOne({ email: item.email, }); + let existingAddress = await ShippingAddressRD.findOne({ + user: Retaildistributor?._id, + isDefault: true, + }).exec(); + + if (!existingAddress) { + existingAddress = await ShippingAddressRD.findOne({ + user: Retaildistributor?._id, + }) + .sort({ createdAt: 1 }) + .exec(); + } if (Kyc) { // Track updated fields const updatedFields = []; - + const addressFields = [ + "Name", + "phoneNumber", + "state", + "city", + "street", + "tradeName", + "postalCode", + "district", + ]; // Check for changes in user details let kycUpdated = false; for (let field in item) { const currentValue = Kyc[field]?.toString(); const newValue = item[field]?.toString(); - + if (currentValue !== newValue) { updatedFields.push(field); Kyc[field] = item[field]; // Update Kyc with the new value - - if (Retaildistributor && field !== 'email') { + + if (Retaildistributor && field !== "email") { Retaildistributor[field] = item[field]; } kycUpdated = true; } } - // Update Kyc and Retaildistributor if there are any changes if (kycUpdated) { await Kyc.save(); await Retaildistributor.save(); + // Check for changes in address details + const addressData = { + Name: item.name, + phoneNumber: item.mobile_number.toString(), + street: item.address, + city: item.city, + state: item.state, + postalCode: item.pincode, + district: item.district, + country: "India", // Default country + tradeName: item.trade_name, + user: Retaildistributor._id, + }; + console.log(addressData); + let addressUpdated = false; + if (existingAddress) { + const addressUpdates = []; + addressFields.forEach((field) => { + if (existingAddress[field] !== addressData[field]) { + addressUpdates.push(field); + addressUpdated = true; + } + }); + + if (addressUpdated) { + await ShippingAddressRD.updateOne( + { user: Retaildistributor._id }, + addressData + ); + } + } else { + // Create new address + await ShippingAddressRD.create(addressData); + } updatedDistributors.push({ ...Kyc._doc, updatedFields: updatedFields.join(", "), @@ -224,7 +283,22 @@ export const uploadRetaildistributors = async (req, res) => { password, }; Retaildistributor = new RetailDistributor(retailDistributorData); - await Retaildistributor.save(); + const newRd = await Retaildistributor.save(); + // Now create the address for the new user + const addressData = { + Name: item.name, + phoneNumber: item.mobile_number.toString(), + street: item.address, + city: item.city, + state: item.state, + postalCode: item.pincode, + district: item.district, + country: "India", // Default country + tradeName: item.trade_name, + user: newRd._id, // Use the saved user's ID + isDefault: true, + }; + await ShippingAddressRD.create(addressData); // Send email with the new password await sendEmail({ to: `${item.email}`, // Change to your recipient diff --git a/resources/ShippingAddresses/ShippingAddressController.js b/resources/ShippingAddresses/ShippingAddressController.js index 7a83833..e176dcd 100644 --- a/resources/ShippingAddresses/ShippingAddressController.js +++ b/resources/ShippingAddresses/ShippingAddressController.js @@ -2,28 +2,17 @@ import ShippingAddress from "./ShippingAddressModel.js"; export const AddshippingAddress = async (req, res) => { // console.log("request came here"); try { - const { - first_Name, - last_Name, - phone_Number, - street, - city, - state, - postalCode, - country, - } = req.body; + const { Name, phoneNumber, street, city, state, postalCode, country } = + req.body; // console.log(req.body); switch (true) { //validation - case !first_Name: { - return res.status(404).json({ msg: "please provide first_Name" }); + case !Name: { + return res.status(404).json({ msg: "please provide Name" }); } - case !last_Name: { - return res.status(404).json({ msg: "please provide last_Name" }); - } - case !phone_Number: { - return res.status(404).json({ msg: "please provide phone_Number" }); + case !phoneNumber: { + return res.status(404).json({ msg: "please provide phoneNumber" }); } case !street: { return res.status(404).json({ msg: "please provide street" }); @@ -60,6 +49,8 @@ export const AddshippingAddress = async (req, res) => { export const AddshippingAddressByAdmin = async (req, res) => { try { const { + Name, + phoneNumber, street, city, state, @@ -68,15 +59,20 @@ export const AddshippingAddressByAdmin = async (req, res) => { panNumber, tradeName, gstNumber, + isDefault, } = req.body; // Validate required fields - if (!street || !city || !state || !postalCode || !panNumber) { - return res.status(400).json({ msg: "Please provide all required fields" }); + if (!Name || !phoneNumber || !street || !city || !state || !postalCode || !panNumber) { + return res + .status(400) + .json({ msg: "Please provide all required fields: Name, phone number, street, city, state, postal code, and PAN number" }); } - // Create shipping address object + // Create new shipping address const newAddress = await ShippingAddress.create({ + Name, + phoneNumber, street, city, state, @@ -86,26 +82,36 @@ export const AddshippingAddressByAdmin = async (req, res) => { tradeName, gstNumber, user: req.params._id, // Assuming req.params._id contains the correct user ID + isDefault, }); + // If this address is marked as default, set all other addresses for this user to isDefault: false + if (isDefault) { + await ShippingAddress.updateMany( + { user: req.params._id, _id: { $ne: newAddress._id } }, // Exclude the new address + { $set: { isDefault: false } } + ); + } + + // Respond with success res.status(201).json({ success: true, address: newAddress, message: "Shipping address added successfully", }); } catch (error) { - // 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); + 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 + + // General error response res.status(500).json({ success: false, message: error.message || "Something went wrong", @@ -164,13 +170,14 @@ export const deleteSelfShippingAddress = async (req, res) => { .status(400) .json({ message: "please Provide shipping Address Id" }); const getselfAddress = await ShippingAddress.findById(req.params.id); + const userId = req.body.userId ? req.body.userId : req.user._id; if (!getselfAddress) { return res.status(404).json({ success: false, message: "No shipping Address Found!", }); } - if (getselfAddress?.user.toString() === req.user._id.toString()) { + if (getselfAddress?.user.toString() === userId.toString()) { const address = await ShippingAddress.findByIdAndDelete(req.params.id); await address.remove(); return res.status(200).json({ @@ -195,21 +202,25 @@ export const deleteSelfShippingAddress = async (req, res) => { export const updateShippingAddress = async (req, res) => { try { const { - first_Name, - last_Name, - phone_Number, + Name, + phoneNumber, street, city, state, postalCode, country, + panNumber, + tradeName, + gstNumber, + isDefault, } = req.body; + // console.log(req.body); const _id = req.params.id; if (!req.params.id) return res .status(400) .json({ message: "please Provide shipping Address Id" }); - const getselfAddress = await ShippingAddress.findById(req.params.id); + const getselfAddress = await ShippingAddress.findById(_id); if (!getselfAddress) { return res.status(404).json({ success: false, @@ -218,13 +229,10 @@ export const updateShippingAddress = async (req, res) => { } switch (true) { //validation - case !first_Name: { - return res.status(404).json({ msg: "please provide first_Name" }); + case !Name: { + return res.status(404).json({ msg: "please provide Name" }); } - case !last_Name: { - return res.status(404).json({ msg: "please provide last_Name" }); - } - case !phone_Number: { + case !phoneNumber: { return res.status(404).json({ msg: "please provide phone_Number" }); } case !street: { @@ -242,16 +250,36 @@ export const updateShippingAddress = async (req, res) => { case !country: { return res.status(404).json({ msg: "please provide country" }); } + case !panNumber: { + return res.status(404).json({ msg: "please provide panNumber" }); + } + case !tradeName: { + return res.status(404).json({ msg: "please provide tradeName" }); + } + case !gstNumber: { + return res.status(404).json({ msg: "please provide gstNumber" }); + } } + // If the updated address is marked as default, update all other addresses to isDefault: false + if (isDefault) { + await ShippingAddress.updateMany( + { user: getselfAddress.user, _id: { $ne: _id } }, // exclude current address + { $set: { isDefault: false } } + ); + } + const updateAddressData = { - first_Name, - last_Name, - phone_Number, + Name, + phoneNumber, street, city, state, postalCode, country, + panNumber, + tradeName, + gstNumber, + isDefault, }; const updateShippingAddress = await ShippingAddress.findByIdAndUpdate( { _id: _id }, diff --git a/resources/ShippingAddresses/ShippingAddressModel.js b/resources/ShippingAddresses/ShippingAddressModel.js index 57502ed..399c02d 100644 --- a/resources/ShippingAddresses/ShippingAddressModel.js +++ b/resources/ShippingAddresses/ShippingAddressModel.js @@ -2,10 +2,7 @@ import mongoose from "mongoose"; const shippingAddressSchema = new mongoose.Schema( { - firstName: { - type: String, - }, - lastName: { + Name: { type: String, }, phoneNumber: { diff --git a/resources/ShippingAddressesRD/RDShippingAddressController.js b/resources/ShippingAddressesRD/RDShippingAddressController.js new file mode 100644 index 0000000..9c75435 --- /dev/null +++ b/resources/ShippingAddressesRD/RDShippingAddressController.js @@ -0,0 +1,339 @@ +import ShippingAddressRD from "./RDShippingAddressModel.js"; +export const AddshippingAddress = async (req, res) => { + // console.log("request came here"); + try { + const { + Name, + phoneNumber, + street, + city, + state, + postalCode, + country, + district, + } = req.body; + + // console.log(req.body); + switch (true) { + //validation + case !Name: { + return res.status(404).json({ msg: "please provide Name" }); + } + case !phoneNumber: { + return res.status(404).json({ msg: "please provide phoneNumber" }); + } + case !street: { + return res.status(404).json({ msg: "please provide street" }); + } + case !city: { + return res.status(404).json({ msg: "please provide city" }); + } + case !state: { + return res.status(404).json({ msg: "please provide state" }); + } + case !postalCode: { + return res.status(404).json({ msg: "please provide postalCode" }); + } + case !country: { + return res.status(404).json({ msg: "please provide country" }); + } + case !tradeName: { + return res.status(404).json({ msg: "please provide tradeName" }); + } + case !district: { + return res.status(404).json({ msg: "please provide district" }); + } + } + req.body.user = req.user._id; + const address = await ShippingAddressRD.create(req.body); + + res.status(201).json({ + success: true, + address, + message: "shipping Address Added", + }); + } catch (error) { + console.log(error.message); + res.status(500).json({ + success: false, + message: error.message ? error.message : "Something went Wrong", + }); + } +}; +export const AddshippingAddressByAdmin = async (req, res) => { + try { + const { + Name, + phoneNumber, + street, + district, + city, + state, + postalCode, + country, + tradeName, + isDefault, + } = req.body; + + // Validate required fields + if ( + !Name || + !phoneNumber || + !street || + !city || + !state || + !postalCode || + !tradeName || + !district + ) { + return res + .status(400) + .json({ + msg: "Please provide all required fields: Name, phone number, street, city, state, postal code, district and tradeName", + }); + } + + // Create new shipping address + const newAddress = await ShippingAddressRD.create({ + Name, + phoneNumber, + street, + district, + city, + state, + postalCode, + country, + tradeName, + user: req.params._id, + isDefault, + }); + + // If this address is marked as default, set all other addresses for this user to isDefault: false + if (isDefault) { + await ShippingAddressRD.updateMany( + { user: req.params._id, _id: { $ne: newAddress._id } }, // Exclude the new address + { $set: { isDefault: false } } + ); + } + + // Respond with success + res.status(201).json({ + success: true, + address: newAddress, + message: "Shipping address added successfully", + }); + } catch (error) { + // 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 response + res.status(500).json({ + success: false, + message: error.message || "Something went wrong", + }); + } +}; + +// For website +export const getSingleUserSippingAddress = async (req, res) => { + try { + const UserShippingAddress = await ShippingAddressRD.find({ + user: req.user._id, + }).sort({ createdAt: -1 }); + if (UserShippingAddress) { + res.status(201).json({ + success: true, + UserShippingAddress, + message: "All User Shipping Address Fetched", + }); + } + } catch (error) { + res.status(500).json({ + success: false, + message: error.message ? error.message : "Something went Wrong", + }); + } +}; +// For Admin +export const getSingleUserSippingAddressForAdmin = async (req, res) => { + try { + // console.log(req.params._id); + const UserShippingAddress = await ShippingAddressRD.find({ + user: req.params._id, + }).sort({ createdAt: -1 }); + // console.log(UserShippingAddress); + if (UserShippingAddress) { + res.status(201).json({ + success: true, + UserShippingAddress, + message: "All User Shipping Address Fetched", + }); + } + } catch (error) { + res.status(500).json({ + success: false, + message: error.message ? error.message : "Something went Wrong", + }); + } +}; + +/// +export const deleteSelfShippingAddress = async (req, res) => { + try { + if (!req.params.id) + return res + .status(400) + .json({ message: "please Provide shipping Address Id" }); + const getselfAddress = await ShippingAddressRD.findById(req.params.id); + const userId = req.body.userId ? req.body.userId : req.user._id; + if (!getselfAddress) { + return res.status(404).json({ + success: false, + message: "No shipping Address Found!", + }); + } + if (getselfAddress?.user.toString() === userId.toString()) { + const address = await ShippingAddressRD.findByIdAndDelete(req.params.id); + await address.remove(); + return res.status(200).json({ + success: true, + message: "Shipping Address Deleted Successfully!", + }); + } else { + return res.status(400).json({ + success: false, + message: "you can only delete self shipping address!!", + }); + } + } catch (error) { + res.status(500).json({ + success: false, + message: error.message ? error.message : "Something went Wrong", + }); + } +}; + +// update shipping addresss +export const updateShippingAddress = async (req, res) => { + try { + const { + Name, + phoneNumber, + street, + city, + district, + state, + postalCode, + country, + tradeName, + isDefault, + } = req.body; + // console.log(req.body); + const _id = req.params.id; + if (!req.params.id) + return res + .status(400) + .json({ message: "please Provide shipping Address Id" }); + const getselfAddress = await ShippingAddressRD.findById(_id); + if (!getselfAddress) { + return res.status(404).json({ + success: false, + message: "No shipping Address Found!", + }); + } + switch (true) { + //validation + case !Name: { + return res.status(404).json({ msg: "please provide Name" }); + } + case !phoneNumber: { + return res.status(404).json({ msg: "please provide phone_Number" }); + } + case !street: { + return res.status(404).json({ msg: "please provide street" }); + } + case !city: { + return res.status(404).json({ msg: "please provide city" }); + } + case !state: { + return res.status(404).json({ msg: "please provide state" }); + } + case !postalCode: { + return res.status(404).json({ msg: "please provide postalCode" }); + } + case !country: { + return res.status(404).json({ msg: "please provide country" }); + } + case !tradeName: { + return res.status(404).json({ msg: "please provide tradeName" }); + } + case !district: { + return res.status(404).json({ msg: "please provide district" }); + } + } + // If the updated address is marked as default, update all other addresses to isDefault: false + if (isDefault) { + await ShippingAddressRD.updateMany( + { user: getselfAddress.user, _id: { $ne: _id } }, // exclude current address + { $set: { isDefault: false } } + ); + } + + const updateAddressData = { + Name, + phoneNumber, + street, + district, + city, + state, + postalCode, + country, + tradeName, + isDefault, + }; + const updateShippingAddress = await ShippingAddressRD.findByIdAndUpdate( + { _id: _id }, + { $set: updateAddressData }, + { new: true } + ); + + res.status(201).json({ + success: true, + updateShippingAddress, + message: "Shipping Address updated", + }); + } catch (error) { + res.status(500).json({ + success: false, + message: error.message ? error.message : "Something went Wrong", + }); + } +}; + +export const getSingleSippingAddress = async (req, res) => { + try { + let _id = req.params.id; + const address = await ShippingAddressRD.findById({ _id: _id }); + + if (address) { + res.status(201).json({ + success: true, + address, + message: "Shipping Address Fetched", + }); + } + } catch (error) { + res.status(500).json({ + success: false, + message: error.message ? error.message : "Something went Wrong", + }); + } +}; diff --git a/resources/ShippingAddressesRD/RDShippingAddressModel.js b/resources/ShippingAddressesRD/RDShippingAddressModel.js new file mode 100644 index 0000000..8054fc0 --- /dev/null +++ b/resources/ShippingAddressesRD/RDShippingAddressModel.js @@ -0,0 +1,62 @@ +import mongoose from "mongoose"; + +const shippingAddressSchema = new mongoose.Schema( + { + Name: { + type: String, + }, + phoneNumber: { + type: Number, + }, + street: { + type: String, + required: true, + }, + district: { + type: String, + required: true, + }, + city: { + type: String, + required: true, + trim: true, + }, + state: { + type: String, + required: true, + }, + postalCode: { + type: String, + required: true, + trim: true, + validate: { + validator: function (v) { + return /^\d{6}$/.test(v); + }, + message: "Postal code must be a 6-digit number", + }, + }, + country: { + type: String, + required: true, + }, + tradeName: { + type: String, + required: true, + }, + isDefault: { + type: Boolean, + default: false, + }, + user: { + type: mongoose.Schema.Types.ObjectId, + ref: "RetailDistributor", + required: true, + }, + }, + { timestamps: true, versionKey: false } +); + +const ShippingAddressRD = mongoose.model("ShippingAddressRD", shippingAddressSchema); + +export default ShippingAddressRD; diff --git a/resources/ShippingAddressesRD/RDShippingAddressRoute.js b/resources/ShippingAddressesRD/RDShippingAddressRoute.js new file mode 100644 index 0000000..fd91146 --- /dev/null +++ b/resources/ShippingAddressesRD/RDShippingAddressRoute.js @@ -0,0 +1,43 @@ +import express from "express"; +import { + AddshippingAddress, + getSingleUserSippingAddress, + deleteSelfShippingAddress, + getSingleUserSippingAddressForAdmin, + updateShippingAddress, + getSingleSippingAddress, + AddshippingAddressByAdmin, +} from "./RDShippingAddressController.js"; +import { authorizeRoles, isAuthenticatedUser } from "../../middlewares/auth.js"; +import { isAuthenticatedRD } from "../../middlewares/rdAuth.js"; +const router = express.Router(); + +router.route("/new").post(isAuthenticatedRD, AddshippingAddress); +router + .route("/admin/new/:_id") + .post( + isAuthenticatedUser, + authorizeRoles("admin"), + AddshippingAddressByAdmin + ); + +router + .route("/user/address/") + .get(isAuthenticatedUser, getSingleUserSippingAddress); +router.route("/").get(isAuthenticatedRD, getSingleUserSippingAddress); +router + .route("/user/address/:_id") + .get( + isAuthenticatedUser, + authorizeRoles("admin"), + getSingleUserSippingAddressForAdmin + ); + +router + .route("/delete/:id") + .delete(isAuthenticatedUser, deleteSelfShippingAddress); + +router.route("/update/:id").patch(isAuthenticatedUser, updateShippingAddress); +router.route("/get/:id").get(isAuthenticatedUser, getSingleSippingAddress); + +export default router; diff --git a/resources/Stock/StockController.js b/resources/Stock/StockController.js index ca45b65..3ce20fe 100644 --- a/resources/Stock/StockController.js +++ b/resources/Stock/StockController.js @@ -5,7 +5,7 @@ import { RDStock } from "./RdStockModel.js"; export const getProductsAndStockByPD = async (req, res) => { try { - const { userId } = req.params; + const userId = req.params.userId || req.user._id; // Pagination parameters const PAGE_SIZE = parseInt(req.query.show) || 10; diff --git a/resources/Stock/StockRoute.js b/resources/Stock/StockRoute.js index 4e21b56..40bd222 100644 --- a/resources/Stock/StockRoute.js +++ b/resources/Stock/StockRoute.js @@ -10,7 +10,6 @@ const router = express.Router(); router.get( "/pd/stock/:userId", isAuthenticatedUser, - authorizeRoles("admin"), getProductsAndStockByPD ); router.get( diff --git a/resources/Task/TaskController.js b/resources/Task/TaskController.js index 1221b8a..d67f76e 100644 --- a/resources/Task/TaskController.js +++ b/resources/Task/TaskController.js @@ -181,26 +181,39 @@ const getStartAndEndOfDay = (date) => { export const getTasksByDates = async (req, res) => { try { await updateOverdueTasks(); + + // Initialize filter object + const filter = {}; + console.log(req.userType); + // Determine the filter based on user type + if (req.userType === "SalesCoOrdinator") { + filter.taskAssignedTo = req.user._id; // Use `=` to assign values, and `===` for comparison + } else { + filter.taskAssignedBy = req.user._id; + } // Get the date from the query const { Date: queryDate } = req.query; let taskDate; - // If date is provided in query, parse it, otherwise use today's date + + // If date is provided in query, parse it; otherwise, use today's date if (queryDate) { taskDate = parseDate(queryDate); } else { // Get today's date in UTC taskDate = new Date(); } + // Get the start and end of the day in UTC const { startOfDay, endOfDay } = getStartAndEndOfDay(taskDate); + // Find tasks for the user, filtered by createdAt within the start and end of the day const tasks = await Task.find({ - taskAssignedBy: req.user._id, + ...filter, // Use the filter object for querying createdAt: { $gte: startOfDay, $lte: endOfDay }, }) .populate({ - path: "taskAssignedTo", + path: req.userType === "SalesCoOrdinator" ? "taskAssignedBy" : "taskAssignedTo", // Change path based on user type select: "name mobileNumber email", }) .sort({ createdAt: -1 }); diff --git a/resources/Task/TaskRoute.js b/resources/Task/TaskRoute.js index f35955d..d654595 100644 --- a/resources/Task/TaskRoute.js +++ b/resources/Task/TaskRoute.js @@ -9,37 +9,22 @@ import { } from "./TaskController.js"; import { isAuthenticatedSalesCoOrdinator } from "../../middlewares/SalesCoOrdinatorAuth.js"; import { isAuthenticatedTerritoryManager } from "../../middlewares/TerritoryManagerAuth.js"; +import { isAuthenticated_SC_TM } from "../../middlewares/generalAuth.js"; const router = express.Router(); // Route for Territory Manager to assign a task -router.post( - "/assign-task", - isAuthenticatedTerritoryManager, - assignTask -); +router.post("/assign-task", isAuthenticatedTerritoryManager, assignTask); // Route for Sales Coordinator to view their tasks by status -router.get( - "/tasks/:status", - isAuthenticatedSalesCoOrdinator, - getTasksByStatus -); +router.get("/tasks/:status", isAuthenticatedSalesCoOrdinator, getTasksByStatus); router.get( "/alltasks/:status", isAuthenticatedTerritoryManager, getAllTasksByStatus ); -router.get( - "/alltask", - isAuthenticatedTerritoryManager, - getTasksByDates -); -router.get( - "/task/type/:task", - isAuthenticatedSalesCoOrdinator, - getTasksbytask -); +router.get("/alltask", isAuthenticated_SC_TM, getTasksByDates); +router.get("/task/type/:task", isAuthenticatedSalesCoOrdinator, getTasksbytask); // Route to update task status router.put( "/update-task-status/:taskId", diff --git a/resources/user/userController.js b/resources/user/userController.js index 1cc566e..4a51f07 100644 --- a/resources/user/userController.js +++ b/resources/user/userController.js @@ -394,6 +394,10 @@ export const uploadPrincipaldistributors = async (req, res) => { for (let i = 1; i < data.length; i++) { const row = data[i]; + // Skip the row if it's completely empty + if (row.every((cell) => cell === undefined || cell === "")) { + continue; + } const item = {}; headers.forEach((header, index) => { @@ -495,6 +499,8 @@ export const uploadPrincipaldistributors = async (req, res) => { // Track updated fields const updatedFields = []; const addressFields = [ + "Name", + "phoneNumber", "panNumber", "gstNumber", "state", @@ -503,9 +509,18 @@ export const uploadPrincipaldistributors = async (req, res) => { "tradeName", "postalCode", ]; - const existingAddress = await ShippingAddress.findOne({ + let existingAddress = await ShippingAddress.findOne({ user: distributor._id, - }); + isDefault: true, + }).exec(); + + if (!existingAddress) { + existingAddress = await ShippingAddress.findOne({ + user: distributor._id, + }) + .sort({ createdAt: 1 }) // Get the first created address as fallback + .exec(); + } // Check for changes in user details let userUpdated = false; @@ -537,6 +552,8 @@ export const uploadPrincipaldistributors = async (req, res) => { // Check for changes in address details const addressData = { + Name: item.name, + phoneNumber: item.phone.toString(), street: item.street, city: item.city, state: item.state, @@ -609,6 +626,8 @@ export const uploadPrincipaldistributors = async (req, res) => { }); // Now create the address for the new user const addressData = { + Name: item.name, + phoneNumber: item.phone, street: item.street, city: item.city, state: item.state, @@ -618,6 +637,7 @@ export const uploadPrincipaldistributors = async (req, res) => { tradeName: item.tradeName, gstNumber: item.gstNumber, user: distributor._id, // Use the saved user's ID + isDefault: true, }; const newAddress = await ShippingAddress.create(addressData); @@ -1011,7 +1031,7 @@ export const getAllUser = catchAsyncErrors(async (req, res, next) => { } if (SBU) { - filter.SBU = { $regex: SBU, $options: "i" }; + filter.SBU = { $regex: SBU, $options: "i" }; } const limit = parseInt(show, 10); @@ -1070,7 +1090,7 @@ export const getAllPD = catchAsyncErrors(async (req, res, next) => { // Aggregate orders data for each user const orderStats = await PdOrder.aggregate([ - { $match: { addedBy: { $in: users.map(user => user._id) } } }, // Match orders for the listed distributors + { $match: { addedBy: { $in: users.map((user) => user._id) } } }, // Match orders for the listed distributors { $group: { _id: "$addedBy", // Group by addedBy (distributor ID) @@ -1081,8 +1101,10 @@ export const getAllPD = catchAsyncErrors(async (req, res, next) => { ]); // Map orders data to corresponding users - const usersWithOrderStats = users.map(user => { - const orderData = orderStats.find(order => order._id.toString() === user._id.toString()); + const usersWithOrderStats = users.map((user) => { + const orderData = orderStats.find( + (order) => order._id.toString() === user._id.toString() + ); return { ...user.toObject(), totalOrders: orderData ? orderData.totalOrders : 0, @@ -1097,7 +1119,7 @@ export const getAllPD = catchAsyncErrors(async (req, res, next) => { total_pages: Math.ceil(totalUsers / limit), }); } catch (error) { - console.error('Error fetching Principal Distributors:', error); + console.error("Error fetching Principal Distributors:", error); res.status(500).json({ message: "Server Error", error }); } });