From 45e54f6c744d543b8fe87960f3c74717b73d9692 Mon Sep 17 00:00:00 2001 From: Sibunnayak Date: Thu, 10 Oct 2024 10:54:56 +0530 Subject: [PATCH] rd stock calculation done using the inventory --- resources/Inventory/InventoryController.js | 56 ++++++++++++-- resources/Inventory/InventoryModel.js | 74 +++++++++++------- resources/Inventory/InventoryRoute.js | 5 +- resources/RD_Ordes/rdOrderController.js | 60 +++++++-------- resources/Stock/StockController.js | 90 ++++++++++++++++++++++ resources/Stock/StockRoute.js | 8 +- 6 files changed, 224 insertions(+), 69 deletions(-) diff --git a/resources/Inventory/InventoryController.js b/resources/Inventory/InventoryController.js index c2a7e8b..7e104bc 100644 --- a/resources/Inventory/InventoryController.js +++ b/resources/Inventory/InventoryController.js @@ -6,32 +6,74 @@ 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; - // console.log("req.user", req.user); - const currentYear = new Date().getFullYear().toString().slice(-2); - const randomChars = crypto.randomBytes(4).toString("hex").toUpperCase(); - const uniqueId = `${currentYear}-${randomChars}`; - // console.log("uniqueId", uniqueId); + + if (addedFor === "RetailDistributor") { + // Find the RetailDistributor stock + const rdStock = await RDStock.findOne({ userId: addedForId }); + if (!rdStock) { + return res.status(404).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, - uniqueId, }); - // console.log("newInventory", newInventory); + 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 }); } diff --git a/resources/Inventory/InventoryModel.js b/resources/Inventory/InventoryModel.js index 31fd7c0..d8003e3 100644 --- a/resources/Inventory/InventoryModel.js +++ b/resources/Inventory/InventoryModel.js @@ -1,7 +1,12 @@ -import mongoose from 'mongoose'; +import mongoose from "mongoose"; // Define Product record schema const ProductRecordSchema = new mongoose.Schema({ + productid: { + type: mongoose.Schema.Types.ObjectId, + ref: "Product", + required: true, + }, SKU: { type: String, required: true, @@ -21,33 +26,44 @@ const ProductRecordSchema = new mongoose.Schema({ }); // Define main Inventory schema -const InventorySchema = new mongoose.Schema({ - uniqueId: { - type: String, - required: true, - unique: true, +const InventorySchema = new mongoose.Schema( + { + uniqueId: { + type: String, + required: true, + unique: true, + }, + userId: { + type: mongoose.Schema.Types.ObjectId, + refPath: "userType", + required: true, + }, + userType: { + type: String, + required: true, + enum: ["SalesCoOrdinator", "TerritoryManager"], + }, + addedFor: { + type: String, + required: true, + enum: ["PrincipalDistributor", "RetailDistributor"], + }, + addedForId: { + type: mongoose.Schema.Types.ObjectId, + refPath: "addedFor", + required: true, + }, + products: [ProductRecordSchema], }, - userId: { - type: mongoose.Schema.Types.ObjectId, - refPath: 'userType', - required: true, - }, - userType: { - type: String, - required: true, - enum: ['SalesCoOrdinator', 'TerritoryManager'], - }, - addedFor: { - type: String, - required: true, - enum: ['PrincipalDistributor', 'RetailDistributor'], - }, - addedForId: { - type: mongoose.Schema.Types.ObjectId, - refPath: 'addedFor', - required: true, - }, - products: [ProductRecordSchema], -}, { timestamps: true, versionKey: false }); + { timestamps: true, versionKey: false } +); -export const Inventory = mongoose.model('Inventory', InventorySchema); +InventorySchema.pre("save", function (next) { + if (!this.uniqueId) { + const currentYear = new Date().getFullYear().toString().slice(-2); + const randomChars = crypto.randomBytes(4).toString("hex").toUpperCase(); + this.uniqueId = `${currentYear}-${randomChars}`; + } + next(); +}); +export const Inventory = mongoose.model("Inventory", InventorySchema); \ No newline at end of file diff --git a/resources/Inventory/InventoryRoute.js b/resources/Inventory/InventoryRoute.js index 36e64b7..ca8944c 100644 --- a/resources/Inventory/InventoryRoute.js +++ b/resources/Inventory/InventoryRoute.js @@ -3,11 +3,12 @@ import { addInventory, getDistributors,getAllInventories,getSingleInventory } fr import { isAuthenticatedSalesCoOrdinator } from "../../middlewares/SalesCoOrdinatorAuth.js"; import { isAuthenticatedTerritoryManager } from "../../middlewares/TerritoryManagerAuth.js"; import { authorizeRoles, isAuthenticatedUser } from "../../middlewares/auth.js"; +import {isAuthenticated_SC_TM } from "../../middlewares/generalAuth.js"; const router = express.Router(); // Route to add inventory data -router.post("/add-SC", isAuthenticatedSalesCoOrdinator, addInventory); -router.post("/add-TM", isAuthenticatedTerritoryManager, addInventory); +router.post("/add", isAuthenticated_SC_TM, addInventory); +// router.post("/add-TM", isAuthenticatedTerritoryManager, addInventory); // Route to get all PD or RD names based on type router.get( "/distributors-SC/:type", diff --git a/resources/RD_Ordes/rdOrderController.js b/resources/RD_Ordes/rdOrderController.js index 3fca418..1d2b24c 100644 --- a/resources/RD_Ordes/rdOrderController.js +++ b/resources/RD_Ordes/rdOrderController.js @@ -7,7 +7,7 @@ import { PDStock } from "../Stock/PdStockModel.js"; import { createKYC } from "../../Utils/rejectKyc.js"; import { Notification } from "../Notification/notificationModal.js"; import { sendPushNotification } from "../../Utils/sendPushNotification.js"; - +import {RDStock} from "../Stock/RdStockModel.js"; // Controller to create a new order by RD export const createOrderRD = async (req, res) => { try { @@ -973,38 +973,38 @@ export const updateCourierStatusToDeliveredForPD = async (req, res) => { if (!userId) { return res.status(400).json({ error: "User not found for the order" }); } - // Check if PDStock exists for the user - // let pdStock = await PDStock.findOne({ userId }); + // Check if RDStock exists for the user + let rdStock = await RDStock.findOne({ userId }); + + if (!rdStock) { + // If no stock record exists, create a new one + rdStock = new RDStock({ + userId, + products: [], // Initialize with empty products array + }); + } + // Iterate over each item in the invoice + for (let item of invoice.items) { + const { productId, processquantity } = item; - // if (!pdStock) { - // // If no stock record exists, create a new one - // pdStock = new PDStock({ - // userId, - // products: [], // Initialize with empty products array - // }); - // } - // // Iterate over each item in the invoice - // for (let item of invoice.items) { - // const { productId, processquantity } = item; + // Check if the product already exists in the PDStock for the user + const existingProduct = rdStock.products.find( + (p) => p.productid.toString() === productId.toString() + ); - // // Check if the product already exists in the PDStock for the user - // const existingProduct = pdStock.products.find( - // (p) => p.productid.toString() === productId.toString() - // ); - - // if (existingProduct) { - // // If the product exists, update the stock by adding the processquantity - // existingProduct.Stock += processquantity; - // } else { - // // If the product doesn't exist, add a new entry for the product - // pdStock.products.push({ - // productid: productId, - // Stock: processquantity, - // }); - // } - // } + if (existingProduct) { + // If the product exists, update the stock by adding the processquantity + existingProduct.Stock += processquantity; + } else { + // If the product doesn't exist, add a new entry for the product + rdStock.products.push({ + productid: productId, + Stock: processquantity, + }); + } + } // Save the updated PDStock - // await pdStock.save(); + await rdStock.save(); // Format the current date for display const formattedDate = formatDate(new Date()); diff --git a/resources/Stock/StockController.js b/resources/Stock/StockController.js index 2a4b9b1..7bfe281 100644 --- a/resources/Stock/StockController.js +++ b/resources/Stock/StockController.js @@ -199,4 +199,94 @@ export const getProductsAndStockByRD = async (req, res) => { message: "Error fetching products and stock", }); } +}; + +export const getProductsAndStockForRD = async (req, res) => { + try { + const { userId } = req.user._id; + + // 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, + }, + }, + ]), + ]); + + // 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, + 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/StockRoute.js b/resources/Stock/StockRoute.js index 4d014c6..e5e674b 100644 --- a/resources/Stock/StockRoute.js +++ b/resources/Stock/StockRoute.js @@ -1,6 +1,11 @@ import express from "express"; -import { getProductsAndStockByPD ,getProductsAndStockByRD} from "./StockController.js"; +import { + getProductsAndStockByPD, + getProductsAndStockByRD, + getProductsAndStockForRD, +} from "./StockController.js"; import { authorizeRoles, isAuthenticatedUser } from "../../middlewares/auth.js"; +import {isAuthenticatedRD} from "../../middlewares/rdAuth.js"; const router = express.Router(); router.get( @@ -15,4 +20,5 @@ router.get( authorizeRoles("admin"), getProductsAndStockByRD ); +router.get("/stock", isAuthenticatedRD, getProductsAndStockForRD); export default router;