committed by
GitHub
parent
52d020717c
commit
4763da2d69
@@ -1,7 +1,6 @@
|
||||
const mongoose = require("mongoose");
|
||||
const Item = require("../models/Item");
|
||||
const WidgetFamily = require("../models/WidgetFamily");
|
||||
const Inventory = require("../models/Inventory");
|
||||
const {
|
||||
PickItemTransaction,
|
||||
PutItemTransaction,
|
||||
@@ -11,11 +10,11 @@ const {
|
||||
ReportItemTransaction,
|
||||
AdjustItemTransaction,
|
||||
} = require("../models/ItemTransaction");
|
||||
|
||||
const { S3 } = require("./../config/aws");
|
||||
const ItemAssociation = require("../models/ItemAssociation");
|
||||
const Sublevel = require("../models/Sublevel");
|
||||
const { InventoryTypes, ReportItemForTypes } = require("../config/constants");
|
||||
|
||||
const { ReportItemForTypes } = require("../config/constants");
|
||||
const { filterItems, filterItemAssociations } = require("./utils/aggregation");
|
||||
module.exports = {
|
||||
/**
|
||||
* Gets the Item data by `id`
|
||||
@@ -24,16 +23,22 @@ module.exports = {
|
||||
const { id } = req.params;
|
||||
|
||||
if (!id) {
|
||||
res.status(400).send("Missing id param");
|
||||
res.status(400).send({ success: false, error: "Missing id param" });
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const itemData = await Item.findById(id);
|
||||
const itemData = await Item.findById(id).populate({ path: "widgetFamily", populate: "inventory" });
|
||||
if (!itemData) {
|
||||
res.status(404);
|
||||
res.status(404).send({ success: false, error: "Item not found" });
|
||||
return;
|
||||
}
|
||||
if (itemData.images && itemData.images.length > 0) {
|
||||
itemData.images = itemData.images.map((_) => {
|
||||
return { _id: _._id, url: S3.generatePresignedUrl(_.url) };
|
||||
});
|
||||
}
|
||||
|
||||
res.send({ success: true, data: itemData });
|
||||
} catch (error) {
|
||||
next(error);
|
||||
@@ -63,9 +68,16 @@ module.exports = {
|
||||
countPerPalletPackage: req.body.countPerPalletPackage,
|
||||
customAttributes: req.body.customAttributes,
|
||||
widgetFamily: widgetFamily,
|
||||
policiesMetadata: {
|
||||
underStockLevelCount: req.body.policiesMetadata.underStockLevelCount,
|
||||
overStockLevelCount: req.body.policiesMetadata.overStockLevelCount,
|
||||
alertStockLevelCount: req.body.policiesMetadata.alertStockLevelCount,
|
||||
reorderStockLevelCount: req.body.policiesMetadata.reorderStockLevelCount,
|
||||
},
|
||||
};
|
||||
|
||||
for (const key of Object.keys(item)) {
|
||||
if (["customAttributes"].includes(key)) continue;
|
||||
if (item[key] === undefined) {
|
||||
res.status(400).send({ success: false, error: `Missing required param: "${key}"` });
|
||||
return;
|
||||
@@ -80,6 +92,24 @@ module.exports = {
|
||||
res.status(404);
|
||||
return;
|
||||
}
|
||||
|
||||
const images = req.files;
|
||||
|
||||
for (let i = 0; i < images.length; i++) {
|
||||
const url = await S3.uploadFile(
|
||||
`item/${itemData._id.toString()}-${Date.now()}-${i}.${images[i].originalname.split(".").slice(-1).pop()}`,
|
||||
images[i].path
|
||||
);
|
||||
itemData.images ||= [];
|
||||
itemData.images.push({ url });
|
||||
}
|
||||
itemData.save();
|
||||
|
||||
if (itemData.images) {
|
||||
itemData.images = itemData.images.map((_) => {
|
||||
return { _id: _._id, url: S3.generatePresignedUrl(_.url) };
|
||||
});
|
||||
}
|
||||
res.send({ success: true, data: itemData });
|
||||
} catch (error) {
|
||||
next(error);
|
||||
@@ -130,8 +160,32 @@ module.exports = {
|
||||
itemData[key] = item[key];
|
||||
}
|
||||
}
|
||||
// Removal of images
|
||||
const existingImageIds = req.body.imageIds || [];
|
||||
itemData.images = itemData.images.filter((image) => {
|
||||
if (!image) return false;
|
||||
return existingImageIds.includes(image._id.toString());
|
||||
});
|
||||
// Addition of images
|
||||
const images = req.files;
|
||||
if (images && Array.isArray(images)) {
|
||||
for (let i = 0; i < images.length; i++) {
|
||||
const url = await S3.uploadFile(
|
||||
`item/${itemData._id.toString()}-${Date.now()}-${i}.${images[i].originalname.split(".").slice(-1).pop()}`,
|
||||
images[i].path
|
||||
);
|
||||
itemData.images ||= [];
|
||||
itemData.images.push({ url });
|
||||
}
|
||||
}
|
||||
|
||||
await itemData.save();
|
||||
|
||||
if (itemData.images) {
|
||||
itemData.images = itemData.images.map((_) => {
|
||||
return { _id: _._id, url: S3.generatePresignedUrl(_.url) };
|
||||
});
|
||||
}
|
||||
res.send({ success: true, data: itemData });
|
||||
} catch (error) {
|
||||
next(error);
|
||||
@@ -142,75 +196,39 @@ module.exports = {
|
||||
* Gets the Items data by filter
|
||||
*/
|
||||
getItemsByFilter: async (req, res, next) => {
|
||||
let { family, type, inventory, page, perPage } = req.query;
|
||||
let { family, inventory, page, perPage } = req.query;
|
||||
page = page ? parseInt(page) : 0;
|
||||
perPage = perPage ? parseInt(perPage) : 10;
|
||||
const inventoryFilters = {};
|
||||
let inventories;
|
||||
let widgetFamilies;
|
||||
let itemFilters;
|
||||
try {
|
||||
if (type && InventoryTypes.includes(type)) {
|
||||
inventoryFilters["type"] = type;
|
||||
}
|
||||
const results = await filterItems(inventory, family, page, perPage);
|
||||
|
||||
if (inventory) {
|
||||
inventoryFilters["_id"] = inventory;
|
||||
for (const item of results[0].result) {
|
||||
if (item.images) {
|
||||
item.images = item.images.map((_) => {
|
||||
return { _id: _._id, url: S3.generatePresignedUrl(_.url) };
|
||||
});
|
||||
}
|
||||
}
|
||||
res.send({ success: true, data: results[0] });
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
},
|
||||
getItemAssociationsByFilter: async (req, res, next) => {
|
||||
let { family, inventory, page, perPage } = req.query;
|
||||
page = page ? parseInt(page) : 0;
|
||||
perPage = perPage ? parseInt(perPage) : 10;
|
||||
try {
|
||||
const results = await filterItemAssociations(inventory, family, page, perPage);
|
||||
|
||||
if (Object.keys(inventoryFilters).length > 0) {
|
||||
inventories = await Inventory.find(inventoryFilters);
|
||||
for (const item of results[0].result) {
|
||||
if (item.images) {
|
||||
item.images = item.images.map((_) => {
|
||||
return { _id: _._id, url: S3.generatePresignedUrl(_.url) };
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const widgetFamilyFilters = [];
|
||||
if (inventories) {
|
||||
widgetFamilyFilters.push({
|
||||
inventory: { $in: inventories.map((_) => _._id) },
|
||||
});
|
||||
}
|
||||
|
||||
if (family) {
|
||||
widgetFamilyFilters.push({
|
||||
name: family,
|
||||
});
|
||||
}
|
||||
if (widgetFamilyFilters.length > 0) {
|
||||
widgetFamilies = await WidgetFamily.find({
|
||||
$or: widgetFamilyFilters,
|
||||
});
|
||||
}
|
||||
|
||||
if (widgetFamilies) {
|
||||
itemFilters = { widgetFamily: { $in: widgetFamilies.map((_) => _._id) } };
|
||||
} else {
|
||||
itemFilters = {};
|
||||
}
|
||||
const itemData = await Item.find(
|
||||
itemFilters,
|
||||
{
|
||||
id: 1,
|
||||
commonName: 1,
|
||||
formalName: 1,
|
||||
description: 1,
|
||||
manufacturer: 1,
|
||||
widgetFamily: 1,
|
||||
size: 1,
|
||||
color: 1,
|
||||
type: 1,
|
||||
unitOfMaterial: 1,
|
||||
unitCost: 1,
|
||||
packageCount: 1,
|
||||
countPerPallet: 1,
|
||||
countPerPalletPackage: 1,
|
||||
customAttributes: 1,
|
||||
},
|
||||
{ skip: page * perPage, limit: perPage }
|
||||
).populate({ path: "widgetFamily" });
|
||||
if (!itemData) {
|
||||
res.status(404);
|
||||
return;
|
||||
}
|
||||
res.send({ success: true, data: itemData });
|
||||
res.send({ success: true, data: results[0] });
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
@@ -229,7 +247,7 @@ module.exports = {
|
||||
return;
|
||||
}
|
||||
|
||||
const { putQuantity, subLevel } = req.body;
|
||||
const { putQuantity, subLevel, usageReason, job } = req.body;
|
||||
if (!(putQuantity && putQuantity > 0) || !(subLevel && mongoose.isValidObjectId(subLevel))) {
|
||||
res.status(400).send("Invalid value for putQuantity/subLevel");
|
||||
return;
|
||||
@@ -250,6 +268,8 @@ module.exports = {
|
||||
performedBy: res.locals.user,
|
||||
putQuantity: putQuantity,
|
||||
subLevel: subLevelObj,
|
||||
usageReason: usageReason ? usageReason : "",
|
||||
job: job,
|
||||
});
|
||||
res.send({ success: true, data: { itemAssociation, itemTransaction } });
|
||||
res.send({ success: true, data: { itemAssociation, itemTransaction } });
|
||||
@@ -272,7 +292,7 @@ module.exports = {
|
||||
return;
|
||||
}
|
||||
|
||||
const { pickupQuantity, subLevel } = req.body;
|
||||
const { pickupQuantity, subLevel, usageReason, job } = req.body;
|
||||
if (!(pickupQuantity && pickupQuantity > 0) || !(subLevel && mongoose.isValidObjectId(subLevel))) {
|
||||
res.status(400).send("Invalid value for pickupQuantity/subLevel");
|
||||
return;
|
||||
@@ -293,6 +313,8 @@ module.exports = {
|
||||
performedBy: res.locals.user,
|
||||
pickupQuantity: pickupQuantity,
|
||||
subLevel: subLevelObj,
|
||||
usageReason: usageReason ? usageReason : "",
|
||||
job: job,
|
||||
});
|
||||
res.send({ success: true, data: { itemAssociation, itemTransaction } });
|
||||
} catch (error) {
|
||||
@@ -314,15 +336,15 @@ module.exports = {
|
||||
return;
|
||||
}
|
||||
|
||||
const { reserveQuantity, job, pickupDate } = req.body;
|
||||
if (!(reserveQuantity && reserveQuantity > 0) || !(job && mongoose.isValidObjectId(job)) || !(pickupDate && Date.parse(pickupDate))) {
|
||||
res.status(400).send("Invalid value for reserveQuantity/job/pickupDate");
|
||||
const { reserveQuantity, job, pickupDate, usageReason } = req.body;
|
||||
if (!(reserveQuantity && reserveQuantity > 0) || !(job && mongoose.isValidObjectId(job))) {
|
||||
res.status(400).send("Invalid value for reserveQuantity/job");
|
||||
return;
|
||||
}
|
||||
|
||||
const itemAssociation = await ItemAssociation.findOne({ item_id: item._id, availableQuantity: { $gte: reserveQuantity } });
|
||||
if (!itemAssociation) {
|
||||
res.status(500).send("Quantity unavailable");
|
||||
res.status(500).send({ success: false, error: "Quantity unavailable" });
|
||||
return;
|
||||
}
|
||||
itemAssociation.reservedQuantity = itemAssociation.reservedQuantity + reserveQuantity;
|
||||
@@ -335,7 +357,8 @@ module.exports = {
|
||||
performedBy: res.locals.user,
|
||||
reserveQuantity: reserveQuantity,
|
||||
job: job,
|
||||
pickupDate: Date.parse(pickupDate),
|
||||
pickupDate: pickupDate ? Date.parse(pickupDate) : undefined,
|
||||
usageReason: usageReason ? usageReason : "",
|
||||
});
|
||||
res.send({ success: true, data: { itemAssociation, itemTransaction } });
|
||||
} catch (error) {
|
||||
@@ -357,19 +380,17 @@ module.exports = {
|
||||
return;
|
||||
}
|
||||
|
||||
const { checkInMeterReading, hasIssue, issueDescription } = req.body;
|
||||
if (!(checkInMeterReading && checkInMeterReading > 0)) {
|
||||
res.status(400).send("Invalid value for checkInMeterReading");
|
||||
return;
|
||||
}
|
||||
const { checkInMeterReading, hasIssue, issueDescription, usageReason, job } = req.body;
|
||||
|
||||
const itemTransaction = await CheckInItemTransaction.create({
|
||||
type: "CHECK-IN",
|
||||
performedOn: item,
|
||||
performedBy: res.locals.user,
|
||||
checkInMeterReading: checkInMeterReading,
|
||||
hasIssue: hasIssue,
|
||||
hasIssue: hasIssue || false,
|
||||
issueDescription: hasIssue ? issueDescription : "",
|
||||
usageReason: usageReason ? usageReason : "",
|
||||
job: job,
|
||||
});
|
||||
res.send({ success: true, data: { itemTransaction } });
|
||||
} catch (error) {
|
||||
@@ -391,19 +412,15 @@ module.exports = {
|
||||
return;
|
||||
}
|
||||
|
||||
const { checkOutMeterReading, job, usageReason } = req.body;
|
||||
if (!(checkOutMeterReading && checkOutMeterReading > 0) || !(job && mongoose.isValidObjectId(job))) {
|
||||
res.status(400).send("Invalid value for checkOutMeterReading/job");
|
||||
return;
|
||||
}
|
||||
const { checkOutMeterReading, usageReason, job } = req.body;
|
||||
|
||||
const itemTransaction = await CheckOutItemTransaction.create({
|
||||
type: "CHECK-OUT",
|
||||
performedOn: item,
|
||||
performedBy: res.locals.user,
|
||||
checkOutMeterReading: checkOutMeterReading,
|
||||
job: job,
|
||||
usageReason: usageReason ? usageReason : "",
|
||||
job: job,
|
||||
});
|
||||
res.send({ success: true, data: { itemTransaction } });
|
||||
} catch (error) {
|
||||
@@ -425,7 +442,7 @@ module.exports = {
|
||||
return;
|
||||
}
|
||||
|
||||
const { reportingFor, details } = req.body;
|
||||
const { reportingFor, details, usageReason, job } = req.body;
|
||||
if (!(reportingFor && ReportItemForTypes.includes(reportingFor))) {
|
||||
res.status(400).send("Invalid value for checkOutMeterReading/job");
|
||||
return;
|
||||
@@ -437,6 +454,8 @@ module.exports = {
|
||||
performedBy: res.locals.user,
|
||||
reportingFor: reportingFor,
|
||||
details: details ? details : "",
|
||||
usageReason: usageReason ? usageReason : "",
|
||||
job: job,
|
||||
});
|
||||
res.send({ success: true, data: { itemTransaction } });
|
||||
} catch (error) {
|
||||
@@ -458,7 +477,7 @@ module.exports = {
|
||||
return;
|
||||
}
|
||||
|
||||
const { recountedQuantity, damagedQuantity, subLevel } = req.body;
|
||||
const { recountedQuantity, damagedQuantity, subLevel, usageReason, job } = req.body;
|
||||
if (!(recountedQuantity && recountedQuantity > 0) || !(subLevel && mongoose.isValidObjectId(subLevel))) {
|
||||
res.status(400).send("Invalid value for pickupQuantity/subLevel");
|
||||
return;
|
||||
@@ -483,10 +502,64 @@ module.exports = {
|
||||
damagedQuantity,
|
||||
totalAdjustment,
|
||||
newAdjustedQuantity: itemAssociation.totalQuantity,
|
||||
usageReason: usageReason ? usageReason : "",
|
||||
job: job,
|
||||
});
|
||||
res.send({ success: true, data: { itemAssociation, itemTransaction } });
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
},
|
||||
|
||||
addImageToItem: async (req, res, next) => {
|
||||
const { id } = req.params;
|
||||
if (!mongoose.isValidObjectId(id)) {
|
||||
res.status(400).send({ success: false, error: "invalid id" });
|
||||
}
|
||||
|
||||
const item = await Item.findById(id);
|
||||
if (!item) {
|
||||
res.status(404).send({ success: false, error: "item not found" });
|
||||
}
|
||||
|
||||
const image = req.file;
|
||||
const url = await S3.uploadFile(`item/${item._id.toString()}-${Date.now()}-0.${image.originalname.split(".").slice(-1).pop()}`, image.path);
|
||||
item.images ||= [];
|
||||
item.images.push({ url });
|
||||
await item.save();
|
||||
if (item.images) {
|
||||
item.images = item.images.map((_) => {
|
||||
return { _id: _._id, url: S3.generatePresignedUrl(_.url) };
|
||||
});
|
||||
}
|
||||
res.send({ success: true, data: item });
|
||||
},
|
||||
|
||||
removeImageFromItem: async (req, res, next) => {
|
||||
const { id, image_id } = req.params;
|
||||
if (!mongoose.isValidObjectId(id)) {
|
||||
res.status(400).send({ success: false, error: "invalid id" });
|
||||
}
|
||||
if (!mongoose.isValidObjectId(image_id)) {
|
||||
res.status(400).send({ success: false, error: "invalid image_id" });
|
||||
}
|
||||
|
||||
const item = await Item.findById(id);
|
||||
if (!item) {
|
||||
res.status(404).send({ success: false, error: "item not found" });
|
||||
}
|
||||
|
||||
item.images = item.images.filter((itemImage) => {
|
||||
return itemImage._id.toString() != image_id;
|
||||
});
|
||||
|
||||
await item.save();
|
||||
|
||||
if (item.images) {
|
||||
item.images = item.images.map((_) => {
|
||||
return { _id: _._id, url: S3.generatePresignedUrl(_.url) };
|
||||
});
|
||||
}
|
||||
res.send({ success: true, data: item });
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user