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.

This commit is contained in:
Tom Butcher 2025-12-27 14:01:46 +00:00
parent 2ac550b0c4
commit eb2e920028
11 changed files with 211 additions and 1 deletions

View File

@ -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);
});

View File

@ -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);
});

View File

@ -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);
});

View File

@ -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);
});

View File

@ -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);
});

View File

@ -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);

View File

@ -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(),

View File

@ -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,

View File

@ -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(),

View File

@ -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);

View File

@ -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(),