All checks were successful
farmcontrol/farmcontrol-api/pipeline/head This commit looks good
This commit introduces a new `deleteObjects` function in the database module, allowing for bulk deletion of objects based on specified filters and states. Additionally, new route handlers for deleting invoices, payment policies, payments, tax records, filament stocks, order items, part stocks, product stocks, purchase orders, shipments, stock audits, stock locations, stock transfers, app passwords, couriers, courier services, document printers, document sizes, document templates, email accounts, email templates, filaments, filament SKUs, files, hosts, materials, note types, parts, part SKUs, permission settings, product categories, products, and vendor entities are added. Each route supports deletion based on filters, enhancing the application's data management capabilities.
478 lines
11 KiB
JavaScript
478 lines
11 KiB
JavaScript
import config from '../../config.js';
|
|
import { orderItemModel } from '../../database/schemas/inventory/orderitem.schema.js';
|
|
import { getModelByName } from '../misc/model.js';
|
|
import log4js from 'log4js';
|
|
import mongoose from 'mongoose';
|
|
import {
|
|
deleteObject,
|
|
deleteObjects,
|
|
listObjects,
|
|
getObject,
|
|
editObject,
|
|
editObjects,
|
|
newObject,
|
|
listObjectsByProperties,
|
|
getModelStats,
|
|
getModelHistory,
|
|
searchObjects,
|
|
getPropertyValues,
|
|
getObjectNeighbors,
|
|
} from '../../database/database.js';
|
|
const logger = log4js.getLogger('Order Items');
|
|
logger.level = config.server.logLevel;
|
|
|
|
const ORDER_ITEM_POPULATE = [
|
|
{
|
|
path: 'order',
|
|
},
|
|
{
|
|
path: 'taxRate',
|
|
strictPopulate: false,
|
|
},
|
|
{
|
|
path: 'item',
|
|
populate: [
|
|
{ path: 'costTaxRate', strictPopulate: false },
|
|
{ path: 'priceTaxRate', strictPopulate: false },
|
|
],
|
|
strictPopulate: false,
|
|
},
|
|
{
|
|
path: 'sku',
|
|
strictPopulate: false,
|
|
populate: [
|
|
{
|
|
path: 'filament',
|
|
populate: { path: 'costTaxRate', strictPopulate: false },
|
|
strictPopulate: false,
|
|
},
|
|
{
|
|
path: 'part',
|
|
populate: [
|
|
{ path: 'costTaxRate', strictPopulate: false },
|
|
{ path: 'priceTaxRate', strictPopulate: false },
|
|
],
|
|
strictPopulate: false,
|
|
},
|
|
{
|
|
path: 'product',
|
|
populate: [
|
|
{ path: 'costTaxRate', strictPopulate: false },
|
|
{ path: 'priceTaxRate', strictPopulate: false },
|
|
],
|
|
strictPopulate: false,
|
|
},
|
|
{ path: 'costTaxRate', strictPopulate: false },
|
|
{ path: 'priceTaxRate', strictPopulate: false },
|
|
],
|
|
},
|
|
];
|
|
|
|
export const listOrderItemsRouteHandler = async (
|
|
req,
|
|
res,
|
|
page = 1,
|
|
limit = 25,
|
|
property = '',
|
|
filter = {},
|
|
search = '',
|
|
sort = '',
|
|
order = 'ascend'
|
|
) => {
|
|
const result = await listObjects({
|
|
model: orderItemModel,
|
|
page,
|
|
limit,
|
|
property,
|
|
filter,
|
|
search,
|
|
sort,
|
|
order,
|
|
populate: [
|
|
{
|
|
path: 'order',
|
|
},
|
|
{
|
|
path: 'taxRate',
|
|
strictPopulate: false,
|
|
},
|
|
{
|
|
path: 'shipment',
|
|
strictPopulate: false,
|
|
},
|
|
{
|
|
path: 'item',
|
|
populate: [
|
|
{ path: 'costTaxRate', strictPopulate: false },
|
|
{ path: 'priceTaxRate', strictPopulate: false },
|
|
],
|
|
},
|
|
{
|
|
path: 'sku',
|
|
strictPopulate: false,
|
|
populate: [
|
|
{
|
|
path: 'filament',
|
|
populate: { path: 'costTaxRate', strictPopulate: false },
|
|
strictPopulate: false,
|
|
},
|
|
{
|
|
path: 'part',
|
|
populate: [
|
|
{ path: 'costTaxRate', strictPopulate: false },
|
|
{ path: 'priceTaxRate', strictPopulate: false },
|
|
],
|
|
strictPopulate: false,
|
|
},
|
|
{
|
|
path: 'product',
|
|
populate: [
|
|
{ path: 'costTaxRate', strictPopulate: false },
|
|
{ path: 'priceTaxRate', strictPopulate: false },
|
|
],
|
|
strictPopulate: false,
|
|
},
|
|
{ path: 'costTaxRate', strictPopulate: false },
|
|
{ path: 'priceTaxRate', strictPopulate: false },
|
|
],
|
|
},
|
|
],
|
|
});
|
|
|
|
if (result?.error) {
|
|
logger.error('Error listing order items.');
|
|
res.status(result.code).send(result);
|
|
return;
|
|
}
|
|
|
|
logger.debug(`List of order items (Page ${page}, Limit ${limit}). Count: ${result.length}`);
|
|
res.send(result);
|
|
};
|
|
|
|
export const listOrderItemsByPropertiesRouteHandler = async (
|
|
req,
|
|
res,
|
|
properties = '',
|
|
filter = {},
|
|
masterFilter = {}
|
|
) => {
|
|
const result = await listObjectsByProperties({
|
|
model: orderItemModel,
|
|
properties,
|
|
filter,
|
|
populate: [],
|
|
masterFilter,
|
|
});
|
|
|
|
if (result?.error) {
|
|
logger.error('Error listing order items.');
|
|
res.status(result.code).send(result);
|
|
return;
|
|
}
|
|
|
|
logger.debug(`List of order items. Count: ${result.length}`);
|
|
res.send(result);
|
|
};
|
|
|
|
export const getOrderItemPropertyValuesRouteHandler = async (
|
|
req,
|
|
res,
|
|
property,
|
|
filter,
|
|
masterFilter
|
|
) => {
|
|
const result = await getPropertyValues({
|
|
model: orderItemModel,
|
|
property,
|
|
filter: { ...filter, ...masterFilter },
|
|
});
|
|
res.send(result);
|
|
};
|
|
|
|
export const searchOrderItemsRouteHandler = async (req, res, search) => {
|
|
const result = await searchObjects({
|
|
model: orderItemModel,
|
|
search,
|
|
});
|
|
res.send(result);
|
|
};
|
|
|
|
export const getOrderItemRouteHandler = async (req, res) => {
|
|
const id = req.params.id;
|
|
const result = await getObject({
|
|
model: orderItemModel,
|
|
id,
|
|
populate: ORDER_ITEM_POPULATE,
|
|
});
|
|
if (result?.error) {
|
|
logger.warn(`Order Item not found with supplied id.`);
|
|
return res.status(result.code).send(result);
|
|
}
|
|
logger.debug(`Retreived order item with ID: ${id}`);
|
|
res.send(result);
|
|
};
|
|
|
|
export const editOrderItemRouteHandler = async (req, res) => {
|
|
// Get ID from params
|
|
const id = new mongoose.Types.ObjectId(req.params.id);
|
|
|
|
logger.trace(`Order Item with ID: ${id}`);
|
|
|
|
const skuType =
|
|
req.body.sku && req.body.itemType ? req.body.itemType + 'Sku' : null;
|
|
|
|
let name = req.body.name;
|
|
if (!name && req.body.sku && skuType) {
|
|
const skuEntry = getModelByName(skuType);
|
|
if (skuEntry?.model) {
|
|
const sku = await getObject({
|
|
model: skuEntry.model,
|
|
id: req.body.sku,
|
|
cached: true,
|
|
});
|
|
name = sku?.name;
|
|
}
|
|
}
|
|
if (!name && req.body.item && req.body.itemType) {
|
|
const itemEntry = getModelByName(req.body.itemType);
|
|
if (itemEntry?.model) {
|
|
const item = await getObject({
|
|
model: itemEntry.model,
|
|
id: req.body.item,
|
|
cached: true,
|
|
});
|
|
name = item?.name;
|
|
}
|
|
}
|
|
|
|
const updateData = {
|
|
updatedAt: new Date(),
|
|
name: req.body.name ?? name,
|
|
itemType: req.body.itemType,
|
|
item: req.body.item,
|
|
sku: req.body.sku,
|
|
orderType: req.body.orderType,
|
|
order: req.body.order,
|
|
syncAmount: req.body.syncAmount,
|
|
itemAmount: req.body.itemAmount,
|
|
quantity: req.body.quantity,
|
|
totalAmount: req.body.totalAmount,
|
|
shipment: req.body.shipment,
|
|
taxRate: req.body.taxRate,
|
|
totalAmountWithTax: req.body.totalAmountWithTax,
|
|
};
|
|
// Create audit log before updating
|
|
const result = await editObject({
|
|
model: orderItemModel,
|
|
id,
|
|
updateData,
|
|
user: req.user,
|
|
populate: ORDER_ITEM_POPULATE,
|
|
});
|
|
|
|
if (result.error) {
|
|
logger.error('Error editing order item:', result.error);
|
|
res.status(result.code || 500).send(result);
|
|
return;
|
|
}
|
|
|
|
logger.debug(`Edited order item with ID: ${id}`);
|
|
|
|
res.send(result);
|
|
};
|
|
|
|
export const editMultipleOrderItemsRouteHandler = async (req, res) => {
|
|
const updates = req.body.map((update) => ({
|
|
_id: update._id,
|
|
name: update.name,
|
|
itemType: update.itemType,
|
|
item: update.item,
|
|
sku: update.sku,
|
|
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 skuType =
|
|
req.body.sku && req.body.itemType ? req.body.itemType + 'Sku' : null;
|
|
|
|
let name = req.body.name;
|
|
if (!name && req.body.sku && skuType) {
|
|
const skuEntry = getModelByName(skuType);
|
|
if (skuEntry?.model) {
|
|
const sku = await getObject({
|
|
model: skuEntry.model,
|
|
id: req.body.sku,
|
|
cached: true,
|
|
});
|
|
name = sku?.name;
|
|
}
|
|
}
|
|
if (!name && req.body.item && req.body.itemType) {
|
|
const itemEntry = getModelByName(req.body.itemType);
|
|
if (itemEntry?.model) {
|
|
const item = await getObject({
|
|
model: itemEntry.model,
|
|
id: req.body.item,
|
|
cached: true,
|
|
});
|
|
name = item?.name;
|
|
}
|
|
}
|
|
|
|
const newData = {
|
|
updatedAt: new Date(),
|
|
name: name || 'Order Item',
|
|
purchaseOrder: req.body.purchaseOrder,
|
|
state: { type: 'draft' },
|
|
itemType: req.body.itemType,
|
|
item: req.body.item,
|
|
sku: req.body.sku,
|
|
orderType: req.body.orderType,
|
|
order: req.body.order,
|
|
syncAmount: req.body.syncAmount,
|
|
itemAmount: req.body.itemAmount,
|
|
quantity: req.body.quantity,
|
|
totalAmount: req.body.totalAmount,
|
|
taxRate: req.body.taxRate,
|
|
totalAmountWithTax: req.body.totalAmountWithTax,
|
|
shipment: req.body.shipment,
|
|
};
|
|
const result = await newObject({
|
|
model: orderItemModel,
|
|
newData,
|
|
user: req.user,
|
|
});
|
|
if (result.error) {
|
|
logger.error('No order item created:', result.error);
|
|
return res.status(result.code).send(result);
|
|
}
|
|
|
|
logger.debug(`New order item with ID: ${result._id}`);
|
|
|
|
res.send(result);
|
|
};
|
|
|
|
export const deleteOrderItemByFilterRouteHandler = async (
|
|
req,
|
|
res,
|
|
filter = {},
|
|
masterFilter = {}
|
|
) => {
|
|
const result = await deleteObjects({
|
|
model: orderItemModel,
|
|
filter: { ...masterFilter, ...filter },
|
|
user: req.user,
|
|
});
|
|
|
|
if (result.error) {
|
|
logger.error('Failed to delete filtered OrderItem:', result.error);
|
|
return res.status(result.code || 500).send(result);
|
|
}
|
|
|
|
res.send(result);
|
|
};
|
|
|
|
export const deleteOrderItemRouteHandler = async (req, res) => {
|
|
// Get ID from params
|
|
const id = new mongoose.Types.ObjectId(req.params.id);
|
|
|
|
logger.trace(`Order Item with ID: ${id}`);
|
|
|
|
const result = await deleteObject({
|
|
model: orderItemModel,
|
|
id,
|
|
user: req.user,
|
|
});
|
|
if (result.error) {
|
|
logger.error('No order item deleted:', result.error);
|
|
return res.status(result.code).send(result);
|
|
}
|
|
|
|
logger.debug(`Deleted order item with ID: ${result._id}`);
|
|
|
|
res.send(result);
|
|
};
|
|
|
|
export const getOrderItemStatsRouteHandler = async (req, res) => {
|
|
const result = await getModelStats({ model: orderItemModel });
|
|
if (result?.error) {
|
|
logger.error('Error fetching order item stats:', result.error);
|
|
return res.status(result.code).send(result);
|
|
}
|
|
logger.trace('Order item stats:', result);
|
|
res.send(result);
|
|
};
|
|
|
|
export const getOrderItemHistoryRouteHandler = async (req, res) => {
|
|
const from = req.query.from;
|
|
const to = req.query.to;
|
|
const result = await getModelHistory({ model: orderItemModel, from, to });
|
|
if (result?.error) {
|
|
logger.error('Error fetching order item history:', result.error);
|
|
return res.status(result.code).send(result);
|
|
}
|
|
logger.trace('Order item history:', result);
|
|
res.send(result);
|
|
};
|
|
export const getOrderItemNeighborsRouteHandler = async (
|
|
req,
|
|
res,
|
|
property = '',
|
|
filter = {},
|
|
search = '',
|
|
sort = '',
|
|
order = 'ascend',
|
|
id
|
|
) => {
|
|
if (!id) {
|
|
return res.status(400).send({ error: 'Missing id parameter', code: 400 });
|
|
}
|
|
|
|
const result = await getObjectNeighbors({
|
|
model: orderItemModel,
|
|
id,
|
|
filter,
|
|
search,
|
|
sort,
|
|
order,
|
|
});
|
|
|
|
if (result?.error) {
|
|
logger.error('Error fetching orderItem neighbors.');
|
|
return res.status(result.code).send(result);
|
|
}
|
|
|
|
logger.debug(`Retrieved orderItem neighbors for ID: ${id}`);
|
|
res.send(result);
|
|
};
|
|
|