From 622e30628280132ba209b557b858fba178825449 Mon Sep 17 00:00:00 2001 From: Sathishkumar Krishnan Date: Sun, 27 Feb 2022 17:21:17 +0530 Subject: [PATCH] feat: added sublevel filter query --- src/controller/sublevel.controller.js | 45 +++++++++++++++ src/controller/sublevel.router.js | 4 ++ src/controller/utils/aggregation.js | 82 +++++++++++++++++++++++++++ 3 files changed, 131 insertions(+) create mode 100644 src/controller/utils/aggregation.js diff --git a/src/controller/sublevel.controller.js b/src/controller/sublevel.controller.js index 8d37c51..34f7ae4 100644 --- a/src/controller/sublevel.controller.js +++ b/src/controller/sublevel.controller.js @@ -1,8 +1,13 @@ const Sublevel = require("../models/Sublevel"); const mongoose = require("mongoose"); +const { filterSublevels } = require("./utils/aggregation"); const { addSublevelToParent, deleteSubLevelTreeFromRoot, validPositions } = require("./utils/sublevel"); const { SubLevelTypes } = require("../config/constants"); +const getLabelTerm = (name) => { + return name.toString().slice(name.toString().length - 3); +}; + module.exports = { /** * Gets the sublevel data by `id` @@ -183,4 +188,44 @@ module.exports = { next(error); } }, + + filterSublevels: async (req, res, next) => { + const { warehouse, zone, area, row } = req.body; + const results = await filterSublevels({ warehouse, zone, area, row }); + const resultsGroupedByBay = {}; + for (const resultItem of results) { + if (resultsGroupedByBay[resultItem.bay._id]) { + resultsGroupedByBay[resultItem.bay._id].location_data.push({ + level: { id: resultItem.level._id, name: resultItem.level.name }, + sublevel: { id: resultItem.sublevel1._id, name: resultItem.sublevel1.name }, + label: `Z${getLabelTerm(resultItem.zone._id)}-A${getLabelTerm(resultItem.area._id)}-R${getLabelTerm(resultItem.row._id)}-B${getLabelTerm( + resultItem.bay._id + )}-L${getLabelTerm(resultItem.level._id)}-${resultItem.sublevel1.name}`, + }); + } else { + resultsGroupedByBay[resultItem.bay._id] = { + warehouse: { id: resultItem._id, name: resultItem.name }, + zone: { id: resultItem.zone._id, name: resultItem.area.name }, + area: { id: resultItem.area._id, name: resultItem.area.name }, + row: { id: resultItem.row._id, name: resultItem.row.name }, + bay: { id: resultItem.bay._id, name: resultItem.bay.name }, + totem_label: [ + `Z${getLabelTerm(resultItem.zone._id)}-A${getLabelTerm(resultItem.area._id)}-R${getLabelTerm(resultItem.row._id)}-B${getLabelTerm( + resultItem.bay._id + )}}`, + ], + location_data: [ + { + level: { id: resultItem.level._id, name: resultItem.level.name }, + sublevel: { id: resultItem.sublevel1._id, name: resultItem.sublevel1.name }, + label: `Z${getLabelTerm(resultItem.zone._id)}-A${getLabelTerm(resultItem.area._id)}-R${getLabelTerm( + resultItem.row._id + )}-B${getLabelTerm(resultItem.bay._id)}-L${getLabelTerm(resultItem.level._id)}-${resultItem.sublevel1.name}`, + }, + ], + }; + } + } + res.send({ success: true, data: Object.values(resultsGroupedByBay) }); + }, }; diff --git a/src/controller/sublevel.router.js b/src/controller/sublevel.router.js index 7a511b1..db3dbd4 100644 --- a/src/controller/sublevel.router.js +++ b/src/controller/sublevel.router.js @@ -1,6 +1,10 @@ const router = require("express").Router(); const controller = require("./sublevel.controller"); +/** + * @route /sublevel/filter + */ +router.post("/filter", controller.filterSublevels); /** * @route /sublevel/ diff --git a/src/controller/utils/aggregation.js b/src/controller/utils/aggregation.js new file mode 100644 index 0000000..d17998f --- /dev/null +++ b/src/controller/utils/aggregation.js @@ -0,0 +1,82 @@ +const mongoose = require("mongoose"); +const Warehouse = require("./../../models/Warehouse"); + +const lookupPipeline = (from, localField, foreignField, as) => { + return { + $lookup: { + from, + localField, + foreignField, + as, + }, + }; +}; + +const unwindPipeline = (path, preserveNullAndEmptyArrays = true) => { + return { + $unwind: { + path: "$" + path, + preserveNullAndEmptyArrays, + }, + }; +}; + +const sublevelFilterAggregationPipeline = (warehouse, zone, area, row) => { + const sublevelFilterAggregationPipeline = []; + if (warehouse && mongoose.isValidObjectId(warehouse)) { + sublevelFilterAggregationPipeline.push({ + $match: { + _id: mongoose.Types.ObjectId(warehouse), + }, + }); + } + + sublevelFilterAggregationPipeline.push(lookupPipeline("zones", "_id", "warehouse_id", "zone")); + sublevelFilterAggregationPipeline.push(unwindPipeline("zone")); + if (warehouse && zone && mongoose.isValidObjectId(zone)) { + sublevelFilterAggregationPipeline.push({ + $match: { + "zone._id": mongoose.Types.ObjectId(zone), + }, + }); + } + + sublevelFilterAggregationPipeline.push(lookupPipeline("areas", "zone._id", "zone_id", "area")); + sublevelFilterAggregationPipeline.push(unwindPipeline("area")); + if (warehouse && zone && area && mongoose.isValidObjectId(area)) { + sublevelFilterAggregationPipeline.push({ + $match: { + "area._id": mongoose.Types.ObjectId(area), + }, + }); + } + + sublevelFilterAggregationPipeline.push(lookupPipeline("rows", "area._id", "area_id", "row")); + sublevelFilterAggregationPipeline.push(unwindPipeline("row")); + if (warehouse && zone && area && row && mongoose.isValidObjectId(row)) { + sublevelFilterAggregationPipeline.push({ + $match: { + "row._id": mongoose.Types.ObjectId(row), + }, + }); + } + + sublevelFilterAggregationPipeline.push(lookupPipeline("bays", "row._id", "row_id", "bay")); + sublevelFilterAggregationPipeline.push(unwindPipeline("bay")); + sublevelFilterAggregationPipeline.push(lookupPipeline("levels", "bay._id", "bay_id", "level")); + sublevelFilterAggregationPipeline.push(unwindPipeline("level")); + sublevelFilterAggregationPipeline.push(lookupPipeline("sublevels", "level._id", "main_level_id", "sublevel1")); + sublevelFilterAggregationPipeline.push(unwindPipeline("sublevel1")); + // sublevelFilterAggregationPipeline.push(lookupPipeline("sublevels", "sublevel1._id", "parent_id", "sublevel2")); + // sublevelFilterAggregationPipeline.push(unwindPipeline("sublevel2", false)); + // sublevelFilterAggregationPipeline.push(lookupPipeline("sublevels", "sublevel2._id", "parent_id", "sublevel3")); + // sublevelFilterAggregationPipeline.push(unwindPipeline("sublevel3", false)); + return sublevelFilterAggregationPipeline; +}; + +module.exports = { + filterSublevels: async ({ warehouse, zone, area, row }) => { + const pipeline = sublevelFilterAggregationPipeline(warehouse, zone, area, row); + return await Warehouse.aggregate(pipeline); + }, +};