From eb2e92002891c4b98a8122b49330208af4563a34 Mon Sep 17 00:00:00 2001 From: Tom Butcher Date: Sat, 27 Dec 2025 14:01:46 +0000 Subject: [PATCH] Add batch update functionality for filament stocks, order items, part stocks, purchase orders, shipments, and filaments. Implemented new route handlers for editing multiple records and enhanced existing services to support bulk updates. --- src/routes/inventory/filamentstocks.js | 6 +++ src/routes/inventory/orderitems.js | 6 +++ src/routes/inventory/partstocks.js | 6 +++ src/routes/inventory/purchaseorders.js | 6 +++ src/routes/inventory/shipments.js | 6 +++ src/routes/management/filaments.js | 6 +++ src/services/inventory/filamentstocks.js | 27 +++++++++++++ src/services/inventory/orderitems.js | 44 ++++++++++++++++++++ src/services/inventory/partstocks.js | 27 +++++++++++++ src/services/inventory/stockevents.js | 27 +++++++++++++ src/services/management/filaments.js | 51 +++++++++++++++++++++++- 11 files changed, 211 insertions(+), 1 deletion(-) diff --git a/src/routes/inventory/filamentstocks.js b/src/routes/inventory/filamentstocks.js index 16f842c..ef60df3 100644 --- a/src/routes/inventory/filamentstocks.js +++ b/src/routes/inventory/filamentstocks.js @@ -7,6 +7,7 @@ import { listFilamentStocksRouteHandler, getFilamentStockRouteHandler, editFilamentStockRouteHandler, + editMultipleFilamentStocksRouteHandler, newFilamentStockRouteHandler, deleteFilamentStockRouteHandler, listFilamentStocksByPropertiesRouteHandler, @@ -51,6 +52,11 @@ router.get('/:id', isAuthenticated, (req, res) => { getFilamentStockRouteHandler(req, res); }); +// update multiple filament stocks +router.put('/', isAuthenticated, async (req, res) => { + editMultipleFilamentStocksRouteHandler(req, res); +}); + router.put('/:id', isAuthenticated, async (req, res) => { editFilamentStockRouteHandler(req, res); }); diff --git a/src/routes/inventory/orderitems.js b/src/routes/inventory/orderitems.js index 21b9bc5..6c315c7 100644 --- a/src/routes/inventory/orderitems.js +++ b/src/routes/inventory/orderitems.js @@ -7,6 +7,7 @@ import { listOrderItemsRouteHandler, getOrderItemRouteHandler, editOrderItemRouteHandler, + editMultipleOrderItemsRouteHandler, newOrderItemRouteHandler, deleteOrderItemRouteHandler, listOrderItemsByPropertiesRouteHandler, @@ -51,6 +52,11 @@ router.get('/:id', isAuthenticated, (req, res) => { getOrderItemRouteHandler(req, res); }); +// update multiple order items +router.put('/', isAuthenticated, async (req, res) => { + editMultipleOrderItemsRouteHandler(req, res); +}); + router.put('/:id', isAuthenticated, async (req, res) => { editOrderItemRouteHandler(req, res); }); diff --git a/src/routes/inventory/partstocks.js b/src/routes/inventory/partstocks.js index 43e1128..6918316 100644 --- a/src/routes/inventory/partstocks.js +++ b/src/routes/inventory/partstocks.js @@ -7,6 +7,7 @@ import { listPartStocksRouteHandler, getPartStockRouteHandler, editPartStockRouteHandler, + editMultiplePartStocksRouteHandler, newPartStockRouteHandler, deletePartStockRouteHandler, listPartStocksByPropertiesRouteHandler, @@ -51,6 +52,11 @@ router.get('/:id', isAuthenticated, (req, res) => { getPartStockRouteHandler(req, res); }); +// update multiple part stocks +router.put('/', isAuthenticated, async (req, res) => { + editMultiplePartStocksRouteHandler(req, res); +}); + router.put('/:id', isAuthenticated, async (req, res) => { editPartStockRouteHandler(req, res); }); diff --git a/src/routes/inventory/purchaseorders.js b/src/routes/inventory/purchaseorders.js index 4459969..4b0160d 100644 --- a/src/routes/inventory/purchaseorders.js +++ b/src/routes/inventory/purchaseorders.js @@ -7,6 +7,7 @@ import { listPurchaseOrdersRouteHandler, getPurchaseOrderRouteHandler, editPurchaseOrderRouteHandler, + editMultiplePurchaseOrdersRouteHandler, newPurchaseOrderRouteHandler, deletePurchaseOrderRouteHandler, listPurchaseOrdersByPropertiesRouteHandler, @@ -51,6 +52,11 @@ router.get('/:id', isAuthenticated, (req, res) => { getPurchaseOrderRouteHandler(req, res); }); +// update multiple purchase orders +router.put('/', isAuthenticated, async (req, res) => { + editMultiplePurchaseOrdersRouteHandler(req, res); +}); + router.put('/:id', isAuthenticated, async (req, res) => { editPurchaseOrderRouteHandler(req, res); }); diff --git a/src/routes/inventory/shipments.js b/src/routes/inventory/shipments.js index fbed4a4..2acf609 100644 --- a/src/routes/inventory/shipments.js +++ b/src/routes/inventory/shipments.js @@ -7,6 +7,7 @@ import { listShipmentsRouteHandler, getShipmentRouteHandler, editShipmentRouteHandler, + editMultipleShipmentsRouteHandler, newShipmentRouteHandler, deleteShipmentRouteHandler, listShipmentsByPropertiesRouteHandler, @@ -65,6 +66,11 @@ router.get('/:id', isAuthenticated, (req, res) => { getShipmentRouteHandler(req, res); }); +// update multiple shipments +router.put('/', isAuthenticated, async (req, res) => { + editMultipleShipmentsRouteHandler(req, res); +}); + router.put('/:id', isAuthenticated, async (req, res) => { editShipmentRouteHandler(req, res); }); diff --git a/src/routes/management/filaments.js b/src/routes/management/filaments.js index 9638922..46a7f97 100644 --- a/src/routes/management/filaments.js +++ b/src/routes/management/filaments.js @@ -8,6 +8,7 @@ import { listFilamentsByPropertiesRouteHandler, getFilamentRouteHandler, editFilamentRouteHandler, + editMultipleFilamentsRouteHandler, newFilamentRouteHandler, getFilamentStatsRouteHandler, getFilamentHistoryRouteHandler, @@ -66,6 +67,11 @@ router.get('/:id', isAuthenticated, (req, res) => { getFilamentRouteHandler(req, res); }); +// update filaments info +router.put('/', isAuthenticated, async (req, res) => { + editMultipleFilamentsRouteHandler(req, res); +}); + // update printer info router.put('/:id', isAuthenticated, async (req, res) => { editFilamentRouteHandler(req, res); diff --git a/src/services/inventory/filamentstocks.js b/src/services/inventory/filamentstocks.js index 74ef3a4..46dac25 100644 --- a/src/services/inventory/filamentstocks.js +++ b/src/services/inventory/filamentstocks.js @@ -7,6 +7,7 @@ import { listObjects, getObject, editObject, + editObjects, newObject, listObjectsByProperties, getModelStats, @@ -114,6 +115,32 @@ export const editFilamentStockRouteHandler = async (req, res) => { res.send(result); }; +export const editMultipleFilamentStocksRouteHandler = async (req, res) => { + const updates = req.body.map((update) => ({ + _id: update._id, + })); + + if (!Array.isArray(updates)) { + return res.status(400).send({ error: 'Body must be an array of updates.', code: 400 }); + } + + const result = await editObjects({ + model: filamentStockModel, + updates, + user: req.user, + }); + + if (result.error) { + logger.error('Error editing filament stocks:', result.error); + res.status(result.code || 500).send(result); + return; + } + + logger.debug(`Edited ${updates.length} filament stocks`); + + res.send(result); +}; + export const newFilamentStockRouteHandler = async (req, res) => { const newData = { updatedAt: new Date(), diff --git a/src/services/inventory/orderitems.js b/src/services/inventory/orderitems.js index ef6bf22..98e305e 100644 --- a/src/services/inventory/orderitems.js +++ b/src/services/inventory/orderitems.js @@ -7,6 +7,7 @@ import { listObjects, getObject, editObject, + editObjects, newObject, listObjectsByProperties, getModelStats, @@ -43,6 +44,10 @@ export const listOrderItemsRouteHandler = async ( path: 'taxRate', strictPopulate: false, }, + { + path: 'shipment', + strictPopulate: false, + }, { path: 'item', populate: { path: 'costTaxRate', strictPopulate: false }, @@ -138,6 +143,7 @@ export const editOrderItemRouteHandler = async (req, res) => { itemAmount: req.body.itemAmount, quantity: req.body.quantity, totalAmount: req.body.totalAmount, + shipment: req.body.shipment, taxRate: req.body.taxRate, totalAmountWithTax: req.body.totalAmountWithTax, }; @@ -160,6 +166,43 @@ export const editOrderItemRouteHandler = async (req, res) => { res.send(result); }; +export const editMultipleOrderItemsRouteHandler = async (req, res) => { + const updates = req.body.map((update) => ({ + _id: update._id, + itemType: update.itemType, + item: update.item, + orderType: update.orderType, + order: update.order, + syncAmount: update.syncAmount, + itemAmount: update.itemAmount, + quantity: update.quantity, + totalAmount: update.totalAmount, + shipment: update.shipment, + taxRate: update.taxRate, + totalAmountWithTax: update.totalAmountWithTax, + })); + + if (!Array.isArray(updates)) { + return res.status(400).send({ error: 'Body must be an array of updates.', code: 400 }); + } + + const result = await editObjects({ + model: orderItemModel, + updates, + user: req.user, + }); + + if (result.error) { + logger.error('Error editing order items:', result.error); + res.status(result.code || 500).send(result); + return; + } + + logger.debug(`Edited ${updates.length} order items`); + + res.send(result); +}; + export const newOrderItemRouteHandler = async (req, res) => { const newData = { updatedAt: new Date(), @@ -175,6 +218,7 @@ export const newOrderItemRouteHandler = async (req, res) => { totalAmount: req.body.totalAmount, taxRate: req.body.taxRate, totalAmountWithTax: req.body.totalAmountWithTax, + shipment: req.body.shipment, }; const result = await newObject({ model: orderItemModel, diff --git a/src/services/inventory/partstocks.js b/src/services/inventory/partstocks.js index dd7b146..613c504 100644 --- a/src/services/inventory/partstocks.js +++ b/src/services/inventory/partstocks.js @@ -7,6 +7,7 @@ import { listObjects, getObject, editObject, + editObjects, newObject, listObjectsByProperties, getModelStats, @@ -114,6 +115,32 @@ export const editPartStockRouteHandler = async (req, res) => { res.send(result); }; +export const editMultiplePartStocksRouteHandler = async (req, res) => { + const updates = req.body.map((update) => ({ + _id: update._id, + })); + + if (!Array.isArray(updates)) { + return res.status(400).send({ error: 'Body must be an array of updates.', code: 400 }); + } + + const result = await editObjects({ + model: partStockModel, + updates, + user: req.user, + }); + + if (result.error) { + logger.error('Error editing part stocks:', result.error); + res.status(result.code || 500).send(result); + return; + } + + logger.debug(`Edited ${updates.length} part stocks`); + + res.send(result); +}; + export const newPartStockRouteHandler = async (req, res) => { const newData = { updatedAt: new Date(), diff --git a/src/services/inventory/stockevents.js b/src/services/inventory/stockevents.js index cde961b..cf919d9 100644 --- a/src/services/inventory/stockevents.js +++ b/src/services/inventory/stockevents.js @@ -7,6 +7,7 @@ import { listObjects, getObject, editObject, + editObjects, newObject, listObjectsByProperties, getModelStats, @@ -145,6 +146,32 @@ export const editStockEventRouteHandler = async (req, res) => { res.send(result); }; +export const editMultipleStockEventsRouteHandler = async (req, res) => { + const updates = req.body.map((update) => ({ + _id: update._id, + })); + + if (!Array.isArray(updates)) { + return res.status(400).send({ error: 'Body must be an array of updates.', code: 400 }); + } + + const result = await editObjects({ + model: stockEventModel, + updates, + user: req.user, + }); + + if (result.error) { + logger.error('Error editing stock events:', result.error); + res.status(result.code || 500).send(result); + return; + } + + logger.debug(`Edited ${updates.length} stock events`); + + res.send(result); +}; + export const deleteStockEventRouteHandler = async (req, res) => { // Get ID from params const id = new mongoose.Types.ObjectId(req.params.id); diff --git a/src/services/management/filaments.js b/src/services/management/filaments.js index a420be1..38cc8c9 100644 --- a/src/services/management/filaments.js +++ b/src/services/management/filaments.js @@ -7,6 +7,7 @@ import { listObjects, listObjectsByProperties, editObject, + editObjects, newObject, getModelStats, getModelHistory, @@ -58,7 +59,16 @@ export const listFilamentsByPropertiesRouteHandler = async ( model: filamentModel, properties, filter, - populate: 'vendor', + populate: [ + { + path: 'vendor', + from: 'vendors', + }, + { + path: 'costTaxRate', + from: 'taxrates', + }, + ], }); if (result?.error) { @@ -126,6 +136,45 @@ export const editFilamentRouteHandler = async (req, res) => { res.send(result); }; +export const editMultipleFilamentsRouteHandler = async (req, res) => { + const updates = req.body.map((update) => ({ + _id: update._id, + name: update.name, + barcode: update.barcode, + url: update.url, + image: update.image, + color: update.color, + vendor: update.vendor, + type: update.type, + cost: update.cost, + costTaxRate: update.costTaxRate, + costWithTax: update.costWithTax, + diameter: update.diameter, + density: update.density, + emptySpoolWeight: update.emptySpoolWeight, + })); + + if (!Array.isArray(updates)) { + return res.status(400).send({ error: 'Body must be an array of updates.', code: 400 }); + } + + const result = await editObjects({ + model: filamentModel, + updates, + user: req.user, + }); + + if (result.error) { + logger.error('Error editing filaments:', result.error); + res.status(result.code || 500).send(result); + return; + } + + logger.debug(`Edited ${updates.length} filaments`); + + res.send(result); +}; + export const newFilamentRouteHandler = async (req, res) => { const newData = { createdAt: new Date(),