diff --git a/back/methods/viaexpress-config/internationalExpedition.js b/back/methods/viaexpress-config/internationalExpedition.js new file mode 100644 index 0000000000..698bb1dac4 --- /dev/null +++ b/back/methods/viaexpress-config/internationalExpedition.js @@ -0,0 +1,45 @@ +const axios = require('axios'); +const {DOMParser} = require('xmldom'); + +module.exports = Self => { + Self.remoteMethod('internationalExpedition', { + description: 'Create an expedition and return a label', + accessType: 'WRITE', + accepts: [{ + arg: 'expeditionFk', + type: 'number', + required: true + }], + returns: { + type: ['object'], + root: true + }, + http: { + path: `/internationalExpedition`, + verb: 'POST' + } + }); + + Self.internationalExpedition = async expeditionFk => { + const models = Self.app.models; + + const viaexpressConfig = await models.ViaexpressConfig.findOne({ + fields: ['url'] + }); + + const renderedXml = await models.ViaexpressConfig.renderer(expeditionFk); + const response = await axios.post(`${viaexpressConfig.url}ServicioVxClientes.asmx`, renderedXml, { + headers: { + 'Content-Type': 'application/soap+xml; charset=utf-8' + } + }); + + const xmlString = response.data; + const parser = new DOMParser(); + const xmlDoc = parser.parseFromString(xmlString, 'text/xml'); + const referenciaVxElement = xmlDoc.getElementsByTagName('ReferenciaVx')[0]; + const referenciaVx = referenciaVxElement.textContent; + + return referenciaVx; + }; +}; diff --git a/back/methods/viaexpress-config/renderer.js b/back/methods/viaexpress-config/renderer.js new file mode 100644 index 0000000000..e9abce5ca7 --- /dev/null +++ b/back/methods/viaexpress-config/renderer.js @@ -0,0 +1,126 @@ +const fs = require('fs'); +const ejs = require('ejs'); + +module.exports = Self => { + Self.remoteMethod('renderer', { + description: 'Renders the data from an XML', + accessType: 'READ', + accepts: [{ + arg: 'expeditionFk', + type: 'number', + required: true + }], + returns: { + type: ['object'], + root: true + }, + http: { + path: `/renderer`, + verb: 'GET' + } + }); + + Self.renderer = async expeditionFk => { + const models = Self.app.models; + + const viaexpressConfig = await models.ViaexpressConfig.findOne({ + fields: ['client', 'user', 'password', 'defaultWeight', 'deliveryType'] + }); + + const expedition = await models.Expedition.findOne({ + fields: ['id', 'ticketFk'], + where: {id: expeditionFk}, + include: [ + { + relation: 'ticket', + scope: { + fields: ['shipped', 'addressFk', 'clientFk', 'companyFk'], + include: [ + { + relation: 'client', + scope: { + fields: ['mobile', 'phone', 'email'] + } + }, + { + relation: 'address', + scope: { + fields: [ + 'nickname', + 'street', + 'postalCode', + 'city', + 'mobile', + 'phone', + 'provinceFk' + ], + include: { + relation: 'province', + scope: { + fields: ['name', 'countryFk'], + include: { + relation: 'country', + scope: { + fields: ['code'], + } + } + + } + } + } + }, + { + relation: 'company', + scope: { + fields: ['clientFk'], + include: { + relation: 'client', + scope: { + fields: ['socialName', 'mobile', 'phone', 'email', 'defaultAddressFk'], + include: { + relation: 'defaultAddress', + scope: { + fields: [ + 'street', + 'postalCode', + 'city', + 'mobile', + 'phone', + 'provinceFk' + ], + include: { + relation: 'province', + scope: { + fields: ['name'] + } + } + } + } + } + } + } + } + ] + } + + } + ] + }); + + const ticket = expedition.ticket(); + const sender = ticket.company().client(); + const shipped = ticket.shipped.toISOString(); + const data = { + viaexpressConfig, + sender, + senderAddress: sender.defaultAddress(), + client: ticket.client(), + address: ticket.address(), + shipped + }; + + const template = fs.readFileSync(__dirname + '/template.ejs', 'utf-8'); + const renderedXml = ejs.render(template, data); + return renderedXml; + }; +}; diff --git a/back/methods/viaexpress-config/template.ejs b/back/methods/viaexpress-config/template.ejs new file mode 100644 index 0000000000..0b6eb468c6 --- /dev/null +++ b/back/methods/viaexpress-config/template.ejs @@ -0,0 +1,52 @@ + + + + + + <%= viaexpressConfig.defaultWeight %> + 1 + 0 + <%= shipped %> + 0 + <%= viaexpressConfig.deliveryType %> + 0 + 0 + 0 + 0 + 0 + + + 0 + + + + <%= sender.socialName %> + <%= senderAddress.street %> + <%= senderAddress.postalCode %> + <%= senderAddress.city %> + <%= senderAddress.province().name %> + + <%= senderAddress.mobile || senderAddress.phone || sender.mobile || sender.phone %> + <%= sender.email %> + + + <%= address.nickname %> + <%= address.street %> + <%= address.postalCode %> + <%= address.city %> + + <%= address.province().name %> + + <%= address.mobile || address.phone || client.mobile || client.phone %> + <%= client.email %> + <%= address.province().country().code %> + + + <%= viaexpressConfig.client %> + <%= viaexpressConfig.user %> + <%= viaexpressConfig.password %> + + + + + diff --git a/back/model-config.json b/back/model-config.json index 0e37bf5278..b88956deef 100644 --- a/back/model-config.json +++ b/back/model-config.json @@ -150,6 +150,9 @@ }, "PrintConfig": { "dataSource": "vn" + }, + "ViaexpressConfig": { + "dataSource": "vn" } } diff --git a/back/models/company.json b/back/models/company.json index f8b5641aca..d7e88cd11e 100644 --- a/back/models/company.json +++ b/back/models/company.json @@ -27,5 +27,12 @@ "where" :{ "expired": null } + }, + "relations": { + "client": { + "type": "belongsTo", + "model": "Client", + "foreignKey": "clientFk" + } } } diff --git a/back/models/viaexpress-config.js b/back/models/viaexpress-config.js new file mode 100644 index 0000000000..d0335b28b6 --- /dev/null +++ b/back/models/viaexpress-config.js @@ -0,0 +1,4 @@ +module.exports = Self => { + require('../methods/viaexpress-config/internationalExpedition')(Self); + require('../methods/viaexpress-config/renderer')(Self); +}; diff --git a/back/models/viaexpress-config.json b/back/models/viaexpress-config.json new file mode 100644 index 0000000000..8df24201be --- /dev/null +++ b/back/models/viaexpress-config.json @@ -0,0 +1,34 @@ +{ + "name": "ViaexpressConfig", + "base": "VnModel", + "options": { + "mysql": { + "table": "viaexpressConfig" + } + }, + "properties": { + "id": { + "type": "number", + "required": true + }, + "url": { + "type": "string", + "required": true + }, + "client": { + "type": "string" + }, + "user": { + "type": "string" + }, + "password": { + "type": "string" + }, + "defaultWeight": { + "type": "number" + }, + "deliveryType": { + "type": "string" + } + } +} diff --git a/db/changes/232601/00-acl_viaexpressConfig.sql b/db/changes/232601/00-acl_viaexpressConfig.sql new file mode 100644 index 0000000000..d4c186dd41 --- /dev/null +++ b/db/changes/232601/00-acl_viaexpressConfig.sql @@ -0,0 +1,4 @@ +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES + ('ViaexpressConfig', 'internationalExpedition', 'WRITE', 'ALLOW', 'ROLE', 'employee'), + ('ViaexpressConfig', 'renderer', 'READ', 'ALLOW', 'ROLE', 'employee'); diff --git a/db/changes/232601/00-viaexpress.sql b/db/changes/232601/00-viaexpress.sql new file mode 100644 index 0000000000..42cf3b6479 --- /dev/null +++ b/db/changes/232601/00-viaexpress.sql @@ -0,0 +1,10 @@ +CREATE TABLE `vn`.`viaexpressConfig` ( + id int auto_increment NOT NULL, + url varchar(100) NOT NULL, + client varchar(100) NOT NULL, + user varchar(100) NOT NULL, + password varchar(100) NOT NULL, + defaultWeight decimal(10,2) NOT NULL, + deliveryType varchar(5) NOT NULL, + CONSTRAINT viaexpressConfig_PK PRIMARY KEY (id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index eaa00a3de0..338a732256 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -579,13 +579,13 @@ INSERT INTO `vn`.`supplierAccount`(`id`, `supplierFk`, `iban`, `bankEntityFk`) VALUES (241, 442, 'ES111122333344111122221111', 128); -INSERT INTO `vn`.`company`(`id`, `code`, `supplierAccountFk`, `workerManagerFk`, `companyCode`, `sage200Company`, `expired`, `companyGroupFk`, `phytosanitary`) +INSERT INTO `vn`.`company`(`id`, `code`, `supplierAccountFk`, `workerManagerFk`, `companyCode`, `sage200Company`, `expired`, `companyGroupFk`, `phytosanitary` , `clientFk`) VALUES - (69 , 'CCs', NULL, 30, NULL, 0, NULL, 1, NULL), - (442 , 'VNL', 241, 30, 2 , 1, NULL, 2, 'VNL Company - Plant passport'), - (567 , 'VNH', NULL, 30, NULL, 4, NULL, 1, 'VNH Company - Plant passport'), - (791 , 'FTH', NULL, 30, NULL, 3, '2015-11-30', 1, NULL), - (1381, 'ORN', NULL, 30, NULL, 7, NULL, 1, 'ORN Company - Plant passport'); + (69 , 'CCs', NULL, 30, NULL, 0, NULL, 1, NULL , NULL), + (442 , 'VNL', 241, 30, 2 , 1, NULL, 2, 'VNL Company - Plant passport' , 1101), + (567 , 'VNH', NULL, 30, NULL, 4, NULL, 1, 'VNH Company - Plant passport' , NULL), + (791 , 'FTH', NULL, 30, NULL, 3, '2015-11-30', 1, NULL , NULL), + (1381, 'ORN', NULL, 30, NULL, 7, NULL, 1, 'ORN Company - Plant passport' , NULL); INSERT INTO `vn`.`taxArea` (`code`, `claveOperacionFactura`, `CodigoTransaccion`) VALUES diff --git a/modules/item/back/methods/item/activeBuyers.js b/modules/item/back/methods/item/activeBuyers.js deleted file mode 100644 index e16ff877b0..0000000000 --- a/modules/item/back/methods/item/activeBuyers.js +++ /dev/null @@ -1,44 +0,0 @@ -const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; -const mergeFilters = require('vn-loopback/util/filter').mergeFilters; - -module.exports = Self => { - Self.remoteMethod('activeBuyers', { - description: 'Returns a list of buyers for the given item type', - accepts: [{ - arg: 'filter', - type: 'object', - description: `Filter defining where, order, offset, and limit - must be a JSON-encoded string` - }], - returns: { - type: ['object'], - root: true - }, - http: { - path: `/activeBuyers`, - verb: 'GET' - } - }); - - Self.activeBuyers = async(filter, options) => { - const conn = Self.dataSource.connector; - const where = {isActive: true}; - const myOptions = {}; - - if (typeof options == 'object') - Object.assign(myOptions, options); - - filter = mergeFilters(filter, {where}); - - let stmt = new ParameterizedSQL( - `SELECT DISTINCT w.id workerFk, w.firstName, w.lastName, u.name, u.nickname - FROM worker w - JOIN itemType it ON it.workerFk = w.id - JOIN account.user u ON u.id = w.id - JOIN item i ON i.typeFk = it.id`, - null, myOptions); - - stmt.merge(conn.makeSuffix(filter)); - - return conn.executeStmt(stmt); - }; -}; diff --git a/modules/item/back/methods/item/specs/activeBuyers.spec.js b/modules/item/back/methods/item/specs/activeBuyers.spec.js deleted file mode 100644 index 5bf36756fc..0000000000 --- a/modules/item/back/methods/item/specs/activeBuyers.spec.js +++ /dev/null @@ -1,24 +0,0 @@ -const models = require('vn-loopback/server/server').models; - -describe('Worker activeBuyers', () => { - it('should return the buyers in itemType as result', async() => { - const tx = await models.Item.beginTransaction({}); - - try { - const options = {transaction: tx}; - const filter = {}; - const result = await models.Item.activeBuyers(filter, options); - const firstWorker = result[0]; - const secondWorker = result[1]; - - expect(result.length).toEqual(2); - expect(firstWorker.nickname).toEqual('logisticBossNick'); - expect(secondWorker.nickname).toEqual('buyerNick'); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } - }); -}); diff --git a/modules/item/back/models/item.js b/modules/item/back/models/item.js index b8baa97ea7..61c5c2588c 100644 --- a/modules/item/back/models/item.js +++ b/modules/item/back/models/item.js @@ -14,7 +14,6 @@ module.exports = Self => { require('../methods/item/getWasteByWorker')(Self); require('../methods/item/getWasteByItem')(Self); require('../methods/item/createIntrastat')(Self); - require('../methods/item/activeBuyers')(Self); require('../methods/item/buyerWasteEmail')(Self); require('../methods/item/labelPdf')(Self); diff --git a/modules/item/front/request-search-panel/index.html b/modules/item/front/request-search-panel/index.html index a766847760..9d35fbca4a 100644 --- a/modules/item/front/request-search-panel/index.html +++ b/modules/item/front/request-search-panel/index.html @@ -1,7 +1,7 @@
@@ -26,7 +26,7 @@ search-function="{firstName: $search}" value-field="id" where="{role: {inq: ['logistic', 'buyer']}}" - label="Atender"> + label="Buyer"> {{nickname}} @@ -57,7 +57,7 @@ {{firstName}} {{lastName}} - +
- - - - { - Self.remoteMethodCtx('getItemTypeWorker', { + Self.remoteMethod('getItemTypeWorker', { description: 'Returns the workers that appear in itemType', accessType: 'READ', accepts: [{ @@ -20,38 +22,37 @@ module.exports = Self => { } }); - Self.getItemTypeWorker = async(ctx, filter, options) => { - const myOptions = {}; + Self.getItemTypeWorker = async filter => { const conn = Self.dataSource.connector; - let tx; - - if (typeof options == 'object') - Object.assign(myOptions, options); const query = `SELECT DISTINCT u.id, u.nickname FROM itemType it JOIN worker w ON w.id = it.workerFk JOIN account.user u ON u.id = w.id`; + const stmt = new ParameterizedSQL(query); - let stmt = new ParameterizedSQL(query); - - if (filter.where) { - const value = filter.where.firstName; - const myFilter = { - where: {or: [ + filter.where = buildFilter(filter.where, (param, value) => { + switch (param) { + case 'firstName': + return {or: [ {'w.firstName': {like: `%${value}%`}}, {'w.lastName': {like: `%${value}%`}}, {'u.name': {like: `%${value}%`}}, {'u.nickname': {like: `%${value}%`}} - ]} - }; + ]}; + case 'id': + return {'w.id': value}; + } + }); - stmt.merge(conn.makeSuffix(myFilter)); - } + let myFilter = { + where: {'u.active': true} + }; - if (tx) await tx.commit(); + myFilter = mergeFilters(myFilter, filter); + stmt.merge(conn.makeSuffix(myFilter)); return conn.executeStmt(stmt); }; }; diff --git a/modules/ticket/back/methods/ticket-request/specs/getItemTypeWorkers.spec.js b/modules/ticket/back/methods/ticket-request/specs/getItemTypeWorkers.spec.js index ae5c508b6d..c57451c261 100644 --- a/modules/ticket/back/methods/ticket-request/specs/getItemTypeWorkers.spec.js +++ b/modules/ticket/back/methods/ticket-request/specs/getItemTypeWorkers.spec.js @@ -1,12 +1,10 @@ const models = require('vn-loopback/server/server').models; describe('ticket-request getItemTypeWorker()', () => { - const ctx = {req: {accessToken: {userId: 18}}}; - it('should return the buyer as result', async() => { const filter = {where: {firstName: 'buyer'}}; - const result = await models.TicketRequest.getItemTypeWorker(ctx, filter); + const result = await models.TicketRequest.getItemTypeWorker(filter); expect(result.length).toEqual(1); }); @@ -14,7 +12,7 @@ describe('ticket-request getItemTypeWorker()', () => { it('should return the workers at itemType as result', async() => { const filter = {}; - const result = await models.TicketRequest.getItemTypeWorker(ctx, filter); + const result = await models.TicketRequest.getItemTypeWorker(filter); expect(result.length).toBeGreaterThan(1); });