import dotenv from "dotenv"; import { stockEventModel } from "../../schemas/inventory/stockevent.schema.js"; import log4js from "log4js"; import mongoose from "mongoose"; dotenv.config(); const logger = log4js.getLogger("Stock Events"); logger.level = process.env.LOG_LEVEL; export const listStockEventsRouteHandler = async ( req, res, page = 1, limit = 25, property = "", filter = {}, sort = "", order = "ascend" ) => { try { const skip = (page - 1) * limit; let stockEvents; let aggregateCommand = []; // Lookup filamentStock aggregateCommand.push({ $lookup: { from: "filamentstocks", localField: "filamentStock", foreignField: "_id", as: "filamentStock", }, }); aggregateCommand.push({ $unwind: "$filamentStock" }); // Conditionally lookup subJob only if it exists aggregateCommand.push({ $lookup: { from: "subjobs", localField: "subJob", foreignField: "_id", as: "subJob", }, }); aggregateCommand.push({ $addFields: { subJob: { $cond: { if: { $eq: [{ $size: "$subJob" }, 0] }, then: null, else: { $arrayElemAt: ["$subJob", 0] } } } } }); if (filter != {}) { aggregateCommand.push({ $match: filter }); } if (property != "") { aggregateCommand.push({ $group: { _id: `$${property}` } }); aggregateCommand.push({ $project: { _id: 0, [property]: "$_id" } }); } // Add sorting if sort parameter is provided if (sort) { const sortOrder = order === "descend" ? -1 : 1; aggregateCommand.push({ $sort: { [sort]: sortOrder } }); } // Add pagination after sorting aggregateCommand.push({ $skip: skip }); aggregateCommand.push({ $limit: Number(limit) }); console.log('Aggregation pipeline:', JSON.stringify(aggregateCommand, null, 2)); stockEvents = await stockEventModel.aggregate(aggregateCommand); logger.trace( `List of stock events (Page ${page}, Limit ${limit}, Property ${property}, Sort ${sort}, Order ${order}):`, stockEvents, ); res.send(stockEvents); } catch (error) { logger.error("Error listing stock events:", error); res.status(500).send({ error: error }); } }; export const getStockEventRouteHandler = async (req, res) => { try { const id = new mongoose.Types.ObjectId(req.params.id); const stockEvent = await stockEventModel .findOne({ _id: id, }) .populate("filamentStock") .populate("subJob") .populate("job"); if (!stockEvent) { logger.warn(`Stock event not found with supplied id.`); return res.status(404).send({ error: "Stock event not found." }); } logger.trace(`Stock event with ID: ${id}:`, stockEvent); res.send(stockEvent); } catch (error) { logger.error("Error fetching stock event:", error); res.status(500).send({ error: error.message }); } }; export const newStockEventRouteHandler = async (req, res) => { try { const newStockEvent = { type: req.body.type, value: req.body.value, subJob: req.body.subJob ? new mongoose.Types.ObjectId(req.body.subJob) : null, job: req.body.job ? new mongoose.Types.ObjectId(req.body.job) : null, filamentStock: new mongoose.Types.ObjectId(req.body.filamentStock), timestamp: new Date() }; const result = await stockEventModel.create(newStockEvent); if (!result) { logger.error("No stock event created."); return res.status(500).send({ error: "No stock event created." }); } return res.send({ status: "ok", id: result._id }); } catch (error) { logger.error("Error adding stock event:", error); return res.status(500).send({ error: error.message }); } };