From 2d08bca25db72cbabd04dccbb08821400890a69e Mon Sep 17 00:00:00 2001 From: Llewellyn D'souza Date: Mon, 27 Dec 2021 17:59:25 +0530 Subject: [PATCH 01/17] Added: init sublevel --- src/controller/index.js | 2 + src/controller/sublevel.controller.js | 96 +++++++++++++++++++++++++++ src/controller/sublevel.router.js | 19 ++++++ 3 files changed, 117 insertions(+) create mode 100644 src/controller/sublevel.controller.js create mode 100644 src/controller/sublevel.router.js diff --git a/src/controller/index.js b/src/controller/index.js index 64bc9dd..d1b41a7 100644 --- a/src/controller/index.js +++ b/src/controller/index.js @@ -11,6 +11,7 @@ const areaRouter = require("./area.router"); const bayRouter = require("./bay.router"); const rowRouter = require("./row.router"); const levelRouter = require("./level.router"); +const sublevelRouter = require("./sublevel.router"); router.use("/user-role", AuthenticateMiddleware, userRoleRouter); router.use("/user-permission", AuthenticateMiddleware, userPermissionRouter); @@ -22,6 +23,7 @@ router.use("/area", areaRouter); router.use("/bay", bayRouter); router.use("/row", rowRouter); router.use("/level", levelRouter); +router.use("/sublevel", sublevelRouter); router.get("/", (req, res) => { diff --git a/src/controller/sublevel.controller.js b/src/controller/sublevel.controller.js new file mode 100644 index 0000000..97dc2d3 --- /dev/null +++ b/src/controller/sublevel.controller.js @@ -0,0 +1,96 @@ +const SubLevel = require("../models/SubLevel"); +const mongoose = require("mongoose"); + +module.exports = { + /** + * Gets the sublevel data by `id` + */ + getSubLevelByID: async (req, res, next) => { + const { id } = req.params; + + if (!id) { + res.status(400).send("Missing id param"); + return; + } + + try { + const subLevelData = await SubLevel.findById(id); + if (!subLevelData) { + res.status(404); + return; + } + req.send(subLevelData); + } catch (error) { + next(error); + } + }, + + /** + * Create a sublevel + */ + createSubLevel: async (req, res, next) => { + const { name, type, specs, main_level_id } = req.body; + + if (!(name && type && main_level_id)) { + res.status(400).send("Missing params param"); + return; + } + + try { + const levelData = new SubLevel({ + name, + type: type, + specs, + main_level_id: mongoose.Types.ObjectId(main_level_id), + }); + + await levelData.save(); + if (!levelData) { + res.status(404); + return; + } + req.send(levelData); + } catch (error) { + next(error); + } + }, + + /** + * Update a sublevels' detail + */ + updateSubLevelByID: async (req, res, next) => { + const { id } = req.params; + + if (!id) { + res.status(400).send("Missing id param"); + return; + } + + const { name, type, specs, main_level_id } = req.body; + + if (!(name || type || specs || main_level_id)) { + res.status(400).send("Missing data in body"); + return; + } + + try { + const levelData = await SubLevel.findById(id); + if (!levelData) { + res.status(404); + return; + } + + if (name) levelData.name = name; + if (type) levelData.type = type; + if (specs) levelData.specs = specs; + if (main_level_id) { + levelData.main_level_id = mongoose.Types.ObjectId(main_level_id); + } + + await levelData.save(); + req.send(levelData); + } catch (error) { + next(error); + } + }, +}; diff --git a/src/controller/sublevel.router.js b/src/controller/sublevel.router.js new file mode 100644 index 0000000..2714fd2 --- /dev/null +++ b/src/controller/sublevel.router.js @@ -0,0 +1,19 @@ +const router = require("express").Router(); +const controller = require("./sublevel.controller"); + +/** + * @route /sublevel/:id + */ +router.get("/:id", controller.getSubLevelByID); + +/** + * @route /sublevel/ + */ +router.post("/", controller.createSubLevel); + +/** + * @route /sublevel/ + */ +router.patch("/:id", controller.updateSubLevelByID); + +module.exports = router; From 4cdc8f732e168bc6c8b91cb437cc870adad98874 Mon Sep 17 00:00:00 2001 From: Llewellyn D'souza Date: Tue, 28 Dec 2021 16:43:16 +0530 Subject: [PATCH 02/17] Added: sub/level position constants Updated: Schemas --- src/config/constants.js | 31 +++++++++++++++++++++++++++++++ src/models/Level.js | 13 ++++--------- src/models/Sublevel.js | 11 +++++------ 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/src/config/constants.js b/src/config/constants.js index 6ccf7a5..93c794b 100644 --- a/src/config/constants.js +++ b/src/config/constants.js @@ -12,6 +12,36 @@ const UserActions = [ "Receive", ]; +const LevelPositions = [ + "B", + "D", + "DB", + "DF", + "F", + "L", + "LB", + "LD", + "LDB", + "LDF", + "LF", + "LU", + "LUB", + "LUF", + "R", + "RB", + "RD", + "RDB", + "RDF", + "RF", + "RU", + "RUB", + "RUF", + "U", + "UB", + "UF", + "W", +]; + const InventoryScopes = ["Inventory", "Material", "Item"]; const WarehouseScopes = [ @@ -53,6 +83,7 @@ module.exports = { InventoryTypes, CustomAttributeTypes, SubLevelTypes, + LevelPositions, SUPER_ADMIN_ROLE: "super-admin", COMPANY_ADMIN_ROLE: "company-admin", WAREHOUSE_ADMIN_ROLE: "warehouse-admin", diff --git a/src/models/Level.js b/src/models/Level.js index debc961..857b561 100644 --- a/src/models/Level.js +++ b/src/models/Level.js @@ -1,5 +1,5 @@ const mongoose = require("mongoose"); -const { SubLevelTypes } = require("../config/constants"); +const { SubLevelTypes, LevelPositions } = require("../config/constants"); const schema = new mongoose.Schema( { @@ -29,15 +29,10 @@ const schema = new mongoose.Schema( type: String, enum: SubLevelTypes }, - depth: { + postition: { required: true, - type: Number, - min: 1, // Level is at 0 - max: 5, - }, - bay_id: { - type: mongoose.Schema.Types.ObjectId, - ref: "Bay", + type: String, + enum: LevelPositions, }, sub_level_id: { required: true, diff --git a/src/models/Sublevel.js b/src/models/Sublevel.js index 7d0dbe0..1334ae6 100644 --- a/src/models/Sublevel.js +++ b/src/models/Sublevel.js @@ -1,5 +1,5 @@ const mongoose = require("mongoose"); -const { SubLevelTypes } = require("../config/constants"); +const { SubLevelTypes, LevelPositions } = require("../config/constants"); const schema = new mongoose.Schema( { @@ -11,7 +11,7 @@ const schema = new mongoose.Schema( type: { type: String, required: true, - enum: SubLevelTypes + enum: SubLevelTypes, }, specs: { // TBD @@ -39,11 +39,10 @@ const schema = new mongoose.Schema( type: String, enum: SubLevelTypes, }, - depth: { + postition: { required: true, - type: Number, - min: 1, // Level is at 0 - max: 5, + type: String, + enum: LevelPositions, }, sub_level_id: { required: true, From 7a724b8a3965525645f835b98bf850146899a244 Mon Sep 17 00:00:00 2001 From: Llewellyn D'souza Date: Tue, 28 Dec 2021 16:44:40 +0530 Subject: [PATCH 03/17] Create sublevel and udpate sublevel details --- src/controller/sublevel.controller.js | 53 +++++++++++++-------------- src/controller/sublevel.router.js | 2 +- 2 files changed, 26 insertions(+), 29 deletions(-) diff --git a/src/controller/sublevel.controller.js b/src/controller/sublevel.controller.js index 97dc2d3..94c9eac 100644 --- a/src/controller/sublevel.controller.js +++ b/src/controller/sublevel.controller.js @@ -1,4 +1,4 @@ -const SubLevel = require("../models/SubLevel"); +const SubLevel = require("../models/Sublevel"); const mongoose = require("mongoose"); module.exports = { @@ -29,27 +29,33 @@ module.exports = { * Create a sublevel */ createSubLevel: async (req, res, next) => { - const { name, type, specs, main_level_id } = req.body; + const { name, type, specs, parent_sublevel_id, main_level_id } = req.body; - if (!(name && type && main_level_id)) { + if (!(name && type && parent_sublevel_id)) { res.status(400).send("Missing params param"); return; } try { - const levelData = new SubLevel({ + const { parent_current_depth, parent_main_level_id } = parent_sublevel_id + ? await SubLevel.findById(parent_sublevel_id) + : { current_depth: 1, p_main_level_id: main_level_id }; + + const sublevelData = new SubLevel({ name, type: type, specs, - main_level_id: mongoose.Types.ObjectId(main_level_id), + main_level_id: parent_main_level_id, + current_depth: parent_current_depth + 1, + parent_sublevel_id: mongoose.Types.ObjectId(parent_sublevel_id), }); - await levelData.save(); - if (!levelData) { + await sublevelData.save(); + if (!sublevelData) { res.status(404); return; } - req.send(levelData); + req.send(sublevelData); } catch (error) { next(error); } @@ -58,37 +64,28 @@ module.exports = { /** * Update a sublevels' detail */ - updateSubLevelByID: async (req, res, next) => { + updateSubLevelDetailsByID: async (req, res, next) => { + const { name, type, specs } = req.body; const { id } = req.params; - if (!id) { - res.status(400).send("Missing id param"); - return; - } - - const { name, type, specs, main_level_id } = req.body; - - if (!(name || type || specs || main_level_id)) { - res.status(400).send("Missing data in body"); + if (!(name || type || specs)) { + res.status(400).send("Missing params param"); return; } try { - const levelData = await SubLevel.findById(id); - if (!levelData) { + const sublevelData = await SubLevel.findById(id); + if (!sublevelData) { res.status(404); return; } - if (name) levelData.name = name; - if (type) levelData.type = type; - if (specs) levelData.specs = specs; - if (main_level_id) { - levelData.main_level_id = mongoose.Types.ObjectId(main_level_id); - } + if (name) sublevelData.name = name; + if (type) sublevelData.type = type; + if (specs) sublevelData.specs = specs; - await levelData.save(); - req.send(levelData); + const newData = await sublevelData.save(); + req.send(newData); } catch (error) { next(error); } diff --git a/src/controller/sublevel.router.js b/src/controller/sublevel.router.js index 2714fd2..8ca2863 100644 --- a/src/controller/sublevel.router.js +++ b/src/controller/sublevel.router.js @@ -14,6 +14,6 @@ router.post("/", controller.createSubLevel); /** * @route /sublevel/ */ -router.patch("/:id", controller.updateSubLevelByID); +router.patch("/:id", controller.updateSubLevelDetailsByID); module.exports = router; From 806cfefba3b77f56e9dbbabd619d8fff7c557e70 Mon Sep 17 00:00:00 2001 From: Llewellyn D'souza Date: Tue, 28 Dec 2021 17:00:19 +0530 Subject: [PATCH 04/17] Added: delete sub level tree --- src/controller/utils/sublevel.js | 30 ++++++++++++++++++++++++++++++ src/models/Sublevel.js | 6 ++++++ 2 files changed, 36 insertions(+) create mode 100644 src/controller/utils/sublevel.js diff --git a/src/controller/utils/sublevel.js b/src/controller/utils/sublevel.js new file mode 100644 index 0000000..9fcca0b --- /dev/null +++ b/src/controller/utils/sublevel.js @@ -0,0 +1,30 @@ +const SubLevel = require("../../models/Sublevel"); +const Level = require("../../models/Level"); + +// exports.moveSublevel = async (sub_level_id, under_sub_or_level_id, isMainLevel) => { + +// }; + +exports.deleteSubLevelTreeFromRoot = async (root_sub_level_id) => { + let sub_level_ids = []; + let temp_sub_level_ids = [root_sub_level_id]; + + while (temp_sub_level_ids.length > 0) { + const level_sub_level_data = await SubLevel.find({ + _id: temp_sub_level_ids, + }); + + sub_level_ids = [...sub_level_ids, ...temp_sub_level_ids]; + temp_sub_level_ids = []; + + level_sub_level_data.forEach((sub_level_data) => { + sub_level_data.sub_levels.forEach((sub_level) => { + temp_sub_level_ids.push(sub_level.sub_level_id.toString()); + }); + }); + } + + await SubLevel.deleteMany({ _id: sub_level_ids }); + console.log("Deleting sub-level tree", { sub_level_ids }); + return sub_level_ids; +}; diff --git a/src/models/Sublevel.js b/src/models/Sublevel.js index 1334ae6..465de94 100644 --- a/src/models/Sublevel.js +++ b/src/models/Sublevel.js @@ -67,6 +67,12 @@ const schema = new mongoose.Schema( } ); +schema.pre("save", function (next) { + // const sublevel = this; + // // write validation here? + next(); +}); + const SubLevel = mongoose.model("SubLevel", schema); module.exports = SubLevel; From 66ac295bdc3b7f840858fae66b82a6ac9a2e2b62 Mon Sep 17 00:00:00 2001 From: Llewellyn D'souza Date: Wed, 29 Dec 2021 14:36:28 +0530 Subject: [PATCH 05/17] Modified: Level positions --- src/config/constants.js | 19 ------------------- src/models/Level.js | 13 +++++++------ src/models/Sublevel.js | 21 +++++++++++---------- 3 files changed, 18 insertions(+), 35 deletions(-) diff --git a/src/config/constants.js b/src/config/constants.js index 93c794b..304a435 100644 --- a/src/config/constants.js +++ b/src/config/constants.js @@ -13,33 +13,14 @@ const UserActions = [ ]; const LevelPositions = [ - "B", - "D", - "DB", - "DF", - "F", - "L", - "LB", - "LD", "LDB", "LDF", - "LF", - "LU", "LUB", "LUF", - "R", - "RB", - "RD", "RDB", "RDF", - "RF", - "RU", "RUB", "RUF", - "U", - "UB", - "UF", - "W", ]; const InventoryScopes = ["Inventory", "Material", "Item"]; diff --git a/src/models/Level.js b/src/models/Level.js index 857b561..4e0dee5 100644 --- a/src/models/Level.js +++ b/src/models/Level.js @@ -27,13 +27,14 @@ const schema = new mongoose.Schema( type: { required: true, type: String, - enum: SubLevelTypes - }, - postition: { - required: true, - type: String, - enum: LevelPositions, + enum: SubLevelTypes, }, + postition: [ + { + type: String, + enum: LevelPositions, + }, + ], sub_level_id: { required: true, type: mongoose.Schema.Types.ObjectId, diff --git a/src/models/Sublevel.js b/src/models/Sublevel.js index 465de94..b9cde4e 100644 --- a/src/models/Sublevel.js +++ b/src/models/Sublevel.js @@ -39,11 +39,12 @@ const schema = new mongoose.Schema( type: String, enum: SubLevelTypes, }, - postition: { - required: true, - type: String, - enum: LevelPositions, - }, + postitions: [ + { + type: String, + enum: LevelPositions, + }, + ], sub_level_id: { required: true, type: mongoose.Schema.Types.ObjectId, @@ -55,11 +56,11 @@ const schema = new mongoose.Schema( type: Boolean, default: false, }, - inventory: [ - { - type: mongoose.Schema.Types.ObjectId, - ref: "Inventory", - }, + preffered_inventory: [ + // { + // type: mongoose.Schema.Types.ObjectId, + // ref: "Inventory", + // }, ], }, { From 2f17ae2881e9fa07543546437d456ee09cf44bb6 Mon Sep 17 00:00:00 2001 From: Llewellyn D'souza Date: Wed, 29 Dec 2021 15:19:17 +0530 Subject: [PATCH 06/17] Added: Polymorphic preffered inventory --- src/config/constants.js | 3 +++ src/models/Sublevel.js | 16 +++++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/config/constants.js b/src/config/constants.js index 304a435..8e66871 100644 --- a/src/config/constants.js +++ b/src/config/constants.js @@ -51,6 +51,8 @@ const CustomAttributeTypes = [ "Enumerable", ]; +const SublevelInventoryTypes = ["Inventory", "Material", "Item"]; + const AUTHENTICATION_FAILURE_ERROR_MESSAGE = "Authentication Failed!"; const AUTHORIZATION_FAILURE_ERROR_MESSAGE = "User not permitted due to lack of access!"; @@ -63,6 +65,7 @@ module.exports = { WarehouseScopes, InventoryTypes, CustomAttributeTypes, + SublevelInventoryTypes, SubLevelTypes, LevelPositions, SUPER_ADMIN_ROLE: "super-admin", diff --git a/src/models/Sublevel.js b/src/models/Sublevel.js index 9873d87..5da8c61 100644 --- a/src/models/Sublevel.js +++ b/src/models/Sublevel.js @@ -1,5 +1,5 @@ const mongoose = require("mongoose"); -const { SubLevelTypes, LevelPositions } = require("../config/constants"); +const { SubLevelTypes, LevelPositions, SublevelInventoryTypes } = require("../config/constants"); const schema = new mongoose.Schema( { @@ -57,10 +57,16 @@ const schema = new mongoose.Schema( default: false, }, preffered_inventory: [ - // { - // type: mongoose.Schema.Types.ObjectId, - // ref: "Inventory", - // }, + { + id: { + type: mongoose.Schema.Types.ObjectId, + refPath: "type", + }, + type: { + type: String, + enum: SublevelInventoryTypes, + }, + }, ], }, { From a48cbae6f9fcbc7d08aff74c25915fd58be256b0 Mon Sep 17 00:00:00 2001 From: Llewellyn D'souza Date: Wed, 29 Dec 2021 16:08:57 +0530 Subject: [PATCH 07/17] Update: Specs of type mixed --- src/models/Sublevel.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/models/Sublevel.js b/src/models/Sublevel.js index 5da8c61..b32bee0 100644 --- a/src/models/Sublevel.js +++ b/src/models/Sublevel.js @@ -14,8 +14,7 @@ const schema = new mongoose.Schema( enum: SubLevelTypes, }, specs: { - // TBD - type: String, + type: Object, trim: true, }, main_level_id: { From b3f96ca8cd82ce49664ebf0fa881955a2b54a969 Mon Sep 17 00:00:00 2001 From: Llewellyn D'souza Date: Wed, 29 Dec 2021 16:31:14 +0530 Subject: [PATCH 08/17] Added: js style docs for sublevel utils --- src/controller/utils/sublevel.js | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/controller/utils/sublevel.js b/src/controller/utils/sublevel.js index 7f44a85..c9af515 100644 --- a/src/controller/utils/sublevel.js +++ b/src/controller/utils/sublevel.js @@ -1,10 +1,26 @@ const Sublevel = require("../../models/Sublevel"); -const Level = require("../../models/Level"); +// const Level = require("../../models/Level"); -// exports.moveSublevel = async (sub_level_id, under_sub_or_level_id, isMainLevel) => { - -// }; +/** + * To move a sub level + * @param {string} sub_level_id The Sublevel to me moved + * @param {string} parent_sub_or_level_id The Level/Sublevel under which to be moved + * @returns {{success: boolean, message: string}} + */ +exports.moveSublevel = async (sub_level_id, parent_sub_or_level_id) => { + /** + * - Check if depths of parent_sub_level_id and parent_sub_or_level_id are same + * - Copy and add references + * - Delete and remove references + */ + return { success: false, message: "not implemented" }; +}; +/** + * To delete a sub level and all corresponding sub levels under it + * @param {string} root_sub_level_id The root Sublevel ID + * @returns {string[]} The Sublevel IDs that have been deleted + */ exports.deleteSubLevelTreeFromRoot = async (root_sub_level_id) => { let sub_level_ids = []; let temp_sub_level_ids = [root_sub_level_id]; From 812c691befafcfcbd4a01146bcfa1cd289839ee0 Mon Sep 17 00:00:00 2001 From: Llewellyn D'souza Date: Wed, 29 Dec 2021 16:49:56 +0530 Subject: [PATCH 09/17] Updated: create sublevel modified --- src/controller/sublevel.controller.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/controller/sublevel.controller.js b/src/controller/sublevel.controller.js index c028a81..374c0ec 100644 --- a/src/controller/sublevel.controller.js +++ b/src/controller/sublevel.controller.js @@ -29,17 +29,17 @@ module.exports = { * Create a sublevel */ createSubLevel: async (req, res, next) => { - const { name, type, specs, parent_sublevel_id, main_level_id } = req.body; + const { name, type, specs, parent_id, parentIsLevel } = req.body; - if (!(name && type && parent_sublevel_id)) { + if (!(name && type && parent_id)) { res.status(400).send("Missing params param"); return; } try { - const { parent_current_depth, parent_main_level_id } = parent_sublevel_id - ? await Sublevel.findById(parent_sublevel_id) - : { current_depth: 1, p_main_level_id: main_level_id }; + const { parent_current_depth, parent_main_level_id } = parentIsLevel + ? { parent_current_depth: 0, parent_main_level_id: parent_id } + : await Sublevel.findById(parent_id); const sublevelData = new Sublevel({ name, @@ -47,7 +47,7 @@ module.exports = { specs, main_level_id: parent_main_level_id, current_depth: parent_current_depth + 1, - parent_sublevel_id: mongoose.Types.ObjectId(parent_sublevel_id), + parent_sublevel_id: mongoose.Types.ObjectId(parent_id), }); await sublevelData.save(); From fad703f0b7bb7d28d37a5d7326b3577fc4634849 Mon Sep 17 00:00:00 2001 From: Llewellyn D'souza Date: Wed, 29 Dec 2021 17:16:22 +0530 Subject: [PATCH 10/17] Update: add sublevel to parent --- src/controller/sublevel.controller.js | 7 +++++-- src/controller/utils/sublevel.js | 20 ++++++++++++++++++++ src/models/Level.js | 2 +- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/controller/sublevel.controller.js b/src/controller/sublevel.controller.js index 374c0ec..d97789f 100644 --- a/src/controller/sublevel.controller.js +++ b/src/controller/sublevel.controller.js @@ -1,5 +1,6 @@ const Sublevel = require("../models/Sublevel"); const mongoose = require("mongoose"); +const { addSublevelToParent } = require("./utils/sublevel"); module.exports = { /** @@ -29,7 +30,7 @@ module.exports = { * Create a sublevel */ createSubLevel: async (req, res, next) => { - const { name, type, specs, parent_id, parentIsLevel } = req.body; + const { name, type, specs, parent_id, parentIsLevel, positions } = req.body; if (!(name && type && parent_id)) { res.status(400).send("Missing params param"); @@ -41,7 +42,7 @@ module.exports = { ? { parent_current_depth: 0, parent_main_level_id: parent_id } : await Sublevel.findById(parent_id); - const sublevelData = new Sublevel({ + const sublevelData = Sublevel.create({ name, type: type, specs, @@ -50,6 +51,8 @@ module.exports = { parent_sublevel_id: mongoose.Types.ObjectId(parent_id), }); + await addSublevelToParent({ type, positions, sub_level_id: sublevelData._id.toString() }, parent_id, parentIsLevel); + await sublevelData.save(); if (!sublevelData) { res.status(404); diff --git a/src/controller/utils/sublevel.js b/src/controller/utils/sublevel.js index c9af515..8427fda 100644 --- a/src/controller/utils/sublevel.js +++ b/src/controller/utils/sublevel.js @@ -44,3 +44,23 @@ exports.deleteSubLevelTreeFromRoot = async (root_sub_level_id) => { console.log("Deleting sub-level tree", { sub_level_ids }); return sub_level_ids; }; + +/** + * Add the sublevel data to the parent document + * @param {{type: string, positions: string[], sub_level_id: string}} payload The sublevel data + * @param {string} parent_id The parent level ID + * @param {boolean} parentIsLevel Is parent a level? + */ +exports.addSublevelToParent = async (payload, parent_id, parentIsLevel) => { + if (parentIsLevel) { + // add sublevel to parent + const parentData = await Sublevel.findById(parent_id); + parentData.sub_levels.push(payload); + return await parentData.save(); + } else { + // add sublevel to sublevel + const parentData = await Sublevel.findById(parent_id); + parentData.sub_levels.push(payload); + return await parentData.save(); + } +}; diff --git a/src/models/Level.js b/src/models/Level.js index 4e0dee5..8248963 100644 --- a/src/models/Level.js +++ b/src/models/Level.js @@ -29,7 +29,7 @@ const schema = new mongoose.Schema( type: String, enum: SubLevelTypes, }, - postition: [ + postitions: [ { type: String, enum: LevelPositions, From 7976233668cd5c7324c3a5cf8b62ab9f7bc07b15 Mon Sep 17 00:00:00 2001 From: Llewellyn D'souza Date: Wed, 29 Dec 2021 17:28:06 +0530 Subject: [PATCH 11/17] Sublevel Utils --- src/controller/utils/sublevel.js | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/controller/utils/sublevel.js b/src/controller/utils/sublevel.js index 8427fda..fd4bcd1 100644 --- a/src/controller/utils/sublevel.js +++ b/src/controller/utils/sublevel.js @@ -1,5 +1,5 @@ const Sublevel = require("../../models/Sublevel"); -// const Level = require("../../models/Level"); +const Level = require("../../models/Level"); /** * To move a sub level @@ -7,7 +7,7 @@ const Sublevel = require("../../models/Sublevel"); * @param {string} parent_sub_or_level_id The Level/Sublevel under which to be moved * @returns {{success: boolean, message: string}} */ -exports.moveSublevel = async (sub_level_id, parent_sub_or_level_id) => { +const moveSublevel = async (sub_level_id, parent_sub_or_level_id) => { /** * - Check if depths of parent_sub_level_id and parent_sub_or_level_id are same * - Copy and add references @@ -21,10 +21,13 @@ exports.moveSublevel = async (sub_level_id, parent_sub_or_level_id) => { * @param {string} root_sub_level_id The root Sublevel ID * @returns {string[]} The Sublevel IDs that have been deleted */ -exports.deleteSubLevelTreeFromRoot = async (root_sub_level_id) => { +const deleteSubLevelTreeFromRoot = async (root_sub_level_id) => { let sub_level_ids = []; let temp_sub_level_ids = [root_sub_level_id]; + // remove from parent first + await removeSublevelFromParent(root_sub_level_id); + while (temp_sub_level_ids.length > 0) { const level_sub_level_data = await Sublevel.find({ _id: temp_sub_level_ids, @@ -51,7 +54,7 @@ exports.deleteSubLevelTreeFromRoot = async (root_sub_level_id) => { * @param {string} parent_id The parent level ID * @param {boolean} parentIsLevel Is parent a level? */ -exports.addSublevelToParent = async (payload, parent_id, parentIsLevel) => { +const addSublevelToParent = async (payload, parent_id, parentIsLevel) => { if (parentIsLevel) { // add sublevel to parent const parentData = await Sublevel.findById(parent_id); @@ -64,3 +67,23 @@ exports.addSublevelToParent = async (payload, parent_id, parentIsLevel) => { return await parentData.save(); } }; + +const removeSublevelFromParent = async (id) => { + const { main_level_id, parent_sublevel_id, current_depth } = await Sublevel.findById(id); + if (current_depth == 1) { + // it means parent is level + const parentData = await Level.findById(main_level_id); + parentData.sub_levels = parentData.sub_levels.filter((sub_level) => sub_level.sub_level_id != id); + } else { + // parent is another sublevel + const parentData = await Sublevel.findById(parent_sublevel_id); + parentData.sub_levels = parentData.sub_levels.filter((sub_level) => sub_level.sub_level_id != id); + } +}; + +module.exports = { + addSublevelToParent, + removeSublevelFromParent, + deleteSubLevelTreeFromRoot, + moveSublevel, +}; From 220aea56f5c5bce043c977834a2d4832d9ad718b Mon Sep 17 00:00:00 2001 From: Llewellyn Dsouza Date: Wed, 29 Dec 2021 22:38:18 +0530 Subject: [PATCH 12/17] Find available positions --- src/controller/utils/sublevel.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/controller/utils/sublevel.js b/src/controller/utils/sublevel.js index fd4bcd1..37e7ab6 100644 --- a/src/controller/utils/sublevel.js +++ b/src/controller/utils/sublevel.js @@ -1,5 +1,6 @@ const Sublevel = require("../../models/Sublevel"); const Level = require("../../models/Level"); +const { LevelPositions } = require("../../config/constants"); /** * To move a sub level @@ -81,9 +82,23 @@ const removeSublevelFromParent = async (id) => { } }; +/** + * Provides a list of available positions at the particular Level/Sublevel + * @param {object} sublevelData Level / Sublevel mongoose document + * @returns {string[]} The list of available positions + */ +const findAvailablePositions = (sublevelData) => { + let positionsOccupied = []; + sublevelData.sub_levels.forEach((sublevel) => { + positionsOccupied = [...positionsOccupied, ...sublevel.sub_levels]; + }); + return LevelPositions.filter((pos) => !positionsOccupied.includes(pos)); +}; + module.exports = { addSublevelToParent, removeSublevelFromParent, deleteSubLevelTreeFromRoot, moveSublevel, + findAvailablePositions, }; From ce92f1d1b9e0613399b46831623829344c6a92ef Mon Sep 17 00:00:00 2001 From: Llewellyn Dsouza Date: Wed, 29 Dec 2021 22:38:56 +0530 Subject: [PATCH 13/17] Fix: create sublevel after confirming positions --- src/controller/sublevel.controller.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/controller/sublevel.controller.js b/src/controller/sublevel.controller.js index d97789f..09ff906 100644 --- a/src/controller/sublevel.controller.js +++ b/src/controller/sublevel.controller.js @@ -38,11 +38,13 @@ module.exports = { } try { - const { parent_current_depth, parent_main_level_id } = parentIsLevel + const parentData = parentIsLevel ? { parent_current_depth: 0, parent_main_level_id: parent_id } : await Sublevel.findById(parent_id); - const sublevelData = Sublevel.create({ + const { parent_current_depth, parent_main_level_id } = parentData; + + const sublevelData = new Sublevel({ name, type: type, specs, @@ -51,7 +53,11 @@ module.exports = { parent_sublevel_id: mongoose.Types.ObjectId(parent_id), }); - await addSublevelToParent({ type, positions, sub_level_id: sublevelData._id.toString() }, parent_id, parentIsLevel); + await addSublevelToParent( + { type, positions, sub_level_id: sublevelData._id.toString() }, + parent_id, + parentIsLevel + ); await sublevelData.save(); if (!sublevelData) { From 97dd2e139810006fc2d6860f0c7629b6eb2e2257 Mon Sep 17 00:00:00 2001 From: Llewellyn Dsouza Date: Wed, 29 Dec 2021 22:44:20 +0530 Subject: [PATCH 14/17] Added: Notes --- src/controller/index.js | 1 - src/controller/sublevel.router.js | 7 ++++++- src/models/Level.js | 3 +-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/controller/index.js b/src/controller/index.js index 32b0360..b8183d3 100644 --- a/src/controller/index.js +++ b/src/controller/index.js @@ -25,7 +25,6 @@ router.use("/bay", bayRouter); router.use("/row", rowRouter); router.use("/level", levelRouter); router.use("/sublevel", sublevelRouter); - router.use("/dashboard", dashboardRouter); router.get("/", (req, res) => { diff --git a/src/controller/sublevel.router.js b/src/controller/sublevel.router.js index 8ca2863..42a3cb6 100644 --- a/src/controller/sublevel.router.js +++ b/src/controller/sublevel.router.js @@ -12,8 +12,13 @@ router.get("/:id", controller.getSubLevelByID); router.post("/", controller.createSubLevel); /** - * @route /sublevel/ + * @route /sublevel/:id */ router.patch("/:id", controller.updateSubLevelDetailsByID); +/** + * - delete + * - add prefered_inventory + */ + module.exports = router; diff --git a/src/models/Level.js b/src/models/Level.js index 8248963..c33565d 100644 --- a/src/models/Level.js +++ b/src/models/Level.js @@ -14,8 +14,7 @@ const schema = new mongoose.Schema( trim: true, }, specs: { - // TODO: TBD - type: String, + type: Object, trim: true, }, bay_id: { From e64e2a98c86ac50beef02e750094cec54155658b Mon Sep 17 00:00:00 2001 From: Llewellyn D'souza Date: Thu, 30 Dec 2021 12:48:43 +0530 Subject: [PATCH 15/17] Added: delete sublevel --- src/controller/sublevel.controller.js | 29 ++++++++++++++++++--------- src/controller/sublevel.router.js | 5 +++++ 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/controller/sublevel.controller.js b/src/controller/sublevel.controller.js index 09ff906..2269441 100644 --- a/src/controller/sublevel.controller.js +++ b/src/controller/sublevel.controller.js @@ -1,6 +1,6 @@ const Sublevel = require("../models/Sublevel"); const mongoose = require("mongoose"); -const { addSublevelToParent } = require("./utils/sublevel"); +const { addSublevelToParent, deleteSubLevelTreeFromRoot } = require("./utils/sublevel"); module.exports = { /** @@ -38,9 +38,7 @@ module.exports = { } try { - const parentData = parentIsLevel - ? { parent_current_depth: 0, parent_main_level_id: parent_id } - : await Sublevel.findById(parent_id); + const parentData = parentIsLevel ? { parent_current_depth: 0, parent_main_level_id: parent_id } : await Sublevel.findById(parent_id); const { parent_current_depth, parent_main_level_id } = parentData; @@ -53,11 +51,7 @@ module.exports = { parent_sublevel_id: mongoose.Types.ObjectId(parent_id), }); - await addSublevelToParent( - { type, positions, sub_level_id: sublevelData._id.toString() }, - parent_id, - parentIsLevel - ); + await addSublevelToParent({ type, positions, sub_level_id: sublevelData._id.toString() }, parent_id, parentIsLevel); await sublevelData.save(); if (!sublevelData) { @@ -99,4 +93,21 @@ module.exports = { next(error); } }, + + /** + * Deletes a sublevel + */ + deleteSublevel: async (req, res, next) => { + const { id } = req.params; + if (!id) { + res.status(404).send("Provide an ID"); + } + + try { + const deletedSublevels = deleteSubLevelTreeFromRoot(id); + res.send({ success: deletedSublevels.length, data: { deletedSublevels: deletedSublevels } }); + } catch (err) { + next(err); + } + }, }; diff --git a/src/controller/sublevel.router.js b/src/controller/sublevel.router.js index 42a3cb6..99b1bf2 100644 --- a/src/controller/sublevel.router.js +++ b/src/controller/sublevel.router.js @@ -16,6 +16,11 @@ router.post("/", controller.createSubLevel); */ router.patch("/:id", controller.updateSubLevelDetailsByID); +/** + * @route /sublevel/:id + */ +router.delete('/:id', controller.deleteSublevel); + /** * - delete * - add prefered_inventory From 8c721f3b1d1dbadf4293c22f6fbae4093a55dcd6 Mon Sep 17 00:00:00 2001 From: Llewellyn D'souza Date: Thu, 30 Dec 2021 14:38:03 +0530 Subject: [PATCH 16/17] validate positions --- src/controller/sublevel.controller.js | 20 ++++++++++++++++++-- src/controller/utils/sublevel.js | 10 ++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/controller/sublevel.controller.js b/src/controller/sublevel.controller.js index 2269441..0307022 100644 --- a/src/controller/sublevel.controller.js +++ b/src/controller/sublevel.controller.js @@ -1,6 +1,7 @@ const Sublevel = require("../models/Sublevel"); const mongoose = require("mongoose"); -const { addSublevelToParent, deleteSubLevelTreeFromRoot } = require("./utils/sublevel"); +const { addSublevelToParent, deleteSubLevelTreeFromRoot, validPositions } = require("./utils/sublevel"); +const { SubLevelTypes } = require("../config/constants"); module.exports = { /** @@ -32,11 +33,21 @@ module.exports = { createSubLevel: async (req, res, next) => { const { name, type, specs, parent_id, parentIsLevel, positions } = req.body; - if (!(name && type && parent_id)) { + if (!(name && type && parent_id && positions)) { res.status(400).send("Missing params param"); return; } + if (!SubLevelTypes.includes(type)) { + res.status(400).send("Invalid type"); + return; + } + + if (!validPositions(positions)) { + res.status(400).send("Invalid positions"); + return; + } + try { const parentData = parentIsLevel ? { parent_current_depth: 0, parent_main_level_id: parent_id } : await Sublevel.findById(parent_id); @@ -76,6 +87,11 @@ module.exports = { return; } + if (type && !SubLevelTypes.includes(type)) { + res.status(400).send("Invalid type"); + return; + } + try { const sublevelData = await Sublevel.findById(id); if (!sublevelData) { diff --git a/src/controller/utils/sublevel.js b/src/controller/utils/sublevel.js index 37e7ab6..3e63a93 100644 --- a/src/controller/utils/sublevel.js +++ b/src/controller/utils/sublevel.js @@ -95,10 +95,20 @@ const findAvailablePositions = (sublevelData) => { return LevelPositions.filter((pos) => !positionsOccupied.includes(pos)); }; +/** + * Check if positions are valid positions + * @param {string[]} positions An array of positions + * @returns {boolean} + */ +const validPositions = (positions) => { + return positions.every((position) => LevelPositions.includes(position)); +}; + module.exports = { addSublevelToParent, removeSublevelFromParent, deleteSubLevelTreeFromRoot, moveSublevel, findAvailablePositions, + validPositions, }; From 56538a5c0b3382a7dbefd30a73933edfe4191d4e Mon Sep 17 00:00:00 2001 From: Llewellyn D'souza Date: Thu, 30 Dec 2021 14:50:56 +0530 Subject: [PATCH 17/17] Add inventory --- src/controller/sublevel.controller.js | 25 +++++++++++++++++++++++++ src/controller/sublevel.router.js | 6 +++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/controller/sublevel.controller.js b/src/controller/sublevel.controller.js index 0307022..a62b36b 100644 --- a/src/controller/sublevel.controller.js +++ b/src/controller/sublevel.controller.js @@ -60,6 +60,7 @@ module.exports = { main_level_id: parent_main_level_id, current_depth: parent_current_depth + 1, parent_sublevel_id: mongoose.Types.ObjectId(parent_id), + preffered_inventory: [], }); await addSublevelToParent({ type, positions, sub_level_id: sublevelData._id.toString() }, parent_id, parentIsLevel); @@ -126,4 +127,28 @@ module.exports = { next(err); } }, + + /** + * Add preffered_inventory to a sublevel + */ + addInventory: async (req, res, next) => { + const { id, inventory } = req.body; + const sublevelData = await Sublevel.findById(id); + if (!sublevelData) { + res.status(404); + return; + } + // eslint-disable-next-line no-prototype-builtins + if (inventory.every((_) => _.hasOwnProperty("id") && _.hasOwnProperty("type"))) { + res.status(404).send({ success: false, message: "invalid inventory data" }); + return; + } + try { + sublevelData.preffered_inventory.push(...inventory); + await sublevelData.save(); + res.send({ success: true, data: sublevelData.preffered_inventory }); + } catch (err) { + next(err); + } + }, }; diff --git a/src/controller/sublevel.router.js b/src/controller/sublevel.router.js index 99b1bf2..3f4a4e2 100644 --- a/src/controller/sublevel.router.js +++ b/src/controller/sublevel.router.js @@ -19,11 +19,11 @@ router.patch("/:id", controller.updateSubLevelDetailsByID); /** * @route /sublevel/:id */ -router.delete('/:id', controller.deleteSublevel); +router.delete("/:id", controller.deleteSublevel); /** - * - delete - * - add prefered_inventory + * @route /sublevel/add-inventory */ +router.post("/add-inventory", controller.addInventory); module.exports = router;