191 lines
5.8 KiB
JavaScript
191 lines
5.8 KiB
JavaScript
import dotenv from 'dotenv';
|
|
import { filamentStockModel } from '../../schemas/inventory/filamentstock.schema.js';
|
|
import { filamentModel } from '../../schemas/management/filament.schema.js';
|
|
import { stockEventModel } from '../../schemas/inventory/stockevent.schema.js';
|
|
import log4js from 'log4js';
|
|
import mongoose from 'mongoose';
|
|
import { distributeNew, flatternObjectIds, getAuditLogs, newAuditLog } from '../../utils.js';
|
|
|
|
dotenv.config();
|
|
|
|
const logger = log4js.getLogger('Filament Stocks');
|
|
logger.level = process.env.LOG_LEVEL;
|
|
|
|
export const listFilamentStocksRouteHandler = async (
|
|
req,
|
|
res,
|
|
page = 1,
|
|
limit = 25,
|
|
property = '',
|
|
filter = {},
|
|
sort = '',
|
|
order = 'ascend'
|
|
) => {
|
|
try {
|
|
// Calculate the skip value based on the page number and limit
|
|
const skip = (page - 1) * limit;
|
|
|
|
let filamentStock;
|
|
let aggregateCommand = [];
|
|
|
|
aggregateCommand.push({
|
|
$lookup: {
|
|
from: 'filaments', // The collection name (usually lowercase plural)
|
|
localField: 'filament', // The field in your current model
|
|
foreignField: '_id', // The field in the products collection
|
|
as: 'filament', // The output field name
|
|
},
|
|
});
|
|
|
|
aggregateCommand.push({ $unwind: '$filament' });
|
|
|
|
if (filter != {}) {
|
|
// use filtering if present
|
|
aggregateCommand.push({ $match: filter });
|
|
}
|
|
|
|
if (property != '') {
|
|
aggregateCommand.push({ $group: { _id: `$${property}` } }); // group all same properties
|
|
aggregateCommand.push({ $project: { _id: 0, [property]: '$_id' } }); // rename _id to the property name
|
|
} else {
|
|
aggregateCommand.push({ $project: { image: 0, url: 0 } });
|
|
}
|
|
|
|
// Add sorting if sort parameter is provided
|
|
if (sort) {
|
|
const sortOrder = order === 'descend' ? -1 : 1;
|
|
aggregateCommand.push({ $sort: { [sort]: sortOrder } });
|
|
}
|
|
|
|
aggregateCommand.push({ $skip: skip });
|
|
aggregateCommand.push({ $limit: Number(limit) });
|
|
|
|
console.log(aggregateCommand);
|
|
|
|
filamentStock = await filamentStockModel.aggregate(aggregateCommand);
|
|
|
|
logger.trace(
|
|
`List of filamentStocks (Page ${page}, Limit ${limit}, Property ${property}):`,
|
|
filamentStock
|
|
);
|
|
res.send(filamentStock);
|
|
} catch (error) {
|
|
logger.error('Error listing filament stocks:', error);
|
|
res.status(500).send({ error: error });
|
|
}
|
|
};
|
|
|
|
export const getFilamentStockRouteHandler = async (req, res) => {
|
|
try {
|
|
// Get ID from params
|
|
const id = new mongoose.Types.ObjectId(req.params.id);
|
|
// Fetch the filamentStock with the given remote address
|
|
const filamentStock = await filamentStockModel
|
|
.findOne({
|
|
_id: id,
|
|
})
|
|
.populate('filament');
|
|
|
|
if (!filamentStock) {
|
|
logger.warn(`Filament stock not found with supplied id.`);
|
|
return res.status(404).send({ error: 'Print job not found.' });
|
|
}
|
|
|
|
logger.trace(`Filament stock with ID: ${id}:`, filamentStock);
|
|
|
|
const auditLogs = await getAuditLogs(id);
|
|
|
|
res.send({ ...filamentStock._doc, auditLogs: auditLogs });
|
|
} catch (error) {
|
|
logger.error('Error fetching filament stock:', error);
|
|
res.status(500).send({ error: error.message });
|
|
}
|
|
};
|
|
|
|
export const newFilamentStockRouteHandler = async (req, res) => {
|
|
var filament = null;
|
|
|
|
try {
|
|
// Get ID from params
|
|
const id = new mongoose.Types.ObjectId(req.body.filament._id);
|
|
// Fetch the filament with the given remote address
|
|
filament = await filamentModel.findOne({
|
|
_id: id,
|
|
});
|
|
|
|
if (!filament) {
|
|
logger.warn(`Filament not found with supplied id.`);
|
|
return res.status(404).send({ error: 'Filament not found.' });
|
|
}
|
|
|
|
logger.trace(`Filament with ID: ${id}:`, filament);
|
|
} catch (error) {
|
|
logger.error('Error fetching filament:', error);
|
|
return res.status(500).send({ error: error.message });
|
|
}
|
|
|
|
try {
|
|
logger.warn(req.body);
|
|
const startingWeight = req.body.startingWeight; // { net, gross }
|
|
if (!startingWeight || typeof startingWeight.gross !== 'number') {
|
|
return res.status(400).send({ error: 'startingWeight.gross is required' });
|
|
}
|
|
// Calculate net if not provided
|
|
const net =
|
|
typeof startingWeight.net === 'number'
|
|
? startingWeight.net
|
|
: startingWeight.gross - filament.emptySpoolWeight;
|
|
const starting = {
|
|
gross: startingWeight.gross,
|
|
net: net,
|
|
};
|
|
const newFilamentStock = {
|
|
startingWeight: starting,
|
|
currentWeight: { ...starting },
|
|
filament: req.body.filament,
|
|
state: {
|
|
type: 'unconsumed',
|
|
percent: '0', // schema requires string
|
|
},
|
|
};
|
|
|
|
const result = await filamentStockModel.create(flatternObjectIds(newFilamentStock));
|
|
|
|
if (!result) {
|
|
logger.error('No filament stock created.');
|
|
return res.status(500).send({ error: 'No filament stock created.' });
|
|
}
|
|
|
|
await newAuditLog(newFilamentStock, result._id, 'filamentStock', req.user);
|
|
await distributeNew(result._id, 'filamentStock');
|
|
|
|
console.log(result);
|
|
|
|
// Create initial stock event (optional, but keep logic if needed)
|
|
const stockEvent = {
|
|
value: starting.net,
|
|
current: starting.net,
|
|
unit: 'g',
|
|
parent: result,
|
|
parentType: 'filamentStock',
|
|
owner: req.user,
|
|
ownerType: 'user',
|
|
createdAt: new Date(),
|
|
updatedAt: new Date(),
|
|
};
|
|
|
|
const eventResult = await stockEventModel.create(flatternObjectIds(stockEvent));
|
|
if (!eventResult) {
|
|
logger.error('Failed to create initial stock event.');
|
|
return res.status(500).send({ error: 'Failed to create initial stock event.' });
|
|
}
|
|
|
|
await newAuditLog(stockEvent, eventResult._id, 'stockEvent', req.user);
|
|
|
|
return res.send({ status: 'ok' });
|
|
} catch (updateError) {
|
|
logger.error('Error adding filament stock:', updateError);
|
|
return res.status(500).send({ error: updateError.message });
|
|
}
|
|
};
|