feat(spec): refs #6403 mrwIntegration
gitea/salix/pipeline/pr-master There was a failure building this commit
Details
gitea/salix/pipeline/pr-master There was a failure building this commit
Details
This commit is contained in:
parent
85b1391006
commit
c10cb7c051
|
@ -5,7 +5,7 @@ const ejs = require('ejs');
|
||||||
const UserError = require('vn-loopback/util/user-error');
|
const UserError = require('vn-loopback/util/user-error');
|
||||||
|
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
Self.remoteMethodCtx('createShipment', {
|
Self.remoteMethod('createShipment', {
|
||||||
description: 'Create an expedition and return a base64Binary label',
|
description: 'Create an expedition and return a base64Binary label',
|
||||||
accessType: 'WRITE',
|
accessType: 'WRITE',
|
||||||
accepts: [{
|
accepts: [{
|
||||||
|
@ -23,71 +23,89 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.createShipment = async(ctx, expeditionFk, options) => {
|
Self.createShipment = async(expeditionFk, options) => {
|
||||||
const myOptions = {};
|
const myOptions = {};
|
||||||
|
|
||||||
if (typeof options == 'object')
|
if (typeof options == 'object')
|
||||||
Object.assign(myOptions, options);
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
if (!myOptions.transaction)
|
||||||
|
myOptions.transaction = await Self.beginTransaction({});
|
||||||
|
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
const mrw = await models.MrwConfig.findOne(null, myOptions);
|
const mrw = await models.MrwConfig.findOne(null, myOptions);
|
||||||
console.log('mrw: ', mrw);
|
|
||||||
|
|
||||||
if (!mrw)
|
if (!mrw)
|
||||||
throw new UserError(`Some mrwConfig parameters are not set`);
|
throw new UserError(`Some mrwConfig parameters are not set`);
|
||||||
|
|
||||||
const [expeditionData] = await Self.rawSql(
|
const query =
|
||||||
fs.readFileSync(__dirname + '/expeditionData.sql', 'utf-8'),
|
`SELECT CASE co.code
|
||||||
null,
|
WHEN 'ES' THEN a.postalCode
|
||||||
myOptions
|
WHEN 'PT' THEN LEFT(a.postalCode, 4)
|
||||||
);
|
WHEN 'AD' THEN REPLACE(a.postalCode, 'AD', '00')
|
||||||
console.log('sigue');
|
END postalCode,
|
||||||
|
a.city,
|
||||||
|
a.street,
|
||||||
|
co.code countryCode,
|
||||||
|
c.fi,
|
||||||
|
c.name clientName,
|
||||||
|
c.phone,
|
||||||
|
DATE_FORMAT(t.shipped, '%d/%m/%Y') created,
|
||||||
|
t.shipped,
|
||||||
|
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 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`;
|
||||||
|
|
||||||
|
const [expeditionData] = await Self.rawSql(query, [expeditionFk], myOptions);
|
||||||
|
|
||||||
if (!expeditionData)
|
if (!expeditionData)
|
||||||
throw new UserError(`This expedition is not a MRW shipment`);
|
throw new UserError(`This expedition is not a MRW shipment`);
|
||||||
|
|
||||||
if (expeditionData?.created < Date.vnNew())
|
const today = Date.vnNew();
|
||||||
throw new UserError(`This ticket has a shipped date earlier than today`); po;
|
today.setHours(0, 0, 0, 0);
|
||||||
|
if (expeditionData?.shipped.setHours(0, 0, 0, 0) < today)
|
||||||
|
throw new UserError(`This ticket has a shipped date earlier than today`);
|
||||||
|
|
||||||
const shipmentResponse = await sendXmlDoc('createShipment', {mrw, expeditionData});
|
const shipmentResponse = await sendXmlDoc('createShipment', {mrw, expeditionData}, 'application/soap+xml');
|
||||||
|
const shipmentId = getTextByTag(shipmentResponse, 'NumeroEnvio');
|
||||||
const parser = new DOMParser();
|
|
||||||
const shipmentXmlDoc = parser.parseFromString(shipmentResponse, 'text/xml');
|
|
||||||
const shipmentId = getTextByTag(shipmentXmlDoc, 'NumeroEnvio');
|
|
||||||
|
|
||||||
if (!shipmentId)
|
if (!shipmentId)
|
||||||
throw new UserError(getTextByTag(shipmentXmlDoc, 'Mensaje'));
|
throw new UserError(getTextByTag(shipmentResponse, 'Mensaje'));
|
||||||
|
|
||||||
const getLabelResponse = await sendXmlDoc('getLabel', {mrw, shipmentId});
|
const getLabelResponse = await sendXmlDoc('getLabel', {mrw, shipmentId}, 'text/xml');
|
||||||
|
const file = getTextByTag(getLabelResponse, 'EtiquetaFile');
|
||||||
|
|
||||||
const getLabelXmlDoc = parser.parseFromString(getLabelResponse, 'text/xml');
|
await models.Expedition.updateAll({id: expeditionFk}, {externalId: shipmentId}, myOptions);
|
||||||
const file = getTextByTag(getLabelXmlDoc, 'EtiquetaFile');
|
await myOptions.transaction.commit();
|
||||||
console.log('file: ', file);
|
|
||||||
if (!file) {
|
|
||||||
const message = getTextByTag(getLabelXmlDoc, 'Mensaje') ??
|
|
||||||
`The MRW web service is not returning the expected response`;
|
|
||||||
throw new UserError(message);
|
|
||||||
}
|
|
||||||
await models.Expedition.updateAll({id: expeditionFk}, {externalId: shipmentId}, options);
|
|
||||||
|
|
||||||
return file;
|
return file;
|
||||||
};
|
};
|
||||||
|
|
||||||
function getTextByTag(xmlDoc, tag) {
|
function getTextByTag(xmlDoc, tag) {
|
||||||
const parser = new DOMParser();
|
return xmlDoc?.getElementsByTagName(tag)[0]?.textContent;
|
||||||
const doc = parser.parseFromString(xmlDoc?.data, 'text/xml');
|
|
||||||
return doc?.getElementsByTagName(tag)[0]?.textContent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function sendXmlDoc(xmlDock, params) {
|
async function sendXmlDoc(xmlDock, params, contentType) {
|
||||||
|
const parser = new DOMParser();
|
||||||
|
|
||||||
const xmlTemplate = fs.readFileSync(__dirname + `/${xmlDock}.ejs`, 'utf-8');
|
const xmlTemplate = fs.readFileSync(__dirname + `/${xmlDock}.ejs`, 'utf-8');
|
||||||
const renderedTemplate = ejs.render(xmlTemplate, params);
|
const renderedTemplate = ejs.render(xmlTemplate, params);
|
||||||
const {data} = await axios.post(params.mrw.url, renderedTemplate, {
|
const data = await axios.post(params.mrw.url, renderedTemplate, {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/soap+xml; charset=utf-8'
|
'Content-Type': `${contentType}; charset=utf-8`
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return parser.parseFromString(data.data, 'text/xml');
|
||||||
console.log('data: ', data);
|
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
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 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 = 14
|
|
||||||
LIMIT 1
|
|
|
@ -13,7 +13,7 @@ const ticket1 = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const expedition1 = {
|
const expedition1 = {
|
||||||
'id': 14,
|
'id': 17,
|
||||||
'agencyModeFk': 999,
|
'agencyModeFk': 999,
|
||||||
'ticketFk': 44,
|
'ticketFk': 44,
|
||||||
'freightItemFk': 71,
|
'freightItemFk': 71,
|
||||||
|
@ -27,6 +27,11 @@ const expedition1 = {
|
||||||
'isBox': 71,
|
'isBox': 71,
|
||||||
'editorFk': 100
|
'editorFk': 100
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const returnsValues = [
|
||||||
|
{data: fs.readFileSync(__dirname + '/mockGetLabel.xml', 'utf-8')},
|
||||||
|
{data: fs.readFileSync(__dirname + '/mockCreateShipment.xml', 'utf-8')}
|
||||||
|
];
|
||||||
let options;
|
let options;
|
||||||
|
|
||||||
fdescribe('MRWConfig createShipment()', () => {
|
fdescribe('MRWConfig createShipment()', () => {
|
||||||
|
@ -64,28 +69,46 @@ fdescribe('MRWConfig createShipment()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create a shipment and return a base64Binary label', async() => {
|
it('should create a shipment and return a base64Binary label', async() => {
|
||||||
try {
|
spyOn(axios, 'post').and.callFake(() =>
|
||||||
const returnsValues = [
|
Promise.resolve(returnsValues.pop())
|
||||||
{data: fs.readFileSync(__dirname + '/mockGetLabel.xml', 'utf-8')},
|
);
|
||||||
{data: fs.readFileSync(__dirname + '/mockCreateShipment.xml', 'utf-8')}
|
|
||||||
];
|
|
||||||
spyOn(axios, 'post').and.callFake(() =>
|
|
||||||
Promise.resolve(returnsValues.pop())
|
|
||||||
);
|
|
||||||
const ctx = {args: {isChargedToMana: false}};
|
|
||||||
const base64Binary = await models.MrwConfig.createShipment(ctx, expedition1.id, options);
|
|
||||||
|
|
||||||
expect(base64Binary).toEqual(mockBase64Binary);
|
await models.Ticket.updateAll({id: ticket1.id}, {shipped: Date.vnNew()}, options);
|
||||||
|
const base64Binary = await models.MrwConfig.createShipment(expedition1.id, options);
|
||||||
|
|
||||||
await options.transaction.rollback();
|
expect(base64Binary).toEqual(mockBase64Binary);
|
||||||
} catch (e) {
|
});
|
||||||
await options.transaction.rollback();
|
|
||||||
throw e;
|
it('should fail if mrwConfig has no data', async() => {
|
||||||
}
|
let error;
|
||||||
|
await models.MrwConfig.createShipment(expedition1.id).catch(e => {
|
||||||
|
error = e;
|
||||||
|
}).finally(async() => {
|
||||||
|
expect(error.message).toEqual(`Some mrwConfig parameters are not set`);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(error).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fail if expeditionFk is not a MrwExpedition', async() => {
|
||||||
|
let error;
|
||||||
|
await models.MrwConfig.createShipment(undefined, options).catch(e => {
|
||||||
|
error = e;
|
||||||
|
}).finally(async() => {
|
||||||
|
expect(error.message).toEqual(`This expedition is not a MRW shipment`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it(' should fail if the creation date of this ticket is before the current date it', async() => {
|
||||||
|
let error;
|
||||||
|
const yesterday = Date.vnNew();
|
||||||
|
|
||||||
|
yesterday.setDate(yesterday.getDate() - 1);
|
||||||
|
await models.Ticket.updateAll({id: ticket1.id}, {shipped: yesterday}, options);
|
||||||
|
await models.MrwConfig.createShipment(expedition1.id, options).catch(e => {
|
||||||
|
error = e;
|
||||||
|
}).finally(async() => {
|
||||||
|
expect(error.message).toEqual(`This ticket has a shipped date earlier than today`);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
async function dbPopulate() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -14,24 +14,11 @@ COLLATE=utf8mb3_unicode_ci;
|
||||||
|
|
||||||
ALTER TABLE `vn`.`packingSite` ADD `hasNewLabelMrwMethod` BOOL NULL;
|
ALTER TABLE `vn`.`packingSite` ADD `hasNewLabelMrwMethod` BOOL NULL;
|
||||||
|
|
||||||
|
|
||||||
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');
|
|
||||||
|
|
||||||
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
|
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
|
||||||
VALUES('MrwConfig', 'cancelShipment', 'WRITE', 'ALLOW', 'ROLE', 'employee');
|
VALUES('MrwConfig', 'cancelShipment', 'WRITE', 'ALLOW', 'ROLE', 'employee');
|
||||||
|
|
||||||
INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalType`,`principalId`)
|
INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalType`,`principalId`)
|
||||||
VALUES ('MrwConfig','createShipment','WRITE','ALLOW','ROLE','employee');
|
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');
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue