import mongoose from "mongoose"; import cloudinary from "../../Utils/cloudinary.js"; import { KYC } from "./KycModel.js"; import User from "../user/userModel.js"; import { createKYC, rejectKYC } from "../../Utils/rejectKyc.js"; import SalesCoOrdinator from "../SalesCoOrdinators/SalesCoOrdinatorModel.js"; import TerritoryManager from "../TerritoryManagers/TerritoryManagerModel.js"; 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, email, trade_name, address, state, city, district, pincode, mobile_number, principal_distributer, pan_number, aadhar_number, gst_number, notes, } = req.body; const { selfie_entrance_img, pan_img, aadhar_img, gst_img, pesticide_license_img, } = req.files; let fertilizer_license_img; if (req.files && req.files.fertilizer_license_img) { fertilizer_license_img = req.files.fertilizer_license_img; } if (!req?.user) return res.status(400).json({ message: "Please login!" }); const userType = req.userType; try { if (!mongoose.Types.ObjectId.isValid(req.user._id)) { return res.status(400).json({ message: "Please login again" }); } const isExits = await KYC.find({ email: email }); if (isExits.length > 0) { throw new Error("Email already exists"); } // Upload images to Cloudinary and store only public_id and url const uploadImage = async (image, folder) => { if (!image) return null; const result = await cloudinary.v2.uploader.upload(image.tempFilePath, { folder, }); return { public_id: result.public_id, url: result.secure_url, }; }; const panImg = await uploadImage(pan_img, "KYC/pan"); const aadharImg = await uploadImage(aadhar_img, "KYC/aadhar"); const gstImg = await uploadImage(gst_img, "KYC/gst"); const pesticideLicenseImg = await uploadImage( pesticide_license_img, "KYC/pesticide_license" ); const fertilizerLicenseImg = await uploadImage( fertilizer_license_img, "KYC/fertilizer_license" ); const selfieEntranceImg = await uploadImage( selfie_entrance_img, "KYC/selfie_entrance" ); // Create KYC document const kyc = await KYC.create({ name, email, trade_name, address, state, city, district, pincode, mobile_number, principal_distributer, pan_number, pan_img: panImg, aadhar_number, aadhar_img: aadharImg, gst_number, gst_img: gstImg, pesticide_license_img: pesticideLicenseImg, fertilizer_license_img: fertilizerLicenseImg || {}, selfie_entrance_img: selfieEntranceImg, addedBy: req.user._id, userType: userType, notes, }); if (principal_distributer) { await createKYC( kyc.principal_distributer, "KYC Created", `${trade_name} sent request to approve the KYC .` ); await Notification.create({ title: "KYC Created", msg: `KYC created for the trade name ${name}`, kyc_ref: kyc._id, added_for: kyc.principal_distributer, }); } if (kyc) { return res .status(201) .json({ success: true, kyc, message: "KYC created" }); } } catch (error) { res.status(500).json({ success: false, message: error.message ? error.message : "Something went wrong", }); } }; export const deletekycImageFromCloudinary = async (req, res) => { const { public_id, folder } = req.params; const { kycid, imageType } = req.body; // console.log(req.body); // console.log(req.params); // Map frontend field names to backend field names in the KYC schema const imageFieldMapping = { selfieEntranceImg: "selfie_entrance_img", panImg: "pan_img", aadharImg: "aadhar_img", gstImg: "gst_img", pesticideLicenseImg: "pesticide_license_img", fertilizerLicenseImg: "fertilizer_license_img", }; try { if (!public_id || !imageType) { return res.status(400).json({ success: false, msg: "Please provide a valid image public ID and image type!", }); } // Get the corresponding backend field name const backendImageField = imageFieldMapping[imageType]; if (!backendImageField) { return res.status(400).json({ success: false, msg: "Invalid image type provided!", }); } // Define the full Cloudinary public ID path const folderPath = "KYC"; const fullPublicId = `${folderPath}/${folder}/${public_id}`; // Delete the image from Cloudinary const response = await cloudinary.v2.uploader.destroy(fullPublicId); if (response.result === "ok") { // Update the KYC document to set the image field to null const updateField = {}; updateField[backendImageField] = null; const kycRecord = await KYC.findByIdAndUpdate( kycid, { $set: updateField }, { new: true } ); if (!kycRecord) { return res.status(404).json({ success: false, msg: "KYC record not found!", }); } return res.status(200).json({ success: true, msg: "Image deleted successfully!", data: kycRecord, }); } else { throw new Error("Failed to delete image from Cloudinary."); } } catch (error) { return res.status(500).json({ success: false, msg: error.message || "Something went wrong!", }); } }; export const createretaildistributor = async (req, res) => { const { name, email, trade_name, address, state, city, district, pincode, mobile_number, pan_number, aadhar_number, gst_number, } = req.body; try { if (!mongoose.Types.ObjectId.isValid(req.user._id)) { return res.status(400).json({ message: "Please login again" }); } if (!req.files) { return res.status(400).json({ message: "No files were uploaded." }); } const { selfieEntranceImg, panImg, aadharImg, gstImg, pesticideLicenseImg, } = req.files; // console.log(req.files); const fertilizerLicenseImg = req.files.fertilizerLicenseImg || null; if ( !panImg || !aadharImg || !gstImg || !selfieEntranceImg || !pesticideLicenseImg ) { return res .status(400) .json({ message: "Please upload all required images." }); } // Upload images to Cloudinary const uploadImage = async (image, folder) => { if (!image) return null; const result = await cloudinary.v2.uploader.upload(image.tempFilePath, { folder, }); return { public_id: result.public_id, url: result.secure_url, }; }; const pan_img = await uploadImage(panImg, "KYC/pan"); const aadhar_img = await uploadImage(aadharImg, "KYC/aadhar"); const gst_img = await uploadImage(gstImg, "KYC/gst"); const pesticide_license_img = await uploadImage( pesticideLicenseImg, "KYC/pesticide_license" ); const fertilizer_license_img = await uploadImage( fertilizerLicenseImg, "KYC/fertilizer_license" ); const selfie_entrance_img = await uploadImage( selfieEntranceImg, "KYC/selfie_entrance" ); // Create KYC document const kycData = { name, email, trade_name, address, state, city, district, pincode, mobile_number, pan_number, pan_img, aadhar_number, aadhar_img, gst_number, gst_img, pesticide_license_img, fertilizer_license_img: fertilizer_license_img || null, // Optional field selfie_entrance_img, status: "approved", }; const kyc = await KYC.create(kycData); if (!kyc) { return res.status(400).json({ message: "Failed to create KYC." }); } // Generate password const password = generatePassword(name, email); // Create RetailDistributor document const retailDistributorData = { name, email, mobile_number, kyc: kyc._id, password, }; const retailDistributor = new RetailDistributor(retailDistributorData); 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 from: `${process.env.SEND_EMAIL_FROM}`, // Change to your verified sender subject: `Welcome to Cheminova - Account Created Successfully`, html: `

Dear ${name},

We are pleased to inform you that your retailer account has been successfully created. Please find your account details below:

Name: ${name}

Mobile Number: ${mobile_number}


Email is: ${email}

Password: ${password}


You can log in to your account using the following link:

Click here to log in


For convenience, you can also download our mobile app from the following links:


If you have not requested this email or have any concerns, please contact our support team immediately.


Best regards,

Cheminova Support Team

`, }); // Send response res.status(201).json({ success: true, kyc, retailDistributor, message: "Retail Distributor created successfully", }); } catch (error) { res.status(500).json({ success: false, message: error.message ? error.message : "Something went wrong!", }); } }; // Get All KYC export const getAllKyc = async (req, res) => { try { // Fetch all KYC documents from the database // console.log("req came here "); // console.log(req.user._id); const kycs = await KYC.find({ principal_distributer: req.user._id }) .populate("principal_distributer", "name") .populate("addedBy"); // console.log(kycs); // Send the fetched data as a response res.status(200).json(kycs); } catch (error) { // Handle any errors that occur during the fetch operation console.log(error); res.status(500).json({ message: "Server Error", error }); } }; // Get all KYC Rejected export const getAllKycRejected = async (req, res) => { try { // Fetch all KYC documents from the database // console.log("req came here "); const kycs = await KYC.find({ status: "reject", addedBy: req.user._id }) .sort({ createdAt: -1 }) .populate("principal_distributer", "name") .populate("addedBy"); // console.log(kycs); // Send the fetched data as a response res.status(200).json(kycs); } catch (error) { // Handle any errors that occur during the fetch operation console.log(error); res.status(500).json({ message: "Server Error", error }); } }; // Get All KYC Approved export const getAllKycApproved = async (req, res) => { try { // Extract query parameters from the request const { page = 1, show = 10, name, principaldistributor } = req.query; const skip = (page - 1) * show; // Build the main query object const query = { status: "approved" }; // If a trade name is provided, add it to the query if (name) { query.trade_name = new RegExp(name, "i"); // Case-insensitive search for trade name } // If a principal distributor name is provided, find the matching distributor IDs let principalDistributerIds = []; if (principaldistributor) { const matchingDistributors = await mongoose.model("User").find( { name: new RegExp(principaldistributor, "i"), // Case-insensitive search for principal distributor name }, "_id" ); // Only return the _id field principalDistributerIds = matchingDistributors.map( (distributor) => distributor._id ); // If matching distributors are found, add the IDs to the main query if (principalDistributerIds.length > 0) { query.principal_distributer = { $in: principalDistributerIds }; } } // Find the KYC records with pagination and populate specific fields const kycs = await KYC.find(query) .sort({ createdAt: -1 }) .populate("principal_distributer", "name") // Only include the 'name' field .populate("addedBy") .skip(skip) .limit(parseInt(show)); // Get total count of documents that match the query const total_data = await KYC.countDocuments(query); // Send the response with pagination data res.status(200).json({ success: true, total_data, total_pages: Math.ceil(total_data / show), kycs, }); } catch (error) { console.error(error); res.status(500).json({ message: "Server Error", error }); } }; // Get Single KYC export const getKycById = async (req, res) => { try { // Get the KYC ID from the request parameters const { id } = req.params; // Fetch the KYC document from the database by ID const kyc = await KYC.findById(id) .populate("principal_distributer", "name") .populate("addedBy"); // Check if the KYC document exists if (!kyc) { return res.status(404).json({ message: "KYC document not found" }); } // Send the fetched KYC document as a response res.status(200).json(kyc); } catch (error) { // Handle any errors that occur during the fetch operation res.status(500).json({ message: "Server Error", error }); } }; export const updateKycStatus = async (req, res) => { const { status, rejectionReason, user } = req.body; const { id } = req.params; try { // Find the KYC document by ID const kyc = await KYC.findById(id); if (!kyc) { return res.status(404).json({ message: "KYC record not found" }); } // Check if the user has access if (kyc.principal_distributer.toString() !== req.user._id.toString()) { return res.status(403).json({ message: "Access denied" }); } const trade_name = kyc.trade_name; if (status === "approved") { kyc.status = status; await rejectKYC( kyc.addedBy, "KYC Approved", `Your KYC for ${trade_name} has been approved.` ); await Notification.create({ title: "KYC Approved", msg: `Your KYC for ${trade_name} has been approved.`, kyc_ref: kyc._id, added_for: kyc.addedBy, }); // Generate a secure password for RetailDistributor const password = generatePassword(kyc.name, kyc.email); // Create RetailDistributor document const retailDistributorData = { name: kyc.name, email: kyc.email, mobile_number: kyc.mobile_number, principal_distributer: kyc.principal_distributer, addedBy: kyc.addedBy, userType: kyc.userType, kyc: kyc._id, password, }; const retailDistributor = new RetailDistributor(retailDistributorData); 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, from: process.env.SEND_EMAIL_FROM, subject: `Welcome to Cheminova - Account Created Successfully`, html: `

Dear ${kyc.name},

We are pleased to inform you that your Retailer account has been successfully created. Please find your account details below:

Name: ${kyc.name}

Mobile Number: ${kyc.mobile_number}


Email is: ${kyc.email}

Password: ${password}


You can log in to your account using the following link:

Click here to log in


For convenience, you can also download our mobile app from the following links:


If you have not requested this email or have any concerns, please contact our support team immediately.


Best regards,

Cheminova Support Team

`, }); } if (status === "reject") { await rejectKYC( kyc.addedBy, "KYC application Rejected", `KYC for ${trade_name} has been rejected. Reason: ${rejectionReason}` ); await Notification.create({ title: "KYC Rejected", msg: `KYC for ${trade_name} has been rejected. Reason: ${rejectionReason}`, kyc_ref: kyc._id, added_for: kyc.addedBy, }); } // Update rejection reason in notes if status is rejected if (kyc.status === "reject" || status === "reject") { if (status) { kyc.status = status; } kyc.notes.push({ message: rejectionReason, user: user, replyDate: new Date(), }); } // Save the updated KYC document await kyc.save(); // Populate principal_distributer and addedBy fields const updatedKyc = await KYC.findById(kyc._id) .populate("principal_distributer", "name") // Populate specific fields if needed .populate("addedBy"); // Send the populated KYC in the response res .status(200) .json({ message: "KYC status updated successfully", kyc: updatedKyc }); } catch (error) { console.log(error); res.status(500).json({ message: "Error updating KYC status", error }); } }; export const getAllPrincipalDistributers = async (req, res) => { try { // Define the filter for the query let filter = { role: "principal-Distributor" }; // Check the user type and adjust the filter accordingly if (req.userType === "SalesCoOrdinator") { // If userType is "SalesCoOrdinator", filter by req.user.mappedBy filter.mappedby = req.user.mappedby; } else { // Otherwise, filter by req.user._id filter.mappedby = req.user._id; } // console.log(filter); // Fetch the principal distributors based on the filter const principalDistributers = await User.find(filter); // console.log(principalDistributers); // Send the fetched data as a response if (principalDistributers.length > 0) { res.status(200).json(principalDistributers); } else { res.status(404).json({ message: "No Principal Distributors found" }); } } catch (error) { // Handle any errors that occur during the fetch operation res.status(500).json({ message: "Server Error", error }); } }; // Fcm token storing export const saveFCMTokenForSC = async (req, res) => { const { fcmToken } = req.body; const userId = req.user._id; try { // Fetch the current FCM token for the user const user = await SalesCoOrdinator.findById(userId); if (!user) { return res.status(404).send("User not found"); } // Check if the new FCM token is different from the current one if (user.fcm_token && user.fcm_token === fcmToken) { return res.status(200).send("FCM Token is already up to date"); } // Update the FCM token user.fcm_token = fcmToken; await user.save(); res.status(200).send("FCM Token saved successfully"); } catch (error) { console.error("Error saving FCM Token:", error); res.status(500).send("Internal Server Error"); } }; export const saveFCMTokenForTM = async (req, res) => { const { fcmToken } = req.body; const userId = req.user._id; try { // Fetch the current FCM token for the user const user = await TerritoryManager.findById(userId); if (!user) { return res.status(404).send("User not found"); } // Check if the new FCM token is different from the current one if (user.fcm_token && user.fcm_token === fcmToken) { return res.status(200).send("FCM Token is already up to date"); } // Update the FCM token user.fcm_token = fcmToken; await user.save(); res.status(200).send("FCM Token saved successfully"); } catch (error) { console.error("Error saving FCM Token:", error); res.status(500).send("Internal Server Error"); } };