7152-devToTest_2414 #2228
|
@ -29,7 +29,8 @@ module.exports = Self => {
|
|||
http: {
|
||||
path: `/:id/downloadFile`,
|
||||
verb: 'GET'
|
||||
}
|
||||
},
|
||||
accessScopes: ['read:multimedia']
|
||||
});
|
||||
|
||||
Self.downloadFile = async function(ctx, id) {
|
||||
|
|
|
@ -42,7 +42,8 @@ module.exports = Self => {
|
|||
http: {
|
||||
path: `/:id/download`,
|
||||
verb: 'GET'
|
||||
}
|
||||
},
|
||||
accessScopes: ['read:multimedia']
|
||||
});
|
||||
|
||||
Self.download = async function(id, fileCabinet, filter) {
|
||||
|
|
|
@ -47,7 +47,8 @@ module.exports = Self => {
|
|||
http: {
|
||||
path: `/:collection/:size/:id/download`,
|
||||
verb: 'GET'
|
||||
}
|
||||
},
|
||||
accessScopes: ['read:multimedia']
|
||||
});
|
||||
|
||||
Self.download = async function(ctx, collection, size, id) {
|
||||
|
|
|
@ -7,7 +7,7 @@ describe('NotificationSubscription getList()', () => {
|
|||
const notifications = await models.Notification.find({});
|
||||
const totalAvailable = notifications.length - active.length;
|
||||
|
||||
expect(active.length).toEqual(2);
|
||||
expect(active.length).toEqual(3);
|
||||
expect(available.length).toEqual(totalAvailable);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('shareToken', {
|
||||
description: 'Returns token to view files or images and share it',
|
||||
accessType: 'WRITE',
|
||||
accepts: [],
|
||||
returns: {
|
||||
type: 'Object',
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/shareToken`,
|
||||
verb: 'GET'
|
||||
}
|
||||
});
|
||||
|
||||
Self.shareToken = async function(ctx) {
|
||||
const {accessToken: token} = ctx.req;
|
||||
|
||||
const user = await Self.findById(token.userId);
|
||||
const multimediaToken = await user.accessTokens.create({
|
||||
scopes: ['read:multimedia']
|
||||
});
|
||||
|
||||
return {multimediaToken};
|
||||
};
|
||||
};
|
|
@ -0,0 +1,27 @@
|
|||
const {models} = require('vn-loopback/server/server');
|
||||
describe('Share Token', () => {
|
||||
let ctx = null;
|
||||
beforeAll(async() => {
|
||||
const unAuthCtx = {
|
||||
req: {
|
||||
headers: {},
|
||||
connection: {
|
||||
remoteAddress: '127.0.0.1'
|
||||
},
|
||||
getLocale: () => 'en'
|
||||
},
|
||||
args: {}
|
||||
};
|
||||
let login = await models.VnUser.signIn(unAuthCtx, 'salesAssistant', 'nightmare');
|
||||
let accessToken = await models.AccessToken.findById(login.token);
|
||||
ctx = {req: {accessToken: accessToken}};
|
||||
});
|
||||
|
||||
it('should renew token', async() => {
|
||||
const multimediaToken = await models.VnUser.shareToken(ctx);
|
||||
|
||||
expect(Object.keys(multimediaToken).length).toEqual(1);
|
||||
expect(multimediaToken.multimediaToken.userId).toEqual(ctx.req.accessToken.userId);
|
||||
expect(multimediaToken.multimediaToken.scopes[0]).toEqual('read:multimedia');
|
||||
});
|
||||
});
|
|
@ -13,6 +13,7 @@ module.exports = function(Self) {
|
|||
require('../methods/vn-user/privileges')(Self);
|
||||
require('../methods/vn-user/validate-auth')(Self);
|
||||
require('../methods/vn-user/renew-token')(Self);
|
||||
require('../methods/vn-user/share-token')(Self);
|
||||
require('../methods/vn-user/update-user')(Self);
|
||||
|
||||
Self.definition.settings.acls = Self.definition.settings.acls.filter(acl => acl.property !== 'create');
|
||||
|
|
|
@ -1,129 +1,140 @@
|
|||
{
|
||||
"name": "VnUser",
|
||||
"base": "User",
|
||||
"validateUpsert": true,
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "account.user"
|
||||
}
|
||||
},
|
||||
"name": "VnUser",
|
||||
"base": "User",
|
||||
"validateUpsert": true,
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "account.user"
|
||||
}
|
||||
},
|
||||
"mixins": {
|
||||
"Loggable": true
|
||||
},
|
||||
"resetPasswordTokenTTL": "604800",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "number",
|
||||
"id": true
|
||||
},
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "number",
|
||||
"id": true
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"required": true
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
},
|
||||
"roleFk": {
|
||||
"type": "number",
|
||||
"mysql": {
|
||||
"columnName": "role"
|
||||
}
|
||||
},
|
||||
"nickname": {
|
||||
"type": "string"
|
||||
},
|
||||
"lang": {
|
||||
"type": "string"
|
||||
},
|
||||
"active": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
"emailVerified": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"created": {
|
||||
"type": "date"
|
||||
},
|
||||
"updated": {
|
||||
"type": "date"
|
||||
},
|
||||
"image": {
|
||||
"type": "string"
|
||||
},
|
||||
"hasGrant": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"type": "string",
|
||||
"required": true
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
},
|
||||
"roleFk": {
|
||||
"type": "number",
|
||||
"mysql": {
|
||||
"columnName": "role"
|
||||
}
|
||||
},
|
||||
"nickname": {
|
||||
"type": "string"
|
||||
},
|
||||
"lang": {
|
||||
"type": "string"
|
||||
},
|
||||
"active": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
"emailVerified": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"created": {
|
||||
"type": "date"
|
||||
},
|
||||
"updated": {
|
||||
"type": "date"
|
||||
},
|
||||
"image": {
|
||||
"type": "string"
|
||||
},
|
||||
"hasGrant": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"passExpired": {
|
||||
"type": "date"
|
||||
},
|
||||
"twoFactor": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
"role": {
|
||||
"type": "belongsTo",
|
||||
"model": "VnRole",
|
||||
"foreignKey": "roleFk"
|
||||
},
|
||||
"roles": {
|
||||
"type": "hasMany",
|
||||
"model": "RoleRole",
|
||||
"foreignKey": "role",
|
||||
"primaryKey": "roleFk"
|
||||
},
|
||||
"emailUser": {
|
||||
"type": "hasOne",
|
||||
"model": "EmailUser",
|
||||
"foreignKey": "userFk"
|
||||
},
|
||||
"worker": {
|
||||
"type": "hasOne",
|
||||
"model": "Worker",
|
||||
"foreignKey": "id"
|
||||
},
|
||||
"userConfig": {
|
||||
"type": "hasOne",
|
||||
"model": "UserConfig",
|
||||
"foreignKey": "userFk"
|
||||
}
|
||||
},
|
||||
"acls": [
|
||||
{
|
||||
"property": "signIn",
|
||||
"accessType": "EXECUTE",
|
||||
"principalType": "ROLE",
|
||||
"principalId": "$everyone",
|
||||
"permission": "ALLOW"
|
||||
}, {
|
||||
"property": "recoverPassword",
|
||||
"accessType": "EXECUTE",
|
||||
"principalType": "ROLE",
|
||||
"principalId": "$everyone",
|
||||
"permission": "ALLOW"
|
||||
}, {
|
||||
"property": "validateAuth",
|
||||
"accessType": "EXECUTE",
|
||||
"principalType": "ROLE",
|
||||
"principalId": "$everyone",
|
||||
"permission": "ALLOW"
|
||||
}, {
|
||||
"property": "privileges",
|
||||
"accessType": "*",
|
||||
"principalType": "ROLE",
|
||||
"principalId": "$authenticated",
|
||||
"permission": "ALLOW"
|
||||
}, {
|
||||
"property": "renewToken",
|
||||
"accessType": "WRITE",
|
||||
"principalType": "ROLE",
|
||||
"principalId": "$authenticated",
|
||||
"permission": "ALLOW"
|
||||
}
|
||||
],
|
||||
"twoFactor": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
"role": {
|
||||
"type": "belongsTo",
|
||||
"model": "VnRole",
|
||||
"foreignKey": "roleFk"
|
||||
},
|
||||
"roles": {
|
||||
"type": "hasMany",
|
||||
"model": "RoleRole",
|
||||
"foreignKey": "role",
|
||||
"primaryKey": "roleFk"
|
||||
},
|
||||
"emailUser": {
|
||||
"type": "hasOne",
|
||||
"model": "EmailUser",
|
||||
"foreignKey": "userFk"
|
||||
},
|
||||
"worker": {
|
||||
"type": "hasOne",
|
||||
"model": "Worker",
|
||||
"foreignKey": "id"
|
||||
},
|
||||
"userConfig": {
|
||||
"type": "hasOne",
|
||||
"model": "UserConfig",
|
||||
"foreignKey": "userFk"
|
||||
}
|
||||
},
|
||||
"acls": [
|
||||
{
|
||||
"property": "signIn",
|
||||
"accessType": "EXECUTE",
|
||||
"principalType": "ROLE",
|
||||
"principalId": "$everyone",
|
||||
"permission": "ALLOW"
|
||||
},
|
||||
{
|
||||
"property": "recoverPassword",
|
||||
"accessType": "EXECUTE",
|
||||
"principalType": "ROLE",
|
||||
"principalId": "$everyone",
|
||||
"permission": "ALLOW"
|
||||
},
|
||||
{
|
||||
"property": "validateAuth",
|
||||
"accessType": "EXECUTE",
|
||||
"principalType": "ROLE",
|
||||
"principalId": "$everyone",
|
||||
"permission": "ALLOW"
|
||||
},
|
||||
{
|
||||
"property": "privileges",
|
||||
"accessType": "*",
|
||||
"principalType": "ROLE",
|
||||
"principalId": "$authenticated",
|
||||
"permission": "ALLOW"
|
||||
},
|
||||
{
|
||||
"property": "renewToken",
|
||||
"accessType": "WRITE",
|
||||
"principalType": "ROLE",
|
||||
"principalId": "$authenticated",
|
||||
"permission": "ALLOW"
|
||||
},
|
||||
{
|
||||
"property": "shareToken",
|
||||
"accessType": "WRITE",
|
||||
"principalType": "ROLE",
|
||||
"principalId": "$authenticated",
|
||||
"permission": "ALLOW"
|
||||
}
|
||||
],
|
||||
"scopes": {
|
||||
"preview": {
|
||||
"fields": [
|
||||
|
@ -140,7 +151,7 @@
|
|||
"hasGrant",
|
||||
"realm",
|
||||
"email",
|
||||
"emailVerified"
|
||||
"emailVerified"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ UPDATE vn.supplier
|
|||
|
||||
UPDATE `vn`.`claimRatio` SET `claimAmount` = '10' WHERE (`clientFk` = '1101');
|
||||
|
||||
INSERT INTO `vn`.`agency` (`name`, `warehouseFk`, `isOwn`, `isAnyVolumeAllowed`)
|
||||
INSERT INTO `vn`.`agency` (`name`, `warehouseFk`, `isOwn`, `isAnyVolumeAllowed`)
|
||||
VALUES
|
||||
('Agencia', '1', '1', '1'),
|
||||
('Otra agencia ', '1', '0', '0');
|
||||
|
|
|
@ -592,13 +592,13 @@ INSERT INTO `vn`.`supplierAccount`(`id`, `supplierFk`, `iban`, `bankEntityFk`)
|
|||
VALUES
|
||||
(241, 442, 'ES111122333344111122221111', 128);
|
||||
|
||||
INSERT INTO `vn`.`company`(`id`, `code`, `supplierAccountFk`, `workerManagerFk`, `companyCode`, `sage200Company`, `expired`, `companyGroupFk`, `phytosanitary` , `clientFk`)
|
||||
INSERT INTO `vn`.`company`(`id`, `code`, `supplierAccountFk`, `workerManagerFk`, `companyCode`, `expired`, `companyGroupFk`, `phytosanitary` , `clientFk`)
|
||||
VALUES
|
||||
(69 , 'CCs', NULL, 30, NULL, 0, NULL, 1, NULL , NULL),
|
||||
(442 , 'VNL', 241, 30, 2 , 1, NULL, 2, 'VNL Company - Plant passport' , 1101),
|
||||
(567 , 'VNH', NULL, 30, NULL, 4, NULL, 1, 'VNH Company - Plant passport' , NULL),
|
||||
(791 , 'FTH', NULL, 30, NULL, 3, '2015-11-30', 1, NULL , NULL),
|
||||
(1381, 'ORN', NULL, 30, NULL, 7, NULL, 1, 'ORN Company - Plant passport' , NULL);
|
||||
(69 , 'CCs', NULL, 30, 0, NULL, 1, NULL , NULL),
|
||||
(442 , 'VNL', 241, 30, 1, NULL, 2, 'VNL Company - Plant passport' , 1101),
|
||||
(567 , 'VNH', NULL, 30, 4, NULL, 1, 'VNH Company - Plant passport' , NULL),
|
||||
(791 , 'FTH', NULL, 30, 3, '2015-11-30', 1, NULL , NULL),
|
||||
(1381, 'ORN', NULL, 30, 7, NULL, 1, 'ORN Company - Plant passport' , NULL);
|
||||
|
||||
INSERT INTO `vn`.`taxArea` (`code`, `claveOperacionFactura`, `CodigoTransaccion`)
|
||||
VALUES
|
||||
|
@ -1491,8 +1491,8 @@ INSERT INTO `bs`.`waste`(`buyer`, `year`, `week`, `family`, `itemFk`, `itemTypeF
|
|||
|
||||
INSERT INTO `vn`.`buy`(`id`,`entryFk`,`itemFk`,`buyingValue`,`quantity`,`packagingFk`,`stickers`,`freightValue`,`packageValue`,`comissionValue`,`packing`,`grouping`,`groupingMode`,`location`,`price1`,`price2`,`price3`, `printedStickers`,`isChecked`,`isIgnored`,`weight`, `created`)
|
||||
VALUES
|
||||
(1, 1, 1, 50, 5000, 4, 1, 1.500, 1.500, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0, 1, 0, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH)),
|
||||
(2, 2, 1, 50, 100, 4, 1, 1.500, 1.500, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0, 1, 0, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH)),
|
||||
(1, 1, 1, 50, 5000, 4, 1, 1.500, 1.500, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0, 1, 0, 1, util.VN_CURDATE() - INTERVAL 2 MONTH),
|
||||
(2, 2, 1, 50, 100, 4, 1, 1.500, 1.500, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0, 1, 0, 1, util.VN_CURDATE() - INTERVAL 1 MONTH),
|
||||
(3, 3, 1, 50, 100, 4, 1, 1.500, 1.500, 0.000, 1, 1, 0, NULL, 0.00, 99.6, 99.4, 0, 1, 0, 1, util.VN_CURDATE()),
|
||||
(4, 2, 2, 5, 450, 3, 1, 1.000, 1.000, 0.000, 10, 10, 0, NULL, 0.00, 7.30, 7.00, 0, 1, 0, 2.5, util.VN_CURDATE()),
|
||||
(5, 3, 3, 55, 500, 5, 1, 1.000, 1.000, 0.000, 1, 1, 0, NULL, 0.00, 78.3, 75.6, 0, 1, 0, 2.5, util.VN_CURDATE()),
|
||||
|
@ -2809,7 +2809,8 @@ INSERT INTO `util`.`notification` (`id`, `name`, `description`)
|
|||
(3, 'not-main-printer-configured', 'A printer distinct than main has been configured'),
|
||||
(4, 'supplier-pay-method-update', 'A supplier pay method has been updated'),
|
||||
(5, 'modified-entry', 'An entry has been modified'),
|
||||
(6, 'book-entry-deleted', 'accounting entries deleted');
|
||||
(6, 'book-entry-deleted', 'accounting entries deleted'),
|
||||
(7, 'zone-included','An email to notify zoneCollisions');
|
||||
|
||||
INSERT INTO `util`.`notificationAcl` (`notificationFk`, `roleFk`)
|
||||
VALUES
|
||||
|
@ -2819,7 +2820,8 @@ INSERT INTO `util`.`notificationAcl` (`notificationFk`, `roleFk`)
|
|||
(3, 9),
|
||||
(4, 1),
|
||||
(5, 9),
|
||||
(6, 9);
|
||||
(6, 9),
|
||||
(7, 9);
|
||||
|
||||
INSERT INTO `util`.`notificationQueue` (`id`, `notificationFk`, `params`, `authorFk`, `status`, `created`)
|
||||
VALUES
|
||||
|
@ -2836,8 +2838,8 @@ INSERT INTO `util`.`notificationSubscription` (`notificationFk`, `userFk`)
|
|||
(2, 1109),
|
||||
(1, 9),
|
||||
(1, 3),
|
||||
(6, 9);
|
||||
|
||||
(6, 9),
|
||||
(7, 9);
|
||||
|
||||
INSERT INTO `vn`.`routeConfig` (`id`, `defaultWorkCenterFk`)
|
||||
VALUES
|
||||
|
|
|
@ -17,13 +17,13 @@ BEGIN
|
|||
e.id accountFk,
|
||||
UCASE(e.name),
|
||||
''
|
||||
FROM expense e
|
||||
FROM vn.expense e
|
||||
UNION
|
||||
SELECT company_getCode(vCompanyFk),
|
||||
a.account,
|
||||
UCASE(a.bank),
|
||||
''
|
||||
FROM accounting a
|
||||
FROM vn.accounting a
|
||||
WHERE a.isActive
|
||||
AND a.`account`
|
||||
UNION
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`root`@`localhost` FUNCTION `vn`.`travel_hasUniqueAwb`(
|
||||
vSelf INT
|
||||
)
|
||||
RETURNS BOOL
|
||||
READS SQL DATA
|
||||
BEGIN
|
||||
/**
|
||||
* Comprueba que el travel pasado tiene un AWB lógico,
|
||||
* no se pueden tener varios AWB asociados al mismo DUA
|
||||
*
|
||||
* @param vSelf Id del travel
|
||||
*/
|
||||
DECLARE vHasUniqueAwb BOOL DEFAULT TRUE;
|
||||
|
||||
SELECT NOT COUNT(t2.awbFk) INTO vHasUniqueAwb
|
||||
FROM entry e
|
||||
JOIN travel t ON t.id = e.travelFk
|
||||
JOIN duaEntry de ON de.entryFk = e.id
|
||||
JOIN duaEntry de2 ON de2.duaFk = de.duaFk
|
||||
JOIN entry e2 ON e2.id = de2.entryFk
|
||||
JOIN travel t2 ON t2.id = e2.travelFk
|
||||
WHERE t.id = vSelf
|
||||
AND t2.awbFk <> t.awbFk;
|
||||
|
||||
RETURN vHasUniqueAwb;
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -1,8 +1,9 @@
|
|||
DELIMITER $$
|
||||
|
||||
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`zone_getCollisions`()
|
||||
BEGIN
|
||||
/**
|
||||
* Calcula si para un mismo codigo postal y dia
|
||||
* Calcula si para un mismo codigo postal y dia
|
||||
* hay mas de una zona configurada y manda correo
|
||||
*
|
||||
*/
|
||||
|
@ -10,17 +11,18 @@ BEGIN
|
|||
DECLARE vZoneFk INT;
|
||||
DECLARE vIsDone INT DEFAULT FALSE;
|
||||
DECLARE vTableCollisions TEXT;
|
||||
DECLARE json_data JSON;
|
||||
DECLARE cur1 CURSOR FOR SELECT zoneFk from tmp.zoneOption;
|
||||
|
||||
|
||||
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vIsDone = TRUE;
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp.zone;
|
||||
CREATE TEMPORARY TABLE tmp.zone
|
||||
SELECT z.id
|
||||
SELECT z.id
|
||||
FROM zone z
|
||||
JOIN agencyMode am ON am.id = z.agencyModeFk
|
||||
JOIN deliveryMethod dm ON dm.id = am.deliveryMethodFk
|
||||
WHERE dm.code IN ('AGENCY','DELIVERY');
|
||||
WHERE dm.code IN ('AGENCY','DELIVERY');
|
||||
|
||||
CALL zone_getOptionsForShipment(util.VN_CURDATE(),FALSE);
|
||||
|
||||
|
@ -35,7 +37,7 @@ BEGIN
|
|||
PRIMARY KEY zoneFkk (zoneFk, geoFk),
|
||||
INDEX(geoFk))
|
||||
ENGINE = MyISAM;
|
||||
|
||||
|
||||
OPEN cur1;
|
||||
cur1Loop: LOOP
|
||||
SET vIsDone = FALSE;
|
||||
|
@ -43,82 +45,63 @@ BEGIN
|
|||
IF vIsDone THEN
|
||||
LEAVE cur1Loop;
|
||||
END IF;
|
||||
|
||||
|
||||
CALL zone_getLeaves(vZoneFk, NULL, NULL, TRUE);
|
||||
|
||||
myLoop: LOOP
|
||||
myLoop: LOOP
|
||||
SET vGeoFk = NULL;
|
||||
SELECT geoFk INTO vGeoFk
|
||||
SELECT geoFk INTO vGeoFk
|
||||
FROM tmp.zoneNodes zn
|
||||
WHERE NOT isChecked
|
||||
LIMIT 1;
|
||||
|
||||
|
||||
IF vGeoFk IS NULL THEN
|
||||
LEAVE myLoop;
|
||||
END IF;
|
||||
|
||||
|
||||
CALL zone_getLeaves(vZoneFk, vGeoFk, NULL, TRUE);
|
||||
UPDATE tmp.zoneNodes
|
||||
SET isChecked = TRUE
|
||||
SET isChecked = TRUE
|
||||
WHERE geoFk = vGeoFk;
|
||||
END LOOP;
|
||||
|
||||
END LOOP;
|
||||
CLOSE cur1;
|
||||
DELETE FROM tmp.zoneNodes
|
||||
DELETE FROM tmp.zoneNodes
|
||||
WHERE sons > 0;
|
||||
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS geoCollision;
|
||||
CREATE TEMPORARY TABLE geoCollision
|
||||
SELECT z.agencyModeFk, zn.geoFk, zw.warehouseFk
|
||||
FROM tmp.zoneNodes zn
|
||||
JOIN zone z ON z.id = zn.zoneFk
|
||||
JOIN zoneWarehouse zw ON z.id = zw.zoneFk
|
||||
JOIN zoneWarehouse zw ON z.id = zw.zoneFk
|
||||
GROUP BY z.agencyModeFk, zn.geoFk, zw.warehouseFk
|
||||
HAVING count(*) > 1;
|
||||
|
||||
SELECT '<table cellspacing="10">
|
||||
<tr>
|
||||
<th>C.Postal</th>
|
||||
<th>Número de zona</th>
|
||||
<th>Precio</th>
|
||||
<th>Zona</th>
|
||||
<th>Almacén</th>
|
||||
<th>Salix</th>
|
||||
</tr>' INTO vTableCollisions;
|
||||
|
||||
INSERT INTO mail (receiver,replyTo,subject,body)
|
||||
SELECT 'pepe@verdnatura.es' receiver,
|
||||
'noreply@verdnatura.es' replyTo,
|
||||
CONCAT('Colisiones en zonas ', util.VN_CURDATE()) subject,
|
||||
CONCAT(vTableCollisions,
|
||||
GROUP_CONCAT(sub.td SEPARATOR ''),
|
||||
'</table>') body
|
||||
FROM(SELECT
|
||||
CONCAT('<tr>
|
||||
<td>', zn.name, '</td>
|
||||
<td>', zoneFk,'</td>
|
||||
<td>', z.price,'</td>
|
||||
<td>', z.name,'</td>
|
||||
<td>', w.name, '</td>
|
||||
<td>', CONCAT('<a href="https://salix.verdnatura.es/#!/zone/',
|
||||
zoneFk,
|
||||
'/location?q=%7B%22search%22:%22',
|
||||
zn.name,
|
||||
'%22%7D">'
|
||||
'https://salix.verdnatura.es/#!/zone/',
|
||||
zoneFk,
|
||||
'/location?q=%7B%22search%22:%22',
|
||||
zn.name,
|
||||
'%22%7D</a>'),'</td>
|
||||
</tr>') td
|
||||
FROM tmp.zoneNodes zn
|
||||
JOIN zone z ON z.id = zn.zoneFk
|
||||
JOIN geoCollision gc ON gc.agencyModeFk = z.agencyModeFk AND zn.geoFk = gc.geoFk
|
||||
JOIN warehouse w ON w.id = gc.warehouseFk) sub;
|
||||
|
||||
DROP TEMPORARY TABLE
|
||||
geoCollision,
|
||||
|
||||
-- Recojo los datos de la zona que ha dado conflicto
|
||||
SELECT JSON_ARRAYAGG(
|
||||
JSON_OBJECT(
|
||||
'zoneFk', zoneFk,
|
||||
'zn', JSON_OBJECT('name', zn.name),
|
||||
'z', JSON_OBJECT('name', z.name,'price', z.price),
|
||||
'w', JSON_OBJECT('name', w.name)
|
||||
)
|
||||
) FROM tmp.zoneNodes zn
|
||||
JOIN zone z ON z.id = zn.zoneFk
|
||||
JOIN geoCollision gc ON gc.agencyModeFk = z.agencyModeFk AND zn.geoFk = gc.geoFk
|
||||
JOIN warehouse w ON w.id = gc.warehouseFk
|
||||
INTO json_data;
|
||||
|
||||
-- Creo un registro de la notificacion 'zone-included' para reportar via email
|
||||
SELECT util.notification_send(
|
||||
'zone-included',
|
||||
JSON_OBJECT('zoneCollisions',json_data),
|
||||
account.myUser_getId()
|
||||
);
|
||||
|
||||
DROP TEMPORARY TABLE
|
||||
geoCollision,
|
||||
tmp.zone,
|
||||
tmp.zoneNodes;
|
||||
END$$
|
||||
|
|
|
@ -7,6 +7,8 @@ BEGIN
|
|||
CALL supplier_checkIsActive(NEW.supplierFk);
|
||||
SET NEW.currencyFk = entry_getCurrency(NEW.currencyFk, NEW.supplierFk);
|
||||
SET NEW.commission = entry_getCommission(NEW.travelFk, NEW.currencyFk,NEW.supplierFk);
|
||||
|
||||
IF NEW.travelFk IS NOT NULL AND NOT travel_hasUniqueAwb(NEW.travelFk) THEN
|
||||
CALL util.throw('The travel is incorrect, there is a different AWB in the associated entries');
|
||||
END IF;
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
|
|
@ -8,13 +8,18 @@ BEGIN
|
|||
DECLARE vHasDistinctWarehouses BOOL;
|
||||
|
||||
SET NEW.editorFk = account.myUser_getId();
|
||||
|
||||
IF NOT (NEW.travelFk <=> OLD.travelFk) THEN
|
||||
|
||||
IF !(NEW.travelFk <=> OLD.travelFk) THEN
|
||||
IF NEW.travelFk IS NOT NULL AND NOT travel_hasUniqueAwb(NEW.travelFk) THEN
|
||||
CALL util.throw('The travel is incorrect, there is a different AWB in the associated entries');
|
||||
END IF;
|
||||
|
||||
SELECT COUNT(*) > 0 INTO vIsVirtual
|
||||
FROM entryVirtual WHERE entryFk = NEW.id;
|
||||
|
||||
SELECT !(o.warehouseInFk <=> n.warehouseInFk)
|
||||
OR !(o.warehouseOutFk <=> n.warehouseOutFk)
|
||||
SELECT NOT (o.warehouseInFk <=> n.warehouseInFk)
|
||||
OR NOT (o.warehouseOutFk <=> n.warehouseOutFk)
|
||||
INTO vHasDistinctWarehouses
|
||||
FROM travel o, travel n
|
||||
WHERE o.id = OLD.travelFk
|
||||
|
@ -43,9 +48,8 @@ BEGIN
|
|||
SET NEW.currencyFk = entry_getCurrency(NEW.currencyFk, NEW.supplierFk);
|
||||
END IF;
|
||||
|
||||
IF NOT (NEW.travelFk <=> OLD.travelFk)
|
||||
OR NOT (NEW.currencyFk <=> OLD.currencyFk) THEN
|
||||
SET NEW.commission = entry_getCommission(NEW.travelFk, NEW.currencyFk,NEW.supplierFk);
|
||||
IF NOT (NEW.travelFk <=> OLD.travelFk) OR NOT (NEW.currencyFk <=> OLD.currencyFk) THEN
|
||||
SET NEW.commission = entry_getCommission(NEW.travelFk, NEW.currencyFk, NEW.supplierFk);
|
||||
END IF;
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
|
|
@ -5,7 +5,7 @@ CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`travel_afterUpdate`
|
|||
BEGIN
|
||||
CALL stock.log_add('travel', NEW.id, OLD.id);
|
||||
|
||||
IF !(NEW.shipped <=> OLD.shipped) THEN
|
||||
IF NOT(NEW.shipped <=> OLD.shipped) THEN
|
||||
UPDATE entry
|
||||
SET commission = entry_getCommission(travelFk, currencyFk,supplierFk)
|
||||
WHERE travelFk = NEW.id;
|
||||
|
@ -23,5 +23,9 @@ BEGIN
|
|||
CALL buy_checkItem();
|
||||
END IF;
|
||||
END IF;
|
||||
|
||||
IF (NOT(NEW.awbFk <=> OLD.awbFk)) AND NEW.awbFk IS NOT NULL AND NOT travel_hasUniqueAwb(NEW.id) THEN
|
||||
CALL util.throw('The AWB is incorrect, there is a different AWB in the associated entries');
|
||||
END IF;
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
|
|
@ -8,5 +8,9 @@ BEGIN
|
|||
CALL travel_checkDates(NEW.shipped, NEW.landed);
|
||||
|
||||
CALL travel_checkWarehouseIsFeedStock(NEW.warehouseInFk);
|
||||
|
||||
IF NEW.awbFk IS NOT NULL AND NOT travel_hasUniqueAwb(NEW.id) THEN
|
||||
CALL util.throw('The AWB is incorrect, there is a different AWB in the associated entries');
|
||||
END IF;
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
|
|
@ -8,5 +8,6 @@ BEGIN
|
|||
`changedModel` = 'zoneIncluded',
|
||||
`changedModelId` = OLD.zoneFk,
|
||||
`userFk` = account.myUser_getId();
|
||||
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
|
|
@ -4,5 +4,6 @@ CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`zoneIncluded_beforeIn
|
|||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.editorFk = account.myUser_getId();
|
||||
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
|
|
@ -4,5 +4,6 @@ CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`zoneIncluded_beforeUp
|
|||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.editorFk = account.myUser_getId();
|
||||
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE util.notification MODIFY COLUMN id int(11) auto_increment NOT NULL;
|
|
@ -0,0 +1,15 @@
|
|||
INSERT IGNORE INTO util.notification ( `name`,`description`)
|
||||
VALUES
|
||||
( 'zone-included','An email to notify zoneCollisions');
|
||||
|
||||
-- Change value if destionation user should be different
|
||||
SET @DESTINATION_USER = "pepe";
|
||||
|
||||
SET @MaxId = LAST_INSERT_ID();
|
||||
|
||||
INSERT IGNORE INTO util.notificationSubscription (notificationFk,userFk)
|
||||
VALUES(
|
||||
@MaxId, (SELECT id from `account`.`user` where name = @DESTINATION_USER));
|
||||
|
||||
INSERT IGNORE INTO util.notificationAcl (notificationFk,roleFk)
|
||||
SELECT @MaxId, (SELECT role from `account`.`user` where name = @DESTINATION_USER) FROM util.notification WHERE name= "zone-included";
|
|
@ -0,0 +1,73 @@
|
|||
-- Auto-generated SQL script #202403061303
|
||||
UPDATE vn.company
|
||||
SET companyCode=0
|
||||
WHERE id=69;
|
||||
UPDATE vn.company
|
||||
SET companyCode=1
|
||||
WHERE id=442;
|
||||
UPDATE vn.company
|
||||
SET companyCode=4
|
||||
WHERE id=567;
|
||||
UPDATE vn.company
|
||||
SET companyCode=2
|
||||
WHERE id=791;
|
||||
UPDATE vn.company
|
||||
SET companyCode=3
|
||||
WHERE id=792;
|
||||
UPDATE vn.company
|
||||
SET companyCode=5
|
||||
WHERE id=965;
|
||||
UPDATE vn.company
|
||||
SET companyCode=7
|
||||
WHERE id=1381;
|
||||
UPDATE vn.company
|
||||
SET companyCode=3
|
||||
WHERE id=1463;
|
||||
UPDATE vn.company
|
||||
SET companyCode=8
|
||||
WHERE id=2142;
|
||||
UPDATE vn.company
|
||||
SET companyCode=6
|
||||
WHERE id=2393;
|
||||
UPDATE vn.company
|
||||
SET companyCode=9
|
||||
WHERE id=3869;
|
||||
|
||||
-- Auto-generated SQL script #202403061311
|
||||
UPDATE vn.company
|
||||
SET sage200Company=NULL
|
||||
WHERE id=69;
|
||||
UPDATE vn.company
|
||||
SET sage200Company=NULL
|
||||
WHERE id=442;
|
||||
UPDATE vn.company
|
||||
SET sage200Company=NULL
|
||||
WHERE id=567;
|
||||
UPDATE vn.company
|
||||
SET sage200Company=NULL
|
||||
WHERE id=791;
|
||||
UPDATE vn.company
|
||||
SET sage200Company=NULL
|
||||
WHERE id=792;
|
||||
UPDATE vn.company
|
||||
SET sage200Company=NULL
|
||||
WHERE id=965;
|
||||
UPDATE vn.company
|
||||
SET sage200Company=NULL
|
||||
WHERE id=1381;
|
||||
UPDATE vn.company
|
||||
SET sage200Company=NULL
|
||||
WHERE id=1463;
|
||||
UPDATE vn.company
|
||||
SET sage200Company=NULL
|
||||
WHERE id=2142;
|
||||
UPDATE vn.company
|
||||
SET sage200Company=NULL
|
||||
WHERE id=2393;
|
||||
UPDATE vn.company
|
||||
SET sage200Company=NULL
|
||||
WHERE id=3869;
|
||||
|
||||
|
||||
ALTER TABLE vn.company CHANGE sage200Company sage200Company__ int(2) DEFAULT NULL NULL COMMENT '@deprecated 06/03/2024';
|
||||
ALTER TABLE vn.company MODIFY COLUMN sage200Company__ int(2) DEFAULT NULL NULL COMMENT '@deprecated 06/03/2024';
|
|
@ -0,0 +1,3 @@
|
|||
-- Place your SQL code here
|
||||
|
||||
|
|
@ -83,22 +83,27 @@ export default class Auth {
|
|||
}
|
||||
|
||||
onLoginOk(json, now, remember) {
|
||||
this.vnToken.set(json.data.token, now, json.data.ttl, remember);
|
||||
|
||||
return this.loadAcls().then(() => {
|
||||
let continueHash = this.$state.params.continue;
|
||||
if (continueHash)
|
||||
this.$window.location = continueHash;
|
||||
else
|
||||
this.$state.go('home');
|
||||
});
|
||||
return this.$http.get('VnUsers/ShareToken', {
|
||||
headers: {Authorization: json.data.token}
|
||||
}).then(({data}) => {
|
||||
this.vnToken.set(json.data.token, data.multimediaToken.id, now, json.data.ttl, remember);
|
||||
this.loadAcls().then(() => {
|
||||
let continueHash = this.$state.params.continue;
|
||||
if (continueHash)
|
||||
this.$window.location = continueHash;
|
||||
else
|
||||
this.$state.go('home');
|
||||
});
|
||||
}).catch(() => {});
|
||||
}
|
||||
|
||||
logout() {
|
||||
this.$http.post('Accounts/logout', null, {headers: {'Authorization': this.vnToken.tokenMultimedia},
|
||||
}).catch(() => {});
|
||||
|
||||
let promise = this.$http.post('VnUsers/logout', null, {
|
||||
headers: {Authorization: this.vnToken.token}
|
||||
}).catch(() => {});
|
||||
|
||||
this.vnToken.unset();
|
||||
this.loggedIn = false;
|
||||
this.vnModules.reset();
|
||||
|
|
|
@ -19,7 +19,7 @@ function interceptor($q, vnApp, $translate) {
|
|||
|
||||
if (config.url.charAt(0) !== '/' && apiPath)
|
||||
config.url = `${apiPath}${config.url}`;
|
||||
if (token)
|
||||
if (token && !config.headers.Authorization)
|
||||
config.headers.Authorization = token;
|
||||
if ($translate.use())
|
||||
config.headers['Accept-Language'] = $translate.use();
|
||||
|
|
|
@ -24,21 +24,22 @@ export default class Token {
|
|||
} catch (e) {}
|
||||
}
|
||||
|
||||
set(token, created, ttl, remember) {
|
||||
set(token, tokenMultimedia, created, ttl, remember) {
|
||||
this.unset();
|
||||
|
||||
Object.assign(this, {
|
||||
token,
|
||||
tokenMultimedia,
|
||||
created,
|
||||
ttl,
|
||||
remember
|
||||
});
|
||||
this.vnInterceptor.setToken(token);
|
||||
this.vnInterceptor.setToken(token, tokenMultimedia);
|
||||
try {
|
||||
if (remember)
|
||||
this.setStorage(localStorage, token, created, ttl);
|
||||
this.setStorage(localStorage, token, tokenMultimedia, created, ttl);
|
||||
else
|
||||
this.setStorage(sessionStorage, token, created, ttl);
|
||||
this.setStorage(sessionStorage, token, tokenMultimedia, created, ttl);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
|
@ -46,6 +47,7 @@ export default class Token {
|
|||
|
||||
unset() {
|
||||
this.token = null;
|
||||
this.tokenMultimedia = null;
|
||||
this.created = null;
|
||||
this.ttl = null;
|
||||
this.remember = null;
|
||||
|
@ -57,13 +59,15 @@ export default class Token {
|
|||
|
||||
getStorage(storage) {
|
||||
this.token = storage.getItem('vnToken');
|
||||
this.tokenMultimedia = storage.getItem('vnTokenMultimedia');
|
||||
if (!this.token) return;
|
||||
const created = storage.getItem('vnTokenCreated');
|
||||
this.created = created && new Date(created);
|
||||
this.ttl = storage.getItem('vnTokenTtl');
|
||||
}
|
||||
|
||||
setStorage(storage, token, created, ttl) {
|
||||
setStorage(storage, token, tokenMultimedia, created, ttl) {
|
||||
storage.setItem('vnTokenMultimedia', tokenMultimedia);
|
||||
storage.setItem('vnToken', token);
|
||||
storage.setItem('vnTokenCreated', created.toJSON());
|
||||
storage.setItem('vnTokenTtl', ttl);
|
||||
|
@ -71,6 +75,7 @@ export default class Token {
|
|||
|
||||
removeStorage(storage) {
|
||||
storage.removeItem('vnToken');
|
||||
storage.removeItem('vnTokenMultimedia');
|
||||
storage.removeItem('vnTokenCreated');
|
||||
storage.removeItem('vnTokenTtl');
|
||||
}
|
||||
|
|
|
@ -23,8 +23,7 @@ export class Layout extends Component {
|
|||
if (!this.$.$root.user) return;
|
||||
|
||||
const userId = this.$.$root.user.id;
|
||||
const token = this.vnToken.token;
|
||||
return `/api/Images/user/160x160/${userId}/download?access_token=${token}`;
|
||||
return `/api/Images/user/160x160/${userId}/download?access_token=${this.vnToken.tokenMultimedia}`;
|
||||
}
|
||||
|
||||
refresh() {
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
ng-click="$ctrl.showDescriptor($event, userLog)">
|
||||
<img
|
||||
ng-if="::userLog.user.image"
|
||||
ng-src="/api/Images/user/160x160/{{::userLog.userFk}}/download?access_token={{::$ctrl.vnToken.token}}">
|
||||
ng-src="/api/Images/user/160x160/{{::userLog.userFk}}/download?access_token={{::$ctrl.vnToken.tokenMultimedia}}">
|
||||
</img>
|
||||
</vn-avatar>
|
||||
</div>
|
||||
|
@ -181,7 +181,7 @@
|
|||
val="{{::nickname}}">
|
||||
<img
|
||||
ng-if="::image"
|
||||
ng-src="/api/Images/user/160x160/{{::id}}/download?access_token={{::$ctrl.vnToken.token}}">
|
||||
ng-src="/api/Images/user/160x160/{{::id}}/download?access_token={{::$ctrl.vnToken.tokenMultimedia}}">
|
||||
</img>
|
||||
</vn-avatar>
|
||||
<div>
|
||||
|
|
|
@ -13,7 +13,7 @@ export function run($window, $rootScope, vnAuth, vnApp, vnToken, $state) {
|
|||
if (!collection || !size || !id) return;
|
||||
|
||||
const basePath = `/api/Images/${collection}/${size}/${id}`;
|
||||
return `${basePath}/download?access_token=${vnToken.token}`;
|
||||
return `${basePath}/download?access_token=${vnToken.tokenMultimedia}`;
|
||||
};
|
||||
|
||||
$window.validations = {};
|
||||
|
|
|
@ -220,5 +220,7 @@
|
|||
"Shelving not valid": "Shelving not valid",
|
||||
"printerNotExists": "The printer does not exist",
|
||||
"There are not picking tickets": "There are not picking tickets",
|
||||
"ticketCommercial": "The ticket {{ ticket }} for the salesperson {{ salesMan }} is in preparation. (automatically generated message)"
|
||||
"ticketCommercial": "The ticket {{ ticket }} for the salesperson {{ salesMan }} is in preparation. (automatically generated message)",
|
||||
"This password can only be changed by the user themselves": "This password can only be changed by the user themselves",
|
||||
"They're not your subordinate": "They're not your subordinate"
|
||||
}
|
||||
|
|
|
@ -346,5 +346,7 @@
|
|||
"CountryFK cannot be empty": "El país no puede estar vacío",
|
||||
"Cmr file does not exist": "El archivo del cmr no existe",
|
||||
"You are not allowed to modify the alias": "No estás autorizado a modificar el alias",
|
||||
"The address of the customer must have information about Incoterms and Customs Agent": "El consignatario del cliente debe tener informado Incoterms y Agente de aduanas"
|
||||
}
|
||||
"The address of the customer must have information about Incoterms and Customs Agent": "El consignatario del cliente debe tener informado Incoterms y Agente de aduanas",
|
||||
"This password can only be changed by the user themselves": "Esta contraseña solo puede ser modificada por el propio usuario",
|
||||
"They're not your subordinate": "No es tu subordinado/a."
|
||||
}
|
||||
|
|
|
@ -15,7 +15,8 @@ module.exports = Self => {
|
|||
http: {
|
||||
path: `/logout`,
|
||||
verb: 'POST'
|
||||
}
|
||||
},
|
||||
accessScopes: ['DEFAULT', 'read:multimedia']
|
||||
});
|
||||
|
||||
Self.logout = async ctx => Self.app.models.VnUser.logout(ctx.req.accessToken.id);
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
|
||||
const ForbiddenError = require('vn-loopback/util/forbiddenError');
|
||||
const {models} = require('vn-loopback/server/server');
|
||||
|
||||
module.exports = Self => {
|
||||
require('../methods/account/sync')(Self);
|
||||
require('../methods/account/sync-by-id')(Self);
|
||||
|
@ -7,4 +10,11 @@ module.exports = Self => {
|
|||
require('../methods/account/logout')(Self);
|
||||
require('../methods/account/change-password')(Self);
|
||||
require('../methods/account/set-password')(Self);
|
||||
|
||||
Self.setUnverifiedPassword = async(id, pass, options) => {
|
||||
const {emailVerified} = await models.VnUser.findById(id, {fields: ['emailVerified']}, options);
|
||||
if (emailVerified) throw new ForbiddenError('This password can only be changed by the user themselves');
|
||||
|
||||
await models.VnUser.setPassword(id, pass, options);
|
||||
};
|
||||
};
|
||||
|
|
|
@ -32,7 +32,8 @@ module.exports = Self => {
|
|||
http: {
|
||||
path: `/:id/downloadFile`,
|
||||
verb: 'GET'
|
||||
}
|
||||
},
|
||||
accessScopes: ['read:multimedia']
|
||||
});
|
||||
|
||||
Self.downloadFile = async function(ctx, id) {
|
||||
|
|
|
@ -114,7 +114,7 @@
|
|||
<vn-td center shrink>
|
||||
<a ng-show="balance.hasPdf"
|
||||
target="_blank"
|
||||
href="api/InvoiceOuts/{{::balance.id}}/download?access_token={{::$ctrl.vnToken.token}}">
|
||||
href="api/InvoiceOuts/{{::balance.id}}/download?access_token={{::$ctrl.vnToken.tokenMultimedia}}">
|
||||
<vn-icon-button
|
||||
icon="cloud_download"
|
||||
title="{{'Download PDF' | translate}}">
|
||||
|
|
|
@ -31,7 +31,8 @@ module.exports = Self => {
|
|||
http: {
|
||||
path: '/:id/download',
|
||||
verb: 'GET'
|
||||
}
|
||||
},
|
||||
accessScopes: ['read:multimedia']
|
||||
});
|
||||
|
||||
Self.download = async function(ctx, id, options) {
|
||||
|
|
|
@ -31,7 +31,8 @@ module.exports = Self => {
|
|||
http: {
|
||||
path: '/downloadZip',
|
||||
verb: 'GET'
|
||||
}
|
||||
},
|
||||
accessScopes: ['read:multimedia']
|
||||
});
|
||||
|
||||
Self.downloadZip = async function(ctx, ids, options) {
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
<vn-menu vn-id="showInvoiceMenu">
|
||||
<vn-list>
|
||||
<a class="vn-item"
|
||||
href="api/InvoiceOuts/{{$ctrl.id}}/download?access_token={{$ctrl.vnToken.token}}"
|
||||
href="api/InvoiceOuts/{{$ctrl.id}}/download?access_token={{$ctrl.vnToken.tokenMultimedia}}"
|
||||
target="_blank"
|
||||
name="showInvoicePdf"
|
||||
translate>
|
||||
|
|
|
@ -25,7 +25,7 @@ export default class Controller extends Section {
|
|||
openPdf() {
|
||||
if (this.checked.length <= 1) {
|
||||
const [invoiceOutId] = this.checked;
|
||||
const url = `api/InvoiceOuts/${invoiceOutId}/download?access_token=${this.vnToken.token}`;
|
||||
const url = `api/InvoiceOuts/${invoiceOutId}/download?access_token=${this.vnToken.tokenMultimedia}`;
|
||||
window.open(url, '_blank');
|
||||
} else {
|
||||
const invoiceOutIds = this.checked;
|
||||
|
|
|
@ -11,6 +11,7 @@ module.exports = Self => {
|
|||
path: `/download`,
|
||||
verb: 'POST',
|
||||
},
|
||||
accessScopes: ['read:multimedia']
|
||||
});
|
||||
|
||||
Self.download = async() => {
|
||||
|
|
|
@ -29,7 +29,8 @@ module.exports = Self => {
|
|||
http: {
|
||||
path: '/downloadCmrsZip',
|
||||
verb: 'GET'
|
||||
}
|
||||
},
|
||||
accessScopes: ['read:multimedia']
|
||||
});
|
||||
|
||||
Self.downloadCmrsZip = async function(ctx, ids, options) {
|
||||
|
|
|
@ -29,7 +29,8 @@ module.exports = Self => {
|
|||
http: {
|
||||
path: '/downloadZip',
|
||||
verb: 'GET'
|
||||
}
|
||||
},
|
||||
accessScopes: ['read:multimedia']
|
||||
});
|
||||
|
||||
Self.downloadZip = async function(ctx, id, options) {
|
||||
|
|
|
@ -34,7 +34,9 @@ module.exports = Self => {
|
|||
http: {
|
||||
path: '/:id/driver-route-pdf',
|
||||
verb: 'GET'
|
||||
}
|
||||
},
|
||||
accessScopes: ['read:multimedia']
|
||||
|
||||
});
|
||||
|
||||
Self.driverRoutePdf = (ctx, id) => Self.printReport(ctx, id, 'driver-route');
|
||||
|
|
|
@ -40,7 +40,7 @@ export default class Controller extends Section {
|
|||
const stringRoutesIds = routesIds.join(',');
|
||||
|
||||
if (this.checked.length <= 1) {
|
||||
const url = `api/Routes/${stringRoutesIds}/driver-route-pdf?access_token=${this.vnToken.token}`;
|
||||
const url = `api/Routes/${stringRoutesIds}/driver-route-pdf?access_token=${this.vnToken.tokenMultimedia}`;
|
||||
window.open(url, '_blank');
|
||||
} else {
|
||||
const serializedParams = this.$httpParamSerializer({
|
||||
|
|
|
@ -29,7 +29,8 @@ module.exports = Self => {
|
|||
http: {
|
||||
path: `/:id/downloadFile`,
|
||||
verb: 'GET'
|
||||
}
|
||||
},
|
||||
accessScopes: ['read:multimedia']
|
||||
});
|
||||
|
||||
Self.downloadFile = async function(ctx, id) {
|
||||
|
|
|
@ -1,31 +1,29 @@
|
|||
const UserError = require('vn-loopback/util/user-error');
|
||||
const ForbiddenError = require('vn-loopback/util/forbiddenError');
|
||||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('setPassword', {
|
||||
description: 'Set a new password',
|
||||
accepts: [
|
||||
{
|
||||
arg: 'workerFk',
|
||||
type: 'number',
|
||||
required: true,
|
||||
description: 'The worker id',
|
||||
},
|
||||
{
|
||||
arg: 'newPass',
|
||||
type: 'String',
|
||||
required: true,
|
||||
description: 'The new worker password'
|
||||
}
|
||||
],
|
||||
accepts: [{
|
||||
arg: 'id',
|
||||
type: 'number',
|
||||
required: true,
|
||||
description: 'The worker id',
|
||||
http: {source: 'path'}
|
||||
}, {
|
||||
arg: 'newPass',
|
||||
type: 'String',
|
||||
required: true,
|
||||
description: 'The new worker password'
|
||||
}],
|
||||
http: {
|
||||
path: `/:id/setPassword`,
|
||||
verb: 'PATCH'
|
||||
}
|
||||
});
|
||||
Self.setPassword = async(ctx, options) => {
|
||||
Self.setPassword = async(ctx, id, newPass, options) => {
|
||||
const models = Self.app.models;
|
||||
const myOptions = {};
|
||||
const {args} = ctx;
|
||||
let tx;
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
if (!myOptions.transaction) {
|
||||
|
@ -33,11 +31,10 @@ module.exports = Self => {
|
|||
myOptions.transaction = tx;
|
||||
}
|
||||
try {
|
||||
const isSubordinate = await models.Worker.isSubordinate(ctx, args.workerFk, myOptions);
|
||||
if (!isSubordinate) throw new UserError('You don\'t have enough privileges.');
|
||||
const isSubordinate = await Self.isSubordinate(ctx, id, myOptions);
|
||||
if (!isSubordinate) throw new ForbiddenError('They\'re not your subordinate');
|
||||
|
||||
await models.VnUser.setPassword(args.workerFk, args.newPass, myOptions);
|
||||
await models.VnUser.updateAll({id: args.workerFk}, {emailVerified: true}, myOptions);
|
||||
await models.Account.setUnverifiedPassword(id, newPass, myOptions);
|
||||
|
||||
if (tx) await tx.commit();
|
||||
} catch (e) {
|
||||
|
|
|
@ -1,31 +1,30 @@
|
|||
const UserError = require('vn-loopback/util/user-error');
|
||||
|
||||
const models = require('vn-loopback/server/server').models;
|
||||
const {models} = require('vn-loopback/server/server');
|
||||
|
||||
describe('worker setPassword()', () => {
|
||||
let ctx;
|
||||
const newPass = 'H3rn4d3z#';
|
||||
const employeeId = 1;
|
||||
const managerId = 20;
|
||||
const administrativeId = 5;
|
||||
|
||||
beforeAll(() => {
|
||||
ctx = {
|
||||
req: {
|
||||
accessToken: {},
|
||||
accessToken: {userId: managerId},
|
||||
headers: {origin: 'http://localhost'}
|
||||
},
|
||||
args: {workerFk: 9}
|
||||
};
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
ctx.req.accessToken.userId = 20;
|
||||
ctx.args.newPass = 'H3rn4d3z#';
|
||||
});
|
||||
|
||||
it('should change the password', async() => {
|
||||
it('should change the password if it is a subordinate and the email is not verified', async() => {
|
||||
const tx = await models.Worker.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
await models.Worker.setPassword(ctx, options);
|
||||
await models.Worker.setPassword(ctx, employeeId, newPass, options);
|
||||
const isNewPass = await passHasBeenChanged(employeeId, newPass, options);
|
||||
|
||||
expect(isNewPass).toBeTrue();
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
|
@ -33,29 +32,48 @@ describe('worker setPassword()', () => {
|
|||
}
|
||||
});
|
||||
|
||||
it('should throw an error: Password does not meet requirements', async() => {
|
||||
const tx = await models.Collection.beginTransaction({});
|
||||
ctx.args.newPass = 'Hi';
|
||||
it('should not change the password if it is a subordinate and the email is verified', async() => {
|
||||
const tx = await models.Worker.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
await models.Worker.setPassword(ctx, options);
|
||||
await models.VnUser.updateAll({id: employeeId}, {emailVerified: true}, options);
|
||||
await models.Worker.setPassword(ctx, employeeId, newPass, options);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
expect(e.message).toEqual(`This password can only be changed by the user themselves`);
|
||||
await tx.rollback();
|
||||
}
|
||||
});
|
||||
|
||||
it('should not change the password if it is not a subordinate', async() => {
|
||||
const tx = await models.Worker.beginTransaction({});
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
await models.Worker.setPassword(ctx, administrativeId, newPass, options);
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
expect(e.message).toEqual(`They're not your subordinate`);
|
||||
await tx.rollback();
|
||||
}
|
||||
});
|
||||
|
||||
it('should throw an error: Password does not meet requirements', async() => {
|
||||
const tx = await models.Worker.beginTransaction({});
|
||||
const newPass = 'Hi';
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
await models.Worker.setPassword(ctx, employeeId, newPass, options);
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
expect(e.sqlMessage).toEqual('Password does not meet requirements');
|
||||
await tx.rollback();
|
||||
}
|
||||
});
|
||||
|
||||
it('should throw an error: You don\'t have enough privileges.', async() => {
|
||||
ctx.req.accessToken.userId = 5;
|
||||
const tx = await models.Collection.beginTransaction({});
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
await models.Worker.setPassword(ctx, options);
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
expect(e).toEqual(new UserError(`You don't have enough privileges.`));
|
||||
await tx.rollback();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const passHasBeenChanged = async(userId, pass, options) => {
|
||||
const user = await models.VnUser.findById(userId, null, options);
|
||||
return user.hasPassword(pass);
|
||||
};
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
? 'Click to allow the user to be disabled'
|
||||
: 'Click to exclude the user from getting disabled'}}
|
||||
</vn-item>
|
||||
<vn-item ng-if="!$ctrl.worker.user.emailVerified" ng-click="setPassword.show()" translate>
|
||||
Change password
|
||||
<vn-item ng-if="!$ctrl.worker.user.emailVerified && $ctrl.vnConfig.storage.currentUserWorkerId !=$ctrl.worker.id" ng-click="setPassword.show()" translate>
|
||||
Change password
|
||||
</vn-item>
|
||||
</slot-menu>
|
||||
<slot-body>
|
||||
|
|
|
@ -69,6 +69,7 @@ class Controller extends Descriptor {
|
|||
}
|
||||
]
|
||||
};
|
||||
|
||||
return this.getData(`Workers/${this.id}`, {filter})
|
||||
.then(res => this.entity = res.data);
|
||||
}
|
||||
|
@ -86,15 +87,14 @@ class Controller extends Descriptor {
|
|||
if (this.newPassword != this.repeatPassword)
|
||||
throw new UserError(`Passwords don't match`);
|
||||
this.$http.patch(
|
||||
`Workers/${this.entity.id}/setPassword`,
|
||||
{workerFk: this.entity.id, newPass: this.newPassword}
|
||||
`Workers/${this.entity.id}/setPassword`, {newPass: this.newPassword}
|
||||
) .then(() => {
|
||||
this.vnApp.showSuccess(this.$translate.instant('Password changed!'));
|
||||
});
|
||||
}).then(() => this.loadData());
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$element', '$scope', '$rootScope'];
|
||||
Controller.$inject = ['$element', '$scope', '$rootScope', 'vnConfig'];
|
||||
|
||||
ngModule.vnComponent('vnWorkerDescriptor', {
|
||||
template: require('./index.html'),
|
||||
|
|
|
@ -16,6 +16,7 @@ describe('vnWorkerDescriptor', () => {
|
|||
const id = 1;
|
||||
const response = 'foo';
|
||||
|
||||
$httpBackend.whenGET('UserConfigs/getUserConfig').respond({});
|
||||
$httpBackend.expectRoute('GET', `Workers/${id}`).respond(response);
|
||||
controller.id = id;
|
||||
$httpBackend.flush();
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
const models = require('vn-loopback/server/server').models;
|
||||
const LoopBackContext = require('loopback-context');
|
||||
|
||||
describe('zone toggleIsIncluded()', () => {
|
||||
beforeAll(async() => {
|
||||
const activeCtx = {
|
||||
|
@ -58,7 +57,7 @@ describe('zone toggleIsIncluded()', () => {
|
|||
|
||||
await models.Zone.toggleIsIncluded(1, 20, false, options);
|
||||
|
||||
let result = await models.Zone.toggleIsIncluded(1, 20, undefined, options);
|
||||
const result = await models.Zone.toggleIsIncluded(1, 20, undefined, options);
|
||||
|
||||
expect(result).toEqual({count: 1});
|
||||
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
"dataSource": "vn"
|
||||
},
|
||||
"AgencyMode": {
|
||||
"dataSource": "vn"
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"DeliveryMethod": {
|
||||
"dataSource": "vn"
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"Zone": {
|
||||
"dataSource": "vn"
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
const Stylesheet = require(`vn-print/core/stylesheet`);
|
||||
|
||||
const path = require('path');
|
||||
const vnPrintPath = path.resolve('print');
|
||||
|
||||
module.exports = new Stylesheet([
|
||||
`${vnPrintPath}/common/css/spacing.css`,
|
||||
`${vnPrintPath}/common/css/misc.css`,
|
||||
`${vnPrintPath}/common/css/layout.css`,
|
||||
`${vnPrintPath}/common/css/email.css`])
|
||||
.mergeStyles();
|
|
@ -0,0 +1,7 @@
|
|||
subject: Colisiones en zonas
|
||||
title: "La zona {0} y localización {1} ha sido registrada en más de un sitio"
|
||||
postalCode: C. Postal
|
||||
zoneFk: Número de zona
|
||||
price: Precio
|
||||
zone: Zona
|
||||
warehouse: Almacén
|
|
@ -0,0 +1,42 @@
|
|||
<!DOCTYPE html>
|
||||
<html v-bind:lang="$i18n.locale">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<meta name="format-detection" content="telephone=no" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table class="grid column-oriented">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ $t('postalCode') }}</th>
|
||||
<th>{{ $t('zoneFk') }}</th>
|
||||
<th>{{ $t('price') }}</th>
|
||||
<th>{{ $t('zone') }}</th>
|
||||
<th>{{ $t('warehouse') }}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="zone in zoneCollisions">
|
||||
<td>{{ zone.zn.name }}</td>
|
||||
<td>{{ zone.zoneFk }}</td>
|
||||
<td>{{ zone.z.price }}</td>
|
||||
<td>{{ zone.z.name }}</td>
|
||||
<td>{{ zone.w.name }}</td>
|
||||
<td>
|
||||
<a v-bind:href="'https://salix.verdnatura.es/#!/zone/'+
|
||||
zone.zoneFk+
|
||||
'/location?q=%7B%22search%22:%22'+
|
||||
zone.zn.name+
|
||||
'%22%7D'">
|
||||
https://salix.verdnatura.es/#!/zone/
|
||||
{{zone.zoneFk}}
|
||||
/location?q=%7B%22search%22:%22
|
||||
{{zone.zn.name}}
|
||||
%22%7D</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,12 @@
|
|||
const Component = require(`vn-print/core/component`);
|
||||
const emailHeader = new Component('email-header');
|
||||
|
||||
module.exports = {
|
||||
name: 'zone-included',
|
||||
components: {
|
||||
'email-header': emailHeader.build(),
|
||||
},
|
||||
props: {
|
||||
zoneCollisions: {type: Array, required: true}
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue