From 7ea1fbfb260184dbb9fcf5c7c0ceedb82c04f814 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 18 Jan 2024 15:09:52 +0100 Subject: [PATCH] refs #5509 feat: entryDms funcionality --- db/changes/240401/00-entryDms.sql | 87 +++++++++++++++++++ db/dump/fixtures.sql | 10 ++- .../back/methods/entry-dms/removeFile.js | 53 +++++++++++ .../back/methods/entry-dms/uploadFile.js | 86 ++++++++++++++++++ modules/entry/back/models/entry-dms.js | 11 +++ modules/entry/back/models/entry-dms.json | 28 ++++++ 6 files changed, 273 insertions(+), 2 deletions(-) create mode 100644 db/changes/240401/00-entryDms.sql create mode 100644 modules/entry/back/methods/entry-dms/removeFile.js create mode 100644 modules/entry/back/methods/entry-dms/uploadFile.js create mode 100644 modules/entry/back/models/entry-dms.js create mode 100644 modules/entry/back/models/entry-dms.json diff --git a/db/changes/240401/00-entryDms.sql b/db/changes/240401/00-entryDms.sql new file mode 100644 index 0000000000..5dab74de99 --- /dev/null +++ b/db/changes/240401/00-entryDms.sql @@ -0,0 +1,87 @@ +CREATE OR REPLACE TABLE `vn`.`entryDms` ( + `entryFk` int(11) NOT NULL, + `dmsFk` int(11) NOT NULL, + `editorFk` int(10) unsigned DEFAULT NULL, + PRIMARY KEY (`entryFk`,`dmsFk`), + KEY `gestdoc_id` (`dmsFk`), + KEY `entryDms_editor` (`editorFk`), + CONSTRAINT `entryDms_dms` FOREIGN KEY (`dmsFk`) REFERENCES `dms` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `entryDms_editor` FOREIGN KEY (`editorFk`) REFERENCES `account`.`user` (`id`), + CONSTRAINT `entryDms_entry` FOREIGN KEY (`entryFk`) REFERENCES `entry` (`id`) ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; + +DROP TRIGGER IF EXISTS `vn`.`entryDms_beforeInsert`; +USE `vn`; + +DELIMITER $$ +$$ +CREATE DEFINER=`root`@`localhost` TRIGGER `vn`.`entryDms_beforeInsert` + BEFORE INSERT ON `entryDms` + FOR EACH ROW +BEGIN + SET NEW.editorFk = account.myUser_getId(); +END $$ +DELIMITER ; + +DROP TRIGGER IF EXISTS `vn`.`entryDms_beforeUpdate`; +USE `vn`; + +DELIMITER $$ +$$ +CREATE DEFINER=`root`@`localhost` TRIGGER `vn`.`entryDms_beforeUpdate` + BEFORE UPDATE ON `entryDms` + FOR EACH ROW +BEGIN + SET NEW.editorFk = account.myUser_getId(); +END $$ +DELIMITER ; + +DROP TRIGGER IF EXISTS `vn`.`entryDms_beforeDelete`; +USE `vn`; + +DELIMITER $$ +$$ +CREATE DEFINER=`root`@`localhost` TRIGGER `vn`.`entryDms_beforeDelete` + BEFORE DELETE ON `entryDms` + FOR EACH ROW +BEGIN + UPDATE dms + SET dmsTypeFk = (SELECT id + FROM dmsType + WHERE `code` = 'trash' + ) + WHERE id = OLD.dmsFk AND ( SELECT IF(COUNT(*) > 0, FALSE, TRUE) + FROM entryDms + WHERE dmsFk = OLD.dmsFk + ) ; +END $$ +DELIMITER ; + +DROP TRIGGER IF EXISTS `vn`.`entryDms_afterDelete`; +USE `vn`; + +DELIMITER $$ +$$ +CREATE DEFINER=`root`@`localhost` TRIGGER `vn`.`entryDms_afterDelete` + AFTER DELETE ON `entryDms` + FOR EACH ROW +BEGIN + INSERT INTO entryLog + SET `action` = 'delete', + `changedModel` = 'entryDms', + `changedModelId` = OLD.entryFk, + `userFk` = account.myUser_getId(); +END $$ +DELIMITER ; + + +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES + ('WorkerDms', '*', '*', 'ALLOW', 'ROLE', 'employee'), + ('EntryDms', '*', '*', 'ALLOW', 'ROLE', 'employee'), + ('Entry', 'uploadFile', 'WRITE', 'ALLOW', 'ROLE', 'employee'); + +UPDATE `salix`.`ACL` + SET accessType = '*' + WHERE model = 'ClientDms' + AND property = '*'; diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index b243692bb2..b962abfedd 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -2387,7 +2387,8 @@ INSERT INTO `vn`.`dmsType`(`id`, `name`, `path`, `readRoleFk`, `writeRoleFk`, `c (17, 'cmr', 'cmr', NULL, NULL, 'cmr'), (18, 'dua', 'dua', NULL, NULL, 'dua'), (19, 'inmovilizado', 'inmovilizado', NULL, NULL, 'fixedAssets'), - (20, 'ReclamaciĆ³n', 'reclamacion', 1, 1, 'claim'); + (20, 'ReclamaciĆ³n', 'reclamacion', 1, 1, 'claim'), + (21, 'Entrada', 'entrada', 1, 1, 'entry'); INSERT INTO `vn`.`dms`(`id`, `dmsTypeFk`, `file`, `contentType`, `workerFk`, `warehouseFk`, `companyFk`, `hardCopyNumber`, `hasFile`, `reference`, `description`, `created`) VALUES @@ -2398,7 +2399,8 @@ INSERT INTO `vn`.`dms`(`id`, `dmsTypeFk`, `file`, `contentType`, `workerFk`, `wa (5, 5, '5.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'travel: 1', 'dmsForThermograph', util.VN_CURDATE()), (6, 5, '6.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'NotExists', 'DoesNotExists', util.VN_CURDATE()), (7, 20, '7.jpg', 'image/jpeg', 9, 1, 442, NULL, FALSE, '1', 'TICKET ID DEL CLIENTE BRUCE WAYNE ID 1101', util.VN_CURDATE()), - (8, 20, '8.mp4', 'video/mp4', 9, 1, 442, NULL, FALSE, '1', 'TICKET ID DEL CLIENTE BRUCE WAYNE ID 1101', util.VN_CURDATE()); + (8, 20, '8.mp4', 'video/mp4', 9, 1, 442, NULL, FALSE, '1', 'TICKET ID DEL CLIENTE BRUCE WAYNE ID 1101', util.VN_CURDATE()), + (9, 21, '7.jpg', 'image/jpeg', 9, 1, 442, NULL, FALSE, '1', 'ENTRADA ID 1', util.VN_CURDATE()); INSERT INTO `vn`.`claimDms`(`claimFk`, `dmsFk`) VALUES @@ -3043,3 +3045,7 @@ INSERT INTO `vn`.`clientSms` (`id`, `clientFk`, `smsFk`, `ticketFk`) (4, 1103, 4, 32), (13, 1101, 1, NULL), (14, 1101, 4, 27); + +INSERT INTO `vn`.`entryDms`(`entryFk`, `dmsFk`, `editorFk`) + VALUES + (1, 9, 9); diff --git a/modules/entry/back/methods/entry-dms/removeFile.js b/modules/entry/back/methods/entry-dms/removeFile.js new file mode 100644 index 0000000000..677e627a6b --- /dev/null +++ b/modules/entry/back/methods/entry-dms/removeFile.js @@ -0,0 +1,53 @@ +const UserError = require('vn-loopback/util/user-error'); + +module.exports = Self => { + Self.remoteMethodCtx('removeFile', { + description: 'Removes a claim document', + accessType: 'WRITE', + accepts: { + arg: 'id', + type: 'number', + description: 'The document id', + http: {source: 'path'} + }, + returns: { + type: 'object', + root: true + }, + http: { + path: `/:id/removeFile`, + verb: 'POST' + } + }); + + Self.removeFile = async(ctx, id, options) => { + const myOptions = {}; + let tx; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + try { + const targetEntryDms = await Self.findById(id, null, myOptions); + const targetDms = await Self.app.models.Dms.removeFile(ctx, targetEntryDms.dmsFk, myOptions); + + if (!targetDms || ! targetEntryDms) + throw new UserError('Try again'); + + const entryDmsDestroyed = await targetEntryDms.destroy(myOptions); + + if (tx) await tx.commit(); + + return entryDmsDestroyed; + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } + }; +}; + diff --git a/modules/entry/back/methods/entry-dms/uploadFile.js b/modules/entry/back/methods/entry-dms/uploadFile.js new file mode 100644 index 0000000000..fe0cfab5ff --- /dev/null +++ b/modules/entry/back/methods/entry-dms/uploadFile.js @@ -0,0 +1,86 @@ + +module.exports = Self => { + Self.remoteMethodCtx('uploadFile', { + description: 'Upload and attach a file', + accessType: 'WRITE', + accepts: [{ + arg: 'id', + type: 'number', + description: 'The claim id', + http: {source: 'path'} + }, + { + arg: 'warehouseId', + type: 'number', + description: 'The warehouse id', + required: true + }, + { + arg: 'companyId', + type: 'number', + description: 'The company id', + required: true + }, + { + arg: 'dmsTypeId', + type: 'number', + description: 'The dms type id', + required: true + }, + { + arg: 'reference', + type: 'string', + required: true + }, + { + arg: 'description', + type: 'string', + required: true + }, + { + arg: 'hasFile', + type: 'boolean', + description: 'True if has an attached file', + required: true + }], + returns: { + type: 'object', + root: true + }, + http: { + path: `/:id/uploadFile`, + verb: 'POST' + } + }); + + Self.uploadFile = async(ctx, id, options) => { + const {Dms, EntryDms} = 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 uploadedFiles = await Dms.uploadFile(ctx, myOptions); + + const promises = uploadedFiles.map(dms => EntryDms.create({ + entryFk: id, + dmsFk: dms.id + }, myOptions)); + await Promise.all(promises); + + if (tx) await tx.commit(); + + return uploadedFiles; + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } + }; +}; diff --git a/modules/entry/back/models/entry-dms.js b/modules/entry/back/models/entry-dms.js new file mode 100644 index 0000000000..b00337968d --- /dev/null +++ b/modules/entry/back/models/entry-dms.js @@ -0,0 +1,11 @@ +const UserError = require('vn-loopback/util/user-error'); + +module.exports = Self => { + require('../methods/entry-dms/removeFile')(Self); + + Self.rewriteDbError(function(err) { + if (err.code === 'ER_DUP_ENTRY') + return new UserError('This document already exists on this entry'); + return err; + }); +}; diff --git a/modules/entry/back/models/entry-dms.json b/modules/entry/back/models/entry-dms.json new file mode 100644 index 0000000000..c43443c858 --- /dev/null +++ b/modules/entry/back/models/entry-dms.json @@ -0,0 +1,28 @@ +{ + "name": "EntryDms", + "base": "Loggable", + "options": { + "mysql": { + "table": "entryDms" + } + }, + "properties": { + "dmsFk": { + "type": "number", + "id": true, + "required": true + } + }, + "relations": { + "entry": { + "type": "belongsTo", + "model": "Entry", + "foreignKey": "entryFk" + }, + "dms": { + "type": "belongsTo", + "model": "Dms", + "foreignKey": "dmsFk" + } + } +}