diff --git a/db/dump/fixtures.before.sql b/db/dump/fixtures.before.sql index c5e66babf6..b83d190c91 100644 --- a/db/dump/fixtures.before.sql +++ b/db/dump/fixtures.before.sql @@ -3793,6 +3793,7 @@ INSERT INTO vn.workCenter (id, name, payrollCenterFk, counter, warehouseFk, stre UPDATE vn.locker SET workerFk = 1110 WHERE id = 147; +ALTER TABLE vn.docuwareTablet ADD fileCabinet varchar(100) NULL; ALTER TABLE vn.docuware ADD modelFk VARCHAR(45) DEFAULT NULL NULL; ALTER TABLE vn.docuware ADD CONSTRAINT docuware_module_FK FOREIGN KEY (modelFk) REFERENCES salix.module(code); -- Auto-generated SQL script #202405201318 @@ -3811,3 +3812,6 @@ UPDATE vn.docuware UPDATE vn.docuware SET modelFk='worker' WHERE id=3; +-- Auto-generated SQL script #202405201951 +INSERT INTO salix.ACL (model,property,accessType,permission,principalType,principalId) + VALUES ('Worker','isPDASigned','READ','ALLOW','ROLE','hr'); diff --git a/modules/worker/back/methods/worker/docuwareUpload.js b/modules/worker/back/methods/worker/docuwareUpload.js new file mode 100644 index 0000000000..530b29ecc0 --- /dev/null +++ b/modules/worker/back/methods/worker/docuwareUpload.js @@ -0,0 +1,117 @@ +const axios = require('axios'); +const {models} = require('vn-loopback/server/server'); +const UserError = require('vn-loopback/util/user-error'); + +module.exports = Self => { + Self.docuwareUpload = async({ctx, tabletFk, ids: workerId, myOptions, uri, docuwareOptions, dialogId}) => { + if (!Array.isArray(workerId)) workerId = [workerId]; + for (id of ticketIds) { + // get delivery note + ctx.args.id = id; + const deliveryNote = await models.Ticket.deliveryNotePdf(ctx, { + id, + type: 'deliveryNote' + }, myOptions); + // get ticket data + const ticket = await models.Ticket.findById(id, { + include: [{ + relation: 'client', + scope: { + fields: ['id', 'name', 'fi'] + } + }] + }, myOptions); + + // upload file + const templateJson = { + 'Fields': [ + { + 'FieldName': 'N__ALBAR_N', + 'ItemElementName': 'string', + 'Item': id, + }, + { + 'FieldName': 'CIF_PROVEEDOR', + 'ItemElementName': 'string', + 'Item': ticket.client().fi, + }, + { + 'FieldName': 'CODIGO_PROVEEDOR', + 'ItemElementName': 'string', + 'Item': ticket.client().id, + }, + { + 'FieldName': 'NOMBRE_PROVEEDOR', + 'ItemElementName': 'string', + 'Item': ticket.client().name + ' - ' + id, + }, + { + 'FieldName': 'FECHA_FACTURA', + 'ItemElementName': 'date', + 'Item': ticket.shipped, + }, + { + 'FieldName': 'TOTAL_FACTURA', + 'ItemElementName': 'Decimal', + 'Item': ticket.totalWithVat, + }, + { + 'FieldName': 'ESTADO', + 'ItemElementName': 'string', + 'Item': 'Pendiente procesar', + }, + { + 'FieldName': 'FIRMA_', + 'ItemElementName': 'string', + 'Item': 'Si', + }, + { + 'FieldName': 'FILTRO_TABLET', + 'ItemElementName': 'string', + 'Item': tabletFk, + } + ] + }; + + if (process.env.NODE_ENV != 'production') + throw new UserError('Action not allowed on the test environment'); + + // delete old + const docuwareFile = await models.Docuware.checkFile(id, fileCabinet, false); + if (docuwareFile) { + const deleteJson = { + 'Field': [{'FieldName': 'ESTADO', 'Item': 'Pendiente eliminar', 'ItemElementName': 'String'}] + }; + const deleteUri = `${uri}/${docuwareFile.id}/Fields`; + await axios.put(deleteUri, deleteJson, docuwareOptions.headers); + } + + const uploadUri = `${uri}?StoreDialogId=${dialogId}`; + const FormData = require('form-data'); + const data = new FormData(); + + data.append('document', JSON.stringify(templateJson), 'schema.json'); + data.append('file[]', deliveryNote[0], 'file.pdf'); + const uploadOptions = { + headers: { + 'Content-Type': 'multipart/form-data', + 'X-File-ModifiedDate': Date.vnNew(), + 'Cookie': docuwareOptions.headers.headers.Cookie, + ...data.getHeaders() + }, + }; + + try { + await axios.post(uploadUri, data, uploadOptions); + } catch (err) { + const $t = ctx.req.__; + const message = $t('Failed to upload delivery note', {id}); + if (uploaded.length) + await models.TicketTracking.setDelivered(ctx, uploaded, myOptions); + throw new UserError(message); + } + uploaded.push(id); + } + }; +}; + diff --git a/modules/worker/back/methods/worker/signedPDA.js b/modules/worker/back/methods/worker/signedPDA.js new file mode 100644 index 0000000000..5080b84d5c --- /dev/null +++ b/modules/worker/back/methods/worker/signedPDA.js @@ -0,0 +1,54 @@ +const UserError = require('vn-loopback/util/user-error'); + +module.exports = Self => { + Self.remoteMethodCtx('isPDASigned', { + description: 'Deallocate the PDA of the worker', + accepts: [{ + arg: 'ctx', + type: 'Object', + http: {source: 'context'} + }, { + arg: 'id', + type: 'number', + required: true, + description: 'The worker id', + http: {source: 'path'} + }, { + arg: 'pda', + type: 'number', + required: true, + description: 'The pda id' + }], + returns: { + type: ['object'], + root: true + }, + http: { + path: '/:id/:pda/isPDASigned', + verb: 'GET' + } + }); + + Self.isPDASigned = async(ctx, options) => { + const models = Self.app.models; + const args = ctx.args; + let tx; + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + try { + const pda = await models.DeviceProduction.findById(args.pda, myOptions); + if (pda.stateFk != 'idle') throw new UserError(`The PDA state is not idle`); + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } + }; +}; diff --git a/modules/worker/back/models/device-production-user.js b/modules/worker/back/models/device-production-user.js index 81af484d30..f228f6d55a 100644 --- a/modules/worker/back/models/device-production-user.js +++ b/modules/worker/back/models/device-production-user.js @@ -1,4 +1,5 @@ const UserError = require('vn-loopback/util/user-error'); + module.exports = Self => { Self.rewriteDbError(function(err) { if (err.code === 'ER_DUP_ENTRY') diff --git a/modules/worker/back/models/worker.js b/modules/worker/back/models/worker.js index 0b0e043f2e..6f9c1e2393 100644 --- a/modules/worker/back/models/worker.js +++ b/modules/worker/back/models/worker.js @@ -8,6 +8,7 @@ module.exports = Self => { require('../methods/worker/createAbsence')(Self); require('../methods/worker/deleteAbsence')(Self); require('../methods/worker/updateAbsence')(Self); + require('../methods/worker/docuwareUpload')(Self); require('../methods/worker/active')(Self); require('../methods/worker/activeWithRole')(Self); require('../methods/worker/activeWithInheritedRole')(Self); @@ -17,6 +18,7 @@ module.exports = Self => { require('../methods/worker/new')(Self); require('../methods/worker/deallocatePDA')(Self); require('../methods/worker/allocatePDA')(Self); + require('../methods/worker/signedPDA')(Self); require('../methods/worker/search')(Self); require('../methods/worker/isAuthorized')(Self); require('../methods/worker/setPassword')(Self);