other
This commit is contained in:
151
backend/controllers/stock.controller.js
Normal file
151
backend/controllers/stock.controller.js
Normal file
@@ -0,0 +1,151 @@
|
||||
import Product from "../models/Product.model.js";
|
||||
import Order from "../models/Order.model.js";
|
||||
import Store from "../models/Store.model.js";
|
||||
import mongoose from "mongoose";
|
||||
import logger from "../utils/logger.js";
|
||||
|
||||
/**
|
||||
* Updates a product's stock quantity
|
||||
*/
|
||||
export const updateStock = async (req, res) => {
|
||||
try {
|
||||
const { productId } = req.params;
|
||||
const { currentStock, stockTracking, lowStockThreshold } = req.body;
|
||||
|
||||
if (currentStock === undefined) {
|
||||
return res.status(400).json({ message: "Stock quantity is required" });
|
||||
}
|
||||
|
||||
// Validate product exists and belongs to the vendor's store
|
||||
const product = await Product.findOne({
|
||||
_id: productId,
|
||||
storeId: req.user.storeId
|
||||
});
|
||||
|
||||
if (!product) {
|
||||
return res.status(404).json({ message: "Product not found" });
|
||||
}
|
||||
|
||||
// Update stock values
|
||||
let stockStatus = "in_stock";
|
||||
if (currentStock <= 0) {
|
||||
stockStatus = "out_of_stock";
|
||||
} else if (currentStock <= (lowStockThreshold || product.lowStockThreshold)) {
|
||||
stockStatus = "low_stock";
|
||||
}
|
||||
|
||||
const updatedProduct = await Product.findByIdAndUpdate(
|
||||
productId,
|
||||
{
|
||||
currentStock: currentStock,
|
||||
stockTracking: stockTracking !== undefined ? stockTracking : product.stockTracking,
|
||||
lowStockThreshold: lowStockThreshold !== undefined ? lowStockThreshold : product.lowStockThreshold,
|
||||
stockStatus: stockStatus
|
||||
},
|
||||
{ new: true }
|
||||
);
|
||||
|
||||
return res.status(200).json(updatedProduct);
|
||||
|
||||
} catch (error) {
|
||||
logger.error("Error updating stock", { error });
|
||||
return res.status(500).json({ message: "Failed to update stock", error: error.message });
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets stock information for all products in a store
|
||||
*/
|
||||
export const getStoreStock = async (req, res) => {
|
||||
try {
|
||||
const products = await Product.find({ storeId: req.user.storeId })
|
||||
.select('_id name currentStock stockTracking stockStatus lowStockThreshold')
|
||||
.sort({ stockStatus: 1, name: 1 });
|
||||
|
||||
return res.status(200).json(products);
|
||||
} catch (error) {
|
||||
logger.error("Error fetching store stock", { error });
|
||||
return res.status(500).json({ message: "Failed to fetch stock information", error: error.message });
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates stock levels when an order is placed
|
||||
* This should be called from the order creation logic
|
||||
*/
|
||||
export const decreaseStockOnOrder = async (order) => {
|
||||
try {
|
||||
// Process each ordered product
|
||||
for (const item of order.products) {
|
||||
const product = await Product.findById(item.productId);
|
||||
|
||||
// Skip if product doesn't exist or stock tracking is disabled
|
||||
if (!product || !product.stockTracking) continue;
|
||||
|
||||
// Calculate new stock level
|
||||
let newStock = Math.max(0, product.currentStock - item.quantity);
|
||||
let stockStatus = "in_stock";
|
||||
|
||||
if (newStock <= 0) {
|
||||
stockStatus = "out_of_stock";
|
||||
} else if (newStock <= product.lowStockThreshold) {
|
||||
stockStatus = "low_stock";
|
||||
}
|
||||
|
||||
// Update the product stock
|
||||
await Product.findByIdAndUpdate(
|
||||
item.productId,
|
||||
{
|
||||
currentStock: newStock,
|
||||
stockStatus: stockStatus
|
||||
},
|
||||
{ new: true }
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
logger.error("Error decreasing stock on order", { orderId: order._id, error });
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Restores stock when an order is cancelled
|
||||
*/
|
||||
export const restoreStockOnCancel = async (order) => {
|
||||
try {
|
||||
// Process each ordered product
|
||||
for (const item of order.products) {
|
||||
const product = await Product.findById(item.productId);
|
||||
|
||||
// Skip if product doesn't exist or stock tracking is disabled
|
||||
if (!product || !product.stockTracking) continue;
|
||||
|
||||
// Calculate new stock level
|
||||
let newStock = product.currentStock + item.quantity;
|
||||
let stockStatus = "in_stock";
|
||||
|
||||
if (newStock <= 0) {
|
||||
stockStatus = "out_of_stock";
|
||||
} else if (newStock <= product.lowStockThreshold) {
|
||||
stockStatus = "low_stock";
|
||||
}
|
||||
|
||||
// Update the product stock
|
||||
await Product.findByIdAndUpdate(
|
||||
item.productId,
|
||||
{
|
||||
currentStock: newStock,
|
||||
stockStatus: stockStatus
|
||||
},
|
||||
{ new: true }
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
logger.error("Error restoring stock on cancel", { orderId: order._id, error });
|
||||
return false;
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user