From 01619d621a2718e3370f096e158c2bc6893b4b2a Mon Sep 17 00:00:00 2001 From: Tom Butcher Date: Sun, 24 Aug 2025 11:09:40 +0100 Subject: [PATCH] Using global functions for database interaction. --- src/routes/inventory/filamentstocks.js | 42 ++-- src/routes/management/users.js | 32 +-- src/routes/production/jobs.js | 12 +- src/services/inventory/filamentstocks.js | 284 ++++++++++------------- src/services/management/filaments.js | 264 ++++++++------------- src/services/management/hosts.js | 12 +- src/services/management/users.js | 188 +++++++-------- src/services/production/jobs.js | 32 ++- 8 files changed, 395 insertions(+), 471 deletions(-) diff --git a/src/routes/inventory/filamentstocks.js b/src/routes/inventory/filamentstocks.js index e6d0d39..70e7ed9 100644 --- a/src/routes/inventory/filamentstocks.js +++ b/src/routes/inventory/filamentstocks.js @@ -1,32 +1,34 @@ import express from 'express'; import { isAuthenticated } from '../../keycloak.js'; -import { parseFilter } from '../../utils.js'; +import { getFilter, convertPropertiesString } from '../../utils.js'; const router = express.Router(); import { listFilamentStocksRouteHandler, getFilamentStockRouteHandler, + editFilamentStockRouteHandler, newFilamentStockRouteHandler, + deleteFilamentStockRouteHandler, + listFilamentStocksByPropertiesRouteHandler, } from '../../services/inventory/filamentstocks.js'; -// list of filamentStocks +// list of filament stocks router.get('/', isAuthenticated, (req, res) => { - const { page, limit, property, sort, order } = req.query; + const { page, limit, property, search, sort, order } = req.query; + const allowedFilters = ['filament', 'state', 'startingWeight', 'currentWeight']; + const filter = getFilter(req.query, allowedFilters); + listFilamentStocksRouteHandler(req, res, page, limit, property, filter, search, sort, order); +}); - const allowedFilters = ['filament', 'filament._id']; - - var filter = {}; - - for (const [key, value] of Object.entries(req.query)) { - for (var i = 0; i < allowedFilters.length; i++) { - if (key == allowedFilters[i]) { - const parsedFilter = parseFilter(key, value); - filter = { ...filter, ...parsedFilter }; - } - } +router.get('/properties', isAuthenticated, (req, res) => { + let properties = convertPropertiesString(req.query.properties); + const allowedFilters = ['filament', 'state.type']; + const filter = getFilter(req.query, allowedFilters, false); + var masterFilter = {}; + if (req.query.masterFilter) { + masterFilter = JSON.parse(req.query.masterFilter); } - - listFilamentStocksRouteHandler(req, res, page, limit, property, filter, sort, order); + listFilamentStocksByPropertiesRouteHandler(req, res, properties, filter, masterFilter); }); router.post('/', isAuthenticated, (req, res) => { @@ -37,4 +39,12 @@ router.get('/:id', isAuthenticated, (req, res) => { getFilamentStockRouteHandler(req, res); }); +router.put('/:id', isAuthenticated, async (req, res) => { + editFilamentStockRouteHandler(req, res); +}); + +router.delete('/:id', isAuthenticated, async (req, res) => { + deleteFilamentStockRouteHandler(req, res); +}); + export default router; diff --git a/src/routes/management/users.js b/src/routes/management/users.js index e26f5f7..ac15246 100644 --- a/src/routes/management/users.js +++ b/src/routes/management/users.js @@ -1,34 +1,34 @@ import express from 'express'; import { isAuthenticated } from '../../keycloak.js'; -import { parseFilter } from '../../utils.js'; +import { convertPropertiesString, getFilter } from '../../utils.js'; const router = express.Router(); import { listUsersRouteHandler, + listUsersByPropertiesRouteHandler, getUserRouteHandler, editUserRouteHandler, } from '../../services/management/users.js'; -// list of users +// list of document templates router.get('/', isAuthenticated, (req, res) => { const { page, limit, property, search, sort, order } = req.query; - - const allowedFilters = ['username', 'name', 'firstName', 'lastName']; - - var filter = {}; - - for (const [key, value] of Object.entries(req.query)) { - for (var i = 0; i < allowedFilters.length; i++) { - if (key == allowedFilters[i]) { - const parsedFilter = parseFilter(key, value); - filter = { ...filter, ...parsedFilter }; - } - } - } - + const allowedFilters = ['name', 'username', 'firstName', 'lastName', 'email']; + const filter = getFilter(req.query, allowedFilters); listUsersRouteHandler(req, res, page, limit, property, filter, search, sort, order); }); +router.get('/properties', isAuthenticated, (req, res) => { + let properties = convertPropertiesString(req.query.properties); + const allowedFilters = []; + const filter = getFilter(req.query, allowedFilters, false); + var masterFilter = {}; + if (req.query.masterFilter) { + masterFilter = JSON.parse(req.query.masterFilter); + } + listUsersByPropertiesRouteHandler(req, res, properties, filter, masterFilter); +}); + router.get('/:id', isAuthenticated, (req, res) => { getUserRouteHandler(req, res); }); diff --git a/src/routes/production/jobs.js b/src/routes/production/jobs.js index 8d341d4..197278b 100644 --- a/src/routes/production/jobs.js +++ b/src/routes/production/jobs.js @@ -4,21 +4,29 @@ import { isAuthenticated } from '../../keycloak.js'; const router = express.Router(); import { listJobsRouteHandler, + listJobsByPropertiesRouteHandler, getJobRouteHandler, newJobRouteHandler, deleteJobRouteHandler, getJobStatsRouteHandler, } from '../../services/production/jobs.js'; -import { getFilter } from '../../utils.js'; +import { convertPropertiesString, getFilter } from '../../utils.js'; // list of jobs router.get('/', isAuthenticated, (req, res) => { const { page, limit, property, search, sort, order } = req.query; - const allowedFilters = ['country']; + const allowedFilters = ['state']; const filter = getFilter(req.query, allowedFilters); listJobsRouteHandler(req, res, page, limit, property, filter, search, sort, order); }); +router.get('/properties', isAuthenticated, (req, res) => { + let properties = convertPropertiesString(req.query.properties); + const allowedFilters = ['state']; + const filter = getFilter(req.query, allowedFilters, false); + listJobsByPropertiesRouteHandler(req, res, properties, filter); +}); + router.post('/', isAuthenticated, (req, res) => { newJobRouteHandler(req, res); }); diff --git a/src/services/inventory/filamentstocks.js b/src/services/inventory/filamentstocks.js index 525f0e2..47daa06 100644 --- a/src/services/inventory/filamentstocks.js +++ b/src/services/inventory/filamentstocks.js @@ -1,11 +1,15 @@ 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'; - +import { + deleteObject, + listObjects, + getObject, + editObject, + newObject, + listObjectsByProperties, +} from '../../database/database.js'; dotenv.config(); const logger = log4js.getLogger('Filament Stocks'); @@ -18,173 +22,137 @@ export const listFilamentStocksRouteHandler = async ( 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; + const result = await listObjects({ + model: filamentStockModel, + page, + limit, + property, + filter, + search, + sort, + order, + populate: [{ path: 'filament' }], + }); - 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 }); + if (result?.error) { + logger.error('Error listing filament stocks.'); + res.status(result.code).send(result); + return; } + + logger.debug(`List of filament stocks (Page ${page}, Limit ${limit}). Count: ${result.length}`); + res.send(result); +}; + +export const listFilamentStocksByPropertiesRouteHandler = async ( + req, + res, + properties = '', + filter = {}, + masterFilter = {} +) => { + const result = await listObjectsByProperties({ + model: filamentStockModel, + properties, + filter, + populate: ['filament'], + masterFilter, + }); + + if (result?.error) { + logger.error('Error listing filament stocks.'); + res.status(result.code).send(result); + return; + } + + logger.debug(`List of filament stocks. Count: ${result.length}`); + res.send(result); }; 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 }); + const id = req.params.id; + const result = await getObject({ + model: filamentStockModel, + id, + populate: [{ path: 'filament' }], + }); + if (result?.error) { + logger.warn(`Filament Stock not found with supplied id.`); + return res.status(result.code).send(result); } + logger.debug(`Retreived filament stock with ID: ${id}`); + res.send(result); +}; + +export const editFilamentStockRouteHandler = async (req, res) => { + // Get ID from params + const id = new mongoose.Types.ObjectId(req.params.id); + + logger.trace(`Filament Stock with ID: ${id}`); + + const updateData = {}; + // Create audit log before updating + const result = await editObject({ + model: filamentStockModel, + id, + updateData, + user: req.user, + }); + + if (result.error) { + logger.error('Error editing filament stock:', result.error); + res.status(result).send(result); + return; + } + + logger.debug(`Edited filament stock with ID: ${id}`); + + res.send(result); }; 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 }); + const newData = { + updatedAt: new Date(), + startingWeight: req.body.startingWeight, + currentWeight: req.body.currentWeight, + filament: req.body.filament, + }; + const result = await newObject({ + model: filamentStockModel, + newData, + user: req.user, + }); + if (result.error) { + logger.error('No filament stock created:', result.error); + return res.status(result.code).send(result); } - 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 - }, - }; + logger.debug(`New filament stock with ID: ${result._id}`); - 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 }); - } + res.send(result); +}; + +export const deleteFilamentStockRouteHandler = async (req, res) => { + // Get ID from params + const id = new mongoose.Types.ObjectId(req.params.id); + + logger.trace(`Filament Stock with ID: ${id}`); + + const result = await deleteObject({ + model: filamentStockModel, + id, + user: req.user, + }); + if (result.error) { + logger.error('No filament stock deleted:', result.error); + return res.status(result.code).send(result); + } + + logger.debug(`Deleted filament stock with ID: ${result._id}`); + + res.send(result); }; diff --git a/src/services/management/filaments.js b/src/services/management/filaments.js index b429e75..32df82f 100644 --- a/src/services/management/filaments.js +++ b/src/services/management/filaments.js @@ -1,15 +1,14 @@ -import dotenv from 'dotenv'; +import dotenv, { populate } 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'; + getObject, + listObjects, + listObjectsByProperties, + editObject, + newObject, +} from '../../database/database.js'; dotenv.config(); const logger = log4js.getLogger('Filaments'); @@ -26,69 +25,26 @@ export const listFilamentsRouteHandler = async ( sort = '', order = 'ascend' ) => { - try { - // Calculate the skip value based on the page number and limit - const skip = (page - 1) * limit; + const result = await listObjects({ + model: filamentModel, + page, + limit, + property, + filter, + search, + sort, + order, + populate: ['vendor'], + }); - 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 }); + if (result?.error) { + logger.error('Error listing filaments.'); + res.status(result.code).send(result); + return; } + + logger.debug(`List of filaments (Page ${page}, Limit ${limit}). Count: ${result.length}`); + res.send(result); }; export const listFilamentsByPropertiesRouteHandler = async ( @@ -115,118 +71,86 @@ export const listFilamentsByPropertiesRouteHandler = async ( }; 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 }); + const id = req.params.id; + const result = await getObject({ + model: filamentModel, + id, + populate: 'vendor', + }); + if (result?.error) { + logger.warn(`Filament not found with supplied id.`); + return res.status(result.code).send(result); } + logger.debug(`Retreived filament with ID: ${id}`); + res.send(result); }; 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 }); + // Get ID from params + const id = new mongoose.Types.ObjectId(req.params.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}`); - logger.trace(`Filament with ID: ${id}:`, filament); + 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, + }; + const result = await editObject({ + model: filamentModel, + id, + updateData, + user: req.user, + }); - 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 }); + if (result.error) { + logger.error('Error editing filament:', result.error); + res.status(result).send(result); + return; } + + logger.debug(`Edited filament with ID: ${id}`); + + res.send(result); }; 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 newData = { + 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 }); + const result = await newObject({ + model: filamentModel, + newData, + user: req.user, + }); + if (result.error) { + logger.error('No filament created:', result.error); + return res.status(result.code).send(result); } + + logger.debug(`New filament with ID: ${result._id}`); + + res.send(result); }; diff --git a/src/services/management/hosts.js b/src/services/management/hosts.js index 724e622..d4f2d96 100644 --- a/src/services/management/hosts.js +++ b/src/services/management/hosts.js @@ -47,11 +47,18 @@ export const listHostsRouteHandler = async ( res.send(result); }; -export const listHostsByPropertiesRouteHandler = async (req, res, properties = '', filter = {}) => { +export const listHostsByPropertiesRouteHandler = async ( + req, + res, + properties = '', + filter = {}, + masterFilter = {} +) => { const result = await listObjectsByProperties({ model: hostModel, properties, filter, + masterFilter, }); if (result?.error) { @@ -88,8 +95,9 @@ export const editHostRouteHandler = async (req, res) => { updatedAt: new Date(), name: req.body.name, active: req.body.active, + tags: req.body.tags, }; - // Create audit log before updating + const result = await editObject({ model: hostModel, id, diff --git a/src/services/management/users.js b/src/services/management/users.js index c36a90c..d977257 100644 --- a/src/services/management/users.js +++ b/src/services/management/users.js @@ -2,7 +2,12 @@ import dotenv from 'dotenv'; import { userModel } from '../../schemas/management/user.schema.js'; import log4js from 'log4js'; import mongoose from 'mongoose'; -import { distributeUpdate, editAuditLog } from '../../utils.js'; +import { + listObjects, + listObjectsByProperties, + getObject, + editObject, +} from '../../database/database.js'; dotenv.config(); @@ -20,122 +25,93 @@ export const listUsersRouteHandler = async ( sort = '', order = 'ascend' ) => { - try { - // Calculate the skip value based on the page number and limit - const skip = (page - 1) * limit; + const result = await listObjects({ + model: userModel, + page, + limit, + property, + filter, + search, + sort, + order, + }); - let user; - let aggregateCommand = []; - - if (search) { - // Add a text search match stage for name and brand fields - aggregateCommand.push({ - $match: { - $text: { - $search: search, - }, - }, - }); - } - - 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 - } - - // 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); - - user = await userModel.aggregate(aggregateCommand); - - logger.trace(`List of users (Page ${page}, Limit ${limit}, Property ${property}):`, user); - res.send(user); - } catch (error) { - logger.error('Error listing users:', error); - res.status(500).send({ error: error }); + if (result?.error) { + logger.error('Error listing users.'); + res.status(result.code).send(result); + return; } + + logger.debug(`List of users (Page ${page}, Limit ${limit}). Count: ${result.length}`); + res.send(result); +}; + +export const listUsersByPropertiesRouteHandler = async ( + req, + res, + properties = '', + filter = {}, + masterFilter = {} +) => { + const result = await listObjectsByProperties({ + model: userModel, + properties, + filter, + masterFilter, + }); + + if (result?.error) { + logger.error('Error listing users.'); + res.status(result.code).send(result); + return; + } + + logger.debug(`List of users. Count: ${result.length}`); + res.send(result); }; export const getUserRouteHandler = async (req, res) => { - try { - // Get ID from params - const id = new mongoose.Types.ObjectId(req.params.id); - // Fetch the user with the given ID - const user = await userModel.findOne({ - _id: id, - }); - - if (!user) { - logger.warn(`User not found with supplied id.`); - return res.status(404).send({ error: 'User not found.' }); - } - - logger.trace(`User with ID: ${id}:`, user); - - res.send({ ...user._doc }); - } catch (error) { - logger.error('Error fetching User:', error); - res.status(500).send({ error: error.message }); + const id = req.params.id; + const result = await getObject({ + model: userModel, + id, + }); + if (result?.error) { + logger.warn(`User not found with supplied id.`); + return res.status(result.code).send(result); } + logger.debug(`Retreived user with ID: ${id}`); + res.send(result); }; export const editUserRouteHandler = async (req, res) => { - try { - // Get ID from params - const id = new mongoose.Types.ObjectId(req.params.id); - // Fetch the user with the given ID - const user = await userModel.findOne({ _id: id }); + // Get ID from params + const id = new mongoose.Types.ObjectId(req.params.id); - if (!user) { - // Error handling - logger.warn(`User not found with supplied id.`); - return res.status(404).send({ error: 'User not found.' }); - } + logger.trace(`User with ID: ${id}`); - logger.trace(`User with ID: ${id}:`, user); + const updateData = { + updatedAt: new Date(), + name: req.body.name, + firstName: req.body.firstName, + lastName: req.body.lastName, + email: req.body.email, + }; + // Create audit log before updating + const result = await editObject({ + model: userModel, + id, + updateData, + user: req.user, + }); - try { - const updateData = { - updatedAt: new Date(), - username: req.body.username, - name: req.body.name, - firstName: req.body.firstName, - lastName: req.body.lastName, - email: req.body.email, - }; - - console.log(req.user); - - // Create audit log before updating - await editAuditLog(user.toObject(), updateData, id, 'user', req.user); - - const result = await userModel.updateOne({ _id: id }, { $set: updateData }); - if (result.nModified === 0) { - logger.error('No User updated.'); - res.status(500).send({ error: 'No users updated.' }); - } - - await distributeUpdate(updateData, id, 'user'); - } catch (updateError) { - logger.error('Error updating user:', updateError); - res.status(500).send({ error: updateError.message }); - } - res.send('OK'); - } catch (fetchError) { - logger.error('Error fetching user:', fetchError); - res.status(500).send({ error: fetchError.message }); + if (result.error) { + logger.error('Error editing user:', result.error); + res.status(result).send(result); + return; } + + logger.debug(`Edited user with ID: ${id}`); + + res.send(result); }; diff --git a/src/services/production/jobs.js b/src/services/production/jobs.js index 0814a82..4ccaa76 100644 --- a/src/services/production/jobs.js +++ b/src/services/production/jobs.js @@ -2,7 +2,13 @@ import dotenv from 'dotenv'; import mongoose from 'mongoose'; import { jobModel } from '../../schemas/production/job.schema.js'; import log4js from 'log4js'; -import { deleteObject, getObject, listObjects, newObject } from '../../database/database.js'; +import { + deleteObject, + getObject, + listObjects, + listObjectsByProperties, + newObject, +} from '../../database/database.js'; import { subJobModel } from '../../schemas/production/subjob.schema.js'; dotenv.config(); @@ -42,6 +48,30 @@ export const listJobsRouteHandler = async ( res.send(result); }; +export const listJobsByPropertiesRouteHandler = async ( + req, + res, + properties = '', + filter = {}, + masterFilter = {} +) => { + const result = await listObjectsByProperties({ + model: jobModel, + properties, + filter, + masterFilter, + }); + + if (result?.error) { + logger.error('Error listing jobs.'); + res.status(result.code).send(result); + return; + } + + logger.debug(`List of jobs. Count: ${result.length}`); + res.send(result); +}; + export const getJobRouteHandler = async (req, res) => { const id = req.params.id; const result = await getObject({