diff --git a/back/methods/account/funcionalityAcl.js b/back/methods/account/hasFuncionalityAcl.js similarity index 71% rename from back/methods/account/funcionalityAcl.js rename to back/methods/account/hasFuncionalityAcl.js index ae73dee0b..d6224fffc 100644 --- a/back/methods/account/funcionalityAcl.js +++ b/back/methods/account/hasFuncionalityAcl.js @@ -1,5 +1,5 @@ module.exports = Self => { - Self.remoteMethod('funcionalityAcl', { + Self.remoteMethod('hasFuncionalityAcl', { description: 'Return if user has permissions', accepts: [ { @@ -20,12 +20,12 @@ module.exports = Self => { root: true }, http: { - path: `/funcionalityAcl`, + path: `/hasFuncionalityAcl`, verb: 'GET' } }); - Self.funcionalityAcl = async function(ctx, model, property) { + Self.hasFuncionalityAcl = async function(ctx, model, property) { const userId = ctx.req.accessToken.userId; const models = Self.app.models; @@ -36,11 +36,10 @@ module.exports = Self => { } }); - const hasPermissions = acls.filter(async acl => { - console.log('FILTER: '); - acl.role && await models.Account.hasRole(userId, acl.role); - }); - console.log(hasPermissions); + let hasPermissions; + for (let acl of acls) + if (!hasPermissions) hasPermissions = await models.Account.hasRole(userId, acl.role); + if (hasPermissions) return true; return false; diff --git a/back/models/account.js b/back/models/account.js index f824ed898..7d7fa9fe3 100644 --- a/back/models/account.js +++ b/back/models/account.js @@ -7,7 +7,7 @@ module.exports = Self => { require('../methods/account/change-password')(Self); require('../methods/account/set-password')(Self); require('../methods/account/validate-token')(Self); - require('../methods/account/funcionalityAcl')(Self); + require('../methods/account/hasFuncionalityAcl')(Self); require('../methods/account/privileges')(Self); // Validations diff --git a/db/changes/10490-august/00-funcionalityAcl.sql b/db/changes/10491-august/00-funcionalityAcl.sql similarity index 60% rename from db/changes/10490-august/00-funcionalityAcl.sql rename to db/changes/10491-august/00-funcionalityAcl.sql index b52580327..02f3dbcc4 100644 --- a/db/changes/10490-august/00-funcionalityAcl.sql +++ b/db/changes/10491-august/00-funcionalityAcl.sql @@ -3,11 +3,13 @@ CREATE TABLE `salix`.`funcionalityAcl` ( `model` varchar(255) COLLATE utf8mb3_unicode_ci DEFAULT NULL, `property` varchar(255) COLLATE utf8mb3_unicode_ci DEFAULT NULL, `role` varchar(45) COLLATE utf8mb3_unicode_ci DEFAULT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=65 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; + PRIMARY KEY (`id`), + CONSTRAINT `role_FK` FOREIGN KEY (`role`) REFERENCES `account`.`role` (`name`) ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; INSERT INTO `salix`.`funcionalityAcl` (`model`, `property`, `role`) VALUES ('Sale', 'editTracked', 'production'), - ('Sale', 'editCloned', NULL); + ('Sale', 'editCloned', 66); + ('Sale', 'editWeekly', 66); diff --git a/db/changes/10491-august/delete.keep b/db/changes/10491-august/delete.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 4bd4dd96b..fa76f6f84 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -1357,7 +1357,8 @@ INSERT INTO `vn`.`ticketWeekly`(`ticketFk`, `weekDay`) (2, 1), (3, 2), (4, 4), - (5, 6); + (5, 6), + (14, 6); INSERT INTO `vn`.`travel`(`id`,`shipped`, `landed`, `warehouseInFk`, `warehouseOutFk`, `agencyModeFk`, `m3`, `kg`,`ref`, `totalEntries`, `cargoSupplierFk`) VALUES @@ -2667,7 +2668,7 @@ INSERT INTO `vn`.`ticketCollection` (`ticketFk`, `collectionFk`, `created`, `lev INSERT INTO `vn`.`saleCloned` (`saleClonedFk`, `saleOriginalFk`) VALUES - ('26', '25'); + ('27', '25'); UPDATE `account`.`user` SET `hasGrant` = 1 diff --git a/db/export-data.sh b/db/export-data.sh index bbbeb7152..7252267ba 100755 --- a/db/export-data.sh +++ b/db/export-data.sh @@ -34,6 +34,7 @@ TABLES=( salix ACL fieldAcl + funcionalityAcl module defaultViewConfig ) diff --git a/e2e/paths/05-ticket/09_weekly.spec.js b/e2e/paths/05-ticket/09_weekly.spec.js index d04138ee5..0ba57aa9d 100644 --- a/e2e/paths/05-ticket/09_weekly.spec.js +++ b/e2e/paths/05-ticket/09_weekly.spec.js @@ -19,7 +19,7 @@ describe('Ticket descriptor path', () => { it('should count the amount of tickets in the turns section', async() => { const result = await page.countElement(selectors.ticketsIndex.weeklyTicket); - expect(result).toEqual(5); + expect(result).toEqual(6); }); it('should go back to the ticket index then search and access a ticket summary', async() => { @@ -104,7 +104,7 @@ describe('Ticket descriptor path', () => { await page.doSearch(); const nResults = await page.countElement(selectors.ticketsIndex.searchWeeklyResult); - expect(nResults).toEqual(5); + expect(nResults).toEqual(6); }); it('should update the agency then remove it afterwards', async() => { diff --git a/loopback/locale/en.json b/loopback/locale/en.json index e5a0fae32..6d2faf604 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -133,5 +133,6 @@ "Descanso semanal 36h. / 72h.": "Weekly rest 36h. / 72h.", "Password does not meet requirements": "Password does not meet requirements", "You don't have privileges to change the zone": "You don't have privileges to change the zone or for these parameters there are more than one shipping options, talk to agencies", - "Not enough privileges to edit a client": "Not enough privileges to edit a client" + "Not enough privileges to edit a client": "Not enough privileges to edit a client", + "Sale(s) blocked, please contact production": "Sale(s) blocked, please contact production" } \ 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 1b9e471ef..c0cd4b701 100644 --- a/modules/ticket/back/methods/sale/canEdit.js +++ b/modules/ticket/back/methods/sale/canEdit.js @@ -37,10 +37,18 @@ module.exports = Self => { const saleCloned = await models.SaleCloned.find({where: {saleClonedFk: {inq: sales}}}, myOptions); const hasSaleCloned = saleCloned.length; - const canEditTracked = await models.Account.funcionalityAcl(ctx, 'Sale', 'editTracked'); - const canEditCloned = await models.Account.funcionalityAcl(ctx, 'Sale', 'editCloned'); + const isTicketWeekly = + await models.TicketWeekly.findOne({where: {ticketFk: firstSale.ticketFk}}, myOptions); - const canEdit = (canEditTracked || !hasSaleTracking) && (canEditCloned || !hasSaleCloned); + const canEditTracked = await models.Account.hasFuncionalityAcl(ctx, 'Sale', 'editTracked'); + const canEditCloned = await models.Account.hasFuncionalityAcl(ctx, 'Sale', 'editCloned'); + const canEditWeekly = await models.Account.hasFuncionalityAcl(ctx, 'Ticket', 'editWeekly'); + + const shouldEditTracked = canEditTracked || !hasSaleTracking; + const shouldEditCloned = canEditCloned || !hasSaleCloned; + const shouldEditWeekly = canEditWeekly || !isTicketWeekly; + + const canEdit = shouldEditTracked && shouldEditCloned && shouldEditWeekly; return canEdit; }; diff --git a/modules/ticket/back/methods/sale/specs/canEdit.spec.js b/modules/ticket/back/methods/sale/specs/canEdit.spec.js index 1fe63f33c..7d89471f6 100644 --- a/modules/ticket/back/methods/sale/specs/canEdit.spec.js +++ b/modules/ticket/back/methods/sale/specs/canEdit.spec.js @@ -76,7 +76,7 @@ describe('sale canEdit()', () => { const buyerId = 35; const ctx = {req: {accessToken: {userId: buyerId}}}; - const sales = [26]; + const sales = [27]; const result = await models.Sale.canEdit(ctx, sales, options); @@ -91,14 +91,80 @@ describe('sale canEdit()', () => { it('should return true if any of the sales is cloned and has the correct role', async() => { const tx = await models.Sale.beginTransaction({}); + const roleEnabled = await models.FuncionalityAcl.findOne({ + where: { + model: 'Sale', + property: 'editCloned' + } + }); + if (!roleEnabled || !roleEnabled.role) return; try { const options = {transaction: tx}; - const productionId = 49; - const ctx = {req: {accessToken: {userId: productionId}}}; + const roleId = await models.Role.findOne({ + where: { + name: roleEnabled.role + } + }); + const ctx = {req: {accessToken: {userId: roleId}}}; - const sales = [26]; + const sales = [27]; + + const result = await models.Sale.canEdit(ctx, sales, options); + + expect(result).toEqual(true); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should return false if any of the sales is of ticket weekly', async() => { + const tx = await models.Sale.beginTransaction({}); + + try { + const options = {transaction: tx}; + + const employeeId = 1; + const ctx = {req: {accessToken: {userId: employeeId}}}; + + const sales = [33]; + + const result = await models.Sale.canEdit(ctx, sales, options); + + expect(result).toEqual(false); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should return true if any of the sales is of ticketWeekly and has the correct role', async() => { + const tx = await models.Sale.beginTransaction({}); + const roleEnabled = await models.FuncionalityAcl.findOne({ + where: { + model: 'Sale', + property: 'editWeekly' + } + }); + if (!roleEnabled || !roleEnabled.role) return; + + try { + const options = {transaction: tx}; + + const roleId = await models.Role.findOne({ + where: { + name: roleEnabled.role + } + }); + const ctx = {req: {accessToken: {userId: roleId}}}; + + const sales = [33]; const result = await models.Sale.canEdit(ctx, sales, options); diff --git a/modules/ticket/back/methods/ticket-weekly/specs/filter.spec.js b/modules/ticket/back/methods/ticket-weekly/specs/filter.spec.js index 411bbe014..2587b6657 100644 --- a/modules/ticket/back/methods/ticket-weekly/specs/filter.spec.js +++ b/modules/ticket/back/methods/ticket-weekly/specs/filter.spec.js @@ -17,7 +17,7 @@ describe('ticket-weekly filter()', () => { const firstRow = result[0]; expect(firstRow.ticketFk).toEqual(1); - expect(result.length).toEqual(5); + expect(result.length).toEqual(6); await tx.rollback(); } catch (e) {