From 0579c563b95757fb3fba0eaca92996a39c265643 Mon Sep 17 00:00:00 2001 From: vicent Date: Wed, 22 Mar 2023 15:03:12 +0100 Subject: [PATCH 01/61] refs #5327 ordernar por columnas --- .../ticket/back/methods/ticket/getSales.js | 37 ++++++++++++++----- modules/ticket/front/sale/index.html | 18 ++++----- 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/modules/ticket/back/methods/ticket/getSales.js b/modules/ticket/back/methods/ticket/getSales.js index 321e8e24e..17261f6fc 100644 --- a/modules/ticket/back/methods/ticket/getSales.js +++ b/modules/ticket/back/methods/ticket/getSales.js @@ -3,13 +3,20 @@ module.exports = Self => { Self.remoteMethod('getSales', { description: 'New filter', accessType: 'READ', - accepts: [{ - arg: 'id', - type: 'number', - required: true, - description: 'The ticket id', - http: {source: 'path'} - }], + accepts: [ + { + arg: 'filter', + type: 'object', + description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string', + http: {source: 'query'} + }, + { + arg: 'id', + type: 'number', + required: true, + description: 'The ticket id', + http: {source: 'path'} + }], returns: { type: ['object'], root: true @@ -20,14 +27,24 @@ module.exports = Self => { } }); - Self.getSales = async(id, options) => { + Self.getSales = async(filter, id, options) => { const models = Self.app.models; - const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); + // let newFilter; + // if (filter && filter.order) { + // const filterOrder = filter.order; + // const saleColumns = ['itemFk', 'quantity', 'concept', 'price', 'discount']; + + // for (const saleColum of saleColumns) { + // if (filterOrder.includes(saleColum)) return newFilter = filter.order; + // else newFilter = 'concept'; + // } + // } + // console.log(newFilter); const sales = await models.Sale.find({ include: { relation: 'item', @@ -53,7 +70,7 @@ module.exports = Self => { } }, where: {ticketFk: id}, - order: 'concept' + order: newFilter }, myOptions); // Get items available diff --git a/modules/ticket/front/sale/index.html b/modules/ticket/front/sale/index.html index 8764417a8..74cb101f4 100644 --- a/modules/ticket/front/sale/index.html +++ b/modules/ticket/front/sale/index.html @@ -60,15 +60,15 @@ - Visible - Available - Id - Quantity - Item - Price - Disc - Amount - Packaging + Visible + Available + Id + Quantity + Item + Price + Disc + Amount + Packaging From 34126119e2c0cd43a220b07fe573c650f59a8986 Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 23 Mar 2023 09:02:22 +0100 Subject: [PATCH 02/61] fix errors --- modules/ticket/back/methods/ticket/getSales.js | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/modules/ticket/back/methods/ticket/getSales.js b/modules/ticket/back/methods/ticket/getSales.js index 17261f6fc..e3d6af389 100644 --- a/modules/ticket/back/methods/ticket/getSales.js +++ b/modules/ticket/back/methods/ticket/getSales.js @@ -29,22 +29,13 @@ module.exports = Self => { Self.getSales = async(filter, id, options) => { const models = Self.app.models; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); - // let newFilter; - // if (filter && filter.order) { - // const filterOrder = filter.order; - // const saleColumns = ['itemFk', 'quantity', 'concept', 'price', 'discount']; - - // for (const saleColum of saleColumns) { - // if (filterOrder.includes(saleColum)) return newFilter = filter.order; - // else newFilter = 'concept'; - // } - // } - // console.log(newFilter); + console.log(filter); const sales = await models.Sale.find({ include: { relation: 'item', @@ -70,7 +61,7 @@ module.exports = Self => { } }, where: {ticketFk: id}, - order: newFilter + order: 'concept' }, myOptions); // Get items available @@ -126,7 +117,7 @@ module.exports = Self => { if (salesWithLogs.includes(sale.id)) sale.$hasLogs = true; } - + console.log(sales); return sales; }; }; From faab024e24ba61ed6095cc7e7796025642514e6a Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 6 Apr 2023 09:59:45 +0200 Subject: [PATCH 03/61] test --- modules/ticket/front/sale/index.html | 6 +++--- modules/ticket/front/sale/index.js | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/modules/ticket/front/sale/index.html b/modules/ticket/front/sale/index.html index 74cb101f4..2b3674a75 100644 --- a/modules/ticket/front/sale/index.html +++ b/modules/ticket/front/sale/index.html @@ -63,7 +63,7 @@ Visible Available Id - Quantity + Quantity Item Price Disc @@ -73,7 +73,7 @@ - + @@ -232,7 +232,7 @@ vn-tooltip="Add item" vn-bind="+" icon="add_circle" - ng-click="$ctrl.add()" + ng-click="$ctrl.cambiarOrden('quantity')" disabled="!$ctrl.isEditable"> diff --git a/modules/ticket/front/sale/index.js b/modules/ticket/front/sale/index.js index f3fb89d04..075532d8f 100644 --- a/modules/ticket/front/sale/index.js +++ b/modules/ticket/front/sale/index.js @@ -7,6 +7,12 @@ class Controller extends Section { super($element, $); this._sales = []; this.manaCode = 'mana'; + this.ordenarPor = 'quantity'; + } + + cambiarOrden(columna) { + this.ordenarPor = columna; + console.log(this.ordenarPor); } get manaCode() { From cc9ce65678f175e78ad9ff15352a4578a7de0908 Mon Sep 17 00:00:00 2001 From: vicent Date: Tue, 11 Apr 2023 07:44:25 +0200 Subject: [PATCH 04/61] test --- modules/ticket/front/sale/index.html | 4 ++-- modules/ticket/front/sale/index.js | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/modules/ticket/front/sale/index.html b/modules/ticket/front/sale/index.html index 74cb101f4..1b378a9da 100644 --- a/modules/ticket/front/sale/index.html +++ b/modules/ticket/front/sale/index.html @@ -63,7 +63,7 @@ Visible Available Id - Quantity + Quantity Item Price Disc @@ -73,7 +73,7 @@ - + diff --git a/modules/ticket/front/sale/index.js b/modules/ticket/front/sale/index.js index f3fb89d04..379b48cc9 100644 --- a/modules/ticket/front/sale/index.js +++ b/modules/ticket/front/sale/index.js @@ -7,6 +7,11 @@ class Controller extends Section { super($element, $); this._sales = []; this.manaCode = 'mana'; + this.ordenarPor = 'nombre'; + } + + cambiarOrden(columna) { + this.ordenarPor = columna; } get manaCode() { From db19f153fbe0f0ae1090b5675d74e59ae58226a7 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 18 Apr 2023 15:03:23 +0200 Subject: [PATCH 05/61] refs #5488 removes 'role ==' --- db/changes/231601/00-acls.sql | 6 ++++++ modules/ticket/back/methods/ticket/updateDiscount.js | 7 ++----- modules/zone/back/methods/agency/getLanded.js | 9 +++------ modules/zone/back/methods/zone/includingExpired.js | 6 +----- 4 files changed, 12 insertions(+), 16 deletions(-) create mode 100644 db/changes/231601/00-acls.sql diff --git a/db/changes/231601/00-acls.sql b/db/changes/231601/00-acls.sql new file mode 100644 index 000000000..359448672 --- /dev/null +++ b/db/changes/231601/00-acls.sql @@ -0,0 +1,6 @@ +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES + ('Ticket', 'editDiscount', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'), + ('Ticket', 'editDiscount', 'WRITE', 'ALLOW', 'ROLE', 'salesPerson'); + ('Agency', 'seeExpired', 'READ', 'ALLOW', 'ROLE', 'administrative'); + ('Agency', 'seeExpired', 'READ', 'ALLOW', 'ROLE', 'productionBoss'); diff --git a/modules/ticket/back/methods/ticket/updateDiscount.js b/modules/ticket/back/methods/ticket/updateDiscount.js index 4dd346161..4b31c0ce4 100644 --- a/modules/ticket/back/methods/ticket/updateDiscount.js +++ b/modules/ticket/back/methods/ticket/updateDiscount.js @@ -85,17 +85,14 @@ module.exports = Self => { const userId = ctx.req.accessToken.userId; const isLocked = await models.Ticket.isLocked(id, myOptions); - const roles = await models.Account.getRoles(userId, myOptions); - const hasAllowedRoles = roles.filter(role => - role == 'salesPerson' || role == 'claimManager' - ); + const canEditDiscount = await models.ACL.checkAccessAcl(ctx, 'Ticket', 'editDiscount'); const state = await Self.app.models.TicketState.findOne({ where: {ticketFk: id} }, myOptions); const alertLevel = state ? state.alertLevel : null; - if (isLocked || (!hasAllowedRoles && alertLevel > 0)) + if (isLocked || (!canEditDiscount && alertLevel > 0)) throw new UserError(`The sales of this ticket can't be modified`); const usesMana = await models.Sale.usesMana(ctx, myOptions); diff --git a/modules/zone/back/methods/agency/getLanded.js b/modules/zone/back/methods/agency/getLanded.js index a662f59dd..ef5a183f3 100644 --- a/modules/zone/back/methods/agency/getLanded.js +++ b/modules/zone/back/methods/agency/getLanded.js @@ -35,17 +35,14 @@ module.exports = Self => { }); Self.getLanded = async(ctx, shipped, addressFk, agencyModeFk, warehouseFk, options) => { + const models = Self.app.models; const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); - const userId = ctx.req.accessToken.userId; - const models = Self.app.models; - const roles = await models.Account.getRoles(userId); - const canSeeExpired = roles.filter(role => - role == 'productionBoss' || role == 'administrative' - ); + const canSeeExpired = await models.ACL.checkAccessAcl(ctx, 'Agency', 'editDiscount'); + let showExpired = false; if (canSeeExpired.length) showExpired = true; diff --git a/modules/zone/back/methods/zone/includingExpired.js b/modules/zone/back/methods/zone/includingExpired.js index e93b86471..31678c83d 100644 --- a/modules/zone/back/methods/zone/includingExpired.js +++ b/modules/zone/back/methods/zone/includingExpired.js @@ -24,7 +24,6 @@ module.exports = Self => { if (typeof options == 'object') Object.assign(myOptions, options); - const userId = ctx.req.accessToken.userId; const conn = Self.dataSource.connector; const models = Self.app.models; const where = filter.where; @@ -36,10 +35,7 @@ module.exports = Self => { && where.agencyModeFk && where.warehouseFk; if (filterByAvailability) { - const roles = await models.Account.getRoles(userId, myOptions); - const canSeeExpired = roles.filter(role => - role == 'productionBoss' || role == 'administrative' - ); + const canSeeExpired = await models.ACL.checkAccessAcl(ctx, 'Agency', 'editDiscount'); let showExpired = false; if (canSeeExpired.length) showExpired = true; From c1d4281b1bcc9e7ee935f872ae2dd8e49c9451ea Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 19 Apr 2023 13:59:26 +0200 Subject: [PATCH 06/61] refs #5488 replace hasWriteRole, hasReadRole --- back/methods/dms/removeFile.js | 8 +-- back/methods/dms/updateFile.js | 2 +- back/methods/dms/uploadFile.js | 2 +- back/methods/image/download.js | 2 +- back/methods/image/upload.js | 2 +- back/models/dms-type.js | 55 ++-------------- back/models/dms-type.json | 31 +++++++-- back/models/dms.js | 4 +- back/models/image-collection.js | 64 ------------------- back/models/specs/dms.spec.js | 4 +- .../{00-acls.sql => 00-useSpecificsAcls.sql} | 8 ++- .../01-dmsTypeAndImageCollectionAcls.sql | 22 +++++++ db/dump/fixtures.sql | 50 +++++++++------ .../claim/back/methods/claim/uploadFile.js | 2 +- .../fixed-price/specs/editFixedPrice.spec.js | 4 +- .../back/methods/worker-dms/downloadFile.js | 2 +- .../worker-dms/specs/downloadFile.spec.js | 6 +- modules/zone/back/methods/agency/getLanded.js | 7 +- 18 files changed, 106 insertions(+), 169 deletions(-) delete mode 100644 back/models/image-collection.js rename db/changes/231601/{00-acls.sql => 00-useSpecificsAcls.sql} (66%) create mode 100644 db/changes/231601/01-dmsTypeAndImageCollectionAcls.sql diff --git a/back/methods/dms/removeFile.js b/back/methods/dms/removeFile.js index a9ff36883..8007407d5 100644 --- a/back/methods/dms/removeFile.js +++ b/back/methods/dms/removeFile.js @@ -35,14 +35,14 @@ module.exports = Self => { try { const dms = await models.Dms.findById(id, null, myOptions); - const trashDmsType = await models.DmsType.findOne({ - where: {code: 'trash'} - }, myOptions); - const hasWriteRole = await models.DmsType.hasWriteRole(ctx, dms.dmsTypeFk, myOptions); + const hasWriteRole = await models.DmsType.checkRole(ctx, dms.dmsTypeFk, 'WRITE', myOptions); if (!hasWriteRole) throw new UserError(`You don't have enough privileges`); + const trashDmsType = await models.DmsType.findOne({ + where: {code: 'trash'} + }, myOptions); await dms.updateAttribute('dmsTypeFk', trashDmsType.id, myOptions); if (tx) await tx.commit(); diff --git a/back/methods/dms/updateFile.js b/back/methods/dms/updateFile.js index cfc4c322f..0ecced31a 100644 --- a/back/methods/dms/updateFile.js +++ b/back/methods/dms/updateFile.js @@ -71,7 +71,7 @@ module.exports = Self => { } try { - const hasWriteRole = await models.DmsType.hasWriteRole(ctx, args.dmsTypeId); + const hasWriteRole = await models.DmsType.checkRole(ctx, args.dmsTypeId, 'WRITE'); if (!hasWriteRole) throw new UserError(`You don't have enough privileges`); diff --git a/back/methods/dms/uploadFile.js b/back/methods/dms/uploadFile.js index a4212b804..ca1c1339d 100644 --- a/back/methods/dms/uploadFile.js +++ b/back/methods/dms/uploadFile.js @@ -66,7 +66,7 @@ module.exports = Self => { let srcFile; try { - const hasWriteRole = await models.DmsType.hasWriteRole(ctx, args.dmsTypeId, myOptions); + const hasWriteRole = await models.DmsType.checkRole(ctx, args.dmsTypeId, 'WRITE'); if (!hasWriteRole) throw new UserError(`You don't have enough privileges`); diff --git a/back/methods/image/download.js b/back/methods/image/download.js index 3a8bcf30e..e3e8c495c 100644 --- a/back/methods/image/download.js +++ b/back/methods/image/download.js @@ -67,7 +67,7 @@ module.exports = Self => { if (!image) return false; - const hasReadRole = models.ImageCollection.hasReadRole(ctx, collection); + const hasReadRole = await models.ACL.checkAccessAcl(ctx, 'ImageCollection', collection, 'READ'); if (!hasReadRole) throw new UserError(`You don't have enough privileges`); diff --git a/back/methods/image/upload.js b/back/methods/image/upload.js index 1de0064f6..53c6fcd3a 100644 --- a/back/methods/image/upload.js +++ b/back/methods/image/upload.js @@ -37,7 +37,7 @@ module.exports = Self => { let tempFilePath; try { - const hasWriteRole = await models.ImageCollection.hasWriteRole(ctx, args.collection); + const hasWriteRole = await models.ACL.checkAccessAcl(ctx, 'ImageCollection', args.collection, 'WRITE'); if (!hasWriteRole) throw new UserError(`You don't have enough privileges`); diff --git a/back/models/dms-type.js b/back/models/dms-type.js index c9329f30b..43f258319 100644 --- a/back/models/dms-type.js +++ b/back/models/dms-type.js @@ -1,65 +1,18 @@ module.exports = Self => { - /** - * Checks if current user has - * read privileges over a dms - * - * @param {Object} ctx - Request context - * @param {Interger} id - DmsType id - * @param {Object} options - Query options - * @return {Boolean} True for user with read privileges - */ - Self.hasReadRole = async(ctx, id, options) => { - const models = Self.app.models; - const dmsType = await models.DmsType.findById(id, { - include: { - relation: 'readRole' - } - }, options); - - return await hasRole(ctx, dmsType, options); - }; - /** * Checks if current user has * write privileges over a dms * * @param {Object} ctx - Request context * @param {Interger} id - DmsType id + * @param {String} type - Acl accessType * @param {Object} options - Query options * @return {Boolean} True for user with write privileges */ - Self.hasWriteRole = async(ctx, id, options) => { + Self.checkRole = async(ctx, id, type, options) => { const models = Self.app.models; - const dmsType = await models.DmsType.findById(id, { - include: { - relation: 'writeRole' - } - }, options); + const dmsType = await models.DmsType.findById(id, {fields: ['code']}, options); - return await hasRole(ctx, dmsType, options); + return await models.ACL.checkAccessAcl(ctx, 'DmsType', dmsType.code, type); }; - - /** - * Checks if current user has - * read or write privileges - * @param {Object} ctx - Context - * @param {Object} dmsType - Dms type [read/write] - * @param {Object} options - Query options - */ - async function hasRole(ctx, dmsType, options) { - const models = Self.app.models; - const myUserId = ctx.req.accessToken.userId; - - const readRole = dmsType.readRole() && dmsType.readRole().name; - const writeRole = dmsType.writeRole() && dmsType.writeRole().name; - const requiredRole = readRole || writeRole; - - const hasRequiredRole = await models.VnUser.hasRole(myUserId, requiredRole, options); - const isRoot = await models.VnUser.hasRole(myUserId, 'root', options); - - if (isRoot || hasRequiredRole) - return true; - - return false; - } }; diff --git a/back/models/dms-type.json b/back/models/dms-type.json index c7a1815fe..c986060ac 100644 --- a/back/models/dms-type.json +++ b/back/models/dms-type.json @@ -38,10 +38,27 @@ "foreignKey": "writeRoleFk" } }, - "acls": [{ - "accessType": "READ", - "principalType": "ROLE", - "principalId": "$everyone", - "permission": "ALLOW" - }] -} \ No newline at end of file + "acls": [ + { + "property": "find", + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + }, + { + "property": "findById", + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + }, + { + "property": "findOne", + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + } + ] +} diff --git a/back/models/dms.js b/back/models/dms.js index 24c072f56..8ecd10cb1 100644 --- a/back/models/dms.js +++ b/back/models/dms.js @@ -7,11 +7,11 @@ module.exports = Self => { require('../methods/dms/updateFile')(Self); require('../methods/dms/deleteTrashFiles')(Self); - Self.checkRole = async function(ctx, id) { + Self.checkRole = async function(ctx, id, type) { const models = Self.app.models; const dms = await Self.findById(id); - return await models.DmsType.hasReadRole(ctx, dms.dmsTypeFk); + return await models.DmsType.checkRole(ctx, dms.dmsTypeFk, type); }; Self.getFile = async function(id) { diff --git a/back/models/image-collection.js b/back/models/image-collection.js deleted file mode 100644 index 2c4d274ee..000000000 --- a/back/models/image-collection.js +++ /dev/null @@ -1,64 +0,0 @@ -module.exports = Self => { - /** - * Checks if current user has - * read privileges over a collection - * - * @param {object} ctx - Request context - * @param {interger} name - Collection name - * @param {object} options - Query options - * @return {boolean} True for user with read privileges - */ - Self.hasReadRole = async(ctx, name, options) => { - const collection = await Self.findOne({where: {name}}, { - include: { - relation: 'readRole' - } - }, options); - - return await hasRole(ctx, collection, options); - }; - - /** - * Checks if current user has - * write privileges over a collection - * - * @param {object} ctx - Request context - * @param {string} name - Collection name - * @param {object} options - Query options - * @return {boolean} True for user with write privileges - */ - Self.hasWriteRole = async(ctx, name, options) => { - const collection = await Self.findOne({ - include: { - relation: 'writeRole' - }, - where: {name} - }, options); - - return await hasRole(ctx, collection, options); - }; - - /** - * Checks if current user has - * read or write privileges - * @param {Object} ctx - Context - * @param {Object} collection - Collection [read/write] - * @param {Object} options - Query options - */ - async function hasRole(ctx, collection, options) { - const models = Self.app.models; - const myUserId = ctx.req.accessToken.userId; - - const readRole = collection.readRole() && collection.readRole().name; - const writeRole = collection.writeRole() && collection.writeRole().name; - const requiredRole = readRole || writeRole; - - const hasRequiredRole = await models.VnUser.hasRole(myUserId, requiredRole, options); - const isRoot = await models.VnUser.hasRole(myUserId, 'root', options); - - if (isRoot || hasRequiredRole) - return true; - - return false; - } -}; diff --git a/back/models/specs/dms.spec.js b/back/models/specs/dms.spec.js index 3f13e88ff..e539387fb 100644 --- a/back/models/specs/dms.spec.js +++ b/back/models/specs/dms.spec.js @@ -37,14 +37,14 @@ describe('Dms', () => { const dmsId = 1; it('should return a true for an employee with permission', async() => { let ctx = {req: {accessToken: {userId: 1107}}}; - const result = await Dms.checkRole(ctx, dmsId); + const result = await Dms.checkRole(ctx, dmsId, 'READ'); expect(result).toBeTruthy(); }); it('should return false for an employee without permission', async() => { let ctx = {req: {accessToken: {userId: 1101}}}; - const result = await Dms.checkRole(ctx, dmsId); + const result = await Dms.checkRole(ctx, dmsId, 'READ'); expect(result).toBeFalsy(); }); diff --git a/db/changes/231601/00-acls.sql b/db/changes/231601/00-useSpecificsAcls.sql similarity index 66% rename from db/changes/231601/00-acls.sql rename to db/changes/231601/00-useSpecificsAcls.sql index 359448672..a9610ab31 100644 --- a/db/changes/231601/00-acls.sql +++ b/db/changes/231601/00-useSpecificsAcls.sql @@ -1,6 +1,8 @@ INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('Ticket', 'editDiscount', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'), - ('Ticket', 'editDiscount', 'WRITE', 'ALLOW', 'ROLE', 'salesPerson'); - ('Agency', 'seeExpired', 'READ', 'ALLOW', 'ROLE', 'administrative'); - ('Agency', 'seeExpired', 'READ', 'ALLOW', 'ROLE', 'productionBoss'); + ('Ticket', 'editDiscount', 'WRITE', 'ALLOW', 'ROLE', 'salesPerson'), + ('Agency', 'seeExpired', 'READ', 'ALLOW', 'ROLE', 'administrative'), + ('Agency', 'seeExpired', 'READ', 'ALLOW', 'ROLE', 'productionBoss'), + ('Claim', 'createAfterDeadline', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'), + ('Claim', 'editState', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'); diff --git a/db/changes/231601/01-dmsTypeAndImageCollectionAcls.sql b/db/changes/231601/01-dmsTypeAndImageCollectionAcls.sql new file mode 100644 index 000000000..eb4093e93 --- /dev/null +++ b/db/changes/231601/01-dmsTypeAndImageCollectionAcls.sql @@ -0,0 +1,22 @@ +-- DmsType model +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + SELECT 'DmsType', d.code, 'WRITE', 'ALLOW', 'ROLE', r.name + FROM `vn`.`dmsType` d + JOIN `account`.`role` r ON r.id = d.writeRoleFk; + +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + SELECT 'DmsType', d.code, 'READ', 'ALLOW', 'ROLE', r.name + FROM `vn`.`dmsType` d + JOIN `account`.`role` r ON r.id = d.readRoleFk; + +-- ImageCollection model +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + SELECT 'ImageCollection', i.name, 'WRITE', 'ALLOW', 'ROLE', r.name + FROM `hedera`.`imageCollection` i + JOIN `account`.`role` r ON r.id = i.writeRoleFk; + +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + SELECT 'ImageCollection', i.name, 'READ', 'ALLOW', 'ROLE', r.name + FROM `hedera`.`imageCollection` i + JOIN `account`.`role` r ON r.id = i.readRoleFk; + diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index d6be639c5..041a57cc0 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -2320,26 +2320,36 @@ INSERT INTO `vn`.`workerTimeControl`(`userFk`, `timed`, `manual`, `direction`, ` INSERT INTO `vn`.`dmsType`(`id`, `name`, `path`, `readRoleFk`, `writeRoleFk`, `code`) VALUES - (1, 'Facturas Recibidas', 'recibidas', NULL, NULL, 'invoiceIn'), - (2, 'Doc oficial', 'oficial', NULL, NULL, 'officialDoc'), - (3, 'Laboral', 'laboral', 37, 37, 'hhrrData'), - (4, 'Albaranes recibidos', 'entradas', NULL, NULL, 'deliveryNote'), - (5, 'Otros', 'otros', 1, 1, 'miscellaneous'), - (6, 'Pruebas', 'pruebas', NULL, NULL, 'tests'), - (7, 'IAE Clientes', 'IAE_Clientes', 1, 1, 'economicActivitiesTax'), - (8, 'Fiscal', 'fiscal', NULL, NULL, 'fiscal'), - (9, 'Vehiculos', 'vehiculos', NULL, NULL, 'vehicles'), - (10, 'Plantillas', 'plantillas', NULL, NULL, 'templates'), - (11, 'Contratos', 'contratos', NULL, NULL, 'contracts'), - (12, 'ley de pagos', 'ley pagos', 1, 1, 'paymentsLaw'), - (13, 'Basura', 'basura', 1, 1, 'trash'), - (14, 'Ticket', 'tickets', 1, 1, 'ticket'), - (15, 'Presupuestos', 'Presupuestos', NULL, NULL, 'budgets'), - (16, 'Logistica', 'logistica', NULL, NULL, 'logistics'), - (17, 'cmr', 'cmr', NULL, NULL, 'cmr'), - (18, 'dua', 'dua', NULL, NULL, 'dua'), - (19, 'inmovilizado', 'inmovilizado', NULL, NULL, 'fixedAssets'), - (20, 'Reclamación', 'reclamacion', 1, 1, 'claim'); + (1, 'Facturas Recibidas', 'recibidas', 1, 1, 'invoiceIn'), + (2, 'Doc oficial', 'oficial', 1, 1, 'officialDoc'), + (3, 'Laboral', 'laboral', 37, 37, 'hhrrData'), + (4, 'Albaranes recibidos', 'entradas', 1, 1, 'deliveryNote'), + (5, 'Otros', 'otros', 1, 1, 'miscellaneous'), + (6, 'Pruebas', 'pruebas', 1, 1, 'tests'), + (7, 'IAE Clientes', 'IAE_Clientes', 1, 1, 'economicActivitiesTax'), + (8, 'Fiscal', 'fiscal', 1, 1, 'fiscal'), + (9, 'Vehiculos', 'vehiculos', 1, 1, 'vehicles'), + (10, 'Plantillas', 'plantillas', 1, 1, 'templates'), + (11, 'Contratos', 'contratos', 1, 1, 'contracts'), + (12, 'ley de pagos', 'ley pagos', 1, 1, 'paymentsLaw'), + (13, 'Basura', 'basura', 1, 1, 'trash'), + (14, 'Ticket', 'tickets', 1, 1, 'ticket'), + (15, 'Presupuestos', 'Presupuestos', 1, 1, 'budgets'), + (16, 'Logistica', 'logistica', 1, 1, 'logistics'), + (17, 'cmr', 'cmr', 1, 1, 'cmr'), + (18, 'dua', 'dua', 1, 1, 'dua'), + (19, 'inmovilizado', 'inmovilizado', 1, 1, 'fixedAssets'), + (20, 'Reclamación', 'reclamacion', 1, 1, 'claim'); + +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + SELECT 'DmsType', d.code, 'WRITE', 'ALLOW', 'ROLE', r.name + FROM `vn`.`dmsType` d + JOIN `account`.`role` r ON r.id = d.writeRoleFk; + +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + SELECT 'DmsType', d.code, 'READ', 'ALLOW', 'ROLE', r.name + FROM `vn`.`dmsType` d + JOIN `account`.`role` r ON r.id = d.readRoleFk; INSERT INTO `vn`.`dms`(`id`, `dmsTypeFk`, `file`, `contentType`, `workerFk`, `warehouseFk`, `companyFk`, `hardCopyNumber`, `hasFile`, `reference`, `description`, `created`) VALUES diff --git a/modules/claim/back/methods/claim/uploadFile.js b/modules/claim/back/methods/claim/uploadFile.js index 3d0737cf8..14aa088a4 100644 --- a/modules/claim/back/methods/claim/uploadFile.js +++ b/modules/claim/back/methods/claim/uploadFile.js @@ -75,7 +75,7 @@ module.exports = Self => { let srcFile; try { - const hasWriteRole = await models.DmsType.hasWriteRole(ctx, args.dmsTypeId, myOptions); + const hasWriteRole = await models.DmsType.checkRole(ctx, args.dmsTypeId, 'WRITE', myOptions); if (!hasWriteRole) throw new UserError(`You don't have enough privileges`); diff --git a/modules/item/back/methods/fixed-price/specs/editFixedPrice.spec.js b/modules/item/back/methods/fixed-price/specs/editFixedPrice.spec.js index 9c265f28a..db255a91e 100644 --- a/modules/item/back/methods/fixed-price/specs/editFixedPrice.spec.js +++ b/modules/item/back/methods/fixed-price/specs/editFixedPrice.spec.js @@ -37,7 +37,7 @@ describe('Item editFixedPrice()', () => { const options = {transaction: tx}; try { - const filter = {'it.categoryFk': 1}; + const filter = {where: {'it.categoryFk': 1}}; const ctx = { args: { filter: filter @@ -48,7 +48,7 @@ describe('Item editFixedPrice()', () => { const field = 'rate2'; const newValue = 88; - await models.FixedPrice.editFixedPrice(ctx, field, newValue, null, filter, options); + await models.FixedPrice.editFixedPrice(ctx, field, newValue, null, filter.where, options); const [result] = await models.FixedPrice.filter(ctx, filter, options); diff --git a/modules/worker/back/methods/worker-dms/downloadFile.js b/modules/worker/back/methods/worker-dms/downloadFile.js index cc8653e0e..d129814a2 100644 --- a/modules/worker/back/methods/worker-dms/downloadFile.js +++ b/modules/worker/back/methods/worker-dms/downloadFile.js @@ -33,7 +33,7 @@ module.exports = Self => { }); Self.downloadFile = async function(ctx, id) { - if (!await Self.app.models.Dms.checkRole(ctx, id) && !await Self.isMine(ctx, id)) + if (!await Self.app.models.Dms.checkRole(ctx, id, 'READ') && !await Self.isMine(ctx, id)) throw new UserError(`You don't have enough privileges`); return await Self.app.models.Dms.getFile(id); }; diff --git a/modules/worker/back/methods/worker-dms/specs/downloadFile.spec.js b/modules/worker/back/methods/worker-dms/specs/downloadFile.spec.js index ac8e4539f..bdeec215c 100644 --- a/modules/worker/back/methods/worker-dms/specs/downloadFile.spec.js +++ b/modules/worker/back/methods/worker-dms/specs/downloadFile.spec.js @@ -1,4 +1,4 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; describe('worker-dms downloadFile()', () => { let dmsId = 4; @@ -6,7 +6,7 @@ describe('worker-dms downloadFile()', () => { it('should return a response for an employee with text content-type', async() => { let workerId = 1106; let ctx = {req: {accessToken: {userId: workerId}}}; - const result = await app.models.WorkerDms.downloadFile(ctx, dmsId); + const result = await models.WorkerDms.downloadFile(ctx, dmsId); expect(result[1]).toEqual('text/plain'); }); @@ -17,7 +17,7 @@ describe('worker-dms downloadFile()', () => { let error; try { - await app.models.WorkerDms.downloadFile(ctx, dmsId); + await models.WorkerDms.downloadFile(ctx, dmsId); } catch (e) { error = e; } diff --git a/modules/zone/back/methods/agency/getLanded.js b/modules/zone/back/methods/agency/getLanded.js index ef5a183f3..ebaa2db62 100644 --- a/modules/zone/back/methods/agency/getLanded.js +++ b/modules/zone/back/methods/agency/getLanded.js @@ -41,10 +41,7 @@ module.exports = Self => { if (typeof options == 'object') Object.assign(myOptions, options); - const canSeeExpired = await models.ACL.checkAccessAcl(ctx, 'Agency', 'editDiscount'); - - let showExpired = false; - if (canSeeExpired.length) showExpired = true; + const canSeeExpired = await models.ACL.checkAccessAcl(ctx, 'Agency', 'seeExpired', 'READ'); const stmts = []; stmts.push(new ParameterizedSQL( @@ -53,7 +50,7 @@ module.exports = Self => { addressFk, agencyModeFk, warehouseFk, - showExpired + canSeeExpired ] )); From 39333a9119cab4880db63beb1f058d8b5edb66a7 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 19 Apr 2023 15:23:32 +0200 Subject: [PATCH 07/61] refs #5488 replace hasRole for checkAccessAcl --- db/changes/231601/00-DROP_BEFORE_MERGE.sql | 65 +++++++++++++++++++ db/changes/231601/00-User.sql | 2 +- ...geCollectionAcls.sql => 00-modelsAcls.sql} | 6 ++ db/changes/231601/00-useSpecificsAcls.sql | 1 + db/changes/231601/01-ClaimReAcl.sql | 2 + db/dump/fixtures.sql | 5 ++ .../back/methods/claim-state/isEditable.js | 11 +--- .../back/methods/claim/createFromSales.js | 6 +- .../back/methods/client/updateAddress.js | 6 +- 9 files changed, 90 insertions(+), 14 deletions(-) create mode 100644 db/changes/231601/00-DROP_BEFORE_MERGE.sql rename db/changes/231601/{01-dmsTypeAndImageCollectionAcls.sql => 00-modelsAcls.sql} (80%) create mode 100644 db/changes/231601/01-ClaimReAcl.sql diff --git a/db/changes/231601/00-DROP_BEFORE_MERGE.sql b/db/changes/231601/00-DROP_BEFORE_MERGE.sql new file mode 100644 index 000000000..211a407ab --- /dev/null +++ b/db/changes/231601/00-DROP_BEFORE_MERGE.sql @@ -0,0 +1,65 @@ +DELETE FROM `salix`.`ACL` WHERE id=7; + +INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) + VALUES + ('Client', 'setRating', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'setRating', 'WRITE', 'ALLOW', 'ROLE', 'financial'); + +INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) + VALUES + ('Client', '*', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'addressesPropagateRe', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'canBeInvoiced', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'canCreateTicket', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'consumption', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'createAddress', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'createWithUser', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'extendedListFilter', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'getAverageInvoiced', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'getCard', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'getDebt', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'getMana', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'transactions', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'hasCustomerRole', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'isValidClient', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'lastActiveTickets', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'sendSms', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'setPassword', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'summary', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'updateAddress', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'updateFiscalData', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'updateUser', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'uploadFile', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'campaignMetricsPdf', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'campaignMetricsEmail', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'clientWelcomeHtml', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'clientWelcomeEmail', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'printerSetupHtml', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'printerSetupEmail', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'sepaCoreEmail', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'letterDebtorPdf', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'letterDebtorStHtml', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'letterDebtorStEmail', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'letterDebtorNdHtml', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'letterDebtorNdEmail', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'clientDebtStatementPdf', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'clientDebtStatementHtml', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'clientDebtStatementEmail', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'creditRequestPdf', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'creditRequestHtml', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'creditRequestEmail', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'incotermsAuthorizationPdf', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'incotermsAuthorizationHtml', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'incotermsAuthorizationEmail', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'consumptionSendQueued', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'filter', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'getClientOrSupplierReference', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'upsert', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'create', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'replaceById', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'updateAttributes', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'updateAttributes', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'deleteById', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'replaceOrCreate', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'updateAll', '*', 'ALLOW', 'ROLE', 'employee'), + ('Client', 'upsertWithWhere', '*', 'ALLOW', 'ROLE', 'employee'); diff --git a/db/changes/231601/00-User.sql b/db/changes/231601/00-User.sql index 6c80d2c2d..8a7054403 100644 --- a/db/changes/231601/00-User.sql +++ b/db/changes/231601/00-User.sql @@ -1,4 +1,4 @@ -create or replace definer = root@localhost view User as +create or replace definer = root@localhost view `salix`.`User` as select `account`.`user`.`id` AS `id`, `account`.`user`.`realm` AS `realm`, `account`.`user`.`name` AS `name`, diff --git a/db/changes/231601/01-dmsTypeAndImageCollectionAcls.sql b/db/changes/231601/00-modelsAcls.sql similarity index 80% rename from db/changes/231601/01-dmsTypeAndImageCollectionAcls.sql rename to db/changes/231601/00-modelsAcls.sql index eb4093e93..62f2b20d0 100644 --- a/db/changes/231601/01-dmsTypeAndImageCollectionAcls.sql +++ b/db/changes/231601/00-modelsAcls.sql @@ -20,3 +20,9 @@ INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `pri FROM `hedera`.`imageCollection` i JOIN `account`.`role` r ON r.id = i.readRoleFk; +-- ClaimState +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + SELECT 'ClaimState', c.code, 'WRITE', 'ALLOW', 'ROLE', r.name + FROM `vn`.`claimState` c + JOIN `account`.`role` r ON r.id = c.roleFk; + diff --git a/db/changes/231601/00-useSpecificsAcls.sql b/db/changes/231601/00-useSpecificsAcls.sql index a9610ab31..24d3c5723 100644 --- a/db/changes/231601/00-useSpecificsAcls.sql +++ b/db/changes/231601/00-useSpecificsAcls.sql @@ -5,4 +5,5 @@ INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `pri ('Agency', 'seeExpired', 'READ', 'ALLOW', 'ROLE', 'administrative'), ('Agency', 'seeExpired', 'READ', 'ALLOW', 'ROLE', 'productionBoss'), ('Claim', 'createAfterDeadline', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'), + ('Client', 'editAddressLogifloraAllowed', 'WRITE', 'ALLOW', 'ROLE', 'salesAssistant'), ('Claim', 'editState', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'); diff --git a/db/changes/231601/01-ClaimReAcl.sql b/db/changes/231601/01-ClaimReAcl.sql new file mode 100644 index 000000000..c30ec2123 --- /dev/null +++ b/db/changes/231601/01-ClaimReAcl.sql @@ -0,0 +1,2 @@ +DELETE FROM salix.ACL +WHERE id=101; diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 041a57cc0..f76192be0 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -1774,6 +1774,11 @@ INSERT INTO `vn`.`claimState`(`id`, `code`, `description`, `roleFk`, `priority`, ( 6, 'mana', 'Mana', 72, 4, 0), ( 7, 'lack', 'Faltas', 72, 2, 0); +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + SELECT 'ClaimState', c.code, 'WRITE', 'ALLOW', 'ROLE', r.name + FROM `vn`.`claimState` c + JOIN `account`.`role` r ON r.id = c.roleFk; + INSERT INTO `vn`.`claim`(`id`, `ticketCreated`, `claimStateFk`, `clientFk`, `workerFk`, `responsibility`, `isChargedToMana`, `created`, `packages`, `rma`, `ticketFk`) VALUES (1, util.VN_CURDATE(), 1, 1101, 18, 3, 0, util.VN_CURDATE(), 0, '02676A049183', 11), diff --git a/modules/claim/back/methods/claim-state/isEditable.js b/modules/claim/back/methods/claim-state/isEditable.js index 641bc3b42..73a8338da 100644 --- a/modules/claim/back/methods/claim-state/isEditable.js +++ b/modules/claim/back/methods/claim-state/isEditable.js @@ -20,19 +20,14 @@ module.exports = Self => { }); Self.isEditable = async(ctx, id, options) => { - const userId = ctx.req.accessToken.userId; const models = Self.app.models; const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); + const state = await models.ClaimState.findById(id, {fields: ['code']}, myOptions); + if (!state) return false; - const state = await models.ClaimState.findById(id, { - include: { - relation: 'writeRole' - } - }, myOptions); - const roleWithGrants = state && state.writeRole().name; - return await models.VnUser.hasRole(userId, roleWithGrants, myOptions); + return await models.ACL.checkAccessAcl(ctx, 'ClaimState', state.code); }; }; diff --git a/modules/claim/back/methods/claim/createFromSales.js b/modules/claim/back/methods/claim/createFromSales.js index 10d0b9b28..07bdb30aa 100644 --- a/modules/claim/back/methods/claim/createFromSales.js +++ b/modules/claim/back/methods/claim/createFromSales.js @@ -59,12 +59,14 @@ module.exports = Self => { const landedPlusWeek = new Date(ticket.landed); landedPlusWeek.setDate(landedPlusWeek.getDate() + 7); - const hasClaimManagerRole = await models.VnUser.hasRole(userId, 'claimManager', myOptions); const isClaimable = landedPlusWeek >= Date.vnNew(); + const canCreateClaimAfterDeadline = + await models.ACL.checkAccessAcl(ctx, 'Claim', 'createAfterDeadline', 'WRITE'); + if (ticket.isDeleted) throw new UserError(`You can't create a claim for a removed ticket`); - if (!isClaimable && !hasClaimManagerRole) + if (!isClaimable && !canCreateClaimAfterDeadline) throw new UserError(`You can't create a claim from a ticket delivered more than seven days ago`); const newClaim = await Self.create({ diff --git a/modules/client/back/methods/client/updateAddress.js b/modules/client/back/methods/client/updateAddress.js index e521870fd..7342b28f1 100644 --- a/modules/client/back/methods/client/updateAddress.js +++ b/modules/client/back/methods/client/updateAddress.js @@ -87,15 +87,15 @@ module.exports = function(Self) { Self.updateAddress = async(ctx, clientId, addressId, options) => { const models = Self.app.models; const args = ctx.args; - const userId = ctx.req.accessToken.userId; const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); - const isSalesAssistant = await models.VnUser.hasRole(userId, 'salesAssistant', myOptions); + const canEditAddressLogifloraAllowed = + await models.ACL.checkAccessAcl(ctx, 'Client', 'editAddressLogifloraAllowed'); - if (args.isLogifloraAllowed && !isSalesAssistant) + if (args.isLogifloraAllowed && !canEditAddressLogifloraAllowed) throw new UserError(`You don't have enough privileges`); const address = await models.Address.findOne({ From 8502b74dee18f0dbc6d584547de5161d4bdb89fd Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 24 Apr 2023 11:07:04 +0200 Subject: [PATCH 08/61] feat(): replace hasRole to checkAccessAcl --- db/changes/231601/00-DROP_BEFORE_MERGE.sql | 65 ------------------- db/changes/231601/00-client_setRatingAcl.sql | 1 - db/changes/231601/00-useSpecificsAcls.sql | 11 ++++ db/changes/231601/01-ClaimReAcl.sql | 2 - .../claim/back/methods/claim/updateClaim.js | 5 +- .../back/methods/client/updateFiscalData.js | 5 +- .../client/back/methods/client/updateUser.js | 7 +- modules/client/back/models/client.js | 18 ++--- .../back/methods/invoiceOut/createPdf.js | 5 +- 9 files changed, 30 insertions(+), 89 deletions(-) delete mode 100644 db/changes/231601/00-DROP_BEFORE_MERGE.sql delete mode 100644 db/changes/231601/01-ClaimReAcl.sql diff --git a/db/changes/231601/00-DROP_BEFORE_MERGE.sql b/db/changes/231601/00-DROP_BEFORE_MERGE.sql deleted file mode 100644 index 211a407ab..000000000 --- a/db/changes/231601/00-DROP_BEFORE_MERGE.sql +++ /dev/null @@ -1,65 +0,0 @@ -DELETE FROM `salix`.`ACL` WHERE id=7; - -INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) - VALUES - ('Client', 'setRating', 'READ', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'setRating', 'WRITE', 'ALLOW', 'ROLE', 'financial'); - -INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) - VALUES - ('Client', '*', 'READ', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'addressesPropagateRe', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'canBeInvoiced', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'canCreateTicket', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'consumption', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'createAddress', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'createWithUser', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'extendedListFilter', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'getAverageInvoiced', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'getCard', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'getDebt', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'getMana', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'transactions', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'hasCustomerRole', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'isValidClient', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'lastActiveTickets', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'sendSms', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'setPassword', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'summary', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'updateAddress', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'updateFiscalData', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'updateUser', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'uploadFile', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'campaignMetricsPdf', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'campaignMetricsEmail', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'clientWelcomeHtml', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'clientWelcomeEmail', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'printerSetupHtml', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'printerSetupEmail', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'sepaCoreEmail', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'letterDebtorPdf', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'letterDebtorStHtml', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'letterDebtorStEmail', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'letterDebtorNdHtml', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'letterDebtorNdEmail', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'clientDebtStatementPdf', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'clientDebtStatementHtml', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'clientDebtStatementEmail', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'creditRequestPdf', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'creditRequestHtml', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'creditRequestEmail', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'incotermsAuthorizationPdf', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'incotermsAuthorizationHtml', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'incotermsAuthorizationEmail', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'consumptionSendQueued', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'filter', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'getClientOrSupplierReference', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'upsert', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'create', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'replaceById', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'updateAttributes', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'updateAttributes', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'deleteById', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'replaceOrCreate', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'updateAll', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'upsertWithWhere', '*', 'ALLOW', 'ROLE', 'employee'); diff --git a/db/changes/231601/00-client_setRatingAcl.sql b/db/changes/231601/00-client_setRatingAcl.sql index b041b131a..6687b11ec 100644 --- a/db/changes/231601/00-client_setRatingAcl.sql +++ b/db/changes/231601/00-client_setRatingAcl.sql @@ -27,7 +27,6 @@ INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalTyp ('Client', 'summary', '*', 'ALLOW', 'ROLE', 'employee'), ('Client', 'updateAddress', '*', 'ALLOW', 'ROLE', 'employee'), ('Client', 'updateFiscalData', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'updateUser', '*', 'ALLOW', 'ROLE', 'employee'), ('Client', 'uploadFile', '*', 'ALLOW', 'ROLE', 'employee'), ('Client', 'campaignMetricsPdf', '*', 'ALLOW', 'ROLE', 'employee'), ('Client', 'campaignMetricsEmail', '*', 'ALLOW', 'ROLE', 'employee'), diff --git a/db/changes/231601/00-useSpecificsAcls.sql b/db/changes/231601/00-useSpecificsAcls.sql index 24d3c5723..bd9642f30 100644 --- a/db/changes/231601/00-useSpecificsAcls.sql +++ b/db/changes/231601/00-useSpecificsAcls.sql @@ -6,4 +6,15 @@ INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `pri ('Agency', 'seeExpired', 'READ', 'ALLOW', 'ROLE', 'productionBoss'), ('Claim', 'createAfterDeadline', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'), ('Client', 'editAddressLogifloraAllowed', 'WRITE', 'ALLOW', 'ROLE', 'salesAssistant'), + ('Client', 'editFiscalDataWithoutTaxDataCheck', 'WRITE', 'ALLOW', 'ROLE', 'salesAssistant'), + ('Client', 'editVerifiedDataWithoutTaxDataCheck', 'WRITE', 'ALLOW', 'ROLE', 'salesAssistant'), + ('Client', 'editCredit', 'WRITE', 'ALLOW', 'ROLE', 'financialBoss'), + ('Client', 'isNotEditableCredit', 'WRITE', 'ALLOW', 'ROLE', 'financialBoss'), + ('InvoiceOut', 'canCreatePdf', 'WRITE', 'ALLOW', 'ROLE', 'invoicing'), ('Claim', 'editState', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'); + +DELETE FROM `salix`.`ACL` + WHERE + model = 'Claim' + AND property = '*' + AND accessType = '*'; diff --git a/db/changes/231601/01-ClaimReAcl.sql b/db/changes/231601/01-ClaimReAcl.sql deleted file mode 100644 index c30ec2123..000000000 --- a/db/changes/231601/01-ClaimReAcl.sql +++ /dev/null @@ -1,2 +0,0 @@ -DELETE FROM salix.ACL -WHERE id=101; diff --git a/modules/claim/back/methods/claim/updateClaim.js b/modules/claim/back/methods/claim/updateClaim.js index f10c68b21..cc7392e39 100644 --- a/modules/claim/back/methods/claim/updateClaim.js +++ b/modules/claim/back/methods/claim/updateClaim.js @@ -46,7 +46,6 @@ module.exports = Self => { Self.updateClaim = async(ctx, id, options) => { const models = Self.app.models; - const userId = ctx.req.accessToken.userId; const args = ctx.args; let tx; const myOptions = {}; @@ -81,9 +80,9 @@ module.exports = Self => { if (args.claimStateFk) { const canEditOldState = await models.ClaimState.isEditable(ctx, claim.claimStateFk, myOptions); const canEditNewState = await models.ClaimState.isEditable(ctx, args.claimStateFk, myOptions); - const isClaimManager = await models.VnUser.hasRole(userId, 'claimManager', myOptions); + const canEditState = await models.ACL.checkAccessAcl(ctx, 'Claim', 'editState', 'WRITE'); - if (!canEditOldState || !canEditNewState || changedHasToPickUp && !isClaimManager) + if (!canEditOldState || !canEditNewState || changedHasToPickUp && !canEditState) throw new UserError(`You don't have enough privileges to change that field`); } diff --git a/modules/client/back/methods/client/updateFiscalData.js b/modules/client/back/methods/client/updateFiscalData.js index c63dc3991..697c567a3 100644 --- a/modules/client/back/methods/client/updateFiscalData.js +++ b/modules/client/back/methods/client/updateFiscalData.js @@ -131,9 +131,10 @@ module.exports = Self => { myOptions.transaction = tx; } try { - const isSalesAssistant = await models.VnUser.hasRole(userId, 'salesAssistant', myOptions); + const canEditNotTaxDataChecked = + await models.ACL.checkAccessAcl(ctx, 'Client', 'editFiscalDataWithoutTaxDataCheck', 'WRITE'); const client = await models.Client.findById(clientId, null, myOptions); - if (!isSalesAssistant && client.isTaxDataChecked) + if (!canEditNotTaxDataChecked && client.isTaxDataChecked) throw new UserError(`Not enough privileges to edit a client with verified data`); // Sage data validation const taxDataChecked = args.isTaxDataChecked; diff --git a/modules/client/back/methods/client/updateUser.js b/modules/client/back/methods/client/updateUser.js index 479b4da47..55f1accdd 100644 --- a/modules/client/back/methods/client/updateUser.js +++ b/modules/client/back/methods/client/updateUser.js @@ -2,6 +2,7 @@ const UserError = require('vn-loopback/util/user-error'); module.exports = Self => { Self.remoteMethodCtx('updateUser', { description: 'Updates the user information', + accessType: 'WRITE', accepts: [ { arg: 'id', @@ -32,7 +33,6 @@ module.exports = Self => { Self.updateUser = async function(ctx, id, options) { const models = Self.app.models; - const userId = ctx.req.accessToken.userId; let tx; const myOptions = {}; @@ -45,9 +45,8 @@ module.exports = Self => { } try { - const isSalesPerson = await models.VnUser.hasRole(userId, 'salesPerson', myOptions); - - if (!isSalesPerson) + const canEdit = await models.ACL.checkAccessAcl(ctx, 'Client', 'updateUser', 'WRITE'); + if (!canEdit) throw new UserError(`Not enough privileges to edit a client`); const isClient = await models.Client.findById(id, null, myOptions); diff --git a/modules/client/back/models/client.js b/modules/client/back/models/client.js index a86a782e4..26813cf2b 100644 --- a/modules/client/back/models/client.js +++ b/modules/client/back/models/client.js @@ -217,9 +217,9 @@ module.exports = Self => { const models = Self.app.models; const loopBackContext = LoopBackContext.getCurrentContext(); - const userId = loopBackContext.active.accessToken.userId; + const accessToken = {req: loopBackContext.active.accessToken}; - const isSalesAssistant = await models.VnUser.hasRole(userId, 'salesAssistant', ctx.options); + const editVerifiedDataWithoutTaxDataChecked = models.ACL.checkAccessAcl(accessToken, 'Client', 'editVerifiedDataWithoutTaxDataCheck', 'WRITE'); const hasChanges = orgData && changes; const isTaxDataChecked = hasChanges && (changes.isTaxDataChecked || orgData.isTaxDataChecked); @@ -231,8 +231,8 @@ module.exports = Self => { const sageTransactionType = hasChanges && (changes.sageTransactionTypeFk || orgData.sageTransactionTypeFk); const sageTransactionTypeChanged = hasChanges && orgData.sageTransactionTypeFk != sageTransactionType; - const cantEditVerifiedData = isTaxDataCheckedChanged && !isSalesAssistant; - const cantChangeSageData = (sageTaxTypeChanged || sageTransactionTypeChanged) && !isSalesAssistant; + const cantEditVerifiedData = isTaxDataCheckedChanged && !editVerifiedDataWithoutTaxDataChecked; + const cantChangeSageData = (sageTaxTypeChanged || sageTransactionTypeChanged) && !editVerifiedDataWithoutTaxDataChecked; if (cantEditVerifiedData || cantChangeSageData) throw new UserError(`You don't have enough privileges`); @@ -400,9 +400,10 @@ module.exports = Self => { Self.changeCredit = async function changeCredit(ctx, finalState, changes) { const models = Self.app.models; const userId = ctx.options.accessToken.userId; + const accessToken = {req: {accessToken: ctx.options.accessToken} }; - const isFinancialBoss = await models.VnUser.hasRole(userId, 'financialBoss', ctx.options); - if (!isFinancialBoss) { + const canEditCredit = await models.ACL.checkAccessAcl(accessToken, 'Client', 'editCredit', 'WRITE'); + if (!canEditCredit) { const lastCredit = await models.ClientCredit.findOne({ where: { clientFk: finalState.id @@ -411,10 +412,9 @@ module.exports = Self => { }, ctx.options); const lastAmount = lastCredit && lastCredit.amount; - const lastWorkerId = lastCredit && lastCredit.workerFk; - const lastWorkerIsFinancialBoss = await models.VnUser.hasRole(lastWorkerId, 'financialBoss', ctx.options); + const lastCreditIsNotEditable = !await models.ACL.checkAccessAcl(accessToken, 'Client', 'isNotEditableCredit', 'WRITE'); - if (lastAmount == 0 && lastWorkerIsFinancialBoss) + if (lastAmount == 0 && lastCreditIsNotEditable) throw new UserError(`You can't change the credit set to zero from a financialBoss`); const creditLimits = await models.ClientCreditLimit.find({ diff --git a/modules/invoiceOut/back/methods/invoiceOut/createPdf.js b/modules/invoiceOut/back/methods/invoiceOut/createPdf.js index a9c151ae4..dfdb3c1a7 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/createPdf.js +++ b/modules/invoiceOut/back/methods/invoiceOut/createPdf.js @@ -25,7 +25,6 @@ module.exports = Self => { Self.createPdf = async function(ctx, id, options) { const models = Self.app.models; - const userId = ctx.req.accessToken.userId; if (process.env.NODE_ENV == 'test') throw new UserError(`Action not allowed on the test environment`); @@ -43,9 +42,9 @@ module.exports = Self => { try { const invoiceOut = await Self.findById(id, null, myOptions); - const hasInvoicing = await models.VnUser.hasRole(userId, 'invoicing', myOptions); + const canCreatePdf = await models.ACL.checkAccessAcl(ctx, 'InvoiceOut', 'canCreatePdf', 'WRITE'); - if (invoiceOut.hasPdf && !hasInvoicing) + if (invoiceOut.hasPdf && !canCreatePdf) throw new UserError(`You don't have enough privileges`); await invoiceOut.updateAttributes({ From 4cb231759fa47f69134b4fd67ee1cd1fed6a7e4a Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 25 Apr 2023 09:15:05 +0200 Subject: [PATCH 09/61] feat(State/Supplier): replace hasRole to acls --- db/changes/231601/00-useSpecificsAcls.sql | 11 +++++++++++ modules/supplier/back/models/supplier.js | 10 ++++++---- modules/ticket/back/methods/state/editableStates.js | 12 ++++++------ modules/ticket/back/methods/state/isEditable.js | 3 +++ 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/db/changes/231601/00-useSpecificsAcls.sql b/db/changes/231601/00-useSpecificsAcls.sql index bd9642f30..9b9b3cebb 100644 --- a/db/changes/231601/00-useSpecificsAcls.sql +++ b/db/changes/231601/00-useSpecificsAcls.sql @@ -2,6 +2,10 @@ INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `pri VALUES ('Ticket', 'editDiscount', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'), ('Ticket', 'editDiscount', 'WRITE', 'ALLOW', 'ROLE', 'salesPerson'), + ('State', 'editableStates', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('State', 'seeEditableStates', 'READ', 'ALLOW', 'ROLE', 'administrative'), + ('State', 'seeEditableStates', 'READ', 'ALLOW', 'ROLE', 'production'), + ('State', 'seeFilteredEditableStates', 'READ', 'ALLOW', 'ROLE', 'salesPerson'), ('Agency', 'seeExpired', 'READ', 'ALLOW', 'ROLE', 'administrative'), ('Agency', 'seeExpired', 'READ', 'ALLOW', 'ROLE', 'productionBoss'), ('Claim', 'createAfterDeadline', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'), @@ -11,6 +15,7 @@ INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `pri ('Client', 'editCredit', 'WRITE', 'ALLOW', 'ROLE', 'financialBoss'), ('Client', 'isNotEditableCredit', 'WRITE', 'ALLOW', 'ROLE', 'financialBoss'), ('InvoiceOut', 'canCreatePdf', 'WRITE', 'ALLOW', 'ROLE', 'invoicing'), + ('Supplier', 'editPayMethodCheck', 'WRITE', 'ALLOW', 'ROLE', 'financial'), ('Claim', 'editState', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'); DELETE FROM `salix`.`ACL` @@ -18,3 +23,9 @@ DELETE FROM `salix`.`ACL` model = 'Claim' AND property = '*' AND accessType = '*'; + +DELETE FROM `salix`.`ACL` + WHERE + model = 'State' + AND property = '*' + AND accessType = 'READ'; diff --git a/modules/supplier/back/models/supplier.js b/modules/supplier/back/models/supplier.js index c4ce0c517..c67f0055e 100644 --- a/modules/supplier/back/models/supplier.js +++ b/modules/supplier/back/models/supplier.js @@ -98,18 +98,20 @@ module.exports = Self => { Self.observe('before save', async function(ctx) { if (ctx.isNewInstance) return; - const loopbackContext = LoopBackContext.getCurrentContext(); const changes = ctx.data || ctx.instance; const orgData = ctx.currentInstance; - const userId = loopbackContext.active.accessToken.userId; + const loopBackContext = LoopBackContext.getCurrentContext(); + const accessToken = {req: loopBackContext.active.accessToken}; + + const editPayMethodCheck = + await Self.app.models.ACL.checkAccessAcl(accessToken, 'Supplier', 'editPayMethodCheck', 'WRITE'); - const isNotFinancial = !await Self.app.models.VnUser.hasRole(userId, 'financial'); const isPayMethodChecked = changes.isPayMethodChecked || orgData.isPayMethodChecked; const hasChanges = orgData && changes; const isPayMethodCheckedChanged = hasChanges && orgData.isPayMethodChecked != isPayMethodChecked; - if (isNotFinancial && isPayMethodCheckedChanged) + if (!editPayMethodCheck && isPayMethodCheckedChanged) throw new UserError('You can not modify is pay method checked'); }); diff --git a/modules/ticket/back/methods/state/editableStates.js b/modules/ticket/back/methods/state/editableStates.js index 061097a65..9c103c0b6 100644 --- a/modules/ticket/back/methods/state/editableStates.js +++ b/modules/ticket/back/methods/state/editableStates.js @@ -18,21 +18,21 @@ module.exports = Self => { Self.editableStates = async(ctx, filter, options) => { const models = Self.app.models; - const userId = ctx.req.accessToken.userId; const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); let statesList = await models.State.find(filter, myOptions); - const isProduction = await models.VnUser.hasRole(userId, 'production', myOptions); - const isSalesPerson = await models.VnUser.hasRole(userId, 'salesPerson', myOptions); - const isAdministrative = await models.VnUser.hasRole(userId, 'administrative', myOptions); + const seeEditableStates = await models.ACL.checkAccessAcl(ctx, 'State', 'seeEditableStates', 'READ'); - if (isProduction || isAdministrative) + if (seeEditableStates) return statesList; - if (isSalesPerson) { + const seeFilteredEditableStates = + await models.ACL.checkAccessAcl(ctx, 'State', 'seeFilteredEditableStates', 'READ'); + + if (seeFilteredEditableStates) { return statesList = statesList.filter(stateList => stateList.alertLevel === 0 || stateList.code === 'PICKER_DESIGNED' ); diff --git a/modules/ticket/back/methods/state/isEditable.js b/modules/ticket/back/methods/state/isEditable.js index 730e6b9eb..5d5f6a205 100644 --- a/modules/ticket/back/methods/state/isEditable.js +++ b/modules/ticket/back/methods/state/isEditable.js @@ -30,6 +30,9 @@ module.exports = Self => { const isProduction = await models.VnUser.hasRole(userId, 'production', myOptions); const isSalesPerson = await models.VnUser.hasRole(userId, 'salesPerson', myOptions); const isAdministrative = await models.VnUser.hasRole(userId, 'administrative', myOptions); + // const isEditableAlertLevel = + // await Self.app.models.ACL.checkAccessAcl(accessToken, 'Supplier', 'editPayMethodCheck', 'WRITE'); + const state = await models.State.findById(stateId, null, myOptions); const salesPersonAllowed = (isSalesPerson && (state.code == 'PICKER_DESIGNED' || state.code == 'PRINTED')); From 0c668c6ade80a7b5578870d5065d357db616954d Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 25 Apr 2023 14:17:36 +0200 Subject: [PATCH 10/61] refs #5488 feat(): replace all hasRole to checkAccessAcl --- db/changes/231601/00-useSpecificsAcls.sql | 32 ++++++++++++++++++- .../ticket/back/methods/state/isEditable.js | 18 +++++------ .../back/methods/ticket/componentUpdate.js | 4 +-- .../back/methods/ticket/isRoleAdvanced.js | 18 ++--------- .../back/methods/ticket/priceDifference.js | 5 ++- .../ticket/back/methods/ticket/setDeleted.js | 6 ++-- .../worker-time-control/addTimeEntry.js | 4 +-- .../worker-time-control/deleteTimeEntry.js | 2 +- .../worker-time-control/updateTimeEntry.js | 2 +- .../back/methods/worker/createAbsence.js | 2 +- .../back/methods/worker/deleteAbsence.js | 2 +- .../back/methods/worker/isSubordinate.js | 7 ++-- .../back/methods/worker/updateAbsence.js | 2 +- 13 files changed, 58 insertions(+), 46 deletions(-) diff --git a/db/changes/231601/00-useSpecificsAcls.sql b/db/changes/231601/00-useSpecificsAcls.sql index 9b9b3cebb..01906d09c 100644 --- a/db/changes/231601/00-useSpecificsAcls.sql +++ b/db/changes/231601/00-useSpecificsAcls.sql @@ -2,10 +2,19 @@ INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `pri VALUES ('Ticket', 'editDiscount', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'), ('Ticket', 'editDiscount', 'WRITE', 'ALLOW', 'ROLE', 'salesPerson'), + ('Ticket', 'hasRoleAdvanced', '*', 'ALLOW', 'ROLE', 'salesAssistant'), + ('Ticket', 'hasRoleAdvanced', '*', 'ALLOW', 'ROLE', 'deliveryBoss'), + ('Ticket', 'hasRoleAdvanced', '*', 'ALLOW', 'ROLE', 'buyer'), + ('Ticket', 'hasRoleAdvanced', '*', 'ALLOW', 'ROLE', 'claimManager'), + ('Ticket', 'deleteTicketWithPartPrepared', 'WRITE', 'ALLOW', 'ROLE', 'salesAssistant'), + ('Ticket', 'editZone', 'WRITE', 'ALLOW', 'ROLE', 'deliveryBoss'), ('State', 'editableStates', 'READ', 'ALLOW', 'ROLE', 'employee'), ('State', 'seeEditableStates', 'READ', 'ALLOW', 'ROLE', 'administrative'), ('State', 'seeEditableStates', 'READ', 'ALLOW', 'ROLE', 'production'), ('State', 'seeFilteredEditableStates', 'READ', 'ALLOW', 'ROLE', 'salesPerson'), + ('State', 'isSomeEditable', 'READ', 'ALLOW', 'ROLE', 'salesPerson'), + ('State', 'isAllEditable', 'READ', 'ALLOW', 'ROLE', 'production'), + ('State', 'isAllEditable', 'READ', 'ALLOW', 'ROLE', 'administrative'), ('Agency', 'seeExpired', 'READ', 'ALLOW', 'ROLE', 'administrative'), ('Agency', 'seeExpired', 'READ', 'ALLOW', 'ROLE', 'productionBoss'), ('Claim', 'createAfterDeadline', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'), @@ -16,7 +25,10 @@ INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `pri ('Client', 'isNotEditableCredit', 'WRITE', 'ALLOW', 'ROLE', 'financialBoss'), ('InvoiceOut', 'canCreatePdf', 'WRITE', 'ALLOW', 'ROLE', 'invoicing'), ('Supplier', 'editPayMethodCheck', 'WRITE', 'ALLOW', 'ROLE', 'financial'), - ('Claim', 'editState', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'); + ('Worker', 'isTeamBoss', 'WRITE', 'ALLOW', 'ROLE', 'teamBoss'), + ('Worker', 'forceIsSubordinate', 'READ', 'ALLOW', 'ROLE', 'hr'), + ('Claim', 'editState', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'), + ('Claim', 'filter', 'READ', 'ALLOW', 'ROLE', 'employee'); DELETE FROM `salix`.`ACL` WHERE @@ -24,8 +36,26 @@ DELETE FROM `salix`.`ACL` AND property = '*' AND accessType = '*'; +DELETE FROM `salix`.`ACL` + WHERE + model = 'Ticket' + AND property = '*' + AND accessType = '*'; + DELETE FROM `salix`.`ACL` WHERE model = 'State' AND property = '*' AND accessType = 'READ'; + +DELETE FROM `salix`.`ACL` + WHERE + model = 'Worker' + AND property = '*' + AND accessType = 'READ'; + +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES + ('State', 'find', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('State', 'findById', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('State', 'findOne', 'READ', 'ALLOW', 'ROLE', 'employee'); diff --git a/modules/ticket/back/methods/state/isEditable.js b/modules/ticket/back/methods/state/isEditable.js index 5d5f6a205..ec246c61f 100644 --- a/modules/ticket/back/methods/state/isEditable.js +++ b/modules/ticket/back/methods/state/isEditable.js @@ -19,25 +19,23 @@ module.exports = Self => { }); Self.isEditable = async(ctx, stateId, options) => { - const accessToken = ctx.req.accessToken; const models = Self.app.models; - const userId = accessToken.userId; const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); - const isProduction = await models.VnUser.hasRole(userId, 'production', myOptions); - const isSalesPerson = await models.VnUser.hasRole(userId, 'salesPerson', myOptions); - const isAdministrative = await models.VnUser.hasRole(userId, 'administrative', myOptions); - // const isEditableAlertLevel = - // await Self.app.models.ACL.checkAccessAcl(accessToken, 'Supplier', 'editPayMethodCheck', 'WRITE'); + const isAllEditable = await models.ACL.checkAccessAcl(ctx, 'State', 'isAllEditable', 'READ'); const state = await models.State.findById(stateId, null, myOptions); + const isSomeEditable = ( + await models.ACL.checkAccessAcl(ctx, 'State', 'isSomeEditable', 'READ') + && ( + state.code == 'PICKER_DESIGNED' || state.code == 'PRINTED' + ) + ); - const salesPersonAllowed = (isSalesPerson && (state.code == 'PICKER_DESIGNED' || state.code == 'PRINTED')); - - const isAllowed = isProduction || isAdministrative || salesPersonAllowed || state.alertLevel == 0; + const isAllowed = isAllEditable || isSomeEditable || state.alertLevel == 0; return isAllowed; }; }; diff --git a/modules/ticket/back/methods/ticket/componentUpdate.js b/modules/ticket/back/methods/ticket/componentUpdate.js index 531d13b51..65247bb4e 100644 --- a/modules/ticket/back/methods/ticket/componentUpdate.js +++ b/modules/ticket/back/methods/ticket/componentUpdate.js @@ -121,8 +121,8 @@ module.exports = Self => { if (!isEditable) throw new UserError(`The sales of this ticket can't be modified`); - const isDeliveryBoss = await models.VnUser.hasRole(userId, 'deliveryBoss', myOptions); - if (!isDeliveryBoss) { + const editZone = await models.ACL.checkAccessAcl(ctx, 'Ticket', 'editZone', 'WRITE'); + if (!editZone) { const zoneShipped = await models.Agency.getShipped( args.landed, args.addressFk, diff --git a/modules/ticket/back/methods/ticket/isRoleAdvanced.js b/modules/ticket/back/methods/ticket/isRoleAdvanced.js index d6186a0c9..df6ef164c 100644 --- a/modules/ticket/back/methods/ticket/isRoleAdvanced.js +++ b/modules/ticket/back/methods/ticket/isRoleAdvanced.js @@ -12,21 +12,7 @@ module.exports = Self => { } }); - Self.isRoleAdvanced = async(ctx, options) => { - const models = Self.app.models; - const userId = ctx.req.accessToken.userId; - const myOptions = {}; - - if (typeof options == 'object') - Object.assign(myOptions, options); - - const isSalesAssistant = await models.VnUser.hasRole(userId, 'salesAssistant', myOptions); - const isDeliveryBoss = await models.VnUser.hasRole(userId, 'deliveryBoss', myOptions); - const isBuyer = await models.VnUser.hasRole(userId, 'buyer', myOptions); - const isClaimManager = await models.VnUser.hasRole(userId, 'claimManager', myOptions); - - const isRoleAdvanced = isSalesAssistant || isDeliveryBoss || isBuyer || isClaimManager; - - return isRoleAdvanced; + Self.isRoleAdvanced = async ctx => { + return Self.app.models.ACL.checkAccessAcl(ctx, 'Ticket', 'hasRoleAdvanced', '*'); }; }; diff --git a/modules/ticket/back/methods/ticket/priceDifference.js b/modules/ticket/back/methods/ticket/priceDifference.js index a0a10d997..4f9bffa99 100644 --- a/modules/ticket/back/methods/ticket/priceDifference.js +++ b/modules/ticket/back/methods/ticket/priceDifference.js @@ -60,7 +60,6 @@ module.exports = Self => { Self.priceDifference = async(ctx, options) => { const args = ctx.args; const models = Self.app.models; - const userId = ctx.req.accessToken.userId; const myOptions = {}; let tx; @@ -78,8 +77,8 @@ module.exports = Self => { if (!isEditable) throw new UserError(`The sales of this ticket can't be modified`); - const isDeliveryBoss = await models.VnUser.hasRole(userId, 'deliveryBoss', myOptions); - if (!isDeliveryBoss) { + const editZone = await models.ACL.checkAccessAcl(ctx, 'Ticket', 'editZone', 'WRITE'); + if (!editZone) { const zoneShipped = await models.Agency.getShipped( args.landed, args.addressId, diff --git a/modules/ticket/back/methods/ticket/setDeleted.js b/modules/ticket/back/methods/ticket/setDeleted.js index 2889160d1..81c95529f 100644 --- a/modules/ticket/back/methods/ticket/setDeleted.js +++ b/modules/ticket/back/methods/ticket/setDeleted.js @@ -36,7 +36,6 @@ module.exports = Self => { } try { - const userId = ctx.req.accessToken.userId; const isEditable = await Self.isEditable(ctx, id, myOptions); if (!isEditable) @@ -51,7 +50,8 @@ module.exports = Self => { throw new UserError($t('Tickets with associated refunds', {id: ticketRefunds[0].id})); // Check if has sales with shelving - const isSalesAssistant = await models.VnUser.hasRole(userId, 'salesAssistant', myOptions); + const canDeleteTicketWithPartPrepared = + await models.ACL.checkAccessAcl(ctx, 'Ticket', 'deleteTicketWithPartPrepared', 'WRITE'); const sales = await models.Sale.find({ include: {relation: 'itemShelvingSale'}, where: {ticketFk: id} @@ -60,7 +60,7 @@ module.exports = Self => { return sale.itemShelvingSale(); }); - if (hasItemShelvingSales && !isSalesAssistant) + if (hasItemShelvingSales && !canDeleteTicketWithPartPrepared) throw new UserError(`You cannot delete a ticket that part of it is being prepared`); // Check for existing claim diff --git a/modules/worker/back/methods/worker-time-control/addTimeEntry.js b/modules/worker/back/methods/worker-time-control/addTimeEntry.js index 01a5a16ee..bcc96985f 100644 --- a/modules/worker/back/methods/worker-time-control/addTimeEntry.js +++ b/modules/worker/back/methods/worker-time-control/addTimeEntry.js @@ -40,10 +40,10 @@ module.exports = Self => { Object.assign(myOptions, options); const isSubordinate = await models.Worker.isSubordinate(ctx, workerId, myOptions); - const isTeamBoss = await models.VnUser.hasRole(currentUserId, 'teamBoss', myOptions); + const isTeamBoss = await models.ACL.checkAccessAcl(ctx, 'Worker', 'isTeamBoss', 'WRITE'); const isHimself = currentUserId == workerId; - if (isSubordinate === false || (isSubordinate && isHimself && !isTeamBoss)) + if (!isSubordinate || (isSubordinate && isHimself && !isTeamBoss)) throw new UserError(`You don't have enough privileges`); query = `CALL vn.workerTimeControl_clockIn(?,?,?)`; diff --git a/modules/worker/back/methods/worker-time-control/deleteTimeEntry.js b/modules/worker/back/methods/worker-time-control/deleteTimeEntry.js index 1dcd12f5b..80482901f 100644 --- a/modules/worker/back/methods/worker-time-control/deleteTimeEntry.js +++ b/modules/worker/back/methods/worker-time-control/deleteTimeEntry.js @@ -32,7 +32,7 @@ module.exports = Self => { const targetTimeEntry = await Self.findById(id, null, myOptions); const isSubordinate = await models.Worker.isSubordinate(ctx, targetTimeEntry.userFk, myOptions); - const isTeamBoss = await models.VnUser.hasRole(currentUserId, 'teamBoss', myOptions); + const isTeamBoss = await models.ACL.checkAccessAcl(ctx, 'Worker', 'isTeamBoss', 'WRITE'); const isHimself = currentUserId == targetTimeEntry.userFk; if (isSubordinate === false || (isSubordinate && isHimself && !isTeamBoss)) diff --git a/modules/worker/back/methods/worker-time-control/updateTimeEntry.js b/modules/worker/back/methods/worker-time-control/updateTimeEntry.js index 344421311..8231be7bb 100644 --- a/modules/worker/back/methods/worker-time-control/updateTimeEntry.js +++ b/modules/worker/back/methods/worker-time-control/updateTimeEntry.js @@ -38,7 +38,7 @@ module.exports = Self => { const targetTimeEntry = await Self.findById(id, null, myOptions); const isSubordinate = await models.Worker.isSubordinate(ctx, targetTimeEntry.userFk, myOptions); - const isTeamBoss = await models.VnUser.hasRole(currentUserId, 'teamBoss', myOptions); + const isTeamBoss = await models.ACL.checkAccessAcl(ctx, 'Worker', 'isTeamBoss', 'WRITE'); const isHimself = currentUserId == targetTimeEntry.userFk; const notAllowed = isSubordinate === false || (isSubordinate && isHimself && !isTeamBoss); diff --git a/modules/worker/back/methods/worker/createAbsence.js b/modules/worker/back/methods/worker/createAbsence.js index f53164a50..cb2cf8330 100644 --- a/modules/worker/back/methods/worker/createAbsence.js +++ b/modules/worker/back/methods/worker/createAbsence.js @@ -53,7 +53,7 @@ module.exports = Self => { try { const isSubordinate = await models.Worker.isSubordinate(ctx, id, myOptions); - const isTeamBoss = await models.VnUser.hasRole(userId, 'teamBoss', myOptions); + const isTeamBoss = await models.ACL.checkAccessAcl(ctx, 'Worker', 'isTeamBoss', 'WRITE'); if (!isSubordinate || (isSubordinate && userId == id && !isTeamBoss)) throw new UserError(`You don't have enough privileges`); diff --git a/modules/worker/back/methods/worker/deleteAbsence.js b/modules/worker/back/methods/worker/deleteAbsence.js index 2d0078ba7..c315f5178 100644 --- a/modules/worker/back/methods/worker/deleteAbsence.js +++ b/modules/worker/back/methods/worker/deleteAbsence.js @@ -40,7 +40,7 @@ module.exports = Self => { try { const isSubordinate = await models.Worker.isSubordinate(ctx, id, myOptions); - const isTeamBoss = await models.VnUser.hasRole(userId, 'teamBoss', myOptions); + const isTeamBoss = await models.ACL.checkAccessAcl(ctx, 'Worker', 'isTeamBoss', 'WRITE'); if (!isSubordinate || (isSubordinate && userId == id && !isTeamBoss)) throw new UserError(`You don't have enough privileges`); diff --git a/modules/worker/back/methods/worker/isSubordinate.js b/modules/worker/back/methods/worker/isSubordinate.js index 6c17ad0d0..9a1f1e683 100644 --- a/modules/worker/back/methods/worker/isSubordinate.js +++ b/modules/worker/back/methods/worker/isSubordinate.js @@ -25,8 +25,6 @@ module.exports = Self => { Self.isSubordinate = async(ctx, id, options) => { const models = Self.app.models; - const myUserId = ctx.req.accessToken.userId; - const myOptions = {}; if (typeof options == 'object') @@ -37,8 +35,9 @@ module.exports = Self => { return subordinate.workerFk == id; }); - const isHr = await models.VnUser.hasRole(myUserId, 'hr', myOptions); - if (isHr || isSubordinate) + const forceIsSubordinate = await models.ACL.checkAccessAcl(ctx, 'Worker', 'forceIsSubordinate', 'READ'); + + if (forceIsSubordinate || isSubordinate) return true; return false; diff --git a/modules/worker/back/methods/worker/updateAbsence.js b/modules/worker/back/methods/worker/updateAbsence.js index d904c2c14..5e13097a0 100644 --- a/modules/worker/back/methods/worker/updateAbsence.js +++ b/modules/worker/back/methods/worker/updateAbsence.js @@ -30,7 +30,7 @@ module.exports = Self => { const models = Self.app.models; const userId = ctx.req.accessToken.userId; const isSubordinate = await models.Worker.isSubordinate(ctx, id); - const isTeamBoss = await models.VnUser.hasRole(userId, 'teamBoss'); + const isTeamBoss = await models.ACL.checkAccessAcl(ctx, 'Worker', 'isTeamBoss', 'WRITE'); if (!isSubordinate || (isSubordinate && userId == id && !isTeamBoss)) throw new UserError(`You don't have enough privileges`); From c62f8e1c14a3dc72aa30921970d746e9cc7b9abb Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 26 Apr 2023 12:13:14 +0200 Subject: [PATCH 11/61] refs #5297 feat(worker): iban and bankEntity not required --- e2e/paths/03-worker/06_create.spec.js | 1 - modules/worker/back/methods/worker/new.js | 22 +++++++++---------- .../back/methods/worker/specs/new.spec.js | 2 -- modules/worker/front/create/index.js | 5 +++++ 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/e2e/paths/03-worker/06_create.spec.js b/e2e/paths/03-worker/06_create.spec.js index 98e67edbf..203d9ba9a 100644 --- a/e2e/paths/03-worker/06_create.spec.js +++ b/e2e/paths/03-worker/06_create.spec.js @@ -25,7 +25,6 @@ describe('Worker create path', () => { await page.write(selectors.workerCreate.postcode, '46680'); await page.write(selectors.workerCreate.street, 'S/ Doomstadt'); await page.write(selectors.workerCreate.email, 'doctorDoom@marvel.com'); - await page.write(selectors.workerCreate.iban, 'ES9121000418450200051332'); // should check for autocompleted worker code and worker user name const workerCode = await page diff --git a/modules/worker/back/methods/worker/new.js b/modules/worker/back/methods/worker/new.js index 144b07f10..68f962254 100644 --- a/modules/worker/back/methods/worker/new.js +++ b/modules/worker/back/methods/worker/new.js @@ -54,18 +54,6 @@ module.exports = Self => { description: `The worker province`, required: true, }, - { - arg: 'iban', - type: 'string', - description: `The worker iban`, - required: true, - }, - { - arg: 'bankEntityFk', - type: 'number', - description: `The worker bank entity`, - required: true, - }, { arg: 'companyFk', type: 'number', @@ -101,6 +89,16 @@ module.exports = Self => { type: 'date', description: `The worker birth`, required: true, + }, + { + arg: 'iban', + type: 'string', + description: `The worker iban`, + }, + { + arg: 'bankEntityFk', + type: 'number', + description: `The worker bank entity`, } ], returns: { diff --git a/modules/worker/back/methods/worker/specs/new.spec.js b/modules/worker/back/methods/worker/specs/new.spec.js index dbcc66683..d2c6157fb 100644 --- a/modules/worker/back/methods/worker/specs/new.spec.js +++ b/modules/worker/back/methods/worker/specs/new.spec.js @@ -27,8 +27,6 @@ describe('Worker new', () => { street: 'S/ defaultWorkerStreet', city: 'defaultWorkerCity', provinceFk: 1, - iban: 'ES8304879798578129532677', - bankEntityFk: 128, companyFk: 442, postcode: '46680', phone: '123456789', diff --git a/modules/worker/front/create/index.js b/modules/worker/front/create/index.js index 7966926b0..3db68b245 100644 --- a/modules/worker/front/create/index.js +++ b/modules/worker/front/create/index.js @@ -8,6 +8,11 @@ export default class Controller extends Section { } onSubmit() { + if (!this.worker.iban && !this.worker.bankEntityFk) { + delete this.worker.iban; + delete this.worker.bankEntityFk; + } + return this.$.watcher.submit().then(json => { this.$state.go('worker.card.basicData', {id: json.data.id}); }); From 42e3c8f29d82ca82dc96ba73f51bb4f12cf6ebe7 Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 28 Apr 2023 09:35:15 +0200 Subject: [PATCH 12/61] refs #5488 fix(): use hasWriteRole --- back/methods/dms/removeFile.js | 10 +-- back/methods/dms/updateFile.js | 2 +- back/methods/dms/uploadFile.js | 2 +- back/methods/image/download.js | 2 +- back/methods/image/upload.js | 2 +- back/models/dms-type.js | 55 ++++++++++++++-- back/models/dms-type.json | 29 ++------- back/models/dms.js | 4 +- back/models/image-collection.js | 64 +++++++++++++++++++ db/changes/231601/00-modelsAcls.sql | 28 -------- db/dump/fixtures.sql | 55 ++++++---------- .../back/methods/claim-state/isEditable.js | 11 +++- .../claim/back/methods/claim/uploadFile.js | 2 +- .../back/methods/worker-dms/downloadFile.js | 2 +- 14 files changed, 162 insertions(+), 106 deletions(-) create mode 100644 back/models/image-collection.js delete mode 100644 db/changes/231601/00-modelsAcls.sql diff --git a/back/methods/dms/removeFile.js b/back/methods/dms/removeFile.js index 8007407d5..a9ff36883 100644 --- a/back/methods/dms/removeFile.js +++ b/back/methods/dms/removeFile.js @@ -35,14 +35,14 @@ module.exports = Self => { try { const dms = await models.Dms.findById(id, null, myOptions); - - const hasWriteRole = await models.DmsType.checkRole(ctx, dms.dmsTypeFk, 'WRITE', myOptions); - if (!hasWriteRole) - throw new UserError(`You don't have enough privileges`); - const trashDmsType = await models.DmsType.findOne({ where: {code: 'trash'} }, myOptions); + + const hasWriteRole = await models.DmsType.hasWriteRole(ctx, dms.dmsTypeFk, myOptions); + if (!hasWriteRole) + throw new UserError(`You don't have enough privileges`); + await dms.updateAttribute('dmsTypeFk', trashDmsType.id, myOptions); if (tx) await tx.commit(); diff --git a/back/methods/dms/updateFile.js b/back/methods/dms/updateFile.js index 0ecced31a..cfc4c322f 100644 --- a/back/methods/dms/updateFile.js +++ b/back/methods/dms/updateFile.js @@ -71,7 +71,7 @@ module.exports = Self => { } try { - const hasWriteRole = await models.DmsType.checkRole(ctx, args.dmsTypeId, 'WRITE'); + const hasWriteRole = await models.DmsType.hasWriteRole(ctx, args.dmsTypeId); if (!hasWriteRole) throw new UserError(`You don't have enough privileges`); diff --git a/back/methods/dms/uploadFile.js b/back/methods/dms/uploadFile.js index ca1c1339d..a4212b804 100644 --- a/back/methods/dms/uploadFile.js +++ b/back/methods/dms/uploadFile.js @@ -66,7 +66,7 @@ module.exports = Self => { let srcFile; try { - const hasWriteRole = await models.DmsType.checkRole(ctx, args.dmsTypeId, 'WRITE'); + const hasWriteRole = await models.DmsType.hasWriteRole(ctx, args.dmsTypeId, myOptions); if (!hasWriteRole) throw new UserError(`You don't have enough privileges`); diff --git a/back/methods/image/download.js b/back/methods/image/download.js index e3e8c495c..c4037b809 100644 --- a/back/methods/image/download.js +++ b/back/methods/image/download.js @@ -67,7 +67,7 @@ module.exports = Self => { if (!image) return false; - const hasReadRole = await models.ACL.checkAccessAcl(ctx, 'ImageCollection', collection, 'READ'); + const hasReadRole = await models.ImageCollection.hasReadRole(ctx, collection); if (!hasReadRole) throw new UserError(`You don't have enough privileges`); diff --git a/back/methods/image/upload.js b/back/methods/image/upload.js index 1f89b9cc6..51da327f6 100644 --- a/back/methods/image/upload.js +++ b/back/methods/image/upload.js @@ -37,7 +37,7 @@ module.exports = Self => { let tempFilePath; try { - const hasWriteRole = await models.ACL.checkAccessAcl(ctx, 'ImageCollection', args.collection, 'WRITE'); + const hasWriteRole = await models.ImageCollection.hasWriteRole(ctx, args.collection); if (!hasWriteRole) throw new UserError(`You don't have enough privileges`); diff --git a/back/models/dms-type.js b/back/models/dms-type.js index 43f258319..c9329f30b 100644 --- a/back/models/dms-type.js +++ b/back/models/dms-type.js @@ -1,18 +1,65 @@ module.exports = Self => { + /** + * Checks if current user has + * read privileges over a dms + * + * @param {Object} ctx - Request context + * @param {Interger} id - DmsType id + * @param {Object} options - Query options + * @return {Boolean} True for user with read privileges + */ + Self.hasReadRole = async(ctx, id, options) => { + const models = Self.app.models; + const dmsType = await models.DmsType.findById(id, { + include: { + relation: 'readRole' + } + }, options); + + return await hasRole(ctx, dmsType, options); + }; + /** * Checks if current user has * write privileges over a dms * * @param {Object} ctx - Request context * @param {Interger} id - DmsType id - * @param {String} type - Acl accessType * @param {Object} options - Query options * @return {Boolean} True for user with write privileges */ - Self.checkRole = async(ctx, id, type, options) => { + Self.hasWriteRole = async(ctx, id, options) => { const models = Self.app.models; - const dmsType = await models.DmsType.findById(id, {fields: ['code']}, options); + const dmsType = await models.DmsType.findById(id, { + include: { + relation: 'writeRole' + } + }, options); - return await models.ACL.checkAccessAcl(ctx, 'DmsType', dmsType.code, type); + return await hasRole(ctx, dmsType, options); }; + + /** + * Checks if current user has + * read or write privileges + * @param {Object} ctx - Context + * @param {Object} dmsType - Dms type [read/write] + * @param {Object} options - Query options + */ + async function hasRole(ctx, dmsType, options) { + const models = Self.app.models; + const myUserId = ctx.req.accessToken.userId; + + const readRole = dmsType.readRole() && dmsType.readRole().name; + const writeRole = dmsType.writeRole() && dmsType.writeRole().name; + const requiredRole = readRole || writeRole; + + const hasRequiredRole = await models.VnUser.hasRole(myUserId, requiredRole, options); + const isRoot = await models.VnUser.hasRole(myUserId, 'root', options); + + if (isRoot || hasRequiredRole) + return true; + + return false; + } }; diff --git a/back/models/dms-type.json b/back/models/dms-type.json index c986060ac..de3d564b4 100644 --- a/back/models/dms-type.json +++ b/back/models/dms-type.json @@ -38,27 +38,10 @@ "foreignKey": "writeRoleFk" } }, - "acls": [ - { - "property": "find", - "accessType": "READ", - "principalType": "ROLE", - "principalId": "$everyone", - "permission": "ALLOW" - }, - { - "property": "findById", - "accessType": "READ", - "principalType": "ROLE", - "principalId": "$everyone", - "permission": "ALLOW" - }, - { - "property": "findOne", - "accessType": "READ", - "principalType": "ROLE", - "principalId": "$everyone", - "permission": "ALLOW" - } - ] + "acls": [{ + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + }] } diff --git a/back/models/dms.js b/back/models/dms.js index 8ecd10cb1..24c072f56 100644 --- a/back/models/dms.js +++ b/back/models/dms.js @@ -7,11 +7,11 @@ module.exports = Self => { require('../methods/dms/updateFile')(Self); require('../methods/dms/deleteTrashFiles')(Self); - Self.checkRole = async function(ctx, id, type) { + Self.checkRole = async function(ctx, id) { const models = Self.app.models; const dms = await Self.findById(id); - return await models.DmsType.checkRole(ctx, dms.dmsTypeFk, type); + return await models.DmsType.hasReadRole(ctx, dms.dmsTypeFk); }; Self.getFile = async function(id) { diff --git a/back/models/image-collection.js b/back/models/image-collection.js new file mode 100644 index 000000000..2c4d274ee --- /dev/null +++ b/back/models/image-collection.js @@ -0,0 +1,64 @@ +module.exports = Self => { + /** + * Checks if current user has + * read privileges over a collection + * + * @param {object} ctx - Request context + * @param {interger} name - Collection name + * @param {object} options - Query options + * @return {boolean} True for user with read privileges + */ + Self.hasReadRole = async(ctx, name, options) => { + const collection = await Self.findOne({where: {name}}, { + include: { + relation: 'readRole' + } + }, options); + + return await hasRole(ctx, collection, options); + }; + + /** + * Checks if current user has + * write privileges over a collection + * + * @param {object} ctx - Request context + * @param {string} name - Collection name + * @param {object} options - Query options + * @return {boolean} True for user with write privileges + */ + Self.hasWriteRole = async(ctx, name, options) => { + const collection = await Self.findOne({ + include: { + relation: 'writeRole' + }, + where: {name} + }, options); + + return await hasRole(ctx, collection, options); + }; + + /** + * Checks if current user has + * read or write privileges + * @param {Object} ctx - Context + * @param {Object} collection - Collection [read/write] + * @param {Object} options - Query options + */ + async function hasRole(ctx, collection, options) { + const models = Self.app.models; + const myUserId = ctx.req.accessToken.userId; + + const readRole = collection.readRole() && collection.readRole().name; + const writeRole = collection.writeRole() && collection.writeRole().name; + const requiredRole = readRole || writeRole; + + const hasRequiredRole = await models.VnUser.hasRole(myUserId, requiredRole, options); + const isRoot = await models.VnUser.hasRole(myUserId, 'root', options); + + if (isRoot || hasRequiredRole) + return true; + + return false; + } +}; diff --git a/db/changes/231601/00-modelsAcls.sql b/db/changes/231601/00-modelsAcls.sql deleted file mode 100644 index 62f2b20d0..000000000 --- a/db/changes/231601/00-modelsAcls.sql +++ /dev/null @@ -1,28 +0,0 @@ --- DmsType model -INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) - SELECT 'DmsType', d.code, 'WRITE', 'ALLOW', 'ROLE', r.name - FROM `vn`.`dmsType` d - JOIN `account`.`role` r ON r.id = d.writeRoleFk; - -INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) - SELECT 'DmsType', d.code, 'READ', 'ALLOW', 'ROLE', r.name - FROM `vn`.`dmsType` d - JOIN `account`.`role` r ON r.id = d.readRoleFk; - --- ImageCollection model -INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) - SELECT 'ImageCollection', i.name, 'WRITE', 'ALLOW', 'ROLE', r.name - FROM `hedera`.`imageCollection` i - JOIN `account`.`role` r ON r.id = i.writeRoleFk; - -INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) - SELECT 'ImageCollection', i.name, 'READ', 'ALLOW', 'ROLE', r.name - FROM `hedera`.`imageCollection` i - JOIN `account`.`role` r ON r.id = i.readRoleFk; - --- ClaimState -INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) - SELECT 'ClaimState', c.code, 'WRITE', 'ALLOW', 'ROLE', r.name - FROM `vn`.`claimState` c - JOIN `account`.`role` r ON r.id = c.roleFk; - diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 8346cedbd..d28549c9d 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -1775,11 +1775,6 @@ INSERT INTO `vn`.`claimState`(`id`, `code`, `description`, `roleFk`, `priority`, ( 6, 'mana', 'Mana', 72, 4, 0), ( 7, 'lack', 'Faltas', 72, 2, 0); -INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) - SELECT 'ClaimState', c.code, 'WRITE', 'ALLOW', 'ROLE', r.name - FROM `vn`.`claimState` c - JOIN `account`.`role` r ON r.id = c.roleFk; - INSERT INTO `vn`.`claim`(`id`, `ticketCreated`, `claimStateFk`, `clientFk`, `workerFk`, `responsibility`, `isChargedToMana`, `created`, `packages`, `rma`, `ticketFk`) VALUES (1, util.VN_CURDATE(), 1, 1101, 18, 3, 0, util.VN_CURDATE(), 0, '02676A049183', 11), @@ -2326,36 +2321,26 @@ INSERT INTO `vn`.`workerTimeControl`(`userFk`, `timed`, `manual`, `direction`, ` INSERT INTO `vn`.`dmsType`(`id`, `name`, `path`, `readRoleFk`, `writeRoleFk`, `code`) VALUES - (1, 'Facturas Recibidas', 'recibidas', 1, 1, 'invoiceIn'), - (2, 'Doc oficial', 'oficial', 1, 1, 'officialDoc'), - (3, 'Laboral', 'laboral', 37, 37, 'hhrrData'), - (4, 'Albaranes recibidos', 'entradas', 1, 1, 'deliveryNote'), - (5, 'Otros', 'otros', 1, 1, 'miscellaneous'), - (6, 'Pruebas', 'pruebas', 1, 1, 'tests'), - (7, 'IAE Clientes', 'IAE_Clientes', 1, 1, 'economicActivitiesTax'), - (8, 'Fiscal', 'fiscal', 1, 1, 'fiscal'), - (9, 'Vehiculos', 'vehiculos', 1, 1, 'vehicles'), - (10, 'Plantillas', 'plantillas', 1, 1, 'templates'), - (11, 'Contratos', 'contratos', 1, 1, 'contracts'), - (12, 'ley de pagos', 'ley pagos', 1, 1, 'paymentsLaw'), - (13, 'Basura', 'basura', 1, 1, 'trash'), - (14, 'Ticket', 'tickets', 1, 1, 'ticket'), - (15, 'Presupuestos', 'Presupuestos', 1, 1, 'budgets'), - (16, 'Logistica', 'logistica', 1, 1, 'logistics'), - (17, 'cmr', 'cmr', 1, 1, 'cmr'), - (18, 'dua', 'dua', 1, 1, 'dua'), - (19, 'inmovilizado', 'inmovilizado', 1, 1, 'fixedAssets'), - (20, 'Reclamación', 'reclamacion', 1, 1, 'claim'); - -INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) - SELECT 'DmsType', d.code, 'WRITE', 'ALLOW', 'ROLE', r.name - FROM `vn`.`dmsType` d - JOIN `account`.`role` r ON r.id = d.writeRoleFk; - -INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) - SELECT 'DmsType', d.code, 'READ', 'ALLOW', 'ROLE', r.name - FROM `vn`.`dmsType` d - JOIN `account`.`role` r ON r.id = d.readRoleFk; + (1, 'Facturas Recibidas', 'recibidas', NULL, NULL, 'invoiceIn'), + (2, 'Doc oficial', 'oficial', NULL, NULL, 'officialDoc'), + (3, 'Laboral', 'laboral', 37, 37, 'hhrrData'), + (4, 'Albaranes recibidos', 'entradas', NULL, NULL, 'deliveryNote'), + (5, 'Otros', 'otros', 1, 1, 'miscellaneous'), + (6, 'Pruebas', 'pruebas', NULL, NULL, 'tests'), + (7, 'IAE Clientes', 'IAE_Clientes', 1, 1, 'economicActivitiesTax'), + (8, 'Fiscal', 'fiscal', NULL, NULL, 'fiscal'), + (9, 'Vehiculos', 'vehiculos', NULL, NULL, 'vehicles'), + (10, 'Plantillas', 'plantillas', NULL, NULL, 'templates'), + (11, 'Contratos', 'contratos', NULL, NULL, 'contracts'), + (12, 'ley de pagos', 'ley pagos', 1, 1, 'paymentsLaw'), + (13, 'Basura', 'basura', 1, 1, 'trash'), + (14, 'Ticket', 'tickets', 1, 1, 'ticket'), + (15, 'Presupuestos', 'Presupuestos', NULL, NULL, 'budgets'), + (16, 'Logistica', 'logistica', NULL, NULL, 'logistics'), + (17, 'cmr', 'cmr', NULL, NULL, 'cmr'), + (18, 'dua', 'dua', NULL, NULL, 'dua'), + (19, 'inmovilizado', 'inmovilizado', NULL, NULL, 'fixedAssets'), + (20, 'Reclamación', 'reclamacion', 1, 1, 'claim'); INSERT INTO `vn`.`dms`(`id`, `dmsTypeFk`, `file`, `contentType`, `workerFk`, `warehouseFk`, `companyFk`, `hardCopyNumber`, `hasFile`, `reference`, `description`, `created`) VALUES diff --git a/modules/claim/back/methods/claim-state/isEditable.js b/modules/claim/back/methods/claim-state/isEditable.js index 73a8338da..641bc3b42 100644 --- a/modules/claim/back/methods/claim-state/isEditable.js +++ b/modules/claim/back/methods/claim-state/isEditable.js @@ -20,14 +20,19 @@ module.exports = Self => { }); Self.isEditable = async(ctx, id, options) => { + const userId = ctx.req.accessToken.userId; const models = Self.app.models; const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); - const state = await models.ClaimState.findById(id, {fields: ['code']}, myOptions); - if (!state) return false; - return await models.ACL.checkAccessAcl(ctx, 'ClaimState', state.code); + const state = await models.ClaimState.findById(id, { + include: { + relation: 'writeRole' + } + }, myOptions); + const roleWithGrants = state && state.writeRole().name; + return await models.VnUser.hasRole(userId, roleWithGrants, myOptions); }; }; diff --git a/modules/claim/back/methods/claim/uploadFile.js b/modules/claim/back/methods/claim/uploadFile.js index 14aa088a4..3d0737cf8 100644 --- a/modules/claim/back/methods/claim/uploadFile.js +++ b/modules/claim/back/methods/claim/uploadFile.js @@ -75,7 +75,7 @@ module.exports = Self => { let srcFile; try { - const hasWriteRole = await models.DmsType.checkRole(ctx, args.dmsTypeId, 'WRITE', myOptions); + const hasWriteRole = await models.DmsType.hasWriteRole(ctx, args.dmsTypeId, myOptions); if (!hasWriteRole) throw new UserError(`You don't have enough privileges`); diff --git a/modules/worker/back/methods/worker-dms/downloadFile.js b/modules/worker/back/methods/worker-dms/downloadFile.js index d129814a2..cc8653e0e 100644 --- a/modules/worker/back/methods/worker-dms/downloadFile.js +++ b/modules/worker/back/methods/worker-dms/downloadFile.js @@ -33,7 +33,7 @@ module.exports = Self => { }); Self.downloadFile = async function(ctx, id) { - if (!await Self.app.models.Dms.checkRole(ctx, id, 'READ') && !await Self.isMine(ctx, id)) + if (!await Self.app.models.Dms.checkRole(ctx, id) && !await Self.isMine(ctx, id)) throw new UserError(`You don't have enough privileges`); return await Self.app.models.Dms.getFile(id); }; From c3038a4d619e80ae3971179986559263e9e34fc1 Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 28 Apr 2023 11:54:11 +0200 Subject: [PATCH 13/61] fix(imageCollection): --- back/models/image-collection.js | 5 +++-- back/models/specs/dms.spec.js | 4 ++-- db/changes/231601/00-User.sql | 21 --------------------- 3 files changed, 5 insertions(+), 25 deletions(-) delete mode 100644 db/changes/231601/00-User.sql diff --git a/back/models/image-collection.js b/back/models/image-collection.js index 2c4d274ee..69905beca 100644 --- a/back/models/image-collection.js +++ b/back/models/image-collection.js @@ -9,10 +9,11 @@ module.exports = Self => { * @return {boolean} True for user with read privileges */ Self.hasReadRole = async(ctx, name, options) => { - const collection = await Self.findOne({where: {name}}, { + const collection = await Self.findOne({ include: { relation: 'readRole' - } + }, + where: {name} }, options); return await hasRole(ctx, collection, options); diff --git a/back/models/specs/dms.spec.js b/back/models/specs/dms.spec.js index e539387fb..3f13e88ff 100644 --- a/back/models/specs/dms.spec.js +++ b/back/models/specs/dms.spec.js @@ -37,14 +37,14 @@ describe('Dms', () => { const dmsId = 1; it('should return a true for an employee with permission', async() => { let ctx = {req: {accessToken: {userId: 1107}}}; - const result = await Dms.checkRole(ctx, dmsId, 'READ'); + const result = await Dms.checkRole(ctx, dmsId); expect(result).toBeTruthy(); }); it('should return false for an employee without permission', async() => { let ctx = {req: {accessToken: {userId: 1101}}}; - const result = await Dms.checkRole(ctx, dmsId, 'READ'); + const result = await Dms.checkRole(ctx, dmsId); expect(result).toBeFalsy(); }); diff --git a/db/changes/231601/00-User.sql b/db/changes/231601/00-User.sql deleted file mode 100644 index 8a7054403..000000000 --- a/db/changes/231601/00-User.sql +++ /dev/null @@ -1,21 +0,0 @@ -create or replace definer = root@localhost view `salix`.`User` as -select `account`.`user`.`id` AS `id`, - `account`.`user`.`realm` AS `realm`, - `account`.`user`.`name` AS `name`, - `account`.`user`.`nickname` AS `nickname`, - `account`.`user`.`bcryptPassword` AS `password`, - `account`.`user`.`role` AS `role`, - `account`.`user`.`active` AS `active`, - `account`.`user`.`email` AS `email`, - `account`.`user`.`emailVerified` AS `emailVerified`, - `account`.`user`.`verificationToken` AS `verificationToken`, - `account`.`user`.`lang` AS `lang`, - `account`.`user`.`lastPassChange` AS `lastPassChange`, - `account`.`user`.`created` AS `created`, - `account`.`user`.`updated` AS `updated`, - `account`.`user`.`image` AS `image`, - `account`.`user`.`recoverPass` AS `recoverPass`, - `account`.`user`.`sync` AS `sync`, - `account`.`user`.`hasGrant` AS `hasGrant` -from `account`.`user`; - From ac55dc4cc72d210fb15e5844b0d88c03dc0f3a1a Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 28 Apr 2023 14:17:19 +0200 Subject: [PATCH 14/61] refs #5297 feat(worker_new): add payMethod --- CHANGELOG.md | 2 ++ .../231601/00-workerConfigPayMethod.sql | 7 +++++ db/dump/fixtures.sql | 4 +-- e2e/helpers/selectors.js | 1 + e2e/paths/03-worker/06_create.spec.js | 3 +- modules/worker/back/methods/worker/new.js | 15 ++++++++-- .../back/methods/worker/specs/new.spec.js | 30 ++++++++++++++++++- modules/worker/back/models/worker-config.json | 3 ++ modules/worker/front/create/index.html | 11 +++++-- modules/worker/front/create/index.js | 3 ++ modules/worker/front/create/locale/es.yml | 1 + 11 files changed, 72 insertions(+), 8 deletions(-) create mode 100644 db/changes/231601/00-workerConfigPayMethod.sql diff --git a/CHANGELOG.md b/CHANGELOG.md index 1be03b733..15ecad61b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,9 +10,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - (Usuarios -> Histórico) Nueva sección - (Roles -> Histórico) Nueva sección +- (Trabajadores -> Dar de alta) Permite elegir el método de pago ### Changed - (Artículo -> Precio fijado) Modificado el buscador superior por uno lateral +- (Trabajadores -> Dar de alta) Quitada obligatoriedad del iban ### Fixed - diff --git a/db/changes/231601/00-workerConfigPayMethod.sql b/db/changes/231601/00-workerConfigPayMethod.sql new file mode 100644 index 000000000..91f477bec --- /dev/null +++ b/db/changes/231601/00-workerConfigPayMethod.sql @@ -0,0 +1,7 @@ +ALTER TABLE `vn`.`workerConfig` ADD payMethodFk tinyint(3) unsigned NULL; +ALTER TABLE `vn`.`workerConfig` ADD CONSTRAINT workerConfig_FK FOREIGN KEY (roleFk) REFERENCES account.`role`(id) ON DELETE RESTRICT ON UPDATE CASCADE; +ALTER TABLE `vn`.`workerConfig` ADD CONSTRAINT workerConfig_FK_1 FOREIGN KEY (payMethodFk) REFERENCES `vn`.`payMethod`(id) ON DELETE SET NULL ON UPDATE CASCADE; +-- Cuando se apruebe el PR quitar y poner en redmine para hacerse manualmente +UPDATE `vn`.`workerConfig` + SET payMethodFk = 4 + WHERE id=1; diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 15ccece35..b72e3e74a 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -2801,9 +2801,9 @@ INSERT INTO `vn`.`payDemDetail` (`id`, `detail`) VALUES (1, 1); -INSERT INTO `vn`.`workerConfig` (`id`, `businessUpdated`, `roleFk`) +INSERT INTO `vn`.`workerConfig` (`id`, `businessUpdated`, `roleFk`, `payMethodFk`) VALUES - (1, NULL, 1); + (1, NULL, 1, 4); INSERT INTO `vn`.`ticketRefund`(`refundTicketFk`, `originalTicketFk`) VALUES diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 1740db7ca..1bde2b29a 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -1041,6 +1041,7 @@ export default { email: 'vn-worker-create vn-textfield[ng-model="$ctrl.worker.email"]', boss: 'vn-worker-create vn-autocomplete[ng-model="$ctrl.worker.bossFk"]', role: 'vn-worker-create vn-autocomplete[ng-model="$ctrl.worker.roleFk"]', + payMethod: 'vn-worker-create vn-autocomplete[ng-model="$ctrl.worker.payMethodFk"]', iban: 'vn-worker-create vn-textfield[ng-model="$ctrl.worker.iban"]', createButton: 'vn-worker-create vn-submit[label="Create"]', }, diff --git a/e2e/paths/03-worker/06_create.spec.js b/e2e/paths/03-worker/06_create.spec.js index 203d9ba9a..cad9802a1 100644 --- a/e2e/paths/03-worker/06_create.spec.js +++ b/e2e/paths/03-worker/06_create.spec.js @@ -1,7 +1,7 @@ import selectors from '../../helpers/selectors.js'; import getBrowser from '../../helpers/puppeteer'; -describe('Worker create path', () => { +fdescribe('Worker create path', () => { let browser; let page; let newWorker; @@ -25,6 +25,7 @@ describe('Worker create path', () => { await page.write(selectors.workerCreate.postcode, '46680'); await page.write(selectors.workerCreate.street, 'S/ Doomstadt'); await page.write(selectors.workerCreate.email, 'doctorDoom@marvel.com'); + await page.autocompleteSearch(selectors.workerCreate.payMethod, 'one'); // should check for autocompleted worker code and worker user name const workerCode = await page diff --git a/modules/worker/back/methods/worker/new.js b/modules/worker/back/methods/worker/new.js index 68f962254..1c2fde3d3 100644 --- a/modules/worker/back/methods/worker/new.js +++ b/modules/worker/back/methods/worker/new.js @@ -90,15 +90,21 @@ module.exports = Self => { description: `The worker birth`, required: true, }, + { + arg: 'payMethodFk', + type: 'number', + description: `The client payMethod`, + required: true, + }, { arg: 'iban', type: 'string', - description: `The worker iban`, + description: `The client iban`, }, { arg: 'bankEntityFk', type: 'number', - description: `The worker bank entity`, + description: `The client bank entity`, } ], returns: { @@ -160,6 +166,10 @@ module.exports = Self => { myOptions ); + const payMethod = await models.PayMethod.findById(args.payMethodFk, {fields: ['isIbanRequiredForClients']}); + if (payMethod.isIbanRequiredForClients && !args.iban) + throw new UserError(`That payment method requires an IBAN`); + await models.Worker.rawSql( 'CALL vn.clientCreate(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', [ @@ -200,6 +210,7 @@ module.exports = Self => { await client.updateAttributes( { + payMethod: args.payMethod, iban: args.iban, bankEntityFk: args.bankEntityFk, defaultAddressFk: address.id, diff --git a/modules/worker/back/methods/worker/specs/new.spec.js b/modules/worker/back/methods/worker/specs/new.spec.js index d2c6157fb..dcd9ab0e9 100644 --- a/modules/worker/back/methods/worker/specs/new.spec.js +++ b/modules/worker/back/methods/worker/specs/new.spec.js @@ -32,7 +32,8 @@ describe('Worker new', () => { phone: '123456789', code: 'DWW', bossFk: 9, - birth: '2022-12-11T23:00:00.000Z' + birth: '2022-12-11T23:00:00.000Z', + payMethodFk: 1 }; it('should return error if personal mail already exists', async() => { @@ -103,6 +104,33 @@ describe('Worker new', () => { expect(error.message).toEqual('This worker already exists'); }); + it('should return error if payMethod require iban', async() => { + const payMethodIbanRequired = await models.PayMethod.findOne({ + where: { + isIbanRequiredForClients: true + }, + fields: ['id'] + }); + + const tx = await models.Worker.beginTransaction({}); + + let error; + try { + const options = {transaction: tx}; + const ctx = { + args: Object.assign({}, defaultWorker, {payMethodFk: payMethodIbanRequired.id}) + }; + await models.Worker.new(ctx, options); + + await tx.rollback(); + } catch (e) { + error = e; + await tx.rollback(); + } + + expect(error.message).toEqual('That payment method requires an IBAN'); + }); + it('should create a new worker', async() => { const newWorker = await models.Worker.new({args: defaultWorker}); diff --git a/modules/worker/back/models/worker-config.json b/modules/worker/back/models/worker-config.json index 05cdfef42..3ece5acc4 100644 --- a/modules/worker/back/models/worker-config.json +++ b/modules/worker/back/models/worker-config.json @@ -14,6 +14,9 @@ }, "roleFk": { "type": "number" + }, + "payMethodFk": { + "type": "number" } }, "acls": [ diff --git a/modules/worker/front/create/index.html b/modules/worker/front/create/index.html index 5f5ab9d07..eb45704a7 100644 --- a/modules/worker/front/create/index.html +++ b/modules/worker/front/create/index.html @@ -142,12 +142,19 @@ + + + on-change="$ctrl.autofillBic()" + rule> { + if (res.data) this.worker.payMethodFk = res.data.payMethodFk; + }); } onSubmit() { diff --git a/modules/worker/front/create/locale/es.yml b/modules/worker/front/create/locale/es.yml index 8c79d770c..78d24a4c9 100644 --- a/modules/worker/front/create/locale/es.yml +++ b/modules/worker/front/create/locale/es.yml @@ -10,3 +10,4 @@ Street: Dirección Postcode: Código postal Web user: Usuario Web Access permission: Permiso de acceso +Pay method: Metodo de pago From a89f400f104f59820f3f36aea55a12bc0aea388d Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 28 Apr 2023 14:22:24 +0200 Subject: [PATCH 15/61] use iban --- e2e/helpers/selectors.js | 1 - e2e/paths/03-worker/06_create.spec.js | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 1bde2b29a..1740db7ca 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -1041,7 +1041,6 @@ export default { email: 'vn-worker-create vn-textfield[ng-model="$ctrl.worker.email"]', boss: 'vn-worker-create vn-autocomplete[ng-model="$ctrl.worker.bossFk"]', role: 'vn-worker-create vn-autocomplete[ng-model="$ctrl.worker.roleFk"]', - payMethod: 'vn-worker-create vn-autocomplete[ng-model="$ctrl.worker.payMethodFk"]', iban: 'vn-worker-create vn-textfield[ng-model="$ctrl.worker.iban"]', createButton: 'vn-worker-create vn-submit[label="Create"]', }, diff --git a/e2e/paths/03-worker/06_create.spec.js b/e2e/paths/03-worker/06_create.spec.js index cad9802a1..98e67edbf 100644 --- a/e2e/paths/03-worker/06_create.spec.js +++ b/e2e/paths/03-worker/06_create.spec.js @@ -1,7 +1,7 @@ import selectors from '../../helpers/selectors.js'; import getBrowser from '../../helpers/puppeteer'; -fdescribe('Worker create path', () => { +describe('Worker create path', () => { let browser; let page; let newWorker; @@ -25,7 +25,7 @@ fdescribe('Worker create path', () => { await page.write(selectors.workerCreate.postcode, '46680'); await page.write(selectors.workerCreate.street, 'S/ Doomstadt'); await page.write(selectors.workerCreate.email, 'doctorDoom@marvel.com'); - await page.autocompleteSearch(selectors.workerCreate.payMethod, 'one'); + await page.write(selectors.workerCreate.iban, 'ES9121000418450200051332'); // should check for autocompleted worker code and worker user name const workerCode = await page From eaf425fb518c525ef27b798cecb1fe598981dffb Mon Sep 17 00:00:00 2001 From: carlossa Date: Wed, 3 May 2023 12:30:33 +0200 Subject: [PATCH 16/61] refs #5328 mod funcion createTicketRefund --- modules/ticket/back/methods/sale/refund.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/ticket/back/methods/sale/refund.js b/modules/ticket/back/methods/sale/refund.js index af58a6286..2517fbd99 100644 --- a/modules/ticket/back/methods/sale/refund.js +++ b/modules/ticket/back/methods/sale/refund.js @@ -11,7 +11,7 @@ module.exports = Self => { { arg: 'servicesIds', type: ['number'] - } + }, ], returns: { type: ['number'], @@ -110,11 +110,13 @@ module.exports = Self => { } }; - async function createTicketRefund(ticketId, now, refundAgencyMode, refoundZoneId, myOptions) { + async function createTicketRefund(ticketId, now, refundAgencyMode, refoundZoneId, myOptions, vTicketId) { const models = Self.app.models; const filter = {include: {relation: 'address'}}; const ticket = await models.Ticket.findById(ticketId, filter, myOptions); + const query = `CALL vn.ticket_recalc(?)`; + const [result] = await Self.rawSql(query, [vTicketId]); const refundTicket = await models.Ticket.create({ clientFk: ticket.clientFk, @@ -131,7 +133,7 @@ module.exports = Self => { await models.TicketRefund.create({ refundTicketFk: refundTicket.id, originalTicketFk: ticket.id, - }, myOptions); + }, myOptions, [result]); return refundTicket; } From 3b2e1ca8d5db0e73369f62fd29fe0f08618b5557 Mon Sep 17 00:00:00 2001 From: carlossa Date: Wed, 3 May 2023 12:36:30 +0200 Subject: [PATCH 17/61] ref #5328 refundTicket.id --- modules/ticket/back/methods/sale/refund.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/ticket/back/methods/sale/refund.js b/modules/ticket/back/methods/sale/refund.js index 2517fbd99..d58875019 100644 --- a/modules/ticket/back/methods/sale/refund.js +++ b/modules/ticket/back/methods/sale/refund.js @@ -101,6 +101,8 @@ module.exports = Self => { } } + const query = `CALL vn.ticket_recalc(?)`; + const [result] = await Self.rawSql(query, [refundTicket.id]); if (tx) await tx.commit(); return refundTicket; @@ -115,8 +117,6 @@ module.exports = Self => { const filter = {include: {relation: 'address'}}; const ticket = await models.Ticket.findById(ticketId, filter, myOptions); - const query = `CALL vn.ticket_recalc(?)`; - const [result] = await Self.rawSql(query, [vTicketId]); const refundTicket = await models.Ticket.create({ clientFk: ticket.clientFk, From 566f03c4976deb68e499e11258983b3e2de880ce Mon Sep 17 00:00:00 2001 From: carlossa Date: Wed, 3 May 2023 13:03:14 +0200 Subject: [PATCH 18/61] refs #5328 commit prueba --- modules/ticket/back/methods/sale/refund.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/ticket/back/methods/sale/refund.js b/modules/ticket/back/methods/sale/refund.js index d58875019..9ee7735a0 100644 --- a/modules/ticket/back/methods/sale/refund.js +++ b/modules/ticket/back/methods/sale/refund.js @@ -112,7 +112,7 @@ module.exports = Self => { } }; - async function createTicketRefund(ticketId, now, refundAgencyMode, refoundZoneId, myOptions, vTicketId) { + async function createTicketRefund(ticketId, now, refundAgencyMode, refoundZoneId, myOptions) { const models = Self.app.models; const filter = {include: {relation: 'address'}}; @@ -133,7 +133,7 @@ module.exports = Self => { await models.TicketRefund.create({ refundTicketFk: refundTicket.id, originalTicketFk: ticket.id, - }, myOptions, [result]); + }, myOptions); return refundTicket; } From 3ac1ce403c8873013f5c77e426cedbc2e6f5b32b Mon Sep 17 00:00:00 2001 From: carlossa Date: Wed, 3 May 2023 14:06:57 +0200 Subject: [PATCH 19/61] refs #5328 myOptions --- modules/ticket/back/methods/sale/refund.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/ticket/back/methods/sale/refund.js b/modules/ticket/back/methods/sale/refund.js index 9ee7735a0..ffbc73db0 100644 --- a/modules/ticket/back/methods/sale/refund.js +++ b/modules/ticket/back/methods/sale/refund.js @@ -100,9 +100,7 @@ module.exports = Self => { }, myOptions); } } - - const query = `CALL vn.ticket_recalc(?)`; - const [result] = await Self.rawSql(query, [refundTicket.id]); + const query = `CALL vn.ticket_recalc(?)`; await Self.rawSql(query, [refundTicket.id], myOptions); if (tx) await tx.commit(); return refundTicket; From dbd0e5138b1d396b36b35e01a53206b02e301b51 Mon Sep 17 00:00:00 2001 From: carlossa Date: Wed, 3 May 2023 14:12:26 +0200 Subject: [PATCH 20/61] refs #5328 fix --- modules/ticket/back/methods/sale/refund.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ticket/back/methods/sale/refund.js b/modules/ticket/back/methods/sale/refund.js index ffbc73db0..3a633de0f 100644 --- a/modules/ticket/back/methods/sale/refund.js +++ b/modules/ticket/back/methods/sale/refund.js @@ -11,7 +11,7 @@ module.exports = Self => { { arg: 'servicesIds', type: ['number'] - }, + } ], returns: { type: ['number'], From 97da5e6e24ce18aabd2ac502dc9efdd16865b007 Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 5 May 2023 13:58:11 +0200 Subject: [PATCH 21/61] refs #5488 feat(isRoleAdvanced): use Acl instead of method --- db/changes/231601/00-useSpecificsAcls.sql | 8 ++++---- .../methods/sale/specs/updateQuantity.spec.js | 2 +- .../ticket/back/methods/sale/updateQuantity.js | 2 +- .../ticket/back/methods/ticket/isEditable.js | 2 +- .../back/methods/ticket/isRoleAdvanced.js | 18 ------------------ modules/ticket/back/models/ticket-methods.js | 1 - 6 files changed, 7 insertions(+), 26 deletions(-) delete mode 100644 modules/ticket/back/methods/ticket/isRoleAdvanced.js diff --git a/db/changes/231601/00-useSpecificsAcls.sql b/db/changes/231601/00-useSpecificsAcls.sql index 01906d09c..7d8ebe40a 100644 --- a/db/changes/231601/00-useSpecificsAcls.sql +++ b/db/changes/231601/00-useSpecificsAcls.sql @@ -2,10 +2,10 @@ INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `pri VALUES ('Ticket', 'editDiscount', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'), ('Ticket', 'editDiscount', 'WRITE', 'ALLOW', 'ROLE', 'salesPerson'), - ('Ticket', 'hasRoleAdvanced', '*', 'ALLOW', 'ROLE', 'salesAssistant'), - ('Ticket', 'hasRoleAdvanced', '*', 'ALLOW', 'ROLE', 'deliveryBoss'), - ('Ticket', 'hasRoleAdvanced', '*', 'ALLOW', 'ROLE', 'buyer'), - ('Ticket', 'hasRoleAdvanced', '*', 'ALLOW', 'ROLE', 'claimManager'), + ('Ticket', 'isRoleAdvanced', '*', 'ALLOW', 'ROLE', 'salesAssistant'), + ('Ticket', 'isRoleAdvanced', '*', 'ALLOW', 'ROLE', 'deliveryBoss'), + ('Ticket', 'isRoleAdvanced', '*', 'ALLOW', 'ROLE', 'buyer'), + ('Ticket', 'isRoleAdvanced', '*', 'ALLOW', 'ROLE', 'claimManager'), ('Ticket', 'deleteTicketWithPartPrepared', 'WRITE', 'ALLOW', 'ROLE', 'salesAssistant'), ('Ticket', 'editZone', 'WRITE', 'ALLOW', 'ROLE', 'deliveryBoss'), ('State', 'editableStates', 'READ', 'ALLOW', 'ROLE', 'employee'), diff --git a/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js b/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js index 4778f6b6d..80adb0bd1 100644 --- a/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js +++ b/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js @@ -64,7 +64,7 @@ describe('sale updateQuantity()', () => { try { const options = {transaction: tx}; - const isRoleAdvanced = await models.Ticket.isRoleAdvanced(ctx, options); + const isRoleAdvanced = await models.ACL.checkAccessAcl(ctx, 'Ticket', 'isRoleAdvanced', '*'); expect(isRoleAdvanced).toEqual(true); diff --git a/modules/ticket/back/methods/sale/updateQuantity.js b/modules/ticket/back/methods/sale/updateQuantity.js index d2927c65c..421c74702 100644 --- a/modules/ticket/back/methods/sale/updateQuantity.js +++ b/modules/ticket/back/methods/sale/updateQuantity.js @@ -64,7 +64,7 @@ module.exports = Self => { const sale = await models.Sale.findById(id, filter, myOptions); - const isRoleAdvanced = await models.Ticket.isRoleAdvanced(ctx, myOptions); + const isRoleAdvanced = await models.ACL.checkAccessAcl(ctx, 'Ticket', 'isRoleAdvanced', '*'); if (newQuantity > sale.quantity && !isRoleAdvanced) throw new UserError('The new quantity should be smaller than the old one'); diff --git a/modules/ticket/back/methods/ticket/isEditable.js b/modules/ticket/back/methods/ticket/isEditable.js index d8fbb86ce..13bd4d57f 100644 --- a/modules/ticket/back/methods/ticket/isEditable.js +++ b/modules/ticket/back/methods/ticket/isEditable.js @@ -30,7 +30,7 @@ module.exports = Self => { where: {ticketFk: id} }, myOptions); - const isRoleAdvanced = await models.Ticket.isRoleAdvanced(ctx, myOptions); + const isRoleAdvanced = await models.ACL.checkAccessAcl(ctx, 'Ticket', 'isRoleAdvanced', '*'); const alertLevel = state ? state.alertLevel : null; const ticket = await models.Ticket.findById(id, { diff --git a/modules/ticket/back/methods/ticket/isRoleAdvanced.js b/modules/ticket/back/methods/ticket/isRoleAdvanced.js deleted file mode 100644 index df6ef164c..000000000 --- a/modules/ticket/back/methods/ticket/isRoleAdvanced.js +++ /dev/null @@ -1,18 +0,0 @@ -module.exports = Self => { - Self.remoteMethodCtx('isRoleAdvanced', { - description: 'Check if a ticket is editable', - accessType: 'READ', - returns: { - type: 'boolean', - root: true - }, - http: { - path: `/isRoleAdvanced`, - verb: 'GET' - } - }); - - Self.isRoleAdvanced = async ctx => { - return Self.app.models.ACL.checkAccessAcl(ctx, 'Ticket', 'hasRoleAdvanced', '*'); - }; -}; diff --git a/modules/ticket/back/models/ticket-methods.js b/modules/ticket/back/models/ticket-methods.js index 3992e7307..e5a8e8d94 100644 --- a/modules/ticket/back/models/ticket-methods.js +++ b/modules/ticket/back/models/ticket-methods.js @@ -36,7 +36,6 @@ module.exports = function(Self) { require('../methods/ticket/getTicketsFuture')(Self); require('../methods/ticket/merge')(Self); require('../methods/ticket/getTicketsAdvance')(Self); - require('../methods/ticket/isRoleAdvanced')(Self); require('../methods/ticket/collectionLabel')(Self); require('../methods/ticket/expeditionPalletLabel')(Self); require('../methods/ticket/saveSign')(Self); From 7e63bc0004dd65845b7d8cb9b858eca504a44392 Mon Sep 17 00:00:00 2001 From: carlossa Date: Mon, 8 May 2023 09:18:22 +0200 Subject: [PATCH 22/61] refs #5297 quit fdescribe --- e2e/paths/13-supplier/03_fiscal_data.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/paths/13-supplier/03_fiscal_data.spec.js b/e2e/paths/13-supplier/03_fiscal_data.spec.js index 31b3fafd2..170a8d05a 100644 --- a/e2e/paths/13-supplier/03_fiscal_data.spec.js +++ b/e2e/paths/13-supplier/03_fiscal_data.spec.js @@ -15,7 +15,7 @@ const $inputs = { sageTaxType: 'vn-supplier-fiscal-data [ng-model="$ctrl.supplier.sageTaxTypeFk"]' }; -fdescribe('Supplier fiscal data path', () => { +describe('Supplier fiscal data path', () => { let browser; let page; From 96b5749e1ea020322f89d69d8282c2b4aaaa33e0 Mon Sep 17 00:00:00 2001 From: carlossa Date: Mon, 8 May 2023 10:17:35 +0200 Subject: [PATCH 23/61] refs #5297 cambio actual --- e2e/paths/13-supplier/03_fiscal_data.spec.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/e2e/paths/13-supplier/03_fiscal_data.spec.js b/e2e/paths/13-supplier/03_fiscal_data.spec.js index 080d916e4..891b769c9 100644 --- a/e2e/paths/13-supplier/03_fiscal_data.spec.js +++ b/e2e/paths/13-supplier/03_fiscal_data.spec.js @@ -1,6 +1,5 @@ import getBrowser from '../../helpers/puppeteer'; -<<<<<<< HEAD const $ = { saveButton: 'vn-supplier-fiscal-data button[type="submit"]', }; @@ -16,8 +15,6 @@ const $inputs = { sageTaxType: 'vn-supplier-fiscal-data [ng-model="$ctrl.supplier.sageTaxTypeFk"]' }; -======= ->>>>>>> a51481c00ea9f503d002b0ba0e259ea51b81677d describe('Supplier fiscal data path', () => { let browser; let page; From ca8373d7f752612d7ed27ce2bdb3a1426edd73c4 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 9 May 2023 14:04:39 +0200 Subject: [PATCH 24/61] feat(acl): add specifics acls to ticket, claim, state and worker --- db/changes/232001/00-useSpecificsAcls.sql | 60 +++++++++++++++++++++-- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/db/changes/232001/00-useSpecificsAcls.sql b/db/changes/232001/00-useSpecificsAcls.sql index 7d8ebe40a..f8bd84c01 100644 --- a/db/changes/232001/00-useSpecificsAcls.sql +++ b/db/changes/232001/00-useSpecificsAcls.sql @@ -36,18 +36,63 @@ DELETE FROM `salix`.`ACL` AND property = '*' AND accessType = '*'; +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES + ('Claim', 'find', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Claim', 'findById', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Claim', 'findOne', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Claim', 'getSummary', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Claim', 'updateClaim', 'WRITE', 'ALLOW', 'ROLE', 'employee'), + ('Claim', 'regularizeClaim', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'),-- ? + ('Claim', 'updateClaimDestination', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'),-- ? + ('Claim', 'downloadFile', 'READ', 'ALLOW', 'ROLE', 'claimManager'),-- ? + ('Claim', 'logs', 'READ', 'ALLOW', 'ROLE', 'claimManager');-- ? + DELETE FROM `salix`.`ACL` WHERE model = 'Ticket' AND property = '*' AND accessType = '*'; +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES + ('Ticket', 'find', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'findById', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'findOne', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'getVolume', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'getTotalVolume', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'summary', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'priceDifference', 'WRITE', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'componentUpdate', 'WRITE', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'new', 'WRITE', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'isEditable', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'setDeleted', 'WRITE', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'restore', 'WRITE', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'getSales', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'getSalesPersonMana', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'filter', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'makeInvoice', 'WRITE', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'updateEditableTicket', 'WRITE', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'updateDiscount', 'WRITE', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'transferSales', 'WRITE', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'sendSms', 'WRITE', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'isLocked', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'freightCost', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'getComponentsSum', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'deliveryNoteCsv', 'READ', 'ALLOW', 'ROLE', 'employee'); + DELETE FROM `salix`.`ACL` WHERE model = 'State' AND property = '*' AND accessType = 'READ'; +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES + ('State', 'find', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('State', 'findById', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('State', 'findOne', 'READ', 'ALLOW', 'ROLE', 'employee'); + DELETE FROM `salix`.`ACL` WHERE model = 'Worker' @@ -56,6 +101,15 @@ DELETE FROM `salix`.`ACL` INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES - ('State', 'find', 'READ', 'ALLOW', 'ROLE', 'employee'), - ('State', 'findById', 'READ', 'ALLOW', 'ROLE', 'employee'), - ('State', 'findOne', 'READ', 'ALLOW', 'ROLE', 'employee'); + ('Worker', 'find', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Worker', 'findById', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Worker', 'findOne', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Worker', 'filter', 'READ', 'ALLOW', 'ROLE', 'employee'), -- ? + ('Worker', 'getWorkedHours', 'READ', 'ALLOW', 'ROLE', 'employee'), -- ? + ('Worker', 'active', 'READ', 'ALLOW', 'ROLE', 'employee'), -- ? + ('Worker', 'activeWithRole', 'READ', 'ALLOW', 'ROLE', 'employee'), -- ? + ('Worker', 'uploadFile', 'WRITE', 'ALLOW', 'ROLE', 'hr'), -- ? + ('Worker', 'contracts', 'READ', 'ALLOW', 'ROLE', 'employee'), -- ? + ('Worker', 'holidays', 'READ', 'ALLOW', 'ROLE', 'employee'), -- ? + ('Worker', 'activeContract', 'READ', 'ALLOW', 'ROLE', 'employee'), -- ? + ('Worker', 'activeWithInheritedRole', 'READ', 'ALLOW', 'ROLE', 'employee'); --? From a345265a89096b66ff8e7942e0fdaa24e87148b9 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 10 May 2023 14:09:06 +0200 Subject: [PATCH 25/61] refs #5488 specifics acls --- db/changes/232001/00-useSpecificsAcls.sql | 30 ++++++++++++----------- loopback/locale/en.json | 5 ++-- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/db/changes/232001/00-useSpecificsAcls.sql b/db/changes/232001/00-useSpecificsAcls.sql index f8bd84c01..d79c9d4d9 100644 --- a/db/changes/232001/00-useSpecificsAcls.sql +++ b/db/changes/232001/00-useSpecificsAcls.sql @@ -43,10 +43,11 @@ INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `pri ('Claim', 'findOne', 'READ', 'ALLOW', 'ROLE', 'employee'), ('Claim', 'getSummary', 'READ', 'ALLOW', 'ROLE', 'employee'), ('Claim', 'updateClaim', 'WRITE', 'ALLOW', 'ROLE', 'employee'), - ('Claim', 'regularizeClaim', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'),-- ? - ('Claim', 'updateClaimDestination', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'),-- ? - ('Claim', 'downloadFile', 'READ', 'ALLOW', 'ROLE', 'claimManager'),-- ? - ('Claim', 'logs', 'READ', 'ALLOW', 'ROLE', 'claimManager');-- ? + ('Claim', 'regularizeClaim', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'), + ('Claim', 'updateClaimDestination', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'), + ('Claim', 'downloadFile', 'READ', 'ALLOW', 'ROLE', 'claimManager'), + ('Claim', 'deleteById', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'), + ('Claim', 'logs', 'READ', 'ALLOW', 'ROLE', 'claimManager'); DELETE FROM `salix`.`ACL` WHERE @@ -62,7 +63,7 @@ INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `pri ('Ticket', 'getVolume', 'READ', 'ALLOW', 'ROLE', 'employee'), ('Ticket', 'getTotalVolume', 'READ', 'ALLOW', 'ROLE', 'employee'), ('Ticket', 'summary', 'READ', 'ALLOW', 'ROLE', 'employee'), - ('Ticket', 'priceDifference', 'WRITE', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'priceDifference', 'READ', 'ALLOW', 'ROLE', 'employee'), ('Ticket', 'componentUpdate', 'WRITE', 'ALLOW', 'ROLE', 'employee'), ('Ticket', 'new', 'WRITE', 'ALLOW', 'ROLE', 'employee'), ('Ticket', 'isEditable', 'READ', 'ALLOW', 'ROLE', 'employee'), @@ -79,6 +80,7 @@ INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `pri ('Ticket', 'isLocked', 'READ', 'ALLOW', 'ROLE', 'employee'), ('Ticket', 'freightCost', 'READ', 'ALLOW', 'ROLE', 'employee'), ('Ticket', 'getComponentsSum', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'updateAttributes', 'WRITE', 'ALLOW', 'ROLE', 'delivery'), -- Change Priority in Route tickets ('Ticket', 'deliveryNoteCsv', 'READ', 'ALLOW', 'ROLE', 'employee'); DELETE FROM `salix`.`ACL` @@ -104,12 +106,12 @@ INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `pri ('Worker', 'find', 'READ', 'ALLOW', 'ROLE', 'employee'), ('Worker', 'findById', 'READ', 'ALLOW', 'ROLE', 'employee'), ('Worker', 'findOne', 'READ', 'ALLOW', 'ROLE', 'employee'), - ('Worker', 'filter', 'READ', 'ALLOW', 'ROLE', 'employee'), -- ? - ('Worker', 'getWorkedHours', 'READ', 'ALLOW', 'ROLE', 'employee'), -- ? - ('Worker', 'active', 'READ', 'ALLOW', 'ROLE', 'employee'), -- ? - ('Worker', 'activeWithRole', 'READ', 'ALLOW', 'ROLE', 'employee'), -- ? - ('Worker', 'uploadFile', 'WRITE', 'ALLOW', 'ROLE', 'hr'), -- ? - ('Worker', 'contracts', 'READ', 'ALLOW', 'ROLE', 'employee'), -- ? - ('Worker', 'holidays', 'READ', 'ALLOW', 'ROLE', 'employee'), -- ? - ('Worker', 'activeContract', 'READ', 'ALLOW', 'ROLE', 'employee'), -- ? - ('Worker', 'activeWithInheritedRole', 'READ', 'ALLOW', 'ROLE', 'employee'); --? + ('Worker', 'filter', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Worker', 'getWorkedHours', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Worker', 'active', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Worker', 'activeWithRole', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Worker', 'uploadFile', 'WRITE', 'ALLOW', 'ROLE', 'hr'), + ('Worker', 'contracts', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Worker', 'holidays', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Worker', 'activeContract', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Worker', 'activeWithInheritedRole', 'READ', 'ALLOW', 'ROLE', 'employee'); diff --git a/loopback/locale/en.json b/loopback/locale/en.json index cffedd891..a517a6183 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -171,5 +171,6 @@ "Added observation": "Added observation", "Comment added to client": "Comment added to client", "This ticket is already a refund": "This ticket is already a refund", - "A claim with that sale already exists": "A claim with that sale already exists" -} \ No newline at end of file + "A claim with that sale already exists": "A claim with that sale already exists", + "ASSIGN_ZONE_FIRST": "Assign zone first" +} From 8ed17d99c3945e8cea073f77de3f0f05ba415ce9 Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 11 May 2023 10:02:45 +0200 Subject: [PATCH 26/61] refs #5327 permite filtrar por columnas (desde el front) --- .../ticket/back/methods/ticket/getSales.js | 26 +++++++------------ modules/ticket/front/sale/index.html | 20 +++++++------- modules/ticket/front/sale/index.js | 6 ++--- 3 files changed, 22 insertions(+), 30 deletions(-) diff --git a/modules/ticket/back/methods/ticket/getSales.js b/modules/ticket/back/methods/ticket/getSales.js index e3d6af389..321e8e24e 100644 --- a/modules/ticket/back/methods/ticket/getSales.js +++ b/modules/ticket/back/methods/ticket/getSales.js @@ -3,20 +3,13 @@ module.exports = Self => { Self.remoteMethod('getSales', { description: 'New filter', accessType: 'READ', - accepts: [ - { - arg: 'filter', - type: 'object', - description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string', - http: {source: 'query'} - }, - { - arg: 'id', - type: 'number', - required: true, - description: 'The ticket id', - http: {source: 'path'} - }], + accepts: [{ + arg: 'id', + type: 'number', + required: true, + description: 'The ticket id', + http: {source: 'path'} + }], returns: { type: ['object'], root: true @@ -27,7 +20,7 @@ module.exports = Self => { } }); - Self.getSales = async(filter, id, options) => { + Self.getSales = async(id, options) => { const models = Self.app.models; const myOptions = {}; @@ -35,7 +28,6 @@ module.exports = Self => { if (typeof options == 'object') Object.assign(myOptions, options); - console.log(filter); const sales = await models.Sale.find({ include: { relation: 'item', @@ -117,7 +109,7 @@ module.exports = Self => { if (salesWithLogs.includes(sale.id)) sale.$hasLogs = true; } - console.log(sales); + return sales; }; }; diff --git a/modules/ticket/front/sale/index.html b/modules/ticket/front/sale/index.html index 3bf4e06d0..668c3b6dc 100644 --- a/modules/ticket/front/sale/index.html +++ b/modules/ticket/front/sale/index.html @@ -60,20 +60,20 @@ - Visible - Available - Id - Quantity - Item - Price - Disc - Amount - Packaging + Visible + Available + Id + Quantity + Item + Price + Disc + Amount + Packaging - + diff --git a/modules/ticket/front/sale/index.js b/modules/ticket/front/sale/index.js index 379b48cc9..ec43093f8 100644 --- a/modules/ticket/front/sale/index.js +++ b/modules/ticket/front/sale/index.js @@ -7,11 +7,11 @@ class Controller extends Section { super($element, $); this._sales = []; this.manaCode = 'mana'; - this.ordenarPor = 'nombre'; } - cambiarOrden(columna) { - this.ordenarPor = columna; + sortBy(propertyName) { + this.reverse = (this.propertyName === propertyName) ? !this.reverse : false; + this.propertyName = propertyName; } get manaCode() { From a7fcd8a1bf9f12607ee799c26eaaa540d30d8c4d Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 11 May 2023 10:04:15 +0200 Subject: [PATCH 27/61] changes --- modules/ticket/front/sale/index.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/ticket/front/sale/index.html b/modules/ticket/front/sale/index.html index 9d145d4fc..abdf5f88f 100644 --- a/modules/ticket/front/sale/index.html +++ b/modules/ticket/front/sale/index.html @@ -64,7 +64,7 @@ Visible Available Id - Quantity + Quantity Item Price Disc @@ -233,7 +233,7 @@ vn-tooltip="Add item" vn-bind="+" icon="add_circle" - ng-click="$ctrl.cambiarOrden('quantity')" + ng-click="$ctrl.add()" disabled="!$ctrl.isEditable"> @@ -481,7 +481,7 @@ on-accept="$ctrl.transferSales($ctrl.transfer.ticketId)"> - Add claim - + Date: Thu, 11 May 2023 10:04:59 +0200 Subject: [PATCH 28/61] borrado espacio --- modules/ticket/front/sale/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ticket/front/sale/index.html b/modules/ticket/front/sale/index.html index abdf5f88f..c5fe0743f 100644 --- a/modules/ticket/front/sale/index.html +++ b/modules/ticket/front/sale/index.html @@ -63,7 +63,7 @@ Visible Available - Id + Id Quantity Item Price From 90b844062d31d3e213fe782bcffea2d5f026fb67 Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 11 May 2023 10:17:41 +0200 Subject: [PATCH 29/61] refs #5327 add frontTest --- modules/ticket/front/sale/index.spec.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/modules/ticket/front/sale/index.spec.js b/modules/ticket/front/sale/index.spec.js index 5fb3b3df3..9c340ea74 100644 --- a/modules/ticket/front/sale/index.spec.js +++ b/modules/ticket/front/sale/index.spec.js @@ -2,7 +2,7 @@ import './index.js'; import watcher from 'core/mocks/watcher'; import crudModel from 'core/mocks/crud-model'; -describe('Ticket', () => { +fdescribe('Ticket', () => { describe('Component vnTicketSale', () => { let controller; let $scope; @@ -758,5 +758,15 @@ describe('Ticket', () => { expect(controller.$.editDiscount.hide).toHaveBeenCalledWith(); }); }); + + describe('sortBy()', () => { + it('should set reverse and propertyName properties', () => { + const propertyName = 'id'; + controller.sortBy(propertyName); + + expect(controller.propertyName).toEqual(propertyName); + expect(controller.reverse).toEqual(false); + }); + }); }); }); From 2ed99426ef7b2c86833e83f1aadcc0abbcd13569 Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 11 May 2023 10:18:02 +0200 Subject: [PATCH 30/61] eliminado focus --- modules/ticket/front/sale/index.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ticket/front/sale/index.spec.js b/modules/ticket/front/sale/index.spec.js index 9c340ea74..9da8e6e7c 100644 --- a/modules/ticket/front/sale/index.spec.js +++ b/modules/ticket/front/sale/index.spec.js @@ -2,7 +2,7 @@ import './index.js'; import watcher from 'core/mocks/watcher'; import crudModel from 'core/mocks/crud-model'; -fdescribe('Ticket', () => { +describe('Ticket', () => { describe('Component vnTicketSale', () => { let controller; let $scope; From 08fcbebbaf96fc0b0cddcaf134de9ef787214dfb Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 15 May 2023 14:14:08 +0200 Subject: [PATCH 31/61] refs #5488 polish specifics acls --- db/changes/232001/00-useSpecificsAcls.sql | 14 +++++++------- e2e/paths/06-claim/05_summary.spec.js | 2 +- e2e/paths/06-claim/06_descriptor.spec.js | 2 +- .../ticket/back/methods/ticket/transferSales.js | 1 + .../worker/back/methods/worker/isSubordinate.js | 10 ++-------- modules/zone/back/methods/zone/includingExpired.js | 2 +- 6 files changed, 13 insertions(+), 18 deletions(-) diff --git a/db/changes/232001/00-useSpecificsAcls.sql b/db/changes/232001/00-useSpecificsAcls.sql index d79c9d4d9..2c12e064c 100644 --- a/db/changes/232001/00-useSpecificsAcls.sql +++ b/db/changes/232001/00-useSpecificsAcls.sql @@ -27,8 +27,7 @@ INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `pri ('Supplier', 'editPayMethodCheck', 'WRITE', 'ALLOW', 'ROLE', 'financial'), ('Worker', 'isTeamBoss', 'WRITE', 'ALLOW', 'ROLE', 'teamBoss'), ('Worker', 'forceIsSubordinate', 'READ', 'ALLOW', 'ROLE', 'hr'), - ('Claim', 'editState', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'), - ('Claim', 'filter', 'READ', 'ALLOW', 'ROLE', 'employee'); + ('Claim', 'editState', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'); DELETE FROM `salix`.`ACL` WHERE @@ -38,15 +37,16 @@ DELETE FROM `salix`.`ACL` INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES - ('Claim', 'find', 'READ', 'ALLOW', 'ROLE', 'employee'), - ('Claim', 'findById', 'READ', 'ALLOW', 'ROLE', 'employee'), - ('Claim', 'findOne', 'READ', 'ALLOW', 'ROLE', 'employee'), - ('Claim', 'getSummary', 'READ', 'ALLOW', 'ROLE', 'employee'), - ('Claim', 'updateClaim', 'WRITE', 'ALLOW', 'ROLE', 'employee'), + ('Claim', 'find', 'READ', 'ALLOW', 'ROLE', 'salesPerson'), + ('Claim', 'findById', 'READ', 'ALLOW', 'ROLE', 'salesPerson'), + ('Claim', 'findOne', 'READ', 'ALLOW', 'ROLE', 'salesPerson'), + ('Claim', 'getSummary', 'READ', 'ALLOW', 'ROLE', 'salesPerson'), + ('Claim', 'updateClaim', 'WRITE', 'ALLOW', 'ROLE', 'salesPerson'), ('Claim', 'regularizeClaim', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'), ('Claim', 'updateClaimDestination', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'), ('Claim', 'downloadFile', 'READ', 'ALLOW', 'ROLE', 'claimManager'), ('Claim', 'deleteById', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'), + ('Claim', 'filter', 'READ', 'ALLOW', 'ROLE', 'salesPerson'), ('Claim', 'logs', 'READ', 'ALLOW', 'ROLE', 'claimManager'); DELETE FROM `salix`.`ACL` diff --git a/e2e/paths/06-claim/05_summary.spec.js b/e2e/paths/06-claim/05_summary.spec.js index 758dc2ee3..9656ea656 100644 --- a/e2e/paths/06-claim/05_summary.spec.js +++ b/e2e/paths/06-claim/05_summary.spec.js @@ -17,7 +17,7 @@ describe('Claim summary path', () => { }); it('should navigate to the target claim summary section', async() => { - await page.loginAndModule('employee', 'claim'); + await page.loginAndModule('salesPerson', 'claim'); await page.accessToSearchResult(claimId); await page.waitForState('claim.card.summary'); }); diff --git a/e2e/paths/06-claim/06_descriptor.spec.js b/e2e/paths/06-claim/06_descriptor.spec.js index 0826bad63..059bd68dd 100644 --- a/e2e/paths/06-claim/06_descriptor.spec.js +++ b/e2e/paths/06-claim/06_descriptor.spec.js @@ -16,7 +16,7 @@ describe('Claim descriptor path', () => { }); it('should now navigate to the target claim summary section', async() => { - await page.loginAndModule('employee', 'claim'); + await page.loginAndModule('salesPerson', 'claim'); await page.accessToSearchResult(claimId); await page.waitForState('claim.card.summary'); }); diff --git a/modules/ticket/back/methods/ticket/transferSales.js b/modules/ticket/back/methods/ticket/transferSales.js index 48035648c..f1fc48d51 100644 --- a/modules/ticket/back/methods/ticket/transferSales.js +++ b/modules/ticket/back/methods/ticket/transferSales.js @@ -3,6 +3,7 @@ let UserError = require('vn-loopback/util/user-error'); module.exports = Self => { Self.remoteMethodCtx('transferSales', { description: 'Transfer sales to a new or a given ticket', + accessType: 'WRITE', accepts: [{ arg: 'id', type: 'number', diff --git a/modules/worker/back/methods/worker/isSubordinate.js b/modules/worker/back/methods/worker/isSubordinate.js index 9a1f1e683..53adc68b7 100644 --- a/modules/worker/back/methods/worker/isSubordinate.js +++ b/modules/worker/back/methods/worker/isSubordinate.js @@ -31,15 +31,9 @@ module.exports = Self => { Object.assign(myOptions, options); const mySubordinates = await Self.mySubordinates(ctx, myOptions); - const isSubordinate = mySubordinates.find(subordinate => { - return subordinate.workerFk == id; - }); - + const isSubordinate = mySubordinates.some(subordinate => subordinate.workerFk == id); const forceIsSubordinate = await models.ACL.checkAccessAcl(ctx, 'Worker', 'forceIsSubordinate', 'READ'); - if (forceIsSubordinate || isSubordinate) - return true; - - return false; + return forceIsSubordinate || isSubordinate; }; }; diff --git a/modules/zone/back/methods/zone/includingExpired.js b/modules/zone/back/methods/zone/includingExpired.js index 31678c83d..f9e7fd038 100644 --- a/modules/zone/back/methods/zone/includingExpired.js +++ b/modules/zone/back/methods/zone/includingExpired.js @@ -35,7 +35,7 @@ module.exports = Self => { && where.agencyModeFk && where.warehouseFk; if (filterByAvailability) { - const canSeeExpired = await models.ACL.checkAccessAcl(ctx, 'Agency', 'editDiscount'); + const canSeeExpired = await models.ACL.checkAccessAcl(ctx, 'Agency', 'seeExpired'); let showExpired = false; if (canSeeExpired.length) showExpired = true; From 6300ee4be4179ad2ef650287a31b5e58f3f58953 Mon Sep 17 00:00:00 2001 From: vicent Date: Mon, 15 May 2023 14:24:31 +0200 Subject: [PATCH 32/61] refs #5600 foto de los trabajadores cuadrada --- front/salix/components/descriptor/style.scss | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/front/salix/components/descriptor/style.scss b/front/salix/components/descriptor/style.scss index 27f482f26..b96e900c4 100644 --- a/front/salix/components/descriptor/style.scss +++ b/front/salix/components/descriptor/style.scss @@ -7,22 +7,24 @@ vn-descriptor-content { .photo { position: relative; + width: 100%; + text-align: center; + overflow: hidden; & > img[ng-src] { min-height: 16em; display: block; - max-width: 100%; height: 256px; } vn-float-button { - position: absolute; - margin: 1em; - bottom: 0; + position: absolute; + margin: 1em; + bottom: 0; right: 0 } } - + & > vn-spinner { display: block; height: 40px; @@ -39,7 +41,7 @@ vn-descriptor-content { align-items: stretch; color: $color-font-dark; - & > a, + & > a, & > vn-icon-button { display: flex; min-width: 45px; @@ -89,7 +91,7 @@ vn-descriptor-content { display: flex; align-items: center; justify-content: center; - + & > vn-icon { padding: $spacing-xs $spacing-sm; font-size: 1.5rem; From 0d980334b8da9ed54ba71e9f1f1b2a99ea14096a Mon Sep 17 00:00:00 2001 From: alexandre Date: Wed, 17 May 2023 12:41:00 +0200 Subject: [PATCH 33/61] refs #5634 conditional merge --- modules/ticket/back/methods/ticket/merge.js | 7 ++++--- modules/ticket/back/methods/ticket/setDeleted.js | 3 +++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/modules/ticket/back/methods/ticket/merge.js b/modules/ticket/back/methods/ticket/merge.js index 8aaca1085..9a6f859f7 100644 --- a/modules/ticket/back/methods/ticket/merge.js +++ b/modules/ticket/back/methods/ticket/merge.js @@ -63,10 +63,11 @@ module.exports = Self => { newInstance: {mergedTicket: ticket.originId} }; - await models.TicketLog.create(ticketDestinationLogRecord, myOptions); await models.Sale.updateAll({ticketFk: ticket.originId}, {ticketFk: ticket.destinationId}, myOptions); - await models.Ticket.setDeleted(ctx, ticket.originId, myOptions); - await models.Chat.sendCheckingPresence(ctx, ticket.workerFk, message); + if (await models.Ticket.setDeleted(ctx, ticket.originId, myOptions)) { + await models.TicketLog.create(ticketDestinationLogRecord, myOptions); + await models.Chat.sendCheckingPresence(ctx, ticket.workerFk, message); + } } if (tx) await tx.commit(); diff --git a/modules/ticket/back/methods/ticket/setDeleted.js b/modules/ticket/back/methods/ticket/setDeleted.js index 2889160d1..8c7f9d546 100644 --- a/modules/ticket/back/methods/ticket/setDeleted.js +++ b/modules/ticket/back/methods/ticket/setDeleted.js @@ -36,6 +36,9 @@ module.exports = Self => { } try { + const ticketToDelete = await models.Ticket.findById(id, {fields: ['isDeleted']}, myOptions); + if (ticketToDelete.isDeleted) return false; + const userId = ctx.req.accessToken.userId; const isEditable = await Self.isEditable(ctx, id, myOptions); From 4bcb461d363af6985a25ae7db4447860371371dd Mon Sep 17 00:00:00 2001 From: alexandre Date: Thu, 18 May 2023 11:41:46 +0200 Subject: [PATCH 34/61] refs #3628 added check & date-picker --- modules/item/front/diary/index.js | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/modules/item/front/diary/index.js b/modules/item/front/diary/index.js index 03134913f..1d2e34a66 100644 --- a/modules/item/front/diary/index.js +++ b/modules/item/front/diary/index.js @@ -38,12 +38,8 @@ class Controller extends Section { if (value && value != this._warehouseFk) { this._warehouseFk = value; this.card.warehouseFk = value; + this.filter.where.warehouseFk = this.warehouseFk; - this.$state.go(this.$state.current.name, { - warehouseFk: value - }); - - this.filter.where.warehouseFk = value; this.$.model.refresh(); } } @@ -52,6 +48,28 @@ class Controller extends Section { return this._warehouseFk; } + set date(value) { + this._date = value; + this.filter.where.date = value; + this.filter.where.warehouseFk = this.warehouseFk; + + this.$.model.refresh(); + } + + get date() { + return this._date; + } + + set showOld(value) { + this._showOld = value; + if (!this._showOld) this.date = null; + else this.date = new Date(); + } + + get showOld() { + return this._showOld; + } + scrollToLine(lineFk) { this.$.$applyAsync(() => { const hashFk = this.lineFk || lineFk; From 2591d2d1155064bc23e13799f705bc16943e9f02 Mon Sep 17 00:00:00 2001 From: alexandre Date: Thu, 18 May 2023 11:42:22 +0200 Subject: [PATCH 35/61] refs #3628 added check & date-picker --- db/dump/structure.sql | 322 +++++++++++------- modules/item/back/methods/item/getBalance.js | 4 +- .../methods/item/specs/getBalance.spec.js | 9 +- modules/item/front/diary/index.html | 20 +- modules/item/front/diary/locale/es.yml | 3 +- modules/item/front/diary/style.scss | 5 +- 6 files changed, 222 insertions(+), 141 deletions(-) diff --git a/db/dump/structure.sql b/db/dump/structure.sql index 3256ecdca..380202eeb 100644 --- a/db/dump/structure.sql +++ b/db/dump/structure.sql @@ -59861,141 +59861,205 @@ DELIMITER ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; DELIMITER ;; -CREATE DEFINER=`root`@`localhost` PROCEDURE `item_getBalance`(IN vItemId int, IN vWarehouse int) +CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`item_getBalance`(vItemFk int, vWarehouseFk int, vDate DATETIME) BEGIN - DECLARE vDateInventory DATETIME; - DECLARE vCurdate DATE DEFAULT util.VN_CURDATE(); - DECLARE vDayEnd DATETIME DEFAULT util.dayEnd(vCurdate); +/** + * @vItemFk item a buscar + * @vWarehouseFk almacen donde buscar + * @vDate Si la fecha es null, muestra el histórico desde el inventario. Si la fecha no es null, muestra histórico desde la fecha pasada. + */ - SELECT inventoried INTO vDateInventory FROM config; - SET @a = 0; - SET @currentLineFk = 0; - SET @shipped = ''; + DECLARE vDateInventory DATETIME; + DECLARE vInvCalculated INT; - SELECT DATE(@shipped:= shipped) shipped, - alertLevel, - stateName, - origin, - reference, - clientFk, - name, - `in` AS invalue, - `out`, - @a := @a + IFNULL(`in`,0) - IFNULL(`out`,0) as balance, - @currentLineFk := IF (@shipped < util.VN_CURDATE() - OR (@shipped = util.VN_CURDATE() AND (isPicked OR alertLevel >= 2)), - lineFk,@currentLineFk) lastPreparedLineFk, - isTicket, - lineFk, - isPicked, - clientType, - claimFk - FROM - ( SELECT tr.landed AS shipped, - b.quantity AS `in`, - NULL AS `out`, - al.id AS alertLevel, - st.name AS stateName, - s.name AS name, - e.invoiceNumber AS reference, - e.id AS origin, - s.id AS clientFk, - IF(al.id = 3, TRUE, FALSE) isPicked, - FALSE AS isTicket, - b.id lineFk, - NULL `order`, - NULL AS clientType, - NULL AS claimFk - FROM buy b - JOIN entry e ON e.id = b.entryFk - JOIN travel tr ON tr.id = e.travelFk - JOIN supplier s ON s.id = e.supplierFk - JOIN alertLevel al ON al.id = - CASE - WHEN tr.landed < util.VN_CURDATE() THEN 3 - WHEN tr.landed = util.VN_CURDATE() AND tr.isReceived = TRUE THEN 3 - ELSE 0 - END - JOIN state st ON st.code = al.code - WHERE tr.landed >= vDateInventory - AND vWarehouse = tr.warehouseInFk - AND b.itemFk = vItemId - AND e.isExcludedFromAvailable = FALSE - AND e.isRaid = FALSE - UNION ALL + IF vDate IS NULL THEN + SELECT inventoried INTO vDateInventory + FROM config; + ELSE + SELECT mockUtcTime INTO vDateInventory + FROM util.config; + END IF; - SELECT tr.shipped, - NULL, - b.quantity, - al.id, - st.name, - s.name, - e.invoiceNumber, - e.id, - s.id, - IF(al.id = 3, TRUE, FALSE), - FALSE, - b.id, - NULL, - NULL, - NULL - FROM buy b - JOIN entry e ON e.id = b.entryFk - JOIN travel tr ON tr.id = e.travelFk - JOIN warehouse w ON w.id = tr.warehouseOutFk - JOIN supplier s ON s.id = e.supplierFk - JOIN alertLevel al ON al.id = - CASE - WHEN tr.shipped < util.VN_CURDATE() THEN 3 - WHEN tr.shipped = util.VN_CURDATE() AND tr.isReceived = TRUE THEN 3 - ELSE 0 - END - JOIN state st ON st.code = al.code - WHERE tr.shipped >= vDateInventory - AND vWarehouse =tr.warehouseOutFk - AND s.id <> 4 - AND b.itemFk = vItemId - AND e.isExcludedFromAvailable = FALSE - AND w.isFeedStock = FALSE - AND e.isRaid = FALSE - UNION ALL + CREATE OR REPLACE TEMPORARY TABLE itemDiary( + shipped DATE, + `in` INT(11), + `out` INT(11), + alertLevel INT(11), + stateName VARCHAR(20), + `name` VARCHAR(50), + reference VARCHAR(50), + origin INT(11), + clientFk INT(11), + isPicked INT(11), + isTicket TINYINT(1), + lineFk INT(11), + `order` TINYINT(3) UNSIGNED, + clientType VARCHAR(20), + claimFk INT(10) UNSIGNED + ); - SELECT DATE(t.shipped), - NULL, - s.quantity, - al.id, - st.name, - t.nickname, - t.refFk, - t.id, - t.clientFk, - stk.id, - TRUE, - s.id, - st.`order`, - ct.code, - cb.claimFk - FROM sale s - JOIN ticket t ON t.id = s.ticketFk - LEFT JOIN ticketState ts ON ts.ticket = t.id - LEFT JOIN state st ON st.code = ts.code - JOIN client c ON c.id = t.clientFk - JOIN clientType ct ON ct.id = c.clientTypeFk - JOIN alertLevel al ON al.id = - CASE - WHEN t.shipped < util.VN_CURDATE() THEN 3 - WHEN t.shipped > util.dayEnd(util.VN_CURDATE()) THEN 0 - ELSE IFNULL(ts.alertLevel, 0) - END - LEFT JOIN state stPrep ON stPrep.`code` = 'PREPARED' - LEFT JOIN saleTracking stk ON stk.saleFk = s.id AND stk.stateFk = stPrep.id - LEFT JOIN claimBeginning cb ON s.id = cb.saleFk - WHERE t.shipped >= vDateInventory - AND s.itemFk = vItemId - AND vWarehouse =t.warehouseFk - ORDER BY shipped, alertLevel DESC, isTicket, `order` DESC, isPicked DESC, `in` DESC, `out` DESC - ) AS itemDiary; + INSERT INTO itemDiary + SELECT tr.landed shipped, + b.quantity `in`, + NULL `out`, + al.id alertLevel, + st.name stateName, + s.name `name`, + e.invoiceNumber reference, + e.id origin, + s.id clientFk, + IF(al.code = 'DELIVERED', TRUE, FALSE) isPicked, + FALSE isTicket, + b.id lineFk, + NULL `order`, + NULL clientType, + NULL claimFk + FROM buy b + JOIN entry e ON e.id = b.entryFk + JOIN travel tr ON tr.id = e.travelFk + JOIN supplier s ON s.id = e.supplierFk + JOIN alertLevel al ON al.code = + CASE + WHEN tr.landed < util.VN_CURDATE() THEN 'DELIVERED' + WHEN tr.landed = util.VN_CURDATE() AND tr.isReceived = TRUE THEN 'DELIVERED' + ELSE 'FREE' + END + JOIN state st ON st.code = al.code + WHERE tr.landed >= vDateInventory + AND vWarehouseFk = tr.warehouseInFk + AND b.itemFk = vItemFk + AND e.isExcludedFromAvailable = FALSE + AND e.isRaid = FALSE + UNION ALL + SELECT tr.shipped, + NULL, + b.quantity, + al.id, + st.name, + s.name, + e.invoiceNumber, + e.id, + s.id, + IF(al.code = 'DELIVERED', TRUE, FALSE), + FALSE, + b.id, + NULL, + NULL, + NULL + FROM buy b + JOIN entry e ON e.id = b.entryFk + JOIN travel tr ON tr.id = e.travelFk + JOIN warehouse w ON w.id = tr.warehouseOutFk + JOIN supplier s ON s.id = e.supplierFk + JOIN alertLevel al ON al.code = + CASE + WHEN tr.shipped < util.VN_CURDATE() THEN 'DELIVERED' + WHEN tr.shipped = util.VN_CURDATE() AND tr.isReceived = TRUE THEN 'DELIVERED' + ELSE 'FREE' + END + JOIN state st ON st.code = al.code + JOIN entryConfig ec + WHERE tr.shipped >= vDateInventory + AND vWarehouseFk =tr.warehouseOutFk + AND s.id <> ec.inventorySupplierFk + AND b.itemFk = vItemFk + AND e.isExcludedFromAvailable = FALSE + AND w.isFeedStock = FALSE + AND e.isRaid = FALSE + UNION ALL + SELECT DATE(t.shipped), + NULL, + s.quantity, + al3.id, + st.name, + t.nickname, + t.refFk, + t.id, + t.clientFk, + stk.id, + TRUE, + s.id, + st.`order`, + ct.code, + cb.claimFk + FROM sale s + JOIN ticket t ON t.id = s.ticketFk + LEFT JOIN ticketState ts ON ts.ticket = t.id + LEFT JOIN state st ON st.code = ts.code + JOIN client c ON c.id = t.clientFk + JOIN clientType ct ON ct.id = c.clientTypeFk + JOIN alertLevel al ON al.code = 'DELIVERED' + JOIN alertLevel al2 ON al2.code = 'FREE' + JOIN alertLevel al3 ON al3.id = + CASE + WHEN t.shipped < util.VN_CURDATE() THEN al.code + WHEN t.shipped > util.dayEnd(util.VN_CURDATE()) THEN al2.code + ELSE IFNULL(ts.alertLevel, al2.code) + END + LEFT JOIN state stPrep ON stPrep.`code` = 'PREPARED' + LEFT JOIN saleTracking stk ON stk.saleFk = s.id AND stk.stateFk = stPrep.id + LEFT JOIN claimBeginning cb ON s.id = cb.saleFk + WHERE t.shipped >= vDateInventory + AND s.itemFk = vItemFk + AND vWarehouseFk =t.warehouseFk + ORDER BY shipped, alertLevel DESC, isTicket, `order` DESC, isPicked DESC, `in` DESC, `out` DESC; + IF vDate IS NULL THEN + SET @a = 0; + SET @currentLineFk = 0; + SET @shipped = ''; + + SELECT DATE(@shipped:= shipped) shipped, + alertLevel, + stateName, + origin, + reference, + clientFk, + name, + `in` AS invalue, + `out`, + @a := @a + IFNULL(`in`,0) - IFNULL(`out`,0) as balance, + @currentLineFk := IF (@shipped < util.VN_CURDATE() + OR (@shipped = util.VN_CURDATE() AND (isPicked OR a.code >= 'ON_PREPARATION')), + lineFk, @currentLineFk) lastPreparedLineFk, + isTicket, + lineFk, + isPicked, + clientType, + claimFk + FROM itemDiary + JOIN alertLevel a ON a.id = itemDiary.alertLevel; + ELSE + SELECT sum(`in`) - sum(`out`) INTO vInvCalculated + FROM itemDiary + WHERE shipped < vDate; + + SELECT p1.* + FROM( + SELECT vDate shipped, + 0 alertLevel, + 0 stateName, + 0 origin, + '' reference, + 0 clientFk, + 'Inventario calculado', + vInvCalculated invalue, + NULL `out`, + 0 balance, + 0 lastPreparedLineFk, + 0 isTicket, + 0 lineFk, + 0 isPicked, + 0 clientType, + 0 claimFk + UNION ALL + SELECT shipped, alertlevel, stateName, origin, reference, clientFk, name, `in`, `out`, 0,0, isTicket, lineFk, isPicked, clientType, claimFk + FROM itemDiary + WHERE shipped >= vDate + )as p1; + END IF; + + DROP TEMPORARY TABLE itemDiary; END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; diff --git a/modules/item/back/methods/item/getBalance.js b/modules/item/back/methods/item/getBalance.js index 50372652d..5751b0a04 100644 --- a/modules/item/back/methods/item/getBalance.js +++ b/modules/item/back/methods/item/getBalance.js @@ -26,8 +26,8 @@ module.exports = Self => { Object.assign(myOptions, options); const where = filter.where; - const query = 'CALL vn.item_getBalance(?, ?)'; - const [diary] = await Self.rawSql(query, [where.itemFk, where.warehouseFk], myOptions); + const query = 'CALL vn.item_getBalance(?, ?, ?)'; + const [diary] = await Self.rawSql(query, [where.itemFk, where.warehouseFk, where.date], myOptions); for (const entry of diary) if (entry.clientType === 'loses') entry.highlighted = true; diff --git a/modules/item/back/methods/item/specs/getBalance.spec.js b/modules/item/back/methods/item/specs/getBalance.spec.js index 779516b19..1ffd3c302 100644 --- a/modules/item/back/methods/item/specs/getBalance.spec.js +++ b/modules/item/back/methods/item/specs/getBalance.spec.js @@ -21,7 +21,8 @@ describe('item getBalance()', () => { const filter = { where: { itemFk: 1, - warehouseFk: 1 + warehouseFk: 1, + date: null } }; const results = await models.Item.getBalance(filter, options); @@ -45,14 +46,16 @@ describe('item getBalance()', () => { const firstFilter = { where: { itemFk: 1, - warehouseFk: 1 + warehouseFk: 1, + date: null } }; const secondFilter = { where: { itemFk: 2, - warehouseFk: 1 + warehouseFk: 1, + date: null } }; diff --git a/modules/item/front/diary/index.html b/modules/item/front/diary/index.html index 0f00f5854..1814dad06 100644 --- a/modules/item/front/diary/index.html +++ b/modules/item/front/diary/index.html @@ -25,6 +25,16 @@ ng-model="$ctrl.warehouseFk" label="Select warehouse"> + + + + @@ -44,7 +54,7 @@ - {{::sale.shipped | date:'dd/MM/yyyy' }} @@ -99,13 +109,13 @@ - - - diff --git a/modules/item/front/diary/locale/es.yml b/modules/item/front/diary/locale/es.yml index e00816d78..6a6fe6636 100644 --- a/modules/item/front/diary/locale/es.yml +++ b/modules/item/front/diary/locale/es.yml @@ -1,4 +1,5 @@ In: Entrada Out: Salida Visible quantity: Cantidad visible -Ticket/Entry: Ticket/Entrada \ No newline at end of file +Ticket/Entry: Ticket/Entrada +Show old to inventory: Mostrar lo anterior al inventario diff --git a/modules/item/front/diary/style.scss b/modules/item/front/diary/style.scss index e8d261ec2..0a6cafcb9 100644 --- a/modules/item/front/diary/style.scss +++ b/modules/item/front/diary/style.scss @@ -27,4 +27,7 @@ vn-item-diary { overflow: hidden; text-overflow: ellipsis; } -} \ No newline at end of file + .table-check{ + justify-content: center; + } +} From cbbb5716382a290ffee9f9f1fdf50218f6833719 Mon Sep 17 00:00:00 2001 From: alexandre Date: Thu, 18 May 2023 11:45:50 +0200 Subject: [PATCH 36/61] refs #3628 changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bfff5e53b..d28b22ea0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [2322.01] - 2023-06-08 ### Added -- +- (Artículos -> Histórico) Filtro para mostrar lo anterior al inventario ### Changed From 814568f2a9532f18218177cadd7d5df58324da66 Mon Sep 17 00:00:00 2001 From: carlossa Date: Thu, 18 May 2023 13:11:17 +0200 Subject: [PATCH 37/61] refs #5297 errors solve, trad --- CHANGELOG.md | 4 ---- modules/worker/front/create/locale/es.yml | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8faeff923..ccca79238 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,11 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - (Usuarios -> Histórico) Nueva sección - (Roles -> Histórico) Nueva sección -<<<<<<< HEAD - (Trabajadores -> Dar de alta) Permite elegir el método de pago -======= -- (General -> Traducciones) Correo de bienvenida a clientes al portugués y al francés ->>>>>>> 8a843b37bd9067b6be1dfa090d557b59a0111bcf ### Changed - (Artículo -> Precio fijado) Modificado el buscador superior por uno lateral diff --git a/modules/worker/front/create/locale/es.yml b/modules/worker/front/create/locale/es.yml index 78d24a4c9..1a0f03ef6 100644 --- a/modules/worker/front/create/locale/es.yml +++ b/modules/worker/front/create/locale/es.yml @@ -10,4 +10,4 @@ Street: Dirección Postcode: Código postal Web user: Usuario Web Access permission: Permiso de acceso -Pay method: Metodo de pago +Pay method: Método de pago From 0045edb6982573592dda1c2215beeeaa3ccab6e1 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 23 May 2023 07:39:43 +0200 Subject: [PATCH 38/61] refs #5094 fix get email --- back/methods/docuware/deliveryNoteEmail.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/back/methods/docuware/deliveryNoteEmail.js b/back/methods/docuware/deliveryNoteEmail.js index 1497dcdf9..1557a3a87 100644 --- a/back/methods/docuware/deliveryNoteEmail.js +++ b/back/methods/docuware/deliveryNoteEmail.js @@ -58,7 +58,10 @@ module.exports = Self => { for (const param in args) params[param] = args[param]; - if (!recipient) params.recipient = models.Client.findById(recipientId, {fields: ['email']}); + if (!recipient) { + client = await models.Client.findById(recipientId, {fields: ['email']}); + params.recipient = client.email; + } const email = new Email('delivery-note', params); From dc244b55674e64a1f39da22ca045aef743160af9 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 23 May 2023 08:23:52 +0200 Subject: [PATCH 39/61] refs #5488 remove State_seeFilteredEditableStates --- db/changes/232201/00-useSpecificsAcls.sql | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/db/changes/232201/00-useSpecificsAcls.sql b/db/changes/232201/00-useSpecificsAcls.sql index 2c12e064c..0d17ca948 100644 --- a/db/changes/232201/00-useSpecificsAcls.sql +++ b/db/changes/232201/00-useSpecificsAcls.sql @@ -11,7 +11,6 @@ INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `pri ('State', 'editableStates', 'READ', 'ALLOW', 'ROLE', 'employee'), ('State', 'seeEditableStates', 'READ', 'ALLOW', 'ROLE', 'administrative'), ('State', 'seeEditableStates', 'READ', 'ALLOW', 'ROLE', 'production'), - ('State', 'seeFilteredEditableStates', 'READ', 'ALLOW', 'ROLE', 'salesPerson'), ('State', 'isSomeEditable', 'READ', 'ALLOW', 'ROLE', 'salesPerson'), ('State', 'isAllEditable', 'READ', 'ALLOW', 'ROLE', 'production'), ('State', 'isAllEditable', 'READ', 'ALLOW', 'ROLE', 'administrative'), @@ -115,3 +114,8 @@ INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `pri ('Worker', 'holidays', 'READ', 'ALLOW', 'ROLE', 'employee'), ('Worker', 'activeContract', 'READ', 'ALLOW', 'ROLE', 'employee'), ('Worker', 'activeWithInheritedRole', 'READ', 'ALLOW', 'ROLE', 'employee'); + +DELETE FROM `salix`.`ACL` + WHERE model = 'Client' + AND property = 'updateUser' + AND accessType = '*'; From 0c673e43bc155ce29e485dee50955e4c527b4063 Mon Sep 17 00:00:00 2001 From: carlossa Date: Tue, 23 May 2023 09:02:05 +0200 Subject: [PATCH 40/61] refs #5639 smart-tabla defaulter --- modules/client/front/defaulter/index.html | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/client/front/defaulter/index.html b/modules/client/front/defaulter/index.html index 8f22629a9..1539ee97f 100644 --- a/modules/client/front/defaulter/index.html +++ b/modules/client/front/defaulter/index.html @@ -57,6 +57,12 @@ Comercial + + Country + + + P.Method + From 7fd2927ec9037c81f13b1f1044ec84bee4089b1a Mon Sep 17 00:00:00 2001 From: carlossa Date: Tue, 23 May 2023 11:26:31 +0200 Subject: [PATCH 41/61] refs #5639 smart-table country --- modules/client/back/models/defaulter.json | 10 ++++++++++ modules/client/front/defaulter/index.html | 9 ++++++++- modules/client/front/defaulter/index.js | 14 +++++++++++--- modules/client/front/defaulter/locale/es.yml | 3 +++ 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/modules/client/back/models/defaulter.json b/modules/client/back/models/defaulter.json index ddff1d214..b897a99c3 100644 --- a/modules/client/back/models/defaulter.json +++ b/modules/client/back/models/defaulter.json @@ -29,6 +29,16 @@ "type": "belongsTo", "model": "Client", "foreignKey": "clientFk" + }, + "country": { + "type": "belongsTo", + "model": "Country", + "foreignKey": "countryFk" + }, + "payMethod": { + "type": "belongsTo", + "model": "PayMethod", + "foreignKey": "payMethodFk" } } } \ No newline at end of file diff --git a/modules/client/front/defaulter/index.html b/modules/client/front/defaulter/index.html index 1539ee97f..2feecb752 100644 --- a/modules/client/front/defaulter/index.html +++ b/modules/client/front/defaulter/index.html @@ -60,7 +60,8 @@ Country - + P.Method + + {{::defaulter.countryFk}} + + {{::defaulter.amount | currency: 'EUR': 2}} Date: Tue, 23 May 2023 11:32:26 +0200 Subject: [PATCH 42/61] refs #5639 payMethodFk --- modules/client/front/defaulter/index.html | 6 +++--- modules/client/front/defaulter/index.js | 8 +++++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/modules/client/front/defaulter/index.html b/modules/client/front/defaulter/index.html index 2feecb752..9de1472a6 100644 --- a/modules/client/front/defaulter/index.html +++ b/modules/client/front/defaulter/index.html @@ -121,9 +121,9 @@ {{::defaulter.countryFk}} - + + {{::defaulter.payMethodFk}} + {{::defaulter.amount | currency: 'EUR': 2}} Date: Tue, 23 May 2023 12:31:02 +0200 Subject: [PATCH 43/61] refs #5639 select country, paymethod --- modules/client/back/methods/defaulter/filter.js | 6 +++++- modules/client/front/defaulter/index.html | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/modules/client/back/methods/defaulter/filter.js b/modules/client/back/methods/defaulter/filter.js index 748581913..736c29f9c 100644 --- a/modules/client/back/methods/defaulter/filter.js +++ b/modules/client/back/methods/defaulter/filter.js @@ -67,9 +67,13 @@ module.exports = Self => { uw.id workerFk, uw.name workerName, c.creditInsurance, - d.defaulterSinced + d.defaulterSinced, + cn.country, + pm.name payMethod FROM vn.defaulter d JOIN vn.client c ON c.id = d.clientFk + JOIN vn.country cn ON cn.id = c.countryFk + JOIN vn.payMethod pm ON pm.id = c.payMethodFk LEFT JOIN vn.clientObservation co ON co.clientFk = c.id LEFT JOIN account.user u ON u.id = c.salesPersonFk LEFT JOIN account.user uw ON uw.id = co.workerFk diff --git a/modules/client/front/defaulter/index.html b/modules/client/front/defaulter/index.html index 9de1472a6..c61bd071e 100644 --- a/modules/client/front/defaulter/index.html +++ b/modules/client/front/defaulter/index.html @@ -119,10 +119,10 @@ - {{::defaulter.countryFk}} + {{::defaulter.country}} - {{::defaulter.payMethodFk}} + {{::defaulter.payMethod}} {{::defaulter.amount | currency: 'EUR': 2}} From 4f5bd95d21762e50e5f56b99f978e7058606d584 Mon Sep 17 00:00:00 2001 From: carlossa Date: Tue, 23 May 2023 13:23:46 +0200 Subject: [PATCH 44/61] refs #5639 order --- modules/client/back/models/defaulter.json | 4 ++-- modules/client/front/defaulter/index.html | 4 ++-- modules/client/front/defaulter/index.js | 9 ++++----- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/modules/client/back/models/defaulter.json b/modules/client/back/models/defaulter.json index b897a99c3..03d68ea71 100644 --- a/modules/client/back/models/defaulter.json +++ b/modules/client/back/models/defaulter.json @@ -33,12 +33,12 @@ "country": { "type": "belongsTo", "model": "Country", - "foreignKey": "countryFk" + "foreignKey": "country" }, "payMethod": { "type": "belongsTo", "model": "PayMethod", - "foreignKey": "payMethodFk" + "foreignKey": "payMethod" } } } \ No newline at end of file diff --git a/modules/client/front/defaulter/index.html b/modules/client/front/defaulter/index.html index c61bd071e..4f662b62b 100644 --- a/modules/client/front/defaulter/index.html +++ b/modules/client/front/defaulter/index.html @@ -57,10 +57,10 @@ Comercial - + Country - P.Method diff --git a/modules/client/front/defaulter/index.js b/modules/client/front/defaulter/index.js index dd2f1dba6..95c7622f9 100644 --- a/modules/client/front/defaulter/index.js +++ b/modules/client/front/defaulter/index.js @@ -30,10 +30,10 @@ export default class Controller extends Section { valueField: 'id', } }, { - field: 'countryFk', + field: 'country', autocomplete: { showField: 'country', - valueField: 'id' + valueField: 'country' } }, { field: 'payMethodFk', @@ -144,7 +144,6 @@ export default class Controller extends Section { const params = { defaulters: this.checked, observation: this.defaulter.observation, - country: this.defaulter.countryFk }; this.$http.post(`Defaulters/observationEmail`, params); } @@ -155,8 +154,8 @@ export default class Controller extends Section { case 'amount': case 'clientFk': case 'workerFk': - case 'countryFk': - case 'payMethodFk': + case 'country': + case 'payMethod': case 'salesPersonFk': return {[`d.${param}`]: value}; case 'created': From 2d06f42493a706a9a47aa2ba60d142ba84149c1d Mon Sep 17 00:00:00 2001 From: carlossa Date: Tue, 23 May 2023 13:33:06 +0200 Subject: [PATCH 45/61] refs #5639 defaulterView --- db/changes/232201/00-defaulterView.sql | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 db/changes/232201/00-defaulterView.sql diff --git a/db/changes/232201/00-defaulterView.sql b/db/changes/232201/00-defaulterView.sql new file mode 100644 index 000000000..8b56e5945 --- /dev/null +++ b/db/changes/232201/00-defaulterView.sql @@ -0,0 +1,20 @@ +-- vn.defaulter source + +CREATE OR REPLACE +ALGORITHM = UNDEFINED VIEW `vn`.`defaulter` AS +select + `d`.`clientFk` AS `clientFk`, + `d`.`created` AS `created`, + `d`.`amount` AS `amount`, + `d`.`defaulterSinced` AS `defaulterSinced`, + `d`.`hasChanged` AS `hasChanged`, + `c`.`countryFk` AS `country`, + `c`.`payMethodFk` AS `payMethod` +from + (((`bs`.`defaulter` `d` +join `vn`.`client` `c` on + (`c`.`id` = `d`.`clientFk`)) +join `vn`.`country` `co` on + (`co`.`id` = `c`.`countryFk`)) +join `vn`.`payMethod` `pm` on + (`pm`.`id` = `c`.`payMethodFk`)); \ No newline at end of file From 31b22b759dad485b8aa1beff22e044fbc400c397 Mon Sep 17 00:00:00 2001 From: carlossa Date: Tue, 23 May 2023 14:50:16 +0200 Subject: [PATCH 46/61] refs #5639 fix e2e selectors --- e2e/helpers/selectors.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index b19db24d7..086909ebf 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -313,7 +313,7 @@ export default { anyClient: 'vn-client-defaulter tbody > tr', firstClientName: 'vn-client-defaulter tbody > tr:nth-child(1) > td:nth-child(2) > span', firstSalesPersonName: 'vn-client-defaulter tbody > tr:nth-child(1) > td:nth-child(3) > span', - firstObservation: 'vn-client-defaulter tbody > tr:nth-child(1) > td:nth-child(6) > vn-textarea[ng-model="defaulter.observation"]', + firstObservation: 'vn-client-defaulter tbody > tr:nth-child(1) > td:nth-child(8) > vn-textarea[ng-model="defaulter.observation"]', allDefaulterCheckbox: 'vn-client-defaulter thead vn-multi-check', addObservationButton: 'vn-client-defaulter vn-button[icon="icon-notes"]', observation: '.vn-dialog.shown vn-textarea[ng-model="$ctrl.defaulter.observation"]', From 6294fc0435a6c55958b14a47a2012980bfc52861 Mon Sep 17 00:00:00 2001 From: carlossa Date: Wed, 24 May 2023 10:02:02 +0200 Subject: [PATCH 47/61] refs #5297 back&e2e fix changes --- db/changes/{231801 => 232201}/00-workerConfigPayMethod.sql | 0 modules/worker/back/methods/worker/specs/new.spec.js | 3 ++- 2 files changed, 2 insertions(+), 1 deletion(-) rename db/changes/{231801 => 232201}/00-workerConfigPayMethod.sql (100%) diff --git a/db/changes/231801/00-workerConfigPayMethod.sql b/db/changes/232201/00-workerConfigPayMethod.sql similarity index 100% rename from db/changes/231801/00-workerConfigPayMethod.sql rename to db/changes/232201/00-workerConfigPayMethod.sql diff --git a/modules/worker/back/methods/worker/specs/new.spec.js b/modules/worker/back/methods/worker/specs/new.spec.js index dcd9ab0e9..44f6e9b09 100644 --- a/modules/worker/back/methods/worker/specs/new.spec.js +++ b/modules/worker/back/methods/worker/specs/new.spec.js @@ -33,7 +33,8 @@ describe('Worker new', () => { code: 'DWW', bossFk: 9, birth: '2022-12-11T23:00:00.000Z', - payMethodFk: 1 + payMethodFk: 1, + roleFk: 1 }; it('should return error if personal mail already exists', async() => { From 30c896c975adec36486be7386aef9d79919bc176 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 24 May 2023 11:20:07 +0200 Subject: [PATCH 48/61] refs #5678 feat(sale_canEdit): handle exist sale --- loopback/locale/es.json | 3 +- modules/ticket/back/methods/sale/canEdit.js | 5 ++- .../back/methods/sale/specs/canEdit.spec.js | 42 +++++++++++++------ 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 45993bdd5..956e66985 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -84,6 +84,7 @@ "The current ticket can't be modified": "El ticket actual no puede ser modificado", "The current claim can't be modified": "La reclamación actual no puede ser modificada", "The sales of this ticket can't be modified": "Las lineas de este ticket no pueden ser modificadas", + "The sales do not exist": "La(s) linea(s) seleccionada no(s) exite(n)", "Please select at least one sale": "Por favor selecciona al menos una linea", "All sales must belong to the same ticket": "Todas las lineas deben pertenecer al mismo ticket", "NO_ZONE_FOR_THIS_PARAMETERS": "Para este día no hay ninguna zona configurada", @@ -291,4 +292,4 @@ "comercialId": "Id comercial", "comercialName": "Comercial", "Invalid NIF for VIES": "Invalid NIF for VIES" -} \ No newline at end of file +} diff --git a/modules/ticket/back/methods/sale/canEdit.js b/modules/ticket/back/methods/sale/canEdit.js index 3091ebca7..df0a939bf 100644 --- a/modules/ticket/back/methods/sale/canEdit.js +++ b/modules/ticket/back/methods/sale/canEdit.js @@ -38,6 +38,9 @@ module.exports = Self => { } }, myOptions); + if (!salesData.length) + throw new UserError(`The sales do not exist`); + const ticketId = salesData[0].ticketFk; const isTicketEditable = await models.Ticket.isEditable(ctx, ticketId, myOptions); @@ -62,7 +65,5 @@ module.exports = Self => { throw new UserError('It is not possible to modify cloned sales'); if (!shouldEditFloramondo) throw new UserError('It is not possible to modify sales that their articles are from Floramondo'); - - return true; }; }; diff --git a/modules/ticket/back/methods/sale/specs/canEdit.spec.js b/modules/ticket/back/methods/sale/specs/canEdit.spec.js index 62f98421a..c12277e80 100644 --- a/modules/ticket/back/methods/sale/specs/canEdit.spec.js +++ b/modules/ticket/back/methods/sale/specs/canEdit.spec.js @@ -17,6 +17,32 @@ describe('sale canEdit()', () => { }); }); + describe('sale not exist', () => { + it('should return error if sale not exist', async() => { + const tx = await models.Sale.beginTransaction({}); + + try { + const options = {transaction: tx}; + + const developerId = 9; + const ctx = {req: {accessToken: {userId: developerId}}}; + + let max = await models.Sale.findOne({fields: ['id'], order: 'id DESC'}, options); + max.id = max.id + 1; + + const sales = [max.id]; + await models.Sale.canEdit(ctx, sales, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e.message; + } + + expect(error).toEqual('The sales do not exist'); + }); + }); + describe('sale editTracked', () => { it('should return true if the role is production regardless of the saleTrackings', async() => { const tx = await models.Sale.beginTransaction({}); @@ -29,9 +55,7 @@ describe('sale canEdit()', () => { const sales = [25]; - const result = await models.Sale.canEdit(ctx, sales, options); - - expect(result).toEqual(true); + await models.Sale.canEdit(ctx, sales, options); await tx.rollback(); } catch (e) { @@ -51,9 +75,7 @@ describe('sale canEdit()', () => { const sales = [10]; - const result = await models.Sale.canEdit(ctx, sales, options); - - expect(result).toEqual(true); + await models.Sale.canEdit(ctx, sales, options); await tx.rollback(); } catch (e) { @@ -87,9 +109,7 @@ describe('sale canEdit()', () => { }); const ctx = {req: {accessToken: {userId: role.id}}}; - const result = await models.Sale.canEdit(ctx, saleCloned, options); - - expect(result).toEqual(true); + await models.Sale.canEdit(ctx, saleCloned, options); await tx.rollback(); } catch (e) { @@ -150,9 +170,7 @@ describe('sale canEdit()', () => { const saleToEdit = await models.Sale.findById(sales[0], null, options); await saleToEdit.updateAttribute('itemFk', 9, options); - const result = await models.Sale.canEdit(ctx, sales, options); - - expect(result).toEqual(true); + await models.Sale.canEdit(ctx, sales, options); await tx.rollback(); } catch (e) { From 05fb0a720380ea61d923629b85bcb1dc1471e8bb Mon Sep 17 00:00:00 2001 From: alexandre Date: Wed, 24 May 2023 12:16:19 +0200 Subject: [PATCH 49/61] refs #5677 tickets without state fixed --- loopback/locale/es.json | 5 +-- .../ticket/back/methods/ticket/saveSign.js | 32 ++++++++++--------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 45993bdd5..81a75c0cc 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -290,5 +290,6 @@ "isTaxDataChecked": "Datos comprobados", "comercialId": "Id comercial", "comercialName": "Comercial", - "Invalid NIF for VIES": "Invalid NIF for VIES" -} \ No newline at end of file + "Invalid NIF for VIES": "Invalid NIF for VIES", + "Ticket does not exist": "Este ticket no existe" +} diff --git a/modules/ticket/back/methods/ticket/saveSign.js b/modules/ticket/back/methods/ticket/saveSign.js index aede7de8e..b8f9d5ced 100644 --- a/modules/ticket/back/methods/ticket/saveSign.js +++ b/modules/ticket/back/methods/ticket/saveSign.js @@ -29,8 +29,7 @@ module.exports = Self => { } }); - Self.saveSign = async(ctx, options) => { - const args = Object.assign({}, ctx.args); + Self.saveSign = async(ctx, tickets, location, signedTime, options) => { const models = Self.app.models; const myOptions = {}; let tx; @@ -48,9 +47,9 @@ module.exports = Self => { async function setLocation(ticketId) { await models.Delivery.create({ ticketFk: ticketId, - longitude: args.location.Longitude, - latitude: args.location.Latitude, - dated: args.signedTime || new Date() + longitude: location.Longitude, + latitude: location.Latitude, + dated: signedTime || new Date() }, myOptions); } @@ -107,9 +106,9 @@ module.exports = Self => { } try { - for (let i = 0; i < args.tickets.length; i++) { + for (const ticketId of tickets) { const ticketState = await models.TicketState.findOne( - {where: {ticketFk: args.tickets[i]}, + {where: {ticketFk: ticketId}, fields: ['alertLevel'] }, myOptions); @@ -117,16 +116,19 @@ module.exports = Self => { fields: ['id'] }, myOptions); + if (!ticketState) + throw new UserError('Ticket does not exist'); if (ticketState.alertLevel < packedAlertLevel.id) throw new UserError('This ticket cannot be signed because it has not been boxed'); - else if (!await gestDocExists(args.tickets[i])) { - if (args.location) setLocation(args.tickets[i]); - if (!gestDocCreated) await createGestDoc(args.tickets[i]); - await models.TicketDms.create({ticketFk: args.tickets[i], dmsFk: dms[0].id}, myOptions); - const ticket = await models.Ticket.findById(args.tickets[i], null, myOptions); - await ticket.updateAttribute('isSigned', true, myOptions); - await Self.rawSql(`CALL vn.ticket_setState(?, ?)`, [args.tickets[i], 'DELIVERED'], myOptions); - } + if (await gestDocExists(ticketId)) + throw new UserError('Ticket is already signed'); + + if (location) setLocation(ticketId); + if (!gestDocCreated) await createGestDoc(ticketId); + await models.TicketDms.create({ticketFk: ticketId, dmsFk: dms[0].id}, myOptions); + const ticket = await models.Ticket.findById(ticketId, null, myOptions); + await ticket.updateAttribute('isSigned', true, myOptions); + await Self.rawSql(`CALL vn.ticket_setState(?, ?)`, [ticketId, 'DELIVERED'], myOptions); } if (tx) await tx.commit(); From 856dcf18cba282b8a79bff1e77f8d00aa09e294d Mon Sep 17 00:00:00 2001 From: alexandre Date: Wed, 24 May 2023 12:17:41 +0200 Subject: [PATCH 50/61] refs #5677 locations --- loopback/locale/es.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 81a75c0cc..664a3cf0e 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -291,5 +291,6 @@ "comercialId": "Id comercial", "comercialName": "Comercial", "Invalid NIF for VIES": "Invalid NIF for VIES", - "Ticket does not exist": "Este ticket no existe" + "Ticket does not exist": "Este ticket no existe", + "Ticket is already signed": "Este ticket ya ha sido firmado" } From 6b66eb3bb279f333b3a84ec963cdfa3ae75984bf Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 24 May 2023 12:59:58 +0200 Subject: [PATCH 51/61] refs #5679 typo --- loopback/locale/es.json | 2 +- modules/ticket/back/methods/sale/canEdit.js | 2 +- modules/ticket/back/methods/sale/specs/canEdit.spec.js | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 956e66985..e5a7ba3f5 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -84,7 +84,7 @@ "The current ticket can't be modified": "El ticket actual no puede ser modificado", "The current claim can't be modified": "La reclamación actual no puede ser modificada", "The sales of this ticket can't be modified": "Las lineas de este ticket no pueden ser modificadas", - "The sales do not exist": "La(s) linea(s) seleccionada no(s) exite(n)", + "The sales do not exists": "La(s) linea(s) seleccionada(s) no exite(n)", "Please select at least one sale": "Por favor selecciona al menos una linea", "All sales must belong to the same ticket": "Todas las lineas deben pertenecer al mismo ticket", "NO_ZONE_FOR_THIS_PARAMETERS": "Para este día no hay ninguna zona configurada", diff --git a/modules/ticket/back/methods/sale/canEdit.js b/modules/ticket/back/methods/sale/canEdit.js index df0a939bf..cb3f2420a 100644 --- a/modules/ticket/back/methods/sale/canEdit.js +++ b/modules/ticket/back/methods/sale/canEdit.js @@ -39,7 +39,7 @@ module.exports = Self => { }, myOptions); if (!salesData.length) - throw new UserError(`The sales do not exist`); + throw new UserError(`The sales do not exists`); const ticketId = salesData[0].ticketFk; diff --git a/modules/ticket/back/methods/sale/specs/canEdit.spec.js b/modules/ticket/back/methods/sale/specs/canEdit.spec.js index c12277e80..eef9136a8 100644 --- a/modules/ticket/back/methods/sale/specs/canEdit.spec.js +++ b/modules/ticket/back/methods/sale/specs/canEdit.spec.js @@ -17,8 +17,8 @@ describe('sale canEdit()', () => { }); }); - describe('sale not exist', () => { - it('should return error if sale not exist', async() => { + describe('sale not exists', () => { + it('should return error if sale not exists', async() => { const tx = await models.Sale.beginTransaction({}); try { @@ -39,7 +39,7 @@ describe('sale canEdit()', () => { error = e.message; } - expect(error).toEqual('The sales do not exist'); + expect(error).toEqual('The sales do not exists'); }); }); From 292d9e038d3479517754ee85d7c68d0e547fcd28 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 24 May 2023 13:38:11 +0200 Subject: [PATCH 52/61] typo --- loopback/locale/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/loopback/locale/es.json b/loopback/locale/es.json index e5a7ba3f5..4f45b0cb2 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -84,7 +84,7 @@ "The current ticket can't be modified": "El ticket actual no puede ser modificado", "The current claim can't be modified": "La reclamación actual no puede ser modificada", "The sales of this ticket can't be modified": "Las lineas de este ticket no pueden ser modificadas", - "The sales do not exists": "La(s) linea(s) seleccionada(s) no exite(n)", + "The sales do not exists": "La(s) línea(s) seleccionada(s) no existe(n)", "Please select at least one sale": "Por favor selecciona al menos una linea", "All sales must belong to the same ticket": "Todas las lineas deben pertenecer al mismo ticket", "NO_ZONE_FOR_THIS_PARAMETERS": "Para este día no hay ninguna zona configurada", From de313b641897c5bd0b27b557336234f835ddede1 Mon Sep 17 00:00:00 2001 From: alexandre Date: Wed, 24 May 2023 13:40:26 +0200 Subject: [PATCH 53/61] refs #3628 Show what's before the inventory --- modules/item/front/diary/index.html | 2 +- modules/item/front/diary/locale/es.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/item/front/diary/index.html b/modules/item/front/diary/index.html index 1814dad06..481cec51a 100644 --- a/modules/item/front/diary/index.html +++ b/modules/item/front/diary/index.html @@ -27,7 +27,7 @@ Date: Thu, 25 May 2023 07:22:56 +0200 Subject: [PATCH 54/61] refs #5706 master to test --- modules/ticket/back/methods/ticket/closeAll.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ticket/back/methods/ticket/closeAll.js b/modules/ticket/back/methods/ticket/closeAll.js index 3726d85b7..6690126b9 100644 --- a/modules/ticket/back/methods/ticket/closeAll.js +++ b/modules/ticket/back/methods/ticket/closeAll.js @@ -52,7 +52,7 @@ module.exports = Self => { JOIN province p ON p.id = c.provinceFk JOIN country co ON co.id = p.countryFk LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk - WHERE al.code = 'PACKED' OR (am.code = 'refund' AND al.code != 'delivered') + WHERE (al.code = 'PACKED' OR (am.code = 'refund' AND al.code != 'delivered')) AND DATE(t.shipped) BETWEEN DATE_ADD(?, INTERVAL -2 DAY) AND util.dayEnd(?) AND t.refFk IS NULL From 256f30987fcb06691faa53903e6f03db285d8329 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 25 May 2023 09:46:39 +0200 Subject: [PATCH 55/61] refs #5730 new version 232401 --- CHANGELOG.md | 16 +++++++++++++++- .../230202/00-itemConfig.sql | 0 db/{changes => .archive}/230401/00-ACL.sql | 0 .../230401/00-ACL_tag_update.sql | 0 .../230401/00-createWorker.sql | 0 .../230401/00-ticket_canAdvance.sql | 0 .../230401/00-updateIsToBeMailed.sql | 0 .../230403/00-clienteCompensado.sql | 0 .../230404/00-ticket_canAdvance.sql | 0 db/{changes => .archive}/230601/00-acl_claim.sql | 0 .../230601/00-acl_notifications.sql | 0 .../230601/00-itemConfig_warehouseFk.sql | 0 .../00-uniqueKeyNotificationSubscription.sql | 0 .../230601/01-alter_notSubs.sql | 0 .../230801/00-acl_itemConfig.sql | 0 .../230801/00-supplierIsVies.sql | 0 .../230801/00-workerLocker.sql | 0 .../230801/01-sage_supplierAdd.sql | 0 db/{changes => .archive}/231001/00-delivery.sql | 0 .../231001/00-invoiceOut.sql | 0 .../231001/00-invoiceOut_getWeight.sql | 0 db/{changes => .archive}/231001/00-report.sql | 0 .../231001/01-invoiceOut_getMaxIssued.sql | 0 .../231001/02-invoiceOut_new.sql | 0 .../231001/03-ticketPackaging_add.sql | 0 db/changes/{232201 => 232401}/.gitkeep | 0 package.json | 2 +- 27 files changed, 16 insertions(+), 2 deletions(-) rename db/{changes => .archive}/230202/00-itemConfig.sql (100%) rename db/{changes => .archive}/230401/00-ACL.sql (100%) rename db/{changes => .archive}/230401/00-ACL_tag_update.sql (100%) rename db/{changes => .archive}/230401/00-createWorker.sql (100%) rename db/{changes => .archive}/230401/00-ticket_canAdvance.sql (100%) rename db/{changes => .archive}/230401/00-updateIsToBeMailed.sql (100%) rename db/{changes => .archive}/230403/00-clienteCompensado.sql (100%) rename db/{changes => .archive}/230404/00-ticket_canAdvance.sql (100%) rename db/{changes => .archive}/230601/00-acl_claim.sql (100%) rename db/{changes => .archive}/230601/00-acl_notifications.sql (100%) rename db/{changes => .archive}/230601/00-itemConfig_warehouseFk.sql (100%) rename db/{changes => .archive}/230601/00-uniqueKeyNotificationSubscription.sql (100%) rename db/{changes => .archive}/230601/01-alter_notSubs.sql (100%) rename db/{changes => .archive}/230801/00-acl_itemConfig.sql (100%) rename db/{changes => .archive}/230801/00-supplierIsVies.sql (100%) rename db/{changes => .archive}/230801/00-workerLocker.sql (100%) rename db/{changes => .archive}/230801/01-sage_supplierAdd.sql (100%) rename db/{changes => .archive}/231001/00-delivery.sql (100%) rename db/{changes => .archive}/231001/00-invoiceOut.sql (100%) rename db/{changes => .archive}/231001/00-invoiceOut_getWeight.sql (100%) rename db/{changes => .archive}/231001/00-report.sql (100%) rename db/{changes => .archive}/231001/01-invoiceOut_getMaxIssued.sql (100%) rename db/{changes => .archive}/231001/02-invoiceOut_new.sql (100%) rename db/{changes => .archive}/231001/03-ticketPackaging_add.sql (100%) rename db/changes/{232201 => 232401}/.gitkeep (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6adcf94f3..75e807a7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,21 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [2322.01] - 2023-06-08 +## [2324.01] - 2023-06-08 + +### Added +- + + +### Changed +- + +### Fixed +- + + + +## [2322.01] - 2023-06-01 ### Added - (Tickets -> Crear Factura) Al facturar se envia automáticamente el pdf al cliente diff --git a/db/changes/230202/00-itemConfig.sql b/db/.archive/230202/00-itemConfig.sql similarity index 100% rename from db/changes/230202/00-itemConfig.sql rename to db/.archive/230202/00-itemConfig.sql diff --git a/db/changes/230401/00-ACL.sql b/db/.archive/230401/00-ACL.sql similarity index 100% rename from db/changes/230401/00-ACL.sql rename to db/.archive/230401/00-ACL.sql diff --git a/db/changes/230401/00-ACL_tag_update.sql b/db/.archive/230401/00-ACL_tag_update.sql similarity index 100% rename from db/changes/230401/00-ACL_tag_update.sql rename to db/.archive/230401/00-ACL_tag_update.sql diff --git a/db/changes/230401/00-createWorker.sql b/db/.archive/230401/00-createWorker.sql similarity index 100% rename from db/changes/230401/00-createWorker.sql rename to db/.archive/230401/00-createWorker.sql diff --git a/db/changes/230401/00-ticket_canAdvance.sql b/db/.archive/230401/00-ticket_canAdvance.sql similarity index 100% rename from db/changes/230401/00-ticket_canAdvance.sql rename to db/.archive/230401/00-ticket_canAdvance.sql diff --git a/db/changes/230401/00-updateIsToBeMailed.sql b/db/.archive/230401/00-updateIsToBeMailed.sql similarity index 100% rename from db/changes/230401/00-updateIsToBeMailed.sql rename to db/.archive/230401/00-updateIsToBeMailed.sql diff --git a/db/changes/230403/00-clienteCompensado.sql b/db/.archive/230403/00-clienteCompensado.sql similarity index 100% rename from db/changes/230403/00-clienteCompensado.sql rename to db/.archive/230403/00-clienteCompensado.sql diff --git a/db/changes/230404/00-ticket_canAdvance.sql b/db/.archive/230404/00-ticket_canAdvance.sql similarity index 100% rename from db/changes/230404/00-ticket_canAdvance.sql rename to db/.archive/230404/00-ticket_canAdvance.sql diff --git a/db/changes/230601/00-acl_claim.sql b/db/.archive/230601/00-acl_claim.sql similarity index 100% rename from db/changes/230601/00-acl_claim.sql rename to db/.archive/230601/00-acl_claim.sql diff --git a/db/changes/230601/00-acl_notifications.sql b/db/.archive/230601/00-acl_notifications.sql similarity index 100% rename from db/changes/230601/00-acl_notifications.sql rename to db/.archive/230601/00-acl_notifications.sql diff --git a/db/changes/230601/00-itemConfig_warehouseFk.sql b/db/.archive/230601/00-itemConfig_warehouseFk.sql similarity index 100% rename from db/changes/230601/00-itemConfig_warehouseFk.sql rename to db/.archive/230601/00-itemConfig_warehouseFk.sql diff --git a/db/changes/230601/00-uniqueKeyNotificationSubscription.sql b/db/.archive/230601/00-uniqueKeyNotificationSubscription.sql similarity index 100% rename from db/changes/230601/00-uniqueKeyNotificationSubscription.sql rename to db/.archive/230601/00-uniqueKeyNotificationSubscription.sql diff --git a/db/changes/230601/01-alter_notSubs.sql b/db/.archive/230601/01-alter_notSubs.sql similarity index 100% rename from db/changes/230601/01-alter_notSubs.sql rename to db/.archive/230601/01-alter_notSubs.sql diff --git a/db/changes/230801/00-acl_itemConfig.sql b/db/.archive/230801/00-acl_itemConfig.sql similarity index 100% rename from db/changes/230801/00-acl_itemConfig.sql rename to db/.archive/230801/00-acl_itemConfig.sql diff --git a/db/changes/230801/00-supplierIsVies.sql b/db/.archive/230801/00-supplierIsVies.sql similarity index 100% rename from db/changes/230801/00-supplierIsVies.sql rename to db/.archive/230801/00-supplierIsVies.sql diff --git a/db/changes/230801/00-workerLocker.sql b/db/.archive/230801/00-workerLocker.sql similarity index 100% rename from db/changes/230801/00-workerLocker.sql rename to db/.archive/230801/00-workerLocker.sql diff --git a/db/changes/230801/01-sage_supplierAdd.sql b/db/.archive/230801/01-sage_supplierAdd.sql similarity index 100% rename from db/changes/230801/01-sage_supplierAdd.sql rename to db/.archive/230801/01-sage_supplierAdd.sql diff --git a/db/changes/231001/00-delivery.sql b/db/.archive/231001/00-delivery.sql similarity index 100% rename from db/changes/231001/00-delivery.sql rename to db/.archive/231001/00-delivery.sql diff --git a/db/changes/231001/00-invoiceOut.sql b/db/.archive/231001/00-invoiceOut.sql similarity index 100% rename from db/changes/231001/00-invoiceOut.sql rename to db/.archive/231001/00-invoiceOut.sql diff --git a/db/changes/231001/00-invoiceOut_getWeight.sql b/db/.archive/231001/00-invoiceOut_getWeight.sql similarity index 100% rename from db/changes/231001/00-invoiceOut_getWeight.sql rename to db/.archive/231001/00-invoiceOut_getWeight.sql diff --git a/db/changes/231001/00-report.sql b/db/.archive/231001/00-report.sql similarity index 100% rename from db/changes/231001/00-report.sql rename to db/.archive/231001/00-report.sql diff --git a/db/changes/231001/01-invoiceOut_getMaxIssued.sql b/db/.archive/231001/01-invoiceOut_getMaxIssued.sql similarity index 100% rename from db/changes/231001/01-invoiceOut_getMaxIssued.sql rename to db/.archive/231001/01-invoiceOut_getMaxIssued.sql diff --git a/db/changes/231001/02-invoiceOut_new.sql b/db/.archive/231001/02-invoiceOut_new.sql similarity index 100% rename from db/changes/231001/02-invoiceOut_new.sql rename to db/.archive/231001/02-invoiceOut_new.sql diff --git a/db/changes/231001/03-ticketPackaging_add.sql b/db/.archive/231001/03-ticketPackaging_add.sql similarity index 100% rename from db/changes/231001/03-ticketPackaging_add.sql rename to db/.archive/231001/03-ticketPackaging_add.sql diff --git a/db/changes/232201/.gitkeep b/db/changes/232401/.gitkeep similarity index 100% rename from db/changes/232201/.gitkeep rename to db/changes/232401/.gitkeep diff --git a/package.json b/package.json index d068d6615..7a0dc5b7c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "salix-back", - "version": "23.22.01", + "version": "23.24.01", "author": "Verdnatura Levante SL", "description": "Salix backend", "license": "GPL-3.0", From fa8fd8d5bcca3ab0c9e09e56ff3d6170ec7e8207 Mon Sep 17 00:00:00 2001 From: carlossa Date: Thu, 25 May 2023 11:41:14 +0200 Subject: [PATCH 56/61] refs #5398 update from oldbranch --- modules/client/front/dms/edit/index.html | 7 ++++++- modules/entry/front/basic-data/index.html | 9 +++++++-- modules/item/front/descriptor/index.html | 9 ++++++++- modules/item/front/request-search-panel/index.html | 9 ++++++++- modules/monitor/front/index/search-panel/index.html | 7 ++++++- modules/route/front/agency-term-search-panel/index.html | 5 +++++ modules/route/front/search-panel/index.html | 7 ++++++- modules/ticket/front/advance-search-panel/index.html | 9 ++++++++- modules/ticket/front/basic-data/step-one/index.html | 7 ++++++- modules/ticket/front/dms/edit/index.html | 7 ++++++- modules/ticket/front/future-search-panel/index.html | 9 ++++++++- modules/ticket/front/search-panel/index.html | 7 ++++++- .../travel/front/extra-community-search-panel/index.html | 9 +++++++-- modules/worker/front/dms/create/index.html | 5 +++++ modules/worker/front/dms/create/index.spec.js | 1 + modules/worker/front/dms/edit/index.html | 7 ++++++- 16 files changed, 99 insertions(+), 15 deletions(-) diff --git a/modules/client/front/dms/edit/index.html b/modules/client/front/dms/edit/index.html index 87d69fdcd..58899df2b 100644 --- a/modules/client/front/dms/edit/index.html +++ b/modules/client/front/dms/edit/index.html @@ -2,6 +2,11 @@ vn-id="watcher" data="$ctrl.dms"> + +
diff --git a/modules/entry/front/basic-data/index.html b/modules/entry/front/basic-data/index.html index 0b3537fac..888205320 100644 --- a/modules/entry/front/basic-data/index.html +++ b/modules/entry/front/basic-data/index.html @@ -5,6 +5,11 @@ form="form" save="patch"> + + @@ -152,14 +157,14 @@ diff --git a/modules/item/front/descriptor/index.html b/modules/item/front/descriptor/index.html index 8e85e043f..d98eabe3e 100644 --- a/modules/item/front/descriptor/index.html +++ b/modules/item/front/descriptor/index.html @@ -1,3 +1,8 @@ + + + data="warehouses" + show-field="name" + value="id">> diff --git a/modules/item/front/request-search-panel/index.html b/modules/item/front/request-search-panel/index.html index dfafb02f3..a76684776 100644 --- a/modules/item/front/request-search-panel/index.html +++ b/modules/item/front/request-search-panel/index.html @@ -1,4 +1,9 @@
+ + + data="warehouses" + show-field="name" + value-field="id"> diff --git a/modules/monitor/front/index/search-panel/index.html b/modules/monitor/front/index/search-panel/index.html index 5458202d2..822f84922 100644 --- a/modules/monitor/front/index/search-panel/index.html +++ b/modules/monitor/front/index/search-panel/index.html @@ -1,4 +1,9 @@
+ + + data="Warehouses"> + + + + diff --git a/modules/ticket/front/advance-search-panel/index.html b/modules/ticket/front/advance-search-panel/index.html index ee18c26f9..c2f5ecd8f 100644 --- a/modules/ticket/front/advance-search-panel/index.html +++ b/modules/ticket/front/advance-search-panel/index.html @@ -1,4 +1,9 @@
+ + diff --git a/modules/ticket/front/basic-data/step-one/index.html b/modules/ticket/front/basic-data/step-one/index.html index 498630b87..73df8c370 100644 --- a/modules/ticket/front/basic-data/step-one/index.html +++ b/modules/ticket/front/basic-data/step-one/index.html @@ -4,6 +4,11 @@ order="name" auto-load="true"> + + @@ -25,7 +30,7 @@ + + diff --git a/modules/ticket/front/future-search-panel/index.html b/modules/ticket/front/future-search-panel/index.html index 18b574f2a..d873fbc37 100644 --- a/modules/ticket/front/future-search-panel/index.html +++ b/modules/ticket/front/future-search-panel/index.html @@ -1,4 +1,9 @@
+ + diff --git a/modules/ticket/front/search-panel/index.html b/modules/ticket/front/search-panel/index.html index 7002f3dd6..d22b06a46 100644 --- a/modules/ticket/front/search-panel/index.html +++ b/modules/ticket/front/search-panel/index.html @@ -1,4 +1,9 @@
+ + + data="Warehouses"> + + diff --git a/modules/worker/front/dms/create/index.html b/modules/worker/front/dms/create/index.html index 3495bf260..96f39ea6b 100644 --- a/modules/worker/front/dms/create/index.html +++ b/modules/worker/front/dms/create/index.html @@ -3,6 +3,11 @@ vn-id="watcher" data="$ctrl.dms"> + + { $element = $compile(``)($rootScope); controller = $element.controller('vnWorkerDmsCreate'); controller._worker = {id: 1101, name: 'Bruce wayne'}; + $httpBackend.whenRoute('GET', `Warehouses?filter=%7B%7D`).respond([{$oldData: {}}]); })); describe('worker() setter', () => { diff --git a/modules/worker/front/dms/edit/index.html b/modules/worker/front/dms/edit/index.html index 2ac96851c..e4939b4ea 100644 --- a/modules/worker/front/dms/edit/index.html +++ b/modules/worker/front/dms/edit/index.html @@ -2,6 +2,11 @@ vn-id="watcher" data="$ctrl.dms"> + + From f37d93b469a59b1790a6d7ea2afa7914d31419ab Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 26 May 2023 14:04:00 +0200 Subject: [PATCH 57/61] refs #5488 correct folder --- db/changes/{232201 => 232401}/00-useSpecificsAcls.sql | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename db/changes/{232201 => 232401}/00-useSpecificsAcls.sql (100%) diff --git a/db/changes/232201/00-useSpecificsAcls.sql b/db/changes/232401/00-useSpecificsAcls.sql similarity index 100% rename from db/changes/232201/00-useSpecificsAcls.sql rename to db/changes/232401/00-useSpecificsAcls.sql From 95c438b73a67d676755b070f7b726886734a8089 Mon Sep 17 00:00:00 2001 From: carlossa Date: Fri, 26 May 2023 14:52:47 +0200 Subject: [PATCH 58/61] refs #5648 move claimSure --- modules/ticket/front/sale/index.html | 4 ++-- modules/ticket/front/sale/index.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/ticket/front/sale/index.html b/modules/ticket/front/sale/index.html index b2c0db18d..f7b3c161d 100644 --- a/modules/ticket/front/sale/index.html +++ b/modules/ticket/front/sale/index.html @@ -491,7 +491,7 @@ + on-accept="$ctrl.onCreateClaimAccepted()"> @@ -513,7 +513,7 @@ Add claim diff --git a/modules/ticket/front/sale/index.js b/modules/ticket/front/sale/index.js index be5f22154..ebf74fb9d 100644 --- a/modules/ticket/front/sale/index.js +++ b/modules/ticket/front/sale/index.js @@ -203,7 +203,7 @@ class Controller extends Section { if (pastDays >= this.ticketConfig[0].daysForWarningClaim) this.$.claimConfirm.show(); else - this.onCreateClaimAccepted(); + this.$.claimSure.show(); } onCreateClaimAccepted() { From 138d158f4f69331feb1b43b9f3e32d45aea5517d Mon Sep 17 00:00:00 2001 From: carlossa Date: Mon, 29 May 2023 09:11:41 +0200 Subject: [PATCH 59/61] #refs 5684 remove and mod selectors --- e2e/helpers/selectors.js | 1 + e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js | 1 - loopback/locale/en.json | 6 ++++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 086909ebf..dcd9211f9 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -625,6 +625,7 @@ export default { selectAllSalesCheckbox: 'vn-ticket-sale vn-thead vn-check', secondSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(2) vn-check[ng-model="sale.checked"]', thirdSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(3) vn-check[ng-model="sale.checked"]', + fourthSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(4) vn-check[ng-model="sale.checked"]', deleteSaleButton: 'vn-ticket-sale vn-tool-bar > vn-button[icon="delete"]', transferSaleButton: 'vn-ticket-sale vn-tool-bar > vn-button[icon="call_split"]', moveToTicketInput: 'form vn-input-number[ng-model="$ctrl.transfer.ticketId"] input', diff --git a/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js b/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js index 2158eec8b..2c9646708 100644 --- a/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js +++ b/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js @@ -251,7 +251,6 @@ describe('Ticket Edit sale path', () => { await page.waitToClick(selectors.ticketSales.moreMenu); await page.waitToClick(selectors.ticketSales.moreMenuCreateClaim); await page.waitToClick(selectors.globalItems.acceptButton); - await page.waitToClick(selectors.globalItems.acceptButton); await page.waitForState('claim.card.basicData'); }); diff --git a/loopback/locale/en.json b/loopback/locale/en.json index e950b981b..b8e97412c 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -171,5 +171,7 @@ "Added observation": "Added observation", "Comment added to client": "Comment added to client", "This ticket is already a refund": "This ticket is already a refund", - "A claim with that sale already exists": "A claim with that sale already exists" -} + "A claim with that sale already exists": "A claim with that sale already exists", + "Can't transfer claimed sales": "Can't transfer claimed sales", + "Invalid quantity": "Invalid quantity" +} \ No newline at end of file From 41b1b2fb3fb3a1bde8fdbda6ac4b549838bdd04f Mon Sep 17 00:00:00 2001 From: carlossa Date: Mon, 29 May 2023 10:02:21 +0200 Subject: [PATCH 60/61] fix > --- modules/item/front/descriptor/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/item/front/descriptor/index.html b/modules/item/front/descriptor/index.html index d98eabe3e..7c442d364 100644 --- a/modules/item/front/descriptor/index.html +++ b/modules/item/front/descriptor/index.html @@ -115,7 +115,7 @@ ng-model="$ctrl.warehouseFk" data="warehouses" show-field="name" - value="id">> + value="id"> From ec5a5be9e67ebf99aa57d1e9362839cf0befd94a Mon Sep 17 00:00:00 2001 From: carlossa Date: Tue, 30 May 2023 09:18:52 +0200 Subject: [PATCH 61/61] refs #5328 remove spaces --- modules/ticket/back/methods/sale/refund.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/ticket/back/methods/sale/refund.js b/modules/ticket/back/methods/sale/refund.js index 3a633de0f..18ccee976 100644 --- a/modules/ticket/back/methods/sale/refund.js +++ b/modules/ticket/back/methods/sale/refund.js @@ -100,7 +100,10 @@ module.exports = Self => { }, myOptions); } } - const query = `CALL vn.ticket_recalc(?)`; await Self.rawSql(query, [refundTicket.id], myOptions); + + const query = `CALL vn.ticket_recalc(?)`; + await Self.rawSql(query, [refundTicket.id], myOptions); + if (tx) await tx.commit(); return refundTicket;