4846-claim.search-panel #1174

Merged
vicent merged 18 commits from 4846-claim.search-panel into dev 2023-01-10 13:09:23 +00:00
200 changed files with 36545 additions and 36774 deletions
Showing only changes of commit fb325d5e65 - Show all commits

16
CHANGELOG.md Normal file
View File

@ -0,0 +1,16 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [2302.01] - 2023-01-12
### Added
-
### Changed
-

View File

@ -43,6 +43,9 @@ module.exports = Self => {
if (!recipient)
throw new Error(`Could not send message "${message}" to worker id ${recipientId} from user ${userId}`);
if (process.env.NODE_ENV == 'test')
message = `[Test:Environment to user ${userId}] ` + message;
await models.Chat.create({
senderFk: sender.id,
recipient: `@${recipient.name}`,

View File

@ -26,11 +26,30 @@ module.exports = Self => {
Self.setSaleQuantity = async(saleId, quantity) => {
const models = Self.app.models;
const myOptions = {};
let tx;
const sale = await models.Sale.findById(saleId);
return await sale.updateAttributes({
if (typeof options == 'object')
Object.assign(myOptions, options);
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
try {
const sale = await models.Sale.findById(saleId, null, myOptions);
const saleUpdated = await sale.updateAttributes({
originalQuantity: sale.quantity,
quantity: quantity
});
}, myOptions);
if (tx) await tx.commit();
return saleUpdated;
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
};
};

View File

@ -2,15 +2,26 @@ const models = require('vn-loopback/server/server').models;
describe('setSaleQuantity()', () => {
it('should change quantity sale', async() => {
const tx = await models.Ticket.beginTransaction({});
try {
const options = {transaction: tx};
const saleId = 30;
const newQuantity = 10;
const originalSale = await models.Sale.findById(saleId);
const originalSale = await models.Sale.findById(saleId, null, options);
await models.Collection.setSaleQuantity(saleId, newQuantity);
const updateSale = await models.Sale.findById(saleId);
await models.Collection.setSaleQuantity(saleId, newQuantity, options);
const updateSale = await models.Sale.findById(saleId, null, options);
expect(updateSale.originalQuantity).toEqual(originalSale.quantity);
expect(updateSale.quantity).toEqual(newQuantity);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
});

View File

@ -0,0 +1,215 @@
const md5 = require('md5');
const fs = require('fs-extra');
module.exports = Self => {
Self.remoteMethodCtx('saveSign', {
description: 'Save sign',
accessType: 'WRITE',
accepts:
[
{
arg: 'signContent',
type: 'string',
required: true,
description: 'The sign content'
}, {
arg: 'tickets',
type: ['number'],
required: true,
description: 'The tickets'
}, {
arg: 'signedTime',
type: 'date',
description: 'The signed time'
}, {
arg: 'addressFk',
type: 'number',
required: true,
description: 'The address fk'
}
],
returns: {
type: 'Object',
root: true
},
http: {
path: `/saveSign`,
verb: 'POST'
}
});
async function createGestDoc(ticketId, userFk) {
const models = Self.app.models;
if (!await gestDocExists(ticketId)) {
const result = await models.Ticket.findOne({
where: {
id: ticketId
},
include: [
{
relation: 'warehouse',
scope: {
fields: ['id']
}
}, {
relation: 'client',
scope: {
fields: ['name']
}
}, {
relation: 'route',
scope: {
fields: ['id']
}
}
]
});
const warehouseFk = result.warehouseFk;
const companyFk = result.companyFk;
const client = result.client.name;
const route = result.route.id;
const resultDmsType = await models.DmsType.findOne({
where: {
code: 'Ticket'
}
});
const resultDms = await models.Dms.create({
dmsTypeFk: resultDmsType.id,
reference: ticketId,
description: `Ticket ${ticketId} Cliente ${client} Ruta ${route}`,
companyFk: companyFk,
warehouseFk: warehouseFk,
workerFk: userFk
});
return resultDms.insertId;
}
}
async function gestDocExists(ticket) {
const models = Self.app.models;
const result = await models.TicketDms.findOne({
where: {
ticketFk: ticket
},
fields: ['dmsFk']
});
if (result == null)
return false;
const isSigned = await models.Ticket.findOne({
where: {
id: ticket
},
fields: ['isSigned']
});
if (isSigned)
return true;
else
await models.Dms.destroyById(ticket);
}
async function dmsRecover(ticket, signContent) {
const models = Self.app.models;
await models.DmsRecover.create({
ticketFk: ticket,
sign: signContent
});
}
async function ticketGestdoc(ticket, dmsFk) {
const models = Self.app.models;
models.TicketDms.replaceOrCreate({
ticketFk: ticket,
dmsFk: dmsFk
});
const queryVnTicketSetState = `CALL vn.ticket_setState(?, ?)`;
await Self.rawSql(queryVnTicketSetState, [ticket, 'DELIVERED']);
}
async function updateGestdoc(file, ticket) {
const models = Self.app.models;
models.Dms.updateOne({
where: {
id: ticket
},
file: file,
contentType: 'image/png'
});
}
Self.saveSign = async(ctx, signContent, tickets, signedTime) => {
const models = Self.app.models;
let tx = await Self.beginTransaction({});
try {
const userId = ctx.req.accessToken.userId;
const dmsDir = `storage/dms`;
let image = null;
for (let i = 0; i < tickets.length; i++) {
const alertLevel = await models.TicketState.findOne({
where: {
ticketFk: tickets[i]
},
fields: ['alertLevel']
});
signedTime ? signedTime != undefined : signedTime = new Date();
if (alertLevel >= 2) {
let dir;
let id = null;
let fileName = null;
if (!await gestDocExists(tickets[i])) {
id = await createGestDoc(tickets[i], userId);
const hashDir = md5(id).substring(0, 3);
dir = `${dmsDir}/${hashDir}`;
if (!fs.existsSync(dir))
fs.mkdirSync(dir);
fileName = `${id}.png`;
image = `${dir}/${fileName}`;
} else
if (image != null) {
if (!fs.existsSync(dir))
dmsRecover(tickets[i], signContent);
else {
fs.writeFile(image, signContent, 'base64', async function(err) {
if (err) {
await tx.rollback();
return err.message;
}
});
}
} else
dmsRecover(tickets[i], signContent);
if (id != null && fileName.length > 0) {
ticketGestdoc(tickets[i], id);
updateGestdoc(id, fileName);
}
}
}
if (tx) await tx.commit();
return 'OK';
} catch (err) {
await tx.rollback();
throw err.message;
}
};
};

View File

@ -19,11 +19,11 @@ describe('getStarredModules()', () => {
});
it(`should return the starred modules for a given user`, async() => {
const newStarred = await app.models.StarredModule.create({workerFk: 9, moduleFk: 'Clients', position: 1});
const newStarred = await app.models.StarredModule.create({workerFk: 9, moduleFk: 'customer', position: 1});
const starredModules = await app.models.StarredModule.getStarredModules(ctx);
expect(starredModules.length).toEqual(1);
expect(starredModules[0].moduleFk).toEqual('Clients');
expect(starredModules[0].moduleFk).toEqual('customer');
// restores
await app.models.StarredModule.destroyById(newStarred.id);

View File

@ -26,29 +26,29 @@ describe('setPosition()', () => {
const filter = {
where: {
workerFk: ctx.req.accessToken.userId,
moduleFk: 'Orders'
moduleFk: 'order'
}
};
try {
const options = {transaction: tx};
await app.models.StarredModule.toggleStarredModule(ctx, 'Orders', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'Clients', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'order', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'customer', options);
let orders = await app.models.StarredModule.findOne(filter, options);
filter.where.moduleFk = 'Clients';
filter.where.moduleFk = 'customer';
let clients = await app.models.StarredModule.findOne(filter, options);
expect(orders.position).toEqual(1);
expect(clients.position).toEqual(2);
await app.models.StarredModule.setPosition(ctx, 'Clients', 'left', options);
await app.models.StarredModule.setPosition(ctx, 'customer', 'left', options);
filter.where.moduleFk = 'Clients';
filter.where.moduleFk = 'customer';
clients = await app.models.StarredModule.findOne(filter, options);
filter.where.moduleFk = 'Orders';
filter.where.moduleFk = 'order';
orders = await app.models.StarredModule.findOne(filter, options);
expect(clients.position).toEqual(1);
@ -67,29 +67,29 @@ describe('setPosition()', () => {
const filter = {
where: {
workerFk: ctx.req.accessToken.userId,
moduleFk: 'Orders'
moduleFk: 'order'
}
};
try {
const options = {transaction: tx};
await app.models.StarredModule.toggleStarredModule(ctx, 'Orders', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'Clients', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'order', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'customer', options);
let orders = await app.models.StarredModule.findOne(filter, options);
filter.where.moduleFk = 'Clients';
filter.where.moduleFk = 'customer';
let clients = await app.models.StarredModule.findOne(filter, options);
expect(orders.position).toEqual(1);
expect(clients.position).toEqual(2);
await app.models.StarredModule.setPosition(ctx, 'Orders', 'right', options);
await app.models.StarredModule.setPosition(ctx, 'order', 'right', options);
filter.where.moduleFk = 'Orders';
filter.where.moduleFk = 'order';
orders = await app.models.StarredModule.findOne(filter, options);
filter.where.moduleFk = 'Clients';
filter.where.moduleFk = 'customer';
clients = await app.models.StarredModule.findOne(filter, options);
expect(orders.position).toEqual(2);
@ -108,35 +108,35 @@ describe('setPosition()', () => {
const filter = {
where: {
workerFk: ctx.req.accessToken.userId,
moduleFk: 'Items'
moduleFk: 'item'
}
};
try {
const options = {transaction: tx};
await app.models.StarredModule.toggleStarredModule(ctx, 'Clients', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'Orders', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'Clients', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'Orders', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'Items', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'Claims', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'Clients', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'Orders', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'Zones', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'customer', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'order', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'customer', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'order', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'item', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'claim', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'customer', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'order', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'zone', options);
const items = await app.models.StarredModule.findOne(filter, options);
filter.where.moduleFk = 'Claims';
filter.where.moduleFk = 'claim';
const claims = await app.models.StarredModule.findOne(filter, options);
filter.where.moduleFk = 'Clients';
filter.where.moduleFk = 'customer';
let clients = await app.models.StarredModule.findOne(filter, options);
filter.where.moduleFk = 'Orders';
filter.where.moduleFk = 'order';
let orders = await app.models.StarredModule.findOne(filter, options);
filter.where.moduleFk = 'Zones';
filter.where.moduleFk = 'zone';
const zones = await app.models.StarredModule.findOne(filter, options);
expect(items.position).toEqual(1);
@ -145,12 +145,12 @@ describe('setPosition()', () => {
expect(orders.position).toEqual(4);
expect(zones.position).toEqual(5);
await app.models.StarredModule.setPosition(ctx, 'Clients', 'right', options);
await app.models.StarredModule.setPosition(ctx, 'customer', 'right', options);
filter.where.moduleFk = 'Orders';
filter.where.moduleFk = 'order';
orders = await app.models.StarredModule.findOne(filter, options);
filter.where.moduleFk = 'Clients';
filter.where.moduleFk = 'customer';
clients = await app.models.StarredModule.findOne(filter, options);
expect(orders.position).toEqual(3);
@ -169,31 +169,31 @@ describe('setPosition()', () => {
const filter = {
where: {
workerFk: ctx.req.accessToken.userId,
moduleFk: 'Items'
moduleFk: 'item'
}
};
try {
const options = {transaction: tx};
await app.models.StarredModule.toggleStarredModule(ctx, 'Items', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'Clients', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'Claims', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'Orders', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'Zones', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'item', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'customer', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'claim', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'order', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'zone', options);
const items = await app.models.StarredModule.findOne(filter, options);
filter.where.moduleFk = 'Clients';
filter.where.moduleFk = 'customer';
let clients = await app.models.StarredModule.findOne(filter, options);
filter.where.moduleFk = 'Claims';
filter.where.moduleFk = 'claim';
const claims = await app.models.StarredModule.findOne(filter, options);
filter.where.moduleFk = 'Orders';
filter.where.moduleFk = 'order';
let orders = await app.models.StarredModule.findOne(filter, options);
filter.where.moduleFk = 'Zones';
filter.where.moduleFk = 'zone';
const zones = await app.models.StarredModule.findOne(filter, options);
expect(items.position).toEqual(1);
@ -202,13 +202,13 @@ describe('setPosition()', () => {
expect(orders.position).toEqual(4);
expect(zones.position).toEqual(5);
await app.models.StarredModule.toggleStarredModule(ctx, 'Claims', options);
await app.models.StarredModule.setPosition(ctx, 'Clients', 'right', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'claim', options);
await app.models.StarredModule.setPosition(ctx, 'customer', 'right', options);
filter.where.moduleFk = 'Clients';
filter.where.moduleFk = 'customer';
clients = await app.models.StarredModule.findOne(filter, options);
filter.where.moduleFk = 'Orders';
filter.where.moduleFk = 'order';
orders = await app.models.StarredModule.findOne(filter, options);
expect(orders.position).toEqual(2);

View File

@ -21,15 +21,15 @@ describe('toggleStarredModule()', () => {
});
it('should create a new starred module and then remove it by calling the method again with same args', async() => {
const starredModule = await app.models.StarredModule.toggleStarredModule(ctx, 'Orders');
const starredModule = await app.models.StarredModule.toggleStarredModule(ctx, 'order');
let starredModules = await app.models.StarredModule.getStarredModules(ctx);
expect(starredModules.length).toEqual(1);
expect(starredModule.moduleFk).toEqual('Orders');
expect(starredModule.moduleFk).toEqual('order');
expect(starredModule.workerFk).toEqual(activeCtx.accessToken.userId);
expect(starredModule.position).toEqual(starredModules.length);
await app.models.StarredModule.toggleStarredModule(ctx, 'Orders');
await app.models.StarredModule.toggleStarredModule(ctx, 'order');
starredModules = await app.models.StarredModule.getStarredModules(ctx);
expect(starredModules.length).toEqual(0);

View File

@ -6,6 +6,7 @@ module.exports = Self => {
require('../methods/dms/removeFile')(Self);
require('../methods/dms/updateFile')(Self);
require('../methods/dms/deleteTrashFiles')(Self);
require('../methods/dms/saveSign')(Self);
Self.checkRole = async function(ctx, id) {
const models = Self.app.models;

View File

@ -12,14 +12,9 @@ BEGIN
* @param vAuthorFk The notification author or %NULL if there is no author
* @return The notification id
*/
DECLARE vNotificationFk INT;
SELECT id INTO vNotificationFk
FROM `notification`
WHERE `name` = vNotificationName;
INSERT INTO notificationQueue
SET notificationFk = vNotificationFk,
SET notificationFk = vNotificationName,
params = vParams,
authorFk = vAuthorFk;

View File

@ -1 +0,0 @@
Delete this file

View File

@ -0,0 +1,4 @@
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
VALUES
('MdbApp', 'lock', 'WRITE', 'ALLOW', 'ROLE', 'developer'),
('MdbApp', 'unlock', 'WRITE', 'ALLOW', 'ROLE', 'developer');

View File

@ -0,0 +1 @@
INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalId`) VALUES ('Dms','saveSign','*','ALLOW','employee');

View File

@ -0,0 +1,438 @@
DROP PROCEDURE IF EXISTS `sage`.`accountingMovements_add`;
DELIMITER $$
$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `sage`.`accountingMovements_add`(vYear INT, vCompanyFk INT)
BEGIN
/**
* Traslada la info de contabilidad generada en base a vn.XDiario a la tabla sage.movConta para poder ejecutar posteriormente el proceso de importación de datos de SQL Server
* Solo traladará los asientos marcados con el campo vn.XDiario.enlazadoSage = FALSE
* @vYear Año contable del que se quiere trasladar la información
* @vCompanyFk Empresa de la que se quiere trasladar datos
*/
DECLARE vDatedFrom DATETIME;
DECLARE vDatedTo DATETIME;
DECLARE vDuaTransactionFk INT;
DECLARE vTaxImportFk INT;
DECLARE vTaxImportReducedFk INT;
DECLARE vTaxImportSuperReducedFk INT;
DECLARE vTransactionExportFk INT;
DECLARE vTransactionExportTaxFreeFk INT;
DECLARE vSerialDua VARCHAR(1) DEFAULT 'D';
DECLARE vInvoiceTypeInformativeCode VARCHAR(1);
DECLARE vCountryCanariasCode, vCountryCeutaMelillaCode VARCHAR(2) ;
DECLARE vBookEntries TEXT;
SELECT SiglaNacion INTO vCountryCanariasCode
FROM Naciones
WHERE Nacion ='ISLAS CANARIAS';
SELECT SiglaNacion INTO vCountryCeutaMelillaCode
FROM Naciones
WHERE Nacion ='CEUTA Y MELILLA';
SELECT CodigoTransaccion INTO vDuaTransactionFk
FROM TiposTransacciones
WHERE Transaccion = 'Import. bienes y serv. corrientes pdte. liquidar';
SELECT CodigoIva INTO vTaxImportFk
FROM TiposIva
WHERE Iva = 'IVA 21% importaciones';
SELECT CodigoIva INTO vTaxImportReducedFk
FROM TiposIva
WHERE Iva = 'IVA 10% importaciones';
SELECT CodigoIva INTO vTaxImportSuperReducedFk
FROM TiposIva
WHERE Iva = 'H.P. IVA Soportado Impor 4%';
SELECT CodigoTransaccion INTO vTransactionExportFk
FROM TiposTransacciones
WHERE Transaccion = 'Exportaciones definitivas';
SELECT CodigoTransaccion INTO vTransactionExportTaxFreeFk
FROM TiposTransacciones
WHERE Transaccion = 'Envíos definitivos a Canarias, Ceuta y Melilla';
SELECT codeSage INTO vInvoiceTypeInformativeCode
FROM invoiceType WHERE code ='informative';
SELECT CAST(CONCAT(vYear, '-01-01') AS DATETIME), util.dayEnd(CAST(CONCAT(vYear, '-12-31') AS DATE))
INTO vDatedFrom, vDatedTo;
TRUNCATE movContaIVA;
DELETE FROM movConta
WHERE enlazadoSage = FALSE
AND Asiento <> 1 ;
CALL clientSupplier_add(vCompanyFk);
CALL pgc_add(vCompanyFk);
CALL invoiceOut_manager(vYear, vCompanyFk);
CALL invoiceIn_manager(vYear, vCompanyFk);
INSERT INTO movConta(TipoEntrada,
Ejercicio,
CodigoEmpresa,
Asiento,
CargoAbono,
CodigoCuenta,
Contrapartida,
FechaAsiento,
Comentario,
ImporteAsiento,
NumeroPeriodo,
FechaGrabacion,
CodigoDivisa,
ImporteCambio,
ImporteDivisa,
FactorCambio,
IdProcesoIME,
TipoCarteraIME,
TipoAnaliticaIME,
StatusTraspasadoIME,
TipoImportacionIME,
Metalico347,
BaseIva1,
PorBaseCorrectora1,
PorIva1,
CuotaIva1,
PorRecargoEquivalencia1,
RecargoEquivalencia1,
CodigoTransaccion1,
BaseIva2,
PorBaseCorrectora2,
PorIva2,
CuotaIva2,
PorRecargoEquivalencia2,
RecargoEquivalencia2,
CodigoTransaccion2,
BaseIva3,
PorBaseCorrectora3,
PorIva3,
CuotaIva3,
PorRecargoEquivalencia3,
RecargoEquivalencia3,
CodigoTransaccion3,
BaseIva4,
PorBaseCorrectora4,
PorIva4,
CuotaIva4,
PorRecargoEquivalencia4,
RecargoEquivalencia4,
CodigoTransaccion4,
Año,
Serie,
Factura,
SuFacturaNo,
FechaFactura,
ImporteFactura,
TipoFactura,
CodigoCuentaFactura,
CifDni,
Nombre,
CodigoRetencion,
BaseRetencion,
PorRetencion,
ImporteRetencion,
SiglaNacion,
EjercicioFactura,
FechaOperacion,
Exclusion347,
MantenerAsiento,
ClaveOperacionFactura_,
TipoRectificativa,
FechaFacturaOriginal,
BaseImponibleOriginal,
CuotaIvaOriginal,
ClaseAbonoRectificativas,
RecargoEquivalenciaOriginal,
LibreA1,
CodigoIva1,
CodigoIva2,
CodigoIva3,
CodigoIva4,
IvaDeducible1,
IvaDeducible2,
IvaDeducible3,
IvaDeducible4,
Intracomunitaria
)
SELECT 'EN' TipoEntrada,
YEAR(x.FECHA) Ejercicio,
company_getCode(vCompanyFk) AS CodigoEmpresa,
x.ASIEN Asiento,
IF(EURODEBE <> 0 OR (EURODEBE = 0 AND EUROHABER IS NULL), 'D', 'H') CargoAbono,
x.SUBCTA CodigoCuenta,
x.CONTRA Contrapartida,
x.FECHA FechaAsiento,
x.CONCEPTO Comentario,
IF(x.EURODEBE, x.EURODEBE, x.EUROHABER) ImporteAsiento,
MONTH(x.FECHA) NumeroPeriodo,
IF(sub2.FECREGCON IS NULL, sub2.FECHA_EX, sub2.FECREGCON) FechaGrabacion,
IF(x.CAMBIO, IFNULL(mci.CodigoDivisa, sub3.code), '') CodigoDivisa,
x.CAMBIO ImporteCambio,
IFNULL(x.DEBEME, x.HABERME) ImporteDivisa,
IF(x.CAMBIO, TRUE, FALSE) FactorCambio,
NULL IdProcesoIME,
0 TipoCarteraIME,
0 TipoAnaliticaIME,
0 StatusTraspasadoIME,
0 TipoImportacionIME,
x.METAL Metalico347,
mci.BaseIva1,
mci.PorBaseCorrectora1,
mci.PorIva1,
mci.CuotaIva1,
mci.PorRecargoEquivalencia1,
mci.RecargoEquivalencia1,
mci.CodigoTransaccion1,
mci.BaseIva2,
mci.PorBaseCorrectora2,
mci.PorIva2,
mci.CuotaIva2,
mci.PorRecargoEquivalencia2,
mci.RecargoEquivalencia2,
mci.CodigoTransaccion2,
mci.BaseIva3,
mci.PorBaseCorrectora3,
mci.PorIva3,
mci.CuotaIva3,
mci.PorRecargoEquivalencia3,
mci.RecargoEquivalencia3,
mci.CodigoTransaccion3,
mci.BaseIva4,
mci.PorBaseCorrectora4,
mci.PorIva4,
mci.CuotaIva4,
mci.PorRecargoEquivalencia4,
mci.RecargoEquivalencia4,
mci.CodigoTransaccion4,
mci.Año,
mci.Serie,
mci.Factura,
mci.SuFacturaNo,
mci.FechaFactura,
mci.ImporteFactura,
mci.TipoFactura,
mci.CodigoCuentaFactura,
mci.CifDni,
mci.Nombre,
mci.CodigoRetencion,
mci.BaseRetencion,
mci.PorRetencion,
mci.ImporteRetencion,
mci.SiglaNacion,
mci.EjercicioFactura,
mci.FechaOperacion,
mci.Exclusion347,
TRUE,
mci.ClaveOperacionFactura,
mci.TipoRectificativa,
mci.FechaFacturaOriginal,
mci.BaseImponibleOriginal,
mci.CuotaIvaOriginal,
mci.ClaseAbonoRectificativas,
mci.RecargoEquivalenciaOriginal,
mci.LibreA1,
mci.CodigoIva1,
mci.CodigoIva2,
mci.CodigoIva3,
mci.CodigoIva4,
mci.IvaDeducible1,
mci.IvaDeducible2,
mci.IvaDeducible3,
mci.IvaDeducible4,
mci.Intracomunitaria
FROM vn.XDiario x
LEFT JOIN movContaIVA mci ON mci.id = x.id
LEFT JOIN (SELECT *
FROM (SELECT DISTINCT ASIEN, FECREGCON, FECHA_EX
FROM vn.XDiario
WHERE enlazadoSage = FALSE
ORDER BY ASIEN, FECREGCON DESC, FECHA_EX DESC
LIMIT 10000000000000000000
) sub GROUP BY ASIEN
)sub2 ON sub2.ASIEN = x.ASIEN
LEFT JOIN ( SELECT DISTINCT(account),cu.code
FROM vn.bank b
JOIN vn.currency cu ON cu.id = b.currencyFk
WHERE cu.code <> 'EUR' -- no se informa cuando la divisa en EUR
)sub3 ON sub3.account = x.SUBCTA
WHERE x.enlazadoSage = FALSE
AND x.empresa_id = vCompanyFk
AND x.FECHA BETWEEN vDatedFrom AND vDatedTo;
-- Metálicos
UPDATE movConta m
JOIN (SELECT Asiento,
c.socialName name,
c.fi,
n.SiglaNacion,
m.CodigoCuenta,
m.Contrapartida
FROM movConta m
LEFT JOIN vn.client c ON c.id = IF(m.CargoAbono = 'H',
CAST(SUBSTRING(m.CodigoCuenta, 3, LENGTH(m.CodigoCuenta)) AS UNSIGNED),
CAST(SUBSTRING(m.Contrapartida, 3, LENGTH(m.Contrapartida)) AS UNSIGNED))
LEFT JOIN Naciones n ON n.countryFk = c.countryFk
WHERE m.Metalico347 = TRUE
AND m.enlazadoSage = FALSE
)sub ON m.Asiento = sub.Asiento
SET m.Metalico347 = TRUE,
m.TipoFactura = vInvoiceTypeInformativeCode,
m.CifDni = sub.fi,
m.Nombre = sub.name,
m.SiglaNacion = sub.SiglaNacion
WHERE m.enlazadoSage = FALSE;
UPDATE movConta m
SET m.Metalico347 = FALSE,
m.TipoFactura = ''
WHERE m.CargoAbono = 'D'
AND m.enlazadoSage = FALSE;
-- Elimina cuentas de cliente/proveedor que no se utilizarán en la importación
DELETE cp
FROM clientesProveedores cp
LEFT JOIN movConta mc ON mc.codigoCuenta = cp.codigoCuenta
AND mc.enlazadoSage = FALSE
WHERE mc.codigoCuenta IS NULL;
-- Elimina cuentas contables que no se utilizarán en la importación
DELETE pc
FROM planCuentasPGC pc
LEFT JOIN movConta mc ON mc.codigoCuenta = pc.codigoCuenta
AND mc.enlazadoSage = FALSE
WHERE mc.codigoCuenta IS NULL;
-- DUAS
UPDATE movConta mci
JOIN vn.XDiario x ON x.ASIEN = mci.Asiento
JOIN TiposIva ti ON ti.CodigoIva = x.IVA
JOIN vn.pgcMaster pm ON pm.code = mci.CodigoCuenta COLLATE utf8mb3_unicode_ci
SET mci.BaseIva1 = x.BASEEURO,
mci.PorIva1 = x.IVA,
mci.CuotaIva1 = CAST((x.IVA / 100) * x.BASEEURO AS DECIMAL(10, 2)),
mci.CodigoTransaccion1 = vDuaTransactionFk,
mci.CodigoIva1 = vTaxImportReducedFk,
mci.IvaDeducible1 = TRUE,
mci.FechaFacturaOriginal = x.FECHA_EX,
mci.SuFacturaNo = x.FACTURAEX,
mci.FechaOperacion = x.FECHA_OP,
mci.ImporteFactura = mci.ImporteFactura + x.BASEEURO + CAST((x.IVA / 100) * x.BASEEURO AS DECIMAL(10, 2))
WHERE pm.description = 'HP Iva pendiente'
AND mci.enlazadoSage = FALSE
AND x.SERIE = vSerialDua COLLATE utf8mb3_unicode_ci
AND ti.Iva = 'I.V.A. 10% Nacional';
UPDATE movConta mci
JOIN vn.XDiario x ON x.ASIEN = mci.Asiento
JOIN TiposIva ti ON ti.CodigoIva = x.IVA
JOIN vn.pgcMaster pm ON pm.code = mci.CodigoCuenta COLLATE utf8mb3_unicode_ci
SET mci.BaseIva2 = x.BASEEURO ,
mci.PorIva2 = x.IVA,
mci.CuotaIva2 = CAST((x.IVA / 100) * x.BASEEURO AS DECIMAL(10,2)),
mci.CodigoTransaccion2 = vDuaTransactionFk ,
mci.CodigoIva2 = vTaxImportFk,
mci.IvaDeducible2 = TRUE,
mci.ImporteFactura = mci.ImporteFactura + x.BASEEURO + CAST((x.IVA / 100) * x.BASEEURO AS DECIMAL(10, 2))
WHERE pm.description = 'HP Iva pendiente'
AND mci.enlazadoSage = FALSE
AND x.SERIE = vSerialDua COLLATE utf8mb3_unicode_ci
AND ti.Iva = 'I.V.A. 21%';
UPDATE movConta mci
JOIN vn.XDiario x ON x.ASIEN = mci.Asiento
JOIN TiposIva ti ON ti.CodigoIva = x.IVA
JOIN vn.pgcMaster pm ON pm.code = mci.CodigoCuenta COLLATE utf8mb3_unicode_ci
SET mci.BaseIva3 = x.BASEEURO ,
mci.PorIva3 = x.IVA,
mci.CuotaIva3 = CAST((x.IVA / 100) * x.BASEEURO AS DECIMAL(10,2)),
mci.CodigoTransaccion3 = vDuaTransactionFk ,
mci.CodigoIva3 = vTaxImportSuperReducedFk,
mci.IvaDeducible3 = TRUE,
mci.ImporteFactura = mci.ImporteFactura + x.BASEEURO + CAST((x.IVA / 100) * x.BASEEURO AS DECIMAL(10, 2))
WHERE pm.description = 'HP Iva pendiente'
AND mci.enlazadoSage = FALSE
AND x.SERIE = vSerialDua COLLATE utf8mb3_unicode_ci
AND ti.Iva = 'I.V.A. 4%';
-- Rectificativas
UPDATE movConta mci
JOIN (SELECT x.ASIEN, x.FECHA_RT, x.SERIE_RT, x.FACTU_RT
FROM movConta mci
JOIN vn.XDiario x ON x.ASIEN = mci.Asiento
WHERE mci.TipoRectificativa > 0
AND mci.enlazadoSage = FALSE
AND x.FACTU_RT IS NOT NULL
GROUP BY x.ASIEN
) sub ON sub.ASIEN = mci.Asiento
SET mci.EjercicioFacturaOriginal = YEAR(sub.FECHA_RT),
mci.SerieFacturaOriginal = sub.SERIE_RT,
mci.NumeroFacturaOriginal = sub.FACTU_RT
WHERE mci.TipoRectificativa > 0 AND
mci.enlazadoSage = FALSE ;
-- Exportaciones Andorras y Canarias cambia TT (la cuenta es compartida)
UPDATE movConta mci
SET CodigoTransaccion1 = vTransactionExportTaxFreeFk,
CodigoTransaccion2 = IF(CodigoTransaccion2 = 0, 0, vTransactionExportTaxFreeFk),
CodigoTransaccion3 = IF(CodigoTransaccion3 = 0, 0, vTransactionExportTaxFreeFk),
CodigoTransaccion4 = IF(CodigoTransaccion4 = 0, 0, vTransactionExportTaxFreeFk)
WHERE enlazadoSage = FALSE
AND (CodigoTransaccion1 = vTransactionExportFk
OR CodigoTransaccion2 = vTransactionExportFk
OR CodigoTransaccion3 = vTransactionExportFk
OR CodigoTransaccion4 = vTransactionExportFk)
AND SiglaNacion IN (vCountryCanariasCode COLLATE utf8mb3_unicode_ci, vCountryCeutaMelillaCode COLLATE utf8mb3_unicode_ci);
UPDATE movConta mc
SET CodigoDivisa = 'USD',
FactorCambio = TRUE,
ImporteCambio = ABS( CAST( IF( ImporteDivisa <> 0 AND ImporteCambio = 0, ImporteAsiento / ImporteDivisa, ImporteCambio) AS DECIMAL( 10, 2)))
WHERE enlazadoSage = FALSE
AND (ImporteCambio <> 0 OR ImporteDivisa <> 0 OR FactorCambio);
UPDATE movConta mc
SET importeDivisa= -importeDivisa
WHERE enlazadoSage = FALSE
AND importeDivisa > 0
AND ImporteAsiento < 0;
-- Comprobación que los importes e ivas sean correctos, avisa vía CAU
SELECT GROUP_CONCAT(Asiento ORDER BY Asiento ASC SEPARATOR ',') INTO vBookEntries
FROM(SELECT sub.Asiento
FROM (SELECT mc.Asiento, SUM(mc.ImporteAsiento) amount
FROM movConta mc
WHERE mc.enlazadoSage = FALSE
GROUP BY mc.Asiento)sub
JOIN (SELECT x.ASIEN, SUM(IFNULL(x.EURODEBE,0) + IFNULL(x.EUROHABER,0)) amount
FROM vn.XDiario x
WHERE x.enlazadoSage = FALSE
GROUP BY ASIEN)sub2 ON sub2.ASIEN = sub.Asiento
WHERE sub.amount <> sub2.amount
UNION ALL
SELECT sub.Asiento
FROM (SELECT Asiento, SUM(BaseIva1 + BaseIva2 + BaseIva3 + BaseIva4) amountTaxableBase
FROM movConta
WHERE TipoFactura <> 'I'
AND enlazadoSage = FALSE
GROUP BY Asiento) sub
JOIN (SELECT ASIEN, SUM(BASEEURO) amountTaxableBase
FROM (SELECT ASIEN, SUM(BASEEURO) BASEEURO
FROM vn.XDiario
WHERE FACTURA
AND auxiliar <> '*'
AND enlazadoSage = FALSE
GROUP BY FACTURA, ASIEN)sub3
GROUP BY ASIEN) sub2 ON sub2.ASIEN = sub.Asiento
WHERE sub.amountTaxableBase<>sub2.amountTaxableBase
AND sub.amountTaxableBase/2 <> sub2.amountTaxableBase) sub;
IF vBookEntries IS NOT NULL THEN
SELECT util.notification_send ("book-entries-imported-incorrectly", CONCAT('{"bookEntries":"', vBookEntries,'"}'), null);
END IF;
END$$
DELIMITER ;

View File

@ -0,0 +1,3 @@
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
VALUES
('TicketLog', 'getChanges', 'READ', 'ALLOW', 'ROLE', 'employee');

View File

@ -0,0 +1 @@
ALTER TABLE `vn`.`entry` DROP COLUMN `ref`;

View File

@ -0,0 +1,12 @@
CREATE TABLE `vn`.`invoiceInConfig` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`retentionRate` int(3) NOT NULL,
`retentionName` varchar(25) NOT NULL,
`sageWithholdingFk` smallint(6) NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `invoiceInConfig_sageWithholdingFk` FOREIGN KEY (`sageWithholdingFk`) REFERENCES `sage`.`TiposRetencion`(`CodigoRetencion`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
INSERT INTO `vn`.`invoiceInConfig` (`id`, `retentionRate`, `retentionName`, `sageWithholdingFk`)
VALUES
(1, -2, 'Retención 2%', 2);

View File

@ -0,0 +1,11 @@
CREATE TABLE `vn`.`mdbApp` (
`app` varchar(100) COLLATE utf8mb3_unicode_ci NOT NULL,
`baselineBranchFk` varchar(255) COLLATE utf8mb3_unicode_ci DEFAULT NULL,
`userFk` int(10) unsigned DEFAULT NULL,
`locked` datetime DEFAULT NULL,
PRIMARY KEY (`app`),
KEY `mdbApp_FK` (`userFk`),
KEY `mdbApp_FK_1` (`baselineBranchFk`),
CONSTRAINT `mdbApp_FK` FOREIGN KEY (`userFk`) REFERENCES `account`.`user` (`id`) ON DELETE SET NULL ON UPDATE CASCADE,
CONSTRAINT `mdbApp_FK_1` FOREIGN KEY (`baselineBranchFk`) REFERENCES `mdbBranch` (`name`) ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci

View File

@ -0,0 +1,24 @@
DROP FUNCTION IF EXISTS `util`.`notification_send`;
DELIMITER $$
$$
CREATE DEFINER=`root`@`localhost` FUNCTION `util`.`notification_send`(vNotificationName VARCHAR(255), vParams TEXT, vAuthorFk INT) RETURNS int(11)
MODIFIES SQL DATA
BEGIN
/**
* Sends a notification.
*
* @param vNotificationName The notification name
* @param vParams The notification parameters formatted as JSON
* @param vAuthorFk The notification author or %NULL if there is no author
* @return The notification id
*/
INSERT INTO notificationQueue
SET notificationFk = vNotificationName,
params = vParams,
authorFk = vAuthorFk;
RETURN LAST_INSERT_ID();
END$$
DELIMITER ;

View File

@ -0,0 +1,46 @@
DROP TRIGGER IF EXISTS `vn`.`supplier_beforeUpdate`;
USE `vn`;
DELIMITER $$
$$
CREATE DEFINER=`root`@`localhost` TRIGGER `vn`.`supplier_beforeUpdate`
BEFORE UPDATE ON `supplier`
FOR EACH ROW
BEGIN
DECLARE vHasChange BOOL;
DECLARE vPayMethodChanged BOOL;
DECLARE vPayMethodHasVerified BOOL;
DECLARE vParams JSON;
DECLARE vOldPayMethodName VARCHAR(20);
DECLARE vNewPayMethodName VARCHAR(20);
SELECT hasVerified INTO vPayMethodHasVerified
FROM payMethod
WHERE id = NEW.payMethodFk;
SET vPayMethodChanged = NOT(NEW.payMethodFk <=> OLD.payMethodFk);
IF vPayMethodChanged THEN
SELECT name INTO vOldPayMethodName
FROM payMethod
WHERE id = OLD.payMethodFk;
SELECT name INTO vNewPayMethodName
FROM payMethod
WHERE id = NEW.payMethodFk;
SET vParams = JSON_OBJECT(
'name', NEW.name,
'oldPayMethod', vOldPayMethodName,
'newPayMethod', vNewPayMethodName
);
SELECT util.notification_send('supplier-pay-method-update', vParams, NULL) INTO @id;
END IF;
SET vHasChange = NOT(NEW.payDemFk <=> OLD.payDemFk AND NEW.payDay <=> OLD.payDay) OR vPayMethodChanged;
IF vHasChange AND vPayMethodHasVerified THEN
SET NEW.isPayMethodChecked = FALSE;
END IF;
END$$
DELIMITER ;

View File

@ -0,0 +1,8 @@
CREATE TABLE `vn`.`ticketSms` (
`smsFk` mediumint(8) unsigned NOT NULL,
`ticketFk` int(11) DEFAULT NULL,
PRIMARY KEY (`smsFk`),
KEY `ticketSms_FK_1` (`ticketFk`),
CONSTRAINT `ticketSms_FK` FOREIGN KEY (`smsFk`) REFERENCES `sms` (`id`) ON UPDATE CASCADE,
CONSTRAINT `ticketSms_FK_1` FOREIGN KEY (`ticketFk`) REFERENCES `ticket` (`id`) ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci

View File

@ -0,0 +1,104 @@
DROP PROCEDURE IF EXISTS `vn`.`ticket_canAdvance`;
DELIMITER $$
$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_canAdvance`(vDateFuture DATE, vDateToAdvance DATE, vWarehouseFk INT)
BEGIN
/**
* Devuelve los tickets y la cantidad de lineas de venta que se pueden adelantar.
*
* @param vDateFuture Fecha de los tickets que se quieren adelantar.
* @param vDateToAdvance Fecha a cuando se quiere adelantar.
* @param vWarehouseFk Almacén
*/
DECLARE vDateInventory DATE;
SELECT inventoried INTO vDateInventory FROM vn.config;
DROP TEMPORARY TABLE IF EXISTS tmp.stock;
CREATE TEMPORARY TABLE tmp.stock
(itemFk INT PRIMARY KEY,
amount INT)
ENGINE = MEMORY;
INSERT INTO tmp.stock(itemFk, amount)
SELECT itemFk, SUM(quantity) amount FROM
(
SELECT itemFk, quantity
FROM vn.itemTicketOut
WHERE shipped >= vDateInventory
AND shipped < vDateFuture
AND warehouseFk = vWarehouseFk
UNION ALL
SELECT itemFk, quantity
FROM vn.itemEntryIn
WHERE landed >= vDateInventory
AND landed < vDateFuture
AND isVirtualStock = FALSE
AND warehouseInFk = vWarehouseFk
UNION ALL
SELECT itemFk, quantity
FROM vn.itemEntryOut
WHERE shipped >= vDateInventory
AND shipped < vDateFuture
AND warehouseOutFk = vWarehouseFk
) t
GROUP BY itemFk HAVING amount != 0;
DROP TEMPORARY TABLE IF EXISTS tmp.filter;
CREATE TEMPORARY TABLE tmp.filter
(INDEX (id))
SELECT s.ticketFk futureId,
t2.ticketFk id,
sum((s.quantity <= IFNULL(st.amount,0))) hasStock,
count(DISTINCT s.id) saleCount,
t2.state,
t2.stateCode,
st.name futureState,
st.code futureStateCode,
GROUP_CONCAT(DISTINCT ipt.code ORDER BY ipt.code) futureIpt,
t2.ipt,
t.workerFk,
CAST(sum(litros) AS DECIMAL(10,0)) liters,
CAST(count(*) AS DECIMAL(10,0)) `lines`,
t2.shipped,
t.shipped futureShipped,
t2.totalWithVat,
t.totalWithVat futureTotalWithVat
FROM vn.ticket t
JOIN vn.ticketState ts ON ts.ticketFk = t.id
JOIN vn.state st ON st.id = ts.stateFk
JOIN vn.saleVolume sv ON t.id = sv.ticketFk
JOIN (SELECT
t2.id ticketFk,
t2.addressFk,
st.name state,
st.code stateCode,
GROUP_CONCAT(DISTINCT ipt.code ORDER BY ipt.code) ipt,
t2.shipped,
t2.totalWithVat
FROM vn.ticket t2
JOIN vn.sale s ON s.ticketFk = t2.id
JOIN vn.item i ON i.id = s.itemFk
JOIN vn.ticketState ts ON ts.ticketFk = t2.id
JOIN vn.state st ON st.id = ts.stateFk
LEFT JOIN vn.itemPackingType ipt ON ipt.code = i.itemPackingTypeFk
WHERE t2.shipped BETWEEN vDateToAdvance AND util.dayend(vDateToAdvance)
AND t2.warehouseFk = vWarehouseFk
GROUP BY t2.id) t2 ON t2.addressFk = t.addressFk
JOIN vn.sale s ON s.ticketFk = t.id
JOIN vn.item i ON i.id = s.itemFk
LEFT JOIN vn.itemPackingType ipt ON ipt.code = i.itemPackingTypeFk
LEFT JOIN tmp.stock st ON st.itemFk = s.itemFk
WHERE t.shipped BETWEEN vDateFuture AND util.dayend(vDateFuture)
AND t.warehouseFk = vWarehouseFk
GROUP BY t.id;
DROP TEMPORARY TABLE tmp.stock;
END$$
DELIMITER ;
INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId)
VALUES
('Ticket', 'getTicketsAdvance', 'READ', 'ALLOW', 'ROLE', 'employee');

View File

@ -0,0 +1,73 @@
DROP PROCEDURE IF EXISTS `vn`.`ticket_canbePostponed`;
DELIMITER $$
$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_canbePostponed`(vOriginDated DATE, vFutureDated DATE, vWarehouseFk INT)
BEGIN
/**
* Devuelve un listado de tickets susceptibles de fusionarse con otros tickets en el futuro
*
* @param vOriginDated Fecha en cuestión
* @param vFutureDated Fecha en el futuro a sondear
* @param vWarehouseFk Identificador de vn.warehouse
*/
DROP TEMPORARY TABLE IF EXISTS tmp.filter;
CREATE TEMPORARY TABLE tmp.filter
(INDEX (id))
SELECT sv.ticketFk id,
sub2.id futureId,
GROUP_CONCAT(DISTINCT i.itemPackingTypeFk ORDER BY i.itemPackingTypeFk) ipt,
CAST(sum(litros) AS DECIMAL(10,0)) liters,
CAST(count(*) AS DECIMAL(10,0)) `lines`,
st.name state,
sub2.iptd futureIpt,
sub2.state futureState,
t.clientFk,
t.warehouseFk,
ts.alertLevel,
t.shipped,
sub2.shipped futureShipped,
t.workerFk,
st.code stateCode,
sub2.code futureStateCode
FROM vn.saleVolume sv
JOIN vn.sale s ON s.id = sv.saleFk
JOIN vn.item i ON i.id = s.itemFk
JOIN vn.ticket t ON t.id = sv.ticketFk
JOIN vn.address a ON a.id = t.addressFk
JOIN vn.province p ON p.id = a.provinceFk
JOIN vn.country c ON c.id = p.countryFk
JOIN vn.ticketState ts ON ts.ticketFk = t.id
JOIN vn.state st ON st.id = ts.stateFk
JOIN vn.alertLevel al ON al.id = ts.alertLevel
LEFT JOIN vn.ticketParking tp ON tp.ticketFk = t.id
LEFT JOIN (
SELECT *
FROM (
SELECT
t.addressFk,
t.id,
t.shipped,
st.name state,
st.code code,
GROUP_CONCAT(DISTINCT i.itemPackingTypeFk ORDER BY i.itemPackingTypeFk) iptd
FROM vn.ticket t
JOIN vn.ticketState ts ON ts.ticketFk = t.id
JOIN vn.state st ON st.id = ts.stateFk
JOIN vn.sale s ON s.ticketFk = t.id
JOIN vn.item i ON i.id = s.itemFk
WHERE t.shipped BETWEEN vFutureDated
AND util.dayend(vFutureDated)
AND t.warehouseFk = vWarehouseFk
GROUP BY t.id
) sub
GROUP BY sub.addressFk
) sub2 ON sub2.addressFk = t.addressFk AND t.id != sub2.id
WHERE t.shipped BETWEEN vOriginDated AND util.dayend(vOriginDated)
AND t.warehouseFk = vWarehouseFk
AND al.code = 'FREE'
AND tp.ticketFk IS NULL
GROUP BY sv.ticketFk
HAVING futureId;
END$$
DELIMITER ;

View File

@ -0,0 +1,2 @@
DROP PROCEDURE IF EXISTS `ticket_split`;
DROP PROCEDURE IF EXISTS `ticket_merge`;

View File

@ -0,0 +1,4 @@
INSERT INTO `util`.`notification` (id, name, description) VALUES(3, 'book-entries-imported-incorrectly', 'accounting entries exported incorrectly');
INSERT INTO `util`.`notificationAcl` (notificationFk, roleFk) VALUES(3, 5);
INSERT IGNORE INTO `util`.`notificationSubscription` (notificationFk, userFk) VALUES(3, 19663);

View File

@ -0,0 +1,7 @@
CREATE TABLE `vn`.`stateI18n` (
`stateFk` tinyint(3) unsigned NOT NULL,
`lang` char(2) NOT NULL,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`stateFk`, `lang`),
CONSTRAINT `stateI18n_state_id` FOREIGN KEY (`stateFk`) REFERENCES `vn`.`state` (`id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;

View File

@ -0,0 +1,60 @@
UPDATE salix.module t
SET t.code = 'supplier'
WHERE t.code LIKE 'Suppliers' ESCAPE '#';
UPDATE salix.module t
SET t.code = 'travel'
WHERE t.code LIKE 'Travels' ESCAPE '#';
UPDATE salix.module t
SET t.code = 'ticket'
WHERE t.code LIKE 'Tickets' ESCAPE '#';
UPDATE salix.module t
SET t.code = 'zone'
WHERE t.code LIKE 'Zones' ESCAPE '#';
UPDATE salix.module t
SET t.code = 'monitor'
WHERE t.code LIKE 'Monitors' ESCAPE '#';
UPDATE salix.module t
SET t.code = 'entry'
WHERE t.code LIKE 'Entries' ESCAPE '#';
UPDATE salix.module t
SET t.code = 'invoiceIn'
WHERE t.code LIKE 'Invoices in' ESCAPE '#';
UPDATE salix.module t
SET t.code = 'customer'
WHERE t.code LIKE 'Clients' ESCAPE '#';
UPDATE salix.module t
SET t.code = 'route'
WHERE t.code LIKE 'Routes' ESCAPE '#';
UPDATE salix.module t
SET t.code = 'item'
WHERE t.code LIKE 'Items' ESCAPE '#';
UPDATE salix.module t
SET t.code = 'claim'
WHERE t.code LIKE 'Claims' ESCAPE '#';
UPDATE salix.module t
SET t.code = 'user'
WHERE t.code LIKE 'Users' ESCAPE '#';
UPDATE salix.module t
SET t.code = 'invoiceOut'
WHERE t.code LIKE 'Invoices out' ESCAPE '#';
UPDATE salix.module t
SET t.code = 'order'
WHERE t.code LIKE 'Orders' ESCAPE '#';
UPDATE salix.module t
SET t.code = 'worker'
WHERE t.code LIKE 'Workers' ESCAPE '#';

View File

@ -0,0 +1,73 @@
INSERT INTO
`vn`.`stateI18n` (`stateFk`, `lang`, `name`)
VALUES
(1, 'en', 'Fix'),
(1, 'es', 'Arreglar'),
(2, 'en', 'Free'),
(2, 'es', 'Libre'),
(3, 'en', 'OK'),
(3, 'es', 'OK'),
(4, 'en', 'Printed'),
(4, 'es', 'Impreso'),
(5, 'en', 'Preparation'),
(5, 'es', 'Preparación'),
(6, 'en', 'In Review'),
(6, 'es', 'En Revisión'),
(7, 'en', 'Unfinished'),
(7, 'es', 'Sin Acabar'),
(8, 'en', 'Reviewed'),
(8, 'es', 'Revisado'),
(9, 'en', 'Fitting'),
(9, 'es', 'Encajando'),
(10, 'en', 'Fitted'),
(10, 'es', 'Encajado'),
(11, 'en', 'Billed'),
(11, 'es', 'Facturado'),
(12, 'en', 'Blocked'),
(12, 'es', 'Bloqueado'),
(13, 'en', 'In Delivery'),
(13, 'es', 'En Reparto'),
(14, 'en', 'Prepared'),
(14, 'es', 'Preparado'),
(15, 'en', 'Pending Collection'),
(15, 'es', 'Pendiente de Recogida'),
(16, 'en', 'Delivered'),
(16, 'es', 'Entregado'),
(20, 'en', 'Assigned'),
(20, 'es', 'Asignado'),
(21, 'en', 'Returned'),
(21, 'es', 'Retornado'),
(22, 'en', 'Pending to extend'),
(22, 'es', 'Pendiente ampliar'),
(23, 'en', 'URGENT'),
(23, 'es', 'URGENTE'),
(24, 'en', 'Chained'),
(24, 'es', 'Encadenado'),
(25, 'en', 'Shipping'),
(25, 'es', 'Embarcando'),
(26, 'en', 'Preparation'),
(26, 'es', 'Preparación previa'),
(27, 'en', 'Assisted preparation'),
(27, 'es', 'Preparación asistida'),
(28, 'en', 'Preparation OK'),
(28, 'es', 'Previa OK'),
(29, 'en', 'Preparation Printed'),
(29, 'es', 'Previa Impreso'),
(30, 'en', 'Shipped'),
(30, 'es', 'Embarcado'),
(31, 'en', 'Stowaway printed'),
(31, 'es', 'Polizón Impreso'),
(32, 'en', 'Stowaway OK'),
(32, 'es', 'Polizón OK'),
(33, 'en', 'Auto_Printed'),
(33, 'es', 'Auto_Impreso'),
(34, 'en', 'Pending payment'),
(34, 'es', 'Pendiente de pago'),
(35, 'en', 'Half-Embedded'),
(35, 'es', 'Semi-Encajado'),
(36, 'en', 'Preparation Reviewing'),
(36, 'es', 'Previa Revisando'),
(37, 'en', 'Preparation Reviewed'),
(37, 'es', 'Previa Revisado'),
(38, 'en', 'Preparation Chamber'),
(38, 'es', 'Preparación Cámara');

View File

@ -0,0 +1,16 @@
UPDATE `vn`.starredModule SET moduleFk = 'customer' WHERE moduleFk = 'Clients';
UPDATE `vn`.starredModule SET moduleFk = 'ticket' WHERE moduleFk = 'Tickets';
UPDATE `vn`.starredModule SET moduleFk = 'route' WHERE moduleFk = 'Routes';
UPDATE `vn`.starredModule SET moduleFk = 'zone' WHERE moduleFk = 'Zones';
UPDATE `vn`.starredModule SET moduleFk = 'order' WHERE moduleFk = 'Orders';
UPDATE `vn`.starredModule SET moduleFk = 'claim' WHERE moduleFk = 'Claims';
UPDATE `vn`.starredModule SET moduleFk = 'item' WHERE moduleFk = 'Items';
UPDATE `vn`.starredModule SET moduleFk = 'worker' WHERE moduleFk = 'Workers';
UPDATE `vn`.starredModule SET moduleFk = 'entry' WHERE moduleFk = 'Entries';
UPDATE `vn`.starredModule SET moduleFk = 'invoiceOut' WHERE moduleFk = 'Invoices out';
UPDATE `vn`.starredModule SET moduleFk = 'invoiceIn' WHERE moduleFk = 'Invoices in';
UPDATE `vn`.starredModule SET moduleFk = 'monitor' WHERE moduleFk = 'Monitors';
UPDATE `vn`.starredModule SET moduleFk = 'user' WHERE moduleFk = 'Users';
UPDATE `vn`.starredModule SET moduleFk = 'supplier' WHERE moduleFk = 'Suppliers';
UPDATE `vn`.starredModule SET moduleFk = 'travel' WHERE moduleFk = 'Travels';
UPDATE `vn`.starredModule SET moduleFk = 'shelving' WHERE moduleFk = 'Shelvings';

View File

File diff suppressed because one or more lines are too long

View File

@ -60,7 +60,7 @@ INSERT INTO `vn`.`educationLevel` (`id`, `name`)
INSERT INTO `vn`.`worker`(`id`,`code`, `firstName`, `lastName`, `userFk`, `bossFk`)
SELECT id,UPPER(LPAD(role, 3, '0')), name, name, id, 9
FROM `vn`.`user`;
FROM `account`.`user`;
UPDATE `vn`.`worker` SET bossFk = NULL WHERE id = 20;
UPDATE `vn`.`worker` SET bossFk = 20 WHERE id = 1 OR id = 9;
@ -105,20 +105,8 @@ INSERT INTO `account`.`mailForward`(`account`, `forwardTo`)
VALUES
(1, 'employee@domain.local');
INSERT INTO `vn`.`printer` (`id`, `name`, `path`, `isLabeler`)
VALUES
(1, 'printer1', 'path1', 0),
(2, 'printer2', 'path2', 1);
INSERT INTO `vn`.`worker`(`id`, `code`, `firstName`, `lastName`, `userFk`,`bossFk`, `phone`, `sectorFk`, `labelerFk`)
VALUES
(1106, 'LGN', 'David Charles', 'Haller', 1106, 19, 432978106, NULL, NULL),
(1107, 'ANT', 'Hank' , 'Pym' , 1107, 19, 432978107, NULL, 1),
(1108, 'DCX', 'Charles' , 'Xavier', 1108, 19, 432978108, 1, NULL),
(1109, 'HLK', 'Bruce' , 'Banner', 1109, 19, 432978109, 1, 2),
(1110, 'JJJ', 'Jessica' , 'Jones' , 1110, 19, 432978110, 2, 1);
INSERT INTO `vn`.`currency`(`id`, `code`, `name`, `ratio`)
VALUES
(1, 'EUR', 'Euro', 1),
@ -159,6 +147,19 @@ INSERT INTO `vn`.`sector`(`id`, `description`, `warehouseFk`, `isPreviousPrepare
(1, 'First sector', 1, 1, 'FIRST'),
(2, 'Second sector', 2, 0, 'SECOND');
INSERT INTO `vn`.`printer` (`id`, `name`, `path`, `isLabeler`, `sectorFk`)
VALUES
(1, 'printer1', 'path1', 0, 1),
(2, 'printer2', 'path2', 1, 1);
INSERT INTO `vn`.`worker`(`id`, `code`, `firstName`, `lastName`, `userFk`,`bossFk`, `phone`, `sectorFk`, `labelerFk`)
VALUES
(1106, 'LGN', 'David Charles', 'Haller', 1106, 19, 432978106, NULL, NULL),
(1107, 'ANT', 'Hank' , 'Pym' , 1107, 19, 432978107, NULL, NULL),
(1108, 'DCX', 'Charles' , 'Xavier', 1108, 19, 432978108, 1, NULL),
(1109, 'HLK', 'Bruce' , 'Banner', 1109, 19, 432978109, 1, NULL),
(1110, 'JJJ', 'Jessica' , 'Jones' , 1110, 19, 432978110, 2, NULL);
INSERT INTO `vn`.`parking` (`id`, `column`, `row`, `sectorFk`, `code`, `pickingOrder`)
VALUES
('1', 700, '01', 1, '700-01', 70001),
@ -216,18 +217,18 @@ INSERT INTO `vn`.`deliveryMethod`(`id`, `code`, `description`)
(3, 'PICKUP', 'Recogida'),
(4, 'OTHER', 'Otros');
INSERT INTO `vn`.`agency`(`id`, `name`, `warehouseFk`, `bankFk__`, `warehouseAliasFk`)
INSERT INTO `vn`.`agency`(`id`, `name`, `warehouseFk`, `warehouseAliasFk`)
VALUES
(1, 'inhouse pickup' , 1, 1, 1),
(2, 'Super-Man delivery' , 1, 1, 1),
(3, 'Teleportation device' , 1, 1, 1),
(4, 'Entanglement' , 1, 1, 1),
(5, 'Quantum break device' , 1, 1, 1),
(6, 'Walking' , 1, 1, 1),
(7, 'Gotham247' , 1, 1, 1),
(8, 'Gotham247Expensive' , 1, 1, 1),
(9, 'Refund' , 1, 1, 1),
(10, 'Other agency' , 1, 1, 1);
(1, 'inhouse pickup' , 1, 1),
(2, 'Super-Man delivery' , 1, 1),
(3, 'Teleportation device' , 1, 1),
(4, 'Entanglement' , 1, 1),
(5, 'Quantum break device' , 1, 1),
(6, 'Walking' , 1, 1),
(7, 'Gotham247' , 1, 1),
(8, 'Gotham247Expensive' , 1, 1),
(9, 'Refund' , 1, 1),
(10, 'Other agency' , 1, 1);
UPDATE `vn`.`agencyMode` SET `id` = 1 WHERE `name` = 'inhouse pickup';
UPDATE `vn`.`agencyMode` SET `id` = 2 WHERE `name` = 'Super-Man delivery';
@ -689,7 +690,8 @@ INSERT INTO `vn`.`ticket`(`id`, `priority`, `agencyModeFk`,`warehouseFk`,`routeF
(27 ,NULL, 8, 1, NULL, util.VN_CURDATE(), util.VN_CURDATE(), 1101, 'Wolverine', 1, NULL, 0, 1, 5, 1, util.VN_CURDATE()),
(28, 1, 8, 1, 1, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), 1103, 'Phone Box', 123, NULL, 0, 1, 5, 1, util.VN_CURDATE()),
(29, 1, 8, 1, 1, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), 1103, 'Phone Box', 123, NULL, 0, 1, 5, 1, util.VN_CURDATE()),
(30, 1, 8, 1, 1, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), 1103, 'Phone Box', 123, NULL, 0, 1, 5, 1, util.VN_CURDATE());
(30, 1, 8, 1, 1, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), 1103, 'Phone Box', 123, NULL, 0, 1, 5, 1, util.VN_CURDATE()),
(31, 1, 8, 1, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), DATE_ADD(util.VN_CURDATE(), INTERVAL + 2 DAY), 1103, 'Phone Box', 123, NULL, 0, 1, 5, 1, util.VN_CURDATE());
INSERT INTO `vn`.`ticketObservation`(`id`, `ticketFk`, `observationTypeFk`, `description`)
VALUES
@ -921,21 +923,21 @@ INSERT INTO `vn`.`expeditionStateType`(`id`, `description`, `code`)
(3, 'Perdida', 'LOST');
INSERT INTO `vn`.`expedition`(`id`, `agencyModeFk`, `ticketFk`, `freightItemFk`, `created`, `itemFk__`, `counter`, `workerFk`, `externalId`, `packagingFk`, `stateTypeFk`, `hostFk`)
INSERT INTO `vn`.`expedition`(`id`, `agencyModeFk`, `ticketFk`, `freightItemFk`, `created`, `counter`, `workerFk`, `externalId`, `packagingFk`, `stateTypeFk`, `hostFk`)
VALUES
(1, 1, 1, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 15, 1, 18, 'UR9000006041', 94, 1, 'pc1'),
(2, 1, 1, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 16, 2, 18, 'UR9000006041', 94, 1, NULL),
(3, 1, 1, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), NULL, 3, 18, 'UR9000006041', 94, 2, NULL),
(4, 1, 1, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), NULL, 4, 18, 'UR9000006041', 94, 2, NULL),
(5, 1, 2, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), NULL, 1, 18, NULL, 94, 3, NULL),
(6, 7, 3, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH), NULL, 1, 18, NULL, 94, 3, NULL),
(7, 2, 4, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -3 MONTH), NULL, 1, 18, NULL, 94, NULL,NULL),
(8, 3, 5, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -4 MONTH), NULL, 1, 18, NULL, 94, 1, NULL),
(9, 3, 6, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), NULL, 1, 18, NULL, 94, 2, NULL),
(10, 7, 7, 71, NOW(), NULL, 1, 18, NULL, 94, 3, NULL),
(11, 7, 8, 71, NOW(), NULL, 1, 18, NULL, 94, 3, NULL),
(12, 7, 9, 71, NOW(), NULL, 1, 18, NULL, 94, 3, NULL),
(13, 1, 10,71, NOW(), NULL, 1, 18, NULL, 94, 3, NULL);
(1, 1, 1, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 18, 'UR9000006041', 94, 1, 'pc1'),
(2, 1, 1, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 2, 18, 'UR9000006041', 94, 1, NULL),
(3, 1, 1, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 3, 18, 'UR9000006041', 94, 2, NULL),
(4, 1, 1, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 4, 18, 'UR9000006041', 94, 2, NULL),
(5, 1, 2, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 18, NULL, 94, 3, NULL),
(6, 7, 3, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH), 1, 18, NULL, 94, 3, NULL),
(7, 2, 4, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -3 MONTH), 1, 18, NULL, 94, NULL,NULL),
(8, 3, 5, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -4 MONTH), 1, 18, NULL, 94, 1, NULL),
(9, 3, 6, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 18, NULL, 94, 2, NULL),
(10, 7, 7, 71, NOW(), 1, 18, NULL, 94, 3, NULL),
(11, 7, 8, 71, NOW(), 1, 18, NULL, 94, 3, NULL),
(12, 7, 9, 71, NOW(), 1, 18, NULL, 94, 3, NULL),
(13, 1, 10,71, NOW(), 1, 18, NULL, 94, 3, NULL);
INSERT INTO `vn`.`expeditionState`(`id`, `created`, `expeditionFk`, `typeFk`, `userFk`)
@ -990,7 +992,8 @@ INSERT INTO `vn`.`sale`(`id`, `itemFk`, `ticketFk`, `concept`, `quantity`, `pric
(33, 5, 14, 'Ranged weapon pistol 9mm', 50, 1.79, 0, 0, 0, util.VN_CURDATE()),
(34, 4, 28, 'Melee weapon heavy shield 1x0.5m', 20, 1.72, 0, 0, 0, util.VN_CURDATE()),
(35, 4, 29, 'Melee weapon heavy shield 1x0.5m', 20, 1.72, 0, 0, 0, util.VN_CURDATE()),
(36, 4, 30, 'Melee weapon heavy shield 1x0.5m', 20, 1.72, 0, 0, 0, util.VN_CURDATE());
(36, 4, 30, 'Melee weapon heavy shield 1x0.5m', 20, 1.72, 0, 0, 0, util.VN_CURDATE()),
(37, 4, 31, 'Melee weapon heavy shield 1x0.5m', 20, 1.72, 0, 0, 0, util.VN_CURDATE());
INSERT INTO `vn`.`saleChecked`(`saleFk`, `isChecked`)
VALUES
@ -1132,11 +1135,11 @@ INSERT INTO `vn`.`saleComponent`(`saleFk`, `componentFk`, `value`)
(32, 36, -92.324),
(32, 39, 0.994);
INSERT INTO `vn`.`itemShelving` (`itemFk`, `shelvingFk`, `shelve`, `visible`, `grouping`, `packing`, `userFk`)
INSERT INTO `vn`.`itemShelving` (`itemFk`, `shelvingFk`, `visible`, `grouping`, `packing`, `userFk`)
VALUES
(2, 'GVC', 'A', 1, 1, 1, 1106),
(4, 'HEJ', 'A', 1, 1, 1, 1106),
(1, 'UXN', 'A', 2, 12, 12, 1106);
(2, 'GVC', 1, 1, 1, 1106),
(4, 'HEJ', 1, 1, 1, 1106),
(1, 'UXN', 2, 12, 12, 1106);
INSERT INTO `vn`.`itemShelvingSale` (`itemShelvingFk`, `saleFk`, `quantity`, `created`, `userFk`)
VALUES
@ -1332,9 +1335,9 @@ INSERT INTO `vn`.`itemTypeTag`(`id`, `itemTypeFk`, `tagFk`, `priority`)
CALL `vn`.`itemRefreshTags`(NULL);
INSERT INTO `vn`.`itemLog` (`id`, `originFk`, `userFk`, `action`, `description`)
INSERT INTO `vn`.`itemLog` (`id`, `originFk`, `userFk`, `action`, `description`, `changedModel`, `oldInstance`, `newInstance`, `changedModelId`, `changedModelValue`)
VALUES
('1', '1', '1', 'insert', 'We made a change!');
('1', '1', '1', 'insert', 'We made a change!', 'Item', '{}', '{}', 1, '1');
INSERT INTO `vn`.`recovery`(`id`, `clientFk`, `started`, `finished`, `amount`, `period`)
VALUES
@ -1377,16 +1380,16 @@ INSERT INTO `vn`.`travel`(`id`,`shipped`, `landed`, `warehouseInFk`, `warehouseO
(7, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 5, 4, 1, 50.00, 500, 'seventh travel', 2, 1),
(8, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 5, 1, 1, 50.00, 500, 'eight travel', 1, 2);
INSERT INTO `vn`.`entry`(`id`, `supplierFk`, `created`, `travelFk`, `isConfirmed`, `companyFk`, `ref`,`isExcludedFromAvailable`, `isRaid`, `notes`, `evaNotes`)
INSERT INTO `vn`.`entry`(`id`, `supplierFk`, `created`, `travelFk`, `isConfirmed`, `companyFk`, `invoiceNumber`, `reference`, `isExcludedFromAvailable`, `isRaid`, `notes`, `evaNotes`)
VALUES
(1, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 1, 442, 'Movement 1', 0, 0, '', ''),
(2, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 2, 0, 442, 'Movement 2', 0, 0, 'this is the note two', 'observation two'),
(3, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 3, 0, 442, 'Movement 3', 0, 0, 'this is the note three', 'observation three'),
(4, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 2, 0, 69, 'Movement 4', 0, 0, 'this is the note four', 'observation four'),
(5, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 5, 0, 442, 'Movement 5', 0, 0, 'this is the note five', 'observation five'),
(6, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 6, 0, 442, 'Movement 6', 0, 0, 'this is the note six', 'observation six'),
(7, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 7, 0, 442, 'Movement 7', 0, 0, 'this is the note seven', 'observation seven'),
(8, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 7, 0, 442, 'Movement 8', 1, 1, '', '');
(1, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 1, 442, 'IN2001', 'Movement 1', 0, 0, '', ''),
(2, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 2, 0, 442, 'IN2002', 'Movement 2', 0, 0, 'this is the note two', 'observation two'),
(3, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 3, 0, 442, 'IN2003', 'Movement 3', 0, 0, 'this is the note three', 'observation three'),
(4, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 2, 0, 69, 'IN2004', 'Movement 4', 0, 0, 'this is the note four', 'observation four'),
(5, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 5, 0, 442, 'IN2005', 'Movement 5', 0, 0, 'this is the note five', 'observation five'),
(6, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 6, 0, 442, 'IN2006', 'Movement 6', 0, 0, 'this is the note six', 'observation six'),
(7, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 7, 0, 442, 'IN2007', 'Movement 7', 0, 0, 'this is the note seven', 'observation seven'),
(8, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 7, 0, 442, 'IN2008', 'Movement 8', 1, 1, '', '');
INSERT INTO `bs`.`waste`(`buyer`, `year`, `week`, `family`, `itemFk`, `itemTypeFk`, `saleTotal`, `saleWaste`, `rate`)
VALUES
@ -1406,23 +1409,23 @@ INSERT INTO `bs`.`waste`(`buyer`, `year`, `week`, `family`, `itemFk`, `itemTypeF
('HankPym', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 'Miscellaneous Accessories', 6, 1, '186', '0', '0.0'),
('HankPym', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 'Adhesives', 7, 1, '277', '0', '0.0');
INSERT INTO `vn`.`buy`(`id`,`entryFk`,`itemFk`,`buyingValue`,`quantity`,`packageFk`,`stickers`,`freightValue`,`packageValue`,`comissionValue`,`packing`,`grouping`,`groupingMode`,`location`,`price1`,`price2`,`price3`,`producer`,`printedStickers`,`isChecked`,`isIgnored`,`weight`, `created`)
INSERT INTO `vn`.`buy`(`id`,`entryFk`,`itemFk`,`buyingValue`,`quantity`,`packageFk`,`stickers`,`freightValue`,`packageValue`,`comissionValue`,`packing`,`grouping`,`groupingMode`,`location`,`price1`,`price2`,`price3`, `printedStickers`,`isChecked`,`isIgnored`,`weight`, `created`)
VALUES
(1, 1, 1, 50, 5000, 4, 1, 1.500, 1.500, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, NULL, 0, 1, 0, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH)),
(2, 2, 1, 50, 100, 4, 1, 1.500, 1.500, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, NULL, 0, 1, 0, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH)),
(3, 3, 1, 50, 100, 4, 1, 1.500, 1.500, 0.000, 1, 1, 0, NULL, 0.00, 99.6, 99.4, NULL, 0, 1, 0, 1, util.VN_CURDATE()),
(4, 2, 2, 5, 450, 3, 1, 1.000, 1.000, 0.000, 10, 10, 0, NULL, 0.00, 7.30, 7.00, NULL, 0, 1, 0, 2.5, util.VN_CURDATE()),
(5, 3, 3, 55, 500, 5, 1, 1.000, 1.000, 0.000, 1, 1, 0, NULL, 0.00, 78.3, 75.6, NULL, 0, 1, 0, 2.5, util.VN_CURDATE()),
(6, 4, 8, 50, 1000, 4, 1, 1.000, 1.000, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, NULL, 0, 1, 0, 2.5, util.VN_CURDATE()),
(7, 4, 9, 20, 1000, 3, 1, 0.500, 0.500, 0.000, 10, 10, 1, NULL, 0.00, 30.50, 29.00, NULL, 0, 1, 0, 2.5, util.VN_CURDATE()),
(8, 4, 4, 1.25, 1000, 3, 1, 0.500, 0.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, NULL, 0, 1, 0, 2.5, util.VN_CURDATE()),
(9, 4, 4, 1.25, 1000, 3, 1, 0.500, 0.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, NULL, 0, 1, 0, 4, util.VN_CURDATE()),
(10, 5, 1, 50, 10, 4, 1, 2.500, 2.500, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, NULL, 0, 1, 0, 4, util.VN_CURDATE()),
(11, 5, 4, 1.25, 10, 3, 1, 2.500, 2.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, NULL, 0, 1, 0, 4, util.VN_CURDATE()),
(12, 6, 4, 1.25, 0, 3, 1, 2.500, 2.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, NULL, 0, 1, 0, 4, util.VN_CURDATE()),
(13, 7, 1, 50, 0, 3, 1, 2.000, 2.000, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, NULL, 0, 1, 0, 4, util.VN_CURDATE()),
(14, 7, 2, 5, 0, 3, 1, 2.000, 2.000, 0.000, 10, 10, 1, NULL, 0.00, 7.30, 7.00, NULL, 0, 1, 0, 4, util.VN_CURDATE()),
(15, 7, 4, 1.25, 0, 3, 1, 2.000, 2.000, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, NULL, 0, 1, 0, 4, util.VN_CURDATE());
(1, 1, 1, 50, 5000, 4, 1, 1.500, 1.500, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0, 1, 0, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH)),
(2, 2, 1, 50, 100, 4, 1, 1.500, 1.500, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0, 1, 0, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH)),
(3, 3, 1, 50, 100, 4, 1, 1.500, 1.500, 0.000, 1, 1, 0, NULL, 0.00, 99.6, 99.4, 0, 1, 0, 1, util.VN_CURDATE()),
(4, 2, 2, 5, 450, 3, 1, 1.000, 1.000, 0.000, 10, 10, 0, NULL, 0.00, 7.30, 7.00, 0, 1, 0, 2.5, util.VN_CURDATE()),
(5, 3, 3, 55, 500, 5, 1, 1.000, 1.000, 0.000, 1, 1, 0, NULL, 0.00, 78.3, 75.6, 0, 1, 0, 2.5, util.VN_CURDATE()),
(6, 4, 8, 50, 1000, 4, 1, 1.000, 1.000, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0, 1, 0, 2.5, util.VN_CURDATE()),
(7, 4, 9, 20, 1000, 3, 1, 0.500, 0.500, 0.000, 10, 10, 1, NULL, 0.00, 30.50, 29.00, 0, 1, 0, 2.5, util.VN_CURDATE()),
(8, 4, 4, 1.25, 1000, 3, 1, 0.500, 0.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, 0, 1, 0, 2.5, util.VN_CURDATE()),
(9, 4, 4, 1.25, 1000, 3, 1, 0.500, 0.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, 0, 1, 0, 4, util.VN_CURDATE()),
(10, 5, 1, 50, 10, 4, 1, 2.500, 2.500, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0, 1, 0, 4, util.VN_CURDATE()),
(11, 5, 4, 1.25, 10, 3, 1, 2.500, 2.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, 0, 1, 0, 4, util.VN_CURDATE()),
(12, 6, 4, 1.25, 0, 3, 1, 2.500, 2.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, 0, 1, 0, 4, util.VN_CURDATE()),
(13, 7, 1, 50, 0, 3, 1, 2.000, 2.000, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0, 1, 0, 4, util.VN_CURDATE()),
(14, 7, 2, 5, 0, 3, 1, 2.000, 2.000, 0.000, 10, 10, 1, NULL, 0.00, 7.30, 7.00, 0, 1, 0, 4, util.VN_CURDATE()),
(15, 7, 4, 1.25, 0, 3, 1, 2.000, 2.000, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, 0, 1, 0, 4, util.VN_CURDATE());
INSERT INTO `hedera`.`order`(`id`, `date_send`, `customer_id`, `delivery_method_id`, `agency_id`, `address_id`, `company_id`, `note`, `source_app`, `confirmed`,`total`, `date_make`, `first_row_stamp`, `confirm_date`)
VALUES
@ -1951,30 +1954,34 @@ INSERT INTO `vn`.`workerBusinessType` (`id`, `name`, `isFullTime`, `isPermanent`
(100, 'INDEFINIDO A TIEMPO COMPLETO', 1, 1, 1),
(109, 'CONVERSION DE TEMPORAL EN INDEFINIDO T.COMPLETO', 1, 1, 1);
INSERT INTO `vn`.`businessCategory` (`id`, `description`, `rate`)
VALUES
(1, 'basic employee', 1);
UPDATE `vn`.`business` b
SET `rate` = 7,
`workerBusinessCategoryFk` = 12,
`workerBusinessCategoryFk` = 1,
`workerBusinessTypeFk` = 100,
`amount` = 900.50
WHERE b.id = 1;
UPDATE `vn`.`business` b
SET `rate` = 7,
`workerBusinessCategoryFk` = 12,
`workerBusinessCategoryFk` = 1,
`workerBusinessTypeFk` = 100,
`amount` = 1263.03
WHERE b.id = 1106;
UPDATE `vn`.`business` b
SET `rate` = 7,
`workerBusinessCategoryFk` = 12,
`workerBusinessCategoryFk` = 1,
`workerBusinessTypeFk` = 100,
`amount` = 2000
WHERE b.id = 1107;
UPDATE `vn`.`business` b
SET `rate` = 7,
`workerBusinessCategoryFk` = 12,
`workerBusinessCategoryFk` = 1,
`workerBusinessTypeFk` = 100,
`amount` = 1500
WHERE b.id = 1108;
@ -2684,7 +2691,8 @@ INSERT INTO `util`.`notificationConfig`
INSERT INTO `util`.`notification` (`id`, `name`, `description`)
VALUES
(1, 'print-email', 'notification fixture one');
(1, 'print-email', 'notification fixture one'),
(4, 'supplier-pay-method-update', 'A supplier pay method has been updated');
INSERT INTO `util`.`notificationAcl` (`notificationFk`, `roleFk`)
VALUES
@ -2699,7 +2707,8 @@ INSERT INTO `util`.`notificationQueue` (`id`, `notificationFk`, `params`, `autho
INSERT INTO `util`.`notificationSubscription` (`notificationFk`, `userFk`)
VALUES
(1, 1109),
(1, 1110);
(1, 1110),
(3, 1109);
INSERT INTO `vn`.`routeConfig` (`id`, `defaultWorkCenterFk`)
VALUES
@ -2725,10 +2734,33 @@ UPDATE `account`.`user`
SET `hasGrant` = 1
WHERE `id` = 66;
INSERT INTO `vn`.`ticketLog` (`originFk`, userFk, `action`, changedModel, oldInstance, newInstance, changedModelId, `description`)
VALUES
(7, 18, 'update', 'Sale', '{"quantity":1}', '{"quantity":10}', 1, NULL),
(7, 18, 'update', 'Ticket', '{"quantity":1,"concept":"Chest ammo box"}', '{"quantity":10,"concept":"Chest ammo box"}', 1, NULL),
(7, 18, 'update', 'Sale', '{"price":3}', '{"price":5}', 1, NULL),
(7, 18, 'update', NULL, NULL, NULL, NULL, "Cambio cantidad Melee weapon heavy shield 1x0.5m de '5' a '10'");
INSERT INTO `vn`.`osTicketConfig` (`id`, `host`, `user`, `password`, `oldStatus`, `newStatusId`, `day`, `comment`, `hostDb`, `userDb`, `passwordDb`, `portDb`, `responseType`, `fromEmailId`, `replyTo`)
VALUES
(0, 'http://localhost:56596/scp', 'ostadmin', 'Admin1', 'open', 3, 60, 'Este CAU se ha cerrado automáticamente. Si el problema persiste responda a este mensaje.', 'localhost', 'osticket', 'osticket', 40003, 'reply', 1, 'all');
INSERT INTO `vn`.`mdbApp` (`app`, `baselineBranchFk`, `userFk`, `locked`)
VALUES
('foo', 'master', NULL, NULL),
('bar', 'test', 9, util.VN_NOW());
INSERT INTO `vn`.`ticketLog` (`id`, `originFk`, `userFk`, `action`, `changedModel`, `oldInstance`, `newInstance`, `changedModelId`)
VALUES
(1, 1, 9, 'insert', 'Ticket', '{}', '{"clientFk":1, "nickname": "Bat cave"}', 1);
INSERT INTO `salix`.`url` (`appName`, `environment`, `url`)
VALUES
('lilium', 'dev', 'http://localhost:8080/#/'),
('salix', 'dev', 'http://localhost:5000/#!/');
INSERT INTO `vn`.`payDemDetail` (`id`, `detail`)
VALUES
(1, 1);

File diff suppressed because it is too large Load Diff

View File

@ -41,6 +41,7 @@ dump_tables ${TABLES[@]}
TABLES=(
vn
agencyTermConfig
alertLevel
bookingPlanner
businessType

View File

@ -6,7 +6,6 @@ SCHEMAS=(
cache
edi
hedera
nst
pbx
postgresql
sage
@ -85,7 +84,6 @@ IGNORETABLES=(
--ignore-table=vn.warehouseJoined
--ignore-table=vn.workerTeam__
--ignore-table=vn.XDiario__
--ignore-table=sage.movConta
--ignore-table=sage.movContaCopia
)
mysqldump \

View File

@ -311,10 +311,12 @@ export default {
firstMandateText: 'vn-client-mandate vn-card vn-table vn-tbody > vn-tr'
},
clientLog: {
lastModificationPreviousValue: 'vn-client-log vn-table vn-td.before',
lastModificationCurrentValue: 'vn-client-log vn-table vn-td.after',
penultimateModificationPreviousValue: 'vn-client-log vn-table vn-tr:nth-child(2) vn-td.before',
penultimateModificationCurrentValue: 'vn-client-log vn-table vn-tr:nth-child(2) vn-td.after'
lastModificationPreviousValue: 'vn-client-log vn-tr table tr td.before',
lastModificationCurrentValue: 'vn-client-log vn-tr table tr td.after',
namePreviousValue: 'vn-client-log vn-tr table tr:nth-child(1) td.before',
nameCurrentValue: 'vn-client-log vn-tr table tr:nth-child(1) td.after',
activePreviousValue: 'vn-client-log vn-tr:nth-child(2) table tr:nth-child(2) td.before',
activeCurrentValue: 'vn-client-log vn-tr:nth-child(2) table tr:nth-child(2) td.after'
},
clientBalance: {
@ -518,7 +520,7 @@ export default {
},
itemLog: {
anyLineCreated: 'vn-item-log > vn-log vn-tbody > vn-tr',
fifthLineCreatedProperty: 'vn-item-log > vn-log vn-tbody > vn-tr:nth-child(5) > vn-td > vn-one:nth-child(3) > div span:nth-child(2)',
fifthLineCreatedProperty: 'vn-item-log > vn-log vn-tbody > vn-tr:nth-child(5) table tr:nth-child(3) td.after',
},
ticketSummary: {
header: 'vn-ticket-summary > vn-card > h5',
@ -711,9 +713,10 @@ export default {
ticketLog: {
firstTD: 'vn-ticket-log vn-table vn-td:nth-child(1)',
logButton: 'vn-left-menu a[ui-sref="ticket.card.log"]',
firstLogEntry: 'vn-ticket-log vn-data-viewer vn-tbody vn-tr',
changes: 'vn-ticket-log vn-data-viewer vn-tbody > vn-tr > vn-td:nth-child(7)',
id: 'vn-ticket-log vn-tr:nth-child(1) vn-one:nth-child(1) span'
user: 'vn-ticket-log vn-tbody vn-tr vn-td:nth-child(2)',
action: 'vn-ticket-log vn-tbody vn-tr vn-td:nth-child(4)',
changes: 'vn-ticket-log vn-data-viewer vn-tbody vn-tr table tr:nth-child(2) td.after',
id: 'vn-ticket-log vn-tr:nth-child(1) table tr:nth-child(1) td.before'
},
ticketService: {
addServiceButton: 'vn-ticket-service vn-icon-button[vn-tooltip="Add service"] > button',
@ -735,18 +738,16 @@ export default {
},
ticketFuture: {
openAdvancedSearchButton: 'vn-searchbar .append vn-icon[icon="arrow_drop_down"]',
originDated: 'vn-date-picker[label="Origin ETD"]',
futureDated: 'vn-date-picker[label="Destination ETD"]',
shipped: 'vn-date-picker[label="Origin date"]',
tfShipped: 'vn-date-picker[label="Destination date"]',
originDated: 'vn-date-picker[label="Origin date"]',
futureDated: 'vn-date-picker[label="Destination date"]',
linesMax: 'vn-textfield[label="Max Lines"]',
litersMax: 'vn-textfield[label="Max Liters"]',
ipt: 'vn-autocomplete[label="Origin IPT"]',
tfIpt: 'vn-autocomplete[label="Destination IPT"]',
futureIpt: 'vn-autocomplete[label="Destination IPT"]',
tableIpt: 'vn-autocomplete[name="ipt"]',
tableTfIpt: 'vn-autocomplete[name="tfIpt"]',
tableFutureIpt: 'vn-autocomplete[name="futureIpt"]',
state: 'vn-autocomplete[label="Origin Grouped State"]',
tfState: 'vn-autocomplete[label="Destination Grouped State"]',
futureState: 'vn-autocomplete[label="Destination Grouped State"]',
warehouseFk: 'vn-autocomplete[label="Warehouse"]',
problems: 'vn-check[label="With problems"]',
tableButtonSearch: 'vn-button[vn-tooltip="Search"]',
@ -755,9 +756,34 @@ export default {
firstCheck: 'tbody > tr:nth-child(1) > td > vn-check',
multiCheck: 'vn-multi-check',
tableId: 'vn-textfield[name="id"]',
tableTfId: 'vn-textfield[name="ticketFuture"]',
tableLiters: 'vn-textfield[name="litersMax"]',
tableLines: 'vn-textfield[name="linesMax"]',
tableFutureId: 'vn-textfield[name="futureId"]',
tableLiters: 'vn-textfield[name="liters"]',
tableLines: 'vn-textfield[name="lines"]',
submit: 'vn-submit[label="Search"]',
table: 'tbody > tr:not(.empty-rows)'
},
ticketAdvance: {
openAdvancedSearchButton: 'vn-searchbar .append vn-icon[icon="arrow_drop_down"]',
dateFuture: 'vn-date-picker[label="Origin date"]',
dateToAdvance: 'vn-date-picker[label="Destination date"]',
linesMax: 'vn-textfield[label="Max Lines"]',
litersMax: 'vn-textfield[label="Max Liters"]',
futureIpt: 'vn-autocomplete[label="Origin IPT"]',
ipt: 'vn-autocomplete[label="Destination IPT"]',
tableIpt: 'vn-autocomplete[name="ipt"]',
tableFutureIpt: 'vn-autocomplete[name="futureIpt"]',
futureState: 'vn-autocomplete[label="Origin Grouped State"]',
state: 'vn-autocomplete[label="Destination Grouped State"]',
warehouseFk: 'vn-autocomplete[label="Warehouse"]',
tableButtonSearch: 'vn-button[vn-tooltip="Search"]',
moveButton: 'vn-button[vn-tooltip="Advance tickets"]',
acceptButton: '.vn-confirm.shown button[response="accept"]',
multiCheck: 'vn-multi-check',
tableId: 'vn-textfield[name="id"]',
tableFutureId: 'vn-textfield[name="futureId"]',
tableLiters: 'vn-textfield[name="liters"]',
tableLines: 'vn-textfield[name="lines"]',
tableStock: 'vn-textfield[name="hasStock"]',
submit: 'vn-submit[label="Search"]',
table: 'tbody > tr:not(.empty-rows)'
},
@ -1100,7 +1126,7 @@ export default {
undoChanges: 'vn-travel-basic-data vn-button[label="Undo changes"]'
},
travelLog: {
firstLogFirstTD: 'vn-travel-log vn-tbody > vn-tr > vn-td:nth-child(1) > div'
firstLogFirstTD: 'vn-travel-log vn-tbody > vn-tr > vn-td:nth-child(5)'
},
travelThermograph: {
add: 'vn-travel-thermograph-index vn-float-button[icon="add"]',

View File

@ -1,7 +1,8 @@
import selectors from '../../helpers/selectors';
import getBrowser from '../../helpers/puppeteer';
describe('Login path', async() => {
// https://redmine.verdnatura.es/issues/4995 fix login
xdescribe('RecoverPassword path', async() => {
let browser;
let page;

View File

@ -67,22 +67,22 @@ describe('Client Edit web access path', () => {
});
it(`should confirm the last log shows the updated client name and no modifications on active checkbox`, async() => {
let lastModificationPreviousValue = await page
.waitToGetProperty(selectors.clientLog.lastModificationPreviousValue, 'innerText');
let lastModificationCurrentValue = await page
.waitToGetProperty(selectors.clientLog.lastModificationCurrentValue, 'innerText');
let namePreviousValue = await page
.waitToGetProperty(selectors.clientLog.namePreviousValue, 'innerText');
let nameCurrentValue = await page
.waitToGetProperty(selectors.clientLog.nameCurrentValue, 'innerText');
expect(lastModificationPreviousValue).toEqual('name MaxEisenhardt active false');
expect(lastModificationCurrentValue).toEqual('name Legion active false');
expect(namePreviousValue).toEqual('MaxEisenhardt');
expect(nameCurrentValue).toEqual('Legion');
});
it(`should confirm the penultimate log shows the updated active and no modifications on client name`, async() => {
let penultimateModificationPreviousValue = await page
.waitToGetProperty(selectors.clientLog.penultimateModificationPreviousValue, 'innerText');
let penultimateModificationCurrentValue = await page
.waitToGetProperty(selectors.clientLog.penultimateModificationCurrentValue, 'innerText');
let activePreviousValue = await page
.waitToGetProperty(selectors.clientLog.activePreviousValue, 'innerText');
let activeCurrentValue = await page
.waitToGetProperty(selectors.clientLog.activeCurrentValue, 'innerText');
expect(penultimateModificationPreviousValue).toEqual('name MaxEisenhardt active true');
expect(penultimateModificationCurrentValue).toEqual('name MaxEisenhardt active false');
expect(activePreviousValue).toEqual('✓');
expect(activeCurrentValue).toEqual('✗');
});
});

View File

@ -43,7 +43,7 @@ describe('Client log path', () => {
let lastModificationCurrentValue = await page.
waitToGetProperty(selectors.clientLog.lastModificationCurrentValue, 'innerText');
expect(lastModificationPreviousValue).toEqual('name DavidCharlesHaller');
expect(lastModificationCurrentValue).toEqual('name this is a test');
expect(lastModificationPreviousValue).toEqual('DavidCharlesHaller');
expect(lastModificationCurrentValue).toEqual('this is a test');
});
});

View File

@ -127,8 +127,8 @@ describe('Item regularize path', () => {
await page.waitForState('ticket.index');
});
it('should search for the ticket with id 31 once again', async() => {
await page.accessToSearchResult('31');
it('should search for the ticket missing once again', async() => {
await page.accessToSearchResult('Missing');
await page.waitForState('ticket.card.summary');
});

View File

@ -32,14 +32,17 @@ describe('Ticket expeditions and log path', () => {
it(`should confirm the expedition deleted is shown now in the ticket log`, async() => {
await page.accessToSection('ticket.card.log');
const firstLogEntry = await page
.waitToGetProperty(selectors.ticketLog.firstLogEntry, 'innerText');
const user = await page
.waitToGetProperty(selectors.ticketLog.user, 'innerText');
const action = await page
.waitToGetProperty(selectors.ticketLog.action, 'innerText');
const id = await page
.waitToGetProperty(selectors.ticketLog.id, 'innerText');
expect(firstLogEntry).toContain('production');
expect(firstLogEntry).toContain('Deletes');
expect(user).toContain('production');
expect(action).toContain('Deletes');
expect(id).toEqual('2');
});
});

View File

@ -55,6 +55,6 @@ describe('Ticket log path', () => {
const result = await page.waitToGetProperty(selectors.ticketLog.firstTD, 'innerText');
expect(result.length).toBeGreaterThan('20');
expect(result.length).toBeGreaterThan('15');
});
});

View File

@ -16,9 +16,6 @@ describe('Ticket Future path', () => {
await browser.close();
});
const now = new Date();
const tomorrow = new Date(now.getDate() + 1);
it('should show errors snackbar because of the required data', async() => {
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.warehouseFk);
@ -27,20 +24,6 @@ describe('Ticket Future path', () => {
expect(message.text).toContain('warehouseFk is a required argument');
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.litersMax);
await page.waitToClick(selectors.ticketFuture.submit);
message = await page.waitForSnackbar();
expect(message.text).toContain('litersMax is a required argument');
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.linesMax);
await page.waitToClick(selectors.ticketFuture.submit);
message = await page.waitForSnackbar();
expect(message.text).toContain('linesMax is a required argument');
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.futureDated);
await page.waitToClick(selectors.ticketFuture.submit);
@ -62,44 +45,13 @@ describe('Ticket Future path', () => {
await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
});
it('should search with the origin shipped today', async() => {
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.pickDate(selectors.ticketFuture.shipped, now);
await page.waitToClick(selectors.ticketFuture.submit);
await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
});
it('should search with the origin shipped tomorrow', async() => {
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.pickDate(selectors.ticketFuture.shipped, tomorrow);
await page.waitToClick(selectors.ticketFuture.submit);
await page.waitForNumberOfElements(selectors.ticketFuture.table, 0);
});
it('should search with the destination shipped today', async() => {
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.shipped);
await page.pickDate(selectors.ticketFuture.tfShipped, now);
await page.waitToClick(selectors.ticketFuture.submit);
await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
});
it('should search with the destination shipped tomorrow', async() => {
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.pickDate(selectors.ticketFuture.tfShipped, tomorrow);
await page.waitToClick(selectors.ticketFuture.submit);
await page.waitForNumberOfElements(selectors.ticketFuture.table, 0);
});
it('should search with the origin IPT', async() => {
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.shipped);
await page.clearInput(selectors.ticketFuture.tfShipped);
await page.clearInput(selectors.ticketFuture.ipt);
await page.clearInput(selectors.ticketFuture.tfIpt);
await page.clearInput(selectors.ticketFuture.futureIpt);
await page.clearInput(selectors.ticketFuture.state);
await page.clearInput(selectors.ticketFuture.tfState);
await page.clearInput(selectors.ticketFuture.futureState);
await page.autocompleteSearch(selectors.ticketFuture.ipt, 'Horizontal');
await page.waitToClick(selectors.ticketFuture.submit);
@ -109,14 +61,12 @@ describe('Ticket Future path', () => {
it('should search with the destination IPT', async() => {
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.shipped);
await page.clearInput(selectors.ticketFuture.tfShipped);
await page.clearInput(selectors.ticketFuture.ipt);
await page.clearInput(selectors.ticketFuture.tfIpt);
await page.clearInput(selectors.ticketFuture.futureIpt);
await page.clearInput(selectors.ticketFuture.state);
await page.clearInput(selectors.ticketFuture.tfState);
await page.clearInput(selectors.ticketFuture.futureState);
await page.autocompleteSearch(selectors.ticketFuture.tfIpt, 'Horizontal');
await page.autocompleteSearch(selectors.ticketFuture.futureIpt, 'Horizontal');
await page.waitToClick(selectors.ticketFuture.submit);
await page.waitForNumberOfElements(selectors.ticketFuture.table, 0);
});
@ -124,12 +74,10 @@ describe('Ticket Future path', () => {
it('should search with the origin grouped state', async() => {
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.shipped);
await page.clearInput(selectors.ticketFuture.tfShipped);
await page.clearInput(selectors.ticketFuture.ipt);
await page.clearInput(selectors.ticketFuture.tfIpt);
await page.clearInput(selectors.ticketFuture.futureIpt);
await page.clearInput(selectors.ticketFuture.state);
await page.clearInput(selectors.ticketFuture.tfState);
await page.clearInput(selectors.ticketFuture.futureState);
await page.autocompleteSearch(selectors.ticketFuture.state, 'Free');
await page.waitToClick(selectors.ticketFuture.submit);
@ -139,24 +87,20 @@ describe('Ticket Future path', () => {
it('should search with the destination grouped state', async() => {
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.shipped);
await page.clearInput(selectors.ticketFuture.tfShipped);
await page.clearInput(selectors.ticketFuture.ipt);
await page.clearInput(selectors.ticketFuture.tfIpt);
await page.clearInput(selectors.ticketFuture.futureIpt);
await page.clearInput(selectors.ticketFuture.state);
await page.clearInput(selectors.ticketFuture.tfState);
await page.clearInput(selectors.ticketFuture.futureState);
await page.autocompleteSearch(selectors.ticketFuture.tfState, 'Free');
await page.autocompleteSearch(selectors.ticketFuture.futureState, 'Free');
await page.waitToClick(selectors.ticketFuture.submit);
await page.waitForNumberOfElements(selectors.ticketFuture.table, 0);
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.shipped);
await page.clearInput(selectors.ticketFuture.tfShipped);
await page.clearInput(selectors.ticketFuture.ipt);
await page.clearInput(selectors.ticketFuture.tfIpt);
await page.clearInput(selectors.ticketFuture.futureIpt);
await page.clearInput(selectors.ticketFuture.state);
await page.clearInput(selectors.ticketFuture.tfState);
await page.clearInput(selectors.ticketFuture.futureState);
await page.waitToClick(selectors.ticketFuture.submit);
await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
@ -176,7 +120,7 @@ describe('Ticket Future path', () => {
it('should search in smart-table with an ID Destination', async() => {
await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
await page.write(selectors.ticketFuture.tableTfId, '12');
await page.write(selectors.ticketFuture.tableFutureId, '12');
await page.keyboard.press('Enter');
await page.waitForNumberOfElements(selectors.ticketFuture.table, 5);
@ -199,7 +143,7 @@ describe('Ticket Future path', () => {
it('should search in smart-table with an IPT Destination', async() => {
await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
await page.autocompleteSearch(selectors.ticketFuture.tableTfIpt, 'Vertical');
await page.autocompleteSearch(selectors.ticketFuture.tableFutureIpt, 'Vertical');
await page.waitForNumberOfElements(selectors.ticketFuture.table, 1);
await page.waitToClick(selectors.ticketFuture.tableButtonSearch);

View File

@ -0,0 +1,162 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Ticket Advance path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('employee', 'ticket');
await page.accessToSection('ticket.advance');
});
afterAll(async() => {
await browser.close();
});
it('should show errors snackbar because of the required data', async() => {
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.clearInput(selectors.ticketAdvance.warehouseFk);
await page.waitToClick(selectors.ticketAdvance.submit);
let message = await page.waitForSnackbar();
expect(message.text).toContain('warehouseFk is a required argument');
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.clearInput(selectors.ticketAdvance.dateToAdvance);
await page.waitToClick(selectors.ticketAdvance.submit);
message = await page.waitForSnackbar();
expect(message.text).toContain('dateToAdvance is a required argument');
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.clearInput(selectors.ticketAdvance.dateFuture);
await page.waitToClick(selectors.ticketAdvance.submit);
message = await page.waitForSnackbar();
expect(message.text).toContain('dateFuture is a required argument');
});
it('should search with the required data', async() => {
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.waitToClick(selectors.ticketAdvance.submit);
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1);
});
it('should search with the origin IPT', async() => {
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.autocompleteSearch(selectors.ticketAdvance.ipt, 'Horizontal');
await page.waitToClick(selectors.ticketAdvance.submit);
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 0);
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.clearInput(selectors.ticketAdvance.ipt);
await page.waitToClick(selectors.ticketAdvance.submit);
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1);
});
it('should search with the destination IPT', async() => {
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.autocompleteSearch(selectors.ticketAdvance.futureIpt, 'Horizontal');
await page.waitToClick(selectors.ticketAdvance.submit);
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 0);
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.clearInput(selectors.ticketAdvance.futureIpt);
await page.waitToClick(selectors.ticketAdvance.submit);
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1);
});
it('should search with the origin grouped state', async() => {
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.autocompleteSearch(selectors.ticketAdvance.futureState, 'Free');
await page.waitToClick(selectors.ticketAdvance.submit);
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1);
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.clearInput(selectors.ticketAdvance.futureState);
await page.waitToClick(selectors.ticketAdvance.submit);
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1);
});
it('should search with the destination grouped state', async() => {
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.autocompleteSearch(selectors.ticketAdvance.state, 'Free');
await page.waitToClick(selectors.ticketAdvance.submit);
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 0);
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.clearInput(selectors.ticketAdvance.state);
await page.waitToClick(selectors.ticketAdvance.submit);
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1);
});
it('should search in smart-table with an IPT Origin', async() => {
await page.waitToClick(selectors.ticketAdvance.tableButtonSearch);
await page.autocompleteSearch(selectors.ticketAdvance.tableFutureIpt, 'Vertical');
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1);
await page.waitToClick(selectors.ticketAdvance.tableButtonSearch);
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.waitToClick(selectors.ticketAdvance.submit);
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1);
});
it('should search in smart-table with an IPT Destination', async() => {
await page.waitToClick(selectors.ticketAdvance.tableButtonSearch);
await page.autocompleteSearch(selectors.ticketAdvance.tableIpt, 'Vertical');
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1);
await page.waitToClick(selectors.ticketAdvance.tableButtonSearch);
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.waitToClick(selectors.ticketAdvance.submit);
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1);
});
it('should search in smart-table with stock', async() => {
await page.waitToClick(selectors.ticketAdvance.tableButtonSearch);
await page.write(selectors.ticketAdvance.tableStock, '5');
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 2);
await page.waitToClick(selectors.ticketAdvance.tableButtonSearch);
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.waitToClick(selectors.ticketAdvance.submit);
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1);
});
it('should search in smart-table with especified Lines', async() => {
await page.waitToClick(selectors.ticketAdvance.tableButtonSearch);
await page.write(selectors.ticketAdvance.tableLines, '0');
await page.keyboard.press('Enter');
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1);
await page.waitToClick(selectors.ticketAdvance.tableButtonSearch);
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.waitToClick(selectors.ticketAdvance.submit);
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1);
});
it('should search in smart-table with especified Liters', async() => {
await page.waitToClick(selectors.ticketAdvance.tableButtonSearch);
await page.write(selectors.ticketAdvance.tableLiters, '0');
await page.keyboard.press('Enter');
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1);
await page.waitToClick(selectors.ticketAdvance.tableButtonSearch);
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.waitToClick(selectors.ticketAdvance.submit);
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1);
});
it('should check the three last tickets and move to the future', async() => {
await page.waitToClick(selectors.ticketAdvance.multiCheck);
await page.waitToClick(selectors.ticketAdvance.moveButton);
await page.waitToClick(selectors.ticketAdvance.acceptButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Tickets moved successfully!');
});
});

View File

@ -70,8 +70,8 @@ describe('Supplier basic data path', () => {
});
it('should check the changes have been recorded', async() => {
const result = await page.waitToGetProperty('#newInstance:nth-child(3)', 'innerText');
const result = await page.waitToGetProperty('vn-tr table tr:nth-child(3) td.after', 'innerText');
expect(result).toEqual('note Some notes');
expect(result).toEqual('Some notes');
});
});

View File

@ -14,6 +14,7 @@ export default class CrudModel extends ModelProxy {
this.$q = $q;
this.primaryKey = 'id';
this.autoLoad = false;
this.page = 1;
}
$onInit() {
@ -125,13 +126,20 @@ export default class CrudModel extends ModelProxy {
}
}
loadMore() {
loadMore(append) {
if (!this.moreRows)
return this.$q.resolve();
let filter = Object.assign({}, this.currentFilter);
const filter = Object.assign({}, this.currentFilter);
if (append)
filter.skip = this.orgData ? this.orgData.length : 0;
return this.sendRequest(filter, true);
if (!append) {
this.page += 1;
filter.limit = this.page * this.limit;
}
return this.sendRequest(filter, append);
}
clear() {

View File

@ -148,7 +148,7 @@ describe('Component vnCrudModel', () => {
controller.moreRows = true;
controller.loadMore();
controller.loadMore(true);
expect(controller.sendRequest).toHaveBeenCalledWith({'skip': 2}, true);
});

View File

@ -212,12 +212,12 @@ export default class DropDown extends Popover {
&& !this.model.isLoading;
if (shouldLoad)
this.model.loadMore();
this.model.loadMore(true);
}
onLoadMoreClick(event) {
if (event.defaultPrevented) return;
this.model.loadMore();
this.model.loadMore(true);
}
onContainerClick(event) {

View File

@ -374,9 +374,10 @@ export class Paginable {
/**
* When limit is enabled, loads the next set of rows.
*
* @param {Boolean} append - Whether should append new data
* @return {Promise} The request promise
*/
loadMore() {
return Promise.resolve();
loadMore(append) {
return Promise.resolve(append);
}
}

View File

@ -73,7 +73,7 @@ class Pagination extends Component {
if (shouldLoad) {
this.nLoads++;
this.model.loadMore();
this.model.loadMore(false);
this.$.$apply();
}
}
@ -82,7 +82,7 @@ class Pagination extends Component {
if (this.maxLoads > 0 && this.nLoads == this.maxLoads)
this.nLoads = 0;
this.model.loadMore();
this.model.loadMore(false);
}
$onDestroy() {

View File

@ -147,7 +147,7 @@ export default class SmartTable extends Component {
for (const column of this.columns) {
if (viewConfig.configuration[column.field] == false) {
const baseSelector = `smart-table[view-config-id="${this.viewConfigId}"] table`;
selectors.push(`${baseSelector} thead > tr > th:nth-child(${column.index + 1})`);
selectors.push(`${baseSelector} thead > tr:not([second-header]) > th:nth-child(${column.index + 1})`);
selectors.push(`${baseSelector} tbody > tr > td:nth-child(${column.index + 1})`);
}
}
@ -235,7 +235,7 @@ export default class SmartTable extends Component {
}
registerColumns() {
const header = this.element.querySelector('thead > tr');
const header = this.element.querySelector('thead > tr:not([second-header])');
if (!header) return;
const columns = header.querySelectorAll('th');
@ -254,7 +254,7 @@ export default class SmartTable extends Component {
}
emptyDataRows() {
const header = this.element.querySelector('thead > tr');
const header = this.element.querySelector('thead > tr:not([second-header])');
const columns = header.querySelectorAll('th');
const tbody = this.element.querySelector('tbody');
if (tbody) {
@ -333,7 +333,7 @@ export default class SmartTable extends Component {
}
displaySearch() {
const header = this.element.querySelector('thead > tr');
const header = this.element.querySelector('thead > tr:not([second-header])');
if (!header) return;
const tbody = this.element.querySelector('tbody');

View File

@ -8,6 +8,16 @@ smart-table table {
& > thead {
border-bottom: $border;
& > tr[second-header] {
& > th
{
text-align: center;
border-bottom-style: groove;
font-weight: bold;
text-transform: uppercase;
}
}
& > * > th {
font-weight: normal;
}
@ -60,6 +70,9 @@ smart-table table {
vertical-align: middle;
}
}
&[separator]{
border-left-style: groove;
}
vn-icon.bright, i.bright {
color: #f7931e;
}

View File

@ -29,6 +29,7 @@ export default class Modules {
const module = {
name: mod.name || mod.module,
code: mod.module,
icon: mod.icon || null,
route,
keyBind

View File

@ -3,6 +3,13 @@
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
<<<<<<< HEAD
"dependencies": {
"@uirouter/angularjs": {
"version": "1.0.29",
"resolved": "https://registry.npmjs.org/@uirouter/angularjs/-/angularjs-1.0.29.tgz",
"integrity": "sha512-RImWnBarNixkMto0o8stEaGwZmvhv5cnuOLXyMU2pY8MP2rgEF74ZNJTLeJCW14LR7XDUxVH8Mk8bPI6lxedmQ==",
=======
"packages": {
"": {
"name": "salix-front",
@ -174,11 +181,22 @@
"version": "1.0.30",
"resolved": "https://registry.npmjs.org/@uirouter/angularjs/-/angularjs-1.0.30.tgz",
"integrity": "sha512-qkc3RFZc91S5K0gc/QVAXc9LGDPXjR04vDgG/11j8+yyZEuQojXxKxdLhKIepiPzqLmGRVqzBmBc27gtqaEeZg==",
>>>>>>> dev
"requires": {
"@uirouter/core": "6.0.8"
}
},
"@uirouter/core": {
<<<<<<< HEAD
"version": "6.0.7",
"resolved": "https://registry.npmjs.org/@uirouter/core/-/core-6.0.7.tgz",
"integrity": "sha512-KUTJxL+6q0PiBnFx4/Z+Hsyg0pSGiaW5yZQeJmUxknecjpTbnXkLU8H2EqRn9N2B+qDRa7Jg8RcgeNDPY72O1w=="
},
"angular": {
"version": "1.8.2",
"resolved": "https://registry.npmjs.org/angular/-/angular-1.8.2.tgz",
"integrity": "sha512-IauMOej2xEe7/7Ennahkbb5qd/HFADiNuLSESz9Q27inmi32zB0lnAsFeLEWcox3Gd1F6YhNd1CP7/9IukJ0Gw=="
=======
"version": "6.0.8",
"resolved": "https://registry.npmjs.org/@uirouter/core/-/core-6.0.8.tgz",
"integrity": "sha512-Gc/BAW47i4L54p8dqYCJJZuv2s3tqlXQ0fvl6Zp2xrblELPVfxmjnc0eurx3XwfQdaqm3T6uls6tQKkof/4QMw=="
@ -187,6 +205,7 @@
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/angular/-/angular-1.8.3.tgz",
"integrity": "sha512-5qjkWIQQVsHj4Sb5TcEs4WZWpFeVFHXwxEBHUhrny41D8UrBAd6T/6nPPAsLngJCReIOqi95W3mxdveveutpZw=="
>>>>>>> dev
},
"angular-animate": {
"version": "1.8.2",
@ -202,17 +221,29 @@
}
},
"angular-translate": {
<<<<<<< HEAD
"version": "2.18.4",
"resolved": "https://registry.npmjs.org/angular-translate/-/angular-translate-2.18.4.tgz",
"integrity": "sha512-KohNrkH6J9PK+VW0L/nsRTcg5Fw70Ajwwe3Jbfm54Pf9u9Fd+wuingoKv+h45mKf38eT+Ouu51FPua8VmZNoCw==",
=======
"version": "2.19.0",
"resolved": "https://registry.npmjs.org/angular-translate/-/angular-translate-2.19.0.tgz",
"integrity": "sha512-Z/Fip5uUT2N85dPQ0sMEe1JdF5AehcDe4tg/9mWXNDVU531emHCg53ZND9Oe0dyNiGX5rWcJKmsL1Fujus1vGQ==",
>>>>>>> dev
"requires": {
"angular": "^1.8.0"
}
},
"angular-translate-loader-partial": {
<<<<<<< HEAD
"version": "2.18.4",
"resolved": "https://registry.npmjs.org/angular-translate-loader-partial/-/angular-translate-loader-partial-2.18.4.tgz",
"integrity": "sha512-bsjR+FbB0sdA2528E/ugwKdlPPQhA1looxLxI3otayBTFXBpED33besfSZhYAISLgNMSL038vSssfRUen9qD8w==",
=======
"version": "2.19.0",
"resolved": "https://registry.npmjs.org/angular-translate-loader-partial/-/angular-translate-loader-partial-2.19.0.tgz",
"integrity": "sha512-NnMw13LMV4bPQmJK7/pZOZAnPxe0M5OtUHchADs5Gye7V7feonuEnrZ8e1CKhBlv9a7IQyWoqcBa4Lnhg8gk5w==",
>>>>>>> dev
"requires": {
"angular-translate": "~2.19.0"
}
@ -253,9 +284,15 @@
}
},
"moment": {
<<<<<<< HEAD
"version": "2.29.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
=======
"version": "2.29.4",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
>>>>>>> dev
},
"oclazyload": {
"version": "0.6.3",

View File

@ -1,8 +1,9 @@
<vn-layout
ng-if="$ctrl.showLayout">
</vn-layout>
<vn-out-layout
<ui-view
name="login"
ng-if="!$ctrl.showLayout">
</vn-out-layout>
</ui-view>
<vn-snackbar vn-id="snackbar"></vn-snackbar>
<vn-debug-info></vn-debug-info>

View File

@ -21,7 +21,7 @@ export default class App extends Component {
get showLayout() {
const state = this.$state.current.name || this.$location.$$path.substring(1).replace('/', '.');
const outLayout = ['login', 'recoverPassword', 'resetPassword'];
const outLayout = ['login', 'recoverPassword', 'resetPassword', 'reset-password'];
return state && !outLayout.some(ol => ol == state);
}

View File

@ -33,7 +33,9 @@ export default class Controller extends Component {
if (!res.data.length) return;
for (let starredModule of res.data) {
const module = this.modules.find(mod => mod.name === starredModule.moduleFk);
let moduleName = starredModule.moduleFk;
if (moduleName === 'customer') moduleName = 'client';
const module = this.modules.find(mod => mod.code === moduleName);
if (module) {
module.starred = true;
module.position = starredModule.position;
@ -47,8 +49,10 @@ export default class Controller extends Component {
if (event.defaultPrevented) return;
event.preventDefault();
event.stopPropagation();
let moduleName = module.code;
if (moduleName === 'client') moduleName = 'customer';
const params = {moduleName: module.name};
const params = {moduleName};
const query = `starredModules/toggleStarredModule`;
this.$http.post(query, params).then(res => {
if (res.data) {
@ -84,13 +88,16 @@ export default class Controller extends Component {
event.preventDefault();
event.stopPropagation();
const params = {moduleName: module.name, direction: direction};
let moduleName = module.code;
if (moduleName === 'client') moduleName = 'customer';
const params = {moduleName: moduleName, direction: direction};
const query = `starredModules/setPosition`;
this.$http.post(query, params).then(res => {
if (res.data) {
module.position = res.data.movingModule.position;
this.modules.forEach(mod => {
if (mod.name == res.data.pushedModule.moduleFk)
if (mod.code == res.data.pushedModule.moduleFk)
mod.position = res.data.pushedModule.position;
});
this.vnApp.showSuccess(this.$t('Data saved!'));

View File

@ -19,7 +19,7 @@ describe('Salix Component vnHome', () => {
describe('getStarredModules()', () => {
it('should not set any of the modules as starred if there are no starred modules for the user', () => {
const expectedResponse = [];
controller._modules = [{module: 'client', name: 'Clients'}];
controller._modules = [{code: 'client', name: 'Clients'}];
$httpBackend.whenRoute('GET', 'starredModules/getStarredModules').respond(expectedResponse);
$httpBackend.expectGET('starredModules/getStarredModules').respond(expectedResponse);
@ -31,8 +31,8 @@ describe('Salix Component vnHome', () => {
});
it('should set the example module as starred since its the starred module for the user', () => {
const expectedResponse = [{id: 1, moduleFk: 'Clients', workerFk: 9}];
controller._modules = [{module: 'client', name: 'Clients'}];
const expectedResponse = [{id: 1, moduleFk: 'customer', workerFk: 9}];
controller._modules = [{code: 'client', name: 'Clients'}];
$httpBackend.whenRoute('GET', 'starredModules/getStarredModules').respond(expectedResponse);
$httpBackend.expectGET('starredModules/getStarredModules').respond(expectedResponse);
@ -48,7 +48,7 @@ describe('Salix Component vnHome', () => {
it(`should set the received module as starred if it wasn't starred`, () => {
const expectedResponse = [{id: 1, moduleFk: 'Clients', workerFk: 9}];
const event = new Event('target');
controller._modules = [{module: 'client', name: 'Clients'}];
controller._modules = [{code: 'client', name: 'Clients'}];
$httpBackend.whenRoute('GET', 'starredModules/getStarredModules').respond(expectedResponse);
$httpBackend.expectPOST('starredModules/toggleStarredModule').respond(expectedResponse);
@ -61,7 +61,7 @@ describe('Salix Component vnHome', () => {
it('should set the received module as regular if it was starred', () => {
const event = new Event('target');
controller._modules = [{module: 'client', name: 'Clients', starred: true}];
controller._modules = [{code: 'client', name: 'Clients', starred: true}];
$httpBackend.whenRoute('GET', 'starredModules/getStarredModules').respond([]);
$httpBackend.expectPOST('starredModules/toggleStarredModule').respond(undefined);
@ -76,18 +76,18 @@ describe('Salix Component vnHome', () => {
describe('moveModule()', () => {
it('should perform a query to setPosition and the apply the position to the moved and pushed modules', () => {
const starredModules = [
{id: 1, moduleFk: 'Clients', workerFk: 9},
{id: 2, moduleFk: 'Orders', workerFk: 9}
{id: 1, moduleFk: 'customer', workerFk: 9},
{id: 2, moduleFk: 'order', workerFk: 9}
];
const movedModules = {
movingModule: {position: 2, moduleFk: 'Clients'},
pushedModule: {position: 1, moduleFk: 'Orders'}
movingModule: {position: 2, moduleFk: 'customer'},
pushedModule: {position: 1, moduleFk: 'order'}
};
const event = new Event('target');
controller._modules = [
{module: 'client', name: 'Clients', position: 1},
{module: 'orders', name: 'Orders', position: 2}
{code: 'client', name: 'Clients', position: 1},
{code: 'order', name: 'Orders', position: 2}
];
$httpBackend.whenRoute('GET', 'starredModules/getStarredModules').respond(starredModules);

View File

@ -19,3 +19,4 @@ import './user-popover';
import './upload-photo';
import './bank-entity';
import './log';
import './sendSms';

View File

@ -3,6 +3,8 @@
url="{{$ctrl.url}}"
filter="$ctrl.filter"
link="{originFk: $ctrl.originId}"
where="{changedModel: $ctrl.changedModel,
changedModelId: $ctrl.changedModelId}"
data="$ctrl.logs"
limit="20"
auto-load="true">
@ -13,81 +15,53 @@
<vn-thead>
<vn-tr>
<vn-th field="creationDate">Date</vn-th>
<vn-th field="userFk" class="expendable" shrink>Author</vn-th>
<vn-th field="changedModel" class="expendable">Model</vn-th>
<vn-th field="action" class="expendable" shrink>Action</vn-th>
<vn-th field="changedModelValue" class="expendable">Name</vn-th>
<vn-th expand>Before</vn-th>
<vn-th expand>After</vn-th>
<vn-th field="userFk" shrink>User</vn-th>
<vn-th field="changedModel" ng-if="$ctrl.showModelName" shrink>Model</vn-th>
<vn-th field="action" shrink>Action</vn-th>
<vn-th field="changedModelValue" ng-if="$ctrl.showModelName">Name</vn-th>
<vn-th expand>Changes</vn-th>
</vn-tr>
</vn-thead>
<vn-tbody>
<vn-tr ng-repeat="log in $ctrl.logs">
<vn-td shrink-datetime>
{{::log.creationDate | date:'dd/MM/yyyy HH:mm'}}
<div class="changes">
<div>
<span translate class="label">Changed by</span><span class="label">: </span>
<span ng-class="{'link': log.user.worker.id, 'value': !log.user.worker.id}"
ng-click="$ctrl.showWorkerDescriptor($event, log.user.worker.id)"
translate>{{::log.user.name || 'System' | translate}}
</span>
</div>
<div>
<span translate class="label">Model</span><span class="label">: </span>
<span translate class="value">{{::log.changedModel | dashIfEmpty}}</span>
</div>
<div>
<span translate class="label">Action</span><span class="label">: </span>
<span translate class="value">{{::$ctrl.actionsText[log.action] | dashIfEmpty}}</span>
</div>
<div>
<span translate class="label">Name</span><span class="label">: </span>
<span translate class="value">{{::log.changedModelValue | dashIfEmpty}}</span>
</div>
</div>
</vn-td>
<vn-td class="expendable">
<vn-td>
<span ng-class="{'link': log.user.worker.id, 'value': !log.user.worker.id}"
ng-click="$ctrl.showWorkerDescriptor($event, log.user.worker.id)"
translate>{{::log.user.name || 'System' | translate}}
</span>
</vn-td>
<vn-td class="expendable">
<vn-td ng-if="$ctrl.showModelName">
{{::log.changedModel}}
</vn-td>
<vn-td translate class="expendable">
<vn-td shrink translate>
{{::$ctrl.actionsText[log.action]}}
</vn-td>
<vn-td class="expendable" expand>
<vn-td ng-if="$ctrl.showModelName">
{{::log.changedModelValue}}
</vn-td>
<vn-td expand class="before">
<vn-one ng-repeat="old in log.oldProperties">
<div>
<vn-label-value
no-ellipsize
label="{{::old.key}}"
value="{{::old.value}}">
</vn-label-value>
<vn-td expand>
<table class="attributes">
<thead>
<tr>
<th translate class="field">Field</th>
<th translate>Before</th>
<th translate>After</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="prop in ::log.props">
<td class="field">{{prop.name}}</td>
<td class="before">{{prop.old}}</td>
<td class="after">{{prop.new}}</td>
</tr>
</tbody>
</table>
<div ng-if="log.description != null">
{{::log.description}}
</div>
</vn-one>
</vn-td>
<vn-td expand class="after">
<vn-one ng-repeat="new in log.newProperties" ng-if="!log.description" id="newInstance">
<div>
<vn-label-value
no-ellipsize
label="{{::new.key}}"
value="{{::new.value}}">
</vn-label-value>
</div>
</vn-one>
<vn-one ng-if="!log.newProperties" id="description">
<div>
<span no-ellipsize>{{::log.description}}</span>
</div>
</vn-one>
</vn-td>
</vn-tr>
</vn-tbody>

View File

@ -2,15 +2,17 @@ import ngModule from '../../module';
import Section from '../section';
import './style.scss';
const validDate = /^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]+)?(Z)?$/;
export default class Controller extends Section {
constructor($element, $) {
super($element, $);
this.actionsText = {
'insert': 'Creates',
'update': 'Updates',
'delete': 'Deletes',
'select': 'Views'
}; ``;
insert: 'Creates',
update: 'Updates',
delete: 'Deletes',
select: 'Views'
};
this.filter = {
include: [{
relation: 'user',
@ -33,32 +35,57 @@ export default class Controller extends Section {
set logs(value) {
this._logs = value;
if (!value) return;
if (!this.logs) return;
const empty = {};
const validations = window.validations;
value.forEach(log => {
const locale = validations[log.changedModel] && validations[log.changedModel].locale ? validations[log.changedModel].locale : {};
for (const log of value) {
const oldValues = log.oldInstance || empty;
const newValues = log.newInstance || empty;
const locale = validations[log.changedModel]?.locale || empty;
log.oldProperties = this.getInstance(log.oldInstance, locale);
log.newProperties = this.getInstance(log.newInstance, locale);
let props = Object.keys(oldValues).concat(Object.keys(newValues));
props = [...new Set(props)];
log.props = [];
for (const prop of props) {
log.props.push({
name: locale[prop] || prop,
old: this.formatValue(oldValues[prop]),
new: this.formatValue(newValues[prop])
});
}
getInstance(instance, locale) {
const properties = [];
let validDate = /^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]+)?(Z)?$/;
if (typeof instance == 'object' && instance != null) {
Object.keys(instance).forEach(property => {
if (validDate.test(instance[property]))
instance[property] = new Date(instance[property]).toLocaleString('es-ES');
const key = locale[property] || property;
properties.push({key, value: instance[property]});
});
return properties;
}
return null;
}
get showModelName() {
return !(this.changedModel && this.changedModelId);
}
formatValue(value) {
let type = typeof value;
if (type === 'string' && validDate.test(value)) {
value = new Date(value);
type = typeof value;
}
switch (type) {
case 'boolean':
return value ? '✓' : '✗';
case 'object':
if (value instanceof Date) {
const hasZeroTime =
value.getHours() === 0 &&
value.getMinutes() === 0 &&
value.getSeconds() === 0;
const format = hasZeroTime ? 'dd/MM/yyyy' : 'dd/MM/yyyy HH:mm:ss';
return this.$filter('date')(value, format);
}
else
return value;
default:
return value;
}
}
showWorkerDescriptor(event, workerId) {
@ -73,6 +100,8 @@ ngModule.vnComponent('vnLog', {
bindings: {
model: '<',
originId: '<',
changedModel: '<?',
changedModelId: '<?',
url: '@'
}
});

View File

@ -12,3 +12,4 @@ Deletes: Elimina
Views: Visualiza
System: Sistema
note: nota
Changes: Cambios

View File

@ -23,6 +23,28 @@ vn-log {
display: block;
}
}
.attributes {
width: 100%;
tr {
height: 10px;
& > td {
padding: 2px;
}
& > td.field,
& > th.field {
width: 20%;
color: gray;
}
& > td.before,
& > th.before,
& > td.after,
& > th.after {
width: 40%;
}
}
}
}
.ellipsis {
white-space: nowrap;

View File

@ -1,3 +1,6 @@
<div class="box">
<img src="./logo.svg"/>
<form name="form" ng-submit="$ctrl.submit()">
<vn-textfield
label="User"
ng-model="$ctrl.user"
@ -19,9 +22,11 @@
<div class="spinner-wrapper">
<vn-spinner enable="$ctrl.loading"></vn-spinner>
</div>
<div class="vn-pt-lg">
<!--<div class="vn-pt-lg">
<a ui-sref="recoverPassword" translate>
I do not remember my password
</a>
</div>-->
</div>
</form>
</div>

View File

@ -25,7 +25,7 @@ vn-recover-password{
}
}
vn-out-layout{
vn-login{
position: absolute;
height: 100%;
width: 100%;

View File

@ -1,19 +1,26 @@
import ngModule from '../module';
import Component from 'core/lib/component';
import ngModule from '../../module';
import './style.scss';
import Dialog from '../../../core/components/dialog';
export default class sendSmsDialog extends Dialog {
constructor($element, $scope, $http, $translate, vnApp) {
super($element, $scope, $http, $translate, vnApp);
new CustomEvent('openSmsDialog', {
detail: {
this: this
}
});
}
class Controller extends Component {
open() {
this.$.SMSDialog.show();
}
charactersRemaining() {
const element = this.$.message;
const value = element.input.value;
const element = this.sms.message;
const maxLength = 160;
const textAreaLength = new Blob([value]).size;
return maxLength - textAreaLength;
return maxLength - element.length;
}
onResponse() {
@ -25,23 +32,19 @@ class Controller extends Component {
if (this.charactersRemaining() < 0)
throw new Error(`The message it's too long`);
this.$http.post(`Tickets/${this.sms.ticketId}/sendSms`, this.sms).then(res => {
this.vnApp.showMessage(this.$t('SMS sent!'));
if (res.data) this.emit('send', {response: res.data});
});
return this.onSend({$sms: this.sms});
} catch (e) {
this.vnApp.showError(this.$t(e.message));
return false;
}
return true;
}
}
ngModule.vnComponent('vnTicketSms', {
ngModule.vnComponent('vnSmsDialog', {
template: require('./index.html'),
controller: Controller,
controller: sendSmsDialog,
bindings: {
sms: '<',
onSend: '&',
}
});

View File

@ -9,7 +9,9 @@ function config($stateProvider, $urlRouterProvider) {
.state('login', {
url: '/login?continue',
description: 'Login',
template: '<vn-login></vn-login>'
views: {
'login': {template: '<vn-login></vn-login>'},
}
})
.state('recoverPassword', {
url: '/recover-password',

View File

@ -66,6 +66,7 @@
"MESSAGE_INSURANCE_CHANGE": "I have changed the insurence credit of client [{{clientName}} ({{clientId}})]({{{url}}}) to *{{credit}} €*",
"Changed client paymethod": "I have changed the pay method for client [{{clientName}} ({{clientId}})]({{{url}}})",
"Sent units from ticket": "I sent *{{quantity}}* units of [{{concept}} ({{itemId}})]({{{itemUrl}}}) to *\"{{nickname}}\"* coming from ticket id [{{ticketId}}]({{{ticketUrl}}})",
"Change quantity": "{{concept}} change of {{oldQuantity}} to {{newQuantity}}",
"Claim will be picked": "The product from the claim [({{claimId}})]({{{claimUrl}}}) from the client *{{clientName}}* will be picked",
"Claim state has changed to incomplete": "The state of the claim [({{claimId}})]({{{claimUrl}}}) from client *{{clientName}}* has changed to *incomplete*",
"Claim state has changed to canceled": "The state of the claim [({{claimId}})]({{{claimUrl}}}) from client *{{clientName}}* has changed to *canceled*",
@ -136,12 +137,14 @@
"Password does not meet requirements": "Password does not meet requirements",
"You don't have privileges to change the zone": "You don't have privileges to change the zone or for these parameters there are more than one shipping options, talk to agencies",
"Not enough privileges to edit a client": "Not enough privileges to edit a client",
"Claim pickup order sent": "Claim pickup order sent [({{claimId}})]({{{claimUrl}}}) to client *{{clientName}}*",
"Claim pickup order sent": "Claim pickup order sent [{{claimId}}]({{{claimUrl}}}) to client *{{clientName}}*",
"You don't have grant privilege": "You don't have grant privilege",
"You don't own the role and you can't assign it to another user": "You don't own the role and you can't assign it to another user",
"Email verify": "Email verify",
"Ticket merged": "Ticket [{{id}}]({{{fullPath}}}) ({{{originDated}}}) merged with [{{tfId}}]({{{fullPathFuture}}}) ({{{futureDated}}})",
"Ticket merged": "Ticket [{{originId}}]({{{originFullPath}}}) ({{{originDated}}}) merged with [{{destinationId}}]({{{destinationFullPath}}}) ({{{destinationDated}}})",
"Sale(s) blocked, please contact production": "Sale(s) blocked, please contact production",
"App locked": "App locked by user {{userId}}",
"The sales of the receiver ticket can't be modified": "The sales of the receiver ticket can't be modified",
"Receipt's bank was not found": "Receipt's bank was not found",
"This receipt was not compensated": "This receipt was not compensated",
"Client's email was not found": "Client's email was not found"

View File

@ -134,6 +134,7 @@
"MESSAGE_INSURANCE_CHANGE": "He cambiado el crédito asegurado del cliente [{{clientName}} ({{clientId}})]({{{url}}}) a *{{credit}} €*",
"Changed client paymethod": "He cambiado la forma de pago del cliente [{{clientName}} ({{clientId}})]({{{url}}})",
"Sent units from ticket": "Envio *{{quantity}}* unidades de [{{concept}} ({{itemId}})]({{{itemUrl}}}) a *\"{{nickname}}\"* provenientes del ticket id [{{ticketId}}]({{{ticketUrl}}})",
"Change quantity": "{{concept}} cambia de {{oldQuantity}} a {{newQuantity}}",
"Claim will be picked": "Se recogerá el género de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}*",
"Claim state has changed to incomplete": "Se ha cambiado el estado de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}* a *incompleta*",
"Claim state has changed to canceled": "Se ha cambiado el estado de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}* a *anulado*",
@ -238,16 +239,18 @@
"Modifiable password only via recovery or by an administrator": "Contraseña modificable solo a través de la recuperación o por un administrador",
"Not enough privileges to edit a client": "No tienes suficientes privilegios para editar un cliente",
"This route does not exists": "Esta ruta no existe",
"Claim pickup order sent": "Reclamación Orden de recogida enviada [({{claimId}})]({{{claimUrl}}}) al cliente *{{clientName}}*",
"Claim pickup order sent": "Reclamación Orden de recogida enviada [{{claimId}}]({{{claimUrl}}}) al cliente *{{clientName}}*",
"You don't have grant privilege": "No tienes privilegios para dar privilegios",
"You don't own the role and you can't assign it to another user": "No eres el propietario del rol y no puedes asignarlo a otro usuario",
"Ticket merged": "Ticket [{{id}}]({{{fullPath}}}) ({{{originDated}}}) fusionado con [{{tfId}}]({{{fullPathFuture}}}) ({{{futureDated}}})",
"Ticket merged": "Ticket [{{originId}}]({{{originFullPath}}}) ({{{originDated}}}) fusionado con [{{destinationId}}]({{{destinationFullPath}}}) ({{{destinationDated}}})",
"Already has this status": "Ya tiene este estado",
"There aren't records for this week": "No existen registros para esta semana",
"Empty data source": "Origen de datos vacio",
"App locked": "Aplicación bloqueada por el usuario {{userId}}",
"Email verify": "Correo de verificación",
"Landing cannot be lesser than shipment": "Landing cannot be lesser than shipment",
"Receipt's bank was not found": "No se encontró el banco del recibo",
"This receipt was not compensated": "Este recibo no ha sido compensado",
"Client's email was not found": "No se encontró el email del cliente"
"Client's email was not found": "No se encontró el email del cliente",
"Aplicación bloqueada por el usuario 9": "Aplicación bloqueada por el usuario 9"
}

View File

@ -15,7 +15,7 @@
"legacyUtcDateProcessing": false,
"timezone": "local",
"connectTimeout": 40000,
"acquireTimeout": 20000,
"acquireTimeout": 60000,
"waitForConnections": true
},
"osticket": {

View File

@ -104,6 +104,9 @@
"SageTransactionType": {
"dataSource": "vn"
},
"TicketSms": {
"dataSource": "vn"
},
"TpvError": {
"dataSource": "vn"
},

View File

@ -27,7 +27,7 @@ module.exports = Self => {
message: 'Invalid email',
allowNull: true,
allowBlank: true,
with: /^[\w|.|-]+@[\w|-]+(\.[\w|-]+)*(,[\w|.|-]+@[\w|-]+(\.[\w|-]+)*)*$/
with: /^[\W]*([\w+\-.%]+@[\w\-.]+\.[A-Za-z]{1,61}[\W]*,{1}[\W]*)*([\w+\-.%]+@[\w\-.]+\.[A-Za-z]{1,61})[\W]*$/
});
Self.validatesLengthOf('postcode', {

View File

@ -0,0 +1,28 @@
{
"name": "TicketSms",
"base": "VnModel",
"options": {
"mysql": {
"table": "ticketSms"
}
},
"properties": {
"smsFk": {
"type": "number",
"id": true,
"description": "Identifier"
}
},
"relations": {
"ticket": {
"type": "belongsTo",
"model": "Ticket",
"foreignKey": "ticketFk"
},
"sms": {
"type": "belongsTo",
"model": "Sms",
"foreignKey": "smsFk"
}
}
}

View File

@ -113,10 +113,11 @@
</div>
</slot-body>
</vn-descriptor-content>
<vn-client-sms
<vn-sms-dialog
vn-id="sms"
on-send="$ctrl.onSmsSend($sms)"
sms="$ctrl.newSMS">
</vn-client-sms>
</vn-sms-dialog>
<vn-worker-descriptor-popover
vn-id="workerDescriptor">
</vn-worker-descriptor-popover>

View File

@ -39,6 +39,11 @@ class Controller extends Descriptor {
};
this.$.sms.open();
}
onSmsSend(sms) {
return this.$http.post(`Clients/${this.id}/sendSms`, sms)
.then(() => this.vnApp.showSuccess(this.$t('SMS sent')));
}
}
ngModule.vnComponent('vnClientDescriptor', {

View File

@ -35,7 +35,6 @@ import './sample/index';
import './sample/create';
import './web-payment';
import './log';
import './sms';
import './postcode';
import './postcode/province';
import './postcode/city';

View File

@ -1,49 +0,0 @@
import ngModule from '../module';
import Section from 'salix/components/section';
import './style.scss';
class Controller extends Section {
open() {
this.$.SMSDialog.show();
}
charactersRemaining() {
const element = this.$.message;
const value = element.input.value;
const maxLength = 160;
const textAreaLength = new Blob([value]).size;
return maxLength - textAreaLength;
}
onResponse() {
try {
if (!this.sms.destination)
throw new Error(`The destination can't be empty`);
if (!this.sms.message)
throw new Error(`The message can't be empty`);
if (this.charactersRemaining() < 0)
throw new Error(`The message it's too long`);
this.$http.post(`Clients/${this.$params.id}/sendSms`, this.sms).then(res => {
this.vnApp.showMessage(this.$t('SMS sent!'));
if (res.data) this.emit('send', {response: res.data});
});
} catch (e) {
this.vnApp.showError(this.$t(e.message));
return false;
}
return true;
}
}
Controller.$inject = ['$element', '$scope', '$http', '$translate', 'vnApp'];
ngModule.vnComponent('vnClientSms', {
template: require('./index.html'),
controller: Controller,
bindings: {
sms: '<',
}
});

View File

@ -1,74 +0,0 @@
import './index';
describe('Client', () => {
describe('Component vnClientSms', () => {
let controller;
let $httpBackend;
let $element;
beforeEach(ngModule('client'));
beforeEach(inject(($componentController, $rootScope, _$httpBackend_) => {
$httpBackend = _$httpBackend_;
let $scope = $rootScope.$new();
$element = angular.element('<vn-dialog></vn-dialog>');
controller = $componentController('vnClientSms', {$element, $scope});
controller.client = {id: 1101};
controller.$params = {id: 1101};
controller.$.message = {
input: {
value: 'My SMS'
}
};
}));
describe('onResponse()', () => {
it('should perform a POST query and show a success snackbar', () => {
let params = {destinationFk: 1101, destination: 111111111, message: 'My SMS'};
controller.sms = {destinationFk: 1101, destination: 111111111, message: 'My SMS'};
jest.spyOn(controller.vnApp, 'showMessage');
$httpBackend.expect('POST', `Clients/1101/sendSms`, params).respond(200, params);
controller.onResponse();
$httpBackend.flush();
expect(controller.vnApp.showMessage).toHaveBeenCalledWith('SMS sent!');
});
it('should call onResponse without the destination and show an error snackbar', () => {
controller.sms = {destinationFk: 1101, message: 'My SMS'};
jest.spyOn(controller.vnApp, 'showError');
controller.onResponse('accept');
expect(controller.vnApp.showError).toHaveBeenCalledWith(`The destination can't be empty`);
});
it('should call onResponse without the message and show an error snackbar', () => {
controller.sms = {destinationFk: 1101, destination: 222222222};
jest.spyOn(controller.vnApp, 'showError');
controller.onResponse('accept');
expect(controller.vnApp.showError).toHaveBeenCalledWith(`The message can't be empty`);
});
});
describe('charactersRemaining()', () => {
it('should return the characters remaining in a element', () => {
controller.$.message = {
input: {
value: 'My message 0€'
}
};
let result = controller.charactersRemaining();
expect(result).toEqual(145);
});
});
});
});

View File

@ -154,8 +154,8 @@ module.exports = Self => {
e.id,
e.supplierFk,
e.dated,
e.ref reference,
e.ref invoiceNumber,
e.reference,
e.invoiceNumber,
e.isBooked,
e.isExcludedFromAvailable,
e.notes,

View File

@ -19,16 +19,10 @@
"type": "date"
},
"reference": {
"type": "string",
"mysql": {
"columnName": "ref"
}
"type": "string"
},
"invoiceNumber": {
"type": "string",
"mysql": {
"columnName": "ref"
}
"type": "string"
},
"isBooked": {
"type": "boolean"

View File

@ -2,7 +2,7 @@
"InvoiceIn": {
"dataSource": "vn"
},
"InvoiceInTax": {
"InvoiceInConfig": {
"dataSource": "vn"
},
"InvoiceInDueDay": {
@ -13,5 +13,8 @@
},
"InvoiceInLog": {
"dataSource": "vn"
},
"InvoiceInTax": {
"dataSource": "vn"
}
}

View File

@ -0,0 +1,35 @@
{
"name": "InvoiceInConfig",
"base": "VnModel",
"options": {
"mysql": {
"table": "invoiceInConfig"
}
},
"properties": {
"id": {
"id": true,
"type": "number",
"description": "Identifier"
},
"retentionRate": {
"type": "number"
},
"retentionName": {
"type": "string"
}
},
"relations": {
"sageWithholding": {
"type": "belongsTo",
"model": "SageWithholding",
"foreignKey": "sageWithholdingFk"
}
},
"acls": [{
"accessType": "READ",
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "ALLOW"
}]
}

View File

@ -1,3 +1,10 @@
<vn-crud-model
url="InvoiceInConfigs"
data="$ctrl.config"
filter="{fields: ['sageWithholdingFk']}"
id-value="1"
auto-load="true">
</vn-crud-model>
<vn-descriptor-content
module="invoiceIn"
description="$ctrl.invoiceIn.supplierRef"
@ -26,13 +33,13 @@
Clone Invoice
</vn-item>
<vn-item
ng-if="false"
ng-if="$ctrl.isAgricultural()"
ng-click="$ctrl.showPdfInvoice()"
translate>
Show agricultural invoice as PDF
</vn-item>
<vn-item
ng-if="false"
ng-if="$ctrl.isAgricultural()"
ng-click="sendPdfConfirmation.show({email: $ctrl.entity.supplierContact[0].email})"
translate>
Send agricultural invoice as PDF

View File

@ -110,6 +110,10 @@ class Controller extends Descriptor {
recipientId: this.entity.supplier.id
});
}
isAgricultural() {
return this.invoiceIn.supplier.sageWithholdingFk == this.config[0].sageWithholdingFk;
}
}
ngModule.vnComponent('vnInvoiceInDescriptor', {

View File

@ -9,31 +9,43 @@ module.exports = Self => {
accepts: [
{
arg: 'ids',
type: ['number'],
description: 'The invoice ids'
type: 'string',
description: 'The invoices ids',
}
],
returns: {
arg: 'base64',
type: 'string',
returns: [
{
arg: 'body',
type: 'file',
root: true
},
}, {
arg: 'Content-Type',
type: 'string',
http: {target: 'header'}
}, {
arg: 'Content-Disposition',
type: 'string',
http: {target: 'header'}
}
],
http: {
path: '/downloadZip',
verb: 'POST'
verb: 'GET'
}
});
Self.downloadZip = async function(ctx, ids, options) {
const models = Self.app.models;
const myOptions = {};
const zip = new JSZip();
if (typeof options == 'object')
Object.assign(myOptions, options);
const zip = new JSZip();
let totalSize = 0;
const zipConfig = await models.ZipConfig.findOne(null, myOptions);
let totalSize = 0;
ids = ids.split(',');
for (let id of ids) {
if (zipConfig && totalSize > zipConfig.maxSize) throw new UserError('Files are too large');
const invoiceOutPdf = await models.InvoiceOut.download(ctx, id, myOptions);
@ -44,8 +56,10 @@ module.exports = Self => {
totalSize += sizeInMegabytes;
zip.file(fileName, body);
}
const base64 = await zip.generateAsync({type: 'base64'});
return base64;
const stream = zip.generateNodeStream({streamFiles: true});
return [stream, 'application/zip', `filename="download.zip"`];
};
function extractFileName(str) {

View File

@ -3,7 +3,7 @@ const UserError = require('vn-loopback/util/user-error');
describe('InvoiceOut downloadZip()', () => {
const userId = 9;
const invoiceIds = [1, 2];
const invoiceIds = '1,2';
const ctx = {
req: {
@ -13,6 +13,7 @@ describe('InvoiceOut downloadZip()', () => {
};
it('should return part of link to dowloand the zip', async() => {
pending('https://redmine.verdnatura.es/issues/4875');
const tx = await models.InvoiceOut.beginTransaction({});
try {
@ -30,7 +31,6 @@ describe('InvoiceOut downloadZip()', () => {
});
it('should return an error if the size of the files is too large', async() => {
pending('https://redmine.verdnatura.es/issues/4875');
const tx = await models.InvoiceOut.beginTransaction({});
let error;

View File

@ -29,13 +29,13 @@ export default class Controller extends Section {
window.open(url, '_blank');
} else {
const invoiceOutIds = this.checked;
const params = {
ids: invoiceOutIds
};
this.$http.post(`InvoiceOuts/downloadZip`, params)
.then(res => {
location.href = 'data:application/zip;base64,' + res.data;
const invoicesIds = invoiceOutIds.join(',');
const serializedParams = this.$httpParamSerializer({
access_token: this.vnToken.token,
ids: invoicesIds
});
const url = `api/InvoiceOuts/downloadZip?${serializedParams}`;
window.open(url, '_blank');
}
}
}

View File

@ -0,0 +1,66 @@
const UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
Self.remoteMethodCtx('lock', {
description: 'Lock an app for the user',
accessType: 'WRITE',
accepts: [
{
arg: 'appName',
type: 'string',
required: true,
description: 'The app name',
http: {source: 'path'}
}
],
returns: {
type: ['object'],
root: true
},
http: {
path: `/:appName/lock`,
verb: 'POST'
}
});
Self.lock = async(ctx, appName, options) => {
const models = Self.app.models;
const userId = ctx.req.accessToken.userId;
const myOptions = {};
const $t = ctx.req.__; // $translate
let tx;
if (typeof options == 'object')
Object.assign(myOptions, options);
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
try {
const mdbApp = await models.MdbApp.findById(appName, {fields: ['app', 'locked', 'userFk']}, myOptions);
if (mdbApp.locked) {
throw new UserError($t('App locked', {
userId: mdbApp.userFk
}));
}
const updatedMdbApp = await mdbApp.updateAttributes({
userFk: userId,
locked: new Date()
}, myOptions);
if (tx) await tx.commit();
return updatedMdbApp;
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
};
};

View File

@ -0,0 +1,51 @@
const models = require('vn-loopback/server/server').models;
describe('MdbApp lock()', () => {
it('should throw an error if the app is already locked', async() => {
const tx = await models.MdbApp.beginTransaction({});
let error;
try {
const options = {transaction: tx};
const appName = 'bar';
const developerId = 9;
const ctx = {
req: {
accessToken: {userId: developerId},
__: () => {}
}
};
const result = await models.MdbApp.lock(ctx, appName, options);
expect(result.locked).not.toBeNull();
await tx.rollback();
} catch (e) {
error = e;
await tx.rollback();
}
expect(error).toBeDefined();
});
it(`should lock a mdb `, async() => {
const tx = await models.MdbApp.beginTransaction({});
try {
const options = {transaction: tx};
const appName = 'foo';
const developerId = 9;
const ctx = {req: {accessToken: {userId: developerId}}};
const result = await models.MdbApp.lock(ctx, appName, options);
expect(result.locked).not.toBeNull();
await tx.rollback();
} catch (e) {
await tx.rollback();
}
});
});

View File

@ -0,0 +1,22 @@
const models = require('vn-loopback/server/server').models;
describe('MdbApp unlock()', () => {
it(`should unlock a mdb `, async() => {
const tx = await models.MdbApp.beginTransaction({});
try {
const options = {transaction: tx};
const appName = 'bar';
const developerId = 9;
const ctx = {req: {accessToken: {userId: developerId}}};
const result = await models.MdbApp.unlock(ctx, appName, options);
expect(result.locked).toBeNull();
await tx.rollback();
} catch (e) {
await tx.rollback();
}
});
});

View File

@ -0,0 +1,40 @@
module.exports = Self => {
Self.remoteMethodCtx('unlock', {
description: 'Unlock an app for the user',
accessType: 'WRITE',
accepts: [
{
arg: 'appName',
type: 'string',
required: true,
description: 'The app name',
http: {source: 'path'}
}
],
returns: {
type: ['object'],
root: true
},
http: {
path: `/:appName/unlock`,
verb: 'POST'
}
});
Self.unlock = async(ctx, appName, options) => {
const models = Self.app.models;
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
const mdbApp = await models.MdbApp.findById(appName, null, myOptions);
const updatedMdbApp = await mdbApp.updateAttributes({
userFk: null,
locked: null
}, myOptions);
return updatedMdbApp;
};
};

View File

@ -23,6 +23,12 @@ module.exports = Self => {
type: 'string',
required: true,
description: `The branch name`
},
{
arg: 'unlock',
type: 'boolean',
required: false,
description: `It allows unlock the app`
}
],
returns: {
@ -35,9 +41,11 @@ module.exports = Self => {
}
});
Self.upload = async(ctx, appName, newVersion, branch, options) => {
Self.upload = async(ctx, appName, newVersion, branch, unlock, options) => {
const models = Self.app.models;
const userId = ctx.req.accessToken.userId;
const myOptions = {};
const $t = ctx.req.__; // $translate
const TempContainer = models.TempContainer;
const AccessContainer = models.AccessContainer;
@ -55,6 +63,14 @@ module.exports = Self => {
let srcFile;
try {
const mdbApp = await models.MdbApp.findById(appName, null, myOptions);
if (mdbApp.locked && mdbApp.userFk != userId) {
throw new UserError($t('App locked', {
userId: mdbApp.userFk
}));
}
const tempContainer = await TempContainer.container('access');
const uploaded = await TempContainer.upload(tempContainer.name, ctx.req, ctx.result, fileOptions);
const files = Object.values(uploaded.files).map(file => {
@ -79,7 +95,7 @@ module.exports = Self => {
const existBranch = await models.MdbBranch.findOne({
where: {name: branch}
});
}, myOptions);
if (!existBranch)
throw new UserError('Not exist this branch');
@ -108,7 +124,9 @@ module.exports = Self => {
app: appName,
branchFk: branch,
version: newVersion
});
}, myOptions);
if (unlock) await models.MdbApp.unlock(ctx, appName, myOptions);
if (tx) await tx.commit();
} catch (e) {

View File

@ -1,4 +1,7 @@
{
"MdbApp": {
"dataSource": "vn"
},
"MdbBranch": {
"dataSource": "vn"
},

View File

@ -0,0 +1,4 @@
module.exports = Self => {
require('../methods/mdbApp/lock')(Self);
require('../methods/mdbApp/unlock')(Self);
};

View File

@ -0,0 +1,31 @@
{
"name": "MdbApp",
"base": "VnModel",
"options": {
"mysql": {
"table": "mdbApp"
}
},
"properties": {
"app": {
"type": "string",
"description": "The app name",
"id": true
},
"locked": {
"type": "date"
}
},
"relations": {
"branch": {
"type": "belongsTo",
"model": "MdbBranch",
"foreignKey": "baselineBranchFk"
},
"user": {
"type": "belongsTo",
"model": "MdbBranch",
"foreignKey": "userFk"
}
}
}

View File

@ -38,6 +38,7 @@ module.exports = Self => {
date.setHours(0, 0, 0, 0);
const stmt = new ParameterizedSQL(`
SELECT
v.id,
u.name AS salesPerson,
IFNULL(sc.workerSubstitute, c.salesPersonFk) AS salesPersonFk,
c.id AS clientFk,

View File

@ -61,7 +61,7 @@
</tr>
</thead>
<tbody>
<tr ng-repeat="visit in model.data">
<tr ng-repeat="visit in model.data track by visit.id">
<td shrink-date>
<span class="chip">
{{::visit.dated | date:'dd/MM/yy'}}

Some files were not shown because too many files have changed in this diff Show More