Merge branch 'test' of https://gitea.verdnatura.es/verdnatura/salix into dev
gitea/salix/pipeline/head This commit looks good
Details
gitea/salix/pipeline/head This commit looks good
Details
This commit is contained in:
commit
f636c3b1ab
10
CHANGELOG.md
10
CHANGELOG.md
|
@ -5,21 +5,13 @@ 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).
|
||||
|
||||
## [2328.01] - 2023-07-13
|
||||
|
||||
### Added
|
||||
|
||||
### Changed
|
||||
|
||||
### Fixed
|
||||
|
||||
|
||||
## [2326.01] - 2023-06-29
|
||||
|
||||
### Added
|
||||
- (Entradas -> Correo) Al cambiar el tipo de cambio enviará un correo a las personas designadas
|
||||
- (General -> Históricos) Botón para ver el estado del registro en cada punto
|
||||
- (General -> Históricos) Al filtar por registro se muestra todo el histórial desde que fue creado
|
||||
- (Tickets -> Índice) Permite enviar varios albaranes a Docuware
|
||||
|
||||
### Changed
|
||||
- (General -> Históricos) Los registros se muestran agrupados por usuario y entidad
|
||||
|
|
|
@ -17,25 +17,22 @@ module.exports = Self => {
|
|||
|
||||
Self.renewToken = async function(ctx) {
|
||||
const models = Self.app.models;
|
||||
const userId = ctx.req.accessToken.userId;
|
||||
const created = ctx.req.accessToken.created;
|
||||
const tokenId = ctx.req.accessToken.id;
|
||||
const token = ctx.req.accessToken;
|
||||
|
||||
const now = new Date();
|
||||
const differenceMilliseconds = now - new Date(created);
|
||||
const differenceMilliseconds = now - token.created;
|
||||
const differenceSeconds = Math.floor(differenceMilliseconds / 1000);
|
||||
|
||||
const accessTokenConfig = await models.AccessTokenConfig.findOne({fields: ['renewPeriod']});
|
||||
const fields = ['renewPeriod', 'courtesyTime'];
|
||||
const accessTokenConfig = await models.AccessTokenConfig.findOne({fields});
|
||||
|
||||
console.log(userId, created, now, differenceMilliseconds, differenceSeconds, accessTokenConfig.renewPeriod, differenceSeconds <= accessTokenConfig.renewPeriod);
|
||||
if (differenceSeconds < accessTokenConfig.renewPeriod - accessTokenConfig.courtesyTime)
|
||||
throw new UserError(`The renew period has not been exceeded`, 'periodNotExceeded');
|
||||
|
||||
if (differenceSeconds <= accessTokenConfig.renewPeriod)
|
||||
throw new UserError(`The renew period has not been exceeded`);
|
||||
|
||||
await Self.logout(tokenId);
|
||||
const user = await Self.findById(userId);
|
||||
await Self.logout(token.id);
|
||||
const user = await Self.findById(token.userId);
|
||||
const accessToken = await user.createAccessToken();
|
||||
|
||||
return {token: accessToken.id, created: accessToken.created};
|
||||
return {id: accessToken.id, ttl: accessToken.ttl};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -76,6 +76,6 @@ module.exports = Self => {
|
|||
|
||||
let loginInfo = Object.assign({password}, userInfo);
|
||||
token = await Self.login(loginInfo, 'user');
|
||||
return {token: token.id, created: token.created};
|
||||
return {token: token.id, ttl: token.ttl};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -16,6 +16,10 @@
|
|||
"type": "number",
|
||||
"required": true
|
||||
},
|
||||
"courtesyTime": {
|
||||
"type": "number",
|
||||
"required": true
|
||||
},
|
||||
"renewInterval": {
|
||||
"type": "number",
|
||||
"required": true
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
CREATE TABLE `salix`.`accessTokenConfig` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`renewPeriod` int(10) unsigned DEFAULT NULL,
|
||||
`courtesyTime` int(10) unsigned DEFAULT NULL,
|
||||
`renewInterval` int(10) unsigned DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||
|
||||
INSERT IGNORE INTO `salix`.`accessTokenConfig` (`id`, `renewPeriod`, `renewInterval`)
|
||||
INSERT IGNORE INTO `salix`.`accessTokenConfig` (`id`, `renewPeriod`, `courtesyTime`, `renewInterval`)
|
||||
VALUES
|
||||
(1, 21600, 300);
|
||||
(1, 21600, 5, 300);
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
INSERT INTO salix.ACL (model,property,accessType,permission,principalType,principalId)
|
||||
INSERT INTO `salix`.`ACL` (model,property,accessType,permission,principalType,principalId)
|
||||
VALUES
|
||||
('InvoiceOut','makePdfAndNotify','WRITE','ALLOW','ROLE','invoicing'),
|
||||
('InvoiceOutConfig','*','READ','ALLOW','ROLE','invoicing');
|
||||
|
||||
CREATE OR REPLACE TABLE vn.invoiceOutConfig (
|
||||
CREATE OR REPLACE TABLE `vn`.`invoiceOutConfig` (
|
||||
id INT UNSIGNED auto_increment NOT NULL,
|
||||
parallelism int UNSIGNED DEFAULT 1 NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
|
|
|
@ -699,12 +699,12 @@ INSERT INTO `vn`.`route`(`id`, `time`, `workerFk`, `created`, `vehicleFk`, `agen
|
|||
|
||||
INSERT INTO `vn`.`ticket`(`id`, `priority`, `agencyModeFk`,`warehouseFk`,`routeFk`, `shipped`, `landed`, `clientFk`,`nickname`, `addressFk`, `refFk`, `isDeleted`, `zoneFk`, `zonePrice`, `zoneBonus`, `created`)
|
||||
VALUES
|
||||
(1 , 3, 1, 1, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 1101, 'Bat cave', 121, 'T1111111', 0, 1, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH)),
|
||||
(2 , 1, 1, 1, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 1104, 'Stark tower', 124, 'T1111111', 0, 1, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH)),
|
||||
(3 , 1, 7, 1, 6, DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -2 MONTH), INTERVAL +1 DAY), 1104, 'Stark tower', 124, 'T2222222', 0, 3, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH)),
|
||||
(4 , 3, 2, 1, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -3 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -3 MONTH), INTERVAL +1 DAY), 1104, 'Stark tower', 124, 'T3333333', 0, 9, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -3 MONTH)),
|
||||
(5 , 3, 3, 3, 3, DATE_ADD(util.VN_CURDATE(), INTERVAL -4 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -4 MONTH), INTERVAL +1 DAY), 1104, 'Stark tower', 124, 'T4444444', 0, 10, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -4 MONTH)),
|
||||
(6 , 1, 3, 3, 3, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 1101, 'Mountain Drive Gotham', 1, 'A1111111', 0, 10, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH)),
|
||||
(1 , 3, 1, 1, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 1101, 'Bat cave', 121, NULL, 0, 1, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH)),
|
||||
(2 , 1, 1, 1, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 1104, 'Stark tower', 124, NULL, 0, 1, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH)),
|
||||
(3 , 1, 7, 1, 6, DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -2 MONTH), INTERVAL +1 DAY), 1104, 'Stark tower', 124, NULL, 0, 3, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH)),
|
||||
(4 , 3, 2, 1, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -3 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -3 MONTH), INTERVAL +1 DAY), 1104, 'Stark tower', 124, NULL, 0, 9, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -3 MONTH)),
|
||||
(5 , 3, 3, 3, 3, DATE_ADD(util.VN_CURDATE(), INTERVAL -4 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -4 MONTH), INTERVAL +1 DAY), 1104, 'Stark tower', 124, NULL, 0, 10, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -4 MONTH)),
|
||||
(6 , 1, 3, 3, 3, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 1101, 'Mountain Drive Gotham', 1, NULL, 0, 10, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH)),
|
||||
(7 , NULL, 7, 1, 6, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), 1101, 'Mountain Drive Gotham', 1, NULL, 0, 3, 5, 1, util.VN_CURDATE()),
|
||||
(8 , NULL, 7, 1, 6, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), 1101, 'Bat cave', 121, NULL, 0, 3, 5, 1, util.VN_CURDATE()),
|
||||
(9 , NULL, 7, 1, 6, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), 1104, 'Stark tower', 124, NULL, 0, 3, 5, 1, util.VN_CURDATE()),
|
||||
|
@ -2572,6 +2572,26 @@ INSERT INTO `vn`.`ticketRecalc`(`ticketFk`)
|
|||
|
||||
CALL `vn`.`ticket_doRecalc`();
|
||||
|
||||
UPDATE `vn`.`ticket`
|
||||
SET refFk = 'T1111111'
|
||||
WHERE id IN (1,2);
|
||||
|
||||
UPDATE `vn`.`ticket`
|
||||
SET refFk = 'T2222222'
|
||||
WHERE id = 3;
|
||||
|
||||
UPDATE `vn`.`ticket`
|
||||
SET refFk = 'T3333333'
|
||||
WHERE id = 4;
|
||||
|
||||
UPDATE `vn`.`ticket`
|
||||
SET refFk = 'T4444444'
|
||||
WHERE id = 5;
|
||||
|
||||
UPDATE `vn`.`ticket`
|
||||
SET refFk = 'A1111111'
|
||||
WHERE id = 6;
|
||||
|
||||
INSERT INTO `vn`.`zoneAgencyMode`(`id`, `agencyModeFk`, `zoneFk`)
|
||||
VALUES
|
||||
(1, 1, 1),
|
||||
|
|
|
@ -12605,7 +12605,7 @@ BEGIN
|
|||
FROM myTicket t
|
||||
WHERE shipped BETWEEN TIMESTAMP(vFrom) AND TIMESTAMP(vTo, '23:59:59');
|
||||
|
||||
CALL vn.ticketGetTotal;
|
||||
CALL vn.ticketGetTotal(NULL);
|
||||
|
||||
SELECT v.id, IFNULL(v.landed, v.shipped) landed,
|
||||
v.shipped, v.companyFk, v.nickname,
|
||||
|
@ -47167,7 +47167,7 @@ BEGIN
|
|||
ENGINE = MEMORY
|
||||
SELECT vTicketId ticketFk;
|
||||
|
||||
CALL ticketGetTotal;
|
||||
CALL ticketGetTotal(NULL);
|
||||
|
||||
SELECT total INTO vTotal FROM tmp.ticketTotal;
|
||||
|
||||
|
@ -58494,6 +58494,13 @@ BEGIN
|
|||
DECLARE vIsCEESerial BOOL DEFAULT FALSE;
|
||||
DECLARE vIsCorrectInvoiceDate BOOL;
|
||||
DECLARE vMaxShipped DATE;
|
||||
DECLARE vDone BOOL;
|
||||
DECLARE vTicketFk INT;
|
||||
DECLARE vCursor CURSOR FOR
|
||||
SELECT id
|
||||
FROM ticketToInvoice;
|
||||
|
||||
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
|
||||
|
||||
SET vInvoiceDate = IFNULL(vInvoiceDate, util.VN_CURDATE());
|
||||
|
||||
|
@ -58579,6 +58586,20 @@ BEGIN
|
|||
FROM invoiceOut
|
||||
WHERE id = vNewInvoiceId;
|
||||
|
||||
OPEN vCursor;
|
||||
l: LOOP
|
||||
SET vDone = FALSE;
|
||||
FETCH vCursor INTO vTicketFk;
|
||||
|
||||
IF vDone THEN
|
||||
LEAVE l;
|
||||
END IF;
|
||||
|
||||
CALL ticket_recalc(vTicketFk, vTaxArea);
|
||||
|
||||
END LOOP;
|
||||
CLOSE vCursor;
|
||||
|
||||
UPDATE ticket t
|
||||
JOIN tmp.ticketToInvoice ti ON ti.id = t.id
|
||||
SET t.refFk = vNewRef;
|
||||
|
@ -58594,10 +58615,6 @@ BEGIN
|
|||
INSERT INTO ticketTracking(stateFk,ticketFk,workerFk)
|
||||
SELECT * FROM tmp.updateInter;
|
||||
|
||||
INSERT INTO ticketLog (action, userFk, originFk, description)
|
||||
SELECT 'UPDATE', account.myUser_getId(), ti.id, CONCAT('Crea factura ', vNewRef)
|
||||
FROM tmp.ticketToInvoice ti;
|
||||
|
||||
CALL invoiceExpenceMake(vNewInvoiceId);
|
||||
CALL invoiceTaxMake(vNewInvoiceId,vTaxArea);
|
||||
|
||||
|
@ -69870,7 +69887,7 @@ DELIMITER ;
|
|||
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
|
||||
/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;
|
||||
DELIMITER ;;
|
||||
CREATE DEFINER=`root`@`localhost` PROCEDURE `ticketGetTotal`()
|
||||
CREATE DEFINER=`root`@`localhost` PROCEDURE `ticketGetTotal`(vTaxArea VARCHAR(25))
|
||||
BEGIN
|
||||
/**
|
||||
* Calcula el total con IVA para un conjunto de tickets.
|
||||
|
@ -69878,7 +69895,7 @@ BEGIN
|
|||
* @table tmp.ticket(ticketFk) Identificadores de los tickets a calcular
|
||||
* @return tmp.ticketTotal Total para cada ticket
|
||||
*/
|
||||
CALL ticket_getTax(NULL);
|
||||
CALL ticket_getTax(vTaxArea);
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp.ticketTotal;
|
||||
CREATE TEMPORARY TABLE tmp.ticketTotal
|
||||
|
@ -70029,7 +70046,7 @@ BEGIN
|
|||
AND clientFk = vClientFk
|
||||
AND shipped > '2001-01-01';
|
||||
|
||||
CALL vn.ticketGetTotal;
|
||||
CALL vn.ticketGetTotal(NULL);
|
||||
|
||||
SELECT c.id,
|
||||
c.name as Cliente,
|
||||
|
@ -71878,7 +71895,7 @@ proc: BEGIN
|
|||
LEAVE myLoop;
|
||||
END IF;
|
||||
|
||||
CALL ticket_recalc(vTicketFk);
|
||||
CALL ticket_recalc(vTicketFk, NULL);
|
||||
END LOOP;
|
||||
|
||||
CLOSE cCur;
|
||||
|
@ -72334,14 +72351,14 @@ BEGIN
|
|||
|
||||
CALL addressTaxArea ();
|
||||
|
||||
IF vTaxArea > '' THEN
|
||||
IF vTaxArea IS NOT NULL THEN
|
||||
UPDATE tmp.addressTaxArea
|
||||
SET areaFk = vTaxArea;
|
||||
END IF;
|
||||
|
||||
/* Solo se calcula la base imponible (taxableBase) y el impuesto se calculará posteriormente
|
||||
* No se debería cambiar el sistema por problemas con los decimales
|
||||
*/
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp.ticketTax;
|
||||
CREATE TEMPORARY TABLE tmp.ticketTax
|
||||
(PRIMARY KEY (ticketFk, code, rate))
|
||||
|
@ -72349,7 +72366,7 @@ BEGIN
|
|||
SELECT * FROM (
|
||||
SELECT tmpTicket.ticketFk,
|
||||
bp.pgcFk,
|
||||
SUM(s.quantity * s.price * (100 - s.discount)/100 ) AS taxableBase,
|
||||
SUM(s.quantity * s.price * (100 - s.discount)/100 ) taxableBase,
|
||||
pgc.rate,
|
||||
tc.code,
|
||||
bp.priority
|
||||
|
@ -72369,7 +72386,7 @@ BEGIN
|
|||
JOIN pgc ON pgc.code = bp.pgcFk
|
||||
JOIN taxClass tc ON tc.id = bp.taxClassFk
|
||||
GROUP BY tmpTicket.ticketFk, pgc.code, pgc.rate
|
||||
HAVING taxableBase != 0) t3
|
||||
HAVING taxableBase <> 0) t3
|
||||
ORDER BY priority;
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp.ticketServiceTax;
|
||||
|
@ -72378,7 +72395,7 @@ BEGIN
|
|||
ENGINE = MEMORY
|
||||
SELECT tt.ticketFk,
|
||||
pgc.code pgcFk,
|
||||
SUM(ts.quantity * ts.price) AS taxableBase,
|
||||
SUM(ts.quantity * ts.price) taxableBase,
|
||||
pgc.rate,
|
||||
tc.code
|
||||
FROM tmp.ticket tt
|
||||
|
@ -72394,7 +72411,7 @@ BEGIN
|
|||
JOIN pgc ON pgc.code = bp.pgcFk
|
||||
JOIN taxClass tc ON tc.id = bp.taxClassFk
|
||||
GROUP BY tt.ticketFk, pgc.code
|
||||
HAVING taxableBase != 0;
|
||||
HAVING taxableBase <> 0;
|
||||
|
||||
INSERT INTO tmp.ticketTax (ticketFk, pgcFk, taxableBase, rate, code)
|
||||
SELECT ts.ticketFk, ts.pgcFk, ts.taxableBase, ts.rate, ts.code
|
||||
|
@ -72725,20 +72742,31 @@ DELIMITER ;
|
|||
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
|
||||
/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;
|
||||
DELIMITER ;;
|
||||
CREATE DEFINER=`root`@`localhost` PROCEDURE `ticket_recalc`(vTicketId INT)
|
||||
BEGIN
|
||||
CREATE DEFINER=`root`@`localhost` PROCEDURE `ticket_recalc`(vSelf INT, vTaxArea VARCHAR(25))
|
||||
proc:BEGIN
|
||||
/**
|
||||
* Calcula y guarda el total con/sin IVA en un ticket.
|
||||
*
|
||||
* @param vTicketId Identificador del ticket
|
||||
*/
|
||||
|
||||
DECLARE hasInvoice BOOL;
|
||||
|
||||
SELECT COUNT(*) INTO hasInvoice
|
||||
FROM ticket
|
||||
WHERE id = vSelf
|
||||
AND refFk IS NOT NULL;
|
||||
|
||||
IF hasInvoice THEN
|
||||
LEAVE proc;
|
||||
END IF;
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp.ticket;
|
||||
CREATE TEMPORARY TABLE tmp.ticket
|
||||
ENGINE = MEMORY
|
||||
SELECT vTicketId ticketFk;
|
||||
SELECT vSelf ticketFk;
|
||||
|
||||
CALL ticketGetTotal;
|
||||
CALL ticketGetTotal(vTaxArea);
|
||||
|
||||
UPDATE ticket t
|
||||
JOIN tmp.ticketTotal tt ON tt.ticketFk = t.id
|
||||
|
|
|
@ -39,9 +39,9 @@ describe('Client web access path', () => {
|
|||
const userName = await page.getValue($.userName);
|
||||
const email = await page.getValue($.email);
|
||||
|
||||
await page.accessToSection('client.card.log');
|
||||
const logName = await page.innerText($.nameValue);
|
||||
const logActive = await page.innerText($.activeValue);
|
||||
// await page.accessToSection('client.card.log');
|
||||
// const logName = await page.innerText($.nameValue);
|
||||
// const logActive = await page.innerText($.activeValue);
|
||||
|
||||
expect(enableMessage.type).toBe('success');
|
||||
expect(modifyMessage.type).toBe('success');
|
||||
|
@ -50,7 +50,7 @@ describe('Client web access path', () => {
|
|||
expect(userName).toEqual('Legion');
|
||||
expect(email).toEqual('legion@marvel.com');
|
||||
|
||||
expect(logName).toEqual('Legion');
|
||||
expect(logActive).toEqual('✗');
|
||||
// expect(logName).toEqual('Legion');
|
||||
// expect(logActive).toEqual('✗');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -59,12 +59,13 @@ export default class Auth {
|
|||
password: password || undefined
|
||||
};
|
||||
|
||||
const now = new Date();
|
||||
return this.$http.post('VnUsers/signIn', params)
|
||||
.then(json => this.onLoginOk(json, remember));
|
||||
.then(json => this.onLoginOk(json, now, remember));
|
||||
}
|
||||
|
||||
onLoginOk(json, remember) {
|
||||
this.vnToken.set(json.data.token, json.data.created, remember);
|
||||
onLoginOk(json, now, remember) {
|
||||
this.vnToken.set(json.data.token, now, json.data.ttl, remember);
|
||||
|
||||
return this.loadAcls().then(() => {
|
||||
let continueHash = this.$state.params.continue;
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
import ngModule from '../module';
|
||||
import HttpError from 'core/lib/http-error';
|
||||
|
||||
interceptor.$inject = ['$q', 'vnApp', 'vnToken', '$translate'];
|
||||
function interceptor($q, vnApp, vnToken, $translate) {
|
||||
interceptor.$inject = ['$q', 'vnApp', '$translate'];
|
||||
function interceptor($q, vnApp, $translate) {
|
||||
let apiPath = 'api/';
|
||||
let token = sessionStorage.getItem('vnToken')
|
||||
?? localStorage.getItem('vnToken');
|
||||
|
||||
return {
|
||||
setToken(newToken) {
|
||||
token = newToken;
|
||||
},
|
||||
setApiPath(path) {
|
||||
apiPath = path;
|
||||
},
|
||||
|
@ -14,8 +19,8 @@ function interceptor($q, vnApp, vnToken, $translate) {
|
|||
|
||||
if (config.url.charAt(0) !== '/' && apiPath)
|
||||
config.url = `${apiPath}${config.url}`;
|
||||
if (vnToken.token)
|
||||
config.headers.Authorization = vnToken.token;
|
||||
if (token)
|
||||
config.headers.Authorization = token;
|
||||
if ($translate.use())
|
||||
config.headers['Accept-Language'] = $translate.use();
|
||||
if (config.filter) {
|
||||
|
|
|
@ -6,37 +6,118 @@ import ngModule from '../module';
|
|||
* @property {String} token The current login token or %null
|
||||
*/
|
||||
export default class Token {
|
||||
constructor() {
|
||||
try {
|
||||
this.token = sessionStorage.getItem('vnToken');
|
||||
this.created = sessionStorage.getItem('vnTokenCreated');
|
||||
if (!this.token) {
|
||||
this.token = localStorage.getItem('vnToken');
|
||||
this.created = localStorage.getItem('vnTokenCreated');
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
set(token, created, remember) {
|
||||
this.unset();
|
||||
try {
|
||||
if (remember) {
|
||||
localStorage.setItem('vnToken', token);
|
||||
localStorage.setItem('vnTokenCreated', created);
|
||||
} else {
|
||||
sessionStorage.setItem('vnToken', token);
|
||||
sessionStorage.setItem('vnTokenCreated', created);
|
||||
}
|
||||
} catch (e) {}
|
||||
constructor(vnInterceptor, $http, $rootScope) {
|
||||
Object.assign(this, {
|
||||
vnInterceptor,
|
||||
$http,
|
||||
$rootScope
|
||||
});
|
||||
|
||||
this.token = token;
|
||||
this.created = created;
|
||||
try {
|
||||
this.getStorage(sessionStorage);
|
||||
this.remember = true;
|
||||
|
||||
if (!this.token) {
|
||||
this.getStorage(localStorage);
|
||||
this.remember = false;
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
set(token, created, ttl, remember) {
|
||||
this.unset();
|
||||
|
||||
Object.assign(this, {
|
||||
token,
|
||||
created,
|
||||
ttl,
|
||||
remember
|
||||
});
|
||||
this.vnInterceptor.setToken(token);
|
||||
|
||||
try {
|
||||
if (remember)
|
||||
this.setStorage(localStorage, token, created, ttl);
|
||||
else
|
||||
this.setStorage(sessionStorage, token, created, ttl);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
unset() {
|
||||
localStorage.removeItem('vnToken');
|
||||
sessionStorage.removeItem('vnToken');
|
||||
this.token = null;
|
||||
this.created = null;
|
||||
}
|
||||
this.ttl = null;
|
||||
this.remember = null;
|
||||
this.vnInterceptor.setToken(null);
|
||||
|
||||
this.removeStorage(localStorage);
|
||||
this.removeStorage(sessionStorage);
|
||||
}
|
||||
|
||||
getStorage(storage) {
|
||||
this.token = storage.getItem('vnToken');
|
||||
if (!this.token) return;
|
||||
const created = storage.getItem('vnTokenCreated');
|
||||
this.created = created && new Date(created);
|
||||
this.renewPeriod = storage.getItem('vnTokenRenewPeriod');
|
||||
}
|
||||
|
||||
setStorage(storage, token, created, ttl) {
|
||||
storage.setItem('vnToken', token);
|
||||
storage.setItem('vnTokenCreated', created.toJSON());
|
||||
storage.setItem('vnTokenTtl', ttl);
|
||||
}
|
||||
|
||||
removeStorage(storage) {
|
||||
storage.removeItem('vnToken');
|
||||
storage.removeItem('vnTokenCreated');
|
||||
storage.removeItem('vnTokenTtl');
|
||||
}
|
||||
|
||||
fetchConfig() {
|
||||
const filter = {fields: ['renewInterval', 'renewPeriod']};
|
||||
this.$http.get('AccessTokenConfigs/findOne', {filter}).then(res => {
|
||||
const data = res.data;
|
||||
if (!data) return;
|
||||
this.renewPeriod = data.renewPeriod;
|
||||
this.stopRenewer();
|
||||
this.inservalId = setInterval(() => this.checkValidity(), data.renewInterval * 1000);
|
||||
this.checkValidity();
|
||||
});
|
||||
}
|
||||
|
||||
checkValidity() {
|
||||
if (this.checking || !this.created) return;
|
||||
this.checking = true;
|
||||
const renewPeriod = Math.min(this.ttl, this.renewPeriod) * 1000;
|
||||
const maxDate = this.created.getTime() + renewPeriod;
|
||||
const now = new Date();
|
||||
|
||||
if (now.getTime() <= maxDate) {
|
||||
this.checking = false;
|
||||
return;
|
||||
}
|
||||
|
||||
this.$http.post('VnUsers/renewToken')
|
||||
.then(res => {
|
||||
const token = res.data;
|
||||
this.set(token.id, now, token.ttl, this.remember);
|
||||
})
|
||||
.catch(res => {
|
||||
if (res.data?.error?.code !== 'periodNotExceeded')
|
||||
throw res;
|
||||
})
|
||||
.finally(() => {
|
||||
this.checking = false;
|
||||
});
|
||||
}
|
||||
|
||||
stopRenewer() {
|
||||
clearInterval(this.inservalId);
|
||||
}
|
||||
}
|
||||
Token.$inject = ['vnInterceptor', '$http', '$rootScope'];
|
||||
|
||||
ngModule.service('vnToken', Token);
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
<button class="buttonAccount">
|
||||
<img
|
||||
id="user"
|
||||
ng-src="{{$ctrl.getImageUrl()}}"
|
||||
ng-src="{{::$ctrl.getImageUrl()}}"
|
||||
ng-click="userPopover.show($event)"
|
||||
translate-attr="{title: 'Account'}"
|
||||
on-error-src/>
|
||||
|
|
|
@ -3,14 +3,13 @@ import Component from 'core/lib/component';
|
|||
import './style.scss';
|
||||
|
||||
export class Layout extends Component {
|
||||
constructor($element, $, vnModules, vnToken) {
|
||||
constructor($element, $, vnModules) {
|
||||
super($element, $);
|
||||
this.modules = vnModules.get();
|
||||
}
|
||||
|
||||
$onInit() {
|
||||
this.getUserData();
|
||||
this.getAccessTokenConfig();
|
||||
}
|
||||
|
||||
getUserData() {
|
||||
|
@ -32,42 +31,11 @@ export class Layout extends Component {
|
|||
window.location.reload();
|
||||
}
|
||||
|
||||
getAccessTokenConfig() {
|
||||
this.$http.get('AccessTokenConfigs').then(json => {
|
||||
const firtsResult = json.data[0];
|
||||
if (!firtsResult) return;
|
||||
this.renewPeriod = firtsResult.renewPeriod;
|
||||
this.renewInterval = firtsResult.renewInterval;
|
||||
|
||||
const intervalMilliseconds = firtsResult.renewInterval * 1000;
|
||||
this.inservalId = setInterval(this.checkTokenValidity.bind(this), intervalMilliseconds);
|
||||
});
|
||||
}
|
||||
|
||||
checkTokenValidity() {
|
||||
const now = new Date();
|
||||
const differenceMilliseconds = now - new Date(this.vnToken.created);
|
||||
const differenceSeconds = Math.floor(differenceMilliseconds / 1000);
|
||||
|
||||
console.log(this.vnToken.created, now, differenceMilliseconds, differenceSeconds, this.renewPeriod, differenceSeconds > this.renewPeriod);
|
||||
if (differenceSeconds > this.renewPeriod) {
|
||||
this.$http.post('VnUsers/renewToken')
|
||||
.then(json => {
|
||||
if (json.data.token) {
|
||||
let remember = true;
|
||||
if (window.sessionStorage.vnToken) remember = false;
|
||||
|
||||
this.vnToken.set(json.data.token, json.data.created, remember);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$onDestroy() {
|
||||
clearInterval(this.inservalId);
|
||||
this.vnToken.stopRenewer();
|
||||
}
|
||||
}
|
||||
Layout.$inject = ['$element', '$scope', 'vnModules', 'vnToken'];
|
||||
Layout.$inject = ['$element', '$scope', 'vnModules'];
|
||||
|
||||
ngModule.vnComponent('vnLayout', {
|
||||
template: require('./index.html'),
|
||||
|
|
|
@ -37,49 +37,4 @@ describe('Component vnLayout', () => {
|
|||
expect(url).not.toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('getAccessTokenConfig()', () => {
|
||||
it(`should set the renewPeriod and renewInterval properties in localStorage`, () => {
|
||||
const response = [{
|
||||
renewPeriod: 100,
|
||||
renewInterval: 5
|
||||
}];
|
||||
|
||||
$httpBackend.expect('GET', `AccessTokenConfigs`).respond(response);
|
||||
controller.getAccessTokenConfig();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.renewPeriod).toBe(100);
|
||||
expect(controller.renewInterval).toBe(5);
|
||||
expect(controller.inservalId).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('checkTokenValidity()', () => {
|
||||
it(`should not call renewToken and not set vnToken in the controller`, () => {
|
||||
controller.renewPeriod = 100;
|
||||
controller.vnToken.created = new Date();
|
||||
|
||||
controller.checkTokenValidity();
|
||||
|
||||
expect(controller.vnToken.token).toBeNull();
|
||||
});
|
||||
|
||||
it(`should call renewToken and set vnToken properties in the controller`, () => {
|
||||
const response = {
|
||||
token: 999,
|
||||
created: new Date()
|
||||
};
|
||||
controller.renewPeriod = 100;
|
||||
const oneHourBefore = new Date(Date.now() - (60 * 60 * 1000));
|
||||
controller.vnToken.created = oneHourBefore;
|
||||
|
||||
$httpBackend.expect('POST', `VnUsers/renewToken`).respond(response);
|
||||
controller.checkTokenValidity();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.vnToken.token).toBe(999);
|
||||
expect(controller.vnToken.created).toEqual(response.created);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
</div>
|
||||
<div class="user-log vn-mb-sm" ng-repeat="userLog in ::originLog.logs">
|
||||
<div class="timeline">
|
||||
<div class="user-avatar">
|
||||
<vn-avatar
|
||||
ng-class="::{system: !userLog.user}"
|
||||
val="{{::userLog.user ? userLog.user.nickname : $ctrl.$t('System')}}"
|
||||
|
@ -33,6 +34,7 @@
|
|||
ng-src="/api/Images/user/160x160/{{::userLog.userFk}}/download?access_token={{::$ctrl.vnToken.token}}">
|
||||
</img>
|
||||
</vn-avatar>
|
||||
</div>
|
||||
<div class="arrow bg-panel" ng-if="::$ctrl.byRecord"></div>
|
||||
<div class="line"></div>
|
||||
</div>
|
||||
|
|
|
@ -115,23 +115,21 @@ export default class Controller extends Section {
|
|||
// User
|
||||
|
||||
const userChanged = originChanged
|
||||
|| log.userFk != prevLog.userFk
|
||||
|| nLogs >= 5;
|
||||
|| log.userFk != prevLog.userFk;
|
||||
if (userChanged) {
|
||||
originLog.logs.push(userLog = {
|
||||
user: log.user,
|
||||
userFk: log.userFk,
|
||||
logs: []
|
||||
});
|
||||
nLogs = 0;
|
||||
}
|
||||
nLogs++;
|
||||
|
||||
// Model
|
||||
|
||||
const modelChanged = userChanged
|
||||
|| log.changedModel != prevLog.changedModel
|
||||
|| log.changedModelId != prevLog.changedModelId;
|
||||
|| log.changedModelId != prevLog.changedModelId
|
||||
|| nLogs >= 6;
|
||||
if (modelChanged) {
|
||||
userLog.logs.push(modelLog = {
|
||||
model: log.changedModel,
|
||||
|
@ -140,7 +138,9 @@ export default class Controller extends Section {
|
|||
showValue: log.changedModelValue,
|
||||
logs: []
|
||||
});
|
||||
nLogs = 0;
|
||||
}
|
||||
nLogs++;
|
||||
|
||||
modelLog.logs.push(log);
|
||||
|
||||
|
|
|
@ -44,21 +44,30 @@ vn-log {
|
|||
right: -4px;
|
||||
z-index: 1;
|
||||
}
|
||||
& > .user-avatar {
|
||||
background-color: $color-bg;
|
||||
padding: $spacing-sm 0;
|
||||
margin-top: -$spacing-sm;
|
||||
position: sticky;
|
||||
top: 64px;
|
||||
|
||||
& > vn-avatar {
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
|
||||
&.system {
|
||||
background-color: $color-main !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
& > .line {
|
||||
position: absolute;
|
||||
background-color: $color-main;
|
||||
width: 2px;
|
||||
left: 18px;
|
||||
z-index: -1;
|
||||
top: 44px;
|
||||
bottom: -2px;
|
||||
top: 0;
|
||||
bottom: -$spacing-sm;
|
||||
}
|
||||
}
|
||||
&:last-child > .timeline > .line {
|
||||
|
|
|
@ -11,7 +11,8 @@ function config($stateProvider, $urlRouterProvider) {
|
|||
abstract: true,
|
||||
template: '<vn-layout></vn-layout>',
|
||||
resolve: {
|
||||
config: ['vnConfig', vnConfig => vnConfig.initialize()]
|
||||
config: ['vnConfig', vnConfig => vnConfig.initialize()],
|
||||
token: ['vnToken', vnToken => vnToken.fetchConfig()]
|
||||
}
|
||||
})
|
||||
.state('outLayout', {
|
||||
|
|
|
@ -176,5 +176,6 @@
|
|||
"Can't transfer claimed sales": "Can't transfer claimed sales",
|
||||
"Invalid quantity": "Invalid quantity",
|
||||
"Failed to upload delivery note": "Error to upload delivery note {{id}}",
|
||||
"Mail not sent": "There has been an error sending the invoice to the client [{{clientId}}]({{{clientUrl}}}), please check the email address"
|
||||
"Mail not sent": "There has been an error sending the invoice to the client [{{clientId}}]({{{clientUrl}}}), please check the email address",
|
||||
"The renew period has not been exceeded": "The renew period has not been exceeded"
|
||||
}
|
|
@ -177,7 +177,6 @@
|
|||
"You can not select this payment method without a registered bankery account": "No se puede utilizar este método de pago si no has registrado una cuenta bancaria",
|
||||
"Action not allowed on the test environment": "Esta acción no está permitida en el entorno de pruebas",
|
||||
"The selected ticket is not suitable for this route": "El ticket seleccionado no es apto para esta ruta",
|
||||
"Sorts whole route": "Reordena ruta entera",
|
||||
"New ticket request has been created with price": "Se ha creado una nueva petición de compra '{{description}}' para el día *{{shipped}}*, con una cantidad de *{{quantity}}* y un precio de *{{price}} €*",
|
||||
"New ticket request has been created": "Se ha creado una nueva petición de compra '{{description}}' para el día *{{shipped}}*, con una cantidad de *{{quantity}}*",
|
||||
"Swift / BIC cannot be empty": "Swift / BIC no puede estar vacío",
|
||||
|
|
|
@ -77,14 +77,6 @@ module.exports = Self => {
|
|||
if (salesPersonId)
|
||||
await models.Chat.sendCheckingPresence(ctx, salesPersonId, message);
|
||||
|
||||
await models.ClaimLog.create({
|
||||
originFk: args.id,
|
||||
userFk: userId,
|
||||
action: 'insert',
|
||||
description: 'Claim-pickup-order sent',
|
||||
changedModel: 'Mail'
|
||||
});
|
||||
|
||||
const email = new Email('claim-pickup-order', params);
|
||||
|
||||
return email.send();
|
||||
|
|
|
@ -19,9 +19,6 @@ module.exports = Self => {
|
|||
});
|
||||
|
||||
Self.confirmTransaction = async(ctx, id, options) => {
|
||||
const models = Self.app.models;
|
||||
const userId = ctx.req.accessToken.userId;
|
||||
|
||||
let tx;
|
||||
const myOptions = {userId: ctx.req.accessToken.userId};
|
||||
|
||||
|
@ -34,29 +31,8 @@ module.exports = Self => {
|
|||
}
|
||||
|
||||
try {
|
||||
const oldTpvTransaction = await models.TpvTransaction.findById(id, null, myOptions);
|
||||
|
||||
const confirm = await Self.rawSql('CALL hedera.tpvTransaction_confirmById(?)', [id], myOptions);
|
||||
|
||||
const tpvTransaction = await models.TpvTransaction.findById(id, null, myOptions);
|
||||
|
||||
const oldInstance = {status: oldTpvTransaction.status};
|
||||
const newInstance = {status: tpvTransaction.status};
|
||||
|
||||
const logRecord = {
|
||||
originFk: tpvTransaction.clientFk,
|
||||
userFk: userId,
|
||||
action: 'update',
|
||||
changedModel: 'TpvTransaction',
|
||||
changedModelId: id,
|
||||
oldInstance: oldInstance,
|
||||
newInstance: newInstance
|
||||
};
|
||||
|
||||
await models.ClientLog.create(logRecord, myOptions);
|
||||
|
||||
if (tx) await tx.commit();
|
||||
|
||||
return confirm;
|
||||
} catch (e) {
|
||||
if (tx) await tx.rollback();
|
||||
|
|
|
@ -30,34 +30,9 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.sendSms = async(ctx, id, destination, message, options) => {
|
||||
Self.sendSms = async(ctx, id, destination, message) => {
|
||||
const models = Self.app.models;
|
||||
const myOptions = {};
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
const userId = ctx.req.accessToken.userId;
|
||||
|
||||
const sms = await models.Sms.send(ctx, destination, message);
|
||||
const logRecord = {
|
||||
originFk: id,
|
||||
userFk: userId,
|
||||
action: 'insert',
|
||||
changedModel: 'sms',
|
||||
newInstance: {
|
||||
destinationFk: id,
|
||||
destination: destination,
|
||||
message: message,
|
||||
statusCode: sms.statusCode,
|
||||
status: sms.status
|
||||
}
|
||||
};
|
||||
|
||||
const clientLog = await models.ClientLog.create(logRecord, myOptions);
|
||||
|
||||
sms.logId = clientLog.id;
|
||||
|
||||
return sms;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -13,10 +13,7 @@ describe('client sendSms()', () => {
|
|||
|
||||
const sms = await models.Client.sendSms(ctx, id, destination, message, options);
|
||||
|
||||
const createdLog = await models.ClientLog.findById(sms.logId, null, options);
|
||||
const json = JSON.parse(JSON.stringify(createdLog.newInstance));
|
||||
|
||||
expect(json.message).toEqual(message);
|
||||
expect(sms).toBeDefined();
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
|
|
|
@ -144,20 +144,7 @@ module.exports = Self => {
|
|||
|
||||
if (taxDataChecked && !hasSageData)
|
||||
throw new UserError(`You need to fill sage information before you check verified data`);
|
||||
if (args.despiteOfClient) {
|
||||
const logRecord = {
|
||||
originFk: clientId,
|
||||
userFk: userId,
|
||||
action: 'update',
|
||||
changedModel: 'Client',
|
||||
changedModelId: clientId,
|
||||
description: $t(`Client checked as validated despite of duplication`, {
|
||||
clientId: args.despiteOfClient
|
||||
})
|
||||
};
|
||||
|
||||
await models.ClientLog.create(logRecord, myOptions);
|
||||
}
|
||||
// Remove unwanted properties
|
||||
delete args.ctx;
|
||||
delete args.id;
|
||||
|
|
|
@ -479,21 +479,6 @@ module.exports = Self => {
|
|||
hasChanges = oldData.name != changes.name || oldData.active != changes.active;
|
||||
|
||||
if (!hasChanges) return;
|
||||
|
||||
const isClient = await Self.app.models.Client.count({id: oldData.id});
|
||||
if (isClient) {
|
||||
const loopBackContext = LoopBackContext.getCurrentContext();
|
||||
const userId = loopBackContext.active.accessToken.userId;
|
||||
const logRecord = {
|
||||
originFk: oldData.id,
|
||||
userFk: userId,
|
||||
action: 'update',
|
||||
changedModel: 'VnUser',
|
||||
oldInstance: {name: oldData.name, active: oldData.active},
|
||||
newInstance: {name: changes.name, active: changes.active}
|
||||
};
|
||||
await Self.app.models.ClientLog.create(logRecord);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -21,7 +21,6 @@ module.exports = Self => {
|
|||
|
||||
Self.guessPriority = async(ctx, id) => {
|
||||
const userId = ctx.req.accessToken.userId;
|
||||
const $t = ctx.req.__; // $translate
|
||||
const query = `CALL vn.routeGuessPriority(?)`;
|
||||
const tx = await Self.beginTransaction({});
|
||||
|
||||
|
@ -30,16 +29,6 @@ module.exports = Self => {
|
|||
|
||||
const priority = await Self.rawSql(query, [id], options);
|
||||
|
||||
let logRecord = {
|
||||
originFk: id,
|
||||
userFk: userId,
|
||||
action: 'update',
|
||||
changedModel: 'Route',
|
||||
description: $t('Sorts whole route')
|
||||
};
|
||||
|
||||
await Self.app.models.RouteLog.create(logRecord, options);
|
||||
|
||||
await tx.commit();
|
||||
return priority;
|
||||
} catch (e) {
|
||||
|
|
|
@ -31,18 +31,6 @@ describe('route updateVolume()', () => {
|
|||
const updatedRoute = await app.models.Route.findById(routeId, null, options);
|
||||
|
||||
expect(updatedRoute.m3).not.toEqual(route.m3);
|
||||
|
||||
const logs = await app.models.RouteLog.find({
|
||||
fields: ['id', 'newInstance']
|
||||
}, options);
|
||||
|
||||
const m3Log = logs.filter(log => {
|
||||
if (log.newInstance)
|
||||
return log.newInstance.m3 === updatedRoute.m3;
|
||||
});
|
||||
|
||||
expect(m3Log.length).toEqual(1);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
|
|
|
@ -35,24 +35,9 @@ module.exports = Self => {
|
|||
}
|
||||
|
||||
try {
|
||||
const originalRoute = await models.Route.findById(id, null, myOptions);
|
||||
|
||||
await Self.rawSql(`CALL vn.routeUpdateM3(?)`, [id], myOptions);
|
||||
|
||||
const updatedRoute = await models.Route.findById(id, null, myOptions);
|
||||
|
||||
await models.RouteLog.create({
|
||||
originFk: id,
|
||||
userFk: userId,
|
||||
action: 'update',
|
||||
changedModel: 'Route',
|
||||
changedModelId: id,
|
||||
oldInstance: {m3: originalRoute.m3},
|
||||
newInstance: {m3: updatedRoute.m3}
|
||||
}, myOptions);
|
||||
|
||||
if (tx) await tx.commit();
|
||||
|
||||
return updatedRoute;
|
||||
} catch (e) {
|
||||
if (tx) await tx.rollback();
|
||||
|
|
|
@ -106,7 +106,7 @@ module.exports = Self => {
|
|||
}
|
||||
}
|
||||
|
||||
const query = `CALL vn.ticket_recalc(?)`;
|
||||
const query = `CALL vn.ticket_recalc(?, NULL)`;
|
||||
await Self.rawSql(query, [refundTicket.id], myOptions);
|
||||
|
||||
if (tx) await tx.commit();
|
||||
|
|
|
@ -96,7 +96,7 @@ module.exports = Self => {
|
|||
await sale.updateAttributes({price: newPrice}, myOptions);
|
||||
|
||||
await Self.rawSql('CALL vn.manaSpellersRequery(?)', [userId], myOptions);
|
||||
await Self.rawSql('CALL vn.ticket_recalc(?)', [sale.ticketFk], myOptions);
|
||||
await Self.rawSql('CALL vn.ticket_recalc(?, NULL)', [sale.ticketFk], myOptions);
|
||||
|
||||
const salesPerson = sale.ticket().client().salesPersonUser();
|
||||
if (salesPerson) {
|
||||
|
|
|
@ -97,22 +97,6 @@ module.exports = Self => {
|
|||
});
|
||||
await models.Chat.sendCheckingPresence(ctx, requesterId, message, myOptions);
|
||||
|
||||
const logRecord = {
|
||||
originFk: sale.ticketFk,
|
||||
userFk: userId,
|
||||
action: 'update',
|
||||
changedModel: 'ticketRequest',
|
||||
newInstance: {
|
||||
destinationFk: sale.ticketFk,
|
||||
quantity: sale.quantity,
|
||||
concept: sale.concept,
|
||||
itemId: sale.itemFk,
|
||||
ticketId: sale.ticketFk,
|
||||
}
|
||||
};
|
||||
|
||||
await Self.app.models.TicketLog.create(logRecord, myOptions);
|
||||
|
||||
if (tx) await tx.commit();
|
||||
|
||||
return sale;
|
||||
|
|
|
@ -85,7 +85,7 @@ module.exports = Self => {
|
|||
}, myOptions);
|
||||
|
||||
await Self.rawSql('CALL vn.sale_calculateComponent(?, NULL)', [newSale.id], myOptions);
|
||||
await Self.rawSql('CALL vn.ticket_recalc(?)', [id], myOptions);
|
||||
await Self.rawSql('CALL vn.ticket_recalc(?, NULL)', [id], myOptions);
|
||||
|
||||
const sale = await models.Sale.findById(newSale.id, {
|
||||
include: {
|
||||
|
|
|
@ -242,16 +242,6 @@ module.exports = Self => {
|
|||
const oldProperties = await loggable.translateValues(Self, changes.old);
|
||||
const newProperties = await loggable.translateValues(Self, changes.new);
|
||||
|
||||
await models.TicketLog.create({
|
||||
originFk: args.id,
|
||||
userFk: userId,
|
||||
action: 'update',
|
||||
changedModel: 'Ticket',
|
||||
changedModelId: args.id,
|
||||
oldInstance: oldProperties,
|
||||
newInstance: newProperties
|
||||
}, myOptions);
|
||||
|
||||
const salesPersonId = originalTicket.client().salesPersonFk;
|
||||
if (salesPersonId) {
|
||||
const origin = ctx.req.headers.origin;
|
||||
|
|
|
@ -52,23 +52,10 @@ module.exports = Self => {
|
|||
});
|
||||
if (!ticket.originId || !ticket.destinationId) continue;
|
||||
|
||||
const ticketDestinationLogRecord = {
|
||||
originFk: ticket.destinationId,
|
||||
userFk: ctx.req.accessToken.userId,
|
||||
action: 'update',
|
||||
changedModel: 'Ticket',
|
||||
changedModelId: ticket.destinationId,
|
||||
changedModelValue: ticket.destinationId,
|
||||
oldInstance: {},
|
||||
newInstance: {mergedTicket: ticket.originId}
|
||||
};
|
||||
|
||||
await models.Sale.updateAll({ticketFk: ticket.originId}, {ticketFk: ticket.destinationId}, myOptions);
|
||||
if (await models.Ticket.setDeleted(ctx, ticket.originId, myOptions)) {
|
||||
await models.TicketLog.create(ticketDestinationLogRecord, myOptions);
|
||||
if (await models.Ticket.setDeleted(ctx, ticket.originId, myOptions))
|
||||
await models.Chat.sendCheckingPresence(ctx, ticket.workerFk, message);
|
||||
}
|
||||
}
|
||||
if (tx)
|
||||
await tx.commit();
|
||||
} catch (e) {
|
||||
|
|
|
@ -30,54 +30,12 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.sendSms = async(ctx, id, destination, message, options) => {
|
||||
Self.sendSms = async(ctx, id, destination, message) => {
|
||||
const models = Self.app.models;
|
||||
const myOptions = {};
|
||||
let tx;
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
if (!myOptions.transaction) {
|
||||
tx = await Self.beginTransaction({});
|
||||
myOptions.transaction = tx;
|
||||
}
|
||||
|
||||
const userId = ctx.req.accessToken.userId;
|
||||
|
||||
try {
|
||||
const sms = await models.Sms.send(ctx, destination, message);
|
||||
|
||||
const newTicketSms = {
|
||||
await models.TicketSms.create({
|
||||
ticketFk: id,
|
||||
smsFk: sms.id
|
||||
};
|
||||
await models.TicketSms.create(newTicketSms);
|
||||
|
||||
const logRecord = {
|
||||
originFk: id,
|
||||
userFk: userId,
|
||||
action: 'insert',
|
||||
changedModel: 'sms',
|
||||
newInstance: {
|
||||
destinationFk: id,
|
||||
destination: destination,
|
||||
message: message,
|
||||
statusCode: sms.statusCode,
|
||||
status: sms.status
|
||||
}
|
||||
};
|
||||
|
||||
const ticketLog = await models.TicketLog.create(logRecord, myOptions);
|
||||
|
||||
sms.logId = ticketLog.id;
|
||||
|
||||
if (tx) await tx.commit();
|
||||
|
||||
return sms;
|
||||
} catch (e) {
|
||||
if (tx) await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
|
|
@ -43,12 +43,10 @@ describe('ticket merge()', () => {
|
|||
|
||||
await models.Ticket.merge(ctx, [tickets], options);
|
||||
|
||||
const createdTicketLog = await models.TicketLog.find({where: {originFk: tickets.destinationId}}, options);
|
||||
const deletedTicket = await models.Ticket.findOne({where: {id: tickets.originId}}, options);
|
||||
const salesTicketFuture = await models.Sale.find({where: {ticketFk: tickets.destinationId}}, options);
|
||||
const chatNotificationAfterMerge = await models.Chat.find(null, options);
|
||||
|
||||
expect(createdTicketLog.length).toEqual(1);
|
||||
expect(deletedTicket.isDeleted).toEqual(true);
|
||||
expect(salesTicketFuture.length).toEqual(2);
|
||||
expect(chatNotificationBeforeMerge.length).toEqual(chatNotificationAfterMerge.length - 2);
|
||||
|
|
|
@ -12,19 +12,14 @@ describe('ticket sendSms()', () => {
|
|||
const destination = 222222222;
|
||||
const message = 'this is the message created in a test';
|
||||
|
||||
const sms = await models.Ticket.sendSms(ctx, id, destination, message, options);
|
||||
|
||||
const createdLog = await models.TicketLog.findById(sms.logId, null, options);
|
||||
await models.Ticket.sendSms(ctx, id, destination, message, options);
|
||||
|
||||
const filter = {
|
||||
ticketFk: createdLog.originFk
|
||||
ticketFk: id
|
||||
};
|
||||
const ticketSms = await models.TicketSms.findOne(filter, options);
|
||||
|
||||
const json = JSON.parse(JSON.stringify(createdLog.newInstance));
|
||||
|
||||
expect(json.message).toEqual(message);
|
||||
expect(ticketSms.ticketFk).toEqual(createdLog.originFk);
|
||||
expect(ticketSms.ticketFk).toEqual(id);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
|
|
|
@ -84,13 +84,6 @@ module.exports = Self => {
|
|||
|
||||
for (const sale of sales) {
|
||||
const originalSale = map.get(sale.id);
|
||||
const originalSaleData = { // <-- Loopback modifies original instance on save
|
||||
itemFk: originalSale.itemFk,
|
||||
quantity: originalSale.quantity,
|
||||
concept: originalSale.concept,
|
||||
ticketFk: originalSale.ticketFk
|
||||
};
|
||||
|
||||
if (sale.quantity == originalSale.quantity) {
|
||||
query = `UPDATE sale
|
||||
SET ticketFk = ?
|
||||
|
@ -100,48 +93,6 @@ module.exports = Self => {
|
|||
await transferPartialSale(
|
||||
ticketId, originalSale, sale, myOptions);
|
||||
}
|
||||
|
||||
// Log to original ticket
|
||||
await models.TicketLog.create({
|
||||
originFk: id,
|
||||
userFk: userId,
|
||||
action: 'update',
|
||||
changedModel: 'Sale',
|
||||
changedModelId: sale.id,
|
||||
oldInstance: {
|
||||
item: originalSaleData.itemFk,
|
||||
quantity: originalSaleData.quantity,
|
||||
concept: originalSaleData.concept,
|
||||
ticket: originalSaleData.ticketFk
|
||||
},
|
||||
newInstance: {
|
||||
item: sale.itemFk,
|
||||
quantity: sale.quantity,
|
||||
concept: sale.concept,
|
||||
ticket: ticketId
|
||||
}
|
||||
}, myOptions);
|
||||
|
||||
// Log to destination ticket
|
||||
await models.TicketLog.create({
|
||||
originFk: ticketId,
|
||||
userFk: userId,
|
||||
action: 'update',
|
||||
changedModel: 'Sale',
|
||||
changedModelId: sale.id,
|
||||
oldInstance: {
|
||||
item: originalSaleData.itemFk,
|
||||
quantity: originalSaleData.quantity,
|
||||
concept: originalSaleData.concept,
|
||||
ticket: originalSaleData.ticketFk
|
||||
},
|
||||
newInstance: {
|
||||
item: sale.itemFk,
|
||||
quantity: sale.quantity,
|
||||
concept: sale.concept,
|
||||
ticket: ticketId
|
||||
}
|
||||
}, myOptions);
|
||||
}
|
||||
|
||||
const isTicketEmpty = await models.Ticket.isEmpty(id, myOptions);
|
||||
|
|
|
@ -147,7 +147,7 @@ module.exports = Self => {
|
|||
await Promise.all(promises);
|
||||
|
||||
await Self.rawSql('CALL vn.manaSpellersRequery(?)', [userId], myOptions);
|
||||
await Self.rawSql('CALL vn.ticket_recalc(?)', [id], myOptions);
|
||||
await Self.rawSql('CALL vn.ticket_recalc(?, NULL)', [id], myOptions);
|
||||
|
||||
const ticket = await models.Ticket.findById(id, {
|
||||
include: {
|
||||
|
|
|
@ -1,30 +1,4 @@
|
|||
|
||||
const LoopBackContext = require('loopback-context');
|
||||
|
||||
module.exports = Self => {
|
||||
// Methods
|
||||
require('./ticket-methods')(Self);
|
||||
|
||||
Self.observe('before save', async function(ctx) {
|
||||
const loopBackContext = LoopBackContext.getCurrentContext();
|
||||
const httpCtx = loopBackContext.active;
|
||||
|
||||
if (ctx.isNewInstance) return;
|
||||
|
||||
let changes = ctx.data || ctx.instance;
|
||||
|
||||
if (changes.routeFk === null && ctx.currentInstance.routeFk != null) {
|
||||
let instance = JSON.parse(JSON.stringify(ctx.currentInstance));
|
||||
let userId = httpCtx.accessToken.userId;
|
||||
let logRecord = {
|
||||
originFk: ctx.currentInstance.routeFk,
|
||||
userFk: userId,
|
||||
action: 'delete',
|
||||
changedModel: 'Route',
|
||||
oldInstance: {ticket: instance.id},
|
||||
newInstance: null
|
||||
};
|
||||
await Self.app.models.RouteLog.create(logRecord);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
@ -25,9 +25,7 @@ module.exports = Self => {
|
|||
});
|
||||
|
||||
Self.cloneWithEntries = async(ctx, id) => {
|
||||
const userId = ctx.req.accessToken.userId;
|
||||
const conn = Self.dataSource.connector;
|
||||
const models = Self.app.models;
|
||||
const travel = await Self.findById(id, {
|
||||
fields: [
|
||||
'id',
|
||||
|
@ -81,18 +79,6 @@ module.exports = Self => {
|
|||
]
|
||||
});
|
||||
|
||||
const oldProperties = await loggable.translateValues(Self, travel);
|
||||
const newProperties = await loggable.translateValues(Self, newTravel);
|
||||
await models.TravelLog.create({
|
||||
originFk: newTravel.id,
|
||||
userFk: userId,
|
||||
action: 'insert',
|
||||
changedModel: 'Travel',
|
||||
changedModelId: newTravel.id,
|
||||
oldInstance: oldProperties,
|
||||
newInstance: newProperties
|
||||
});
|
||||
|
||||
return newTravel.id;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -30,24 +30,8 @@ module.exports = Self => {
|
|||
SET travelFk = NULL, dmsFk = NULL
|
||||
WHERE id = ?`, [id], {userId});
|
||||
|
||||
const oldInstance = {
|
||||
travelFk: travelThermograph.travelFk,
|
||||
dmsFk: travelThermograph.dmsFk
|
||||
};
|
||||
|
||||
await models.TravelLog.create({
|
||||
originFk: travelThermograph.travelFk,
|
||||
userFk: userId,
|
||||
action: 'delete',
|
||||
changedModel: 'TravelThermograph',
|
||||
changedModelId: id,
|
||||
oldInstance: oldInstance,
|
||||
newInstance: {}
|
||||
});
|
||||
|
||||
travelThermograph.travelFk = null;
|
||||
travelThermograph.dmsFk = null;
|
||||
|
||||
return travelThermograph;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -40,7 +40,6 @@ module.exports = Self => {
|
|||
Self.updateWorkerTimeControlMail = async(ctx, options) => {
|
||||
const models = Self.app.models;
|
||||
const args = ctx.args;
|
||||
const userId = ctx.req.accessToken.userId;
|
||||
|
||||
const myOptions = {};
|
||||
|
||||
|
@ -57,9 +56,6 @@ module.exports = Self => {
|
|||
|
||||
if (!workerTimeControlMail) throw new UserError(`There aren't records for this week`);
|
||||
|
||||
const oldState = workerTimeControlMail.state;
|
||||
const oldReason = workerTimeControlMail.reason;
|
||||
|
||||
await workerTimeControlMail.updateAttributes({
|
||||
state: args.state,
|
||||
reason: args.reason || null
|
||||
|
@ -70,22 +66,5 @@ module.exports = Self => {
|
|||
sendedCounter: workerTimeControlMail.sendedCounter + 1
|
||||
}, myOptions);
|
||||
}
|
||||
|
||||
const logRecord = {
|
||||
originFk: args.workerId,
|
||||
userFk: userId,
|
||||
action: 'update',
|
||||
changedModel: 'WorkerTimeControlMail',
|
||||
oldInstance: {
|
||||
state: oldState,
|
||||
reason: oldReason
|
||||
},
|
||||
newInstance: {
|
||||
state: args.state,
|
||||
reason: args.reason
|
||||
}
|
||||
};
|
||||
|
||||
return models.WorkerLog.create(logRecord, myOptions);
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "salix-back",
|
||||
"version": "23.28.01",
|
||||
"version": "23.26.01",
|
||||
"author": "Verdnatura Levante SL",
|
||||
"description": "Salix backend",
|
||||
"license": "GPL-3.0",
|
||||
|
|
Loading…
Reference in New Issue