import dotenv from 'dotenv'; import { filamentModel } from '../../schemas/management/filament.schema.js'; import log4js from 'log4js'; import mongoose from 'mongoose'; import { newAuditLog, editAuditLog, distributeUpdate, flatternObjectIds, distributeNew, } from '../../utils.js'; import { listObjectsByProperties } from '../../database/database.js'; dotenv.config(); const logger = log4js.getLogger('Filaments'); logger.level = process.env.LOG_LEVEL; export const listFilamentsRouteHandler = async ( req, res, page = 1, limit = 25, property = '', filter = {}, search = '', sort = '', order = 'ascend' ) => { try { // Calculate the skip value based on the page number and limit const skip = (page - 1) * limit; let filament; let aggregateCommand = []; if (search) { // Add a text search match stage for name and brand fields aggregateCommand.push({ $match: { $text: { $search: search, }, }, }); } aggregateCommand.push({ $lookup: { from: 'vendors', // The collection name (usually lowercase plural) localField: 'vendor', // The field in your current model foreignField: '_id', // The field in the products collection as: 'vendor', // The output field name }, }); aggregateCommand.push({ $unwind: '$vendor' }); 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); filament = await filamentModel.aggregate(aggregateCommand); logger.trace( `List of filaments (Page ${page}, Limit ${limit}, Property ${property}):`, filament ); res.send(filament); } catch (error) { logger.error('Error listing filaments:', error); res.status(500).send({ error: error }); } }; export const listFilamentsByPropertiesRouteHandler = async ( req, res, properties = [], filter = {} ) => { const result = await listObjectsByProperties({ model: filamentModel, properties, filter, populate: 'vendor', }); if (result?.error) { logger.error('Error listing filaments.'); res.status(result.code).send(result); return; } logger.debug(`List of vendors. Count: ${result.length}`); res.send(result); }; export const getFilamentRouteHandler = async (req, res) => { try { // Get ID from params const id = new mongoose.Types.ObjectId(req.params.id); // Fetch the filament with the given remote address const filament = await filamentModel .findOne({ _id: id, }) .populate('vendor'); if (!filament) { logger.warn(`Filament not found with supplied id.`); return res.status(404).send({ error: 'Print job not found.' }); } logger.trace(`Filament with ID: ${id}:`, filament); res.send({ ...filament._doc }); } catch (error) { logger.error('Error fetching Filament:', error); res.status(500).send({ error: error.message }); } }; export const editFilamentRouteHandler = async (req, res) => { try { // Get ID from params const id = new mongoose.Types.ObjectId(req.params.id); // Fetch the filament with the given remote address const filament = await filamentModel.findOne({ _id: id }); if (!filament) { // Error handling logger.warn(`Filament not found with supplied id.`); return res.status(404).send({ error: 'Print job not found.' }); } logger.trace(`Filament with ID: ${id}:`, filament); try { const updateData = { updatedAt: new Date(), name: req.body.name, barcode: req.body.barcode, url: req.body.url, image: req.body.image, color: req.body.color, vendor: req.body.vendor, type: req.body.type, cost: req.body.cost, diameter: req.body.diameter, density: req.body.density, emptySpoolWeight: req.body.emptySpoolWeight, }; // Create audit log before updating await editAuditLog(filament.toObject(), updateData, id, 'filament', req.user); const result = await filamentModel.updateOne( { _id: id }, { $set: flatternObjectIds(updateData) } ); if (result.nModified === 0) { logger.error('No Filament updated.'); return res.status(500).send({ error: 'No filaments updated.' }); } await distributeUpdate(updateData, id, 'filament'); } catch (updateError) { logger.error('Error updating filament:', updateError); return res.status(500).send({ error: updateError.message }); } return res.send('OK'); } catch (fetchError) { logger.error('Error fetching filament:', fetchError); return res.status(500).send({ error: fetchError.message }); } }; export const newFilamentRouteHandler = async (req, res) => { try { const newFilament = { createdAt: new Date(), updatedAt: new Date(), name: req.body.name, barcode: req.body.barcode, url: req.body.url, image: req.body.image, color: req.body.color, vendor: req.body.vendor, type: req.body.type, cost: req.body.cost, diameter: req.body.diameter, density: req.body.density, emptySpoolWeight: req.body.emptySpoolWeight, }; const result = await filamentModel.create(flatternObjectIds(newFilament)); if (result.nCreated === 0) { logger.error('No filament created.'); res.status(500).send({ error: 'No filament created.' }); } // Create audit log for new filament await newAuditLog(newFilament, result._id, 'filament', req.user); await distributeNew(result._id, 'filament'); res.status(200).send({ status: 'ok' }); } catch (updateError) { logger.error('Error updating filament:', updateError); res.status(500).send({ error: updateError.message }); } };