Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 2569-travel_extra_community
gitea/salix/pipeline/head There was a failure building this commit
Details
gitea/salix/pipeline/head There was a failure building this commit
Details
This commit is contained in:
commit
031051abcb
|
@ -29,27 +29,41 @@ module.exports = Self => {
|
|||
let $ = Self.app.models;
|
||||
let token;
|
||||
let usesEmail = user.indexOf('@') !== -1;
|
||||
let userInfo = usesEmail
|
||||
? {email: user}
|
||||
: {username: user};
|
||||
|
||||
let loginInfo = {password};
|
||||
|
||||
if (usesEmail)
|
||||
loginInfo.email = user;
|
||||
else
|
||||
loginInfo.username = user;
|
||||
let loginInfo = Object.assign({password}, userInfo);
|
||||
|
||||
try {
|
||||
token = await $.User.login(loginInfo, 'user');
|
||||
try {
|
||||
let instance = await $.User.findOne({
|
||||
fields: ['username'],
|
||||
where: userInfo
|
||||
});
|
||||
await $.UserAccount.sync(instance.username, password);
|
||||
} catch (err) {
|
||||
if (err.code != 'LOGIN_FAILED' || usesEmail)
|
||||
console.warn(err);
|
||||
}
|
||||
} catch (err) {
|
||||
if (err.code != 'LOGIN_FAILED')
|
||||
throw err;
|
||||
|
||||
let filter = {where: {name: user}};
|
||||
let instance = await Self.findOne(filter);
|
||||
let where = usesEmail
|
||||
? {email: user}
|
||||
: {name: user};
|
||||
Object.assign(where, {
|
||||
password: md5(password || '')
|
||||
});
|
||||
|
||||
if (!instance || instance.password !== md5(password || ''))
|
||||
throw err;
|
||||
let instance = await Self.findOne({
|
||||
fields: ['name'],
|
||||
where
|
||||
});
|
||||
if (!instance) throw err;
|
||||
|
||||
await $.UserAccount.sync(user, password);
|
||||
await $.UserAccount.sync(instance.name, password);
|
||||
token = await $.User.login(loginInfo, 'user');
|
||||
}
|
||||
|
||||
|
|
|
@ -2,24 +2,18 @@ const app = require('vn-loopback/server/server');
|
|||
|
||||
describe('campaign latest()', () => {
|
||||
it('should return the campaigns from the last year', async() => {
|
||||
let result = await app.models.Campaign.latest();
|
||||
|
||||
const lastYearDate = new Date();
|
||||
lastYearDate.setFullYear(lastYearDate.getFullYear() - 1);
|
||||
const lastYear = lastYearDate.getFullYear();
|
||||
|
||||
const now = new Date();
|
||||
const result = await app.models.Campaign.latest();
|
||||
const randomIndex = Math.floor(Math.random() * result.length);
|
||||
const campaignDated = result[randomIndex].dated;
|
||||
const campaignYear = campaignDated.getFullYear();
|
||||
|
||||
expect(result.length).toEqual(3);
|
||||
expect(campaignYear).toEqual(lastYear);
|
||||
expect(campaignDated).toBeLessThanOrEqual(now);
|
||||
});
|
||||
|
||||
it('should return the campaigns from the current year', async() => {
|
||||
const currentDate = new Date();
|
||||
const currentYear = currentDate.getFullYear();
|
||||
|
||||
const now = new Date();
|
||||
const currentYear = now.getFullYear();
|
||||
const result = await app.models.Campaign.latest({
|
||||
where: {dated: {like: `%${currentYear}%`}}
|
||||
});
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
|
||||
VALUES ('Buy', '*', '*', 'ALLOW', 'ROLE', 'buyer');
|
|
@ -1,2 +0,0 @@
|
|||
ALTER TABLE `vn`.`accountingType`
|
||||
ADD COLUMN `receiptDescription` VARCHAR(50) NULL COMMENT 'Descripción por defecto al crear nuevo recibo' AFTER `description`;
|
|
@ -1,119 +0,0 @@
|
|||
USE `vn`;
|
||||
DROP procedure IF EXISTS `ticket_close`;
|
||||
|
||||
DELIMITER $$
|
||||
USE `vn`$$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `ticket_close`(vTicketFk INT)
|
||||
BEGIN
|
||||
/**
|
||||
* Realiza el cierre de todos los
|
||||
* tickets de la tabla ticketClosure.
|
||||
*
|
||||
* @param vTicketFk Id del ticket
|
||||
*/
|
||||
DECLARE vDone BOOL;
|
||||
DECLARE vClientFk INT;
|
||||
DECLARE vCurTicketFk INT;
|
||||
DECLARE vIsTaxDataChecked BOOL;
|
||||
DECLARE vCompanyFk INT;
|
||||
DECLARE vShipped DATE;
|
||||
DECLARE vNewInvoiceId INT;
|
||||
DECLARE vHasDailyInvoice BOOL;
|
||||
DECLARE vWithPackage BOOL;
|
||||
DECLARE vHasToInvoice BOOL;
|
||||
|
||||
DECLARE cur CURSOR FOR
|
||||
SELECT ticketFk FROM tmp.ticketClosure;
|
||||
|
||||
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
|
||||
DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN
|
||||
RESIGNAL;
|
||||
END;
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp.ticketClosure;
|
||||
CREATE TEMPORARY TABLE tmp.ticketClosure
|
||||
SELECT vTicketFk AS ticketFk;
|
||||
|
||||
INSERT INTO tmp.ticketClosure
|
||||
SELECT id FROM stowaway s
|
||||
WHERE s.shipFk = vTicketFk;
|
||||
OPEN cur;
|
||||
|
||||
proc: LOOP
|
||||
SET vDone = FALSE;
|
||||
|
||||
FETCH cur INTO vCurTicketFk;
|
||||
|
||||
IF vDone THEN
|
||||
LEAVE proc;
|
||||
END IF;
|
||||
|
||||
-- ticketClosure start
|
||||
SELECT
|
||||
c.id,
|
||||
c.isTaxDataChecked,
|
||||
t.companyFk,
|
||||
t.shipped,
|
||||
co.hasDailyInvoice,
|
||||
w.isManaged,
|
||||
c.hasToInvoice
|
||||
INTO vClientFk,
|
||||
vIsTaxDataChecked,
|
||||
vCompanyFk,
|
||||
vShipped,
|
||||
vHasDailyInvoice,
|
||||
vWithPackage,
|
||||
vHasToInvoice
|
||||
FROM ticket t
|
||||
JOIN `client` c ON c.id = t.clientFk
|
||||
JOIN province p ON p.id = c.provinceFk
|
||||
JOIN country co ON co.id = p.countryFk
|
||||
JOIN warehouse w ON w.id = t.warehouseFk
|
||||
WHERE t.id = vCurTicketFk;
|
||||
|
||||
INSERT INTO ticketPackaging (ticketFk, packagingFk, quantity)
|
||||
(SELECT vCurTicketFk, p.id, COUNT(*)
|
||||
FROM expedition e
|
||||
JOIN packaging p ON p.itemFk = e.itemFk
|
||||
WHERE e.ticketFk = vCurTicketFk AND p.isPackageReturnable
|
||||
AND vWithPackage
|
||||
GROUP BY p.itemFk);
|
||||
|
||||
-- No retornables o no catalogados
|
||||
INSERT INTO sale (itemFk, ticketFk, concept, quantity, price, isPriceFixed)
|
||||
(SELECT e.itemFk, vCurTicketFk, i.name, COUNT(*) AS amount, getSpecialPrice(e.itemFk, vClientFk), 1
|
||||
FROM expedition e
|
||||
JOIN item i ON i.id = e.itemFk
|
||||
LEFT JOIN packaging p ON p.itemFk = i.id
|
||||
WHERE e.ticketFk = vCurTicketFk AND IFNULL(p.isPackageReturnable, 0) = 0
|
||||
AND getSpecialPrice(e.itemFk, vClientFk) > 0
|
||||
GROUP BY e.itemFk);
|
||||
|
||||
CALL vn.zonePromo_Make();
|
||||
|
||||
IF(vHasDailyInvoice) AND vHasToInvoice THEN
|
||||
|
||||
-- Facturacion rapida
|
||||
CALL ticketTrackingAdd(vCurTicketFk, 'DELIVERED', NULL);
|
||||
-- Facturar si está contabilizado
|
||||
IF vIsTaxDataChecked THEN
|
||||
CALL invoiceOut_newFromClient(
|
||||
vClientFk,
|
||||
(SELECT invoiceSerial(vClientFk, vCompanyFk, 'M')),
|
||||
vShipped,
|
||||
vCompanyFk,
|
||||
NULL,
|
||||
vNewInvoiceId);
|
||||
END IF;
|
||||
ELSE
|
||||
CALL ticketTrackingAdd(vCurTicketFk, (SELECT vn.getAlert3State(vCurTicketFk)), NULL);
|
||||
END IF;
|
||||
END LOOP;
|
||||
|
||||
CLOSE cur;
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp.ticketClosure;
|
||||
END$$
|
||||
|
||||
DELIMITER ;
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
ALTER TABLE `vn`.`entryLog`
|
||||
ADD COLUMN `changedModel` varchar(45) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||
ADD COLUMN `oldInstance` text CHARACTER SET utf8 COLLATE utf8_unicode_ci,
|
||||
ADD COLUMN `newInstance` text CHARACTER SET utf8 COLLATE utf8_unicode_ci,
|
||||
ADD COLUMN `changedModelId` int(11) DEFAULT NULL,
|
||||
ADD COLUMN `changedModelValue` varchar(45) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL;
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
ALTER TABLE `vn`.`ticketService`
|
||||
DROP FOREIGN KEY `ticketServiceIvaGroup`;
|
||||
ALTER TABLE `vn`.`ticketService`
|
||||
CHANGE COLUMN `taxClassFk` `taxClassFk` TINYINT(3) UNSIGNED NOT NULL DEFAULT 2 ;
|
||||
ALTER TABLE `vn`.`ticketService`
|
||||
ADD CONSTRAINT `ticketServiceIvaGroup`
|
||||
FOREIGN KEY (`taxClassFk`)
|
||||
REFERENCES `vn`.`taxClass` (`id`)
|
||||
ON UPDATE CASCADE;
|
|
@ -1,129 +0,0 @@
|
|||
|
||||
ALTER TABLE `account`.`role`
|
||||
MODIFY COLUMN `hasLogin` tinyint(3) unsigned DEFAULT 1 NOT NULL;
|
||||
|
||||
ALTER TABLE `account`.`roleInherit`
|
||||
ADD UNIQUE( `role`, `inheritsFrom`);
|
||||
|
||||
ALTER TABLE `account`.`roleInherit`
|
||||
DROP PRIMARY KEY;
|
||||
|
||||
ALTER TABLE `account`.`roleInherit`
|
||||
ADD `id` INT UNSIGNED NOT NULL AUTO_INCREMENT FIRST,
|
||||
ADD PRIMARY KEY (`id`);
|
||||
|
||||
ALTER TABLE `account`.`mailAlias`
|
||||
ADD `description` VARCHAR(255) NULL AFTER `alias`;
|
||||
|
||||
ALTER TABLE `account`.`mailAliasAccount`
|
||||
ADD UNIQUE( `mailAlias`, `account`);
|
||||
|
||||
ALTER TABLE `account`.`mailAliasAccount`
|
||||
DROP PRIMARY KEY;
|
||||
|
||||
ALTER TABLE `account`.`mailAliasAccount`
|
||||
ADD `id` INT UNSIGNED NOT NULL AUTO_INCREMENT FIRST,
|
||||
ADD PRIMARY KEY (`id`);
|
||||
|
||||
ALTER TABLE account.ldapConfig
|
||||
ADD groupDn varchar(255) NULL;
|
||||
|
||||
UPDATE account.ldapConfig SET groupDn = 'ou=groups,dc=verdnatura,dc=es';
|
||||
|
||||
DROP PROCEDURE IF EXISTS account.user_syncPassword;
|
||||
|
||||
ALTER TABLE account.`user`
|
||||
MODIFY COLUMN sync tinyint(4) DEFAULT 0 NOT NULL COMMENT 'Deprecated';
|
||||
|
||||
CREATE TABLE account.userSync (
|
||||
name varchar(30) NOT NULL,
|
||||
CONSTRAINT userSync_PK PRIMARY KEY (name)
|
||||
)
|
||||
ENGINE=InnoDB
|
||||
DEFAULT CHARSET=utf8
|
||||
COLLATE=utf8_general_ci;
|
||||
|
||||
USE account;
|
||||
|
||||
DELIMITER $$
|
||||
|
||||
DROP TRIGGER IF EXISTS account.user_beforeUpdate$$
|
||||
CREATE DEFINER=`root`@`%` TRIGGER `user_beforeUpdate`
|
||||
BEFORE UPDATE ON `user` FOR EACH ROW
|
||||
BEGIN
|
||||
IF !(NEW.`name` <=> OLD.`name`) THEN
|
||||
CALL user_checkName (NEW.`name`);
|
||||
END IF;
|
||||
|
||||
IF !(NEW.`password` <=> OLD.`password`) THEN
|
||||
SET NEW.bcryptPassword = NULL;
|
||||
SET NEW.lastPassChange = NOW();
|
||||
END IF;
|
||||
END$$
|
||||
|
||||
DROP TRIGGER IF EXISTS account.user_afterUpdate$$
|
||||
CREATE DEFINER=`root`@`%` TRIGGER `user_afterUpdate`
|
||||
AFTER UPDATE ON `user` FOR EACH ROW
|
||||
BEGIN
|
||||
INSERT IGNORE INTO userSync SET `name` = NEW.`name`;
|
||||
|
||||
IF !(OLD.`name` <=> NEW.`name`) THEN
|
||||
INSERT IGNORE INTO userSync SET `name` = OLD.`name`;
|
||||
END IF;
|
||||
|
||||
IF !(NEW.`role` <=> OLD.`role`)
|
||||
THEN
|
||||
INSERT INTO vn.mail SET
|
||||
`sender` = 'jgallego@verdnatura.es',
|
||||
`replyTo` = 'jgallego@verdnatura.es',
|
||||
`subject` = 'Rol modificado',
|
||||
`body` = CONCAT(myUserGetName(), ' ha modificado el rol del usuario ',
|
||||
NEW.`name`, ' de ', OLD.role, ' a ', NEW.role);
|
||||
END IF;
|
||||
END$$
|
||||
|
||||
CREATE DEFINER=`root`@`%` TRIGGER `user_afterInsert`
|
||||
AFTER INSERT ON `user` FOR EACH ROW
|
||||
BEGIN
|
||||
INSERT IGNORE INTO userSync SET `name` = NEW.`name`;
|
||||
END$$
|
||||
|
||||
CREATE DEFINER=`root`@`%` TRIGGER `user_afterDelete`
|
||||
AFTER DELETE ON `user` FOR EACH ROW
|
||||
BEGIN
|
||||
INSERT IGNORE INTO userSync SET `name` = OLD.`name`;
|
||||
END$$
|
||||
|
||||
DROP TRIGGER IF EXISTS account.account_afterInsert$$
|
||||
CREATE DEFINER=`root`@`%` TRIGGER `account_afterInsert`
|
||||
AFTER INSERT ON `account` FOR EACH ROW
|
||||
BEGIN
|
||||
INSERT IGNORE INTO userSync (`name`)
|
||||
SELECT `name` FROM `user` WHERE id = NEW.id;
|
||||
END$$
|
||||
|
||||
DROP TRIGGER IF EXISTS account.account_afterDelete$$
|
||||
CREATE DEFINER=`root`@`%` TRIGGER `account_afterDelete`
|
||||
AFTER DELETE ON `account` FOR EACH ROW
|
||||
BEGIN
|
||||
INSERT IGNORE INTO userSync (`name`)
|
||||
SELECT `name` FROM `user` WHERE id = OLD.id;
|
||||
END$$
|
||||
|
||||
DROP TRIGGER IF EXISTS account.role_beforeInsert$$
|
||||
CREATE DEFINER=`root`@`%` TRIGGER role_beforeInsert
|
||||
BEFORE INSERT ON `role` FOR EACH ROW
|
||||
BEGIN
|
||||
CALL role_checkName(NEW.`name`);
|
||||
END
|
||||
|
||||
DROP TRIGGER IF EXISTS account.role_beforeUpdate$$
|
||||
CREATE DEFINER=`root`@`%` TRIGGER role_beforeUpdate
|
||||
BEFORE UPDATE ON `role` FOR EACH ROW
|
||||
BEGIN
|
||||
IF !(NEW.`name` <=> OLD.`name`) THEN
|
||||
CALL role_checkName (NEW.`name`);
|
||||
END IF;
|
||||
END$$
|
||||
|
||||
DELIMITER ;
|
|
@ -1,13 +0,0 @@
|
|||
DROP PROCEDURE IF EXISTS account.myUserChangePassword;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `account`.`myUserChangePassword`(vOldPassword VARCHAR(255), vPassword VARCHAR(255))
|
||||
BEGIN
|
||||
/**
|
||||
* @deprecated Use myUser_changePassword()
|
||||
*/
|
||||
CALL myUser_changePassword(vOldPassword, vPassword);
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
GRANT EXECUTE ON PROCEDURE account.myUserChangePassword TO account@localhost;
|
|
@ -1,15 +0,0 @@
|
|||
DROP FUNCTION IF EXISTS account.myUserCheckLogin;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` FUNCTION `account`.`myUserCheckLogin`() RETURNS tinyint(1)
|
||||
READS SQL DATA
|
||||
DETERMINISTIC
|
||||
BEGIN
|
||||
/**
|
||||
* @deprecated Use myUser_checkLogin()
|
||||
*/
|
||||
RETURN myUser_checkLogin();
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION account.myUserCheckLogin TO guest@localhost;
|
|
@ -1,15 +0,0 @@
|
|||
DROP FUNCTION IF EXISTS account.myUserGetId;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` FUNCTION `account`.`myUserGetId`() RETURNS int(11)
|
||||
READS SQL DATA
|
||||
DETERMINISTIC
|
||||
BEGIN
|
||||
/**
|
||||
* @deprecated Use myUser_getId()
|
||||
*/
|
||||
RETURN myUser_getId();
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION account.myUserGetId TO guest@localhost;
|
|
@ -1,15 +0,0 @@
|
|||
DROP FUNCTION IF EXISTS account.myUserGetName;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` FUNCTION `account`.`myUserGetName`() RETURNS varchar(30) CHARSET utf8
|
||||
NO SQL
|
||||
DETERMINISTIC
|
||||
BEGIN
|
||||
/**
|
||||
* @deprecated Use myUser_getName()
|
||||
*/
|
||||
RETURN myUser_getName();
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION account.myUserGetName TO guest@localhost;
|
|
@ -1,14 +0,0 @@
|
|||
DROP FUNCTION IF EXISTS account.myUserHasRole;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` FUNCTION `account`.`myUserHasRole`(vRoleName VARCHAR(255)) RETURNS tinyint(1)
|
||||
DETERMINISTIC
|
||||
BEGIN
|
||||
/**
|
||||
* @deprecated Use myUser_hasRole()
|
||||
*/
|
||||
RETURN myUser_hasRole(vRoleName);
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION account.myUserHasRole TO guest@localhost;
|
|
@ -1,14 +0,0 @@
|
|||
DROP FUNCTION IF EXISTS account.myUserHasRoleId;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` FUNCTION `account`.`myUserHasRoleId`(vRoleId INT) RETURNS tinyint(1)
|
||||
DETERMINISTIC
|
||||
BEGIN
|
||||
/**
|
||||
* @deprecated Use myUser_hasRoleId()
|
||||
*/
|
||||
RETURN myUser_hasRoleId(vRoleId);
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION account.myUserHasRoleId TO guest@localhost;
|
|
@ -1,17 +0,0 @@
|
|||
DROP PROCEDURE IF EXISTS account.myUser_changePassword;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `account`.`myUser_changePassword`(vOldPassword VARCHAR(255), vPassword VARCHAR(255))
|
||||
BEGIN
|
||||
/**
|
||||
* Changes the current user password, if user is in recovery mode ignores the
|
||||
* current password.
|
||||
*
|
||||
* @param vOldPassword The current password
|
||||
* @param vPassword The new password
|
||||
*/
|
||||
CALL user_changePassword(myUser_getId(), vOldPassword, vPassword);
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
GRANT EXECUTE ON PROCEDURE account.myUser_changePassword TO account@localhost;
|
|
@ -1,29 +0,0 @@
|
|||
DROP FUNCTION IF EXISTS account.myUser_checkLogin;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` FUNCTION `account`.`myUser_checkLogin`() RETURNS tinyint(1)
|
||||
READS SQL DATA
|
||||
DETERMINISTIC
|
||||
BEGIN
|
||||
/**
|
||||
* Checks that variables @userId and @userName haven't been altered.
|
||||
*
|
||||
* @return %TRUE if they are unaltered or unset, otherwise %FALSE
|
||||
*/
|
||||
DECLARE vSignature VARCHAR(128);
|
||||
DECLARE vKey VARCHAR(255);
|
||||
|
||||
IF @userId IS NOT NULL
|
||||
AND @userName IS NOT NULL
|
||||
AND @userSignature IS NOT NULL
|
||||
THEN
|
||||
SELECT loginKey INTO vKey FROM userConfig;
|
||||
SET vSignature = util.hmacSha2(256, CONCAT_WS('/', @userId, @userName), vKey);
|
||||
RETURN vSignature = @userSignature;
|
||||
END IF;
|
||||
|
||||
RETURN FALSE;
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION account.myUser_checkLogin TO guest@localhost;
|
|
@ -1,27 +0,0 @@
|
|||
DROP FUNCTION IF EXISTS account.myUser_getId;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` FUNCTION `account`.`myUser_getId`() RETURNS int(11)
|
||||
READS SQL DATA
|
||||
DETERMINISTIC
|
||||
BEGIN
|
||||
/**
|
||||
* Returns the current user id.
|
||||
*
|
||||
* @return The user id
|
||||
*/
|
||||
DECLARE vUser INT DEFAULT NULL;
|
||||
|
||||
IF myUser_checkLogin()
|
||||
THEN
|
||||
SET vUser = @userId;
|
||||
ELSE
|
||||
SELECT id INTO vUser FROM user
|
||||
WHERE name = LEFT(USER(), INSTR(USER(), '@') - 1);
|
||||
END IF;
|
||||
|
||||
RETURN vUser;
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION account.myUser_getId TO guest@localhost;
|
|
@ -1,27 +0,0 @@
|
|||
DROP FUNCTION IF EXISTS account.myUser_getName;
|
||||
|
||||
DELIMITER $$
|
||||
$$
|
||||
CREATE DEFINER=`root`@`%` FUNCTION `account`.`myUser_getName`() RETURNS varchar(30) CHARSET utf8
|
||||
NO SQL
|
||||
DETERMINISTIC
|
||||
BEGIN
|
||||
/**
|
||||
* Returns the current user name.
|
||||
*
|
||||
* @return The user name
|
||||
*/
|
||||
DECLARE vUser VARCHAR(30) DEFAULT NULL;
|
||||
|
||||
IF myUser_checkLogin()
|
||||
THEN
|
||||
SET vUser = @userName;
|
||||
ELSE
|
||||
SET vUser = LEFT(USER(), INSTR(USER(), '@') - 1);
|
||||
END IF;
|
||||
|
||||
RETURN vUser;
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION account.myUser_getName TO guest@localhost;
|
|
@ -1,17 +0,0 @@
|
|||
DROP FUNCTION IF EXISTS account.myUser_hasRole;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` FUNCTION `account`.`myUser_hasRole`(vRoleName VARCHAR(255)) RETURNS tinyint(1)
|
||||
DETERMINISTIC
|
||||
BEGIN
|
||||
/**
|
||||
* Checks if current user has/inherits a role.
|
||||
*
|
||||
* @param vRoleName Role to check
|
||||
* @return %TRUE if it has role, %FALSE otherwise
|
||||
*/
|
||||
RETURN user_hasRole(myUser_getName(), vRoleName);
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION account.myUser_hasRole TO guest@localhost;
|
|
@ -1,17 +0,0 @@
|
|||
DROP FUNCTION IF EXISTS account.myUser_hasRoleId;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` FUNCTION `account`.`myUser_hasRoleId`(vRoleId INT) RETURNS tinyint(1)
|
||||
DETERMINISTIC
|
||||
BEGIN
|
||||
/**
|
||||
* Checks if current user has/inherits a role.
|
||||
*
|
||||
* @param vRoleName Role id to check
|
||||
* @return %TRUE if it has role, %FALSE otherwise
|
||||
*/
|
||||
RETURN user_hasRoleId(myUserGetName(), vRoleId);
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION account.myUser_hasRoleId TO guest@localhost;
|
|
@ -1,29 +0,0 @@
|
|||
DROP PROCEDURE IF EXISTS account.myUser_login;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `account`.`myUser_login`(vUserName VARCHAR(255), vPassword VARCHAR(255))
|
||||
READS SQL DATA
|
||||
BEGIN
|
||||
/**
|
||||
* Logs in using the user credentials.
|
||||
*
|
||||
* @param vUserName The user name
|
||||
* @param vPassword The user password
|
||||
*/
|
||||
DECLARE vAuthIsOk BOOLEAN DEFAULT FALSE;
|
||||
|
||||
SELECT COUNT(*) = 1 INTO vAuthIsOk FROM user
|
||||
WHERE name = vUserName
|
||||
AND password = MD5(vPassword)
|
||||
AND active;
|
||||
|
||||
IF vAuthIsOk
|
||||
THEN
|
||||
CALL myUser_loginWithName (vUserName);
|
||||
ELSE
|
||||
CALL util.throw ('INVALID_CREDENTIALS');
|
||||
END IF;
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
GRANT EXECUTE ON PROCEDURE account.myUser_login TO guest@localhost;
|
|
@ -1,25 +0,0 @@
|
|||
DROP PROCEDURE IF EXISTS account.myUser_loginWithKey;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `account`.`myUser_loginWithKey`(vUserName VARCHAR(255), vKey VARCHAR(255))
|
||||
READS SQL DATA
|
||||
BEGIN
|
||||
/**
|
||||
* Logs in using the user name and MySQL master key.
|
||||
*
|
||||
* @param vUserName The user name
|
||||
* @param vKey The MySQL master key
|
||||
*/
|
||||
DECLARE vLoginKey VARCHAR(255);
|
||||
|
||||
SELECT loginKey INTO vLoginKey FROM userConfig;
|
||||
|
||||
IF vLoginKey = vKey THEN
|
||||
CALL myUser_loginWithName(vUserName);
|
||||
ELSE
|
||||
CALL util.throw('INVALID_KEY');
|
||||
END IF;
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
GRANT EXECUTE ON PROCEDURE account.myUser_loginWithKey TO guest@localhost;
|
|
@ -1,26 +0,0 @@
|
|||
DROP PROCEDURE IF EXISTS account.myUser_loginWithName;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `account`.`myUser_loginWithName`(vUserName VARCHAR(255))
|
||||
READS SQL DATA
|
||||
BEGIN
|
||||
/**
|
||||
* Logs in using only the user name. This procedure is intended to be executed
|
||||
* by users with a high level of privileges so that normal users should not have
|
||||
* execute permissions on it.
|
||||
*
|
||||
* @param vUserName The user name
|
||||
*/
|
||||
DECLARE vUserId INT DEFAULT NULL;
|
||||
DECLARE vKey VARCHAR(255);
|
||||
|
||||
SELECT id INTO vUserId FROM user
|
||||
WHERE name = vUserName;
|
||||
|
||||
SELECT loginKey INTO vKey FROM userConfig;
|
||||
|
||||
SET @userId = vUserId;
|
||||
SET @userName = vUserName;
|
||||
SET @userSignature = util.hmacSha2(256, CONCAT_WS('/', vUserId, vUserName), vKey);
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -1,15 +0,0 @@
|
|||
DROP PROCEDURE IF EXISTS account.myUser_logout;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `account`.`myUser_logout`()
|
||||
BEGIN
|
||||
/**
|
||||
* Logouts the user.
|
||||
*/
|
||||
SET @userId = NULL;
|
||||
SET @userName = NULL;
|
||||
SET @userSignature = NULL;
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
GRANT EXECUTE ON PROCEDURE account.myUser_logout TO account@localhost;
|
|
@ -1,52 +0,0 @@
|
|||
DROP FUNCTION IF EXISTS account.passwordGenerate;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` FUNCTION `account`.`passwordGenerate`() RETURNS text CHARSET utf8
|
||||
BEGIN
|
||||
/**
|
||||
* Generates a random password that meets the minimum requirements.
|
||||
*
|
||||
* @return Generated password
|
||||
*/
|
||||
DECLARE vMinLength TINYINT;
|
||||
DECLARE vMinAlpha TINYINT;
|
||||
DECLARE vMinUpper TINYINT;
|
||||
DECLARE vMinDigits TINYINT;
|
||||
DECLARE vMinPunct TINYINT;
|
||||
DECLARE vAlpha TINYINT DEFAULT 0;
|
||||
DECLARE vUpper TINYINT DEFAULT 0;
|
||||
DECLARE vDigits TINYINT DEFAULT 0;
|
||||
DECLARE vPunct TINYINT DEFAULT 0;
|
||||
DECLARE vRandIndex INT;
|
||||
DECLARE vPwd TEXT DEFAULT '';
|
||||
|
||||
DECLARE vAlphaChars TEXT DEFAULT 'abcdefghijklmnopqrstuvwxyz';
|
||||
DECLARE vUpperChars TEXT DEFAULT 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
DECLARE vDigitChars TEXT DEFAULT '1234567890';
|
||||
DECLARE vPunctChars TEXT DEFAULT '!$%&()=.';
|
||||
|
||||
SELECT length, nAlpha, nUpper, nDigits, nPunct
|
||||
INTO vMinLength, vMinAlpha, vMinUpper, vMinDigits, vMinPunct FROM userPassword;
|
||||
|
||||
WHILE LENGTH(vPwd) < vMinLength OR vAlpha < vMinAlpha
|
||||
OR vUpper < vMinUpper OR vDigits < vMinDigits OR vPunct < vMinPunct DO
|
||||
SET vRandIndex = FLOOR((RAND() * 4) + 1);
|
||||
|
||||
CASE
|
||||
WHEN vRandIndex = 1 THEN
|
||||
SET vPwd = CONCAT(vPwd, SUBSTRING(vAlphaChars, FLOOR((RAND() * 26) + 1), 1));
|
||||
SET vAlpha = vAlpha + 1;
|
||||
WHEN vRandIndex = 2 THEN
|
||||
SET vPwd = CONCAT(vPwd, SUBSTRING(vUpperChars, FLOOR((RAND() * 26) + 1), 1));
|
||||
SET vUpper = vUpper + 1;
|
||||
WHEN vRandIndex = 3 THEN
|
||||
SET vPwd = CONCAT(vPwd, SUBSTRING(vDigitChars, FLOOR((RAND() * 10) + 1), 1));
|
||||
SET vDigits = vDigits + 1;
|
||||
WHEN vRandIndex = 4 THEN
|
||||
SET vPwd = CONCAT(vPwd, SUBSTRING(vPunctChars, FLOOR((RAND() * LENGTH(vPunctChars)) + 1), 1));
|
||||
SET vPunct = vPunct + 1;
|
||||
END CASE;
|
||||
END WHILE;
|
||||
RETURN vPwd;
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -1,18 +0,0 @@
|
|||
DROP PROCEDURE IF EXISTS account.role_checkName;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE account.role_checkName(vRoleName VARCHAR(255))
|
||||
BEGIN
|
||||
/**
|
||||
* Checks that role name meets the necessary syntax requirements, otherwise it
|
||||
* throws an exception.
|
||||
* Role name must be written in camelCase.
|
||||
*
|
||||
* @param vRoleName The role name
|
||||
*/
|
||||
IF BINARY vRoleName NOT REGEXP '^[a-z][a-zA-Z]+$' THEN
|
||||
SIGNAL SQLSTATE '45000'
|
||||
SET MESSAGE_TEXT = 'Role name must be written in camelCase';
|
||||
END IF;
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -1,66 +0,0 @@
|
|||
DROP PROCEDURE IF EXISTS account.role_getDescendents;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `account`.`role_getDescendents`(vSelf INT)
|
||||
BEGIN
|
||||
/**
|
||||
* Gets the identifiers of all the subroles implemented by a role (Including
|
||||
* itself).
|
||||
*
|
||||
* @param vSelf The role identifier
|
||||
* @table tmp.role Subroles implemented by the role
|
||||
*/
|
||||
DECLARE vIsRoot BOOL;
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS
|
||||
tmp.role, parents, childs;
|
||||
|
||||
CREATE TEMPORARY TABLE tmp.role
|
||||
(UNIQUE (id))
|
||||
ENGINE = MEMORY
|
||||
SELECT vSelf AS id;
|
||||
|
||||
CREATE TEMPORARY TABLE parents
|
||||
ENGINE = MEMORY
|
||||
SELECT vSelf AS id;
|
||||
|
||||
CREATE TEMPORARY TABLE childs
|
||||
LIKE parents;
|
||||
|
||||
REPEAT
|
||||
DELETE FROM childs;
|
||||
INSERT INTO childs
|
||||
SELECT DISTINCT r.inheritsFrom id
|
||||
FROM parents p
|
||||
JOIN roleInherit r ON r.role = p.id
|
||||
LEFT JOIN tmp.role t ON t.id = r.inheritsFrom
|
||||
WHERE t.id IS NULL;
|
||||
|
||||
DELETE FROM parents;
|
||||
INSERT INTO parents
|
||||
SELECT * FROM childs;
|
||||
|
||||
INSERT INTO tmp.role
|
||||
SELECT * FROM childs;
|
||||
|
||||
UNTIL ROW_COUNT() <= 0
|
||||
END REPEAT;
|
||||
|
||||
-- If it is root all the roles are added
|
||||
|
||||
SELECT COUNT(*) > 0 INTO vIsRoot
|
||||
FROM tmp.role t
|
||||
JOIN role r ON r.id = t.id
|
||||
WHERE r.`name` = 'root';
|
||||
|
||||
IF vIsRoot THEN
|
||||
INSERT IGNORE INTO tmp.role (id)
|
||||
SELECT id FROM role;
|
||||
END IF;
|
||||
|
||||
-- Cleaning
|
||||
|
||||
DROP TEMPORARY TABLE
|
||||
parents, childs;
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -1,53 +0,0 @@
|
|||
DROP PROCEDURE IF EXISTS account.role_sync;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `account`.`role_sync`()
|
||||
BEGIN
|
||||
/**
|
||||
* Synchronize the @roleRole table with the current role hierarchy. This
|
||||
* procedure must be called every time the @roleInherit table is modified so
|
||||
* that the changes made on it are effective.
|
||||
*/
|
||||
DECLARE vRoleId INT;
|
||||
DECLARE vDone BOOL;
|
||||
|
||||
DECLARE cur CURSOR FOR
|
||||
SELECT id FROM role;
|
||||
|
||||
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tRoleRole;
|
||||
CREATE TEMPORARY TABLE tRoleRole
|
||||
ENGINE = MEMORY
|
||||
SELECT * FROM roleRole LIMIT 0;
|
||||
|
||||
OPEN cur;
|
||||
|
||||
l: LOOP
|
||||
SET vDone = FALSE;
|
||||
FETCH cur INTO vRoleId;
|
||||
|
||||
IF vDone THEN
|
||||
LEAVE l;
|
||||
END IF;
|
||||
|
||||
CALL role_getDescendents(vRoleId);
|
||||
|
||||
INSERT INTO tRoleRole (role, inheritsFrom)
|
||||
SELECT vRoleId, id FROM tmp.role;
|
||||
|
||||
DROP TEMPORARY TABLE tmp.role;
|
||||
END LOOP;
|
||||
|
||||
CLOSE cur;
|
||||
|
||||
START TRANSACTION;
|
||||
DELETE FROM roleRole;
|
||||
INSERT INTO roleRole SELECT * FROM tRoleRole;
|
||||
COMMIT;
|
||||
|
||||
DROP TEMPORARY TABLE tRoleRole;
|
||||
|
||||
CALL role_syncPrivileges;
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -1,499 +0,0 @@
|
|||
DROP PROCEDURE IF EXISTS account.role_syncPrivileges;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `account`.`role_syncPrivileges`()
|
||||
BEGIN
|
||||
/**
|
||||
* Synchronizes permissions of MySQL role users based on role hierarchy.
|
||||
* The computed role users of permission mix will be named according to
|
||||
* pattern z-[role_name].
|
||||
*
|
||||
* If any@localhost user exists, it will be taken as a template for basic
|
||||
* attributes.
|
||||
*
|
||||
* Warning! This procedure should only be called when MySQL privileges
|
||||
* are modified. If role hierarchy is modified, you must call the role_sync()
|
||||
* procedure wich calls this internally.
|
||||
*/
|
||||
DECLARE vIsMysql BOOL DEFAULT VERSION() NOT LIKE '%MariaDB%';
|
||||
DECLARE vVersion INT DEFAULT SUBSTRING_INDEX(VERSION(), '.', 1);
|
||||
DECLARE vTplUser VARCHAR(255) DEFAULT 'any';
|
||||
DECLARE vTplHost VARCHAR(255) DEFAULT '%';
|
||||
DECLARE vRoleHost VARCHAR(255) DEFAULT 'localhost';
|
||||
DECLARE vAllHost VARCHAR(255) DEFAULT '%';
|
||||
DECLARE vPrefix VARCHAR(2) DEFAULT 'z-';
|
||||
DECLARE vPrefixedLike VARCHAR(255);
|
||||
DECLARE vPassword VARCHAR(255) DEFAULT '';
|
||||
|
||||
-- Deletes computed role users
|
||||
|
||||
SET vPrefixedLike = CONCAT(vPrefix, '%');
|
||||
|
||||
DELETE FROM mysql.user
|
||||
WHERE `User` LIKE vPrefixedLike;
|
||||
|
||||
DELETE FROM mysql.db
|
||||
WHERE `User` LIKE vPrefixedLike;
|
||||
|
||||
DELETE FROM mysql.tables_priv
|
||||
WHERE `User` LIKE vPrefixedLike;
|
||||
|
||||
DELETE FROM mysql.columns_priv
|
||||
WHERE `User` LIKE vPrefixedLike;
|
||||
|
||||
DELETE FROM mysql.procs_priv
|
||||
WHERE `User` LIKE vPrefixedLike;
|
||||
|
||||
DELETE FROM mysql.proxies_priv
|
||||
WHERE `Proxied_user` LIKE vPrefixedLike;
|
||||
|
||||
-- Temporary tables
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tRole;
|
||||
CREATE TEMPORARY TABLE tRole
|
||||
(INDEX (id))
|
||||
ENGINE = MEMORY
|
||||
SELECT
|
||||
id,
|
||||
`name` role,
|
||||
CONCAT(vPrefix, `name`) prefixedRole
|
||||
FROM role
|
||||
WHERE hasLogin;
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tRoleInherit;
|
||||
CREATE TEMPORARY TABLE tRoleInherit
|
||||
(INDEX (inheritsFrom))
|
||||
ENGINE = MEMORY
|
||||
SELECT
|
||||
r.prefixedRole,
|
||||
ri.`name` inheritsFrom
|
||||
FROM tRole r
|
||||
JOIN roleRole rr ON rr.role = r.id
|
||||
JOIN role ri ON ri.id = rr.inheritsFrom;
|
||||
|
||||
-- Recreate role users
|
||||
|
||||
IF vIsMysql THEN
|
||||
DROP TEMPORARY TABLE IF EXISTS tUser;
|
||||
CREATE TEMPORARY TABLE tUser
|
||||
SELECT
|
||||
r.prefixedRole `User`,
|
||||
vTplHost `Host`,
|
||||
IFNULL(t.`authentication_string`,
|
||||
'') `authentication_string`,
|
||||
IFNULL(t.`plugin`,
|
||||
'mysql_native_password') `plugin`,
|
||||
IFNULL(IF('' != u.`ssl_type`,
|
||||
u.`ssl_type`, t.`ssl_type`),
|
||||
'') `ssl_type`,
|
||||
IFNULL(IF('' != u.`ssl_cipher`,
|
||||
u.`ssl_cipher`, t.`ssl_cipher`),
|
||||
'') `ssl_cipher`,
|
||||
IFNULL(IF('' != u.`x509_issuer`,
|
||||
u.`x509_issuer`, t.`x509_issuer`),
|
||||
'') `x509_issuer`,
|
||||
IFNULL(IF('' != u.`x509_subject`,
|
||||
u.`x509_subject`, t.`x509_subject`),
|
||||
'') `x509_subject`,
|
||||
IFNULL(IF(0 != u.`max_questions`,
|
||||
u.`max_questions`, t.`max_questions`),
|
||||
0) `max_questions`,
|
||||
IFNULL(IF(0 != u.`max_updates`,
|
||||
u.`max_updates`, t.`max_updates`),
|
||||
0) `max_updates`,
|
||||
IFNULL(IF(0 != u.`max_connections`,
|
||||
u.`max_connections`, t.`max_connections`),
|
||||
0) `max_connections`,
|
||||
IFNULL(IF(0 != u.`max_user_connections`,
|
||||
u.`max_user_connections`, t.`max_user_connections`),
|
||||
0) `max_user_connections`
|
||||
FROM tRole r
|
||||
LEFT JOIN mysql.user t
|
||||
ON t.`User` = vTplUser
|
||||
AND t.`Host` = vRoleHost
|
||||
LEFT JOIN mysql.user u
|
||||
ON u.`User` = r.role
|
||||
AND u.`Host` = vRoleHost;
|
||||
|
||||
IF vVersion <= 5 THEN
|
||||
SELECT `Password` INTO vPassword
|
||||
FROM mysql.user
|
||||
WHERE `User` = vTplUser
|
||||
AND `Host` = vRoleHost;
|
||||
|
||||
INSERT INTO mysql.user (
|
||||
`User`,
|
||||
`Host`,
|
||||
`Password`,
|
||||
`authentication_string`,
|
||||
`plugin`,
|
||||
`ssl_type`,
|
||||
`ssl_cipher`,
|
||||
`x509_issuer`,
|
||||
`x509_subject`,
|
||||
`max_questions`,
|
||||
`max_updates`,
|
||||
`max_connections`,
|
||||
`max_user_connections`
|
||||
)
|
||||
SELECT
|
||||
`User`,
|
||||
`Host`,
|
||||
vPassword,
|
||||
`authentication_string`,
|
||||
`plugin`,
|
||||
`ssl_type`,
|
||||
`ssl_cipher`,
|
||||
`x509_issuer`,
|
||||
`x509_subject`,
|
||||
`max_questions`,
|
||||
`max_updates`,
|
||||
`max_connections`,
|
||||
`max_user_connections`
|
||||
FROM tUser;
|
||||
ELSE
|
||||
INSERT INTO mysql.user (
|
||||
`User`,
|
||||
`Host`,
|
||||
`authentication_string`,
|
||||
`plugin`,
|
||||
`ssl_type`,
|
||||
`ssl_cipher`,
|
||||
`x509_issuer`,
|
||||
`x509_subject`,
|
||||
`max_questions`,
|
||||
`max_updates`,
|
||||
`max_connections`,
|
||||
`max_user_connections`
|
||||
)
|
||||
SELECT
|
||||
`User`,
|
||||
`Host`,
|
||||
`authentication_string`,
|
||||
`plugin`,
|
||||
`ssl_type`,
|
||||
`ssl_cipher`,
|
||||
`x509_issuer`,
|
||||
`x509_subject`,
|
||||
`max_questions`,
|
||||
`max_updates`,
|
||||
`max_connections`,
|
||||
`max_user_connections`
|
||||
FROM tUser;
|
||||
END IF;
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tUser;
|
||||
ELSE
|
||||
INSERT INTO mysql.global_priv (
|
||||
`User`,
|
||||
`Host`,
|
||||
`Priv`
|
||||
)
|
||||
SELECT
|
||||
r.prefixedRole,
|
||||
vTplHost,
|
||||
JSON_MERGE_PATCH(
|
||||
IFNULL(t.`Priv`, '{}'),
|
||||
IFNULL(u.`Priv`, '{}'),
|
||||
JSON_OBJECT(
|
||||
'mysql_old_password', JSON_VALUE(t.`Priv`, '$.mysql_old_password'),
|
||||
'mysql_native_password', JSON_VALUE(t.`Priv`, '$.mysql_native_password'),
|
||||
'authentication_string', JSON_VALUE(t.`Priv`, '$.authentication_string')
|
||||
)
|
||||
)
|
||||
FROM tRole r
|
||||
LEFT JOIN mysql.global_priv t
|
||||
ON t.`User` = vTplUser
|
||||
AND t.`Host` = vRoleHost
|
||||
LEFT JOIN mysql.global_priv u
|
||||
ON u.`User` = r.role
|
||||
AND u.`Host` = vRoleHost;
|
||||
END IF;
|
||||
|
||||
INSERT INTO mysql.proxies_priv (
|
||||
`User`,
|
||||
`Host`,
|
||||
`Proxied_user`,
|
||||
`Proxied_host`,
|
||||
`Grantor`
|
||||
)
|
||||
SELECT
|
||||
'',
|
||||
vAllHost,
|
||||
prefixedRole,
|
||||
vTplHost,
|
||||
CONCAT(prefixedRole, '@', vTplHost)
|
||||
FROM tRole;
|
||||
|
||||
-- Copies global privileges
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tUserPriv;
|
||||
|
||||
IF vIsMysql THEN
|
||||
CREATE TEMPORARY TABLE tUserPriv
|
||||
(INDEX (prefixedRole))
|
||||
ENGINE = MEMORY
|
||||
SELECT
|
||||
r.prefixedRole,
|
||||
MAX(u.`Select_priv`) `Select_priv`,
|
||||
MAX(u.`Insert_priv`) `Insert_priv`,
|
||||
MAX(u.`Update_priv`) `Update_priv`,
|
||||
MAX(u.`Delete_priv`) `Delete_priv`,
|
||||
MAX(u.`Create_priv`) `Create_priv`,
|
||||
MAX(u.`Drop_priv`) `Drop_priv`,
|
||||
MAX(u.`Reload_priv`) `Reload_priv`,
|
||||
MAX(u.`Shutdown_priv`) `Shutdown_priv`,
|
||||
MAX(u.`Process_priv`) `Process_priv`,
|
||||
MAX(u.`File_priv`) `File_priv`,
|
||||
MAX(u.`Grant_priv`) `Grant_priv`,
|
||||
MAX(u.`References_priv`) `References_priv`,
|
||||
MAX(u.`Index_priv`) `Index_priv`,
|
||||
MAX(u.`Alter_priv`) `Alter_priv`,
|
||||
MAX(u.`Show_db_priv`) `Show_db_priv`,
|
||||
MAX(u.`Super_priv`) `Super_priv`,
|
||||
MAX(u.`Create_tmp_table_priv`) `Create_tmp_table_priv`,
|
||||
MAX(u.`Lock_tables_priv`) `Lock_tables_priv`,
|
||||
MAX(u.`Execute_priv`) `Execute_priv`,
|
||||
MAX(u.`Repl_slave_priv`) `Repl_slave_priv`,
|
||||
MAX(u.`Repl_client_priv`) `Repl_client_priv`,
|
||||
MAX(u.`Create_view_priv`) `Create_view_priv`,
|
||||
MAX(u.`Show_view_priv`) `Show_view_priv`,
|
||||
MAX(u.`Create_routine_priv`) `Create_routine_priv`,
|
||||
MAX(u.`Alter_routine_priv`) `Alter_routine_priv`,
|
||||
MAX(u.`Create_user_priv`) `Create_user_priv`,
|
||||
MAX(u.`Event_priv`) `Event_priv`,
|
||||
MAX(u.`Trigger_priv`) `Trigger_priv`,
|
||||
MAX(u.`Create_tablespace_priv`) `Create_tablespace_priv`
|
||||
FROM tRoleInherit r
|
||||
JOIN mysql.user u
|
||||
ON u.`User` = r.inheritsFrom
|
||||
AND u.`Host`= vRoleHost
|
||||
GROUP BY r.prefixedRole;
|
||||
|
||||
UPDATE mysql.user u
|
||||
JOIN tUserPriv t
|
||||
ON u.`User` = t.prefixedRole
|
||||
AND u.`Host` = vTplHost
|
||||
SET
|
||||
u.`Select_priv`
|
||||
= t.`Select_priv`,
|
||||
u.`Insert_priv`
|
||||
= t.`Insert_priv`,
|
||||
u.`Update_priv`
|
||||
= t.`Update_priv`,
|
||||
u.`Delete_priv`
|
||||
= t.`Delete_priv`,
|
||||
u.`Create_priv`
|
||||
= t.`Create_priv`,
|
||||
u.`Drop_priv`
|
||||
= t.`Drop_priv`,
|
||||
u.`Reload_priv`
|
||||
= t.`Reload_priv`,
|
||||
u.`Shutdown_priv`
|
||||
= t.`Shutdown_priv`,
|
||||
u.`Process_priv`
|
||||
= t.`Process_priv`,
|
||||
u.`File_priv`
|
||||
= t.`File_priv`,
|
||||
u.`Grant_priv`
|
||||
= t.`Grant_priv`,
|
||||
u.`References_priv`
|
||||
= t.`References_priv`,
|
||||
u.`Index_priv`
|
||||
= t.`Index_priv`,
|
||||
u.`Alter_priv`
|
||||
= t.`Alter_priv`,
|
||||
u.`Show_db_priv`
|
||||
= t.`Show_db_priv`,
|
||||
u.`Super_priv`
|
||||
= t.`Super_priv`,
|
||||
u.`Create_tmp_table_priv`
|
||||
= t.`Create_tmp_table_priv`,
|
||||
u.`Lock_tables_priv`
|
||||
= t.`Lock_tables_priv`,
|
||||
u.`Execute_priv`
|
||||
= t.`Execute_priv`,
|
||||
u.`Repl_slave_priv`
|
||||
= t.`Repl_slave_priv`,
|
||||
u.`Repl_client_priv`
|
||||
= t.`Repl_client_priv`,
|
||||
u.`Create_view_priv`
|
||||
= t.`Create_view_priv`,
|
||||
u.`Show_view_priv`
|
||||
= t.`Show_view_priv`,
|
||||
u.`Create_routine_priv`
|
||||
= t.`Create_routine_priv`,
|
||||
u.`Alter_routine_priv`
|
||||
= t.`Alter_routine_priv`,
|
||||
u.`Create_user_priv`
|
||||
= t.`Create_user_priv`,
|
||||
u.`Event_priv`
|
||||
= t.`Event_priv`,
|
||||
u.`Trigger_priv`
|
||||
= t.`Trigger_priv`,
|
||||
u.`Create_tablespace_priv`
|
||||
= t.`Create_tablespace_priv`;
|
||||
ELSE
|
||||
CREATE TEMPORARY TABLE tUserPriv
|
||||
(INDEX (prefixedRole))
|
||||
SELECT
|
||||
r.prefixedRole,
|
||||
BIT_OR(JSON_VALUE(p.`Priv`, '$.access')) access
|
||||
FROM tRoleInherit r
|
||||
JOIN mysql.global_priv p
|
||||
ON p.`User` = r.inheritsFrom
|
||||
AND p.`Host`= vRoleHost
|
||||
GROUP BY r.prefixedRole;
|
||||
|
||||
UPDATE mysql.global_priv p
|
||||
JOIN tUserPriv t
|
||||
ON p.`User` = t.prefixedRole
|
||||
AND p.`Host` = vTplHost
|
||||
SET
|
||||
p.`Priv` = JSON_SET(p.`Priv`, '$.access', t.access);
|
||||
END IF;
|
||||
|
||||
DROP TEMPORARY TABLE tUserPriv;
|
||||
|
||||
-- Copy schema level privileges
|
||||
|
||||
INSERT INTO mysql.db (
|
||||
`User`,
|
||||
`Host`,
|
||||
`Db`,
|
||||
`Select_priv`,
|
||||
`Insert_priv`,
|
||||
`Update_priv`,
|
||||
`Delete_priv`,
|
||||
`Create_priv`,
|
||||
`Drop_priv`,
|
||||
`Grant_priv`,
|
||||
`References_priv`,
|
||||
`Index_priv`,
|
||||
`Alter_priv`,
|
||||
`Create_tmp_table_priv`,
|
||||
`Lock_tables_priv`,
|
||||
`Create_view_priv`,
|
||||
`Show_view_priv`,
|
||||
`Create_routine_priv`,
|
||||
`Alter_routine_priv`,
|
||||
`Execute_priv`,
|
||||
`Event_priv`,
|
||||
`Trigger_priv`
|
||||
)
|
||||
SELECT
|
||||
r.prefixedRole,
|
||||
vTplHost,
|
||||
t.`Db`,
|
||||
MAX(t.`Select_priv`),
|
||||
MAX(t.`Insert_priv`),
|
||||
MAX(t.`Update_priv`),
|
||||
MAX(t.`Delete_priv`),
|
||||
MAX(t.`Create_priv`),
|
||||
MAX(t.`Drop_priv`),
|
||||
MAX(t.`Grant_priv`),
|
||||
MAX(t.`References_priv`),
|
||||
MAX(t.`Index_priv`),
|
||||
MAX(t.`Alter_priv`),
|
||||
MAX(t.`Create_tmp_table_priv`),
|
||||
MAX(t.`Lock_tables_priv`),
|
||||
MAX(t.`Create_view_priv`),
|
||||
MAX(t.`Show_view_priv`),
|
||||
MAX(t.`Create_routine_priv`),
|
||||
MAX(t.`Alter_routine_priv`),
|
||||
MAX(t.`Execute_priv`),
|
||||
MAX(t.`Event_priv`),
|
||||
MAX(t.`Trigger_priv`)
|
||||
FROM tRoleInherit r
|
||||
JOIN mysql.db t
|
||||
ON t.`User` = r.inheritsFrom
|
||||
AND t.`Host`= vRoleHost
|
||||
GROUP BY r.prefixedRole, t.`Db`;
|
||||
|
||||
-- Copy table level privileges
|
||||
|
||||
INSERT INTO mysql.tables_priv (
|
||||
`User`,
|
||||
`Host`,
|
||||
`Db`,
|
||||
`Table_name`,
|
||||
`Grantor`,
|
||||
`Timestamp`,
|
||||
`Table_priv`,
|
||||
`Column_priv`
|
||||
)
|
||||
SELECT
|
||||
r.prefixedRole,
|
||||
vTplHost,
|
||||
t.`Db`,
|
||||
t.`Table_name`,
|
||||
t.`Grantor`,
|
||||
MAX(t.`Timestamp`),
|
||||
IFNULL(GROUP_CONCAT(NULLIF(t.`Table_priv`, '')), ''),
|
||||
IFNULL(GROUP_CONCAT(NULLIF(t.`Column_priv`, '')), '')
|
||||
FROM tRoleInherit r
|
||||
JOIN mysql.tables_priv t
|
||||
ON t.`User` = r.inheritsFrom
|
||||
AND t.`Host`= vRoleHost
|
||||
GROUP BY r.prefixedRole, t.`Db`, t.`Table_name`;
|
||||
|
||||
-- Copy column level privileges
|
||||
|
||||
INSERT INTO mysql.columns_priv (
|
||||
`User`,
|
||||
`Host`,
|
||||
`Db`,
|
||||
`Table_name`,
|
||||
`Column_name`,
|
||||
`Timestamp`,
|
||||
`Column_priv`
|
||||
)
|
||||
SELECT
|
||||
r.prefixedRole,
|
||||
vTplHost,
|
||||
t.`Db`,
|
||||
t.`Table_name`,
|
||||
t.`Column_name`,
|
||||
MAX(t.`Timestamp`),
|
||||
IFNULL(GROUP_CONCAT(NULLIF(t.`Column_priv`, '')), '')
|
||||
FROM tRoleInherit r
|
||||
JOIN mysql.columns_priv t
|
||||
ON t.`User` = r.inheritsFrom
|
||||
AND t.`Host`= vRoleHost
|
||||
GROUP BY r.prefixedRole, t.`Db`, t.`Table_name`, t.`Column_name`;
|
||||
|
||||
-- Copy routine privileges
|
||||
|
||||
INSERT IGNORE INTO mysql.procs_priv (
|
||||
`User`,
|
||||
`Host`,
|
||||
`Db`,
|
||||
`Routine_name`,
|
||||
`Routine_type`,
|
||||
`Grantor`,
|
||||
`Timestamp`,
|
||||
`Proc_priv`
|
||||
)
|
||||
SELECT
|
||||
r.prefixedRole,
|
||||
vTplHost,
|
||||
t.`Db`,
|
||||
t.`Routine_name`,
|
||||
t.`Routine_type`,
|
||||
t.`Grantor`,
|
||||
t.`Timestamp`,
|
||||
t.`Proc_priv`
|
||||
FROM tRoleInherit r
|
||||
JOIN mysql.procs_priv t
|
||||
ON t.`User` = r.inheritsFrom
|
||||
AND t.`Host`= vRoleHost;
|
||||
|
||||
-- Free memory
|
||||
|
||||
DROP TEMPORARY TABLE
|
||||
tRole,
|
||||
tRoleInherit;
|
||||
|
||||
FLUSH PRIVILEGES;
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -1,15 +0,0 @@
|
|||
DROP FUNCTION IF EXISTS account.userGetId;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` FUNCTION `account`.`userGetId`() RETURNS int(11)
|
||||
READS SQL DATA
|
||||
DETERMINISTIC
|
||||
BEGIN
|
||||
/**
|
||||
* @deprecated Use myUser_getId()
|
||||
*/
|
||||
RETURN myUser_getId();
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION account.userGetId TO guest@localhost;
|
|
@ -1,11 +0,0 @@
|
|||
DROP FUNCTION IF EXISTS account.userGetMysqlRole;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` FUNCTION `account`.`userGetMysqlRole`(vUserName VARCHAR(255)) RETURNS varchar(255) CHARSET utf8
|
||||
BEGIN
|
||||
/**
|
||||
* @deprecated Use user_getMysqlRole()
|
||||
*/
|
||||
RETURN user_getMysqlRole();
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -1,15 +0,0 @@
|
|||
DROP FUNCTION IF EXISTS account.userGetName;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` FUNCTION `account`.`userGetName`() RETURNS varchar(30) CHARSET utf8
|
||||
NO SQL
|
||||
DETERMINISTIC
|
||||
BEGIN
|
||||
/**
|
||||
* @deprecated Use myUser_getName()
|
||||
*/
|
||||
RETURN myUser_getName();
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION account.userGetName TO guest@localhost;
|
|
@ -1,11 +0,0 @@
|
|||
DROP FUNCTION IF EXISTS account.userGetNameFromId;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` FUNCTION `account`.`userGetNameFromId`(vSelf INT) RETURNS varchar(30) CHARSET utf8
|
||||
BEGIN
|
||||
/**
|
||||
* @deprecated Use user_getNameFromId();
|
||||
*/
|
||||
RETURN user_getNameFromId(vSelf);
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -1,12 +0,0 @@
|
|||
DROP FUNCTION IF EXISTS account.userHasRole;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` FUNCTION `account`.`userHasRole`(vUserName VARCHAR(255), vRoleName VARCHAR(255)) RETURNS tinyint(1)
|
||||
DETERMINISTIC
|
||||
BEGIN
|
||||
/**
|
||||
* @deprecated Use user_hasRole()
|
||||
*/
|
||||
RETURN user_hasRole(vUserName, vRoleName);
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -1,12 +0,0 @@
|
|||
DROP FUNCTION IF EXISTS account.userHasRoleId;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` FUNCTION `account`.`userHasRoleId`(vUser VARCHAR(255), vRoleId INT) RETURNS tinyint(1)
|
||||
DETERMINISTIC
|
||||
BEGIN
|
||||
/**
|
||||
* @deprecated Use user_hasRoleId()
|
||||
*/
|
||||
RETURN user_hasRoleId(vUser, vRoleId);
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -1,14 +0,0 @@
|
|||
DROP PROCEDURE IF EXISTS account.userLogin;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `account`.`userLogin`(vUserName VARCHAR(255), vPassword VARCHAR(255))
|
||||
READS SQL DATA
|
||||
BEGIN
|
||||
/**
|
||||
* @deprecated Use myUser_login()
|
||||
*/
|
||||
CALL myUser_login(vUserName, vPassword);
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
GRANT EXECUTE ON PROCEDURE account.userLogin TO guest@localhost;
|
|
@ -1,14 +0,0 @@
|
|||
DROP PROCEDURE IF EXISTS account.userLoginWithKey;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `account`.`userLoginWithKey`(vUserName VARCHAR(255), vKey VARCHAR(255))
|
||||
READS SQL DATA
|
||||
BEGIN
|
||||
/**
|
||||
* @deprecated Use myUser_loginWithKey()
|
||||
*/
|
||||
CALL myUser_loginWithKey(vUserName, vKey);
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
GRANT EXECUTE ON PROCEDURE account.userLoginWithKey TO guest@localhost;
|
|
@ -1,12 +0,0 @@
|
|||
DROP PROCEDURE IF EXISTS account.userLoginWithName;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `account`.`userLoginWithName`(vUserName VARCHAR(255))
|
||||
READS SQL DATA
|
||||
BEGIN
|
||||
/**
|
||||
* @deprecated Use myUser_loginWithName()
|
||||
*/
|
||||
CALL myUser_loginWithName(vUserName);
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -1,14 +0,0 @@
|
|||
DROP PROCEDURE IF EXISTS account.myUserLogout;
|
||||
|
||||
DELIMITER $$
|
||||
$$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `account`.`myUserLogout`()
|
||||
BEGIN
|
||||
/**
|
||||
* @deprecated Use myUser_Logout()
|
||||
*/
|
||||
CALL myUser_logout;
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
GRANT EXECUTE ON PROCEDURE account.myUserLogout TO account@localhost;
|
|
@ -1,16 +0,0 @@
|
|||
DROP PROCEDURE IF EXISTS account.userSetPassword;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `account`.`userSetPassword`(vUserName VARCHAR(255), vPassword VARCHAR(255))
|
||||
BEGIN
|
||||
/**
|
||||
* @deprecated Use user_setPassword()
|
||||
*/
|
||||
DECLARE vUserId INT;
|
||||
|
||||
SELECT id INTO vUserId
|
||||
FROM user WHERE `name` = vUserName;
|
||||
|
||||
CALL user_setPassword(vUserId, vPassword);
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -1,27 +0,0 @@
|
|||
DROP PROCEDURE IF EXISTS account.user_changePassword;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE account.user_changePassword(vSelf INT, vOldPassword VARCHAR(255), vPassword VARCHAR(255))
|
||||
BEGIN
|
||||
/**
|
||||
* Changes the user password.
|
||||
*
|
||||
* @param vSelf The user id
|
||||
* @param vOldPassword The current password
|
||||
* @param vPassword The new password
|
||||
*/
|
||||
DECLARE vPasswordOk BOOL;
|
||||
DECLARE vUserName VARCHAR(255);
|
||||
|
||||
SELECT `password` = MD5(vOldPassword), `name`
|
||||
INTO vPasswordOk, vUserName
|
||||
FROM user WHERE id = vSelf;
|
||||
|
||||
IF NOT vPasswordOk THEN
|
||||
SIGNAL SQLSTATE '45000'
|
||||
SET MESSAGE_TEXT = 'Invalid password';
|
||||
END IF;
|
||||
|
||||
CALL user_setPassword(vSelf, vPassword);
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -1,17 +0,0 @@
|
|||
DROP PROCEDURE IF EXISTS account.user_checkName;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `account`.`user_checkName`(vUserName VARCHAR(255))
|
||||
BEGIN
|
||||
/**
|
||||
* Checks that username meets the necessary syntax requirements, otherwise it
|
||||
* throws an exception.
|
||||
* The user name must only contain lowercase letters or, starting with second
|
||||
* character, numbers or underscores.
|
||||
*/
|
||||
IF vUserName NOT REGEXP '^[a-z0-9_-]*$' THEN
|
||||
SIGNAL SQLSTATE '45000'
|
||||
SET MESSAGE_TEXT = 'INVALID_USER_NAME';
|
||||
END IF;
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -1,22 +0,0 @@
|
|||
DROP FUNCTION IF EXISTS account.user_getMysqlRole;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` FUNCTION `account`.`user_getMysqlRole`(vUserName VARCHAR(255)) RETURNS varchar(255) CHARSET utf8
|
||||
BEGIN
|
||||
/**
|
||||
* From a username, it returns the associated MySQL wich should be used when
|
||||
* using external authentication systems.
|
||||
*
|
||||
* @param vUserName The user name
|
||||
* @return The associated MySQL role
|
||||
*/
|
||||
DECLARE vRole VARCHAR(255);
|
||||
|
||||
SELECT CONCAT(IF(r.hasLogin, 'z-', ''), r.name) INTO vRole
|
||||
FROM role r
|
||||
JOIN user u ON u.role = r.id
|
||||
WHERE u.name = vUserName;
|
||||
|
||||
RETURN vRole;
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -1,20 +0,0 @@
|
|||
DROP FUNCTION IF EXISTS account.user_getNameFromId;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` FUNCTION `account`.`user_getNameFromId`(vSelf INT) RETURNS varchar(30) CHARSET utf8
|
||||
BEGIN
|
||||
/**
|
||||
* Gets user name from it's id.
|
||||
*
|
||||
* @param vSelf The user id
|
||||
* @return The user name
|
||||
*/
|
||||
DECLARE vName VARCHAR(30);
|
||||
|
||||
SELECT `name` INTO vName
|
||||
FROM user
|
||||
WHERE id = vSelf;
|
||||
|
||||
RETURN vName;
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -1,25 +0,0 @@
|
|||
DROP FUNCTION IF EXISTS account.user_hasRole;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` FUNCTION `account`.`user_hasRole`(vUserName VARCHAR(255), vRoleName VARCHAR(255)) RETURNS tinyint(1)
|
||||
DETERMINISTIC
|
||||
BEGIN
|
||||
/**
|
||||
* Checks if user has/inherits a role.
|
||||
*
|
||||
* @param vUserName The user name
|
||||
* @param vRoleName Role to check
|
||||
* @return %TRUE if it has role, %FALSE otherwise
|
||||
*/
|
||||
DECLARE vHasRole BOOL DEFAULT FALSE;
|
||||
|
||||
SELECT COUNT(*) > 0 INTO vHasRole
|
||||
FROM user u
|
||||
JOIN roleRole rr ON rr.role = u.role
|
||||
JOIN role r ON r.id = rr.inheritsFrom
|
||||
WHERE u.`name` = vUserName
|
||||
AND r.`name` = vRoleName COLLATE 'utf8_unicode_ci';
|
||||
|
||||
RETURN vHasRole;
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -1,25 +0,0 @@
|
|||
DROP FUNCTION IF EXISTS account.user_hasRoleId;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` FUNCTION `account`.`user_hasRoleId`(vUser VARCHAR(255), vRoleId INT) RETURNS tinyint(1)
|
||||
DETERMINISTIC
|
||||
BEGIN
|
||||
/**
|
||||
* Checks if user has/inherits a role.
|
||||
*
|
||||
* @param vUserName The user name
|
||||
* @param vRoleId Role id to check
|
||||
* @return %TRUE if it has role, %FALSE otherwise
|
||||
*/
|
||||
DECLARE vHasRole BOOL DEFAULT FALSE;
|
||||
|
||||
SELECT COUNT(*) > 0 INTO vHasRole
|
||||
FROM user u
|
||||
JOIN roleRole rr ON rr.role = u.role
|
||||
JOIN role r ON r.id = rr.inheritsFrom
|
||||
WHERE u.`name` = vUser
|
||||
AND r.id = vRoleId;
|
||||
|
||||
RETURN vHasRole;
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -1,21 +0,0 @@
|
|||
DROP PROCEDURE IF EXISTS account.user_setPassword;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE account.user_setPassword(vSelf INT, vPassword VARCHAR(255))
|
||||
BEGIN
|
||||
/**
|
||||
* Change the password of the passed as a parameter. Only administrators should
|
||||
* have execute privileges on the procedure since it does not request the user's
|
||||
* current password.
|
||||
*
|
||||
* @param vSelf The user id
|
||||
* @param vPassword New password
|
||||
*/
|
||||
CALL user_checkPassword(vPassword);
|
||||
|
||||
UPDATE user SET
|
||||
`password` = MD5(vPassword),
|
||||
`recoverPass` = FALSE
|
||||
WHERE id = vSelf;
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -1 +0,0 @@
|
|||
UPDATE salix.ACL t SET t.principalId = 'salesAssistant' WHERE t.id = 234
|
|
@ -1,37 +0,0 @@
|
|||
CREATE TABLE `vn`.campaign
|
||||
(
|
||||
id INT AUTO_INCREMENT,
|
||||
code ENUM('mothersDay', 'allSaints', 'valentinesDay') NOT NULL,
|
||||
dated DATE DEFAULT CURDATE() NOT NULL,
|
||||
scopeDays INT NOT NULL DEFAULT '15',
|
||||
CONSTRAINT campaign_pk
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX campaign_dated_uindex
|
||||
ON `vn`.campaign (dated);
|
||||
|
||||
-- TODOS SANTOS
|
||||
INSERT INTO `vn`.campaign(code, dated)
|
||||
SELECT 'allSaints' AS code, dated
|
||||
FROM `vn`.time
|
||||
WHERE dated >= CONCAT(YEAR(CURDATE()) - 1, '-01-01')
|
||||
AND month = 11
|
||||
AND day = 1;
|
||||
|
||||
-- SAN VALENTIN
|
||||
INSERT INTO `vn`.campaign(code, dated)
|
||||
SELECT 'valentinesDay' AS code, dated
|
||||
FROM `vn`.time
|
||||
WHERE dated >= CONCAT(YEAR(CURDATE()) - 1, '-01-01')
|
||||
AND month = 2
|
||||
AND day = 14;
|
||||
|
||||
-- DIA DE LA MADRE
|
||||
INSERT INTO `vn`.campaign(code, dated)
|
||||
SELECT 'mothersDay' AS code, dated
|
||||
FROM `vn`.time
|
||||
WHERE dated >= CONCAT(YEAR(CURDATE()) - 1, '-01-01')
|
||||
AND month = 5
|
||||
AND WEEK(dated, 5) - WEEK(DATE_SUB(dated, INTERVAL DAYOFMONTH(dated) - 1 DAY), 5) + 1 = 1 -- WEEK OF MONTH
|
||||
AND DAYOFWEEK(dated) = 1;
|
|
@ -1,4 +0,0 @@
|
|||
ALTER TABLE `vn`.department
|
||||
ADD notificationEmail VARCHAR(150) null;
|
||||
|
||||
UPDATE vn.department t SET t.notificationEmail = 'direccioncomercial@verdnatura.es' WHERE t.id = 43
|
|
@ -8,3 +8,15 @@ ALTER TABLE account.ldapConfig DROP COLUMN `filter`;
|
|||
ALTER TABLE account.ldapConfig CHANGE baseDn userDn varchar(255) DEFAULT NULL NULL COMMENT 'The base DN to do the query';
|
||||
ALTER TABLE account.ldapConfig CHANGE host server varchar(255) NOT NULL COMMENT 'The hostname of LDAP server';
|
||||
ALTER TABLE account.ldapConfig MODIFY COLUMN password varchar(255) NOT NULL COMMENT 'The LDAP password';
|
||||
|
||||
-- Updated
|
||||
|
||||
ALTER TABLE account.sambaConfig DROP COLUMN sshUser;
|
||||
ALTER TABLE account.sambaConfig DROP COLUMN sshPassword;
|
||||
ALTER TABLE account.sambaConfig CHANGE host adController varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL NULL COMMENT 'The hosname of domain controller';
|
||||
ALTER TABLE account.sambaConfig MODIFY COLUMN adController varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL NULL COMMENT 'The hosname of domain controller';
|
||||
|
||||
ALTER TABLE account.sambaConfig DROP COLUMN userDn;
|
||||
ALTER TABLE account.sambaConfig ADD adDomain varchar(255) NOT NULL AFTER id;
|
||||
ALTER TABLE account.sambaConfig ADD verifyCert TINYINT UNSIGNED NOT NULL DEFAULT TRUE AFTER adPassword;
|
||||
ALTER TABLE account.sambaConfig MODIFY COLUMN adController varchar(255) NOT NULL COMMENT 'The hosname of domain controller';
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
UPDATE `salix`.`ACL` SET `principalId` = 'deliveryBoss' WHERE (`id` = '194');
|
||||
UPDATE `salix`.`ACL` SET `principalId` = 'claimManager' WHERE (`id` = '97');
|
||||
UPDATE `salix`.`ACL` SET `principalId` = 'claimManager' WHERE (`id` = '100');
|
||||
UPDATE `salix`.`ACL` SET `principalId` = 'claimManager' WHERE (`id` = '103');
|
||||
UPDATE `salix`.`ACL` SET `principalId` = 'claimManager' WHERE (`id` = '202');
|
||||
|
||||
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('Town', '*', 'WRITE', 'ALLOW', 'ROLE', 'deliveryBoss');
|
||||
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('Province', '*', 'WRITE', 'ALLOW', 'ROLE', 'deliveryBoss');
|
||||
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('supplier', '*', 'WRITE', 'ALLOW', 'ROLE', 'administrative');
|
||||
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('SupplierContact', '*', 'WRITE', 'ALLOW', 'ROLE', 'administrative');
|
|
@ -0,0 +1,3 @@
|
|||
UPDATE `vn`.`claimState` SET `roleFk` = '72' WHERE (`id` = '3');
|
||||
UPDATE `vn`.`claimState` SET `roleFk` = '72' WHERE (`id` = '4');
|
||||
UPDATE `vn`.`claimState` SET `roleFk` = '72' WHERE (`id` = '5');
|
|
@ -0,0 +1,9 @@
|
|||
ALTER TABLE `vn`.`observationType`
|
||||
ADD COLUMN `code` VARCHAR(45) NOT NULL AFTER `description`;
|
||||
|
||||
UPDATE `vn`.`observationType` SET `code` = 'itemPicker' WHERE (`id` = '1');
|
||||
UPDATE `vn`.`observationType` SET `code` = 'packager' WHERE (`id` = '2');
|
||||
UPDATE `vn`.`observationType` SET `code` = 'salesPerson' WHERE (`id` = '4');
|
||||
UPDATE `vn`.`observationType` SET `code` = 'administrative' WHERE (`id` = '5');
|
||||
UPDATE `vn`.`observationType` SET `code` = 'weight' WHERE (`id` = '6');
|
||||
UPDATE `vn`.`observationType` SET `code` = 'delivery' WHERE (`id` = '3');
|
|
@ -0,0 +1,20 @@
|
|||
CREATE TABLE `vn`.`supplierLog` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`originFk` int(11) NOT NULL,
|
||||
`userFk` int(10) unsigned NOT NULL,
|
||||
`action` set('insert','update','delete') COLLATE utf8_unicode_ci NOT NULL,
|
||||
`creationDate` timestamp NULL DEFAULT current_timestamp(),
|
||||
`description` text CHARACTER SET utf8 DEFAULT NULL,
|
||||
`changedModel` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||
`oldInstance` text COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||
`newInstance` text COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||
`changedModelId` int(11) DEFAULT NULL,
|
||||
`changedModelValue` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `logSupplier_ibfk_1` (`originFk`),
|
||||
KEY `supplierLog_ibfk_2` (`userFk`),
|
||||
CONSTRAINT `supplierLog_ibfk_1` FOREIGN KEY (`originFk`) REFERENCES `supplier` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT `supplierLog_ibfk_2` FOREIGN KEY (`userFk`) REFERENCES `account`.`user` (`id`) ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
DROP TRIGGER IF EXISTS `vn`.`ticket_afterUpdate`;
|
||||
|
||||
DELIMITER $$
|
||||
USE `vn`$$
|
||||
CREATE DEFINER=`root`@`%` TRIGGER `ticket_afterUpdate`
|
||||
AFTER UPDATE ON `ticket`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
IF !(NEW.id <=> OLD.id)
|
||||
OR !(NEW.warehouseFk <=> OLD.warehouseFk)
|
||||
OR !(NEW.shipped <=> OLD.shipped) THEN
|
||||
CALL stock.log_add('ticket', NEW.id, OLD.id);
|
||||
END IF;
|
||||
|
||||
IF NEW.clientFk = 2067 AND !(NEW.clientFk <=> OLD.clientFk) THEN
|
||||
-- Fallo que se insertan no se sabe como tickets en este cliente
|
||||
INSERT INTO vn.mail SET
|
||||
`sender` = 'jgallego@verdnatura.es',
|
||||
`replyTo` = 'jgallego@verdnatura.es',
|
||||
`subject` = 'Modificado ticket al cliente 2067',
|
||||
`body` = CONCAT(account.myUserGetName(), ' ha modificado el ticket ',
|
||||
NEW.id);
|
||||
END IF;
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -0,0 +1,107 @@
|
|||
USE `vn`;
|
||||
DROP procedure IF EXISTS `ticket_componentPreview`;
|
||||
|
||||
DELIMITER $$
|
||||
USE `vn`$$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `ticket_componentPreview`(
|
||||
vTicketFk INT,
|
||||
vLanded DATE,
|
||||
vAddressFk INT,
|
||||
vZoneFk INT,
|
||||
vWarehouseFk SMALLINT)
|
||||
BEGIN
|
||||
/**
|
||||
* Calcula los componentes de los articulos de un ticket
|
||||
*
|
||||
* @param vTicketFk id del ticket
|
||||
* @param vLanded nueva fecha de entrega
|
||||
* @param vAddressFk nuevo consignatario
|
||||
* @param vZoneFk nueva zona
|
||||
* @param vWarehouseFk nuevo warehouse
|
||||
*
|
||||
* @return tmp.ticketComponentPreview (warehouseFk, itemFk, componentFk, cost)
|
||||
*/
|
||||
DECLARE vHasDataChanged BOOL DEFAULT FALSE;
|
||||
DECLARE vHasAddressChanged BOOL;
|
||||
DECLARE vHasZoneChanged BOOL DEFAULT FALSE;
|
||||
DECLARE vHasWarehouseChanged BOOL DEFAULT FALSE;
|
||||
|
||||
DECLARE vShipped DATE;
|
||||
DECLARE vAddressTypeRateFk INT DEFAULT NULL;
|
||||
DECLARE vAgencyModeTypeRateFk INT DEFAULT NULL;
|
||||
|
||||
DECLARE vHasChangeAll BOOL DEFAULT FALSE;
|
||||
|
||||
SELECT DATE(landed) <> vLanded,
|
||||
addressFk <> vAddressFk,
|
||||
zoneFk <> vZoneFk,
|
||||
warehouseFk <> vWarehouseFk
|
||||
INTO
|
||||
vHasDataChanged,
|
||||
vHasAddressChanged,
|
||||
vHasZoneChanged,
|
||||
vHasWarehouseChanged
|
||||
FROM vn.ticket t
|
||||
WHERE t.id = vTicketFk;
|
||||
|
||||
IF vHasDataChanged OR vHasWarehouseChanged THEN
|
||||
SET vHasChangeAll = TRUE;
|
||||
END IF;
|
||||
|
||||
IF vHasAddressChanged THEN
|
||||
SET vAddressTypeRateFk = 5;
|
||||
END IF;
|
||||
|
||||
IF vHasZoneChanged THEN
|
||||
SET vAgencyModeTypeRateFk = 6;
|
||||
END IF;
|
||||
|
||||
SELECT TIMESTAMPADD(DAY, -travelingDays, vLanded) INTO vShipped
|
||||
FROM zone
|
||||
WHERE id = vZoneFk;
|
||||
|
||||
CALL buyUltimate(vWarehouseFk, vShipped);
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp.ticketLot;
|
||||
CREATE TEMPORARY TABLE tmp.ticketLot ENGINE = MEMORY (
|
||||
SELECT
|
||||
vWarehouseFk AS warehouseFk,
|
||||
NULL AS available,
|
||||
s.itemFk,
|
||||
bu.buyFk,
|
||||
vZoneFk zoneFk
|
||||
FROM sale s
|
||||
LEFT JOIN tmp.buyUltimate bu ON bu.itemFk = s.itemFk
|
||||
WHERE s.ticketFk = vTicketFk
|
||||
GROUP BY bu.warehouseFk, bu.itemFk);
|
||||
|
||||
CALL catalog_componentPrepare();
|
||||
CALL catalog_componentCalculate(vZoneFk, vAddressFk, vShipped, vWarehouseFk);
|
||||
|
||||
REPLACE INTO tmp.ticketComponent (warehouseFk, itemFk, componentFk, cost)
|
||||
SELECT t.warehouseFk, s.itemFk, sc.componentFk, sc.value
|
||||
FROM saleComponent sc
|
||||
JOIN sale s ON s.id = sc.saleFk
|
||||
JOIN ticket t ON t.id = s.ticketFk
|
||||
JOIN `component` c ON c.id = sc.componentFk
|
||||
WHERE s.ticketFk = vTicketFk
|
||||
AND (c.isRenewable = FALSE
|
||||
OR
|
||||
(NOT vHasChangeAll
|
||||
AND (NOT (c.typeFk <=> vAddressTypeRateFk
|
||||
OR c.typeFk <=> vAgencyModeTypeRateFk))));
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp.ticketComponentPreview;
|
||||
CREATE TEMPORARY TABLE tmp.ticketComponentPreview
|
||||
SELECT * FROM tmp.ticketComponent;
|
||||
|
||||
CALL catalog_componentPurge();
|
||||
DROP TEMPORARY TABLE tmp.buyUltimate;
|
||||
|
||||
IF vShipped IS NULL THEN
|
||||
CALL util.throw('NO_ZONE_AVAILABLE');
|
||||
END IF;
|
||||
END$$
|
||||
|
||||
DELIMITER ;
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
|
@ -87,5 +87,6 @@ TABLES=(
|
|||
sage
|
||||
TiposIva
|
||||
TiposTransacciones
|
||||
TiposRetencion
|
||||
)
|
||||
dump_tables ${TABLES[@]}
|
|
@ -247,7 +247,7 @@ let actions = {
|
|||
|
||||
write: async function(selector, text) {
|
||||
let builtSelector = await this.selectorFormater(selector);
|
||||
await this.waitForSelector(selector, {});
|
||||
await this.waitForSelector(selector);
|
||||
await this.type(builtSelector, text);
|
||||
await this.waitForTextInField(selector, text);
|
||||
},
|
||||
|
@ -340,6 +340,31 @@ let actions = {
|
|||
});
|
||||
},
|
||||
|
||||
waitForTextInField: async function(selector, text) {
|
||||
let builtSelector = await this.selectorFormater(selector);
|
||||
await this.waitForSelector(builtSelector);
|
||||
const expectedText = text.toLowerCase();
|
||||
return new Promise((resolve, reject) => {
|
||||
let attempts = 0;
|
||||
const interval = setInterval(async() => {
|
||||
const currentText = await this.evaluate(selector => {
|
||||
return document.querySelector(selector).value.toLowerCase();
|
||||
}, builtSelector);
|
||||
|
||||
if (currentText === expectedText || attempts === 40) {
|
||||
clearInterval(interval);
|
||||
resolve(currentText);
|
||||
}
|
||||
attempts += 1;
|
||||
}, 100);
|
||||
}).then(result => {
|
||||
if (result === '')
|
||||
return expect(result).toEqual(expectedText);
|
||||
|
||||
return expect(result).toContain(expectedText);
|
||||
});
|
||||
},
|
||||
|
||||
selectorFormater: function(selector) {
|
||||
if (selector.includes('vn-textarea'))
|
||||
return `${selector} textarea`;
|
||||
|
@ -350,14 +375,6 @@ let actions = {
|
|||
return `${selector} input`;
|
||||
},
|
||||
|
||||
waitForTextInField: async function(selector, text) {
|
||||
let builtSelector = await this.selectorFormater(selector);
|
||||
await this.waitForSelector(builtSelector);
|
||||
return await this.waitForFunction((selector, text) => {
|
||||
return document.querySelector(selector).value.toLowerCase().includes(text.toLowerCase());
|
||||
}, {}, builtSelector, text);
|
||||
},
|
||||
|
||||
waitForInnerText: async function(selector) {
|
||||
await this.waitForSelector(selector, {});
|
||||
await this.waitForFunction(selector => {
|
||||
|
|
|
@ -272,9 +272,9 @@ export default {
|
|||
firstRequestItemID: 'vn-item-request vn-tbody > vn-tr:nth-child(1) > vn-td-editable:nth-child(7)',
|
||||
firstRequestQuantity: 'vn-item-request vn-tbody > vn-tr:nth-child(1) > vn-td-editable:nth-child(8)',
|
||||
firstRequestConcept: 'vn-item-request vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(9)',
|
||||
secondRequestStatus: 'vn-item-request vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(10)',
|
||||
firstRequestStatus: 'vn-item-request vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(10)',
|
||||
secondRequestDecline: 'vn-item-request vn-tbody > vn-tr:nth-child(1) vn-icon-button[icon="thumb_down"]',
|
||||
secondRequestStatus: 'vn-item-request vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(10)',
|
||||
secondRequestDecline: 'vn-item-request vn-tr:nth-child(2) vn-icon-button[icon="thumb_down"]',
|
||||
declineReason: 'vn-textarea[ng-model="$ctrl.denyObservation"]'
|
||||
},
|
||||
itemBasicData: {
|
||||
|
@ -413,7 +413,7 @@ export default {
|
|||
stateLabelValue: 'vn-ticket-descriptor vn-label-value[label="State"]',
|
||||
isDeletedIcon: 'vn-ticket-descriptor vn-icon[icon="icon-deletedTicket"]',
|
||||
goBackToModuleIndexButton: 'vn-ticket-descriptor a[ui-sref="ticket.index"]',
|
||||
moreMenu: 'vn-ticket-descriptor vn-icon-button[icon=more_vert]',
|
||||
moreMenu: 'vn-ticket-descriptor vn-ticket-descriptor-menu > vn-icon-button[icon=more_vert]',
|
||||
moreMenuAddStowaway: '.vn-menu [name="addStowaway"]',
|
||||
moreMenuDeleteStowawayButton: '.vn-menu [name="deleteStowaway"]',
|
||||
moreMenuAddToTurn: '.vn-menu [name="addTurn"]',
|
||||
|
@ -482,7 +482,7 @@ export default {
|
|||
firstSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(1) vn-check[ng-model="sale.checked"]',
|
||||
secondSaleText: 'vn-table div > vn-tbody > vn-tr:nth-child(2)',
|
||||
secondSaleId: 'vn-ticket-sale:nth-child(2) vn-td-editable:nth-child(4) text > span',
|
||||
secondSaleIdAutocomplete: 'vn-ticket-sale vn-table vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(4) > vn-autocomplete',
|
||||
secondSaleIdAutocomplete: 'vn-ticket-sale vn-tr:nth-child(2) vn-autocomplete[ng-model="sale.itemFk"]',
|
||||
secondSaleQuantity: 'vn-ticket-sale vn-table vn-tr:nth-child(2) vn-input-number',
|
||||
secondSaleQuantityCell: 'vn-ticket-sale > div > vn-card > vn-table > div > vn-tbody > vn-tr:nth-child(2) > vn-td-editable:nth-child(5)',
|
||||
secondSaleConceptCell: 'vn-ticket-sale vn-tbody > :nth-child(2) > :nth-child(6)',
|
||||
|
@ -613,7 +613,7 @@ export default {
|
|||
isPaidWithManaCheckbox: 'vn-claim-action vn-check[ng-model="$ctrl.claim.isChargedToMana"]'
|
||||
},
|
||||
ordersIndex: {
|
||||
secondSearchResultTotal: 'vn-order-index vn-card > vn-table > div > vn-tbody vn-tr:nth-child(2) vn-td:nth-child(9)',
|
||||
secondSearchResultTotal: 'vn-order-index vn-card > vn-table > div > vn-tbody .vn-tr:nth-child(2) vn-td:nth-child(9)',
|
||||
advancedSearchButton: 'vn-order-search-panel vn-submit[label="Search"]',
|
||||
openAdvancedSearch: 'vn-searchbar vn-icon[icon="arrow_drop_down"]',
|
||||
advancedSearchShowEmptyCheckbox: 'vn-order-search-panel vn-check[label="Show empty"]',
|
||||
|
|
|
@ -19,7 +19,7 @@ describe('Login path', async() => {
|
|||
const message = await page.waitForSnackbar();
|
||||
const state = await page.getState();
|
||||
|
||||
expect(message.text).toBe('Invalid login, remember that distinction is made between uppercase and lowercase');
|
||||
expect(message.text).toContain('Invalid login, remember that distinction is made between uppercase and lowercase');
|
||||
expect(state).toBe('login');
|
||||
});
|
||||
|
||||
|
@ -28,7 +28,7 @@ describe('Login path', async() => {
|
|||
const message = await page.waitForSnackbar();
|
||||
const state = await page.getState();
|
||||
|
||||
expect(message.text).toBe('Invalid login, remember that distinction is made between uppercase and lowercase');
|
||||
expect(message.text).toContain('Invalid login, remember that distinction is made between uppercase and lowercase');
|
||||
expect(state).toBe('login');
|
||||
});
|
||||
|
||||
|
@ -37,7 +37,7 @@ describe('Login path', async() => {
|
|||
const message = await page.waitForSnackbar();
|
||||
const state = await page.getState();
|
||||
|
||||
expect(message.text).toBe('Please enter your username');
|
||||
expect(message.text).toContain('Please enter your username');
|
||||
expect(state).toBe('login');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -31,7 +31,7 @@ describe('Client create path', () => {
|
|||
await page.waitToClick(selectors.createClientView.createButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Some fields are invalid');
|
||||
expect(message.text).toContain('Some fields are invalid');
|
||||
});
|
||||
|
||||
it('should receive an error when clicking the create button having name and Business name fields empty', async() => {
|
||||
|
@ -42,7 +42,7 @@ describe('Client create path', () => {
|
|||
await page.waitToClick(selectors.createClientView.createButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Some fields are invalid');
|
||||
expect(message.text).toContain('Some fields are invalid');
|
||||
});
|
||||
|
||||
it(`should create a new province`, async() => {
|
||||
|
@ -53,7 +53,7 @@ describe('Client create path', () => {
|
|||
await page.waitToClick(selectors.createClientView.saveNewProvicenButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('The province has been created');
|
||||
expect(message.text).toContain('The province has been created');
|
||||
});
|
||||
|
||||
it(`should create a new city`, async() => {
|
||||
|
@ -63,7 +63,7 @@ describe('Client create path', () => {
|
|||
await page.waitToClick(selectors.createClientView.saveNewCityButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('The city has been created');
|
||||
expect(message.text).toContain('The city has been created');
|
||||
});
|
||||
|
||||
it(`should create a new post code`, async() => {
|
||||
|
@ -72,7 +72,7 @@ describe('Client create path', () => {
|
|||
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('The postcode has been created. You can save the data now');
|
||||
expect(message.text).toContain('The postcode has been created. You can save the data now');
|
||||
});
|
||||
|
||||
it(`should attempt to create a new user with all it's data but wrong email`, async() => {
|
||||
|
@ -84,7 +84,7 @@ describe('Client create path', () => {
|
|||
await page.waitToClick(selectors.createClientView.createButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Some fields are invalid');
|
||||
expect(message.text).toContain('Some fields are invalid');
|
||||
});
|
||||
|
||||
it(`should attempt to create a new user with all it's data but wrong postal code`, async() => {
|
||||
|
@ -95,7 +95,7 @@ describe('Client create path', () => {
|
|||
await page.waitToClick(selectors.createClientView.createButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe(`The postcode doesn't exist. Please enter a correct one`);
|
||||
expect(message.text).toContain(`The postcode doesn't exist. Please enter a correct one`);
|
||||
});
|
||||
|
||||
it(`should check for autocompleted city, province and country`, async() => {
|
||||
|
@ -119,7 +119,7 @@ describe('Client create path', () => {
|
|||
await page.waitToClick(selectors.createClientView.createButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should click on the Clients button of the top bar menu', async() => {
|
||||
|
|
|
@ -37,7 +37,7 @@ describe('Client Edit basicData path', () => {
|
|||
await page.waitToClick(selectors.clientBasicData.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should confirm the name have been edited', async() => {
|
||||
|
@ -101,7 +101,7 @@ describe('Client Edit basicData path', () => {
|
|||
await page.waitToClick(selectors.clientBasicData.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should now confirm the name have been edited', async() => {
|
||||
|
|
|
@ -83,7 +83,7 @@ describe('Client Edit fiscalData path', () => {
|
|||
await page.waitToClick(selectors.globalItems.acceptButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Invalid Tax number');
|
||||
expect(message.text).toContain('Invalid Tax number');
|
||||
});
|
||||
|
||||
it(`should edit the fiscal this time with a valid fiscal id`, async() => {
|
||||
|
@ -93,14 +93,14 @@ describe('Client Edit fiscalData path', () => {
|
|||
await page.waitToClick(selectors.globalItems.acceptButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should propagate the Equalization tax', async() => {
|
||||
await page.waitToClick(selectors.globalItems.acceptButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Equivalent tax spreaded');
|
||||
expect(message.text).toContain('Equivalent tax spreaded');
|
||||
});
|
||||
|
||||
it('should receive an error if the fiscal id contains A or B at the beginning', async() => {
|
||||
|
@ -110,7 +110,7 @@ describe('Client Edit fiscalData path', () => {
|
|||
await page.waitToClick(selectors.clientFiscalData.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Cannot check Equalization Tax in this NIF/CIF');
|
||||
expect(message.text).toContain('Cannot check Equalization Tax in this NIF/CIF');
|
||||
});
|
||||
|
||||
it('should finally edit the fixcal data correctly as VIES isnt checked and fiscal id is valid for EQtax', async() => {
|
||||
|
@ -119,7 +119,7 @@ describe('Client Edit fiscalData path', () => {
|
|||
await page.waitToClick(selectors.clientFiscalData.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
// confirm all addresses have now EQtax checked step 1
|
||||
|
@ -155,7 +155,7 @@ describe('Client Edit fiscalData path', () => {
|
|||
await page.waitToClick(selectors.clientFiscalData.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should propagate the Equalization tax changes', async() => {
|
||||
|
@ -163,7 +163,7 @@ describe('Client Edit fiscalData path', () => {
|
|||
await page.waitToClick(selectors.globalItems.acceptButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Equivalent tax spreaded');
|
||||
expect(message.text).toContain('Equivalent tax spreaded');
|
||||
});
|
||||
|
||||
it('should confirm its name have been edited', async() => {
|
||||
|
@ -289,7 +289,7 @@ describe('Client Edit fiscalData path', () => {
|
|||
await page.waitToClick(selectors.clientAddresses.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
// confirm invoice by address checkbox gets checked if the EQtax differs between addresses step 3
|
||||
|
|
|
@ -28,7 +28,7 @@ describe('Client Edit billing data path', () => {
|
|||
await page.waitToClick(selectors.clientBillingData.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('That payment method requires an IBAN');
|
||||
expect(message.text).toContain('That payment method requires an IBAN');
|
||||
});
|
||||
|
||||
// 2256: Windows (hidden mode): Entity code doesn't get the focus, '9999' is written in entity name.
|
||||
|
@ -65,7 +65,7 @@ describe('Client Edit billing data path', () => {
|
|||
await page.waitToClick(selectors.clientBillingData.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Notification sent!');
|
||||
expect(message.text).toContain('Notification sent!');
|
||||
});
|
||||
|
||||
it('should confirm the due day have been edited', async() => {
|
||||
|
|
|
@ -31,7 +31,7 @@ describe('Client Add address path', () => {
|
|||
await page.waitToClick(selectors.clientFiscalData.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Some fields are invalid');
|
||||
expect(message.text).toContain('Some fields are invalid');
|
||||
});
|
||||
|
||||
it('should confirm that the city and province are propertly filled', async() => {
|
||||
|
@ -51,7 +51,7 @@ describe('Client Add address path', () => {
|
|||
await page.waitToClick(selectors.clientAddresses.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Incoterms is required for a non UEE member');
|
||||
expect(message.text).toContain('Incoterms is required for a non UEE member');
|
||||
});
|
||||
|
||||
it(`should receive an error after clicking save button as customsAgent is empty`, async() => {
|
||||
|
@ -59,7 +59,7 @@ describe('Client Add address path', () => {
|
|||
await page.waitToClick(selectors.clientAddresses.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Customs agent is required for a non UEE member');
|
||||
expect(message.text).toContain('Customs agent is required for a non UEE member');
|
||||
});
|
||||
|
||||
it(`should create a new custom agent and then save the address`, async() => {
|
||||
|
@ -73,7 +73,7 @@ describe('Client Add address path', () => {
|
|||
await page.waitToClick(selectors.clientAddresses.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it(`should navigate back to the addresses index`, async() => {
|
||||
|
@ -91,7 +91,7 @@ describe('Client Add address path', () => {
|
|||
await page.waitToClick(selectors.clientAddresses.secondMakeDefaultStar);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it(`should confirm the default address is the expected one`, async() => {
|
||||
|
@ -113,7 +113,7 @@ describe('Client Add address path', () => {
|
|||
await page.waitToClick(selectors.clientAddresses.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('The default consignee can not be unchecked');
|
||||
expect(message.text).toContain('The default consignee can not be unchecked');
|
||||
});
|
||||
|
||||
it(`should go back to the addreses section by clicking the cancel button`, async() => {
|
||||
|
|
|
@ -28,7 +28,7 @@ describe('Client add address notes path', () => {
|
|||
await page.waitToClick(selectors.clientAddresses.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Some fields are invalid');
|
||||
expect(message.text).toContain('Some fields are invalid');
|
||||
});
|
||||
|
||||
it('should not save an observation type without description', async() => {
|
||||
|
@ -37,7 +37,7 @@ describe('Client add address notes path', () => {
|
|||
await page.waitToClick(selectors.clientAddresses.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Some fields are invalid');
|
||||
expect(message.text).toContain('Some fields are invalid');
|
||||
});
|
||||
|
||||
it('should create two new observations', async() => {
|
||||
|
@ -48,6 +48,6 @@ describe('Client add address notes path', () => {
|
|||
await page.waitToClick(selectors.clientAddresses.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -23,7 +23,7 @@ describe('Client Edit web access path', () => {
|
|||
await page.waitToClick(selectors.clientWebAccess.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should confirm web access is now unchecked', async() => {
|
||||
|
|
|
@ -31,7 +31,7 @@ describe('Client Add notes path', () => {
|
|||
await page.waitToClick(selectors.clientNotes.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should confirm the note was created', async() => {
|
||||
|
|
|
@ -27,7 +27,7 @@ describe('Client Add credit path', () => {
|
|||
await page.waitToClick(selectors.clientCredit.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should confirm the credit was updated', async() => {
|
||||
|
|
|
@ -26,7 +26,7 @@ describe('Client Add greuge path', () => {
|
|||
await page.waitToClick(selectors.clientGreuge.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Some fields are invalid');
|
||||
expect(message.text).toContain('Some fields are invalid');
|
||||
});
|
||||
|
||||
it(`should create a new greuge with all its data`, async() => {
|
||||
|
@ -36,7 +36,7 @@ describe('Client Add greuge path', () => {
|
|||
await page.waitToClick(selectors.clientGreuge.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should confirm the greuge was added to the list', async() => {
|
||||
|
|
|
@ -32,7 +32,7 @@ describe('Client lock verified data path', () => {
|
|||
await page.waitToClick(selectors.clientFiscalData.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should confirm the social name have been edited', async() => {
|
||||
|
@ -64,7 +64,7 @@ describe('Client lock verified data path', () => {
|
|||
await page.waitToClick(selectors.globalItems.acceptButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should confirm Verified data checkbox is checked', async() => {
|
||||
|
@ -81,7 +81,7 @@ describe('Client lock verified data path', () => {
|
|||
await page.waitToClick(selectors.clientFiscalData.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should again confirm the social name have been edited', async() => {
|
||||
|
@ -111,7 +111,7 @@ describe('Client lock verified data path', () => {
|
|||
await page.waitToClick(selectors.clientFiscalData.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe(`You can't make changes on a client with verified data`);
|
||||
expect(message.text).toContain(`You can't make changes on a client with verified data`);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -135,7 +135,7 @@ describe('Client lock verified data path', () => {
|
|||
await page.waitToClick(selectors.clientFiscalData.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should now confirm the social name have been edited once and for all', async() => {
|
||||
|
|
|
@ -22,7 +22,7 @@ describe('Client log path', () => {
|
|||
await page.waitToClick(selectors.clientBasicData.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should navigate to the log section', async() => {
|
||||
|
|
|
@ -20,7 +20,7 @@ describe('Client balance path', () => {
|
|||
await page.autocompleteSearch(selectors.globalItems.userLocalCompany, 'CCs');
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should access to the balance section to check the data shown matches the local settings', async() => {
|
||||
|
@ -35,7 +35,7 @@ describe('Client balance path', () => {
|
|||
await page.clearInput(selectors.globalItems.userConfigThirdAutocomplete);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should click the new payment button', async() => {
|
||||
|
@ -51,7 +51,7 @@ describe('Client balance path', () => {
|
|||
await page.waitToClick(selectors.clientBalance.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should edit the 1st line reference', async() => {
|
||||
|
@ -60,7 +60,7 @@ describe('Client balance path', () => {
|
|||
await page.keyboard.press('Enter');
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should check balance is now 0, the reference was saved and the company is now VNL becouse the user local settings were removed', async() => {
|
||||
|
@ -85,7 +85,7 @@ describe('Client balance path', () => {
|
|||
await page.waitToClick(selectors.clientBalance.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should check balance is now -100', async() => {
|
||||
|
@ -101,7 +101,7 @@ describe('Client balance path', () => {
|
|||
await page.waitToClick(selectors.clientBalance.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should check balance is now 50', async() => {
|
||||
|
|
|
@ -22,7 +22,7 @@ describe('Client DMS', () => {
|
|||
await page.respondToDialog('accept');
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it(`should click on the first document line worker name making the descriptor visible`, async() => {
|
||||
|
|
|
@ -24,7 +24,7 @@ describe('Client contacts', () => {
|
|||
await page.waitToClick(selectors.clientContacts.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should delete de contact', async() => {
|
||||
|
@ -33,6 +33,6 @@ describe('Client contacts', () => {
|
|||
await page.waitToClick(selectors.clientContacts.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -26,7 +26,7 @@ describe('Worker basic data path', () => {
|
|||
await page.waitToClick(selectors.workerBasicData.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should reload the section then check the name was edited', async() => {
|
||||
|
|
|
@ -21,7 +21,7 @@ describe('Worker pbx path', () => {
|
|||
await page.waitToClick(selectors.workerPbx.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Extension format is invalid');
|
||||
expect(message.text).toContain('Extension format is invalid');
|
||||
});
|
||||
|
||||
it('should sucessfully save the changes', async() => {
|
||||
|
@ -30,6 +30,6 @@ describe('Worker pbx path', () => {
|
|||
await page.waitToClick(selectors.workerPbx.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved! User must access web');
|
||||
expect(message.text).toContain('Data saved! User must access web');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -59,7 +59,7 @@ describe('Worker time control path', () => {
|
|||
await page.respondToDialog('accept');
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Entry removed');
|
||||
expect(message.text).toContain('Entry removed');
|
||||
});
|
||||
|
||||
it(`should scan out Hank Pym to leave early`, async() => {
|
||||
|
|
|
@ -38,7 +38,7 @@ describe('Item Edit basic data path', () => {
|
|||
await page.waitToClick(selectors.itemBasicData.submitBasicDataButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it(`should create a new intrastat`, async() => {
|
||||
|
@ -57,7 +57,7 @@ describe('Item Edit basic data path', () => {
|
|||
await page.waitToClick(selectors.itemBasicData.submitBasicDataButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it(`should confirm the item name was edited`, async() => {
|
||||
|
|
|
@ -23,7 +23,7 @@ describe('Item edit tax path', () => {
|
|||
await page.waitToClick(selectors.itemTax.submitTaxButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it(`should confirm the first item tax class was edited`, async() => {
|
||||
|
|
|
@ -26,7 +26,7 @@ describe('Item create tags path', () => {
|
|||
await page.waitToClick(selectors.itemTags.submitItemTagsButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it(`should confirm the fourth row data is the expected one`, async() => {
|
||||
|
|
|
@ -25,7 +25,7 @@ describe('Item create niche path', () => {
|
|||
await page.waitToClick(selectors.itemNiches.submitNichesButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it(`should confirm the first niche is the expected one`, async() => {
|
||||
|
|
|
@ -23,7 +23,7 @@ describe('Item Create botanical path', () => {
|
|||
await page.waitToClick(selectors.itemBotanical.submitBotanicalButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it(`should confirm the botanical for the item was created`, async() => {
|
||||
|
@ -58,7 +58,7 @@ describe('Item Create botanical path', () => {
|
|||
await page.waitToClick(selectors.itemBotanical.submitBotanicalButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it(`should confirm the botanical for the item was edited`, async() => {
|
||||
|
|
|
@ -23,7 +23,7 @@ describe('Item Create barcodes path', () => {
|
|||
await page.waitToClick(selectors.itemBarcodes.submitBarcodesButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it(`should confirm the barcode 5 is created and it is now the third barcode as the first was deleted`, async() => {
|
||||
|
|
|
@ -45,7 +45,7 @@ describe('Item Create/Clone path', () => {
|
|||
await page.waitToClick(selectors.itemCreateView.createButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should confirm Infinity Gauntlet item was created', async() => {
|
||||
|
|
|
@ -20,7 +20,7 @@ describe('Item regularize path', () => {
|
|||
await page.autocompleteSearch(selectors.globalItems.userLocalWarehouse, 'Warehouse Four');
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should check the local settings were saved', async() => {
|
||||
|
@ -51,7 +51,7 @@ describe('Item regularize path', () => {
|
|||
await page.waitToClick(selectors.itemDescriptor.regularizeSaveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should click on the Tickets button of the top bar menu', async() => {
|
||||
|
@ -70,7 +70,7 @@ describe('Item regularize path', () => {
|
|||
await page.clearInput(selectors.globalItems.userConfigFirstAutocomplete);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should search for the ticket with alias missing', async() => {
|
||||
|
@ -114,7 +114,7 @@ describe('Item regularize path', () => {
|
|||
await page.waitToClick(selectors.itemDescriptor.regularizeSaveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should again click on the Tickets button of the top bar menu', async() => {
|
||||
|
|
|
@ -36,7 +36,7 @@ describe('Item index path', () => {
|
|||
await page.waitToClick(selectors.itemsIndex.saveFieldsButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should navigate forth and back to see the images column is still visible', async() => {
|
||||
|
@ -70,7 +70,7 @@ describe('Item index path', () => {
|
|||
await page.waitToClick(selectors.itemsIndex.saveFieldsButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should now navigate forth and back to see the ids column is now visible', async() => {
|
||||
|
|
|
@ -34,7 +34,7 @@ describe('Item log path', () => {
|
|||
await page.waitToClick(selectors.itemCreateView.createButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should return to the items index by clicking the return to items button', async() => {
|
||||
|
|
|
@ -29,7 +29,7 @@ describe('Item descriptor path', () => {
|
|||
await page.waitToClick(selectors.itemBasicData.submitBasicDataButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should reload the section and check the inactive icon is bright', async() => {
|
||||
|
@ -45,6 +45,6 @@ describe('Item descriptor path', () => {
|
|||
await page.waitToClick(selectors.itemBasicData.submitBasicDataButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -28,7 +28,7 @@ describe('Item request path', () => {
|
|||
expect(filledConcept).toContain('Melee weapon heavy shield 1x0.5m');
|
||||
});
|
||||
|
||||
it('should the status of the request should now be accepted', async() => {
|
||||
it('should check the status of the request should now be accepted', async() => {
|
||||
let status = await page.waitToGetProperty(selectors.itemRequest.firstRequestStatus, 'innerText');
|
||||
|
||||
expect(status).toContain('Accepted');
|
||||
|
@ -38,7 +38,7 @@ describe('Item request path', () => {
|
|||
await page.waitToClick(selectors.itemRequest.secondRequestDecline);
|
||||
await page.write(selectors.itemRequest.declineReason, 'Not quite as expected');
|
||||
await page.respondToDialog('accept');
|
||||
let status = await page.waitToGetProperty(selectors.itemRequest.firstRequestStatus, 'innerText');
|
||||
let status = await page.waitToGetProperty(selectors.itemRequest.secondRequestStatus, 'innerText');
|
||||
|
||||
expect(status).toContain('Denied');
|
||||
});
|
||||
|
|
|
@ -55,29 +55,13 @@ describe('Ticket List sale path', () => {
|
|||
|
||||
it('should select a valid item to be added as the second item in the sales list', async() => {
|
||||
let searchValue = 'Melee weapon heavy shield 1x0.5m';
|
||||
await page.waitToClick(`${selectors.ticketSales.secondSaleIdAutocomplete} input`);
|
||||
await page.waitForSelector(selector => {
|
||||
document
|
||||
.querySelector(`${selector} vn-drop-down`).$ctrl.content
|
||||
.querySelectorAll('li');
|
||||
}, selectors.ticketSales.secondSaleIdAutocomplete);
|
||||
|
||||
await page.write(`.vn-drop-down.shown`, searchValue);
|
||||
await page.waitForFunction((selector, searchValue) => {
|
||||
let element = document
|
||||
.querySelector(`${selector} vn-drop-down`).$ctrl.content
|
||||
.querySelector('li.active');
|
||||
if (element)
|
||||
return element.innerText.includes(searchValue);
|
||||
}, {}, selectors.ticketSales.secondSaleIdAutocomplete, searchValue);
|
||||
|
||||
await page.keyboard.press('Enter');
|
||||
await page.autocompleteSearch(selectors.ticketSales.secondSaleIdAutocomplete, searchValue);
|
||||
await page.waitToClick(selectors.ticketSales.secondSaleQuantityCell);
|
||||
await page.type(selectors.ticketSales.secondSaleQuantity, '1');
|
||||
await page.keyboard.press('Enter');
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should update the description of the new sale', async() => {
|
||||
|
@ -86,25 +70,25 @@ describe('Ticket List sale path', () => {
|
|||
await page.keyboard.press('Enter');
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should add a third empty item to the sale list', async() => {
|
||||
await page.waitToClick(selectors.ticketSales.newItemButton);
|
||||
await page.waitForNumberOfElements(selectors.ticketSales.saleLine, 3);
|
||||
const sales = await page.countElement(selectors.ticketSales.saleLine);
|
||||
|
||||
expect(sales).toEqual(3);
|
||||
});
|
||||
|
||||
it('should select the 2nd and 3th item and delete both', async() => {
|
||||
await page.waitFor(2000);
|
||||
await page.waitToClick(selectors.ticketSales.secondSaleCheckbox);
|
||||
await page.waitToClick(selectors.ticketSales.thirdSaleCheckbox);
|
||||
await page.waitToClick(selectors.ticketSales.deleteSaleButton);
|
||||
await page.waitToClick(selectors.globalItems.acceptButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it(`should verify there's only 1 single line remaining`, async() => {
|
||||
|
|
|
@ -41,7 +41,7 @@ describe('Ticket Edit sale path', () => {
|
|||
await page.keyboard.press('Enter');
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it(`should check it's state is libre now`, async() => {
|
||||
|
@ -55,7 +55,7 @@ describe('Ticket Edit sale path', () => {
|
|||
await page.waitToClick(selectors.ticketSales.setOk);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it(`should check it's state is OK now`, async() => {
|
||||
|
@ -125,7 +125,7 @@ describe('Ticket Edit sale path', () => {
|
|||
await page.type(selectors.ticketSales.firstSaleQuantity, '11\u000d');
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('The new quantity should be smaller than the old one');
|
||||
expect(message.text).toContain('The new quantity should be smaller than the old one');
|
||||
});
|
||||
|
||||
it('should remove 1 from the first sale quantity', async() => {
|
||||
|
@ -135,7 +135,7 @@ describe('Ticket Edit sale path', () => {
|
|||
await page.type(selectors.ticketSales.firstSaleQuantity, '9\u000d');
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should update the price', async() => {
|
||||
|
@ -144,7 +144,7 @@ describe('Ticket Edit sale path', () => {
|
|||
await page.type(selectors.ticketSales.firstSalePriceInput, '5\u000d');
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should confirm the price have been updated', async() => {
|
||||
|
@ -165,7 +165,7 @@ describe('Ticket Edit sale path', () => {
|
|||
await page.type(selectors.ticketSales.firstSaleDiscountInput, '50\u000d');
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should confirm the discount have been updated', async() => {
|
||||
|
@ -224,7 +224,7 @@ describe('Ticket Edit sale path', () => {
|
|||
await page.waitForSpinnerLoad();
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it(`should confirm the third sale was deleted`, async() => {
|
||||
|
@ -307,7 +307,7 @@ describe('Ticket Edit sale path', () => {
|
|||
await page.waitToClick(selectors.ticketSales.moveToNewTicketButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe(`You can't create a ticket for a inactive client`);
|
||||
expect(message.text).toContain(`You can't create a ticket for a inactive client`);
|
||||
|
||||
await page.closePopup();
|
||||
});
|
||||
|
|
|
@ -24,7 +24,7 @@ describe('Ticket Create notes path', () => {
|
|||
await page.waitToClick(selectors.ticketNotes.submitNotesButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should confirm the note is the expected one', async() => {
|
||||
|
@ -45,6 +45,6 @@ describe('Ticket Create notes path', () => {
|
|||
await page.waitToClick(selectors.ticketNotes.submitNotesButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -24,7 +24,7 @@ describe('Ticket Create packages path', () => {
|
|||
await page.waitToClick(selectors.ticketPackages.savePackagesButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Package cannot be blank');
|
||||
expect(message.text).toContain('Package cannot be blank');
|
||||
});
|
||||
|
||||
it(`should delete the first package and receive and error to save a new one with blank quantity`, async() => {
|
||||
|
@ -33,7 +33,7 @@ describe('Ticket Create packages path', () => {
|
|||
await page.waitToClick(selectors.ticketPackages.savePackagesButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Some fields are invalid');
|
||||
expect(message.text).toContain('Some fields are invalid');
|
||||
});
|
||||
|
||||
it(`should confirm the quantity input isn't invalid yet`, async() => {
|
||||
|
@ -51,7 +51,7 @@ describe('Ticket Create packages path', () => {
|
|||
await page.waitToClick(selectors.ticketPackages.savePackagesButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it(`should confirm the first select is the expected one`, async() => {
|
||||
|
|
|
@ -28,7 +28,7 @@ describe('Ticket Create new tracking state path', () => {
|
|||
await page.waitToClick(selectors.createStateView.saveStateButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('State cannot be blank');
|
||||
expect(message.text).toContain('State cannot be blank');
|
||||
});
|
||||
|
||||
it(`should create a new state`, async() => {
|
||||
|
@ -36,7 +36,7 @@ describe('Ticket Create new tracking state path', () => {
|
|||
await page.waitToClick(selectors.createStateView.saveStateButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -59,7 +59,7 @@ describe('Ticket Create new tracking state path', () => {
|
|||
await page.waitToClick(selectors.createStateView.saveStateButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe(`You don't have enough privileges`);
|
||||
expect(message.text).toContain(`You don't have enough privileges`);
|
||||
});
|
||||
|
||||
it(`should make sure the worker gets autocomplete uppon selecting the assigned state`, async() => {
|
||||
|
@ -74,7 +74,7 @@ describe('Ticket Create new tracking state path', () => {
|
|||
await page.waitToClick(selectors.createStateView.saveStateButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -33,7 +33,7 @@ describe('Ticket descriptor path', () => {
|
|||
await page.waitToClick(selectors.ticketDescriptor.thursdayButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should again click on the Tickets button of the top bar menu', async() => {
|
||||
|
@ -68,7 +68,7 @@ describe('Ticket descriptor path', () => {
|
|||
await page.waitToClick(selectors.ticketDescriptor.saturdayButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should click on the Tickets button of the top bar menu once again', async() => {
|
||||
|
@ -97,7 +97,7 @@ describe('Ticket descriptor path', () => {
|
|||
await page.waitToClick(selectors.ticketsIndex.acceptDeleteTurn);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should confirm the sixth weekly ticket was deleted', async() => {
|
||||
|
@ -111,11 +111,11 @@ describe('Ticket descriptor path', () => {
|
|||
await page.autocompleteSearch(selectors.ticketsIndex.firstWeeklyTicketAgency, 'Silla247');
|
||||
let message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
|
||||
await page.clearInput(selectors.ticketsIndex.firstWeeklyTicketAgency);
|
||||
message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -27,7 +27,7 @@ describe('Ticket purchase request path', () => {
|
|||
await page.waitToClick(selectors.ticketRequests.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should have been redirected to the request index', async() => {
|
||||
|
@ -39,7 +39,7 @@ describe('Ticket purchase request path', () => {
|
|||
await page.keyboard.press('Enter');
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should check the new request was added', async() => {
|
||||
|
@ -67,7 +67,7 @@ describe('Ticket purchase request path', () => {
|
|||
await page.waitToClick(selectors.ticketRequests.thirdRemoveRequestButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toBe('Data saved!');
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should check the request was deleted', async() => {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue