diff --git a/app.js b/app.js index 6f12e23..90c940c 100644 --- a/app.js +++ b/app.js @@ -203,7 +203,7 @@ import TaskRoute from "./resources/Task/TaskRoute.js"; // visit RD and PD import VisitRDandPDRoute from "./resources/VisitRD&PD/VisitRD&PDRoute.js"; //Stock -import Stock from "./resources/Stock/PdStockRoute.js"; +import Stock from "./resources/Stock/StockRoute.js"; app.use("/api/v1", user); //Product diff --git a/resources/Stock/PdStockController.js b/resources/Stock/PdStockController.js deleted file mode 100644 index 0aebe55..0000000 --- a/resources/Stock/PdStockController.js +++ /dev/null @@ -1,103 +0,0 @@ -import mongoose from "mongoose"; -import { PDStock } from "./PdStockModel.js"; -import { Product } from "../Products/ProductModel.js"; - -export const getProductsAndStockByUser = async (req, res) => { - try { - const { userId } = req.params; - - // 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", - }); - } -}; - diff --git a/resources/Stock/RdStockModel.js b/resources/Stock/RdStockModel.js new file mode 100644 index 0000000..20a3dfa --- /dev/null +++ b/resources/Stock/RdStockModel.js @@ -0,0 +1,26 @@ +import mongoose from 'mongoose'; + +// Define Product record schema +const ProductRecordSchema = new mongoose.Schema({ + productid: { + type: mongoose.Schema.Types.ObjectId, + ref: 'Product', + required: true, + }, + Stock: { + type: Number, + default: 0, + }, +}); + +// Define main Stock schema +const StockSchema = new mongoose.Schema({ + userId: { + type: mongoose.Schema.Types.ObjectId, + refPath: 'RetailDistributor', + required: true, + }, + products: [ProductRecordSchema], +}, { timestamps: true, versionKey: false }); + +export const RDStock = mongoose.model('RDStock', StockSchema); diff --git a/resources/Stock/StockController.js b/resources/Stock/StockController.js new file mode 100644 index 0000000..2a4b9b1 --- /dev/null +++ b/resources/Stock/StockController.js @@ -0,0 +1,202 @@ +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; + + // 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; + + // 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", + }); + } +}; \ No newline at end of file diff --git a/resources/Stock/PdStockRoute.js b/resources/Stock/StockRoute.js similarity index 52% rename from resources/Stock/PdStockRoute.js rename to resources/Stock/StockRoute.js index d49a778..4d014c6 100644 --- a/resources/Stock/PdStockRoute.js +++ b/resources/Stock/StockRoute.js @@ -1,5 +1,5 @@ import express from "express"; -import { getProductsAndStockByUser } from "./PdStockController.js"; +import { getProductsAndStockByPD ,getProductsAndStockByRD} from "./StockController.js"; import { authorizeRoles, isAuthenticatedUser } from "../../middlewares/auth.js"; const router = express.Router(); @@ -7,6 +7,12 @@ router.get( "/pd/stock/:userId", isAuthenticatedUser, authorizeRoles("admin"), - getProductsAndStockByUser + getProductsAndStockByPD +); +router.get( + "/rd/stock/:userId", + isAuthenticatedUser, + authorizeRoles("admin"), + getProductsAndStockByRD ); export default router;