From 6c9215bb517ea1700a3a0552b46fd38d94d07c48 Mon Sep 17 00:00:00 2001 From: pablone Date: Wed, 7 Feb 2024 16:52:43 +0100 Subject: [PATCH] feat(mrw): refs #6403 big commit --- back/methods/mrw-config/createShipment.js | 49 +++++++++---------- back/methods/mrw-config/expeditionData.sql | 27 ++++++++++ .../mrw-config/specs/createShipment.spec.js | 45 +++++++++++++++++ db/changes/240401/00-mrwWebService.sql | 26 ++++------ loopback/locale/es.json | 12 ++++- 5 files changed, 115 insertions(+), 44 deletions(-) create mode 100644 back/methods/mrw-config/expeditionData.sql create mode 100644 back/methods/mrw-config/specs/createShipment.spec.js diff --git a/back/methods/mrw-config/createShipment.js b/back/methods/mrw-config/createShipment.js index f6f57e06f..505b7b167 100644 --- a/back/methods/mrw-config/createShipment.js +++ b/back/methods/mrw-config/createShipment.js @@ -2,6 +2,7 @@ const axios = require('axios'); const {DOMParser} = require('xmldom'); const fs = require('fs'); const ejs = require('ejs'); +const UserError = require('vn-loopback/util/user-error'); module.exports = Self => { Self.remoteMethod('createShipment', { @@ -26,35 +27,20 @@ module.exports = Self => { const models = Self.app.models; const mrw = await models.MrwConfig.findOne(); + if (!mrw) + throw new UserError(`Some mrwConfig parameters are not set`); + const [expeditionData] = await Self.rawSql( - `SELECT CASE co.code - WHEN 'ES' THEN a.postalCode - WHEN 'PT' THEN LEFT(a.postalCode, 4) - WHEN 'AD' THEN REPLACE(a.postalCode, 'AD', '00') - END postalCode, - a.city, - a.street, - co.code countryCode, - c.fi, - c.name clientName, - c.phone, - DATE_FORMAT(e.created, '%d/%m/%Y') created, - e.id expeditionId, - LPAD(IF(mw.params IS NULL, ms.serviceType, mw.serviceType), 4 ,'0') serviceType, - IFNULL(mw.weekdays, "N") weekDays - FROM expedition e - JOIN packaging pa ON pa.id = e.packagingFk - JOIN ticket t ON e.ticketFk = t.id - JOIN agencyMode am ON am.id = t.agencyModeFk - JOIN mrwService ms ON ms.agencyModeCodeFk = am.code - LEFT JOIN mrwServiceWeekday mw ON mw.params = DATE_FORMAT(e.created, '%a') - JOIN client c ON t.clientFk = c.id - JOIN address a ON t.addressFk = a.id - JOIN province p ON a.provinceFk = p.id - JOIN country co ON co.id = p.countryFk - WHERE e.id = ?`, [expeditionFk] + fs.readFileSync(__dirname + '/expeditionData.sql', 'utf-8'), + [expeditionFk] ); + if (!expeditionData) + throw new UserError(`This expedition is not a MRW shipment`); + + if (expeditionData?.created < Date.vnNew()) + throw new UserError(`This ticket has a shipped date earlier than today`); + const shipmentTemplate = fs.readFileSync(__dirname + '/createShipment.ejs', 'utf-8'); const renderedShipment = ejs.render(shipmentTemplate, {mrw, expeditionData}); const shipmentResponse = await axios.post(mrw.url, renderedShipment, { @@ -66,6 +52,11 @@ module.exports = Self => { const shipmentXmlDoc = parser.parseFromString(shipmentResponse.data, 'text/xml'); const shipmentId = shipmentXmlDoc.getElementsByTagName('NumeroEnvio')[0].textContent; + if (!shipmentId) { + const message = shipmentXmlDoc.getElementsByTagName('Mensaje')[0]?.textContent; + throw new UserError(message); + } + const getLabelTemplate = fs.readFileSync(__dirname + '/getLabel.ejs', 'utf-8'); const renderedGetLabel = ejs.render(getLabelTemplate, {mrw, shipmentId}); const getLabelResponse = await axios.post(mrw.url, renderedGetLabel, { @@ -76,6 +67,12 @@ module.exports = Self => { const getLabelXmlDoc = parser.parseFromString(getLabelResponse.data, 'text/xml'); const base64Binary = getLabelXmlDoc.getElementsByTagName('EtiquetaFile')[0]?.textContent; + if (!base64Binary) { + const message = getLabelXmlDoc.getElementsByTagName('Mensaje')[0]?.textContent; + if (!message) + throw new UserError(`The MRW web service is not returning the expected response`); + throw new UserError(message); + } const expedition = await models.Expedition.findById(expeditionFk); await expedition.updateAttribute('externalId', shipmentId); diff --git a/back/methods/mrw-config/expeditionData.sql b/back/methods/mrw-config/expeditionData.sql new file mode 100644 index 000000000..2a325cc27 --- /dev/null +++ b/back/methods/mrw-config/expeditionData.sql @@ -0,0 +1,27 @@ +SELECT CASE co.code + WHEN 'ES' THEN a.postalCode + WHEN 'PT' THEN LEFT(a.postalCode, 4) + WHEN 'AD' THEN REPLACE(a.postalCode, 'AD', '00') + END postalCode, + a.city, + a.street, + co.code countryCode, + c.fi, + c.name clientName, + c.phone, + DATE_FORMAT(t.shipped, '%d/%m/%Y') created, + e.id expeditionId, + LPAD(IF(mw.params IS NULL, ms.serviceType, mw.serviceType), 4 ,'0') serviceType, + IF(mw.weekdays, 'S', 'N') weekDays + FROM expedition e + JOIN packaging pa ON pa.id = e.packagingFk + JOIN ticket t ON e.ticketFk = t.id + JOIN agencyMode am ON am.id = t.agencyModeFk + JOIN mrwService ms ON ms.agencyModeCodeFk = am.code + LEFT JOIN mrwServiceWeekday mw ON mw.weekdays = DATE_FORMAT(t.shipped, '%a') + JOIN client c ON t.clientFk = c.id + JOIN address a ON t.addressFk = a.id + JOIN province p ON a.provinceFk = p.id + JOIN country co ON co.id = p.countryFk + WHERE e.id = ? + LIMIT 1 \ No newline at end of file diff --git a/back/methods/mrw-config/specs/createShipment.spec.js b/back/methods/mrw-config/specs/createShipment.spec.js new file mode 100644 index 000000000..2b5d555a1 --- /dev/null +++ b/back/methods/mrw-config/specs/createShipment.spec.js @@ -0,0 +1,45 @@ +const models = require('vn-loopback/server/server').models; +const axios = require('axios'); + +const expeditionFk = 14; +const mockShipmentId = 'baseMockShipmentId'; +const mockBase64Binary = 'base64BinaryString'; +const ticket1 = { + 'id': '44', + 'clientFk': 1101, + 'shipped': Date.vnNew(), + 'nickname': 'MRW', + 'addressFk': 1, + 'agencyModeFk': 26 +}; + +const expedition1 = { + 'id': 14, + 'agencyModeFk': 26, + 'ticketFk': 44, + 'freightItemFk': 71, + 'created': '2001-01-01', + 'counter': 1, + 'workerFk': 18, + 'packagingFk': '94', + 'hostFk': '', + 'stateTypeFk': 3, + 'hasNewRoute': 0, + 'isBox': 71, + 'editorFk': 100 +}; +fdescribe('MRWConfig createShipment()', () => { + it('should create a shipment and return a base64Binary label', async() => { + const tx = await models.MrwConfig.beginTransaction({}); + const options = {transaction: tx}; + + await models.Ticket.create(ticket1, options); + const expedition = await models.Expedition.create(expedition1, options); + + spyOn(axios, 'post').and.returnValues([{data: mockShipmentId}, {data: mockBase64Binary}]); + + const base64Binary = await models.MrwConfig.createShipment(expedition.id, options); + + expect(base64Binary).toEqual(mockBase64Binary); + }); +}); diff --git a/db/changes/240401/00-mrwWebService.sql b/db/changes/240401/00-mrwWebService.sql index eb6aab887..a3c42ad8b 100644 --- a/db/changes/240401/00-mrwWebService.sql +++ b/db/changes/240401/00-mrwWebService.sql @@ -7,13 +7,19 @@ CREATE TABLE IF NOT EXISTS `vn`.`mrwConfig` ( `subscriberCode` varchar(100) NULL, CONSTRAINT mrwConfig_pk PRIMARY KEY (id) ) -ENGINE=InnoDB +ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; ALTER TABLE `vn`.`packingSite` ADD `hasNewLabelMrwMethod` BOOL NULL; -INSERT INTO vn.mrwService (agencyModeCodeFk, clientType, serviceType, kg) VALUES('mrw', 9731, 205, 10); + +INSERT INTO `vn`.`agency` (`name`,`warehouseFk`,`warehouseAliasFk`,`isOwn`,`isAnyVolumeAllowed`) + VALUES ('MRW',1,1,0,0); + +INSERT INTO `vn`.`agencyMode` (`id`, `name`, `description`, `deliveryMethodFk`, `m3`, `web`, `agencyFk`, `inflation`, `isVolumetric`, `reportMail`, `showAgencyName`, `isActive`, `isExternalAgency`, `flag`, `code`, `isRiskFree`, `hasWeightVolumetric`) + VALUES(26, 'MRW', NULL, NULL, 0.0, 0, 11, 0.00, 0, NULL, 1, 1, 0, NULL, 'MRW', 0, 0), + (27, 'mrwEcom', NULL, NULL, 0.0, 0, 11, 0.00, 0, NULL, 1, 1, 0, NULL, 'mrwEcom', 0, 0); INSERT INTO `vn`.`mrwConfig` (`url`, `user`, `password`, `franchiseCode`, `subscriberCode`) VALUES ('https://sagec-test.mrw.es/MRWEnvio.asmx', '04301SGVERDNATURA', 'Verdnatura@4301V', '04301', '009731'); @@ -24,19 +30,7 @@ INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `pri INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalType`,`principalId`) VALUES ('MrwConfig','createShipment','WRITE','ALLOW','ROLE','employee'); +INSERT INTO `vn`.`mrwService` (`agencyModeCodeFk`, `clientType`, `serviceType`, `kg`) VALUES('MRW', 9731, 205, 10); +INSERT INTO `vn`.`mrwServiceWeekday` (`agencyModeCodeFk`, `weekdays`, `serviceType`, `params`) VALUES('mrwEcom', 'sat', 800, 'EntregaSabado=S'); -INSERT INTO `vn`.`agency` (`name`,`warehouseFk`,`warehouseAliasFk`,`isOwn`,`isAnyVolumeAllowed`) - VALUES ('MRW',1,1,0,0); -INSERT INTO `vn`.`agencyMode` (`id`, `name`, `description`, `deliveryMethodFk`, `m3`, `web`, `agencyFk`, `inflation`, `isVolumetric`, `reportMail`, `showAgencyName`, `isActive`, `isExternalAgency`, `flag`, `code`, `isRiskFree`, `hasWeightVolumetric`) - VALUES(25, 'MRW', NULL, NULL, 0.0, 0, 11, 0.00, 0, NULL, 1, 1, 0, NULL, 'MRW', 0, 0), - (26, 'mrwEcom', NULL, NULL, 0.0, 0, 11, 0.00, 0, NULL, 1, 1, 0, NULL, 'mrwEcom', 0, 0); - -INSERT INTO `vn`.`ticket` (`id`, `clientFk`, `warehouseFk`, `shipped`, `nickname`, `refFk`, `addressFk`, `workerFk`, `observations`, `isSigned`, `isLabeled`, `isPrinted`, `packages`, `location`, `hour`, `created`, `isBlocked`, `solution`, `routeFk`, `priority`, `hasPriority`, `companyFk`, `agencyModeFk`, `landed`, `isBoxed`, `isDeleted`, `zoneFk`, `zonePrice`, `zoneBonus`, `totalWithVat`, `totalWithoutVat`, `weight`, `clonedFrom`, `cmrFk`, `editorFk`) - VALUES(44, 1101, 1, '2001-01-01 00:00:00.000', 'MRW', NULL, 1, NULL, NULL, 0, 0, 0, 1, NULL, 0, '2001-01-01 00:00:00.000', 1, NULL, 6, NULL, 1, 442, 25, '2001-01-02', 0, 0, 3, 5.00, 1.00, 8.88, 8.07, NULL, NULL, NULL, 100); - -INSERT INTO vn.expedition (agencyModeFk,ticketFk,freightItemFk,created,counter,workerFk,packagingFk,hostFk,stateTypeFk,hasNewRoute,isBox,editorFk) - VALUES (25,44,71, CURDATE(),1,18,'94','',3,0,71,100); - -INSERT INTO vn.mrwService (agencyModeCodeFk, clientType, serviceType, kg) VALUES('MRW', 9731, 205, 10); -INSERT INTO vn.mrwServiceWeekday (agencyModeCodeFk, weekdays, serviceType, params) VALUES('mrwEcom', 'sat', 800, 'EntregaSabado=S'); \ No newline at end of file diff --git a/loopback/locale/es.json b/loopback/locale/es.json index a8134909e..e0025c5c0 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -329,5 +329,13 @@ "The amount cannot be less than the minimum": "La cantidad no puede ser menor que la cantidad mínima", "quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mínima", "Cannot past travels with entries": "No se pueden pasar envíos con entradas", - "It was not able to remove the next expeditions:": "No se pudo eliminar las siguientes expediciones: {{expeditions}}" -} + "It was not able to remove the next expeditions:": "No se pudo eliminar las siguientes expediciones: {{expeditions}}", + "Esa expedición no es mrw": "Esa expedición no es mrw", + "This expedition is not configured as MRW": "This expedition is not configured as MRW", + "Some config parameters are not set": "Some config parameters are not set", + "The MRW web service is not returning the expected response": "The MRW web service is not returning the expected response", + "1) No se han encontrado datos con estos criterios.": "1) No se han encontrado datos con estos criterios.", + "1) Fecha de recogida incorrecta (fecha cerrada).": "1) Fecha de recogida incorrecta (fecha cerrada).", + "1) Falta indicar la Hora Máxima de Recogida en Sábado2) Fecha de recogida incorrecta (fecha cerrada).": "1) Falta indicar la Hora Máxima de Recogida en Sábado2) Fecha de recogida incorrecta (fecha cerrada).", + "1) Falta indicar la Hora Máxima de Recogida en Sábado2) La fecha de recogida solicitada es 10/02/2024.3) El tipo de servicio no está permitido.4) ": "1) Falta indicar la Hora Máxima de Recogida en Sábado2) La fecha de recogida solicitada es 10/02/2024.3) El tipo de servicio no está permitido.4) " +} \ No newline at end of file