diff --git a/back/methods/dms/saveSign.js b/back/methods/dms/saveSign.js new file mode 100644 index 000000000..f668c5ed2 --- /dev/null +++ b/back/methods/dms/saveSign.js @@ -0,0 +1,215 @@ +const md5 = require('md5'); +const fs = require('fs-extra'); + +module.exports = Self => { + Self.remoteMethodCtx('saveSign', { + description: 'Save sign', + accessType: 'WRITE', + accepts: + [ + { + arg: 'signContent', + type: 'string', + required: true, + description: 'The sign content' + }, { + arg: 'tickets', + type: ['number'], + required: true, + description: 'The tickets' + }, { + arg: 'signedTime', + type: 'date', + description: 'The signed time' + }, { + arg: 'addressFk', + type: 'number', + required: true, + description: 'The address fk' + } + ], + returns: { + type: 'Object', + root: true + }, + http: { + path: `/saveSign`, + verb: 'POST' + } + }); + + async function createGestDoc(ticketId, userFk) { + const models = Self.app.models; + if (!await gestDocExists(ticketId)) { + const result = await models.Ticket.findOne({ + where: { + id: ticketId + }, + include: [ + { + relation: 'warehouse', + scope: { + fields: ['id'] + } + }, { + relation: 'client', + scope: { + fields: ['name'] + } + }, { + relation: 'route', + scope: { + fields: ['id'] + } + } + ] + }); + + const warehouseFk = result.warehouseFk; + const companyFk = result.companyFk; + const client = result.client.name; + const route = result.route.id; + + const resultDmsType = await models.DmsType.findOne({ + where: { + code: 'Ticket' + } + }); + + const resultDms = await models.Dms.create({ + dmsTypeFk: resultDmsType.id, + reference: ticketId, + description: `Ticket ${ticketId} Cliente ${client} Ruta ${route}`, + companyFk: companyFk, + warehouseFk: warehouseFk, + workerFk: userFk + }); + + return resultDms.insertId; + } + } + + async function gestDocExists(ticket) { + const models = Self.app.models; + const result = await models.TicketDms.findOne({ + where: { + ticketFk: ticket + }, + fields: ['dmsFk'] + }); + + if (result == null) + return false; + + const isSigned = await models.Ticket.findOne({ + where: { + id: ticket + }, + fields: ['isSigned'] + }); + + if (isSigned) + return true; + else + await models.Dms.destroyById(ticket); + } + + async function dmsRecover(ticket, signContent) { + const models = Self.app.models; + await models.DmsRecover.create({ + ticketFk: ticket, + sign: signContent + }); + } + + async function ticketGestdoc(ticket, dmsFk) { + const models = Self.app.models; + models.TicketDms.replaceOrCreate({ + ticketFk: ticket, + dmsFk: dmsFk + }); + + const queryVnTicketSetState = `CALL vn.ticket_setState(?, ?)`; + + await Self.rawSql(queryVnTicketSetState, [ticket, 'DELIVERED']); + } + + async function updateGestdoc(file, ticket) { + const models = Self.app.models; + models.Dms.updateOne({ + where: { + id: ticket + }, + file: file, + contentType: 'image/png' + }); + } + + Self.saveSign = async(ctx, signContent, tickets, signedTime) => { + const models = Self.app.models; + let tx = await Self.beginTransaction({}); + try { + const userId = ctx.req.accessToken.userId; + + const dmsDir = `storage/dms`; + + let image = null; + + for (let i = 0; i < tickets.length; i++) { + const alertLevel = await models.TicketState.findOne({ + where: { + ticketFk: tickets[i] + }, + fields: ['alertLevel'] + }); + + signedTime ? signedTime != undefined : signedTime = new Date(); + + if (alertLevel >= 2) { + let dir; + let id = null; + let fileName = null; + + if (!await gestDocExists(tickets[i])) { + id = await createGestDoc(tickets[i], userId); + + const hashDir = md5(id).substring(0, 3); + dir = `${dmsDir}/${hashDir}`; + + if (!fs.existsSync(dir)) + fs.mkdirSync(dir); + + fileName = `${id}.png`; + image = `${dir}/${fileName}`; + } else + + if (image != null) { + if (!fs.existsSync(dir)) + dmsRecover(tickets[i], signContent); + else { + fs.writeFile(image, signContent, 'base64', async function(err) { + if (err) { + await tx.rollback(); + return err.message; + } + }); + } + } else + dmsRecover(tickets[i], signContent); + + if (id != null && fileName.length > 0) { + ticketGestdoc(tickets[i], id); + updateGestdoc(id, fileName); + } + } + } + + if (tx) await tx.commit(); + + return 'OK'; + } catch (err) { + await tx.rollback(); + throw err.message; + } + }; +}; diff --git a/back/models/dms.js b/back/models/dms.js index 24c072f56..fc586201f 100644 --- a/back/models/dms.js +++ b/back/models/dms.js @@ -6,6 +6,7 @@ module.exports = Self => { require('../methods/dms/removeFile')(Self); require('../methods/dms/updateFile')(Self); require('../methods/dms/deleteTrashFiles')(Self); + require('../methods/dms/saveSign')(Self); Self.checkRole = async function(ctx, id) { const models = Self.app.models; diff --git a/db/changes/225201/00-ACL_saveSign.sql b/db/changes/225201/00-ACL_saveSign.sql new file mode 100644 index 000000000..16f9931c4 --- /dev/null +++ b/db/changes/225201/00-ACL_saveSign.sql @@ -0,0 +1 @@ +INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalId`) VALUES ('Dms','saveSign','*','ALLOW','employee'); diff --git a/front/package-lock.json b/front/package-lock.json index 6922cae53..256797df0 100644 --- a/front/package-lock.json +++ b/front/package-lock.json @@ -3,6 +3,13 @@ "version": "1.0.0", "lockfileVersion": 1, "requires": true, +<<<<<<< HEAD + "dependencies": { + "@uirouter/angularjs": { + "version": "1.0.29", + "resolved": "https://registry.npmjs.org/@uirouter/angularjs/-/angularjs-1.0.29.tgz", + "integrity": "sha512-RImWnBarNixkMto0o8stEaGwZmvhv5cnuOLXyMU2pY8MP2rgEF74ZNJTLeJCW14LR7XDUxVH8Mk8bPI6lxedmQ==", +======= "packages": { "": { "name": "salix-front", @@ -174,11 +181,22 @@ "version": "1.0.30", "resolved": "https://registry.npmjs.org/@uirouter/angularjs/-/angularjs-1.0.30.tgz", "integrity": "sha512-qkc3RFZc91S5K0gc/QVAXc9LGDPXjR04vDgG/11j8+yyZEuQojXxKxdLhKIepiPzqLmGRVqzBmBc27gtqaEeZg==", +>>>>>>> dev "requires": { "@uirouter/core": "6.0.8" } }, "@uirouter/core": { +<<<<<<< HEAD + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/@uirouter/core/-/core-6.0.7.tgz", + "integrity": "sha512-KUTJxL+6q0PiBnFx4/Z+Hsyg0pSGiaW5yZQeJmUxknecjpTbnXkLU8H2EqRn9N2B+qDRa7Jg8RcgeNDPY72O1w==" + }, + "angular": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/angular/-/angular-1.8.2.tgz", + "integrity": "sha512-IauMOej2xEe7/7Ennahkbb5qd/HFADiNuLSESz9Q27inmi32zB0lnAsFeLEWcox3Gd1F6YhNd1CP7/9IukJ0Gw==" +======= "version": "6.0.8", "resolved": "https://registry.npmjs.org/@uirouter/core/-/core-6.0.8.tgz", "integrity": "sha512-Gc/BAW47i4L54p8dqYCJJZuv2s3tqlXQ0fvl6Zp2xrblELPVfxmjnc0eurx3XwfQdaqm3T6uls6tQKkof/4QMw==" @@ -187,6 +205,7 @@ "version": "1.8.3", "resolved": "https://registry.npmjs.org/angular/-/angular-1.8.3.tgz", "integrity": "sha512-5qjkWIQQVsHj4Sb5TcEs4WZWpFeVFHXwxEBHUhrny41D8UrBAd6T/6nPPAsLngJCReIOqi95W3mxdveveutpZw==" +>>>>>>> dev }, "angular-animate": { "version": "1.8.2", @@ -202,17 +221,29 @@ } }, "angular-translate": { +<<<<<<< HEAD + "version": "2.18.4", + "resolved": "https://registry.npmjs.org/angular-translate/-/angular-translate-2.18.4.tgz", + "integrity": "sha512-KohNrkH6J9PK+VW0L/nsRTcg5Fw70Ajwwe3Jbfm54Pf9u9Fd+wuingoKv+h45mKf38eT+Ouu51FPua8VmZNoCw==", +======= "version": "2.19.0", "resolved": "https://registry.npmjs.org/angular-translate/-/angular-translate-2.19.0.tgz", "integrity": "sha512-Z/Fip5uUT2N85dPQ0sMEe1JdF5AehcDe4tg/9mWXNDVU531emHCg53ZND9Oe0dyNiGX5rWcJKmsL1Fujus1vGQ==", +>>>>>>> dev "requires": { "angular": "^1.8.0" } }, "angular-translate-loader-partial": { +<<<<<<< HEAD + "version": "2.18.4", + "resolved": "https://registry.npmjs.org/angular-translate-loader-partial/-/angular-translate-loader-partial-2.18.4.tgz", + "integrity": "sha512-bsjR+FbB0sdA2528E/ugwKdlPPQhA1looxLxI3otayBTFXBpED33besfSZhYAISLgNMSL038vSssfRUen9qD8w==", +======= "version": "2.19.0", "resolved": "https://registry.npmjs.org/angular-translate-loader-partial/-/angular-translate-loader-partial-2.19.0.tgz", "integrity": "sha512-NnMw13LMV4bPQmJK7/pZOZAnPxe0M5OtUHchADs5Gye7V7feonuEnrZ8e1CKhBlv9a7IQyWoqcBa4Lnhg8gk5w==", +>>>>>>> dev "requires": { "angular-translate": "~2.19.0" } @@ -253,9 +284,15 @@ } }, "moment": { +<<<<<<< HEAD + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" +======= "version": "2.29.4", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==" +>>>>>>> dev }, "oclazyload": { "version": "0.6.3",