Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 4858-chat_realTime
This commit is contained in:
commit
8dfc588a7e
|
@ -0,0 +1,17 @@
|
||||||
|
# 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
|
||||||
|
- [General](Inicio) Permite recuperar la contraseña
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
- [Tickets](Control clientes) Eliminada sección
|
|
@ -29,8 +29,12 @@ module.exports = Self => {
|
||||||
filter = mergeFilters(filter, {where});
|
filter = mergeFilters(filter, {where});
|
||||||
|
|
||||||
const stmt = new ParameterizedSQL(
|
const stmt = new ParameterizedSQL(
|
||||||
`SELECT * FROM campaign`);
|
`SELECT * FROM (`);
|
||||||
|
stmt.merge('SELECT * FROM campaign');
|
||||||
stmt.merge(conn.makeWhere(filter.where));
|
stmt.merge(conn.makeWhere(filter.where));
|
||||||
|
stmt.merge('ORDER BY dated ASC');
|
||||||
|
stmt.merge('LIMIT 10000000000000000000');
|
||||||
|
stmt.merge(') sub');
|
||||||
stmt.merge('GROUP BY code');
|
stmt.merge('GROUP BY code');
|
||||||
stmt.merge(conn.makePagination(filter));
|
stmt.merge(conn.makePagination(filter));
|
||||||
|
|
||||||
|
|
|
@ -26,11 +26,30 @@ module.exports = Self => {
|
||||||
|
|
||||||
Self.setSaleQuantity = async(saleId, quantity) => {
|
Self.setSaleQuantity = async(saleId, quantity) => {
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
|
const myOptions = {};
|
||||||
|
let tx;
|
||||||
|
|
||||||
const sale = await models.Sale.findById(saleId);
|
if (typeof options == 'object')
|
||||||
return await sale.updateAttributes({
|
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,
|
originalQuantity: sale.quantity,
|
||||||
quantity: quantity
|
quantity: quantity
|
||||||
});
|
}, myOptions);
|
||||||
|
|
||||||
|
if (tx) await tx.commit();
|
||||||
|
|
||||||
|
return saleUpdated;
|
||||||
|
} catch (e) {
|
||||||
|
if (tx) await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,15 +2,26 @@ const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
describe('setSaleQuantity()', () => {
|
describe('setSaleQuantity()', () => {
|
||||||
it('should change quantity sale', async() => {
|
it('should change quantity sale', async() => {
|
||||||
|
const tx = await models.Ticket.beginTransaction({});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
const saleId = 30;
|
const saleId = 30;
|
||||||
const newQuantity = 10;
|
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);
|
await models.Collection.setSaleQuantity(saleId, newQuantity, options);
|
||||||
const updateSale = await models.Sale.findById(saleId);
|
const updateSale = await models.Sale.findById(saleId, null, options);
|
||||||
|
|
||||||
expect(updateSale.originalQuantity).toEqual(originalSale.quantity);
|
expect(updateSale.originalQuantity).toEqual(originalSale.quantity);
|
||||||
expect(updateSale.quantity).toEqual(newQuantity);
|
expect(updateSale.quantity).toEqual(newQuantity);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
|
@ -6,6 +6,7 @@ module.exports = Self => {
|
||||||
require('../methods/dms/removeFile')(Self);
|
require('../methods/dms/removeFile')(Self);
|
||||||
require('../methods/dms/updateFile')(Self);
|
require('../methods/dms/updateFile')(Self);
|
||||||
require('../methods/dms/deleteTrashFiles')(Self);
|
require('../methods/dms/deleteTrashFiles')(Self);
|
||||||
|
require('../methods/dms/saveSign')(Self);
|
||||||
|
|
||||||
Self.checkRole = async function(ctx, id) {
|
Self.checkRole = async function(ctx, id) {
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
|
|
|
@ -12,14 +12,9 @@ BEGIN
|
||||||
* @param vAuthorFk The notification author or %NULL if there is no author
|
* @param vAuthorFk The notification author or %NULL if there is no author
|
||||||
* @return The notification id
|
* @return The notification id
|
||||||
*/
|
*/
|
||||||
DECLARE vNotificationFk INT;
|
|
||||||
|
|
||||||
SELECT id INTO vNotificationFk
|
|
||||||
FROM `notification`
|
|
||||||
WHERE `name` = vNotificationName;
|
|
||||||
|
|
||||||
INSERT INTO notificationQueue
|
INSERT INTO notificationQueue
|
||||||
SET notificationFk = vNotificationFk,
|
SET notificationFk = vNotificationName,
|
||||||
params = vParams,
|
params = vParams,
|
||||||
authorFk = vAuthorFk;
|
authorFk = vAuthorFk;
|
||||||
|
|
||||||
|
|
|
@ -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');
|
|
@ -0,0 +1 @@
|
||||||
|
INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalId`) VALUES ('Dms','saveSign','*','ALLOW','employee');
|
|
@ -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 ;
|
|
@ -0,0 +1,3 @@
|
||||||
|
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
|
||||||
|
VALUES
|
||||||
|
('TicketLog', 'getChanges', 'READ', 'ALLOW', 'ROLE', 'employee');
|
|
@ -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
|
|
@ -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 ;
|
|
@ -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 ;
|
|
@ -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
|
|
@ -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');
|
|
@ -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 ;
|
|
@ -0,0 +1,2 @@
|
||||||
|
DROP PROCEDURE IF EXISTS `ticket_split`;
|
||||||
|
DROP PROCEDURE IF EXISTS `ticket_merge`;
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
|
@ -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');
|
|
@ -0,0 +1,2 @@
|
||||||
|
DELETE FROM `salix`.`ACL` WHERE model="SaleChecked";
|
||||||
|
DROP TABLE IF EXISTS `vn`.`saleChecked`;
|
|
@ -690,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()),
|
(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()),
|
(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()),
|
(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`)
|
INSERT INTO `vn`.`ticketObservation`(`id`, `ticketFk`, `observationTypeFk`, `description`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -991,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()),
|
(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()),
|
(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()),
|
(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`)
|
INSERT INTO `vn`.`saleChecked`(`saleFk`, `isChecked`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -1333,9 +1335,9 @@ INSERT INTO `vn`.`itemTypeTag`(`id`, `itemTypeFk`, `tagFk`, `priority`)
|
||||||
|
|
||||||
CALL `vn`.`itemRefreshTags`(NULL);
|
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
|
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`)
|
INSERT INTO `vn`.`recovery`(`id`, `clientFk`, `started`, `finished`, `amount`, `period`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -2650,7 +2652,7 @@ INSERT INTO `vn`.`mdbVersion` (`app`, `branchFk`, `version`)
|
||||||
|
|
||||||
INSERT INTO `vn`.`accountingConfig` (`id`, `minDate`, `maxDate`)
|
INSERT INTO `vn`.`accountingConfig` (`id`, `minDate`, `maxDate`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, '2022-01-01', '2023-01-01');
|
(1, CONCAT(YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 YEAR)), '-01-01'), CONCAT(YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL +1 YEAR)), '-01-01'));
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO `vn`.`saleGroup` (`userFk`, `parkingFk`, `sectorFk`)
|
INSERT INTO `vn`.`saleGroup` (`userFk`, `parkingFk`, `sectorFk`)
|
||||||
|
@ -2689,7 +2691,8 @@ INSERT INTO `util`.`notificationConfig`
|
||||||
|
|
||||||
INSERT INTO `util`.`notification` (`id`, `name`, `description`)
|
INSERT INTO `util`.`notification` (`id`, `name`, `description`)
|
||||||
VALUES
|
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`)
|
INSERT INTO `util`.`notificationAcl` (`notificationFk`, `roleFk`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -2704,7 +2707,8 @@ INSERT INTO `util`.`notificationQueue` (`id`, `notificationFk`, `params`, `autho
|
||||||
INSERT INTO `util`.`notificationSubscription` (`notificationFk`, `userFk`)
|
INSERT INTO `util`.`notificationSubscription` (`notificationFk`, `userFk`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 1109),
|
(1, 1109),
|
||||||
(1, 1110);
|
(1, 1110),
|
||||||
|
(3, 1109);
|
||||||
|
|
||||||
INSERT INTO `vn`.`routeConfig` (`id`, `defaultWorkCenterFk`)
|
INSERT INTO `vn`.`routeConfig` (`id`, `defaultWorkCenterFk`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -2730,14 +2734,27 @@ UPDATE `account`.`user`
|
||||||
SET `hasGrant` = 1
|
SET `hasGrant` = 1
|
||||||
WHERE `id` = 66;
|
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`)
|
INSERT INTO `vn`.`osTicketConfig` (`id`, `host`, `user`, `password`, `oldStatus`, `newStatusId`, `day`, `comment`, `hostDb`, `userDb`, `passwordDb`, `portDb`, `responseType`, `fromEmailId`, `replyTo`)
|
||||||
VALUES
|
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');
|
(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`)
|
INSERT INTO `vn`.`ticketLog` (`id`, `originFk`, `userFk`, `action`, `changedModel`, `oldInstance`, `newInstance`, `changedModelId`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 1, 9, 'insert', 'Ticket', '{}', '{"clientFk":1, "nickname": "Bat cave"}', 1);
|
(1, 1, 9, 'insert', 'Ticket', '{}', '{"clientFk":1, "nickname": "Bat cave"}', 1);
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO `salix`.`url` (`appName`, `environment`, `url`)
|
INSERT INTO `salix`.`url` (`appName`, `environment`, `url`)
|
||||||
VALUES
|
VALUES
|
||||||
('lilium', 'dev', 'http://localhost:8080/#/'),
|
('lilium', 'dev', 'http://localhost:8080/#/'),
|
||||||
|
@ -2746,3 +2763,4 @@ INSERT INTO `salix`.`url` (`appName`, `environment`, `url`)
|
||||||
INSERT INTO `vn`.`payDemDetail` (`id`, `detail`)
|
INSERT INTO `vn`.`payDemDetail` (`id`, `detail`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 1);
|
(1, 1);
|
||||||
|
|
||||||
|
|
|
@ -16340,6 +16340,185 @@ CREATE TABLE `invoiceType` (
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
|
||||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `movConta`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `movConta`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!40101 SET character_set_client = utf8 */;
|
||||||
|
CREATE TABLE `movConta` (
|
||||||
|
`OrdenMovimientos` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`MovPosicion` varchar(64) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`Ejercicio` smallint(6) NOT NULL,
|
||||||
|
`CodigoEmpresa` smallint(6) NOT NULL,
|
||||||
|
`Asiento` int(11) NOT NULL,
|
||||||
|
`CargoAbono` varchar(1) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`CodigoCuenta` varchar(15) CHARACTER SET utf8mb3 NOT NULL,
|
||||||
|
`Contrapartida` varchar(15) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`FechaAsiento` datetime NOT NULL,
|
||||||
|
`TipoDocumento` varchar(6) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`DocumentoConta` varchar(9) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`Comentario` varchar(40) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`ImporteAsiento` decimal(28,10) NOT NULL,
|
||||||
|
`CodigoDiario` smallint(6) NOT NULL,
|
||||||
|
`CodigoCanal` varchar(10) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`CodigoActividad` varchar(1) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`FechaVencimiento` datetime DEFAULT NULL,
|
||||||
|
`NumeroPeriodo` smallint(6) NOT NULL,
|
||||||
|
`CodigoUsuario` smallint(6) NOT NULL,
|
||||||
|
`FechaGrabacion` datetime NOT NULL,
|
||||||
|
`TipoEntrada` varchar(2) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`CodigoDepartamento` varchar(10) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`CodigoSeccion` varchar(10) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`CodigoDivisa` varchar(3) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`ImporteCambio` decimal(28,10) NOT NULL,
|
||||||
|
`ImporteDivisa` decimal(28,10) NOT NULL,
|
||||||
|
`FactorCambio` decimal(28,10) NOT NULL,
|
||||||
|
`CodigoProyecto` varchar(10) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`LibreN1` int(11) NOT NULL,
|
||||||
|
`LibreN2` int(11) NOT NULL,
|
||||||
|
`LibreA1` varchar(15) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`LibreA2` varchar(15) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`IdDelegacion` varchar(10) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`MovCartera` varchar(64) COLLATE utf8mb3_unicode_ci DEFAULT NULL,
|
||||||
|
`IdProcesoIME` varchar(64) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`TipoCarteraIME` smallint(6) NOT NULL,
|
||||||
|
`TipoAnaliticaIME` smallint(6) NOT NULL,
|
||||||
|
`StatusTraspasadoIME` tinyint(4) NOT NULL,
|
||||||
|
`TipoImportacionIME` tinyint(4) NOT NULL,
|
||||||
|
`BaseIva1` decimal(28,10) NOT NULL,
|
||||||
|
`PorBaseCorrectora1` decimal(28,10) NOT NULL,
|
||||||
|
`PorIva1` decimal(28,10) NOT NULL,
|
||||||
|
`CuotaIva1` decimal(28,10) NOT NULL,
|
||||||
|
`PorRecargoEquivalencia1` decimal(28,10) NOT NULL,
|
||||||
|
`RecargoEquivalencia1` decimal(28,10) NOT NULL,
|
||||||
|
`CodigoTransaccion1` tinyint(4) NOT NULL,
|
||||||
|
`BaseIva2` decimal(28,10) NOT NULL,
|
||||||
|
`PorBaseCorrectora2` decimal(28,10) NOT NULL,
|
||||||
|
`PorIva2` decimal(28,10) NOT NULL,
|
||||||
|
`CuotaIva2` decimal(28,10) NOT NULL,
|
||||||
|
`PorRecargoEquivalencia2` decimal(28,10) NOT NULL,
|
||||||
|
`RecargoEquivalencia2` decimal(28,10) NOT NULL,
|
||||||
|
`CodigoTransaccion2` tinyint(4) NOT NULL,
|
||||||
|
`BaseIva3` decimal(28,10) NOT NULL,
|
||||||
|
`PorBaseCorrectora3` decimal(28,10) NOT NULL,
|
||||||
|
`PorIva3` decimal(28,10) NOT NULL,
|
||||||
|
`CuotaIva3` decimal(28,10) NOT NULL,
|
||||||
|
`PorRecargoEquivalencia3` decimal(28,10) NOT NULL,
|
||||||
|
`RecargoEquivalencia3` decimal(28,10) NOT NULL,
|
||||||
|
`CodigoTransaccion3` tinyint(4) NOT NULL,
|
||||||
|
`baseIva4` decimal(28,10) NOT NULL,
|
||||||
|
`PorBaseCorrectora4` decimal(28,10) NOT NULL,
|
||||||
|
`PorIva4` decimal(28,10) NOT NULL,
|
||||||
|
`CuotaIva4` decimal(28,10) NOT NULL,
|
||||||
|
`PorRecargoEquivalencia4` decimal(28,10) NOT NULL,
|
||||||
|
`RecargoEquivalencia4` decimal(28,10) NOT NULL,
|
||||||
|
`CodigoTransaccion4` tinyint(4) NOT NULL,
|
||||||
|
`Año` smallint(6) NOT NULL,
|
||||||
|
`Serie` varchar(10) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`Factura` int(11) NOT NULL,
|
||||||
|
`SuFacturaNo` varchar(40) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`FechaFactura` datetime NOT NULL,
|
||||||
|
`ImporteFactura` decimal(28,10) NOT NULL,
|
||||||
|
`TipoFactura` varchar(1) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`CodigoCuentaFactura` varchar(15) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`CifDni` varchar(13) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`Nombre` varchar(35) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`CodigoRetencion` smallint(6) NOT NULL,
|
||||||
|
`BaseRetencion` decimal(28,10) NOT NULL,
|
||||||
|
`PorRetencion` decimal(28,10) NOT NULL,
|
||||||
|
`ImporteRetencion` decimal(28,10) NOT NULL,
|
||||||
|
`AbonoIva` smallint(6) NOT NULL,
|
||||||
|
`CodigoActividadF` varchar(1) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`Intracomunitaria` smallint(6) NOT NULL,
|
||||||
|
`CodigoTerritorio` smallint(6) NOT NULL,
|
||||||
|
`SiglaNacion` varchar(2) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`RetencionInformativa` smallint(6) NOT NULL,
|
||||||
|
`EjercicioFacturaOriginal` smallint(6) NOT NULL,
|
||||||
|
`SerieFacturaOriginal` varchar(10) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`NumeroFacturaOriginal` int(11) NOT NULL,
|
||||||
|
`EjercicioFactura` smallint(6) NOT NULL,
|
||||||
|
`CobroPagoRetencion` varchar(1) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`FechaOperacion` datetime NOT NULL,
|
||||||
|
`Exclusion347` smallint(6) NOT NULL,
|
||||||
|
`MovIdentificadorIME` varchar(64) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`Previsiones` varchar(1) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`MantenerAsiento` tinyint(4) NOT NULL,
|
||||||
|
`OrdenMovIME` smallint(6) NOT NULL,
|
||||||
|
`Metalico347` smallint(6) NOT NULL,
|
||||||
|
`ClaveOperacionFactura_` varchar(1) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`SerieAgrupacion_` varchar(10) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`NumeroFacturaInicial_` int(11) NOT NULL,
|
||||||
|
`NumeroFacturaFinal_` int(11) NOT NULL,
|
||||||
|
`IdAsientoExterno` text COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`IdDiarioExterno` varchar(10) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`IdFacturaExterno` text COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`IdMovimiento` varchar(40) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`IdCuadre` smallint(6) NOT NULL,
|
||||||
|
`FechaCuadre` datetime NOT NULL,
|
||||||
|
`TipoCuadre` varchar(4) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`AgrupacionCuadre` int(11) NOT NULL,
|
||||||
|
`StatusSaldo` smallint(6) NOT NULL,
|
||||||
|
`StatusConciliacion` smallint(6) NOT NULL,
|
||||||
|
`CodigoConciliacion` int(11) NOT NULL,
|
||||||
|
`FechaConciliacion` datetime NOT NULL,
|
||||||
|
`TipoConciliacion` smallint(6) NOT NULL,
|
||||||
|
`IndicadorContaBanco` varchar(1) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`Descripcion3` varchar(40) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`Descripcion4` varchar(40) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`Descripcion5` varchar(40) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`Descripcion6` varchar(40) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`Descripcion7` varchar(40) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`Descripcion8` text COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`Descripcion9` text COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`Descripcion2` text COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`Descripcion1` text COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`Punteo1` smallint(6) NOT NULL,
|
||||||
|
`Punteo9` smallint(6) NOT NULL,
|
||||||
|
`Punteo8` smallint(6) NOT NULL,
|
||||||
|
`Punteo7` smallint(6) NOT NULL,
|
||||||
|
`Punteo6` smallint(6) NOT NULL,
|
||||||
|
`Punteo5` smallint(6) NOT NULL,
|
||||||
|
`Punteo4` smallint(6) NOT NULL,
|
||||||
|
`Punteo3` smallint(6) NOT NULL,
|
||||||
|
`Punteo2` smallint(6) NOT NULL,
|
||||||
|
`CodigoIva1` smallint(6) NOT NULL,
|
||||||
|
`CodigoIva2` smallint(6) NOT NULL,
|
||||||
|
`CodigoIva3` smallint(6) NOT NULL,
|
||||||
|
`CodigoIva4` smallint(6) NOT NULL,
|
||||||
|
`CriterioIva` tinyint(4) NOT NULL,
|
||||||
|
`FechaMaxVencimiento` datetime NOT NULL,
|
||||||
|
`TipoCriterioCaja` tinyint(4) NOT NULL,
|
||||||
|
`MovFacturaOrigenIME` text COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`IdFacturaExternoFinal` text COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`IdFacturaExternoInicial` text COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`IdFacturaExternoOriginal` text COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`NumFacturasExternoAgrupacion` int(11) NOT NULL,
|
||||||
|
`CodigoMedioCobro` varchar(1) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`MedioCobro` varchar(31) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`IvaDeducible1` smallint(6) NOT NULL DEFAULT 1,
|
||||||
|
`IvaDeducible2` smallint(6) NOT NULL DEFAULT 1,
|
||||||
|
`IvaDeducible3` smallint(6) NOT NULL DEFAULT 1,
|
||||||
|
`IvaDeducible4` smallint(6) NOT NULL DEFAULT 1,
|
||||||
|
`TipoRectificativa` smallint(6) NOT NULL,
|
||||||
|
`FechaFacturaOriginal` datetime NOT NULL,
|
||||||
|
`BaseImponibleOriginal` decimal(28,10) NOT NULL,
|
||||||
|
`CuotaIvaOriginal` decimal(28,10) NOT NULL,
|
||||||
|
`ClaseAbonoRectificativas` smallint(6) NOT NULL,
|
||||||
|
`RecargoEquivalenciaOriginal` decimal(28,10) NOT NULL,
|
||||||
|
`ObjetoFactura` text COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||||
|
`enlazadoSage` tinyint(1) NOT NULL DEFAULT 0,
|
||||||
|
PRIMARY KEY (`OrdenMovimientos`,`LibreN1`),
|
||||||
|
KEY `ix_movconta2` (`IdProcesoIME`),
|
||||||
|
KEY `CodigoCuenta` (`CodigoCuenta`),
|
||||||
|
KEY `movConta_Asiento` (`Asiento`),
|
||||||
|
KEY `ix_movconta` (`enlazadoSage`,`IdProcesoIME`),
|
||||||
|
KEY `movConta_IdProcesoIME` (`IdProcesoIME`),
|
||||||
|
KEY `movConta_Asiento2` (`Asiento`,`IdProcesoIME`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Table structure for table `movContaIVA`
|
-- Table structure for table `movContaIVA`
|
||||||
--
|
--
|
||||||
|
|
|
@ -84,7 +84,6 @@ IGNORETABLES=(
|
||||||
--ignore-table=vn.warehouseJoined
|
--ignore-table=vn.warehouseJoined
|
||||||
--ignore-table=vn.workerTeam__
|
--ignore-table=vn.workerTeam__
|
||||||
--ignore-table=vn.XDiario__
|
--ignore-table=vn.XDiario__
|
||||||
--ignore-table=sage.movConta
|
|
||||||
--ignore-table=sage.movContaCopia
|
--ignore-table=sage.movContaCopia
|
||||||
)
|
)
|
||||||
mysqldump \
|
mysqldump \
|
||||||
|
|
|
@ -30,7 +30,7 @@ export default {
|
||||||
firstModuleRemovePinIcon: 'vn-home a:nth-child(1) vn-icon[icon="remove_circle"]'
|
firstModuleRemovePinIcon: 'vn-home a:nth-child(1) vn-icon[icon="remove_circle"]'
|
||||||
},
|
},
|
||||||
recoverPassword: {
|
recoverPassword: {
|
||||||
recoverPasswordButton: 'vn-login a[ui-sref="recoverPassword"]',
|
recoverPasswordButton: 'vn-login a[ui-sref="recover-password"]',
|
||||||
email: 'vn-recover-password vn-textfield[ng-model="$ctrl.email"]',
|
email: 'vn-recover-password vn-textfield[ng-model="$ctrl.email"]',
|
||||||
sendEmailButton: 'vn-recover-password vn-submit',
|
sendEmailButton: 'vn-recover-password vn-submit',
|
||||||
},
|
},
|
||||||
|
@ -311,10 +311,12 @@ export default {
|
||||||
firstMandateText: 'vn-client-mandate vn-card vn-table vn-tbody > vn-tr'
|
firstMandateText: 'vn-client-mandate vn-card vn-table vn-tbody > vn-tr'
|
||||||
},
|
},
|
||||||
clientLog: {
|
clientLog: {
|
||||||
lastModificationPreviousValue: 'vn-client-log vn-table vn-td.before',
|
lastModificationPreviousValue: 'vn-client-log vn-tr table tr td.before',
|
||||||
lastModificationCurrentValue: 'vn-client-log vn-table vn-td.after',
|
lastModificationCurrentValue: 'vn-client-log vn-tr table tr td.after',
|
||||||
penultimateModificationPreviousValue: 'vn-client-log vn-table vn-tr:nth-child(2) vn-td.before',
|
namePreviousValue: 'vn-client-log vn-tr table tr:nth-child(1) td.before',
|
||||||
penultimateModificationCurrentValue: 'vn-client-log vn-table vn-tr:nth-child(2) vn-td.after'
|
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: {
|
clientBalance: {
|
||||||
|
@ -518,7 +520,7 @@ export default {
|
||||||
},
|
},
|
||||||
itemLog: {
|
itemLog: {
|
||||||
anyLineCreated: 'vn-item-log > vn-log vn-tbody > vn-tr',
|
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: {
|
ticketSummary: {
|
||||||
header: 'vn-ticket-summary > vn-card > h5',
|
header: 'vn-ticket-summary > vn-card > h5',
|
||||||
|
@ -711,9 +713,10 @@ export default {
|
||||||
ticketLog: {
|
ticketLog: {
|
||||||
firstTD: 'vn-ticket-log vn-table vn-td:nth-child(1)',
|
firstTD: 'vn-ticket-log vn-table vn-td:nth-child(1)',
|
||||||
logButton: 'vn-left-menu a[ui-sref="ticket.card.log"]',
|
logButton: 'vn-left-menu a[ui-sref="ticket.card.log"]',
|
||||||
firstLogEntry: 'vn-ticket-log vn-data-viewer vn-tbody vn-tr',
|
user: 'vn-ticket-log vn-tbody vn-tr vn-td:nth-child(2)',
|
||||||
changes: 'vn-ticket-log vn-data-viewer vn-tbody > vn-tr > vn-td:nth-child(7)',
|
action: 'vn-ticket-log vn-tbody vn-tr vn-td:nth-child(4)',
|
||||||
id: 'vn-ticket-log vn-tr:nth-child(1) vn-one:nth-child(1) span'
|
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: {
|
ticketService: {
|
||||||
addServiceButton: 'vn-ticket-service vn-icon-button[vn-tooltip="Add service"] > button',
|
addServiceButton: 'vn-ticket-service vn-icon-button[vn-tooltip="Add service"] > button',
|
||||||
|
@ -735,18 +738,16 @@ export default {
|
||||||
},
|
},
|
||||||
ticketFuture: {
|
ticketFuture: {
|
||||||
openAdvancedSearchButton: 'vn-searchbar .append vn-icon[icon="arrow_drop_down"]',
|
openAdvancedSearchButton: 'vn-searchbar .append vn-icon[icon="arrow_drop_down"]',
|
||||||
originDated: 'vn-date-picker[label="Origin ETD"]',
|
originDated: 'vn-date-picker[label="Origin date"]',
|
||||||
futureDated: 'vn-date-picker[label="Destination ETD"]',
|
futureDated: 'vn-date-picker[label="Destination date"]',
|
||||||
shipped: 'vn-date-picker[label="Origin date"]',
|
|
||||||
tfShipped: 'vn-date-picker[label="Destination date"]',
|
|
||||||
linesMax: 'vn-textfield[label="Max Lines"]',
|
linesMax: 'vn-textfield[label="Max Lines"]',
|
||||||
litersMax: 'vn-textfield[label="Max Liters"]',
|
litersMax: 'vn-textfield[label="Max Liters"]',
|
||||||
ipt: 'vn-autocomplete[label="Origin IPT"]',
|
ipt: 'vn-autocomplete[label="Origin IPT"]',
|
||||||
tfIpt: 'vn-autocomplete[label="Destination IPT"]',
|
futureIpt: 'vn-autocomplete[label="Destination IPT"]',
|
||||||
tableIpt: 'vn-autocomplete[name="ipt"]',
|
tableIpt: 'vn-autocomplete[name="ipt"]',
|
||||||
tableTfIpt: 'vn-autocomplete[name="tfIpt"]',
|
tableFutureIpt: 'vn-autocomplete[name="futureIpt"]',
|
||||||
state: 'vn-autocomplete[label="Origin Grouped State"]',
|
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"]',
|
warehouseFk: 'vn-autocomplete[label="Warehouse"]',
|
||||||
problems: 'vn-check[label="With problems"]',
|
problems: 'vn-check[label="With problems"]',
|
||||||
tableButtonSearch: 'vn-button[vn-tooltip="Search"]',
|
tableButtonSearch: 'vn-button[vn-tooltip="Search"]',
|
||||||
|
@ -755,9 +756,34 @@ export default {
|
||||||
firstCheck: 'tbody > tr:nth-child(1) > td > vn-check',
|
firstCheck: 'tbody > tr:nth-child(1) > td > vn-check',
|
||||||
multiCheck: 'vn-multi-check',
|
multiCheck: 'vn-multi-check',
|
||||||
tableId: 'vn-textfield[name="id"]',
|
tableId: 'vn-textfield[name="id"]',
|
||||||
tableTfId: 'vn-textfield[name="ticketFuture"]',
|
tableFutureId: 'vn-textfield[name="futureId"]',
|
||||||
tableLiters: 'vn-textfield[name="litersMax"]',
|
tableLiters: 'vn-textfield[name="liters"]',
|
||||||
tableLines: 'vn-textfield[name="linesMax"]',
|
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"]',
|
submit: 'vn-submit[label="Search"]',
|
||||||
table: 'tbody > tr:not(.empty-rows)'
|
table: 'tbody > tr:not(.empty-rows)'
|
||||||
},
|
},
|
||||||
|
@ -1100,7 +1126,7 @@ export default {
|
||||||
undoChanges: 'vn-travel-basic-data vn-button[label="Undo changes"]'
|
undoChanges: 'vn-travel-basic-data vn-button[label="Undo changes"]'
|
||||||
},
|
},
|
||||||
travelLog: {
|
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: {
|
travelThermograph: {
|
||||||
add: 'vn-travel-thermograph-index vn-float-button[icon="add"]',
|
add: 'vn-travel-thermograph-index vn-float-button[icon="add"]',
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import selectors from '../../helpers/selectors';
|
import selectors from '../../helpers/selectors';
|
||||||
import getBrowser from '../../helpers/puppeteer';
|
import getBrowser from '../../helpers/puppeteer';
|
||||||
|
|
||||||
describe('Login path', async() => {
|
describe('RecoverPassword path', async() => {
|
||||||
let browser;
|
let browser;
|
||||||
let page;
|
let page;
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ describe('Login path', async() => {
|
||||||
page = browser.page;
|
page = browser.page;
|
||||||
|
|
||||||
await page.waitToClick(selectors.recoverPassword.recoverPasswordButton);
|
await page.waitToClick(selectors.recoverPassword.recoverPasswordButton);
|
||||||
await page.waitForState('recoverPassword');
|
await page.waitForState('recover-password');
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async() => {
|
afterAll(async() => {
|
||||||
|
|
|
@ -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() => {
|
it(`should confirm the last log shows the updated client name and no modifications on active checkbox`, async() => {
|
||||||
let lastModificationPreviousValue = await page
|
let namePreviousValue = await page
|
||||||
.waitToGetProperty(selectors.clientLog.lastModificationPreviousValue, 'innerText');
|
.waitToGetProperty(selectors.clientLog.namePreviousValue, 'innerText');
|
||||||
let lastModificationCurrentValue = await page
|
let nameCurrentValue = await page
|
||||||
.waitToGetProperty(selectors.clientLog.lastModificationCurrentValue, 'innerText');
|
.waitToGetProperty(selectors.clientLog.nameCurrentValue, 'innerText');
|
||||||
|
|
||||||
expect(lastModificationPreviousValue).toEqual('name MaxEisenhardt active false');
|
expect(namePreviousValue).toEqual('MaxEisenhardt');
|
||||||
expect(lastModificationCurrentValue).toEqual('name Legion active false');
|
expect(nameCurrentValue).toEqual('Legion');
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should confirm the penultimate log shows the updated active and no modifications on client name`, async() => {
|
it(`should confirm the penultimate log shows the updated active and no modifications on client name`, async() => {
|
||||||
let penultimateModificationPreviousValue = await page
|
let activePreviousValue = await page
|
||||||
.waitToGetProperty(selectors.clientLog.penultimateModificationPreviousValue, 'innerText');
|
.waitToGetProperty(selectors.clientLog.activePreviousValue, 'innerText');
|
||||||
let penultimateModificationCurrentValue = await page
|
let activeCurrentValue = await page
|
||||||
.waitToGetProperty(selectors.clientLog.penultimateModificationCurrentValue, 'innerText');
|
.waitToGetProperty(selectors.clientLog.activeCurrentValue, 'innerText');
|
||||||
|
|
||||||
expect(penultimateModificationPreviousValue).toEqual('name MaxEisenhardt active true');
|
expect(activePreviousValue).toEqual('✓');
|
||||||
expect(penultimateModificationCurrentValue).toEqual('name MaxEisenhardt active false');
|
expect(activeCurrentValue).toEqual('✗');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -43,7 +43,7 @@ describe('Client log path', () => {
|
||||||
let lastModificationCurrentValue = await page.
|
let lastModificationCurrentValue = await page.
|
||||||
waitToGetProperty(selectors.clientLog.lastModificationCurrentValue, 'innerText');
|
waitToGetProperty(selectors.clientLog.lastModificationCurrentValue, 'innerText');
|
||||||
|
|
||||||
expect(lastModificationPreviousValue).toEqual('name DavidCharlesHaller');
|
expect(lastModificationPreviousValue).toEqual('DavidCharlesHaller');
|
||||||
expect(lastModificationCurrentValue).toEqual('name this is a test');
|
expect(lastModificationCurrentValue).toEqual('this is a test');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -58,6 +58,7 @@ describe('Worker time control path', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should return error when insert 'out' of first entry`, async() => {
|
it(`should return error when insert 'out' of first entry`, async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
await page.waitToClick(selectors.workerTimeControl.mondayAddTimeButton);
|
await page.waitToClick(selectors.workerTimeControl.mondayAddTimeButton);
|
||||||
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, eightAm);
|
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, eightAm);
|
||||||
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'out');
|
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'out');
|
||||||
|
@ -68,6 +69,7 @@ describe('Worker time control path', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should insert 'in' monday`, async() => {
|
it(`should insert 'in' monday`, async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
await page.waitToClick(selectors.workerTimeControl.mondayAddTimeButton);
|
await page.waitToClick(selectors.workerTimeControl.mondayAddTimeButton);
|
||||||
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, eightAm);
|
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, eightAm);
|
||||||
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'in');
|
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'in');
|
||||||
|
@ -78,6 +80,7 @@ describe('Worker time control path', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should insert 'out' monday`, async() => {
|
it(`should insert 'out' monday`, async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
await page.waitToClick(selectors.workerTimeControl.mondayAddTimeButton);
|
await page.waitToClick(selectors.workerTimeControl.mondayAddTimeButton);
|
||||||
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, fourPm);
|
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, fourPm);
|
||||||
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'out');
|
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'out');
|
||||||
|
@ -88,11 +91,13 @@ describe('Worker time control path', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should check Hank Pym worked 8:20 hours`, async() => {
|
it(`should check Hank Pym worked 8:20 hours`, async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
await page.waitForTextInElement(selectors.workerTimeControl.mondayWorkedHours, '08:20 h.');
|
await page.waitForTextInElement(selectors.workerTimeControl.mondayWorkedHours, '08:20 h.');
|
||||||
await page.waitForTextInElement(selectors.workerTimeControl.weekWorkedHours, '08:20 h.');
|
await page.waitForTextInElement(selectors.workerTimeControl.weekWorkedHours, '08:20 h.');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should remove first entry of monday', async() => {
|
it('should remove first entry of monday', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
await page.waitForTextInElement(selectors.workerTimeControl.firstEntryOfMonday, eightAm);
|
await page.waitForTextInElement(selectors.workerTimeControl.firstEntryOfMonday, eightAm);
|
||||||
await page.waitForTextInElement(selectors.workerTimeControl.secondEntryOfMonday, fourPm);
|
await page.waitForTextInElement(selectors.workerTimeControl.secondEntryOfMonday, fourPm);
|
||||||
await page.waitToClick(selectors.workerTimeControl.firstEntryOfMondayDelete);
|
await page.waitToClick(selectors.workerTimeControl.firstEntryOfMondayDelete);
|
||||||
|
@ -103,6 +108,7 @@ describe('Worker time control path', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should be the 'out' the first entry of monday`, async() => {
|
it(`should be the 'out' the first entry of monday`, async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
const result = await page.waitToGetProperty(selectors.workerTimeControl.firstEntryOfMonday, 'innerText');
|
const result = await page.waitToGetProperty(selectors.workerTimeControl.firstEntryOfMonday, 'innerText');
|
||||||
|
|
||||||
expect(result).toEqual(fourPm);
|
expect(result).toEqual(fourPm);
|
||||||
|
|
|
@ -127,8 +127,8 @@ describe('Item regularize path', () => {
|
||||||
await page.waitForState('ticket.index');
|
await page.waitForState('ticket.index');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should search for the ticket with id 31 once again', async() => {
|
it('should search for the ticket missing once again', async() => {
|
||||||
await page.accessToSearchResult('31');
|
await page.accessToSearchResult('Missing');
|
||||||
await page.waitForState('ticket.card.summary');
|
await page.waitForState('ticket.card.summary');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -32,14 +32,17 @@ describe('Ticket expeditions and log path', () => {
|
||||||
|
|
||||||
it(`should confirm the expedition deleted is shown now in the ticket log`, async() => {
|
it(`should confirm the expedition deleted is shown now in the ticket log`, async() => {
|
||||||
await page.accessToSection('ticket.card.log');
|
await page.accessToSection('ticket.card.log');
|
||||||
const firstLogEntry = await page
|
const user = await page
|
||||||
.waitToGetProperty(selectors.ticketLog.firstLogEntry, 'innerText');
|
.waitToGetProperty(selectors.ticketLog.user, 'innerText');
|
||||||
|
|
||||||
|
const action = await page
|
||||||
|
.waitToGetProperty(selectors.ticketLog.action, 'innerText');
|
||||||
|
|
||||||
const id = await page
|
const id = await page
|
||||||
.waitToGetProperty(selectors.ticketLog.id, 'innerText');
|
.waitToGetProperty(selectors.ticketLog.id, 'innerText');
|
||||||
|
|
||||||
expect(firstLogEntry).toContain('production');
|
expect(user).toContain('production');
|
||||||
expect(firstLogEntry).toContain('Deletes');
|
expect(action).toContain('Deletes');
|
||||||
expect(id).toEqual('2');
|
expect(id).toEqual('2');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -55,6 +55,6 @@ describe('Ticket log path', () => {
|
||||||
|
|
||||||
const result = await page.waitToGetProperty(selectors.ticketLog.firstTD, 'innerText');
|
const result = await page.waitToGetProperty(selectors.ticketLog.firstTD, 'innerText');
|
||||||
|
|
||||||
expect(result.length).toBeGreaterThan('20');
|
expect(result.length).toBeGreaterThan('15');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -16,9 +16,6 @@ describe('Ticket Future path', () => {
|
||||||
await browser.close();
|
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() => {
|
it('should show errors snackbar because of the required data', async() => {
|
||||||
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
|
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
|
||||||
await page.clearInput(selectors.ticketFuture.warehouseFk);
|
await page.clearInput(selectors.ticketFuture.warehouseFk);
|
||||||
|
@ -27,20 +24,6 @@ describe('Ticket Future path', () => {
|
||||||
|
|
||||||
expect(message.text).toContain('warehouseFk is a required argument');
|
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.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
|
||||||
await page.clearInput(selectors.ticketFuture.futureDated);
|
await page.clearInput(selectors.ticketFuture.futureDated);
|
||||||
await page.waitToClick(selectors.ticketFuture.submit);
|
await page.waitToClick(selectors.ticketFuture.submit);
|
||||||
|
@ -62,44 +45,13 @@ describe('Ticket Future path', () => {
|
||||||
await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
|
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() => {
|
it('should search with the origin IPT', async() => {
|
||||||
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
|
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.ipt);
|
||||||
await page.clearInput(selectors.ticketFuture.tfIpt);
|
await page.clearInput(selectors.ticketFuture.futureIpt);
|
||||||
await page.clearInput(selectors.ticketFuture.state);
|
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.autocompleteSearch(selectors.ticketFuture.ipt, 'Horizontal');
|
||||||
await page.waitToClick(selectors.ticketFuture.submit);
|
await page.waitToClick(selectors.ticketFuture.submit);
|
||||||
|
@ -109,14 +61,12 @@ describe('Ticket Future path', () => {
|
||||||
it('should search with the destination IPT', async() => {
|
it('should search with the destination IPT', async() => {
|
||||||
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
|
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.ipt);
|
||||||
await page.clearInput(selectors.ticketFuture.tfIpt);
|
await page.clearInput(selectors.ticketFuture.futureIpt);
|
||||||
await page.clearInput(selectors.ticketFuture.state);
|
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.waitToClick(selectors.ticketFuture.submit);
|
||||||
await page.waitForNumberOfElements(selectors.ticketFuture.table, 0);
|
await page.waitForNumberOfElements(selectors.ticketFuture.table, 0);
|
||||||
});
|
});
|
||||||
|
@ -124,12 +74,10 @@ describe('Ticket Future path', () => {
|
||||||
it('should search with the origin grouped state', async() => {
|
it('should search with the origin grouped state', async() => {
|
||||||
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
|
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.ipt);
|
||||||
await page.clearInput(selectors.ticketFuture.tfIpt);
|
await page.clearInput(selectors.ticketFuture.futureIpt);
|
||||||
await page.clearInput(selectors.ticketFuture.state);
|
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.autocompleteSearch(selectors.ticketFuture.state, 'Free');
|
||||||
await page.waitToClick(selectors.ticketFuture.submit);
|
await page.waitToClick(selectors.ticketFuture.submit);
|
||||||
|
@ -139,24 +87,20 @@ describe('Ticket Future path', () => {
|
||||||
it('should search with the destination grouped state', async() => {
|
it('should search with the destination grouped state', async() => {
|
||||||
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
|
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.ipt);
|
||||||
await page.clearInput(selectors.ticketFuture.tfIpt);
|
await page.clearInput(selectors.ticketFuture.futureIpt);
|
||||||
await page.clearInput(selectors.ticketFuture.state);
|
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.waitToClick(selectors.ticketFuture.submit);
|
||||||
await page.waitForNumberOfElements(selectors.ticketFuture.table, 0);
|
await page.waitForNumberOfElements(selectors.ticketFuture.table, 0);
|
||||||
|
|
||||||
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
|
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.ipt);
|
||||||
await page.clearInput(selectors.ticketFuture.tfIpt);
|
await page.clearInput(selectors.ticketFuture.futureIpt);
|
||||||
await page.clearInput(selectors.ticketFuture.state);
|
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.waitToClick(selectors.ticketFuture.submit);
|
||||||
await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
|
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() => {
|
it('should search in smart-table with an ID Destination', async() => {
|
||||||
await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
|
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.keyboard.press('Enter');
|
||||||
await page.waitForNumberOfElements(selectors.ticketFuture.table, 5);
|
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() => {
|
it('should search in smart-table with an IPT Destination', async() => {
|
||||||
await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
|
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.waitForNumberOfElements(selectors.ticketFuture.table, 1);
|
||||||
|
|
||||||
await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
|
await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
|
|
@ -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!');
|
||||||
|
});
|
||||||
|
});
|
|
@ -70,8 +70,8 @@ describe('Supplier basic data path', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should check the changes have been recorded', async() => {
|
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');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -14,6 +14,7 @@ export default class CrudModel extends ModelProxy {
|
||||||
this.$q = $q;
|
this.$q = $q;
|
||||||
this.primaryKey = 'id';
|
this.primaryKey = 'id';
|
||||||
this.autoLoad = false;
|
this.autoLoad = false;
|
||||||
|
this.page = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
$onInit() {
|
$onInit() {
|
||||||
|
@ -125,13 +126,20 @@ export default class CrudModel extends ModelProxy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loadMore() {
|
loadMore(append) {
|
||||||
if (!this.moreRows)
|
if (!this.moreRows)
|
||||||
return this.$q.resolve();
|
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;
|
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() {
|
clear() {
|
||||||
|
|
|
@ -148,7 +148,7 @@ describe('Component vnCrudModel', () => {
|
||||||
|
|
||||||
controller.moreRows = true;
|
controller.moreRows = true;
|
||||||
|
|
||||||
controller.loadMore();
|
controller.loadMore(true);
|
||||||
|
|
||||||
expect(controller.sendRequest).toHaveBeenCalledWith({'skip': 2}, true);
|
expect(controller.sendRequest).toHaveBeenCalledWith({'skip': 2}, true);
|
||||||
});
|
});
|
||||||
|
|
|
@ -212,12 +212,12 @@ export default class DropDown extends Popover {
|
||||||
&& !this.model.isLoading;
|
&& !this.model.isLoading;
|
||||||
|
|
||||||
if (shouldLoad)
|
if (shouldLoad)
|
||||||
this.model.loadMore();
|
this.model.loadMore(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
onLoadMoreClick(event) {
|
onLoadMoreClick(event) {
|
||||||
if (event.defaultPrevented) return;
|
if (event.defaultPrevented) return;
|
||||||
this.model.loadMore();
|
this.model.loadMore(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
onContainerClick(event) {
|
onContainerClick(event) {
|
||||||
|
|
|
@ -374,9 +374,10 @@ export class Paginable {
|
||||||
/**
|
/**
|
||||||
* When limit is enabled, loads the next set of rows.
|
* When limit is enabled, loads the next set of rows.
|
||||||
*
|
*
|
||||||
|
* @param {Boolean} append - Whether should append new data
|
||||||
* @return {Promise} The request promise
|
* @return {Promise} The request promise
|
||||||
*/
|
*/
|
||||||
loadMore() {
|
loadMore(append) {
|
||||||
return Promise.resolve();
|
return Promise.resolve(append);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,7 @@ class Pagination extends Component {
|
||||||
|
|
||||||
if (shouldLoad) {
|
if (shouldLoad) {
|
||||||
this.nLoads++;
|
this.nLoads++;
|
||||||
this.model.loadMore();
|
this.model.loadMore(false);
|
||||||
this.$.$apply();
|
this.$.$apply();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ class Pagination extends Component {
|
||||||
if (this.maxLoads > 0 && this.nLoads == this.maxLoads)
|
if (this.maxLoads > 0 && this.nLoads == this.maxLoads)
|
||||||
this.nLoads = 0;
|
this.nLoads = 0;
|
||||||
|
|
||||||
this.model.loadMore();
|
this.model.loadMore(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
$onDestroy() {
|
$onDestroy() {
|
||||||
|
|
|
@ -147,7 +147,7 @@ export default class SmartTable extends Component {
|
||||||
for (const column of this.columns) {
|
for (const column of this.columns) {
|
||||||
if (viewConfig.configuration[column.field] == false) {
|
if (viewConfig.configuration[column.field] == false) {
|
||||||
const baseSelector = `smart-table[view-config-id="${this.viewConfigId}"] table`;
|
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})`);
|
selectors.push(`${baseSelector} tbody > tr > td:nth-child(${column.index + 1})`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -235,7 +235,7 @@ export default class SmartTable extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
registerColumns() {
|
registerColumns() {
|
||||||
const header = this.element.querySelector('thead > tr');
|
const header = this.element.querySelector('thead > tr:not([second-header])');
|
||||||
if (!header) return;
|
if (!header) return;
|
||||||
const columns = header.querySelectorAll('th');
|
const columns = header.querySelectorAll('th');
|
||||||
|
|
||||||
|
@ -254,7 +254,7 @@ export default class SmartTable extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
emptyDataRows() {
|
emptyDataRows() {
|
||||||
const header = this.element.querySelector('thead > tr');
|
const header = this.element.querySelector('thead > tr:not([second-header])');
|
||||||
const columns = header.querySelectorAll('th');
|
const columns = header.querySelectorAll('th');
|
||||||
const tbody = this.element.querySelector('tbody');
|
const tbody = this.element.querySelector('tbody');
|
||||||
if (tbody) {
|
if (tbody) {
|
||||||
|
@ -333,7 +333,7 @@ export default class SmartTable extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
displaySearch() {
|
displaySearch() {
|
||||||
const header = this.element.querySelector('thead > tr');
|
const header = this.element.querySelector('thead > tr:not([second-header])');
|
||||||
if (!header) return;
|
if (!header) return;
|
||||||
|
|
||||||
const tbody = this.element.querySelector('tbody');
|
const tbody = this.element.querySelector('tbody');
|
||||||
|
|
|
@ -8,6 +8,16 @@ smart-table table {
|
||||||
& > thead {
|
& > thead {
|
||||||
border-bottom: $border;
|
border-bottom: $border;
|
||||||
|
|
||||||
|
& > tr[second-header] {
|
||||||
|
& > th
|
||||||
|
{
|
||||||
|
text-align: center;
|
||||||
|
border-bottom-style: groove;
|
||||||
|
font-weight: bold;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
& > * > th {
|
& > * > th {
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
@ -60,6 +70,9 @@ smart-table table {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&[separator]{
|
||||||
|
border-left-style: groove;
|
||||||
|
}
|
||||||
vn-icon.bright, i.bright {
|
vn-icon.bright, i.bright {
|
||||||
color: #f7931e;
|
color: #f7931e;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ export default class Auth {
|
||||||
initialize() {
|
initialize() {
|
||||||
let criteria = {
|
let criteria = {
|
||||||
to: state => {
|
to: state => {
|
||||||
const outLayout = ['login', 'recoverPassword', 'resetPassword'];
|
const outLayout = ['login', 'recover-password', 'reset-password'];
|
||||||
return !outLayout.some(ol => ol == state.name);
|
return !outLayout.some(ol => ol == state.name);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,6 +3,13 @@
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"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": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "salix-front",
|
"name": "salix-front",
|
||||||
|
@ -174,11 +181,22 @@
|
||||||
"version": "1.0.30",
|
"version": "1.0.30",
|
||||||
"resolved": "https://registry.npmjs.org/@uirouter/angularjs/-/angularjs-1.0.30.tgz",
|
"resolved": "https://registry.npmjs.org/@uirouter/angularjs/-/angularjs-1.0.30.tgz",
|
||||||
"integrity": "sha512-qkc3RFZc91S5K0gc/QVAXc9LGDPXjR04vDgG/11j8+yyZEuQojXxKxdLhKIepiPzqLmGRVqzBmBc27gtqaEeZg==",
|
"integrity": "sha512-qkc3RFZc91S5K0gc/QVAXc9LGDPXjR04vDgG/11j8+yyZEuQojXxKxdLhKIepiPzqLmGRVqzBmBc27gtqaEeZg==",
|
||||||
|
>>>>>>> dev
|
||||||
"requires": {
|
"requires": {
|
||||||
"@uirouter/core": "6.0.8"
|
"@uirouter/core": "6.0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@uirouter/core": {
|
"@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",
|
"version": "6.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/@uirouter/core/-/core-6.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/@uirouter/core/-/core-6.0.8.tgz",
|
||||||
"integrity": "sha512-Gc/BAW47i4L54p8dqYCJJZuv2s3tqlXQ0fvl6Zp2xrblELPVfxmjnc0eurx3XwfQdaqm3T6uls6tQKkof/4QMw=="
|
"integrity": "sha512-Gc/BAW47i4L54p8dqYCJJZuv2s3tqlXQ0fvl6Zp2xrblELPVfxmjnc0eurx3XwfQdaqm3T6uls6tQKkof/4QMw=="
|
||||||
|
@ -187,6 +205,7 @@
|
||||||
"version": "1.8.3",
|
"version": "1.8.3",
|
||||||
"resolved": "https://registry.npmjs.org/angular/-/angular-1.8.3.tgz",
|
"resolved": "https://registry.npmjs.org/angular/-/angular-1.8.3.tgz",
|
||||||
"integrity": "sha512-5qjkWIQQVsHj4Sb5TcEs4WZWpFeVFHXwxEBHUhrny41D8UrBAd6T/6nPPAsLngJCReIOqi95W3mxdveveutpZw=="
|
"integrity": "sha512-5qjkWIQQVsHj4Sb5TcEs4WZWpFeVFHXwxEBHUhrny41D8UrBAd6T/6nPPAsLngJCReIOqi95W3mxdveveutpZw=="
|
||||||
|
>>>>>>> dev
|
||||||
},
|
},
|
||||||
"angular-animate": {
|
"angular-animate": {
|
||||||
"version": "1.8.2",
|
"version": "1.8.2",
|
||||||
|
@ -202,17 +221,29 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"angular-translate": {
|
"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",
|
"version": "2.19.0",
|
||||||
"resolved": "https://registry.npmjs.org/angular-translate/-/angular-translate-2.19.0.tgz",
|
"resolved": "https://registry.npmjs.org/angular-translate/-/angular-translate-2.19.0.tgz",
|
||||||
"integrity": "sha512-Z/Fip5uUT2N85dPQ0sMEe1JdF5AehcDe4tg/9mWXNDVU531emHCg53ZND9Oe0dyNiGX5rWcJKmsL1Fujus1vGQ==",
|
"integrity": "sha512-Z/Fip5uUT2N85dPQ0sMEe1JdF5AehcDe4tg/9mWXNDVU531emHCg53ZND9Oe0dyNiGX5rWcJKmsL1Fujus1vGQ==",
|
||||||
|
>>>>>>> dev
|
||||||
"requires": {
|
"requires": {
|
||||||
"angular": "^1.8.0"
|
"angular": "^1.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"angular-translate-loader-partial": {
|
"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",
|
"version": "2.19.0",
|
||||||
"resolved": "https://registry.npmjs.org/angular-translate-loader-partial/-/angular-translate-loader-partial-2.19.0.tgz",
|
"resolved": "https://registry.npmjs.org/angular-translate-loader-partial/-/angular-translate-loader-partial-2.19.0.tgz",
|
||||||
"integrity": "sha512-NnMw13LMV4bPQmJK7/pZOZAnPxe0M5OtUHchADs5Gye7V7feonuEnrZ8e1CKhBlv9a7IQyWoqcBa4Lnhg8gk5w==",
|
"integrity": "sha512-NnMw13LMV4bPQmJK7/pZOZAnPxe0M5OtUHchADs5Gye7V7feonuEnrZ8e1CKhBlv9a7IQyWoqcBa4Lnhg8gk5w==",
|
||||||
|
>>>>>>> dev
|
||||||
"requires": {
|
"requires": {
|
||||||
"angular-translate": "~2.19.0"
|
"angular-translate": "~2.19.0"
|
||||||
}
|
}
|
||||||
|
@ -253,9 +284,15 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"moment": {
|
"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",
|
"version": "2.29.4",
|
||||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
|
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
|
||||||
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
|
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
|
||||||
|
>>>>>>> dev
|
||||||
},
|
},
|
||||||
"oclazyload": {
|
"oclazyload": {
|
||||||
"version": "0.6.3",
|
"version": "0.6.3",
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
<vn-layout
|
<ui-view></ui-view>
|
||||||
ng-if="$ctrl.showLayout">
|
|
||||||
</vn-layout>
|
|
||||||
<vn-out-layout
|
|
||||||
ng-if="!$ctrl.showLayout">
|
|
||||||
</vn-out-layout>
|
|
||||||
<vn-snackbar vn-id="snackbar"></vn-snackbar>
|
<vn-snackbar vn-id="snackbar"></vn-snackbar>
|
||||||
<vn-debug-info></vn-debug-info>
|
<vn-debug-info></vn-debug-info>
|
||||||
|
|
|
@ -19,12 +19,6 @@ export default class App extends Component {
|
||||||
this.vnApp.logger = this;
|
this.vnApp.logger = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
get showLayout() {
|
|
||||||
const state = this.$state.current.name || this.$location.$$path.substring(1).replace('/', '.');
|
|
||||||
const outLayout = ['login', 'recoverPassword', 'resetPassword'];
|
|
||||||
return state && !outLayout.some(ol => ol == state);
|
|
||||||
}
|
|
||||||
|
|
||||||
$onDestroy() {
|
$onDestroy() {
|
||||||
this.deregisterCallback();
|
this.deregisterCallback();
|
||||||
this.vnApp.logger = null;
|
this.vnApp.logger = null;
|
||||||
|
|
|
@ -5,10 +5,10 @@ import './descriptor-popover';
|
||||||
import './home/home';
|
import './home/home';
|
||||||
import './layout';
|
import './layout';
|
||||||
import './left-menu/left-menu';
|
import './left-menu/left-menu';
|
||||||
import './login/index';
|
import './login';
|
||||||
import './login/login';
|
import './outLayout';
|
||||||
import './login/recover-password';
|
import './recover-password';
|
||||||
import './login/reset-password';
|
import './reset-password';
|
||||||
import './module-card';
|
import './module-card';
|
||||||
import './module-main';
|
import './module-main';
|
||||||
import './side-menu/side-menu';
|
import './side-menu/side-menu';
|
||||||
|
@ -19,3 +19,4 @@ import './user-popover';
|
||||||
import './upload-photo';
|
import './upload-photo';
|
||||||
import './bank-entity';
|
import './bank-entity';
|
||||||
import './log';
|
import './log';
|
||||||
|
import './sendSms';
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
url="{{$ctrl.url}}"
|
url="{{$ctrl.url}}"
|
||||||
filter="$ctrl.filter"
|
filter="$ctrl.filter"
|
||||||
link="{originFk: $ctrl.originId}"
|
link="{originFk: $ctrl.originId}"
|
||||||
|
where="{changedModel: $ctrl.changedModel,
|
||||||
|
changedModelId: $ctrl.changedModelId}"
|
||||||
data="$ctrl.logs"
|
data="$ctrl.logs"
|
||||||
limit="20"
|
limit="20"
|
||||||
auto-load="true">
|
auto-load="true">
|
||||||
|
@ -13,81 +15,53 @@
|
||||||
<vn-thead>
|
<vn-thead>
|
||||||
<vn-tr>
|
<vn-tr>
|
||||||
<vn-th field="creationDate">Date</vn-th>
|
<vn-th field="creationDate">Date</vn-th>
|
||||||
<vn-th field="userFk" class="expendable" shrink>Author</vn-th>
|
<vn-th field="userFk" shrink>User</vn-th>
|
||||||
<vn-th field="changedModel" class="expendable">Model</vn-th>
|
<vn-th field="changedModel" ng-if="$ctrl.showModelName" shrink>Model</vn-th>
|
||||||
<vn-th field="action" class="expendable" shrink>Action</vn-th>
|
<vn-th field="action" shrink>Action</vn-th>
|
||||||
<vn-th field="changedModelValue" class="expendable">Name</vn-th>
|
<vn-th field="changedModelValue" ng-if="$ctrl.showModelName">Name</vn-th>
|
||||||
<vn-th expand>Before</vn-th>
|
<vn-th expand>Changes</vn-th>
|
||||||
<vn-th expand>After</vn-th>
|
|
||||||
</vn-tr>
|
</vn-tr>
|
||||||
</vn-thead>
|
</vn-thead>
|
||||||
<vn-tbody>
|
<vn-tbody>
|
||||||
<vn-tr ng-repeat="log in $ctrl.logs">
|
<vn-tr ng-repeat="log in $ctrl.logs">
|
||||||
<vn-td shrink-datetime>
|
<vn-td shrink-datetime>
|
||||||
{{::log.creationDate | date:'dd/MM/yyyy HH:mm'}}
|
{{::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>
|
||||||
<vn-td class="expendable">
|
<vn-td>
|
||||||
<span ng-class="{'link': log.user.worker.id, 'value': !log.user.worker.id}"
|
<span ng-class="{'link': log.user.worker.id, 'value': !log.user.worker.id}"
|
||||||
ng-click="$ctrl.showWorkerDescriptor($event, log.user.worker.id)"
|
ng-click="$ctrl.showWorkerDescriptor($event, log.user.worker.id)"
|
||||||
translate>{{::log.user.name || 'System' | translate}}
|
translate>{{::log.user.name || 'System' | translate}}
|
||||||
</span>
|
</span>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td class="expendable">
|
<vn-td ng-if="$ctrl.showModelName">
|
||||||
{{::log.changedModel}}
|
{{::log.changedModel}}
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td translate class="expendable">
|
<vn-td shrink translate>
|
||||||
{{::$ctrl.actionsText[log.action]}}
|
{{::$ctrl.actionsText[log.action]}}
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td class="expendable" expand>
|
<vn-td ng-if="$ctrl.showModelName">
|
||||||
{{::log.changedModelValue}}
|
{{::log.changedModelValue}}
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td expand class="before">
|
<vn-td expand>
|
||||||
<vn-one ng-repeat="old in log.oldProperties">
|
<table class="attributes">
|
||||||
<div>
|
<thead>
|
||||||
<vn-label-value
|
<tr>
|
||||||
no-ellipsize
|
<th translate class="field">Field</th>
|
||||||
label="{{::old.key}}"
|
<th translate>Before</th>
|
||||||
value="{{::old.value}}">
|
<th translate>After</th>
|
||||||
</vn-label-value>
|
</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>
|
</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-td>
|
||||||
</vn-tr>
|
</vn-tr>
|
||||||
</vn-tbody>
|
</vn-tbody>
|
||||||
|
|
|
@ -2,15 +2,17 @@ import ngModule from '../../module';
|
||||||
import Section from '../section';
|
import Section from '../section';
|
||||||
import './style.scss';
|
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 {
|
export default class Controller extends Section {
|
||||||
constructor($element, $) {
|
constructor($element, $) {
|
||||||
super($element, $);
|
super($element, $);
|
||||||
this.actionsText = {
|
this.actionsText = {
|
||||||
'insert': 'Creates',
|
insert: 'Creates',
|
||||||
'update': 'Updates',
|
update: 'Updates',
|
||||||
'delete': 'Deletes',
|
delete: 'Deletes',
|
||||||
'select': 'Views'
|
select: 'Views'
|
||||||
}; ``;
|
};
|
||||||
this.filter = {
|
this.filter = {
|
||||||
include: [{
|
include: [{
|
||||||
relation: 'user',
|
relation: 'user',
|
||||||
|
@ -33,32 +35,57 @@ export default class Controller extends Section {
|
||||||
|
|
||||||
set logs(value) {
|
set logs(value) {
|
||||||
this._logs = value;
|
this._logs = value;
|
||||||
if (!value) return;
|
if (!this.logs) return;
|
||||||
|
const empty = {};
|
||||||
const validations = window.validations;
|
const validations = window.validations;
|
||||||
value.forEach(log => {
|
for (const log of value) {
|
||||||
const locale = validations[log.changedModel] && validations[log.changedModel].locale ? validations[log.changedModel].locale : {};
|
const oldValues = log.oldInstance || empty;
|
||||||
|
const newValues = log.newInstance || empty;
|
||||||
|
const locale = validations[log.changedModel]?.locale || empty;
|
||||||
|
|
||||||
log.oldProperties = this.getInstance(log.oldInstance, locale);
|
let props = Object.keys(oldValues).concat(Object.keys(newValues));
|
||||||
log.newProperties = this.getInstance(log.newInstance, locale);
|
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) {
|
showWorkerDescriptor(event, workerId) {
|
||||||
|
@ -73,6 +100,8 @@ ngModule.vnComponent('vnLog', {
|
||||||
bindings: {
|
bindings: {
|
||||||
model: '<',
|
model: '<',
|
||||||
originId: '<',
|
originId: '<',
|
||||||
|
changedModel: '<?',
|
||||||
|
changedModelId: '<?',
|
||||||
url: '@'
|
url: '@'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,3 +12,4 @@ Deletes: Elimina
|
||||||
Views: Visualiza
|
Views: Visualiza
|
||||||
System: Sistema
|
System: Sistema
|
||||||
note: nota
|
note: nota
|
||||||
|
Changes: Cambios
|
||||||
|
|
|
@ -23,6 +23,28 @@ vn-log {
|
||||||
display: block;
|
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 {
|
.ellipsis {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|
|
@ -1,6 +1,27 @@
|
||||||
<div class="box">
|
<vn-textfield
|
||||||
<img src="./logo.svg"/>
|
label="User"
|
||||||
<form name="form">
|
ng-model="$ctrl.user"
|
||||||
<ui-view></ui-view>
|
vn-id="userField"
|
||||||
</form>
|
vn-focus>
|
||||||
|
</vn-textfield>
|
||||||
|
<vn-textfield
|
||||||
|
label="Password"
|
||||||
|
ng-model="$ctrl.password"
|
||||||
|
type="password">
|
||||||
|
</vn-textfield>
|
||||||
|
<vn-check
|
||||||
|
label="Do not close session"
|
||||||
|
ng-model="$ctrl.remember"
|
||||||
|
name="remember">
|
||||||
|
</vn-check>
|
||||||
|
<div class="footer">
|
||||||
|
<vn-submit label="Enter" ng-click="$ctrl.submit()"></vn-submit>
|
||||||
|
<div class="spinner-wrapper">
|
||||||
|
<vn-spinner enable="$ctrl.loading"></vn-spinner>
|
||||||
|
</div>
|
||||||
|
<div class="vn-pt-lg">
|
||||||
|
<a ui-sref="recover-password" translate>
|
||||||
|
I do not remember my password
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,16 +1,43 @@
|
||||||
import ngModule from '../../module';
|
import ngModule from '../../module';
|
||||||
import Component from 'core/lib/component';
|
|
||||||
import './style.scss';
|
import './style.scss';
|
||||||
|
|
||||||
export default class OutLayout extends Component {
|
/**
|
||||||
constructor($element, $scope) {
|
* A simple login form.
|
||||||
super($element, $scope);
|
*/
|
||||||
}
|
export default class Controller {
|
||||||
}
|
constructor($, $element, vnAuth) {
|
||||||
|
Object.assign(this, {
|
||||||
OutLayout.$inject = ['$element', '$scope'];
|
$,
|
||||||
|
$element,
|
||||||
ngModule.vnComponent('vnOutLayout', {
|
vnAuth,
|
||||||
template: require('./index.html'),
|
user: localStorage.getItem('lastUser'),
|
||||||
controller: OutLayout
|
remember: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
submit() {
|
||||||
|
this.loading = true;
|
||||||
|
this.vnAuth.login(this.user, this.password, this.remember)
|
||||||
|
.then(() => {
|
||||||
|
localStorage.setItem('lastUser', this.user);
|
||||||
|
this.loading = false;
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
this.loading = false;
|
||||||
|
this.password = '';
|
||||||
|
this.focusUser();
|
||||||
|
throw err;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
focusUser() {
|
||||||
|
this.$.userField.select();
|
||||||
|
this.$.userField.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Controller.$inject = ['$scope', '$element', 'vnAuth'];
|
||||||
|
|
||||||
|
ngModule.vnComponent('vnLogin', {
|
||||||
|
template: require('./index.html'),
|
||||||
|
controller: Controller
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,16 +1,5 @@
|
||||||
User: Usuario
|
User: Usuario
|
||||||
Password: Contraseña
|
Password: Contraseña
|
||||||
Email: Correo electrónico
|
|
||||||
Do not close session: No cerrar sesión
|
Do not close session: No cerrar sesión
|
||||||
Enter: Entrar
|
Enter: Entrar
|
||||||
I do not remember my password: No recuerdo mi contraseña
|
I do not remember my password: No recuerdo mi contraseña
|
||||||
Recover password: Recuperar contraseña
|
|
||||||
We will sent you an email to recover your password: Te enviaremos un correo para restablecer tu contraseña
|
|
||||||
Notification sent!: ¡Notificación enviada!
|
|
||||||
Reset password: Restrablecer contraseña
|
|
||||||
New password: Nueva contraseña
|
|
||||||
Repeat password: Repetir contraseña
|
|
||||||
Password requirements: >
|
|
||||||
La contraseña debe tener al menos {{ length }} caracteres de longitud,
|
|
||||||
{{nAlpha}} caracteres alfabéticos, {{nUpper}} letras mayúsculas, {{nDigits}}
|
|
||||||
dígitos y {{nPunct}} símbolos (Ej: $%&.)
|
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
<vn-textfield
|
|
||||||
label="User"
|
|
||||||
ng-model="$ctrl.user"
|
|
||||||
vn-id="userField"
|
|
||||||
vn-focus>
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-textfield
|
|
||||||
label="Password"
|
|
||||||
ng-model="$ctrl.password"
|
|
||||||
type="password">
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-check
|
|
||||||
label="Do not close session"
|
|
||||||
ng-model="$ctrl.remember"
|
|
||||||
name="remember">
|
|
||||||
</vn-check>
|
|
||||||
<div class="footer">
|
|
||||||
<vn-submit label="Enter" ng-click="$ctrl.submit()"></vn-submit>
|
|
||||||
<div class="spinner-wrapper">
|
|
||||||
<vn-spinner enable="$ctrl.loading"></vn-spinner>
|
|
||||||
</div>
|
|
||||||
<div class="vn-pt-lg">
|
|
||||||
<a ui-sref="recoverPassword" translate>
|
|
||||||
I do not remember my password
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,43 +0,0 @@
|
||||||
import ngModule from '../../module';
|
|
||||||
import './style.scss';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A simple login form.
|
|
||||||
*/
|
|
||||||
export default class Controller {
|
|
||||||
constructor($, $element, vnAuth) {
|
|
||||||
Object.assign(this, {
|
|
||||||
$,
|
|
||||||
$element,
|
|
||||||
vnAuth,
|
|
||||||
user: localStorage.getItem('lastUser'),
|
|
||||||
remember: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
submit() {
|
|
||||||
this.loading = true;
|
|
||||||
this.vnAuth.login(this.user, this.password, this.remember)
|
|
||||||
.then(() => {
|
|
||||||
localStorage.setItem('lastUser', this.user);
|
|
||||||
this.loading = false;
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
this.loading = false;
|
|
||||||
this.password = '';
|
|
||||||
this.focusUser();
|
|
||||||
throw err;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
focusUser() {
|
|
||||||
this.$.userField.select();
|
|
||||||
this.$.userField.focus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Controller.$inject = ['$scope', '$element', 'vnAuth'];
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnLogin', {
|
|
||||||
template: require('./login.html'),
|
|
||||||
controller: Controller
|
|
||||||
});
|
|
|
@ -1,8 +1,6 @@
|
||||||
@import "variables";
|
@import "variables";
|
||||||
|
|
||||||
vn-login,
|
vn-login{
|
||||||
vn-reset-password,
|
|
||||||
vn-recover-password{
|
|
||||||
.footer {
|
.footer {
|
||||||
margin-top: 32px;
|
margin-top: 32px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@ -24,69 +22,3 @@ vn-recover-password{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vn-out-layout{
|
|
||||||
position: absolute;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
color: $color-font;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
font-weight: normal;
|
|
||||||
background-color: $color-bg-dark;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
overflow: auto;
|
|
||||||
|
|
||||||
& > .box {
|
|
||||||
box-sizing: border-box;
|
|
||||||
position: absolute;
|
|
||||||
max-width: 304px;
|
|
||||||
min-width: 240px;
|
|
||||||
padding: 48px;
|
|
||||||
background-color: $color-bg-panel;
|
|
||||||
box-shadow: 0 0 16px 0 rgba(0, 0, 0, .6);
|
|
||||||
border-radius: 8px;
|
|
||||||
|
|
||||||
& > img {
|
|
||||||
width: 100%;
|
|
||||||
padding-bottom: 16px;
|
|
||||||
}
|
|
||||||
& > form {
|
|
||||||
& > .vn-textfield {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
& > .vn-check {
|
|
||||||
display: block;
|
|
||||||
.md-label {
|
|
||||||
white-space: inherit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
h5{
|
|
||||||
color: $color-primary;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-secondary{
|
|
||||||
text-align: center;
|
|
||||||
padding-bottom: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 600px) {
|
|
||||||
background-color: $color-bg-panel;
|
|
||||||
|
|
||||||
& > .box {
|
|
||||||
padding: 16px;
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
a{
|
|
||||||
color: $color-primary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
<div class="box">
|
||||||
|
<img src="./logo.svg"/>
|
||||||
|
<form name="form">
|
||||||
|
<ui-view></ui-view>
|
||||||
|
</form>
|
||||||
|
</div>
|
|
@ -0,0 +1,16 @@
|
||||||
|
import ngModule from '../../module';
|
||||||
|
import Component from 'core/lib/component';
|
||||||
|
import './style.scss';
|
||||||
|
|
||||||
|
export default class OutLayout extends Component {
|
||||||
|
constructor($element, $scope) {
|
||||||
|
super($element, $scope);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OutLayout.$inject = ['$element', '$scope'];
|
||||||
|
|
||||||
|
ngModule.vnComponent('vnOutLayout', {
|
||||||
|
template: require('./index.html'),
|
||||||
|
controller: OutLayout
|
||||||
|
});
|
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.2 KiB |
|
@ -0,0 +1,67 @@
|
||||||
|
@import "variables";
|
||||||
|
|
||||||
|
vn-out-layout{
|
||||||
|
position: absolute;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
color: $color-font;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-weight: normal;
|
||||||
|
background-color: $color-bg-dark;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
& > .box {
|
||||||
|
box-sizing: border-box;
|
||||||
|
position: absolute;
|
||||||
|
max-width: 304px;
|
||||||
|
min-width: 240px;
|
||||||
|
padding: 48px;
|
||||||
|
background-color: $color-bg-panel;
|
||||||
|
box-shadow: 0 0 16px 0 rgba(0, 0, 0, .6);
|
||||||
|
border-radius: 8px;
|
||||||
|
|
||||||
|
& > img {
|
||||||
|
width: 100%;
|
||||||
|
padding-bottom: 16px;
|
||||||
|
}
|
||||||
|
& > form {
|
||||||
|
& > .vn-textfield {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
& > .vn-check {
|
||||||
|
display: block;
|
||||||
|
.md-label {
|
||||||
|
white-space: inherit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h5{
|
||||||
|
color: $color-primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-secondary{
|
||||||
|
text-align: center;
|
||||||
|
padding-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 600px) {
|
||||||
|
background-color: $color-bg-panel;
|
||||||
|
|
||||||
|
& > .box {
|
||||||
|
padding: 16px;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a{
|
||||||
|
color: $color-primary;
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,6 +32,6 @@ export default class Controller {
|
||||||
Controller.$inject = ['$scope', '$element', '$http', 'vnApp', '$translate', '$state'];
|
Controller.$inject = ['$scope', '$element', '$http', 'vnApp', '$translate', '$state'];
|
||||||
|
|
||||||
ngModule.vnComponent('vnRecoverPassword', {
|
ngModule.vnComponent('vnRecoverPassword', {
|
||||||
template: require('./recover-password.html'),
|
template: require('./index.html'),
|
||||||
controller: Controller
|
controller: Controller
|
||||||
});
|
});
|
|
@ -0,0 +1,3 @@
|
||||||
|
Recover password: Recuperar contraseña
|
||||||
|
We will sent you an email to recover your password: Te enviaremos un correo para restablecer tu contraseña
|
||||||
|
Notification sent!: ¡Notificación enviada!
|
|
@ -0,0 +1,24 @@
|
||||||
|
@import "variables";
|
||||||
|
|
||||||
|
vn-recover-password{
|
||||||
|
.footer {
|
||||||
|
margin-top: 32px;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
& > .vn-submit {
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
& > input {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
& > .spinner-wrapper {
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
top: 3px;
|
||||||
|
right: -8px;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -43,6 +43,6 @@ export default class Controller {
|
||||||
Controller.$inject = ['$scope', '$element', '$http', 'vnApp', '$translate', '$state', '$location'];
|
Controller.$inject = ['$scope', '$element', '$http', 'vnApp', '$translate', '$state', '$location'];
|
||||||
|
|
||||||
ngModule.vnComponent('vnResetPassword', {
|
ngModule.vnComponent('vnResetPassword', {
|
||||||
template: require('./reset-password.html'),
|
template: require('./index.html'),
|
||||||
controller: Controller
|
controller: Controller
|
||||||
});
|
});
|
|
@ -1,7 +1,3 @@
|
||||||
User: User
|
|
||||||
Password: Password
|
|
||||||
Do not close session: Do not close session
|
|
||||||
Enter: Enter
|
|
||||||
Password requirements: >
|
Password requirements: >
|
||||||
The password must have at least {{ length }} length characters,
|
The password must have at least {{ length }} length characters,
|
||||||
{{nAlpha}} alphabetic characters, {{nUpper}} capital letters, {{nDigits}}
|
{{nAlpha}} alphabetic characters, {{nUpper}} capital letters, {{nDigits}}
|
|
@ -0,0 +1,8 @@
|
||||||
|
Reset password: Restrablecer contraseña
|
||||||
|
New password: Nueva contraseña
|
||||||
|
Repeat password: Repetir contraseñaç
|
||||||
|
Password changed!: ¡Contraseña cambiada!
|
||||||
|
Password requirements: >
|
||||||
|
La contraseña debe tener al menos {{ length }} caracteres de longitud,
|
||||||
|
{{nAlpha}} caracteres alfabéticos, {{nUpper}} letras mayúsculas, {{nDigits}}
|
||||||
|
dígitos y {{nPunct}} símbolos (Ej: $%&.)
|
|
@ -0,0 +1,24 @@
|
||||||
|
@import "variables";
|
||||||
|
|
||||||
|
vn-reset-password{
|
||||||
|
.footer {
|
||||||
|
margin-top: 32px;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
& > .vn-submit {
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
& > input {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
& > .spinner-wrapper {
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
top: 3px;
|
||||||
|
right: -8px;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,19 +1,26 @@
|
||||||
import ngModule from '../module';
|
import ngModule from '../../module';
|
||||||
import Component from 'core/lib/component';
|
|
||||||
import './style.scss';
|
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() {
|
open() {
|
||||||
this.$.SMSDialog.show();
|
this.$.SMSDialog.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
charactersRemaining() {
|
charactersRemaining() {
|
||||||
const element = this.$.message;
|
const element = this.sms.message;
|
||||||
const value = element.input.value;
|
|
||||||
|
|
||||||
const maxLength = 160;
|
const maxLength = 160;
|
||||||
const textAreaLength = new Blob([value]).size;
|
return maxLength - element.length;
|
||||||
return maxLength - textAreaLength;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onResponse() {
|
onResponse() {
|
||||||
|
@ -25,23 +32,19 @@ class Controller extends Component {
|
||||||
if (this.charactersRemaining() < 0)
|
if (this.charactersRemaining() < 0)
|
||||||
throw new Error(`The message it's too long`);
|
throw new Error(`The message it's too long`);
|
||||||
|
|
||||||
this.$http.post(`Tickets/${this.sms.ticketId}/sendSms`, this.sms).then(res => {
|
return this.onSend({$sms: this.sms});
|
||||||
this.vnApp.showMessage(this.$t('SMS sent!'));
|
|
||||||
|
|
||||||
if (res.data) this.emit('send', {response: res.data});
|
|
||||||
});
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.vnApp.showError(this.$t(e.message));
|
this.vnApp.showError(this.$t(e.message));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngModule.vnComponent('vnTicketSms', {
|
ngModule.vnComponent('vnSmsDialog', {
|
||||||
template: require('./index.html'),
|
template: require('./index.html'),
|
||||||
controller: Controller,
|
controller: sendSmsDialog,
|
||||||
bindings: {
|
bindings: {
|
||||||
sms: '<',
|
sms: '<',
|
||||||
|
onSend: '&',
|
||||||
}
|
}
|
||||||
});
|
});
|
|
@ -3,25 +3,38 @@ import getMainRoute from 'core/lib/get-main-route';
|
||||||
|
|
||||||
config.$inject = ['$stateProvider', '$urlRouterProvider'];
|
config.$inject = ['$stateProvider', '$urlRouterProvider'];
|
||||||
function config($stateProvider, $urlRouterProvider) {
|
function config($stateProvider, $urlRouterProvider) {
|
||||||
$urlRouterProvider.otherwise('/');
|
$urlRouterProvider
|
||||||
|
.otherwise('/');
|
||||||
|
|
||||||
$stateProvider
|
$stateProvider
|
||||||
|
.state('layout', {
|
||||||
|
abstract: true,
|
||||||
|
template: '<vn-layout></vn-layout>',
|
||||||
|
})
|
||||||
|
.state('outLayout', {
|
||||||
|
abstract: true,
|
||||||
|
template: '<vn-out-layout></vn-out-layout>',
|
||||||
|
})
|
||||||
.state('login', {
|
.state('login', {
|
||||||
|
parent: 'outLayout',
|
||||||
url: '/login?continue',
|
url: '/login?continue',
|
||||||
description: 'Login',
|
description: 'Login',
|
||||||
template: '<vn-login></vn-login>'
|
template: '<vn-login></vn-login>'
|
||||||
})
|
})
|
||||||
.state('recoverPassword', {
|
.state('recover-password', {
|
||||||
|
parent: 'outLayout',
|
||||||
url: '/recover-password',
|
url: '/recover-password',
|
||||||
description: 'Recover-password',
|
description: 'Recover password',
|
||||||
template: '<vn-recover-password>asd</vn-recover-password>'
|
template: '<vn-recover-password></vn-recover-password>'
|
||||||
})
|
})
|
||||||
.state('resetPassword', {
|
.state('reset-password', {
|
||||||
|
parent: 'outLayout',
|
||||||
url: '/reset-password',
|
url: '/reset-password',
|
||||||
description: 'Reset-password',
|
description: 'Reset password',
|
||||||
template: '<vn-reset-password></vn-reset-password>'
|
template: '<vn-reset-password></vn-reset-password>'
|
||||||
})
|
})
|
||||||
.state('home', {
|
.state('home', {
|
||||||
|
parent: 'layout',
|
||||||
url: '/',
|
url: '/',
|
||||||
description: 'Home',
|
description: 'Home',
|
||||||
template: '<vn-home></vn-home>'
|
template: '<vn-home></vn-home>'
|
||||||
|
@ -52,6 +65,10 @@ function config($stateProvider, $urlRouterProvider) {
|
||||||
};
|
};
|
||||||
if (route.abstract)
|
if (route.abstract)
|
||||||
configRoute.abstract = true;
|
configRoute.abstract = true;
|
||||||
|
|
||||||
|
if (!route.state.includes('.'))
|
||||||
|
configRoute.parent = 'layout';
|
||||||
|
|
||||||
if (route.routeParams)
|
if (route.routeParams)
|
||||||
configRoute.params = route.routeParams;
|
configRoute.params = route.routeParams;
|
||||||
|
|
||||||
|
|
|
@ -66,9 +66,10 @@
|
||||||
"MESSAGE_INSURANCE_CHANGE": "I have changed the insurence credit of client [{{clientName}} ({{clientId}})]({{{url}}}) to *{{credit}} €*",
|
"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}}})",
|
"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}}})",
|
"Sent units from ticket": "I sent *{{quantity}}* units of [{{concept}} ({{itemId}})]({{{itemUrl}}}) to *\"{{nickname}}\"* coming from ticket id [{{ticketId}}]({{{ticketUrl}}})",
|
||||||
"Claim will be picked": "The product from the claim [{{claimId}}]({{{claimUrl}}}) from the client *{{clientName}}* will be picked",
|
"Change quantity": "{{concept}} change of {{oldQuantity}} to {{newQuantity}}",
|
||||||
"Claim state has changed to incomplete": "The state of the claim [{{claimId}}]({{{claimUrl}}}) from client *{{clientName}}* has changed to *incomplete*",
|
"Claim will be picked": "The product from the claim [({{claimId}})]({{{claimUrl}}}) from the client *{{clientName}}* will be picked",
|
||||||
"Claim state has changed to canceled": "The state of the claim [{{claimId}}]({{{claimUrl}}}) from client *{{clientName}}* has changed to *canceled*",
|
"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*",
|
||||||
"Customs agent is required for a non UEE member": "Customs agent is required for a non UEE member",
|
"Customs agent is required for a non UEE member": "Customs agent is required for a non UEE member",
|
||||||
"Incoterms is required for a non UEE member": "Incoterms is required for a non UEE member",
|
"Incoterms is required for a non UEE member": "Incoterms is required for a non UEE member",
|
||||||
"Client checked as validated despite of duplication": "Client checked as validated despite of duplication from client id {{clientId}}",
|
"Client checked as validated despite of duplication": "Client checked as validated despite of duplication from client id {{clientId}}",
|
||||||
|
@ -140,8 +141,10 @@
|
||||||
"You don't have grant privilege": "You don't have grant privilege",
|
"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",
|
"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",
|
"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",
|
"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",
|
"Receipt's bank was not found": "Receipt's bank was not found",
|
||||||
"This receipt was not compensated": "This receipt was not compensated",
|
"This receipt was not compensated": "This receipt was not compensated",
|
||||||
"Client's email was not found": "Client's email was not found"
|
"Client's email was not found": "Client's email was not found"
|
||||||
|
|
|
@ -134,9 +134,10 @@
|
||||||
"MESSAGE_INSURANCE_CHANGE": "He cambiado el crédito asegurado del cliente [{{clientName}} ({{clientId}})]({{{url}}}) a *{{credit}} €*",
|
"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}}})",
|
"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}}})",
|
"Sent units from ticket": "Envio *{{quantity}}* unidades de [{{concept}} ({{itemId}})]({{{itemUrl}}}) a *\"{{nickname}}\"* provenientes del ticket id [{{ticketId}}]({{{ticketUrl}}})",
|
||||||
"Claim will be picked": "Se recogerá el género de la reclamación [{{claimId}}]({{{claimUrl}}}) del cliente *{{clientName}}*",
|
"Change quantity": "{{concept}} cambia de {{oldQuantity}} a {{newQuantity}}",
|
||||||
"Claim state has changed to incomplete": "Se ha cambiado el estado de la reclamación [{{claimId}}]({{{claimUrl}}}) del cliente *{{clientName}}* a *incompleta*",
|
"Claim will be picked": "Se recogerá el género de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}*",
|
||||||
"Claim state has changed to canceled": "Se ha cambiado el estado de la reclamación [{{claimId}}]({{{claimUrl}}}) del cliente *{{clientName}}* a *anulado*",
|
"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*",
|
||||||
"Client checked as validated despite of duplication": "Cliente comprobado a pesar de que existe el cliente id {{clientId}}",
|
"Client checked as validated despite of duplication": "Cliente comprobado a pesar de que existe el cliente id {{clientId}}",
|
||||||
"ORDER_ROW_UNAVAILABLE": "No hay disponibilidad de este producto",
|
"ORDER_ROW_UNAVAILABLE": "No hay disponibilidad de este producto",
|
||||||
"Distance must be lesser than 1000": "La distancia debe ser inferior a 1000",
|
"Distance must be lesser than 1000": "La distancia debe ser inferior a 1000",
|
||||||
|
@ -241,13 +242,15 @@
|
||||||
"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 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",
|
"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",
|
"Already has this status": "Ya tiene este estado",
|
||||||
"There aren't records for this week": "No existen registros para esta semana",
|
"There aren't records for this week": "No existen registros para esta semana",
|
||||||
"Empty data source": "Origen de datos vacio",
|
"Empty data source": "Origen de datos vacio",
|
||||||
|
"App locked": "Aplicación bloqueada por el usuario {{userId}}",
|
||||||
"Email verify": "Correo de verificación",
|
"Email verify": "Correo de verificación",
|
||||||
"Landing cannot be lesser than shipment": "Landing cannot be lesser than shipment",
|
"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",
|
"Receipt's bank was not found": "No se encontró el banco del recibo",
|
||||||
"This receipt was not compensated": "Este recibo no ha sido compensado",
|
"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"
|
||||||
}
|
}
|
|
@ -104,6 +104,9 @@
|
||||||
"SageTransactionType": {
|
"SageTransactionType": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
"TicketSms": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
"TpvError": {
|
"TpvError": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
|
|
@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -113,10 +113,11 @@
|
||||||
</div>
|
</div>
|
||||||
</slot-body>
|
</slot-body>
|
||||||
</vn-descriptor-content>
|
</vn-descriptor-content>
|
||||||
<vn-client-sms
|
<vn-sms-dialog
|
||||||
vn-id="sms"
|
vn-id="sms"
|
||||||
|
on-send="$ctrl.onSmsSend($sms)"
|
||||||
sms="$ctrl.newSMS">
|
sms="$ctrl.newSMS">
|
||||||
</vn-client-sms>
|
</vn-sms-dialog>
|
||||||
<vn-worker-descriptor-popover
|
<vn-worker-descriptor-popover
|
||||||
vn-id="workerDescriptor">
|
vn-id="workerDescriptor">
|
||||||
</vn-worker-descriptor-popover>
|
</vn-worker-descriptor-popover>
|
||||||
|
|
|
@ -39,6 +39,11 @@ class Controller extends Descriptor {
|
||||||
};
|
};
|
||||||
this.$.sms.open();
|
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', {
|
ngModule.vnComponent('vnClientDescriptor', {
|
||||||
|
|
|
@ -35,7 +35,6 @@ import './sample/index';
|
||||||
import './sample/create';
|
import './sample/create';
|
||||||
import './web-payment';
|
import './web-payment';
|
||||||
import './log';
|
import './log';
|
||||||
import './sms';
|
|
||||||
import './postcode';
|
import './postcode';
|
||||||
import './postcode/province';
|
import './postcode/province';
|
||||||
import './postcode/city';
|
import './postcode/city';
|
||||||
|
|
|
@ -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: '<',
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -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);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -73,6 +73,12 @@ export default class Controller extends Section {
|
||||||
this.vnApp.showSuccess(this.$t('Data saved!'));
|
this.vnApp.showSuccess(this.$t('Data saved!'));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
itemSearchFunc($search) {
|
||||||
|
return /^\d+$/.test($search)
|
||||||
|
? {id: $search}
|
||||||
|
: {name: {like: '%' + $search + '%'}};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngModule.vnComponent('vnEntryBuyIndex', {
|
ngModule.vnComponent('vnEntryBuyIndex', {
|
||||||
|
|
|
@ -9,31 +9,43 @@ module.exports = Self => {
|
||||||
accepts: [
|
accepts: [
|
||||||
{
|
{
|
||||||
arg: 'ids',
|
arg: 'ids',
|
||||||
type: ['number'],
|
type: 'string',
|
||||||
description: 'The invoice ids'
|
description: 'The invoices ids',
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
returns: {
|
returns: [
|
||||||
arg: 'base64',
|
{
|
||||||
type: 'string',
|
arg: 'body',
|
||||||
|
type: 'file',
|
||||||
root: true
|
root: true
|
||||||
},
|
}, {
|
||||||
|
arg: 'Content-Type',
|
||||||
|
type: 'string',
|
||||||
|
http: {target: 'header'}
|
||||||
|
}, {
|
||||||
|
arg: 'Content-Disposition',
|
||||||
|
type: 'string',
|
||||||
|
http: {target: 'header'}
|
||||||
|
}
|
||||||
|
],
|
||||||
http: {
|
http: {
|
||||||
path: '/downloadZip',
|
path: '/downloadZip',
|
||||||
verb: 'POST'
|
verb: 'GET'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.downloadZip = async function(ctx, ids, options) {
|
Self.downloadZip = async function(ctx, ids, options) {
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
const myOptions = {};
|
const myOptions = {};
|
||||||
|
const zip = new JSZip();
|
||||||
|
|
||||||
if (typeof options == 'object')
|
if (typeof options == 'object')
|
||||||
Object.assign(myOptions, options);
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
const zip = new JSZip();
|
|
||||||
let totalSize = 0;
|
|
||||||
const zipConfig = await models.ZipConfig.findOne(null, myOptions);
|
const zipConfig = await models.ZipConfig.findOne(null, myOptions);
|
||||||
|
let totalSize = 0;
|
||||||
|
ids = ids.split(',');
|
||||||
|
|
||||||
for (let id of ids) {
|
for (let id of ids) {
|
||||||
if (zipConfig && totalSize > zipConfig.maxSize) throw new UserError('Files are too large');
|
if (zipConfig && totalSize > zipConfig.maxSize) throw new UserError('Files are too large');
|
||||||
const invoiceOutPdf = await models.InvoiceOut.download(ctx, id, myOptions);
|
const invoiceOutPdf = await models.InvoiceOut.download(ctx, id, myOptions);
|
||||||
|
@ -44,8 +56,10 @@ module.exports = Self => {
|
||||||
totalSize += sizeInMegabytes;
|
totalSize += sizeInMegabytes;
|
||||||
zip.file(fileName, body);
|
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) {
|
function extractFileName(str) {
|
||||||
|
|
|
@ -3,7 +3,7 @@ const UserError = require('vn-loopback/util/user-error');
|
||||||
|
|
||||||
describe('InvoiceOut downloadZip()', () => {
|
describe('InvoiceOut downloadZip()', () => {
|
||||||
const userId = 9;
|
const userId = 9;
|
||||||
const invoiceIds = [1, 2];
|
const invoiceIds = '1,2';
|
||||||
const ctx = {
|
const ctx = {
|
||||||
req: {
|
req: {
|
||||||
|
|
||||||
|
|
|
@ -29,13 +29,13 @@ export default class Controller extends Section {
|
||||||
window.open(url, '_blank');
|
window.open(url, '_blank');
|
||||||
} else {
|
} else {
|
||||||
const invoiceOutIds = this.checked;
|
const invoiceOutIds = this.checked;
|
||||||
const params = {
|
const invoicesIds = invoiceOutIds.join(',');
|
||||||
ids: invoiceOutIds
|
const serializedParams = this.$httpParamSerializer({
|
||||||
};
|
access_token: this.vnToken.token,
|
||||||
this.$http.post(`InvoiceOuts/downloadZip`, params)
|
ids: invoicesIds
|
||||||
.then(res => {
|
|
||||||
location.href = 'data:application/zip;base64,' + res.data;
|
|
||||||
});
|
});
|
||||||
|
const url = `api/InvoiceOuts/downloadZip?${serializedParams}`;
|
||||||
|
window.open(url, '_blank');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
|
@ -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();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
|
@ -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();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
|
@ -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;
|
||||||
|
};
|
||||||
|
};
|
|
@ -23,6 +23,12 @@ module.exports = Self => {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
required: true,
|
required: true,
|
||||||
description: `The branch name`
|
description: `The branch name`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'unlock',
|
||||||
|
type: 'boolean',
|
||||||
|
required: false,
|
||||||
|
description: `It allows unlock the app`
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
returns: {
|
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 models = Self.app.models;
|
||||||
|
const userId = ctx.req.accessToken.userId;
|
||||||
const myOptions = {};
|
const myOptions = {};
|
||||||
|
const $t = ctx.req.__; // $translate
|
||||||
|
|
||||||
const TempContainer = models.TempContainer;
|
const TempContainer = models.TempContainer;
|
||||||
const AccessContainer = models.AccessContainer;
|
const AccessContainer = models.AccessContainer;
|
||||||
|
@ -55,6 +63,14 @@ module.exports = Self => {
|
||||||
|
|
||||||
let srcFile;
|
let srcFile;
|
||||||
try {
|
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 tempContainer = await TempContainer.container('access');
|
||||||
const uploaded = await TempContainer.upload(tempContainer.name, ctx.req, ctx.result, fileOptions);
|
const uploaded = await TempContainer.upload(tempContainer.name, ctx.req, ctx.result, fileOptions);
|
||||||
const files = Object.values(uploaded.files).map(file => {
|
const files = Object.values(uploaded.files).map(file => {
|
||||||
|
@ -79,7 +95,7 @@ module.exports = Self => {
|
||||||
|
|
||||||
const existBranch = await models.MdbBranch.findOne({
|
const existBranch = await models.MdbBranch.findOne({
|
||||||
where: {name: branch}
|
where: {name: branch}
|
||||||
});
|
}, myOptions);
|
||||||
|
|
||||||
if (!existBranch)
|
if (!existBranch)
|
||||||
throw new UserError('Not exist this branch');
|
throw new UserError('Not exist this branch');
|
||||||
|
@ -108,7 +124,9 @@ module.exports = Self => {
|
||||||
app: appName,
|
app: appName,
|
||||||
branchFk: branch,
|
branchFk: branch,
|
||||||
version: newVersion
|
version: newVersion
|
||||||
});
|
}, myOptions);
|
||||||
|
|
||||||
|
if (unlock) await models.MdbApp.unlock(ctx, appName, myOptions);
|
||||||
|
|
||||||
if (tx) await tx.commit();
|
if (tx) await tx.commit();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
{
|
{
|
||||||
|
"MdbApp": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
"MdbBranch": {
|
"MdbBranch": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue