203 lines
6.0 KiB
JavaScript

import config from '../../config.js';
import { stockAuditModel } from '../../database/schemas/inventory/stockaudit.schema.js';
import log4js from 'log4js';
import mongoose from 'mongoose';
import { getAuditLogs } from '../../utils.js';
import {
getModelStats, getModelHistory,
searchObjects
} from '../../database/database.js';
const logger = log4js.getLogger('Stock Audits');
logger.level = config.server.logLevel;
export const listStockAuditsRouteHandler = async (
req,
res,
page = 1,
limit = 25,
property = '',
filter = {}
) => {
try {
const skip = (page - 1) * limit;
let stockAudits;
let aggregateCommand = [];
// Lookup createdBy user
aggregateCommand.push({
$lookup: {
from: 'users',
localField: 'createdBy',
foreignField: '_id',
as: 'createdBy',
},
});
aggregateCommand.push({ $unwind: '$createdBy' });
if (filter != {}) {
aggregateCommand.push({ $match: filter });
}
if (property != '') {
aggregateCommand.push({ $group: { _id: `$${property}` } });
aggregateCommand.push({ $project: { _id: 0, [property]: '$_id' } });
}
aggregateCommand.push({ $skip: skip });
aggregateCommand.push({ $limit: Number(limit) });
stockAudits = await stockAuditModel.aggregate(aggregateCommand);
logger.trace(
`List of stock audits (Page ${page}, Limit ${limit}, Property ${property}):`,
stockAudits
);
res.send(stockAudits);
} catch (error) {
logger.error('Error listing stock audits:', error);
res.status(500).send({ error: error });
}
};
export const searchStockAuditsRouteHandler = async (req, res, search) => {
const result = await searchObjects({
model: stockAuditModel,
search,
});
res.send(result);
};
export const getStockAuditRouteHandler = async (req, res) => {
try {
const id = new mongoose.Types.ObjectId(req.params.id);
const stockAudit = await stockAuditModel
.findOne({
_id: id,
})
.populate('createdBy')
.populate('items.filamentStock')
.populate('items.partStock');
if (!stockAudit) {
logger.warn(`Stock audit not found with supplied id.`);
return res.status(404).send({ error: 'Stock audit not found.' });
}
logger.trace(`Stock audit with ID: ${id}:`, stockAudit);
const auditLogs = await getAuditLogs(id);
res.send({ ...stockAudit._doc, auditLogs: auditLogs });
} catch (error) {
logger.error('Error fetching stock audit:', error);
res.status(500).send({ error: error.message });
}
};
export const newStockAuditRouteHandler = async (req, res) => {
try {
const newStockAudit = {
type: req.body.type,
status: req.body.status || 'pending',
notes: req.body.notes,
items: req.body.items.map((item) => ({
type: item.type,
stock:
item.type === 'filament'
? new mongoose.Types.ObjectId(item.filamentStock)
: new mongoose.Types.ObjectId(item.partStock),
expectedQuantity: item.expectedQuantity,
actualQuantity: item.actualQuantity,
notes: item.notes,
})),
createdBy: new mongoose.Types.ObjectId(req.body.createdBy),
completedAt: req.body.status === 'completed' ? new Date() : null,
};
const result = await stockAuditModel.create(newStockAudit);
if (!result) {
logger.error('No stock audit created.');
return res.status(500).send({ error: 'No stock audit created.' });
}
return res.send({ status: 'ok', id: result._id });
} catch (error) {
logger.error('Error adding stock audit:', error);
return res.status(500).send({ error: error.message });
}
};
export const updateStockAuditRouteHandler = async (req, res) => {
try {
const id = new mongoose.Types.ObjectId(req.params.id);
const updateData = {
...req.body,
items: req.body.items?.map((item) => ({
type: item.type,
stock:
item.type === 'filament'
? new mongoose.Types.ObjectId(item.filamentStock)
: new mongoose.Types.ObjectId(item.partStock),
expectedQuantity: item.expectedQuantity,
actualQuantity: item.actualQuantity,
notes: item.notes,
})),
completedAt: req.body.status === 'completed' ? new Date() : null,
};
const result = await stockAuditModel.findByIdAndUpdate(id, { $set: updateData }, { new: true });
if (!result) {
logger.warn(`Stock audit not found with supplied id.`);
return res.status(404).send({ error: 'Stock audit not found.' });
}
logger.trace(`Updated stock audit with ID: ${id}:`, result);
res.send(result);
} catch (error) {
logger.error('Error updating stock audit:', error);
res.status(500).send({ error: error.message });
}
};
export const deleteStockAuditRouteHandler = async (req, res) => {
try {
const id = new mongoose.Types.ObjectId(req.params.id);
const result = await stockAuditModel.findByIdAndDelete(id);
if (!result) {
logger.warn(`Stock audit not found with supplied id.`);
return res.status(404).send({ error: 'Stock audit not found.' });
}
logger.trace(`Deleted stock audit with ID: ${id}`);
res.send({ status: 'ok' });
} catch (error) {
logger.error('Error deleting stock audit:', error);
res.status(500).send({ error: error.message });
}
};
export const getStockAuditStatsRouteHandler = async (req, res) => {
const result = await getModelStats({ model: stockAuditModel });
if (result?.error) {
logger.error('Error fetching stock audit stats:', result.error);
return res.status(result.code).send(result);
}
logger.trace('Stock audit stats:', result);
res.send(result);
};
export const getStockAuditHistoryRouteHandler = async (req, res) => {
const from = req.query.from;
const to = req.query.to;
const result = await getModelHistory({ model: stockAuditModel, from, to });
if (result?.error) {
logger.error('Error fetching stock audit history:', result.error);
return res.status(result.code).send(result);
}
logger.trace('Stock audit history:', result);
res.send(result);
};