import mongoose from "mongoose"; import { PDStock } from "./PdStockModel.js"; import { Product } from "../Products/ProductModel.js"; import { RDStock } from "./RdStockModel.js"; export const getProductsAndStockByPD = async (req, res) => { try { const userId = req.params.userId || req.user._id; // Pagination parameters const PAGE_SIZE = parseInt(req.query.show) || 10; const page = parseInt(req.query.page) || 1; const skip = (page - 1) * PAGE_SIZE; // Filtering criteria const filter = {}; if (req.query.name) { filter.name = { $regex: new RegExp(req.query.name, "i"), }; } if (req.query.category) { filter.category = mongoose.Types.ObjectId(req.query.category); } if (req.query.brand) { filter.brand = mongoose.Types.ObjectId(req.query.brand); } // Fetch user's PDStock data and products concurrently const [userStock, products] = await Promise.all([ PDStock.findOne({ userId: mongoose.Types.ObjectId(userId) }), Product.aggregate([ { $match: filter }, { $lookup: { from: "categorymodels", localField: "category", foreignField: "_id", as: "categoryDetails", }, }, { $lookup: { from: "brandmodels", localField: "brand", foreignField: "_id", as: "brandDetails", }, }, { $project: { category: { $arrayElemAt: ["$categoryDetails.categoryName", 0] }, brand: { $arrayElemAt: ["$brandDetails.brandName", 0] }, GST: 1, HSN_Code: 1, SKU: 1, addedBy: 1, createdAt: 1, description: 1, image: 1, name: 1, price: 1, product_Status: 1, updatedAt: 1, }, }, { $skip: skip }, { $limit: PAGE_SIZE }, ]), ]); // Create a stock map for easy lookup const stockMap = {}; if (userStock && userStock.products) { userStock.products.forEach((product) => { stockMap[product.productid.toString()] = product.Stock; }); } // Combine products with their respective stock const productsWithStock = products.map((product) => ({ ...product, stock: stockMap[product._id.toString()] || 0, })); // Get total count for pagination purposes const total = await Product.countDocuments(filter); return res.status(200).json({ success: true, totalProducts: total, totalPages: Math.ceil(total / PAGE_SIZE), currentPage: page, products: productsWithStock, }); } catch (error) { console.error("Error fetching products with stock:", error); return res.status(500).json({ success: false, message: "Error fetching products and stock", }); } }; export const getProductsAndStockByRD = async (req, res) => { try { const userId = req.params.userId || req.user._id; // Pagination parameters const PAGE_SIZE = parseInt(req.query.show) || 10; const page = parseInt(req.query.page) || 1; const skip = (page - 1) * PAGE_SIZE; // Filtering criteria const filter = {}; if (req.query.name) { filter.name = { $regex: new RegExp(req.query.name, "i"), }; } if (req.query.category) { filter.category = mongoose.Types.ObjectId(req.query.category); } if (req.query.brand) { filter.brand = mongoose.Types.ObjectId(req.query.brand); } // Fetch user's RDStock data and products concurrently const [userStock, products] = await Promise.all([ RDStock.findOne({ userId: mongoose.Types.ObjectId(userId) }), Product.aggregate([ { $match: filter }, { $lookup: { from: "categorymodels", localField: "category", foreignField: "_id", as: "categoryDetails", }, }, { $lookup: { from: "brandmodels", localField: "brand", foreignField: "_id", as: "brandDetails", }, }, { $project: { category: { $arrayElemAt: ["$categoryDetails.categoryName", 0] }, brand: { $arrayElemAt: ["$brandDetails.brandName", 0] }, GST: 1, HSN_Code: 1, SKU: 1, addedBy: 1, createdAt: 1, description: 1, image: 1, name: 1, price: 1, product_Status: 1, updatedAt: 1, }, }, { $skip: skip }, { $limit: PAGE_SIZE }, ]), ]); // Create a stock map for easy lookup const stockMap = {}; if (userStock && userStock.products) { userStock.products.forEach((product) => { stockMap[product.productid.toString()] = product.Stock; }); } // Combine products with their respective stock const productsWithStock = products.map((product) => ({ ...product, stock: stockMap[product._id.toString()] || 0, })); // Get total count for pagination purposes const total = await Product.countDocuments(filter); return res.status(200).json({ success: true, totalProducts: total, totalPages: Math.ceil(total / PAGE_SIZE), currentPage: page, products: productsWithStock, }); } catch (error) { console.error("Error fetching products with stock:", error); return res.status(500).json({ success: false, message: "Error fetching products and stock", }); } }; // Create or Update Stock export const createOrUpdateInventory = async (req, res) => { const userId = req.user._id; try { const { products } = req.body; // products: [{ productid, Stock }] console.log(products); // Fetch all products in the system const allProducts = await Product.find({}, "_id SKU"); // Fetch only _id and SKU fields const allProductIds = allProducts.map((p) => p._id.toString()); // Find existing stock data for the user let stock = await PDStock.findOne({ userId }); const updatedProducts = allProductIds.map((productId) => { const productInRequest = products.find((p) => p.productid === productId); const existingProduct = stock?.products.find( (p) => p.productid.toString() === productId ); if (existingProduct) { // Product exists, only update opening inventory return { ...existingProduct, openingInventory: productInRequest ? productInRequest.Stock : existingProduct.openingInventory, }; } else { // New product, set both stock and opening inventory to the same value console.log("came here "); return { productid: productId, SKU: allProducts.find((p) => p._id.toString() === productId).SKU, openingInventory: productInRequest ? productInRequest.Stock : 0, Stock: productInRequest ? productInRequest.Stock : 0, }; } }); if (stock) { // Update existing stock entry stock.products = updatedProducts; await stock.save(); return res .status(200) .json({ message: "Stock updated successfully", stock }); } else { // Create new stock entry const newStock = new PDStock({ userId, products: updatedProducts }); await newStock.save(); return res .status(201) .json({ message: "Stock created successfully", stock: newStock }); } } catch (error) { console.error("Error updating or creating stock:", error); res.status(500).json({ message: "Server error", error }); } }; export const getStockPD = async (req, res) => { try { const userId = req.user._id; // userId from request // Fetch all products with their _id, name, and SKU const allProducts = await Product.find({}, "_id name SKU"); // Map products into an object for easy access const productMap = new Map( allProducts.map((p) => [p._id.toString(), { name: p.name, sku: p.SKU }]) ); // Fetch the user's stock from the PDStock model let stock = await PDStock.findOne({ userId }); let productsWithStock = []; if (stock) { // Create a map of product stocks from the user's stock const stockMap = new Map( stock.products.map((p) => [ p.productid.toString(), { Stock: p.Stock, openingInventory: p.openingInventory || 0 }, ]) ); // Iterate over all products, assigning stock and opening inventory productsWithStock = allProducts.map((product) => { const productStock = stockMap.get(product._id.toString()) || { Stock: 0, openingInventory: 0, }; return { productid: product._id, name: product.name, SKU: product.SKU, Stock: productStock.Stock, openingInventory: productStock.openingInventory, }; }); } else { // If no stock entry exists, initialize all products with stock and opening inventory as 0 productsWithStock = allProducts.map((product) => ({ productid: product._id, name: product.name, SKU: product.SKU, Stock: 0, openingInventory: 0, })); } return res.status(200).json({ message: "Stock fetched successfully", stocks: productsWithStock, }); } catch (error) { console.error("Error fetching stock:", error); res.status(500).json({ message: "Server error", error }); } }; export const getAllUsersWithStock = async (req, res) => { try { // Destructure query parameters for pagination and filtering const { page = 1, show = 10, name = "", SBU = "" } = req.query; // Convert page and show to numbers const currentPage = parseInt(page, 10); const itemsPerPage = parseInt(show, 10); // Create filters for user based on name and SBU const userFilters = {}; if (name) { userFilters.name = { $regex: name, $options: "i" }; // Case-insensitive regex for name } if (SBU) { userFilters.SBU = { $regex: SBU, $options: "i" }; // Case-insensitive regex for SBU } // Find stock records and populate user details const stockRecords = await PDStock.find() .populate({ path: "userId", model: "User", // Ensure the correct model is used select: "uniqueId SBU name email phone", // Select specific fields match: userFilters, // Apply user filters for name and SBU }) .skip((currentPage - 1) * itemsPerPage) // Pagination .select("-products") .limit(itemsPerPage); // Filter out stock records where userId is null (no match found) const filteredStockRecords = stockRecords.filter( (record) => record.userId !== null ); // Count total records after filtering const totalRecords = await PDStock.countDocuments({ userId: { $exists: true }, }); // Return the filtered stock records with pagination info res.status(200).json({ success: true, data: filteredStockRecords, pagination: { currentPage, itemsPerPage, totalRecords, totalPages: Math.ceil(totalRecords / itemsPerPage), }, }); } catch (error) { console.error(error); res.status(500).json({ success: false, message: "Error fetching users and stock records", }); } };