diff --git a/back/methods/account/recover-password.js b/back/methods/account/recover-password.js
new file mode 100644
index 0000000000..ddea76829c
--- /dev/null
+++ b/back/methods/account/recover-password.js
@@ -0,0 +1,30 @@
+module.exports = Self => {
+ Self.remoteMethod('recoverPassword', {
+ description: 'Send email to the user',
+ accepts: [
+ {
+ arg: 'email',
+ type: 'string',
+ description: 'The email of user',
+ required: true
+ }
+ ],
+ http: {
+ path: `/recoverPassword`,
+ verb: 'POST'
+ }
+ });
+
+ Self.recoverPassword = async function(email) {
+ const models = Self.app.models;
+
+ try {
+ await models.user.resetPassword({email, emailTemplate: 'recover-password'});
+ } catch (err) {
+ if (err.code === 'EMAIL_NOT_FOUND')
+ return;
+ else
+ throw err;
+ }
+ };
+};
diff --git a/back/methods/account/specs/set-password.spec.js b/back/methods/account/specs/set-password.spec.js
index c76fd52b83..fe71873de2 100644
--- a/back/methods/account/specs/set-password.spec.js
+++ b/back/methods/account/specs/set-password.spec.js
@@ -1,6 +1,6 @@
const app = require('vn-loopback/server/server');
-describe('account changePassword()', () => {
+describe('account setPassword()', () => {
it('should throw an error when password does not meet requirements', async() => {
let req = app.models.Account.setPassword(1, 'insecurePass');
diff --git a/back/methods/dms/deleteTrashFiles.js b/back/methods/dms/deleteTrashFiles.js
index 63d7021c5f..f14e65e9f6 100644
--- a/back/methods/dms/deleteTrashFiles.js
+++ b/back/methods/dms/deleteTrashFiles.js
@@ -51,7 +51,7 @@ module.exports = Self => {
const dstFile = path.join(dmsContainer.client.root, pathHash, dms.file);
await fs.unlink(dstFile);
} catch (err) {
- if (err.code != 'ENOENT')
+ if (err.code != 'ENOENT' && dms.file)
throw err;
}
diff --git a/back/models/account.js b/back/models/account.js
index f74052b5c9..c2502380a1 100644
--- a/back/models/account.js
+++ b/back/models/account.js
@@ -1,4 +1,7 @@
+/* eslint max-len: ["error", { "code": 150 }]*/
const md5 = require('md5');
+const LoopBackContext = require('loopback-context');
+const {Email} = require('vn-print');
module.exports = Self => {
require('../methods/account/login')(Self);
@@ -6,6 +9,7 @@ module.exports = Self => {
require('../methods/account/acl')(Self);
require('../methods/account/change-password')(Self);
require('../methods/account/set-password')(Self);
+ require('../methods/account/recover-password')(Self);
require('../methods/account/validate-token')(Self);
require('../methods/account/privileges')(Self);
@@ -27,17 +31,62 @@ module.exports = Self => {
ctx.data.password = md5(ctx.data.password);
});
+ Self.afterRemote('prototype.patchAttributes', async(ctx, instance) => {
+ if (!ctx.args || !ctx.args.data.email) return;
+ const models = Self.app.models;
+
+ const loopBackContext = LoopBackContext.getCurrentContext();
+ const httpCtx = {req: loopBackContext.active};
+ const httpRequest = httpCtx.req.http.req;
+ const headers = httpRequest.headers;
+ const origin = headers.origin;
+ const url = origin.split(':');
+
+ const userId = ctx.instance.id;
+ const user = await models.user.findById(userId);
+
+ class Mailer {
+ async send(verifyOptions, cb) {
+ const params = {
+ url: verifyOptions.verifyHref,
+ recipient: verifyOptions.to,
+ lang: ctx.req.getLocale()
+ };
+
+ const email = new Email('email-verify', params);
+ email.send();
+
+ cb(null, verifyOptions.to);
+ }
+ }
+
+ const options = {
+ type: 'email',
+ to: instance.email,
+ from: {},
+ redirect: `${origin}/#!/account/${instance.id}/basic-data?emailConfirmed`,
+ template: false,
+ mailer: new Mailer,
+ host: url[1].split('/')[2],
+ port: url[2],
+ protocol: url[0],
+ user: Self
+ };
+
+ await user.verify(options);
+ });
+
Self.remoteMethod('getCurrentUserData', {
description: 'Gets the current user data',
accepts: [
{
arg: 'ctx',
- type: 'Object',
+ type: 'object',
http: {source: 'context'}
}
],
returns: {
- type: 'Object',
+ type: 'object',
root: true
},
http: {
@@ -58,7 +107,7 @@ module.exports = Self => {
*
* @param {Integer} userId The user id
* @param {String} name The role name
- * @param {Object} options Options
+ * @param {object} options Options
* @return {Boolean} %true if user has the role, %false otherwise
*/
Self.hasRole = async function(userId, name, options) {
@@ -70,8 +119,8 @@ module.exports = Self => {
* Get all user roles.
*
* @param {Integer} userId The user id
- * @param {Object} options Options
- * @return {Object} User role list
+ * @param {object} options Options
+ * @return {object} User role list
*/
Self.getRoles = async(userId, options) => {
let result = await Self.rawSql(
diff --git a/back/models/account.json b/back/models/account.json
index d0c17e70f6..5e35c711a7 100644
--- a/back/models/account.json
+++ b/back/models/account.json
@@ -40,6 +40,9 @@
"email": {
"type": "string"
},
+ "emailVerified": {
+ "type": "boolean"
+ },
"created": {
"type": "date"
},
@@ -88,16 +91,23 @@
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "ALLOW"
- },
+ },
+ {
+ "property": "recoverPassword",
+ "accessType": "EXECUTE",
+ "principalType": "ROLE",
+ "principalId": "$everyone",
+ "permission": "ALLOW"
+ },
{
- "property": "logout",
+ "property": "logout",
"accessType": "EXECUTE",
"principalType": "ROLE",
"principalId": "$authenticated",
"permission": "ALLOW"
},
{
- "property": "validateToken",
+ "property": "validateToken",
"accessType": "EXECUTE",
"principalType": "ROLE",
"principalId": "$authenticated",
diff --git a/back/models/specs/account.spec.js b/back/models/specs/account.spec.js
index c52bc43782..f31c81b75e 100644
--- a/back/models/specs/account.spec.js
+++ b/back/models/specs/account.spec.js
@@ -1,14 +1,14 @@
-const app = require('vn-loopback/server/server');
+const models = require('vn-loopback/server/server').models;
describe('loopback model Account', () => {
it('should return true if the user has the given role', async() => {
- let result = await app.models.Account.hasRole(1, 'employee');
+ let result = await models.Account.hasRole(1, 'employee');
expect(result).toBeTruthy();
});
it('should return false if the user doesnt have the given role', async() => {
- let result = await app.models.Account.hasRole(1, 'administrator');
+ let result = await models.Account.hasRole(1, 'administrator');
expect(result).toBeFalsy();
});
diff --git a/back/models/specs/user.spec.js b/back/models/specs/user.spec.js
new file mode 100644
index 0000000000..124afdc0cc
--- /dev/null
+++ b/back/models/specs/user.spec.js
@@ -0,0 +1,32 @@
+const models = require('vn-loopback/server/server').models;
+const LoopBackContext = require('loopback-context');
+
+describe('account recoverPassword()', () => {
+ const userId = 1107;
+
+ const activeCtx = {
+ accessToken: {userId: userId},
+ http: {
+ req: {
+ headers: {origin: 'http://localhost'}
+ }
+ }
+ };
+
+ beforeEach(() => {
+ spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
+ active: activeCtx
+ });
+ });
+
+ it('should send email with token', async() => {
+ const userId = 1107;
+ const user = await models.Account.findById(userId);
+
+ await models.Account.recoverPassword(user.email);
+
+ const result = await models.AccessToken.findOne({where: {userId: userId}});
+
+ expect(result).toBeDefined();
+ });
+});
diff --git a/back/models/user.js b/back/models/user.js
new file mode 100644
index 0000000000..b24d702b32
--- /dev/null
+++ b/back/models/user.js
@@ -0,0 +1,27 @@
+const LoopBackContext = require('loopback-context');
+const {Email} = require('vn-print');
+
+module.exports = function(Self) {
+ Self.on('resetPasswordRequest', async function(info) {
+ const loopBackContext = LoopBackContext.getCurrentContext();
+ const httpCtx = {req: loopBackContext.active};
+ const httpRequest = httpCtx.req.http.req;
+ const headers = httpRequest.headers;
+ const origin = headers.origin;
+
+ const user = await Self.app.models.Account.findById(info.user.id);
+ const params = {
+ recipient: info.email,
+ lang: user.lang,
+ url: `${origin}/#!/reset-password?access_token=${info.accessToken.id}`
+ };
+
+ const options = Object.assign({}, info.options);
+ for (const param in options)
+ params[param] = options[param];
+
+ const email = new Email(options.emailTemplate, params);
+
+ return email.send();
+ });
+};
diff --git a/db/changes/10470-family/00-accountingType.sql b/db/changes/10470-family/00-accountingType.sql
deleted file mode 100644
index 964027e3a4..0000000000
--- a/db/changes/10470-family/00-accountingType.sql
+++ /dev/null
@@ -1,3 +0,0 @@
-ALTER TABLE `vn`.`accountingType` ADD daysInFuture INT NULL;
-ALTER TABLE `vn`.`accountingType` MODIFY COLUMN daysInFuture int(11) DEFAULT 0 NULL;
-UPDATE `vn`.`accountingType` SET daysInFuture=1 WHERE id=8;
\ No newline at end of file
diff --git a/db/changes/10470-family/00-aclItemType.sql b/db/changes/10470-family/00-aclItemType.sql
deleted file mode 100644
index 836a69dfd2..0000000000
--- a/db/changes/10470-family/00-aclItemType.sql
+++ /dev/null
@@ -1,4 +0,0 @@
-INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
- VALUES
- ('ItemType', '*', 'READ', 'ALLOW', 'ROLE', 'employee'),
- ('ItemType', '*', 'WRITE', 'ALLOW', 'ROLE', 'buyer');
\ No newline at end of file
diff --git a/db/changes/10470-family/00-aclMdb.sql b/db/changes/10470-family/00-aclMdb.sql
deleted file mode 100644
index b02ddc4514..0000000000
--- a/db/changes/10470-family/00-aclMdb.sql
+++ /dev/null
@@ -1,14 +0,0 @@
-CREATE TABLE IF NOT EXISTS `vn`.`mdbBranch` (
- `name` VARCHAR(255),
- PRIMARY KEY(`name`)
-);
-
-CREATE TABLE IF NOT EXISTS `vn`.`mdbVersion` (
- `app` VARCHAR(255) NOT NULL,
- `branchFk` VARCHAR(255) NOT NULL,
- `version` INT,
- CONSTRAINT `mdbVersion_branchFk` FOREIGN KEY (`branchFk`) REFERENCES `vn`.`mdbBranch` (`name`) ON DELETE CASCADE ON UPDATE CASCADE
-);
-
-INSERT IGNORE INTO `salix`.`ACL` (`id`, `model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
- VALUES(318, 'MdbVersion', '*', '*', 'ALLOW', 'ROLE', 'developer');
diff --git a/db/changes/10470-family/00-chat.sql b/db/changes/10470-family/00-chat.sql
deleted file mode 100644
index d4a8f068a7..0000000000
--- a/db/changes/10470-family/00-chat.sql
+++ /dev/null
@@ -1,13 +0,0 @@
-CREATE TABLE `vn`.`chat` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `senderFk` int(10) unsigned DEFAULT NULL,
- `recipient` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
- `dated` date DEFAULT NULL,
- `checkUserStatus` tinyint(1) DEFAULT NULL,
- `message` varchar(200) COLLATE utf8_unicode_ci DEFAULT NULL,
- `status` tinyint(1) DEFAULT NULL,
- `attempts` int(1) DEFAULT NULL,
- PRIMARY KEY (`id`),
- KEY `chat_FK` (`senderFk`),
- CONSTRAINT `chat_FK` FOREIGN KEY (`senderFk`) REFERENCES `account`.`user` (`id`) ON UPDATE CASCADE
-) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
\ No newline at end of file
diff --git a/db/changes/10470-family/00-creditInsurance.sql b/db/changes/10470-family/00-creditInsurance.sql
deleted file mode 100644
index 9d4db470b8..0000000000
--- a/db/changes/10470-family/00-creditInsurance.sql
+++ /dev/null
@@ -1,8 +0,0 @@
-ALTER TABLE `vn`.`creditInsurance` ADD creditClassificationFk int(11) NULL;
-
-UPDATE `vn`.`creditInsurance` AS `destiny`
- SET `destiny`.`creditClassificationFk`= (SELECT creditClassification FROM `vn`.`creditInsurance` AS `origin` WHERE `origin`.id = `destiny`.id);
-
-ALTER TABLE `vn`.`creditInsurance`
- ADD CONSTRAINT `creditInsurance_creditClassificationFk` FOREIGN KEY (`creditClassificationFk`)
- REFERENCES `vn`.`creditClassification` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
\ No newline at end of file
diff --git a/db/changes/10470-family/00-defaultViewConfig.sql b/db/changes/10470-family/00-defaultViewConfig.sql
deleted file mode 100644
index d423599b17..0000000000
--- a/db/changes/10470-family/00-defaultViewConfig.sql
+++ /dev/null
@@ -1,3 +0,0 @@
-INSERT INTO `salix`.`defaultViewConfig` (tableCode, columns)
-VALUES ('clientsDetail', '{"id":true,"phone":true,"city":true,"socialName":true,"salesPersonFk":true,"email":true,"name":false,"fi":false,"credit":false,"creditInsurance":false,"mobile":false,"street":false,"countryFk":false,"provinceFk":false,"postcode":false,"created":false,"businessTypeFk":false,"payMethodFk":false,"sageTaxTypeFk":false,"sageTransactionTypeFk":false,"isActive":false,"isVies":false,"isTaxDataChecked":false,"isEqualizated":false,"isFreezed":false,"hasToInvoice":false,"hasToInvoiceByAddress":false,"isToBeMailed":false,"hasLcr":false,"hasCoreVnl":false,"hasSepaVnl":false}');
-
diff --git a/db/changes/10470-family/00-ticket_doRefund.sql b/db/changes/10470-family/00-ticket_doRefund.sql
deleted file mode 100644
index f4ecf29d71..0000000000
--- a/db/changes/10470-family/00-ticket_doRefund.sql
+++ /dev/null
@@ -1,127 +0,0 @@
-DROP PROCEDURE IF EXISTS `vn`.`ticket_doRefund`;
-
-DELIMITER $$
-$$
-CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_doRefund`(OUT vNewTicket INT)
-BEGIN
-/**
- * Crea un ticket de abono a partir de tmp.sale y/o tmp.ticketService
- *
- * @return vNewTicket
- */
- DECLARE vDone BIT DEFAULT 0;
- DECLARE vClientFk MEDIUMINT;
- DECLARE vWarehouse TINYINT;
- DECLARE vCompany MEDIUMINT;
- DECLARE vAddress MEDIUMINT;
- DECLARE vRefundAgencyMode INT;
- DECLARE vItemFk INT;
- DECLARE vQuantity DECIMAL (10,2);
- DECLARE vConcept VARCHAR(50);
- DECLARE vPrice DECIMAL (10,2);
- DECLARE vDiscount TINYINT;
- DECLARE vSaleNew INT;
- DECLARE vSaleMain INT;
- DECLARE vZoneFk INT;
- DECLARE vDescription VARCHAR(50);
- DECLARE vTaxClassFk INT;
- DECLARE vTicketServiceTypeFk INT;
- DECLARE vOriginTicket INT;
-
- DECLARE cSales CURSOR FOR
- SELECT s.id, s.itemFk, - s.quantity, s.concept, s.price, s.discount
- FROM tmp.sale s;
-
- DECLARE cTicketServices CURSOR FOR
- SELECT ts.description, - ts.quantity, ts.price, ts.taxClassFk, ts.ticketServiceTypeFk
- FROM tmp.ticketService ts;
-
- DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
-
- SELECT sub.ticketFk INTO vOriginTicket
- FROM (
- SELECT s.ticketFk
- FROM tmp.sale s
- UNION ALL
- SELECT ts.ticketFk
- FROM tmp.ticketService ts
- ) sub
- LIMIT 1;
-
- SELECT id INTO vRefundAgencyMode
- FROM agencyMode WHERE `name` = 'ABONO';
-
- SELECT clientFk, warehouseFk, companyFk, addressFk
- INTO vClientFk, vWarehouse, vCompany, vAddress
- FROM ticket
- WHERE id = vOriginTicket;
-
- SELECT id INTO vZoneFk
- FROM zone WHERE agencyModeFk = vRefundAgencyMode
- LIMIT 1;
-
- INSERT INTO vn.ticket (
- clientFk,
- shipped,
- addressFk,
- agencyModeFk,
- nickname,
- warehouseFk,
- companyFk,
- landed,
- zoneFk
- )
- SELECT
- vClientFk,
- CURDATE(),
- vAddress,
- vRefundAgencyMode,
- a.nickname,
- vWarehouse,
- vCompany,
- CURDATE(),
- vZoneFk
- FROM address a
- WHERE a.id = vAddress;
-
- SET vNewTicket = LAST_INSERT_ID();
-
- SET vDone := FALSE;
- OPEN cSales;
- FETCH cSales INTO vSaleMain, vItemFk, vQuantity, vConcept, vPrice, vDiscount;
-
- WHILE NOT vDone DO
-
- INSERT INTO vn.sale(ticketFk, itemFk, quantity, concept, price, discount)
- VALUES( vNewTicket, vItemFk, vQuantity, vConcept, vPrice, vDiscount );
-
- SET vSaleNew = LAST_INSERT_ID();
-
- INSERT INTO vn.saleComponent(saleFk,componentFk,`value`)
- SELECT vSaleNew,componentFk,`value`
- FROM vn.saleComponent
- WHERE saleFk = vSaleMain;
-
- FETCH cSales INTO vSaleMain, vItemFk, vQuantity, vConcept, vPrice, vDiscount;
-
- END WHILE;
- CLOSE cSales;
-
- SET vDone := FALSE;
- OPEN cTicketServices;
- FETCH cTicketServices INTO vDescription, vQuantity, vPrice, vTaxClassFk, vTicketServiceTypeFk;
-
- WHILE NOT vDone DO
-
- INSERT INTO vn.ticketService(description, quantity, price, taxClassFk, ticketFk, ticketServiceTypeFk)
- VALUES(vDescription, vQuantity, vPrice, vTaxClassFk, vNewTicket, vTicketServiceTypeFk);
-
- FETCH cTicketServices INTO vDescription, vQuantity, vPrice, vTaxClassFk, vTicketServiceTypeFk;
-
- END WHILE;
- CLOSE cTicketServices;
-
- INSERT INTO vn.ticketRefund(refundTicketFk, originalTicketFk)
- VALUES(vNewTicket, vOriginTicket);
-END$$
-DELIMITER ;
diff --git a/db/changes/10470-family/01-creditInsuranceTriggers.sql b/db/changes/10470-family/01-creditInsuranceTriggers.sql
deleted file mode 100644
index 53ba3ba11e..0000000000
--- a/db/changes/10470-family/01-creditInsuranceTriggers.sql
+++ /dev/null
@@ -1,11 +0,0 @@
-DELIMITER $$
-$$
-CREATE DEFINER=`root`@`localhost` TRIGGER `vn`.`creditInsurance_beforeInsert`
- BEFORE INSERT ON `creditInsurance`
- FOR EACH ROW
-BEGIN
- IF NEW.creditClassificationFk THEN
- SET NEW.creditClassification = NEW.creditClassificationFk;
- END IF;
-END$$
-DELIMITER ;
\ No newline at end of file
diff --git a/db/changes/10470-family/01-tableConfig.sql b/db/changes/10470-family/01-tableConfig.sql
deleted file mode 100644
index 685981d902..0000000000
--- a/db/changes/10470-family/01-tableConfig.sql
+++ /dev/null
@@ -1 +0,0 @@
-RENAME TABLE `edi`.`fileConfig` to `edi`.`tableConfig`;
\ No newline at end of file
diff --git a/db/changes/10470-family/02-fileConfig.sql b/db/changes/10470-family/02-fileConfig.sql
deleted file mode 100644
index 3109a46166..0000000000
--- a/db/changes/10470-family/02-fileConfig.sql
+++ /dev/null
@@ -1,22 +0,0 @@
-CREATE TABLE `edi`.`fileConfig`
-(
- name varchar(25) NOT NULL,
- checksum text NULL,
- keyValue tinyint(1) default true NOT NULL,
- constraint fileConfig_pk
- primary key (name)
-);
-
-create unique index fileConfig_name_uindex
- on `edi`.`fileConfig` (name);
-
-
-INSERT INTO `edi`.`fileConfig` (name, checksum, keyValue)
-VALUES ('FEC010104', null, 0);
-
-INSERT INTO `edi`.`fileConfig` (name, checksum, keyValue)
-VALUES ('VBN020101', null, 1);
-
-INSERT INTO `edi`.`fileConfig` (name, checksum, keyValue)
-VALUES ('florecompc2', null, 1);
-
diff --git a/db/changes/10471-family/00-chat.sql b/db/changes/10471-family/00-chat.sql
deleted file mode 100644
index 6f3c9d437f..0000000000
--- a/db/changes/10471-family/00-chat.sql
+++ /dev/null
@@ -1,3 +0,0 @@
-ALTER TABLE `vn`.`chat` MODIFY COLUMN message TEXT CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci DEFAULT NULL NULL;
-ALTER TABLE `vn`.`chat` MODIFY COLUMN dated DATETIME DEFAULT NULL NULL;
-ALTER TABLE `vn`.`chat` ADD error TEXT NULL;
diff --git a/db/changes/10472-family/00-creditInsurance.sql b/db/changes/10472-family/00-creditInsurance.sql
deleted file mode 100644
index 4731cfb2a9..0000000000
--- a/db/changes/10472-family/00-creditInsurance.sql
+++ /dev/null
@@ -1,3 +0,0 @@
-ALTER TABLE `vn`.`creditInsurance`
- ADD CONSTRAINT `creditInsurance_creditClassificationFk` FOREIGN KEY (`creditClassificationFk`)
- REFERENCES `vn`.`creditClassification` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
\ No newline at end of file
diff --git a/db/changes/10480-june/00-ACL.sql b/db/changes/10480-june/00-ACL.sql
deleted file mode 100644
index b13e56e21a..0000000000
--- a/db/changes/10480-june/00-ACL.sql
+++ /dev/null
@@ -1,21 +0,0 @@
-INSERT INTO `salix`.`ACL` (model,property,accessType,permission,principalType,principalId)
- VALUES
- ('InvoiceOut','refund','WRITE','ALLOW','ROLE','invoicing'),
- ('InvoiceOut','refund','WRITE','ALLOW','ROLE','salesAssistant'),
- ('InvoiceOut','refund','WRITE','ALLOW','ROLE','claimManager'),
- ('Ticket','refund','WRITE','ALLOW','ROLE','invoicing'),
- ('Ticket','refund','WRITE','ALLOW','ROLE','salesAssistant'),
- ('Ticket','refund','WRITE','ALLOW','ROLE','claimManager'),
- ('Sale','refund','WRITE','ALLOW','ROLE','salesAssistant'),
- ('Sale','refund','WRITE','ALLOW','ROLE','claimManager'),
- ('TicketRefund','*','WRITE','ALLOW','ROLE','invoicing'),
- ('ClaimObservation','*','WRITE','ALLOW','ROLE','salesPerson'),
- ('ClaimObservation','*','READ','ALLOW','ROLE','salesPerson'),
- ('Client','setPassword','WRITE','ALLOW','ROLE','salesPerson'),
- ('Client','updateUser','WRITE','ALLOW','ROLE','salesPerson');
-
-DELETE FROM `salix`.`ACL` WHERE id=313;
-
-UPDATE `salix`.`ACL`
- SET principalId='invoicing'
- WHERE id=297;
\ No newline at end of file
diff --git a/db/changes/10480-june/00-aclShelvingLog.sql b/db/changes/10480-june/00-aclShelvingLog.sql
deleted file mode 100644
index dc75142d12..0000000000
--- a/db/changes/10480-june/00-aclShelvingLog.sql
+++ /dev/null
@@ -1,3 +0,0 @@
-INSERT INTO `salix`.`ACL` (model,property,accessType,permission,principalType,principalId)
- VALUES
- ('ShelvingLog','*','READ','ALLOW','ROLE','employee');
\ No newline at end of file
diff --git a/db/changes/10480-june/00-aclZoneExclusionGeos.sql b/db/changes/10480-june/00-aclZoneExclusionGeos.sql
deleted file mode 100644
index 4c0f6c9916..0000000000
--- a/db/changes/10480-june/00-aclZoneExclusionGeos.sql
+++ /dev/null
@@ -1,4 +0,0 @@
-INSERT INTO `salix`.`ACL`(`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
- VALUES
- ('ZoneExclusionGeo', '*', 'READ', 'ALLOW', 'ROLE', 'employee'),
- ('ZoneExclusionGeo', '*', 'WRITE', 'ALLOW', 'ROLE', 'deliveryBoss');
\ No newline at end of file
diff --git a/db/changes/10480-june/00-albaran_gestdoc.sql b/db/changes/10480-june/00-albaran_gestdoc.sql
deleted file mode 100644
index a0ba93bd3a..0000000000
--- a/db/changes/10480-june/00-albaran_gestdoc.sql
+++ /dev/null
@@ -1,2 +0,0 @@
-ALTER TABLE `vn2008`.`albaran_gestdoc` DROP FOREIGN KEY fk_albaran_gestdoc_gestdoc1;
-ALTER TABLE `vn2008`.`albaran_gestdoc` ADD CONSTRAINT albaran_gestdoc_FK FOREIGN KEY (gestdoc_id) REFERENCES `vn`.`dms`(id) ON DELETE CASCADE ON UPDATE CASCADE;
\ No newline at end of file
diff --git a/db/changes/10480-june/00-client.sql b/db/changes/10480-june/00-client.sql
deleted file mode 100644
index 4a39bbdf95..0000000000
--- a/db/changes/10480-june/00-client.sql
+++ /dev/null
@@ -1,3 +0,0 @@
-alter table `vn`.`client`
- add hasIncoterms tinyint(1) default 0 not null comment 'Received incoterms authorization from client';
-
diff --git a/db/changes/10480-june/00-deprecations.sql b/db/changes/10480-june/00-deprecations.sql
deleted file mode 100644
index 68becd13e9..0000000000
--- a/db/changes/10480-june/00-deprecations.sql
+++ /dev/null
@@ -1,13 +0,0 @@
-DROP FUNCTION `account`.`userGetId`;
-DROP FUNCTION `account`.`myUserGetName`;
-DROP FUNCTION `account`.`myUserGetId`;
-DROP FUNCTION `account`.`myUserHasRole`;
-DROP FUNCTION `account`.`myUserHasRoleId`;
-DROP FUNCTION `account`.`userGetName`;
-DROP FUNCTION `account`.`userHasRole`;
-DROP FUNCTION `account`.`userHasRoleId`;
-DROP PROCEDURE `account`.`myUserLogout`;
-DROP PROCEDURE `account`.`userLogin`;
-DROP PROCEDURE `account`.`userLoginWithKey`;
-DROP PROCEDURE `account`.`userLoginWithName`;
-DROP PROCEDURE `account`.`userSetPassword`;
\ No newline at end of file
diff --git a/db/changes/10480-june/00-item.sql b/db/changes/10480-june/00-item.sql
deleted file mode 100644
index a08d3f4c14..0000000000
--- a/db/changes/10480-june/00-item.sql
+++ /dev/null
@@ -1 +0,0 @@
-ALTER TABLE `vn`.`item` MODIFY COLUMN description TEXT CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci DEFAULT NULL NULL;
diff --git a/db/changes/10480-june/00-route.sql b/db/changes/10480-june/00-route.sql
deleted file mode 100644
index beb7d5e414..0000000000
--- a/db/changes/10480-june/00-route.sql
+++ /dev/null
@@ -1,10 +0,0 @@
-UPDATE `vn`.`route` r
- JOIN(SELECT r.id, wl.workcenterFk
- FROM `vn`.`route` r
- JOIN `vn`.`routeLog` rl ON rl.originFk = r.id
- JOIN `vn`.`workerLabour` wl ON wl.workerFk = rl.userFk
- AND r.created BETWEEN wl.started AND IFNULL(wl.ended, r.created)
- WHERE r.created BETWEEN '2021-12-01' AND CURDATE()
- AND rl.action = 'insert'
- )sub ON sub.id = r.id
- SET r.commissionWorkCenterFk = sub.workcenterFk;
\ No newline at end of file
diff --git a/db/changes/10480-june/00-sample.sql b/db/changes/10480-june/00-sample.sql
deleted file mode 100644
index 18beb736da..0000000000
--- a/db/changes/10480-june/00-sample.sql
+++ /dev/null
@@ -1,2 +0,0 @@
-INSERT INTO `vn`.`sample` (code, description, isVisible, hasCompany, hasPreview, datepickerEnabled)
-VALUES ('incoterms-authorization', 'Autorización de incoterms', 1, 1, 1, 0);
\ No newline at end of file
diff --git a/db/changes/10480-june/00-shelving.sql b/db/changes/10480-june/00-shelving.sql
deleted file mode 100644
index c66d164c4f..0000000000
--- a/db/changes/10480-june/00-shelving.sql
+++ /dev/null
@@ -1,18 +0,0 @@
-ALTER TABLE `vn`.`itemShelving` DROP FOREIGN KEY itemShelving_fk2;
-ALTER TABLE `vn`.`shelvingLog` DROP FOREIGN KEY shelvingLog_FK_ibfk_1;
-ALTER TABLE `vn`.`smartTag` DROP FOREIGN KEY smartTag_shelving_fk;
-ALTER TABLE `vn`.`workerShelving` DROP FOREIGN KEY workerShelving_shelving_fk;
-
-ALTER TABLE `vn`.`shelving` DROP PRIMARY KEY;
-ALTER TABLE `vn`.`shelving` ADD id INT auto_increment PRIMARY KEY NULL;
-ALTER TABLE `vn`.`shelving` CHANGE id id int(11) auto_increment NOT NULL FIRST;
-ALTER TABLE `vn`.`shelving` ADD CONSTRAINT shelving_UN UNIQUE KEY (code);
-
-ALTER TABLE `vn`.`itemShelving` ADD CONSTRAINT itemShelving_fk2 FOREIGN KEY (shelvingFk) REFERENCES `vn`.`shelving`(code) ON DELETE CASCADE ON UPDATE CASCADE;
-ALTER TABLE `vn`.`shelvingLog` ADD CONSTRAINT shelvingLog_FK_ibfk_1 FOREIGN KEY (originFk) REFERENCES `vn`.`shelving`(code) ON DELETE CASCADE ON UPDATE CASCADE;
-ALTER TABLE `vn`.`smartTag` ADD CONSTRAINT smartTag_FK FOREIGN KEY (shelvingFk) REFERENCES `vn`.`shelving`(code) ON DELETE RESTRICT ON UPDATE CASCADE;
-ALTER TABLE `vn`.`workerShelving` ADD CONSTRAINT workerShelving_FK_1 FOREIGN KEY (shelvingFk) REFERENCES `vn`.`shelving`(code) ON DELETE RESTRICT ON UPDATE CASCADE;
-
-ALTER TABLE vn.shelvingLog DROP FOREIGN KEY shelvingLog_FK_ibfk_1;
-ALTER TABLE vn.shelvingLog MODIFY COLUMN originFk INT NOT NULL;
-ALTER TABLE vn.shelvingLog ADD CONSTRAINT shelvingLog_FK FOREIGN KEY (originFk) REFERENCES vn.shelving(id) ON DELETE CASCADE ON UPDATE CASCADE;
\ No newline at end of file
diff --git a/db/changes/10480-june/00-ticketRefund_beforeUpsert.sql b/db/changes/10480-june/00-ticketRefund_beforeUpsert.sql
deleted file mode 100644
index e6506c5d78..0000000000
--- a/db/changes/10480-june/00-ticketRefund_beforeUpsert.sql
+++ /dev/null
@@ -1,21 +0,0 @@
-DROP PROCEDURE IF EXISTS `vn`.`ticketRefund_beforeUpsert`;
-
-DELIMITER $$
-$$
-CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticketRefund_beforeUpsert`(vRefundTicketFk INT, vOriginalTicketFk INT)
-BEGIN
- DECLARE vAlreadyExists BOOLEAN DEFAULT FALSE;
-
- IF vRefundTicketFk = vOriginalTicketFk THEN
- CALL util.throw('Original ticket and refund ticket has same id');
- END IF;
-
- SELECT COUNT(*) INTO vAlreadyExists
- FROM ticketRefund
- WHERE originalTicketFk = vOriginalTicketFk;
-
- IF vAlreadyExists > 0 THEN
- CALL util.throw('This ticket is already a refund');
- END IF;
-END$$
-DELIMITER ;
diff --git a/db/changes/10480-june/01-claimObservation.sql b/db/changes/10480-june/01-claimObservation.sql
deleted file mode 100644
index 8dc126a9ea..0000000000
--- a/db/changes/10480-june/01-claimObservation.sql
+++ /dev/null
@@ -1,13 +0,0 @@
-CREATE TABLE `vn`.`claimObservation` (
- `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
- `claimFk` int(10) unsigned NOT NULL,
- `workerFk` int(10) unsigned DEFAULT NULL,
- `text` text COLLATE utf8_unicode_ci NOT NULL,
- `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
- PRIMARY KEY (`id`),
- KEY `worker_key` (`workerFk`),
- KEY `claim_key` (`claimFk`),
- KEY `claimObservation_created_IDX` (`created`) USING BTREE,
- CONSTRAINT `claimObservation_ibfk_1` FOREIGN KEY (`claimFk`) REFERENCES `vn`.`claim` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
- CONSTRAINT `claimObservation_ibfk_2` FOREIGN KEY (`workerFk`) REFERENCES `vn`.`worker` (`id`) ON UPDATE CASCADE
-) COMMENT='Todas las observaciones referentes a una reclamación'
\ No newline at end of file
diff --git a/db/changes/10480-june/02-claimTextMigration.sql b/db/changes/10480-june/02-claimTextMigration.sql
deleted file mode 100644
index fa5f6fe834..0000000000
--- a/db/changes/10480-june/02-claimTextMigration.sql
+++ /dev/null
@@ -1,2 +0,0 @@
-INSERT INTO `vn`.`claimObservation` (`claimFk`, `text`, `created`)
-SELECT `id`, `observation`, `created` FROM `vn`.`claim`
\ No newline at end of file
diff --git a/db/changes/10480-june/04-aclParking.sql b/db/changes/10480-june/04-aclParking.sql
deleted file mode 100644
index 05acd68b1c..0000000000
--- a/db/changes/10480-june/04-aclParking.sql
+++ /dev/null
@@ -1,2 +0,0 @@
-INSERT INTO `salix`.`ACL` (model,property,accessType,permission,principalType,principalId)
- VALUES ('Parking','*','*','ALLOW','ROLE','employee')
\ No newline at end of file
diff --git a/db/changes/10480-june/04-aclShelving.sql b/db/changes/10480-june/04-aclShelving.sql
deleted file mode 100644
index b237dfe0da..0000000000
--- a/db/changes/10480-june/04-aclShelving.sql
+++ /dev/null
@@ -1,2 +0,0 @@
-INSERT INTO `salix`.`ACL` (model,property,accessType,permission,principalType,principalId)
- VALUES ('Shelving','*','*','ALLOW','ROLE','employee')
\ No newline at end of file
diff --git a/db/changes/10481-june/00-aclOsTicket.sql b/db/changes/10481-june/00-aclOsTicket.sql
deleted file mode 100644
index ae2a121f56..0000000000
--- a/db/changes/10481-june/00-aclOsTicket.sql
+++ /dev/null
@@ -1,3 +0,0 @@
-INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
- VALUES
- ('OsTicket', '*', '*', 'ALLOW', 'ROLE', 'employee');
\ No newline at end of file
diff --git a/db/changes/10481-june/00-aclOsTicketConfig.sql b/db/changes/10481-june/00-aclOsTicketConfig.sql
deleted file mode 100644
index ad53ea6ae5..0000000000
--- a/db/changes/10481-june/00-aclOsTicketConfig.sql
+++ /dev/null
@@ -1,3 +0,0 @@
-INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
- VALUES
- ('OsTicketConfig', '*', '*', 'ALLOW', 'ROLE', 'it');
\ No newline at end of file
diff --git a/db/changes/10481-june/00-osTicketConfig.sql b/db/changes/10481-june/00-osTicketConfig.sql
deleted file mode 100644
index 8727c816dd..0000000000
--- a/db/changes/10481-june/00-osTicketConfig.sql
+++ /dev/null
@@ -1,16 +0,0 @@
-CREATE TABLE `vn`.`osTicketConfig` (
- `id` int(11) NOT NULL,
- `host` varchar(100) COLLATE utf8mb3_unicode_ci DEFAULT NULL,
- `user` varchar(100) COLLATE utf8mb3_unicode_ci DEFAULT NULL,
- `password` varchar(100) COLLATE utf8mb3_unicode_ci DEFAULT NULL,
- `oldStatus` varchar(100) COLLATE utf8mb3_unicode_ci DEFAULT NULL,
- `newStatusId` int(11) DEFAULT NULL,
- `action` varchar(100) COLLATE utf8mb3_unicode_ci DEFAULT NULL,
- `day` int(11) DEFAULT NULL,
- `comment` varchar(100) COLLATE utf8mb3_unicode_ci DEFAULT NULL,
- `hostDb` varchar(100) COLLATE utf8mb3_unicode_ci DEFAULT NULL,
- `userDb` varchar(100) COLLATE utf8mb3_unicode_ci DEFAULT NULL,
- `passwordDb` varchar(100) COLLATE utf8mb3_unicode_ci DEFAULT NULL,
- `portDb` int(11) DEFAULT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
\ No newline at end of file
diff --git a/db/changes/10490-august/00-ACL.sql b/db/changes/224701/00-ACL.sql
similarity index 100%
rename from db/changes/10490-august/00-ACL.sql
rename to db/changes/224701/00-ACL.sql
diff --git a/db/changes/10490-august/00-acl_receiptPdf.sql b/db/changes/224701/00-acl_receiptPdf.sql
similarity index 100%
rename from db/changes/10490-august/00-acl_receiptPdf.sql
rename to db/changes/224701/00-acl_receiptPdf.sql
diff --git a/db/changes/10490-august/00-clientConsumptionQueue.sql b/db/changes/224701/00-clientConsumptionQueue.sql
similarity index 100%
rename from db/changes/10490-august/00-clientConsumptionQueue.sql
rename to db/changes/224701/00-clientConsumptionQueue.sql
diff --git a/db/changes/10490-august/00-invoiceOutQueue.sql b/db/changes/224701/00-invoiceOutQueue.sql
similarity index 100%
rename from db/changes/10490-august/00-invoiceOutQueue.sql
rename to db/changes/224701/00-invoiceOutQueue.sql
diff --git a/db/changes/10490-august/00-itemConfig.sql b/db/changes/224701/00-itemConfig.sql
similarity index 100%
rename from db/changes/10490-august/00-itemConfig.sql
rename to db/changes/224701/00-itemConfig.sql
diff --git a/db/changes/10490-august/00-printConfig.sql b/db/changes/224701/00-printConfig.sql
similarity index 100%
rename from db/changes/10490-august/00-printConfig.sql
rename to db/changes/224701/00-printConfig.sql
diff --git a/db/changes/10490-august/00-sale_afterUpdate.sql b/db/changes/224701/00-sale_afterUpdate.sql
similarity index 100%
rename from db/changes/10490-august/00-sale_afterUpdate.sql
rename to db/changes/224701/00-sale_afterUpdate.sql
diff --git a/db/changes/10490-august/00-sample.sql b/db/changes/224701/00-sample.sql
similarity index 100%
rename from db/changes/10490-august/00-sample.sql
rename to db/changes/224701/00-sample.sql
diff --git a/db/changes/10490-august/00-user_hasGrant.sql b/db/changes/224701/00-user_hasGrant.sql
similarity index 100%
rename from db/changes/10490-august/00-user_hasGrant.sql
rename to db/changes/224701/00-user_hasGrant.sql
diff --git a/db/changes/10491-august/00-ACL_workerDisableExcluded.sql b/db/changes/224702/00-ACL_workerDisableExcluded.sql
similarity index 100%
rename from db/changes/10491-august/00-ACL_workerDisableExcluded.sql
rename to db/changes/224702/00-ACL_workerDisableExcluded.sql
diff --git a/db/changes/10491-august/00-aclBusiness.sql b/db/changes/224702/00-aclBusiness.sql
similarity index 100%
rename from db/changes/10491-august/00-aclBusiness.sql
rename to db/changes/224702/00-aclBusiness.sql
diff --git a/db/changes/10491-august/00-aclUsesMana.sql b/db/changes/224702/00-aclUsesMana.sql
similarity index 100%
rename from db/changes/10491-august/00-aclUsesMana.sql
rename to db/changes/224702/00-aclUsesMana.sql
diff --git a/db/changes/10491-august/00-defaultPayDem_sameAs_production.sql b/db/changes/224702/00-defaultPayDem_sameAs_production.sql
similarity index 100%
rename from db/changes/10491-august/00-defaultPayDem_sameAs_production.sql
rename to db/changes/224702/00-defaultPayDem_sameAs_production.sql
diff --git a/db/changes/10491-august/00-invoiceInPdf.sql b/db/changes/224702/00-invoiceInPdf.sql
similarity index 100%
rename from db/changes/10491-august/00-invoiceInPdf.sql
rename to db/changes/224702/00-invoiceInPdf.sql
diff --git a/db/changes/10491-august/00-newSupplier_ACL.sql b/db/changes/224702/00-newSupplier_ACL.sql
similarity index 100%
rename from db/changes/10491-august/00-newSupplier_ACL.sql
rename to db/changes/224702/00-newSupplier_ACL.sql
diff --git a/db/changes/10491-august/00-notificationProc.sql b/db/changes/224702/00-notificationProc.sql
similarity index 100%
rename from db/changes/10491-august/00-notificationProc.sql
rename to db/changes/224702/00-notificationProc.sql
diff --git a/db/changes/10491-august/00-notificationTables.sql b/db/changes/224702/00-notificationTables.sql
similarity index 100%
rename from db/changes/10491-august/00-notificationTables.sql
rename to db/changes/224702/00-notificationTables.sql
diff --git a/db/changes/10491-august/00-payMethodFk_Allow_Null.sql b/db/changes/224702/00-payMethodFk_Allow_Null.sql
similarity index 100%
rename from db/changes/10491-august/00-payMethodFk_Allow_Null.sql
rename to db/changes/224702/00-payMethodFk_Allow_Null.sql
diff --git a/db/changes/10491-august/00-supplierActivityFk_Allow_Null.sql b/db/changes/224702/00-supplierActivityFk_Allow_Null.sql
similarity index 100%
rename from db/changes/10491-august/00-supplierActivityFk_Allow_Null.sql
rename to db/changes/224702/00-supplierActivityFk_Allow_Null.sql
diff --git a/db/changes/10491-august/00-ticket_closeByTicket.sql b/db/changes/224702/00-ticket_closeByTicket.sql
similarity index 100%
rename from db/changes/10491-august/00-ticket_closeByTicket.sql
rename to db/changes/224702/00-ticket_closeByTicket.sql
diff --git a/db/changes/10491-august/00-zipConfig.sql b/db/changes/224702/00-zipConfig.sql
similarity index 100%
rename from db/changes/10491-august/00-zipConfig.sql
rename to db/changes/224702/00-zipConfig.sql
diff --git a/db/changes/10500-november/00-ACL.sql b/db/changes/224801/00-ACL.sql
similarity index 100%
rename from db/changes/10500-november/00-ACL.sql
rename to db/changes/224801/00-ACL.sql
diff --git a/db/changes/10500-november/00-claim.sql b/db/changes/224801/00-claim.sql
similarity index 100%
rename from db/changes/10500-november/00-claim.sql
rename to db/changes/224801/00-claim.sql
diff --git a/db/changes/10500-november/00-claimRma.sql b/db/changes/224801/00-claimRma.sql
similarity index 100%
rename from db/changes/10500-november/00-claimRma.sql
rename to db/changes/224801/00-claimRma.sql
diff --git a/db/changes/10501-november/00-aclNotification.sql b/db/changes/224901/00-aclNotification.sql
similarity index 100%
rename from db/changes/10501-november/00-aclNotification.sql
rename to db/changes/224901/00-aclNotification.sql
diff --git a/db/changes/10501-november/00-packingSiteConfig.sql b/db/changes/224901/00-packingSiteConfig.sql
similarity index 100%
rename from db/changes/10501-november/00-packingSiteConfig.sql
rename to db/changes/224901/00-packingSiteConfig.sql
diff --git a/db/changes/10501-november/00-packingSiteUpdate.sql b/db/changes/224901/00-packingSiteUpdate.sql
similarity index 100%
rename from db/changes/10501-november/00-packingSiteUpdate.sql
rename to db/changes/224901/00-packingSiteUpdate.sql
diff --git a/db/changes/10501-november/00-salix_url.sql b/db/changes/224901/00-salix_url.sql
similarity index 100%
rename from db/changes/10501-november/00-salix_url.sql
rename to db/changes/224901/00-salix_url.sql
diff --git a/db/changes/224902/00-aclUserPassword.sql b/db/changes/224902/00-aclUserPassword.sql
new file mode 100644
index 0000000000..b92b54c283
--- /dev/null
+++ b/db/changes/224902/00-aclUserPassword.sql
@@ -0,0 +1,2 @@
+DELETE FROM `salix`.`ACL`
+ WHERE model = 'UserPassword';
diff --git a/db/changes/10502-november/00-deletePickupContact.sql b/db/changes/224902/00-deletePickupContact.sql
similarity index 100%
rename from db/changes/10502-november/00-deletePickupContact.sql
rename to db/changes/224902/00-deletePickupContact.sql
diff --git a/db/changes/10502-november/00-itemShelvingACL.sql b/db/changes/224902/00-itemShelvingACL.sql
similarity index 100%
rename from db/changes/10502-november/00-itemShelvingACL.sql
rename to db/changes/224902/00-itemShelvingACL.sql
diff --git a/db/changes/10502-november/00-itemShelvingPlacementSupplyStockACL.sql b/db/changes/224902/00-itemShelvingPlacementSupplyStockACL.sql
similarity index 100%
rename from db/changes/10502-november/00-itemShelvingPlacementSupplyStockACL.sql
rename to db/changes/224902/00-itemShelvingPlacementSupplyStockACL.sql
diff --git a/db/changes/10502-november/00-workerTimeControlMail.sql b/db/changes/224902/00-workerTimeControlMail.sql
similarity index 100%
rename from db/changes/10502-november/00-workerTimeControlMail.sql
rename to db/changes/224902/00-workerTimeControlMail.sql
diff --git a/db/changes/10502-november/00-zone_getPostalCode.sql b/db/changes/224902/00-zone_getPostalCode.sql
similarity index 100%
rename from db/changes/10502-november/00-zone_getPostalCode.sql
rename to db/changes/224902/00-zone_getPostalCode.sql
diff --git a/db/changes/10503-november/00-ACL_notification_InvoiceE.sql b/db/changes/224903/00-ACL_notification_InvoiceE.sql
similarity index 100%
rename from db/changes/10503-november/00-ACL_notification_InvoiceE.sql
rename to db/changes/224903/00-ACL_notification_InvoiceE.sql
diff --git a/db/changes/10503-november/00-aclInvoiceOut.sql b/db/changes/224903/00-aclInvoiceOut.sql
similarity index 100%
rename from db/changes/10503-november/00-aclInvoiceOut.sql
rename to db/changes/224903/00-aclInvoiceOut.sql
diff --git a/db/changes/10503-november/00-alter_expedition_itemFk.sql b/db/changes/224903/00-alter_expedition_itemFk.sql
similarity index 100%
rename from db/changes/10503-november/00-alter_expedition_itemFk.sql
rename to db/changes/224903/00-alter_expedition_itemFk.sql
diff --git a/db/changes/10503-november/00-clientHasInvoiceElectronic.sql b/db/changes/224903/00-clientHasInvoiceElectronic.sql
similarity index 100%
rename from db/changes/10503-november/00-clientHasInvoiceElectronic.sql
rename to db/changes/224903/00-clientHasInvoiceElectronic.sql
diff --git a/db/changes/10503-november/00-collection_missingTrash.sql b/db/changes/224903/00-collection_missingTrash.sql
similarity index 100%
rename from db/changes/10503-november/00-collection_missingTrash.sql
rename to db/changes/224903/00-collection_missingTrash.sql
diff --git a/db/changes/10503-november/00-deleteInvoiceOutQueue.sql b/db/changes/224903/00-deleteInvoiceOutQueue.sql
similarity index 100%
rename from db/changes/10503-november/00-deleteInvoiceOutQueue.sql
rename to db/changes/224903/00-deleteInvoiceOutQueue.sql
diff --git a/db/changes/10503-november/00-editTrackedACL.sql b/db/changes/224903/00-editTrackedACL.sql
similarity index 100%
rename from db/changes/10503-november/00-editTrackedACL.sql
rename to db/changes/224903/00-editTrackedACL.sql
diff --git a/db/changes/10503-november/00-greuge.sql b/db/changes/224903/00-greuge.sql
similarity index 100%
rename from db/changes/10503-november/00-greuge.sql
rename to db/changes/224903/00-greuge.sql
diff --git a/db/changes/10503-november/00-insert_notification_invoiceE.sql b/db/changes/224903/00-insert_notification_invoiceE.sql
similarity index 100%
rename from db/changes/10503-november/00-insert_notification_invoiceE.sql
rename to db/changes/224903/00-insert_notification_invoiceE.sql
diff --git a/db/changes/10503-november/00-isCompensationACL.sql b/db/changes/224903/00-isCompensationACL.sql
similarity index 100%
rename from db/changes/10503-november/00-isCompensationACL.sql
rename to db/changes/224903/00-isCompensationACL.sql
diff --git a/db/changes/10503-november/00-osTicketConfig.sql b/db/changes/224903/00-osTicketConfig.sql
similarity index 100%
rename from db/changes/10503-november/00-osTicketConfig.sql
rename to db/changes/224903/00-osTicketConfig.sql
diff --git a/db/changes/10503-november/00-ticket_canMerge.sql b/db/changes/224903/00-ticket_canMerge.sql
similarity index 100%
rename from db/changes/10503-november/00-ticket_canMerge.sql
rename to db/changes/224903/00-ticket_canMerge.sql
diff --git a/db/changes/10503-november/00-ticket_canbePostponed.sql b/db/changes/224903/00-ticket_canbePostponed.sql
similarity index 100%
rename from db/changes/10503-november/00-ticket_canbePostponed.sql
rename to db/changes/224903/00-ticket_canbePostponed.sql
diff --git a/db/changes/10503-november/00-timeBusiness_calculate.sql b/db/changes/224903/00-timeBusiness_calculate.sql
similarity index 100%
rename from db/changes/10503-november/00-timeBusiness_calculate.sql
rename to db/changes/224903/00-timeBusiness_calculate.sql
diff --git a/db/changes/10503-november/01-updateClientHasInvoiceElectronic.sql b/db/changes/224903/01-updateClientHasInvoiceElectronic.sql
similarity index 100%
rename from db/changes/10503-november/01-updateClientHasInvoiceElectronic.sql
rename to db/changes/224903/01-updateClientHasInvoiceElectronic.sql
diff --git a/db/changes/10510-december/deleteMe.keep b/db/changes/225001/.gitkeep
similarity index 100%
rename from db/changes/10510-december/deleteMe.keep
rename to db/changes/225001/.gitkeep
diff --git a/db/dump/dumpedFixtures.sql b/db/dump/dumpedFixtures.sql
index c9c265ae78..a4870e2df0 100644
--- a/db/dump/dumpedFixtures.sql
+++ b/db/dump/dumpedFixtures.sql
@@ -22,7 +22,7 @@ USE `util`;
LOCK TABLES `config` WRITE;
/*!40000 ALTER TABLE `config` DISABLE KEYS */;
-INSERT INTO `config` VALUES (1,'10480',0,'production',NULL);
+INSERT INTO `config` VALUES (1,'224602',0,'production',NULL);
/*!40000 ALTER TABLE `config` ENABLE KEYS */;
UNLOCK TABLES;
diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql
index 482218ed24..92b84be43f 100644
--- a/db/dump/fixtures.sql
+++ b/db/dump/fixtures.sql
@@ -2564,10 +2564,6 @@ UPDATE `vn`.`route`
UPDATE `vn`.`route`
SET `invoiceInFk`=2
WHERE `id`=2;
-INSERT INTO `bs`.`salesPerson` (`workerFk`, `year`, `month`, `portfolioWeight`)
- VALUES
- (18, YEAR(util.VN_CURDATE()), MONTH(util.VN_CURDATE()), 807.23),
- (19, YEAR(util.VN_CURDATE()), MONTH(util.VN_CURDATE()), 34.40);
INSERT INTO `bs`.`sale` (`saleFk`, `amount`, `dated`, `typeFk`, `clientFk`)
VALUES
diff --git a/db/dump/structure.sql b/db/dump/structure.sql
index 6d85d0511f..403534787b 100644
--- a/db/dump/structure.sql
+++ b/db/dump/structure.sql
@@ -81044,4 +81044,3 @@ USE `vncontrol`;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2022-09-16 10:44:31
-
diff --git a/db/import-changes.sh b/db/import-changes.sh
index 2b80654d3e..5461f003bb 100755
--- a/db/import-changes.sh
+++ b/db/import-changes.sh
@@ -81,9 +81,9 @@ N_CHANGES=0
for DIR_PATH in "$DIR/changes/"*; do
DIR_NAME=$(basename $DIR_PATH)
- DIR_VERSION=${DIR_NAME:0:5}
+ DIR_VERSION=${DIR_NAME:0:6}
- if [[ ! "$DIR_NAME" =~ ^[0-9]{5}(-[a-zA-Z0-9]+)?$ ]]; then
+ if [[ ! "$DIR_NAME" =~ ^[0-9]{6}$ ]]; then
echo "[WARN] Ignoring wrong directory name: $DIR_NAME"
continue
fi
diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js
index 06fabe3e61..f550e3a9da 100644
--- a/e2e/helpers/selectors.js
+++ b/e2e/helpers/selectors.js
@@ -29,6 +29,11 @@ export default {
firstModulePinIcon: 'vn-home a:nth-child(1) vn-icon[icon="push_pin"]',
firstModuleRemovePinIcon: 'vn-home a:nth-child(1) vn-icon[icon="remove_circle"]'
},
+ recoverPassword: {
+ recoverPasswordButton: 'vn-login a[ui-sref="recoverPassword"]',
+ email: 'vn-recover-password vn-textfield[ng-model="$ctrl.email"]',
+ sendEmailButton: 'vn-recover-password vn-submit',
+ },
accountIndex: {
addAccount: 'vn-user-index button vn-icon[icon="add"]',
newName: 'vn-user-create vn-textfield[ng-model="$ctrl.user.name"]',
diff --git a/e2e/paths/01-salix/04_recoverPassword.spec.js b/e2e/paths/01-salix/04_recoverPassword.spec.js
new file mode 100644
index 0000000000..80ef32cb51
--- /dev/null
+++ b/e2e/paths/01-salix/04_recoverPassword.spec.js
@@ -0,0 +1,40 @@
+import selectors from '../../helpers/selectors';
+import getBrowser from '../../helpers/puppeteer';
+
+describe('Login path', async() => {
+ let browser;
+ let page;
+
+ beforeAll(async() => {
+ browser = await getBrowser();
+ page = browser.page;
+
+ await page.waitToClick(selectors.recoverPassword.recoverPasswordButton);
+ await page.waitForState('recoverPassword');
+ });
+
+ afterAll(async() => {
+ await browser.close();
+ });
+
+ it('should not throw error if not exist user', async() => {
+ await page.write(selectors.recoverPassword.email, 'fakeEmail@mydomain.com');
+ await page.waitToClick(selectors.recoverPassword.sendEmailButton);
+
+ const message = await page.waitForSnackbar();
+
+ expect(message.text).toContain('Notification sent!');
+ });
+
+ it('should send email', async() => {
+ await page.waitForState('login');
+ await page.waitToClick(selectors.recoverPassword.recoverPasswordButton);
+
+ await page.write(selectors.recoverPassword.email, 'BruceWayne@mydomain.com');
+ await page.waitToClick(selectors.recoverPassword.sendEmailButton);
+ const message = await page.waitForSnackbar();
+ await page.waitForState('login');
+
+ expect(message.text).toContain('Notification sent!');
+ });
+});
diff --git a/e2e/paths/05-ticket/20_future.spec.js b/e2e/paths/05-ticket/20_future.spec.js
index 4fee9523bd..6db2bf4f00 100644
--- a/e2e/paths/05-ticket/20_future.spec.js
+++ b/e2e/paths/05-ticket/20_future.spec.js
@@ -5,80 +5,78 @@ describe('Ticket Future path', () => {
let browser;
let page;
- beforeAll(async () => {
+ beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('employee', 'ticket');
await page.accessToSection('ticket.future');
});
- afterAll(async () => {
+ afterAll(async() => {
await browser.close();
});
const now = new Date();
const tomorrow = new Date(now.getDate() + 1);
- const ticket = {
- originDated: now,
- futureDated: now,
- linesMax: '9999',
- litersMax: '9999',
- warehouseFk: 'Warehouse One'
- };
- 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.clearInput(selectors.ticketFuture.warehouseFk);
await page.waitToClick(selectors.ticketFuture.submit);
let message = await page.waitForSnackbar();
+
expect(message.text).toContain('warehouseFk is a required argument');
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.litersMax);
await page.waitToClick(selectors.ticketFuture.submit);
message = await page.waitForSnackbar();
+
expect(message.text).toContain('litersMax is a required argument');
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.linesMax);
await page.waitToClick(selectors.ticketFuture.submit);
message = await page.waitForSnackbar();
+
expect(message.text).toContain('linesMax is a required argument');
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.futureDated);
await page.waitToClick(selectors.ticketFuture.submit);
message = await page.waitForSnackbar();
+
expect(message.text).toContain('futureDated is a required argument');
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.originDated);
await page.waitToClick(selectors.ticketFuture.submit);
message = await page.waitForSnackbar();
+
expect(message.text).toContain('originDated is a required argument');
});
- it('should search with the required data', async () => {
+ it('should search with the required data', async() => {
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.waitToClick(selectors.ticketFuture.submit);
await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
});
- it('should search with the origin shipped today', async () => {
+ 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 () => {
+ 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 () => {
+ 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);
@@ -86,14 +84,14 @@ describe('Ticket Future path', () => {
await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
});
- it('should search with the destination shipped tomorrow', async () => {
+ 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.clearInput(selectors.ticketFuture.shipped);
@@ -108,7 +106,7 @@ describe('Ticket Future path', () => {
await page.waitForNumberOfElements(selectors.ticketFuture.table, 0);
});
- it('should search with the destination IPT', async () => {
+ it('should search with the destination IPT', async() => {
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.shipped);
@@ -123,7 +121,7 @@ describe('Ticket Future path', () => {
await page.waitForNumberOfElements(selectors.ticketFuture.table, 0);
});
- 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.clearInput(selectors.ticketFuture.shipped);
@@ -138,7 +136,7 @@ describe('Ticket Future path', () => {
await page.waitForNumberOfElements(selectors.ticketFuture.table, 3);
});
- 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.clearInput(selectors.ticketFuture.shipped);
@@ -164,10 +162,10 @@ describe('Ticket Future path', () => {
await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
});
- it('should search in smart-table with an ID Origin', async () => {
+ it('should search in smart-table with an ID Origin', async() => {
await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
- await page.write(selectors.ticketFuture.tableId, "13");
- await page.keyboard.press("Enter");
+ await page.write(selectors.ticketFuture.tableId, '13');
+ await page.keyboard.press('Enter');
await page.waitForNumberOfElements(selectors.ticketFuture.table, 2);
await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
@@ -176,10 +174,10 @@ describe('Ticket Future path', () => {
await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
});
- 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.write(selectors.ticketFuture.tableTfId, "12");
- await page.keyboard.press("Enter");
+ await page.write(selectors.ticketFuture.tableTfId, '12');
+ await page.keyboard.press('Enter');
await page.waitForNumberOfElements(selectors.ticketFuture.table, 5);
await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
@@ -188,7 +186,7 @@ describe('Ticket Future path', () => {
await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
});
- it('should search in smart-table with an IPT Origin', async () => {
+ it('should search in smart-table with an IPT Origin', async() => {
await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
await page.autocompleteSearch(selectors.ticketFuture.tableIpt, 'Vertical');
await page.waitForNumberOfElements(selectors.ticketFuture.table, 1);
@@ -199,7 +197,7 @@ describe('Ticket Future path', () => {
await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
});
- 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.autocompleteSearch(selectors.ticketFuture.tableTfIpt, 'Vertical');
await page.waitForNumberOfElements(selectors.ticketFuture.table, 1);
@@ -210,10 +208,10 @@ describe('Ticket Future path', () => {
await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
});
- it('should search in smart-table with especified Lines', async () => {
+ it('should search in smart-table with especified Lines', async() => {
await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
- await page.write(selectors.ticketFuture.tableLines, "0");
- await page.keyboard.press("Enter");
+ await page.write(selectors.ticketFuture.tableLines, '0');
+ await page.keyboard.press('Enter');
await page.waitForNumberOfElements(selectors.ticketFuture.table, 1);
await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
@@ -222,8 +220,8 @@ describe('Ticket Future path', () => {
await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
- await page.write(selectors.ticketFuture.tableLines, "1");
- await page.keyboard.press("Enter");
+ await page.write(selectors.ticketFuture.tableLines, '1');
+ await page.keyboard.press('Enter');
await page.waitForNumberOfElements(selectors.ticketFuture.table, 5);
await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
@@ -232,10 +230,10 @@ describe('Ticket Future path', () => {
await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
});
- it('should search in smart-table with especified Liters', async () => {
+ it('should search in smart-table with especified Liters', async() => {
await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
- await page.write(selectors.ticketFuture.tableLiters, "0");
- await page.keyboard.press("Enter");
+ await page.write(selectors.ticketFuture.tableLiters, '0');
+ await page.keyboard.press('Enter');
await page.waitForNumberOfElements(selectors.ticketFuture.table, 1);
await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
@@ -244,8 +242,8 @@ describe('Ticket Future path', () => {
await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
- await page.write(selectors.ticketFuture.tableLiters, "28");
- await page.keyboard.press("Enter");
+ await page.write(selectors.ticketFuture.tableLiters, '28');
+ await page.keyboard.press('Enter');
await page.waitForNumberOfElements(selectors.ticketFuture.table, 5);
await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
@@ -254,13 +252,13 @@ describe('Ticket Future path', () => {
await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
});
- it('should check the three last tickets and move to the future', async () => {
+ it('should check the three last tickets and move to the future', async() => {
await page.waitToClick(selectors.ticketFuture.multiCheck);
await page.waitToClick(selectors.ticketFuture.firstCheck);
await page.waitToClick(selectors.ticketFuture.moveButton);
await page.waitToClick(selectors.ticketFuture.acceptButton);
const message = await page.waitForSnackbar();
+
expect(message.text).toContain('Tickets moved successfully!');
});
-
});
diff --git a/front/core/lib/component.js b/front/core/lib/component.js
index f17db68a2a..5695d9449c 100644
--- a/front/core/lib/component.js
+++ b/front/core/lib/component.js
@@ -12,9 +12,10 @@ export default class Component extends EventEmitter {
* @param {HTMLElement} $element The main component element
* @param {$rootScope.Scope} $scope The element scope
* @param {Function} $transclude The transclusion function
+ * @param {Function} $location The location function
*/
- constructor($element, $scope, $transclude) {
- super();
+ constructor($element, $scope, $transclude, $location) {
+ super($element, $scope, $transclude, $location);
this.$ = $scope;
if (!$element) return;
@@ -164,7 +165,7 @@ export default class Component extends EventEmitter {
$transclude.$$boundTransclude.$$slots[slot];
}
}
-Component.$inject = ['$element', '$scope'];
+Component.$inject = ['$element', '$scope', '$location', '$state'];
/*
* Automatically adds the most used services to the prototype, so they are
diff --git a/front/core/services/auth.js b/front/core/services/auth.js
index a1dcfa3953..04520cd0b5 100644
--- a/front/core/services/auth.js
+++ b/front/core/services/auth.js
@@ -23,7 +23,10 @@ export default class Auth {
initialize() {
let criteria = {
- to: state => state.name != 'login'
+ to: state => {
+ const outLayout = ['login', 'recoverPassword', 'resetPassword'];
+ return !outLayout.some(ol => ol == state.name);
+ }
};
this.$transitions.onStart(criteria, transition => {
if (this.loggedIn)
diff --git a/front/salix/components/app/app.html b/front/salix/components/app/app.html
index d32c9f68bc..f14fab2dd3 100644
--- a/front/salix/components/app/app.html
+++ b/front/salix/components/app/app.html
@@ -1,9 +1,8 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + {{ $t(`click`) }} + {{ $t('subject') }} + +
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + {{ $t('Click on the following link to change your password.') }} + {{ $t('subject') }} + +
+
+
+
+
+
+
+
+ |
+
{{$t('dear')}},
+ +{{labelData.levelV}} | -{{labelData.ticketFk}} ⬸ {{labelData.clientFk}} | -{{labelData.shipped}} | -|
- | {{labelData.workerCode}} | -||
{{labelData.labelCount}} | -|||
{{labelData.size}} | -|||
{{labelData.agencyDescription}} |
- {{labelData.lineCount}} | -||
{{labelData.nickName}} | -{{labelData.agencyHour}} | -
{{getVertical(labelData)}} | ++ {{labelData.clientFk ? `${labelData.ticketFk} « ${labelData.clientFk}` : labelData.ticketFk}} + | +{{labelData.shipped || '---'}} | +|
+ | {{labelData.workerCode || '---'}} | +||
{{labelData.labelCount || 0}} | +|||
{{labelData.code == 'V' ? (labelData.size || 0) + 'cm' : (labelData.volume || 0) + 'm³'}} | +|||
{{labelData.agencyDescription ? labelData.agencyDescription.toUpperCase() : '---'}} |
+ {{labelData.lineCount || 0}} | +||
{{labelData.nickName ? labelData.nickName.toUpperCase() : '---'}} | +{{labelData.shippedHour || labelData.zoneHour}} | +