dev #1731

Merged
jgallego merged 105 commits from dev into test 2023-08-31 09:13:29 +00:00
17 changed files with 325 additions and 110 deletions
Showing only changes of commit 7d10be37ec - Show all commits

View File

@ -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;
};
};

View File

@ -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;
};
};

View File

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<PutExpedicionInternacional xmlns="http://82.223.6.71:82">
<ObjetoEnvio>
<Peso><%= viaexpressConfig.defaultWeight %></Peso>
<Bultos>1</Bultos>
<Reembolso>0</Reembolso>
<Fecha><%= shipped %></Fecha>
<ConRetorno>0</ConRetorno>
<Tipo><%= viaexpressConfig.deliveryType %></Tipo>
<Debidos>0</Debidos>
<Asegurado>0</Asegurado>
<Imprimir>0</Imprimir>
<ConDevolucionAlbaran>0</ConDevolucionAlbaran>
<Intradia>0</Intradia>
<Observaciones></Observaciones>
<AlbaranRemitente></AlbaranRemitente>
<Modo>0</Modo>
<TextoAgencia></TextoAgencia>
<Terminal></Terminal>
<ObjetoRemitente>
<RazonSocial><%= sender.socialName %></RazonSocial>
<Domicilio><%= senderAddress.street %></Domicilio>
<Cpostal><%= senderAddress.postalCode %></Cpostal>
<Poblacion><%= senderAddress.city %></Poblacion>
<Provincia><%= senderAddress.province().name %></Provincia>
<Contacto></Contacto>
<Telefono><%= senderAddress.mobile || senderAddress.phone || sender.mobile || sender.phone %></Telefono>
<Email><%= sender.email %></Email>
</ObjetoRemitente>
<ObjetoDestinatario>
<RazonSocial><%= address.nickname %></RazonSocial>
<Domicilio><%= address.street %></Domicilio>
<Cpostal><%= address.postalCode %></Cpostal>
<Poblacion><%= address.city %></Poblacion>
<Municipio></Municipio>
<Provincia><%= address.province().name %></Provincia>
<Contacto></Contacto>
<Telefono><%= address.mobile || address.phone || client.mobile || client.phone %></Telefono>
<Email><%= client.email %></Email>
<Pais><%= address.province().country().code %></Pais>
</ObjetoDestinatario>
<ObjetoLogin>
<IdCliente><%= viaexpressConfig.client %></IdCliente>
<Usuario><%= viaexpressConfig.user %></Usuario>
<Password><%= viaexpressConfig.password %></Password>
</ObjetoLogin>
</ObjetoEnvio>
</PutExpedicionInternacional>
</soap12:Body>
</soap12:Envelope>

View File

@ -150,6 +150,9 @@
}, },
"PrintConfig": { "PrintConfig": {
"dataSource": "vn" "dataSource": "vn"
},
"ViaexpressConfig": {
"dataSource": "vn"
} }
} }

View File

@ -27,5 +27,12 @@
"where" :{ "where" :{
"expired": null "expired": null
} }
},
"relations": {
"client": {
"type": "belongsTo",
"model": "Client",
"foreignKey": "clientFk"
}
} }
} }

View File

@ -0,0 +1,4 @@
module.exports = Self => {
require('../methods/viaexpress-config/internationalExpedition')(Self);
require('../methods/viaexpress-config/renderer')(Self);
};

View File

@ -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"
}
}
}

View File

@ -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');

View File

@ -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;

View File

@ -579,13 +579,13 @@ INSERT INTO `vn`.`supplierAccount`(`id`, `supplierFk`, `iban`, `bankEntityFk`)
VALUES VALUES
(241, 442, 'ES111122333344111122221111', 128); (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 VALUES
(69 , 'CCs', NULL, 30, NULL, 0, NULL, 1, NULL), (69 , 'CCs', NULL, 30, NULL, 0, NULL, 1, NULL , NULL),
(442 , 'VNL', 241, 30, 2 , 1, NULL, 2, 'VNL Company - Plant passport'), (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'), (567 , 'VNH', NULL, 30, NULL, 4, NULL, 1, 'VNH Company - Plant passport' , NULL),
(791 , 'FTH', NULL, 30, NULL, 3, '2015-11-30', 1, 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'); (1381, 'ORN', NULL, 30, NULL, 7, NULL, 1, 'ORN Company - Plant passport' , NULL);
INSERT INTO `vn`.`taxArea` (`code`, `claveOperacionFactura`, `CodigoTransaccion`) INSERT INTO `vn`.`taxArea` (`code`, `claveOperacionFactura`, `CodigoTransaccion`)
VALUES VALUES

View File

@ -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);
};
};

View File

@ -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;
}
});
});

View File

@ -14,7 +14,6 @@ module.exports = Self => {
require('../methods/item/getWasteByWorker')(Self); require('../methods/item/getWasteByWorker')(Self);
require('../methods/item/getWasteByItem')(Self); require('../methods/item/getWasteByItem')(Self);
require('../methods/item/createIntrastat')(Self); require('../methods/item/createIntrastat')(Self);
require('../methods/item/activeBuyers')(Self);
require('../methods/item/buyerWasteEmail')(Self); require('../methods/item/buyerWasteEmail')(Self);
require('../methods/item/labelPdf')(Self); require('../methods/item/labelPdf')(Self);

View File

@ -26,7 +26,7 @@
search-function="{firstName: $search}" search-function="{firstName: $search}"
value-field="id" value-field="id"
where="{role: {inq: ['logistic', 'buyer']}}" where="{role: {inq: ['logistic', 'buyer']}}"
label="Atender"> label="Buyer">
<tpl-item>{{nickname}}</tpl-item> <tpl-item>{{nickname}}</tpl-item>
</vn-autocomplete> </vn-autocomplete>
</vn-horizontal> </vn-horizontal>

View File

@ -41,10 +41,10 @@
<vn-autocomplete <vn-autocomplete
vn-one vn-one
ng-model="filter.buyerFk" ng-model="filter.buyerFk"
url="Items/activeBuyers" url="TicketRequests/getItemTypeWorker"
search-function="{firstName: $search}"
show-field="nickname" show-field="nickname"
search-function="{nickname: {like: '%'+ $search +'%'}}" value-field="id"
value-field="workerFk"
label="Buyer"> label="Buyer">
</vn-autocomplete> </vn-autocomplete>
<vn-autocomplete <vn-autocomplete

View File

@ -1,7 +1,9 @@
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
const buildFilter = require('vn-loopback/util/filter').buildFilter;
const mergeFilters = require('vn-loopback/util/filter').mergeFilters;
module.exports = Self => { module.exports = Self => {
Self.remoteMethodCtx('getItemTypeWorker', { Self.remoteMethod('getItemTypeWorker', {
description: 'Returns the workers that appear in itemType', description: 'Returns the workers that appear in itemType',
accessType: 'READ', accessType: 'READ',
accepts: [{ accepts: [{
@ -20,38 +22,37 @@ module.exports = Self => {
} }
}); });
Self.getItemTypeWorker = async(ctx, filter, options) => { Self.getItemTypeWorker = async filter => {
const myOptions = {};
const conn = Self.dataSource.connector; const conn = Self.dataSource.connector;
let tx;
if (typeof options == 'object')
Object.assign(myOptions, options);
const query = const query =
`SELECT DISTINCT u.id, u.nickname `SELECT DISTINCT u.id, u.nickname
FROM itemType it FROM itemType it
JOIN worker w ON w.id = it.workerFk JOIN worker w ON w.id = it.workerFk
JOIN account.user u ON u.id = w.id`; JOIN account.user u ON u.id = w.id`;
const stmt = new ParameterizedSQL(query);
let stmt = new ParameterizedSQL(query); filter.where = buildFilter(filter.where, (param, value) => {
switch (param) {
if (filter.where) { case 'firstName':
const value = filter.where.firstName; return {or: [
const myFilter = {
where: {or: [
{'w.firstName': {like: `%${value}%`}}, {'w.firstName': {like: `%${value}%`}},
{'w.lastName': {like: `%${value}%`}}, {'w.lastName': {like: `%${value}%`}},
{'u.name': {like: `%${value}%`}}, {'u.name': {like: `%${value}%`}},
{'u.nickname': {like: `%${value}%`}} {'u.nickname': {like: `%${value}%`}}
]} ]};
case 'id':
return {'w.id': value};
}
});
let myFilter = {
where: {'u.active': true}
}; };
myFilter = mergeFilters(myFilter, filter);
stmt.merge(conn.makeSuffix(myFilter)); stmt.merge(conn.makeSuffix(myFilter));
}
if (tx) await tx.commit();
return conn.executeStmt(stmt); return conn.executeStmt(stmt);
}; };
}; };

View File

@ -1,12 +1,10 @@
const models = require('vn-loopback/server/server').models; const models = require('vn-loopback/server/server').models;
describe('ticket-request getItemTypeWorker()', () => { describe('ticket-request getItemTypeWorker()', () => {
const ctx = {req: {accessToken: {userId: 18}}};
it('should return the buyer as result', async() => { it('should return the buyer as result', async() => {
const filter = {where: {firstName: 'buyer'}}; 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); expect(result.length).toEqual(1);
}); });
@ -14,7 +12,7 @@ describe('ticket-request getItemTypeWorker()', () => {
it('should return the workers at itemType as result', async() => { it('should return the workers at itemType as result', async() => {
const filter = {}; const filter = {};
const result = await models.TicketRequest.getItemTypeWorker(ctx, filter); const result = await models.TicketRequest.getItemTypeWorker(filter);
expect(result.length).toBeGreaterThan(1); expect(result.length).toBeGreaterThan(1);
}); });