Merge pull request 'fixes #5056 Nuevo sistema de sacado de pedidos: Gestión de vagones' (!1386) from 5056-gestion-vagones into dev
gitea/salix/pipeline/head This commit looks good Details

Reviewed-on: #1386
Reviewed-by: Joan Sanchez <joan@verdnatura.es>
This commit is contained in:
Joan Sanchez 2023-03-30 05:23:29 +00:00
commit 6aca23e466
15 changed files with 569 additions and 0 deletions

View File

@ -0,0 +1,72 @@
CREATE TABLE `vn`.`wagonType` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(30) NOT NULL UNIQUE,
`divisible` tinyint(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb3;
CREATE TABLE `vn`.`wagonTypeColor` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(30) NOT NULL UNIQUE,
`rgb` varchar(30) NOT NULL UNIQUE,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb3;
CREATE TABLE `vn`.`wagonTypeTray` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`typeFk` int(11) unsigned,
`height` int(11) unsigned NOT NULL,
`colorFk` int(11) unsigned,
PRIMARY KEY (`id`),
UNIQUE KEY (`typeFk`,`height`),
CONSTRAINT `wagonTypeTray_type` FOREIGN KEY (`typeFk`) REFERENCES `wagonType` (`id`) ON UPDATE CASCADE,
CONSTRAINT `wagonTypeTray_color` FOREIGN KEY (`colorFk`) REFERENCES `wagonTypeColor` (`id`) ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb3;
CREATE TABLE `vn`.`wagonConfig` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`width` int(11) unsigned DEFAULT 1350,
`height` int(11) unsigned DEFAULT 1900,
`maxWagonHeight` int(11) unsigned DEFAULT 200,
`minHeightBetweenTrays` int(11) unsigned DEFAULT 50,
`maxTrays` int(11) unsigned DEFAULT 6,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb3;
CREATE TABLE `vn`.`collectionWagon` (
`collectionFk` int(11) NOT NULL,
`wagonFk` int(11) NOT NULL,
`position` int(11) unsigned,
PRIMARY KEY (`collectionFk`,`position`),
UNIQUE KEY `collectionWagon_unique` (`collectionFk`,`wagonFk`),
CONSTRAINT `collectionWagon_collection` FOREIGN KEY (`collectionFk`) REFERENCES `collection` (`id`) ON UPDATE CASCADE,
CONSTRAINT `collectionWagon_wagon` FOREIGN KEY (`wagonFk`) REFERENCES `wagon` (`id`) ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
CREATE TABLE `vn`.`collectionWagonTicket` (
`ticketFk` int(11) NOT NULL,
`wagonFk` int(11) NOT NULL,
`trayFk` int(11) unsigned NOT NULL,
`side` SET('L', 'R') NULL,
PRIMARY KEY (`ticketFk`),
CONSTRAINT `collectionWagonTicket_ticket` FOREIGN KEY (`ticketFk`) REFERENCES `ticket` (`id`) ON UPDATE CASCADE,
CONSTRAINT `collectionWagonTicket_wagon` FOREIGN KEY (`wagonFk`) REFERENCES `wagon` (`id`) ON UPDATE CASCADE,
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 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`)
VALUES
('WagonType', '*', '*', 'ALLOW', 'ROLE', 'productionAssi'),
('WagonTypeColor', '*', '*', 'ALLOW', 'ROLE', 'productionAssi'),
('WagonTypeTray', '*', '*', 'ALLOW', 'ROLE', 'productionAssi'),
('WagonConfig', '*', '*', 'ALLOW', 'ROLE', 'productionAssi'),
('CollectionWagon', '*', '*', 'ALLOW', 'ROLE', 'productionAssi'),
('CollectionWagonTicket', '*', '*', 'ALLOW', 'ROLE', 'productionAssi'),
('Wagon', '*', '*', 'ALLOW', 'ROLE', 'productionAssi'),
('WagonType', 'createWagonType', '*', 'ALLOW', 'ROLE', 'productionAssi'),
('WagonType', 'deleteWagonType', '*', 'ALLOW', 'ROLE', 'productionAssi'),
('WagonType', 'editWagonType', '*', 'ALLOW', 'ROLE', 'productionAssi');

View File

@ -2840,4 +2840,27 @@ INSERT INTO `vn`.`workerTimeControlMail` (`id`, `workerFk`, `year`, `week`, `sta
(3, 9, 2000, 51, 'CONFIRMED', util.VN_NOW(), 1, NULL),
(4, 9, 2001, 1, 'SENDED', util.VN_NOW(), 1, NULL);
INSERT INTO `vn`.`wagonConfig` (`id`, `width`, `height`, `maxWagonHeight`, `minHeightBetweenTrays`, `maxTrays`)
VALUES
(1, 1350, 1900, 200, 50, 6);
INSERT INTO `vn`.`wagonTypeColor` (`id`, `name`, `rgb`)
VALUES
(1, 'white', '#ffffff'),
(2, 'red', '#ff0000'),
(3, 'green', '#00ff00'),
(4, 'blue', '#0000ff');
INSERT INTO `vn`.`wagonType` (`id`, `name`, `divisible`)
VALUES
(1, 'Wagon Type #1', 1);
INSERT INTO `vn`.`wagonTypeTray` (`id`, `typeFk`, `height`, `colorFk`)
VALUES
(1, 1, 100, 1),
(2, 1, 50, 2),
(3, 1, 0, 3);

View File

@ -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;
}
};
};

View File

@ -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;
}
};
};

View File

@ -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;
}
};
};

View File

@ -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;
}
});
});

View File

@ -0,0 +1,23 @@
{
"Wagon": {
"dataSource": "vn"
},
"WagonType": {
"dataSource": "vn"
},
"WagonTypeColor": {
"dataSource": "vn"
},
"WagonTypeTray": {
"dataSource": "vn"
},
"WagonConfig": {
"dataSource": "vn"
},
"CollectionWagon": {
"dataSource": "vn"
},
"CollectionWagonTicket": {
"dataSource": "vn"
}
}

View File

@ -0,0 +1,43 @@
{
"name": "CollectionWagonTicket",
"base": "VnModel",
"options": {
"mysql": {
"table": "collectionWagonTicket"
}
},
"properties": {
"ticketFk": {
"id": true,
"type": "number"
},
"wagonFk": {
"type": "number",
"required": true
},
"trayFk": {
"type": "number",
"required": true
},
"side": {
"type": "string"
}
},
"relations": {
"ticket": {
"type": "belongsTo",
"model": "Ticket",
"foreignKey": "ticketFk"
},
"wagon": {
"type": "belongsTo",
"model": "Wagon",
"foreignKey": "wagonFk"
},
"tray": {
"type": "belongsTo",
"model": "WagonTypeTray",
"foreignKey": "trayFk"
}
}
}

View File

@ -0,0 +1,34 @@
{
"name": "CollectionWagon",
"base": "VnModel",
"options": {
"mysql": {
"table": "collectionWagon"
}
},
"properties": {
"collectionFk": {
"id": true,
"type": "number"
},
"wagonFk": {
"type": "number",
"required": true
},
"position": {
"type": "number"
}
},
"relations": {
"collection": {
"type": "belongsTo",
"model": "Collection",
"foreignKey": "collectionFk"
},
"wagon": {
"type": "belongsTo",
"model": "Wagon",
"foreignKey": "wagonFk"
}
}
}

View File

@ -0,0 +1,30 @@
{
"name": "WagonConfig",
"base": "VnModel",
"options": {
"mysql": {
"table": "wagonConfig"
}
},
"properties": {
"id": {
"id": true,
"type": "number"
},
"width": {
"type": "number"
},
"height": {
"type": "string"
},
"maxWagonHeight": {
"type": "number"
},
"minHeightBetweenTrays": {
"type": "number"
},
"maxTrays": {
"type": "number"
}
}
}

View File

@ -0,0 +1,21 @@
{
"name": "WagonTypeColor",
"base": "VnModel",
"options": {
"mysql": {
"table": "wagonTypeColor"
}
},
"properties": {
"id": {
"id": true,
"type": "number"
},
"name": {
"type": "string"
},
"rgb": {
"type": "string"
}
}
}

View File

@ -0,0 +1,36 @@
{
"name": "WagonTypeTray",
"base": "VnModel",
"options": {
"mysql": {
"table": "wagonTypeTray"
}
},
"properties": {
"id": {
"id": true,
"type": "number"
},
"typeFk": {
"type": "number"
},
"height": {
"type": "number"
},
"colorFk": {
"type": "number"
}
},
"relations": {
"type": {
"type": "belongsTo",
"model": "WagonType",
"foreignKey": "typeFk"
},
"color": {
"type": "belongsTo",
"model": "WagonTypeColor",
"foreignKey": "colorFk"
}
}
}

View File

@ -0,0 +1,5 @@
module.exports = Self => {
require('../methods/wagonType/createWagonType')(Self);
require('../methods/wagonType/editWagonType')(Self);
require('../methods/wagonType/deleteWagonType')(Self);
};

View File

@ -0,0 +1,21 @@
{
"name": "WagonType",
"base": "VnModel",
"options": {
"mysql": {
"table": "wagonType"
}
},
"properties": {
"id": {
"id": true,
"type": "number"
},
"name": {
"type": "string"
},
"divisible": {
"type": "boolean"
}
}
}

View File

@ -0,0 +1,34 @@
{
"name": "Wagon",
"base": "VnModel",
"options": {
"mysql": {
"table": "wagon"
}
},
"properties": {
"id": {
"id": true,
"type": "number"
},
"label": {
"type": "number"
},
"volume": {
"type": "number"
},
"plate": {
"type": "string"
},
"typeFk": {
"type": "number"
}
},
"relations": {
"type": {
"type": "belongsTo",
"model": "WagonType",
"foreignKey": "typeFk"
}
}
}