import { Inventory } from "../Inventory/InventoryModel.js"; import User from "../user/userModel.js"; import { KYC } from "../KYC/KycModel.js"; import ShippingAddress from "../ShippingAddresses/ShippingAddressModel.js"; import TerritoryManager from "../TerritoryManagers/TerritoryManagerModel.js"; import SalesCoordinator from "../SalesCoOrdinators/SalesCoOrdinatorModel.js"; import crypto from "crypto"; import RetailDistributor from "../RetailDistributor/RetailDistributorModel.js"; import { RDStock } from "../Stock/RdStockModel.js"; // Add inventory data export const addInventory = async (req, res) => { try { const { products, addedFor, addedForId } = req.body; const userId = req.user._id; const userType = req.userType; if (addedFor === "RetailDistributor") { // Find the RetailDistributor stock const rdStock = await RDStock.findOne({ userId: addedForId }); if (!rdStock) { return res .status(400) .json({ error: "Stock not available for the RetailDistributor" }); } // Array to hold product names that have issues let invalidProducts = []; // Loop through products in the request and check stock availability for (const product of products) { const { productid, Sale, ProductName } = product; // Find product in the RetailDistributor's stock const rdProduct = rdStock.products.find( (p) => p.productid.toString() === productid.toString() ); if (rdProduct) { // Check if sales quantity is less than or equal to the stock if (Sale <= rdProduct.Stock) { // Decrease the stock by sales amount rdProduct.Stock -= Sale; } else { // If sales > stock, add to invalid products list invalidProducts.push(ProductName); } } else { // Product not found in stock, add to invalid products list invalidProducts.push(ProductName); } } // If there are any invalid products, return error message if (invalidProducts.length > 0) { return res.status(400).json({ success: false, message: `Insufficient stock or product not found for: ${invalidProducts.join( ", " )}`, }); } // Save updated stock if all products are valid await rdStock.save(); } // Create and save new inventory record const newInventory = new Inventory({ userId, userType, addedFor, addedForId, products, }); await newInventory.save(); res.status(201).json({ success: true, message: "Inventory added successfully", data: newInventory, }); } catch (error) { res.status(500).json({ success: false, message: "Server error", error }); } }; // Get all distributors (PD or RD) export const getDistributors = async (req, res) => { try { const { type } = req.params; if (!["PrincipalDistributor", "RetailDistributor"].includes(type)) { return res.status(400).json({ message: "Invalid distributor type" }); } let filter = { role: "principal-Distributor" }; let query = {}; // 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; query.mappedSC = req.user._id; } else { // Otherwise, filter by req.user._id filter.mappedby = req.user._id; query.mappedTM = req.user._id; } let distributors; // console.log("type",type); if (type === "PrincipalDistributor") { // Fetch all PrincipalDistributors const principalDistributors = await User.find(filter).sort({ createdAt: -1, }); // console.log("principalDistributors",principalDistributors); // Map each PrincipalDistributor to include their ShippingAddress distributors = await Promise.all( principalDistributors.map(async (distributor) => { const shippingAddress = await ShippingAddress.findOne({ user: distributor._id, }); return { ...distributor.toObject(), shippingAddress, }; }) ); } else { // For RetailDistributor, fetch approved KYC documents distributors = await RetailDistributor.find(query) .populate("kyc") .sort({ createdAt: -1 }); } res.status(200).json(distributors); } catch (error) { res.status(500).json({ message: error.message }); } }; export const getAllInventories = async (req, res) => { try { const { page = 1, show = 10, startDate, endDate, name } = req.query; const query = {}; if (startDate && endDate) { const start = new Date(startDate); const end = new Date(endDate); if (start.toDateString() === end.toDateString()) { query.createdAt = { $gte: start, $lt: new Date(start).setDate(start.getDate() + 1), }; } else { query.createdAt = { $gte: start, $lte: new Date(end).setDate(end.getDate() + 1), }; } } else if (startDate && endDate === "") { query.createdAt = { $gte: new Date(startDate), $lte: new Date(), }; } else if (endDate && startDate === "") { query.createdAt = { $lte: new Date(endDate), }; } const allInventories = await Inventory.find(query).sort({ createdAt: -1 }); // Populate additional details const populatedInventories = await Promise.all( allInventories.map(async (inventory) => { let user = null; if (inventory.userType === "TerritoryManager") { user = await TerritoryManager.findById(inventory.userId); } else if (inventory.userType === "SalesCoordinator") { user = await SalesCoordinator.findById(inventory.userId); } let addedForData = null; let tradeName = null; if (inventory.addedFor === "PrincipalDistributor") { addedForData = await User.findById(inventory.addedForId); if (addedForData) { const shippingAddress = await ShippingAddress.findOne({ user: addedForData._id, }); addedForData = { ...addedForData.toObject(), shippingAddress, }; tradeName = addedForData.shippingAddress?.tradeName?.toLowerCase() || ""; } } else if (inventory.addedFor === "RetailDistributor") { addedForData = await KYC.findById(inventory.addedForId); tradeName = addedForData?.trade_name?.toLowerCase() || ""; } return { ...inventory.toObject(), user, addedForData, tradeName, }; }) ); // Apply name filter if the name parameter is provided let filteredInventories = populatedInventories; if (name) { filteredInventories = filteredInventories.filter( (inventory) => inventory.tradeName && inventory.tradeName.includes(name.toLowerCase()) ); } // Calculate total count of filtered data const total_data = filteredInventories.length; // Apply pagination after filtering const paginatedInventories = filteredInventories.slice( (page - 1) * show, page * show ); // Calculate total pages const total_pages = Math.ceil(total_data / show); // Send response with pagination info res.status(200).json({ total_data, total_pages, current_page: Number(page), inventories: paginatedInventories, }); } catch (error) { console.error("Error in getAllInventories:", error); res.status(500).json({ message: error.message }); } }; // Get single inventory export const getSingleInventory = async (req, res) => { try { const { id } = req.params; const inventory = await Inventory.findById(id); if (!inventory) { return res.status(404).json({ message: "Inventory not found" }); } // Populate user details based on userType let user = null; if (inventory.userType === "TerritoryManager") { user = await TerritoryManager.findById(inventory.userId); } else if (inventory.userType === "SalesCoOrdinator") { user = await SalesCoordinator.findById(inventory.userId); } // Populate addedFor details based on addedFor let addedForData = null; if (inventory.addedFor === "PrincipalDistributor") { addedForData = await User.findById(inventory.addedForId); const shippingAddress = await ShippingAddress.findOne({ user: addedForData._id, }); addedForData = { ...addedForData.toObject(), shippingAddress, }; } else if (inventory.addedFor === "RetailDistributor") { addedForData = await KYC.findById(inventory.addedForId); } res.status(200).json({ ...inventory.toObject(), user, addedForData, }); } catch (error) { res.status(500).json({ message: error.message }); } };