#6403 - mrwIntegration #2005
|
@ -0,0 +1,20 @@
|
||||||
|
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:mrw="http://www.mrw.es/">
|
||||||
|
<soap:Header>
|
||||||
|
<mrw:AuthInfo>
|
||||||
|
<mrw:CodigoFranquicia><%= mrw.franchiseCode %></mrw:CodigoFranquicia>
|
||||||
|
<mrw:CodigoAbonado><%= mrw.subscriberCode %></mrw:CodigoAbonado>
|
||||||
|
<mrw:CodigoDepartamento/>
|
||||||
|
<mrw:UserName><%= mrw.user %></mrw:UserName>
|
||||||
|
<mrw:Password><%= mrw.password %></mrw:Password>
|
||||||
|
</mrw:AuthInfo>
|
||||||
|
</soap:Header>
|
||||||
|
<soap:Body>
|
||||||
|
<mrw:CancelarEnvio>
|
||||||
|
<mrw:request>
|
||||||
|
<mrw:CancelaEnvio>
|
||||||
|
<mrw:NumeroEnvioOriginal><%= externalId %></mrw:NumeroEnvioOriginal>
|
||||||
|
</mrw:CancelaEnvio>
|
||||||
|
</mrw:request>
|
||||||
|
</mrw:CancelarEnvio>
|
||||||
|
</soap:Body>
|
||||||
|
</soap:Envelope>
|
|
@ -0,0 +1,46 @@
|
||||||
|
const axios = require('axios');
|
||||||
|
const fs = require('fs');
|
||||||
|
const ejs = require('ejs');
|
||||||
|
const {DOMParser} = require('xmldom');
|
||||||
|
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethod('cancelShipment', {
|
||||||
|
description: 'Cancel a shipment by providing the expedition ID, interacting with MRW WebService',
|
||||||
|
accessType: 'WRITE',
|
||||||
|
accepts: [{
|
||||||
|
arg: 'expeditionFk',
|
||||||
|
type: 'number',
|
||||||
|
required: true
|
||||||
|
}],
|
||||||
|
returns: {
|
||||||
|
type: ['object'],
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/cancelShipment`,
|
||||||
|
verb: 'POST'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.cancelShipment = async expeditionFk => {
|
||||||
|
const models = Self.app.models;
|
||||||
|
|
||||||
|
const mrw = await models.MrwConfig.findOne();
|
||||||
|
const {externalId} = await models.Expedition.findById(expeditionFk);
|
||||||
|
|
||||||
|
const template = fs.readFileSync(__dirname + '/cancelShipment.ejs', 'utf-8');
|
||||||
|
const renderedXml = ejs.render(template, {mrw, externalId});
|
||||||
|
const response = await axios.post(mrw.url, 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 [resultElement] = xmlDoc.getElementsByTagName('Mensaje');
|
||||||
|
|
||||||
|
return resultElement.textContent;
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,43 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:mrw="http://www.mrw.es/">
|
||||||
|
<soap:Header>
|
||||||
|
<mrw:AuthInfo>
|
||||||
|
<mrw:CodigoFranquicia><%= mrw.franchiseCode %></mrw:CodigoFranquicia>
|
||||||
|
<mrw:CodigoAbonado><%= mrw.subscriberCode %></mrw:CodigoAbonado>
|
||||||
|
<mrw:CodigoDepartamento/>
|
||||||
|
<mrw:UserName><%= mrw.user %></mrw:UserName>
|
||||||
|
<mrw:Password><%= mrw.password %></mrw:Password>
|
||||||
|
</mrw:AuthInfo>
|
||||||
|
</soap:Header>
|
||||||
|
<soap:Body>
|
||||||
|
<mrw:TransmEnvio>
|
||||||
|
<mrw:request>
|
||||||
|
<mrw:DatosEntrega>
|
||||||
|
<mrw:Direccion>
|
||||||
|
<mrw:CodigoTipoVia/>
|
||||||
|
<mrw:Via><%= expeditionData.street %></mrw:Via>
|
||||||
|
<mrw:Numero/>
|
||||||
|
<mrw:Resto/>
|
||||||
|
<mrw:CodigoPostal><%= expeditionData.postalCode %></mrw:CodigoPostal>
|
||||||
|
<mrw:Poblacion><%= expeditionData.city %></mrw:Poblacion>
|
||||||
|
<mrw:Provincia/>
|
||||||
|
<mrw:CodigoPais/>
|
||||||
|
</mrw:Direccion>
|
||||||
|
<mrw:Nif><%= expeditionData.fi %></mrw:Nif>
|
||||||
|
<mrw:Nombre><%= expeditionData.clientName %></mrw:Nombre>
|
||||||
|
<mrw:Telefono><%= expeditionData.phone %></mrw:Telefono>
|
||||||
|
</mrw:DatosEntrega>
|
||||||
|
<mrw:DatosServicio>
|
||||||
|
<mrw:Fecha><%= expeditionData.created %></mrw:Fecha>
|
||||||
|
<mrw:Referencia><%= expeditionData.expeditionDataId %></mrw:Referencia>
|
||||||
|
<mrw:CodigoServicio><%= expeditionData.serviceType %></mrw:CodigoServicio>
|
||||||
|
<mrw:NumeroBultos>1</mrw:NumeroBultos>
|
||||||
|
<mrw:EntregaSabado><%= expeditionData.weekDays %></mrw:EntregaSabado>
|
||||||
|
<mrw:Peso><%= expeditionData.kg %></mrw:Peso>
|
||||||
|
<mrw:Reembolso/>
|
||||||
|
<mrw:ImporteReembolso/>
|
||||||
|
</mrw:DatosServicio>
|
||||||
|
</mrw:request>
|
||||||
|
</mrw:TransmEnvio>
|
||||||
|
</soap:Body>
|
||||||
|
</soap:Envelope>
|
|
@ -0,0 +1,109 @@
|
||||||
|
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', {
|
||||||
|
description: 'Create an expedition and return a base64Binary label from de MRW WebService',
|
||||||
|
accessType: 'WRITE',
|
||||||
|
accepts: [{
|
||||||
|
arg: 'expeditionFk',
|
||||||
|
type: 'number',
|
||||||
|
required: true
|
||||||
|
}],
|
||||||
|
returns: {
|
||||||
|
type: ['object'],
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/createShipment`,
|
||||||
|
verb: 'POST'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.createShipment = async(expeditionFk, options) => {
|
||||||
|
const myOptions = {};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
if (!myOptions.transaction)
|
||||||
|
myOptions.transaction = await Self.beginTransaction({});
|
||||||
|
|
||||||
|
const models = Self.app.models;
|
||||||
|
const mrw = await models.MrwConfig.findOne(null, myOptions);
|
||||||
|
|
||||||
|
if (!mrw)
|
||||||
|
throw new UserError(`Some mrwConfig parameters are not set`);
|
||||||
|
|
||||||
|
const query =
|
||||||
|
`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,
|
||||||
|
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)
|
||||||
|
throw new UserError(`This expedition is not a MRW shipment`);
|
||||||
|
|
||||||
|
const today = Date.vnNew();
|
||||||
|
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}, 'application/soap+xml');
|
||||||
|
const shipmentId = getTextByTag(shipmentResponse, 'NumeroEnvio');
|
||||||
|
|
||||||
|
if (!shipmentId)
|
||||||
|
throw new UserError(getTextByTag(shipmentResponse, 'Mensaje'));
|
||||||
|
|
||||||
|
const getLabelResponse = await sendXmlDoc('getLabel', {mrw, shipmentId}, 'text/xml');
|
||||||
|
const file = getTextByTag(getLabelResponse, 'EtiquetaFile');
|
||||||
|
|
||||||
|
await models.Expedition.updateAll({id: expeditionFk}, {externalId: shipmentId}, myOptions);
|
||||||
|
return file;
|
||||||
|
};
|
||||||
|
|
||||||
|
function getTextByTag(xmlDoc, tag) {
|
||||||
|
return xmlDoc?.getElementsByTagName(tag)[0]?.textContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function sendXmlDoc(xmlDock, params, contentType) {
|
||||||
|
const parser = new DOMParser();
|
||||||
|
|
||||||
|
const xmlTemplate = fs.readFileSync(__dirname + `/${xmlDock}.ejs`, 'utf-8');
|
||||||
|
const renderedTemplate = ejs.render(xmlTemplate, params);
|
||||||
|
const data = await axios.post(params.mrw.url, renderedTemplate, {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': `${contentType}; charset=utf-8`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return parser.parseFromString(data.data, 'text/xml');
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,25 @@
|
||||||
|
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:mrw="http://www.mrw.es/">
|
||||||
|
<soapenv:Header>
|
||||||
|
<mrw:AuthInfo>
|
||||||
|
<mrw:CodigoFranquicia><%= mrw.franchiseCode %></mrw:CodigoFranquicia>
|
||||||
|
<mrw:CodigoAbonado><%= mrw.subscriberCode %></mrw:CodigoAbonado>
|
||||||
|
<mrw:CodigoDepartamento/>
|
||||||
|
<mrw:UserName><%= mrw.user %></mrw:UserName>
|
||||||
|
<mrw:Password><%= mrw.password %></mrw:Password>
|
||||||
|
</mrw:AuthInfo>
|
||||||
|
</soapenv:Header>
|
||||||
|
<soapenv:Body>
|
||||||
|
<mrw:GetEtiquetaEnvio>
|
||||||
|
<mrw:request>
|
||||||
|
<mrw:NumeroEnvio><%= shipmentId %></mrw:NumeroEnvio>
|
||||||
|
<mrw:NumerosEtiqueta>1</mrw:NumerosEtiqueta>
|
||||||
|
<mrw:SeparadorNumerosEnvio></mrw:SeparadorNumerosEnvio>
|
||||||
|
<mrw:FechaInicioEnvio></mrw:FechaInicioEnvio>
|
||||||
|
<mrw:FechaFinEnvio></mrw:FechaFinEnvio>
|
||||||
|
<mrw:TipoEtiquetaEnvio>0</mrw:TipoEtiquetaEnvio>
|
||||||
|
<mrw:ReportTopMargin>0</mrw:ReportTopMargin>
|
||||||
|
<mrw:ReportLeftMargin>0</mrw:ReportLeftMargin>
|
||||||
|
</mrw:request>
|
||||||
|
</mrw:GetEtiquetaEnvio>
|
||||||
|
</soapenv:Body>
|
||||||
|
</soapenv:Envelope>
|
|
@ -0,0 +1,120 @@
|
||||||
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
const axios = require('axios');
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
const mockBase64Binary = 'base64BinaryString';
|
||||||
|
const ticket1 = {
|
||||||
|
'id': '44',
|
||||||
|
'clientFk': 1101,
|
||||||
|
'shipped': Date.vnNew(),
|
||||||
|
'nickname': 'MRW',
|
||||||
|
'addressFk': 1,
|
||||||
|
'agencyModeFk': 999
|
||||||
|
};
|
||||||
|
|
||||||
|
const expedition1 = {
|
||||||
|
'id': 17,
|
||||||
|
'agencyModeFk': 999,
|
||||||
|
'ticketFk': 44,
|
||||||
|
'freightItemFk': 71,
|
||||||
|
'created': '2001-01-01',
|
||||||
|
'counter': 1,
|
||||||
|
'workerFk': 18,
|
||||||
|
'packagingFk': '94',
|
||||||
|
'hostFk': '',
|
||||||
|
'stateTypeFk': 3,
|
||||||
|
'hasNewRoute': 0,
|
||||||
|
'isBox': 71,
|
||||||
|
'editorFk': 100
|
||||||
|
};
|
||||||
|
|
||||||
|
let tx;
|
||||||
|
let options;
|
||||||
|
|
||||||
|
describe('MRWConfig createShipment()', () => {
|
||||||
|
beforeEach(async() => {
|
||||||
|
options = tx = undefined;
|
||||||
|
tx = await models.MrwConfig.beginTransaction({});
|
||||||
|
options = {transaction: tx};
|
||||||
|
|
||||||
|
await models.Agency.create(
|
||||||
|
{'id': 999, 'name': 'mrw'},
|
||||||
|
options
|
||||||
|
);
|
||||||
|
|
||||||
|
await models.AgencyMode.create(
|
||||||
|
{'id': 999, 'name': 'mrw', 'agencyFk': 999, 'code': 'mrw'},
|
||||||
|
options
|
||||||
|
);
|
||||||
|
|
||||||
|
await models.MrwConfig.create(
|
||||||
|
{
|
||||||
|
'url': 'https://url.com',
|
||||||
|
'user': 'user',
|
||||||
|
'password': 'password',
|
||||||
|
'franchiseCode': 'franchiseCode',
|
||||||
|
'subscriberCode': 'subscriberCode'
|
||||||
|
}, options
|
||||||
|
);
|
||||||
|
|
||||||
|
await models.Application.rawSql(
|
||||||
|
`INSERT INTO vn.mrwService
|
||||||
|
SET agencyModeCodeFk = 'mrw',
|
||||||
|
clientType = 1,
|
||||||
|
serviceType = 1,
|
||||||
|
kg = 1`, null, options
|
||||||
|
);
|
||||||
|
await models.Ticket.create(ticket1, options);
|
||||||
|
await models.Expedition.create(expedition1, options);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async() => {
|
||||||
|
await tx.rollback();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create a shipment and return a base64Binary label', async() => {
|
||||||
|
const mockPostResponses = [
|
||||||
|
{data: fs.readFileSync(__dirname + '/mockGetLabel.xml', 'utf-8')},
|
||||||
|
{data: fs.readFileSync(__dirname + '/mockCreateShipment.xml', 'utf-8')}
|
||||||
|
];
|
||||||
|
|
||||||
|
spyOn(axios, 'post').and.callFake(() => Promise.resolve(mockPostResponses.pop()));
|
||||||
|
|
||||||
|
const base64Binary = await models.MrwConfig.createShipment(expedition1.id, options);
|
||||||
|
|
||||||
|
expect(base64Binary).toEqual(mockBase64Binary);
|
||||||
|
});
|
||||||
|
|
||||||
|
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`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||||
|
<soap:Body>
|
||||||
|
<TransmEnvioResponse xmlns="http://www.mrw.es/">
|
||||||
|
<TransmEnvioResult>
|
||||||
|
<Estado>1</Estado>
|
||||||
|
<Mensaje />
|
||||||
|
<NumeroSolicitud>1</NumeroSolicitud>
|
||||||
|
<NumeroEnvio>1</NumeroEnvio>
|
||||||
|
<Url>http://url.com</Url>
|
||||||
|
</TransmEnvioResult>
|
||||||
|
</TransmEnvioResponse>
|
||||||
|
</soap:Body>
|
||||||
|
</soap:Envelope>
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||||
|
<soap:Body>
|
||||||
|
<GetEtiquetaEnvioResponse xmlns="http://www.mrw.es/">
|
||||||
|
<GetEtiquetaEnvioResult>
|
||||||
|
<Estado>1</Estado>
|
||||||
|
<Mensaje />
|
||||||
|
<EtiquetaFile>base64BinaryString</EtiquetaFile>
|
||||||
|
</GetEtiquetaEnvioResult>
|
||||||
|
</GetEtiquetaEnvioResponse>
|
||||||
|
</soap:Body>
|
||||||
|
</soap:Envelope>
|
|
@ -159,6 +159,9 @@
|
||||||
},
|
},
|
||||||
"VnRole": {
|
"VnRole": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
|
"MrwConfig": {
|
||||||
|
"dataSource": "vn"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
require('../methods/mrw-config/createShipment')(Self);
|
||||||
|
require('../methods/mrw-config/cancelShipment')(Self);
|
||||||
|
};
|
|
@ -0,0 +1,31 @@
|
||||||
|
{
|
||||||
|
"name": "MrwConfig",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "mrwConfig"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "number",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"type": "string",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"franchiseCode": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"subscriberCode": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
-- Place your SQL code here
|
||||||
|
CREATE TABLE IF NOT EXISTS `vn`.`mrwConfig` (
|
||||||
|
`id` INT auto_increment NULL,
|
||||||
|
`url` varchar(100) NULL,
|
||||||
|
`user` varchar(100) NULL,
|
||||||
|
`password` varchar(100) NULL,
|
||||||
|
`franchiseCode` varchar(100) NULL,
|
||||||
|
`subscriberCode` varchar(100) NULL,
|
||||||
|
CONSTRAINT mrwConfig_pk PRIMARY KEY (id)
|
||||||
|
)
|
||||||
|
ENGINE=InnoDB
|
||||||
|
DEFAULT CHARSET=utf8mb3
|
||||||
|
COLLATE=utf8mb3_unicode_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `vn`.`packingSite` ADD `hasNewLabelMrwMethod` BOOL NULL;
|
||||||
|
|
||||||
|
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
|
||||||
|
VALUES('MrwConfig', 'cancelShipment', 'WRITE', 'ALLOW', 'ROLE', 'employee');
|
||||||
|
|
||||||
|
INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalType`,`principalId`)
|
||||||
|
VALUES ('MrwConfig','createShipment','WRITE','ALLOW','ROLE','employee');
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue