diff --git a/db/changes/231201/00-wagon.sql b/db/changes/231201/00-wagon.sql index c7725ab4f..2924fdc99 100644 --- a/db/changes/231201/00-wagon.sql +++ b/db/changes/231201/00-wagon.sql @@ -15,7 +15,7 @@ CREATE TABLE `vn`.`wagonTypeColor` ( CREATE TABLE `vn`.`wagonTypeTray` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `typeFk` int(11) unsigned, - `height` int(11) unsigned, + `height` int(11) unsigned NOT NULL, `colorFk` int(11) unsigned, PRIMARY KEY (`id`), UNIQUE KEY (`typeFk`,`height`), @@ -54,7 +54,8 @@ CREATE TABLE `vn`.`collectionWagonTicket` ( CONSTRAINT `collectionWagonTicket_tray` FOREIGN KEY (`trayFk`) REFERENCES `wagonTypeTray` (`id`) ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; -ALTER TABLE `vn`.`wagon` ADD `typeFk` int(11) unsigned DEFAULT NULL; +ALTER TABLE `vn`.`wagon` ADD `typeFk` int(11) unsigned NOT NULL; +ALTER TABLE `vn`.`wagon` ADD `label` int(11) unsigned NOT NULL; ALTER TABLE `vn`.`wagon` ADD CONSTRAINT `wagon_type` FOREIGN KEY (`typeFk`) REFERENCES `wagonType` (`id`) ON UPDATE CASCADE; INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) @@ -65,4 +66,7 @@ INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `pri ('WagonConfig', '*', '*', 'ALLOW', 'ROLE', 'employee'), ('CollectionWagon', '*', '*', 'ALLOW', 'ROLE', 'employee'), ('CollectionWagonTicket', '*', '*', 'ALLOW', 'ROLE', 'employee'), - ('Wagon', '*', '*', 'ALLOW', 'ROLE', 'employee'); + ('Wagon', '*', '*', 'ALLOW', 'ROLE', 'employee'), + ('WagonType', 'createWagonType', '*', 'ALLOW', 'ROLE', 'employee'), + ('WagonType', 'deleteWagonType', '*', 'ALLOW', 'ROLE', 'employee'), + ('WagonType', 'editWagonType', '*', 'ALLOW', 'ROLE', 'employee'); diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 571769e8c..1c8134ca3 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -2838,8 +2838,9 @@ INSERT INTO `vn`.`wagonConfig` (`id`, `width`, `height`, `maxWagonHeight`, `minH INSERT INTO `vn`.`wagonTypeColor` (`id`, `name`, `rgb`) VALUES - (1, 'red', '#ff0000'), - (2, 'green', '#00ff00'), - (3, 'blue', '#0000ff'); + (1, 'white', '#ffffff'), + (2, 'red', '#ff0000'), + (3, 'green', '#00ff00'), + (4, 'blue', '#0000ff'); diff --git a/modules/wagon/back/methods/wagonType/createWagonType.js b/modules/wagon/back/methods/wagonType/createWagonType.js new file mode 100644 index 000000000..fed915b28 --- /dev/null +++ b/modules/wagon/back/methods/wagonType/createWagonType.js @@ -0,0 +1,57 @@ +module.exports = Self => { + Self.remoteMethodCtx('createWagonType', { + description: 'Creates a new wagon type', + accessType: 'WRITE', + accepts: [ + { + arg: 'name', + type: 'String', + required: true + }, + { + arg: 'divisible', + type: 'boolean', + required: true + }, { + arg: 'trays', + type: 'any', + required: true + } + ], + http: { + path: `/createWagonType`, + verb: 'PATCH' + } + }); + + Self.createWagonType = async(ctx, options) => { + const args = ctx.args; + const models = Self.app.models; + const myOptions = {}; + let tx; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + try { + const newWagonType = await models.WagonType.create({name: args.name, divisible: args.divisible}, myOptions); + args.trays.forEach(async tray => { + await models.WagonTypeTray.create({ + typeFk: newWagonType.id, + height: tray.position, + colorFk: tray.color.id + }, myOptions); + }); + + if (tx) await tx.commit(); + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } + }; +}; diff --git a/modules/wagon/back/methods/wagonType/deleteWagonType.js b/modules/wagon/back/methods/wagonType/deleteWagonType.js new file mode 100644 index 000000000..46b65e32f --- /dev/null +++ b/modules/wagon/back/methods/wagonType/deleteWagonType.js @@ -0,0 +1,43 @@ +module.exports = Self => { + Self.remoteMethodCtx('deleteWagonType', { + description: 'Deletes a wagon type', + accessType: 'WRITE', + accepts: [ + { + arg: 'id', + type: 'Number', + required: true + } + ], + http: { + path: `/deleteWagonType`, + verb: 'DELETE' + } + }); + + Self.deleteWagonType = async(ctx, options) => { + const args = ctx.args; + const models = Self.app.models; + const myOptions = {}; + let tx; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + try { + await models.Wagon.destroyAll({typeFk: args.id}, myOptions); + await models.WagonTypeTray.destroyAll({typeFk: args.id}, myOptions); + await models.WagonType.destroyAll({id: args.id}, myOptions); + + if (tx) await tx.commit(); + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } + }; +}; diff --git a/modules/wagon/back/methods/wagonType/editWagonType.js b/modules/wagon/back/methods/wagonType/editWagonType.js new file mode 100644 index 000000000..bd5ad1f16 --- /dev/null +++ b/modules/wagon/back/methods/wagonType/editWagonType.js @@ -0,0 +1,64 @@ +module.exports = Self => { + Self.remoteMethodCtx('editWagonType', { + description: 'Edits a new wagon type', + accessType: 'WRITE', + accepts: [ + { + arg: 'id', + type: 'String', + required: true + }, + { + arg: 'name', + type: 'String', + required: true + }, + { + arg: 'divisible', + type: 'boolean', + required: true + }, { + arg: 'trays', + type: 'any', + required: true + } + ], + http: { + path: `/editWagonType`, + verb: 'PATCH' + } + }); + + Self.editWagonType = async(ctx, options) => { + const args = ctx.args; + const models = Self.app.models; + const myOptions = {}; + let tx; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + try { + const wagonType = await models.WagonType.findById(args.id, null, myOptions); + wagonType.updateAttributes({name: args.name, divisible: args.divisible}, myOptions); + models.WagonTypeTray.destroyAll({typeFk: args.id}, myOptions); + args.trays.forEach(async tray => { + await models.WagonTypeTray.create({ + typeFk: args.id, + height: tray.position, + colorFk: tray.color.id + }, myOptions); + }); + + if (tx) await tx.commit(); + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } + }; +}; diff --git a/modules/wagon/back/methods/wagonType/specs/crudWagonType.spec.js b/modules/wagon/back/methods/wagonType/specs/crudWagonType.spec.js new file mode 100644 index 000000000..92ac61060 --- /dev/null +++ b/modules/wagon/back/methods/wagonType/specs/crudWagonType.spec.js @@ -0,0 +1,63 @@ +const models = require('vn-loopback/server/server').models; + +describe('WagonType crudWagonType()', () => { + const ctx = { + args: { + name: 'Mock wagon type', + divisible: true, + trays: [{position: 0, color: {id: 1}}, + {position: 50, color: {id: 2}}, + {position: 100, color: {id: 3}}] + } + }; + + it(`should create, edit and delete a new wagon type and its trays`, async() => { + const tx = await models.WagonType.beginTransaction({}); + + try { + const options = {transaction: tx}; + + // create + await models.WagonType.createWagonType(ctx, options); + + const newWagonType = await models.WagonType.findOne({where: {name: ctx.args.name}}, options); + const newWagonTrays = await models.WagonTypeTray.find({where: {typeFk: newWagonType.id}}, options); + + expect(newWagonType).not.toEqual(null); + expect(newWagonType.name).toEqual(ctx.args.name); + expect(newWagonType.divisible).toEqual(ctx.args.divisible); + expect(newWagonTrays.length).toEqual(ctx.args.trays.length); + + ctx.args = { + id: newWagonType.id, + name: 'Edited wagon type', + divisible: false, + trays: [{position: 0, color: {id: 1}}] + }; + + // edit + await models.WagonType.editWagonType(ctx, options); + + const editedWagonType = await models.WagonType.findById(newWagonType.id, null, options); + const editedWagonTrays = await models.WagonTypeTray.find({where: {typeFk: newWagonType.id}}, options); + + expect(editedWagonType.name).toEqual(ctx.args.name); + expect(editedWagonType.divisible).toEqual(ctx.args.divisible); + expect(editedWagonTrays.length).toEqual(ctx.args.trays.length); + + // delete + await models.WagonType.deleteWagonType(ctx, options); + + const deletedWagonType = await models.WagonType.findById(newWagonType.id, null, options); + const deletedWagonTrays = await models.WagonTypeTray.find({where: {typeFk: newWagonType.id}}, options); + + expect(deletedWagonType).toEqual(null); + expect(deletedWagonTrays).toEqual([]); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); +}); diff --git a/modules/wagon/back/models/wagon-type.js b/modules/wagon/back/models/wagon-type.js new file mode 100644 index 000000000..bebf7a9d9 --- /dev/null +++ b/modules/wagon/back/models/wagon-type.js @@ -0,0 +1,5 @@ +module.exports = Self => { + require('../methods/wagonType/createWagonType')(Self); + require('../methods/wagonType/editWagonType')(Self); + require('../methods/wagonType/deleteWagonType')(Self); +}; diff --git a/modules/wagon/back/models/wagon.json b/modules/wagon/back/models/wagon.json index 81b9f23e6..61ee61e61 100644 --- a/modules/wagon/back/models/wagon.json +++ b/modules/wagon/back/models/wagon.json @@ -11,6 +11,9 @@ "id": true, "type": "number" }, + "label": { + "type": "number" + }, "volume": { "type": "number" },