diff --git a/db/changes/10090-iberflora/00-ACL.sql b/db/changes/10090-iberflora/00-ACL.sql new file mode 100644 index 000000000..3a20e3ecb --- /dev/null +++ b/db/changes/10090-iberflora/00-ACL.sql @@ -0,0 +1 @@ +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('Claim', 'updateClaimAction', 'WRITE', 'ALLOW', 'ROLE', 'salesAssistant'); diff --git a/db/changes/10090-iberflora/00-claimState.sql b/db/changes/10090-iberflora/00-claimState.sql new file mode 100644 index 000000000..7a964979b --- /dev/null +++ b/db/changes/10090-iberflora/00-claimState.sql @@ -0,0 +1,2 @@ +UPDATE `vn`.`claimState` SET `roleFk` = '21' WHERE (`id` = '3'); +UPDATE `vn`.`claimState` SET `roleFk` = '21' WHERE (`id` = '5'); diff --git a/modules/claim/back/methods/claim/specs/updateClaim.spec.js b/modules/claim/back/methods/claim/specs/updateClaim.spec.js index 5c95c6cb8..095e374bd 100644 --- a/modules/claim/back/methods/claim/specs/updateClaim.spec.js +++ b/modules/claim/back/methods/claim/specs/updateClaim.spec.js @@ -26,24 +26,21 @@ describe('Update Claim', () => { done(); }); - it('should throw error if isSaleAssistant is false and try to modify a forbidden field', async() => { - let params = { - ticketFk: 3, - clientFk: 101, - ticketCreated: newDate, - workerFk: 18, - isChargedToMana: false, - responsibility: 3, - observation: 'another' + it(`should throw an error as the user doesn't have rights`, async() => { + const forbiddenState = 3; + const salesPersonId = 18; + let data = { + claimStateFk: forbiddenState, + observation: 'valid observation' }; let ctx = { req: { accessToken: { - userId: 18 + userId: salesPersonId } } }; - await app.models.Claim.updateClaim(ctx, newInstance.id, params) + await app.models.Claim.updateClaim(ctx, newInstance.id, data) .catch(e => { error = e; }); @@ -51,74 +48,47 @@ describe('Update Claim', () => { expect(error.message).toEqual(`You don't have enough privileges to change that field`); }); - it('should throw error if isSaleAssistant is false and try to modify a valid field but a forbidden stated', async() => { - let params = { - ticketFk: 3, - clientFk: 101, - ticketCreated: newDate, - workerFk: 18, - claimStateFk: 4, - observation: 'another' + it(`should success to update the claim within privileges `, async() => { + const correctState = 4; + const salesPersonId = 18; + let data = { + observation: 'valid observation', + claimStateFk: correctState, }; let ctx = { req: { accessToken: { - userId: 18 + userId: salesPersonId } } }; - await app.models.Claim.updateClaim(ctx, newInstance.id, params) - .catch(e => { - error = e; - }); - - expect(error.message).toEqual(`You don't have enough privileges to change that field`); - }); - - it('should change field observation', async() => { - let params = { - ticketCreated: newDate, - observation: 'another3' - }; - let ctx = { - req: { - accessToken: { - userId: 18 - } - } - }; - await app.models.Claim.updateClaim(ctx, newInstance.id, params); + await app.models.Claim.updateClaim(ctx, newInstance.id, data); let claimUpdated = await app.models.Claim.findById(newInstance.id); - expect(claimUpdated.observation).toEqual(params.observation); + expect(claimUpdated.observation).toEqual(data.observation); }); - it('should change sensible fields as salesAssistant', async() => { - let params = { - ticketFk: 3, - clientFk: 101, - ticketCreated: newDate, - workerFk: 18, + it('should change some sensible fields as salesAssistant', async() => { + const salesAssistantId = 21; + let data = { claimStateFk: 3, - isChargedToMana: true, - responsibility: 3, - observation: 'another' + workerFk: 5, + observation: 'another valid observation' }; let ctx = { req: { accessToken: { - userId: 21 + userId: salesAssistantId } } }; - await app.models.Claim.updateClaim(ctx, newInstance.id, params); + await app.models.Claim.updateClaim(ctx, newInstance.id, data); let claimUpdated = await app.models.Claim.findById(newInstance.id); - expect(claimUpdated.observation).toEqual(params.observation); - expect(claimUpdated.claimStateFk).toEqual(params.claimStateFk); - expect(claimUpdated.responsibility).toEqual(params.responsibility); - expect(claimUpdated.isChargedToMana).toEqual(params.isChargedToMana); + expect(claimUpdated.observation).toEqual(data.observation); + expect(claimUpdated.claimStateFk).toEqual(data.claimStateFk); + expect(claimUpdated.workerFk).toEqual(data.workerFk); }); }); diff --git a/modules/claim/back/methods/claim/specs/updateClaimAction.spec.js b/modules/claim/back/methods/claim/specs/updateClaimAction.spec.js new file mode 100644 index 000000000..3d3404ac5 --- /dev/null +++ b/modules/claim/back/methods/claim/specs/updateClaimAction.spec.js @@ -0,0 +1,43 @@ +const app = require('vn-loopback/server/server'); + +describe('Update Claim', () => { + let newDate = new Date(); + let newInstance; + let original = { + ticketFk: 3, + clientFk: 101, + ticketCreated: newDate, + workerFk: 18, + claimStateFk: 2, + isChargedToMana: true, + responsibility: 4, + observation: 'observation' + }; + + beforeAll(async done => { + newInstance = await app.models.Claim.create(original); + + done(); + }); + + afterAll(async done => { + await app.models.Claim.destroyById(newInstance.id); + done(); + }); + + it('should update the claim isChargedToMana attribute', async() => { + const data = {isChargedToMana: false}; + const result = await app.models.Claim.updateClaimAction(newInstance.id, data); + + expect(result.id).toEqual(newInstance.id); + expect(result.isChargedToMana).toBeFalsy(); + }); + + it('should update the claim responsibility attribute', async() => { + const data = {responsibility: 2}; + const result = await app.models.Claim.updateClaimAction(newInstance.id, data); + + expect(result.id).toEqual(newInstance.id); + expect(result.responsibility).toEqual(2); + }); +}); diff --git a/modules/claim/back/methods/claim/updateClaim.js b/modules/claim/back/methods/claim/updateClaim.js index 66b409d09..51623a7a8 100644 --- a/modules/claim/back/methods/claim/updateClaim.js +++ b/modules/claim/back/methods/claim/updateClaim.js @@ -1,26 +1,23 @@ const UserError = require('vn-loopback/util/user-error'); -let pick = require('object.pick'); -let diff = require('object-diff'); - module.exports = Self => { Self.remoteMethodCtx('updateClaim', { description: 'Update a claim with privileges', accessType: 'WRITE', accepts: [{ arg: 'id', - type: 'string', + type: 'number', required: true, - description: 'Client id', + description: 'Claim id', http: {source: 'path'} }, { - arg: 'params', + arg: 'data', type: 'object', required: true, - description: 'ticketFk, stateFk', + description: 'Data to update on the model', http: {source: 'body'} }], returns: { - type: 'string', + type: 'object', root: true }, http: { @@ -29,28 +26,31 @@ module.exports = Self => { } }); - Self.updateClaim = async(ctx, id, params) => { + Self.updateClaim = async(ctx, id, data) => { let models = Self.app.models; - let isSalesAssistant; - let currentUserId = ctx.req.accessToken.userId; + let claim = await models.Claim.findById(id); - isSalesAssistant = await models.Account.hasRole(currentUserId, 'salesAssistant'); + let canUpdate = await canChangeState(ctx, claim.claimStateFk); + let hasRights = await canChangeState(ctx, data.claimStateFk); - if (!isSalesAssistant) { - let oldClaim = await models.Claim.findById(id); - let notModifiable = ['id', 'responsibility', 'isChargedToMana']; - let changedFields = diff(oldClaim, params); - let changedFieldsPicked = pick(changedFields, notModifiable); - let statesViables = ['Gestionado', 'Pendiente', 'Anulado', 'Mana']; - let oldState = await models.ClaimState.findOne({where: {id: oldClaim.claimStateFk}}); - let newState = await models.ClaimState.findOne({where: {id: params.claimStateFk}}); - let canChangeState = statesViables.includes(oldState.description) - && statesViables.includes(newState.description); - if (Object.keys(changedFieldsPicked).length != 0 || !canChangeState) - throw new UserError(`You don't have enough privileges to change that field`); - } + if (!canUpdate || !hasRights) + throw new UserError(`You don't have enough privileges to change that field`); - let claim = await Self.findById(id); - return await claim.updateAttributes(params); + return await claim.updateAttributes(data); }; + + async function canChangeState(ctx, id) { + let models = Self.app.models; + let userId = ctx.req.accessToken.userId; + + let state = await models.ClaimState.findById(id, { + include: { + relation: 'writeRole' + } + }); + let stateRole = state.writeRole().name; + let canUpdate = await models.Account.hasRole(userId, stateRole); + + return canUpdate; + } }; diff --git a/modules/claim/back/methods/claim/updateClaimAction.js b/modules/claim/back/methods/claim/updateClaimAction.js new file mode 100644 index 000000000..c9c4f1043 --- /dev/null +++ b/modules/claim/back/methods/claim/updateClaimAction.js @@ -0,0 +1,43 @@ + +module.exports = Self => { + Self.remoteMethod('updateClaimAction', { + description: 'Update a claim with privileges', + accessType: 'WRITE', + accepts: [{ + arg: 'id', + type: 'number', + required: true, + description: 'Claim id', + http: {source: 'path'} + }, { + arg: 'data', + type: 'object', + required: true, + description: 'Data to update on the model', + http: {source: 'body'} + }], + returns: { + type: 'object', + root: true + }, + http: { + path: `/:id/updateClaimAction`, + verb: 'post' + } + }); + + Self.updateClaimAction = async(id, data) => { + let models = Self.app.models; + + let claim = await models.Claim.findById(id); + let updatedData = {}; + + if (data.hasOwnProperty('responsibility')) + updatedData.responsibility = data.responsibility; + + if (data.hasOwnProperty('isChargedToMana')) + updatedData.isChargedToMana = data.isChargedToMana; + + return await claim.updateAttributes(updatedData); + }; +}; diff --git a/modules/claim/back/models/claim-state.json b/modules/claim/back/models/claim-state.json index 1707253b0..bf2554f38 100644 --- a/modules/claim/back/models/claim-state.json +++ b/modules/claim/back/models/claim-state.json @@ -18,7 +18,7 @@ } }, "relations": { - "role": { + "writeRole": { "type": "belongsTo", "model": "Role", "foreignKey": "roleFk" diff --git a/modules/claim/back/models/claim.js b/modules/claim/back/models/claim.js index 3d3971027..234a95434 100644 --- a/modules/claim/back/models/claim.js +++ b/modules/claim/back/models/claim.js @@ -5,4 +5,5 @@ module.exports = Self => { require('../methods/claim/updateClaim')(Self); require('../methods/claim/regularizeClaim')(Self); require('../methods/claim/uploadFile')(Self); + require('../methods/claim/updateClaimAction')(Self); }; diff --git a/modules/claim/front/action/index.js b/modules/claim/front/action/index.js index 5193b5114..439b70d39 100644 --- a/modules/claim/front/action/index.js +++ b/modules/claim/front/action/index.js @@ -167,14 +167,14 @@ class Controller { } saveResponsibility(value) { - let query = `/api/Claims/${this.$stateParams.id}/updateClaim`; + let query = `/api/Claims/${this.$stateParams.id}/updateClaimAction`; this.$http.post(query, {responsibility: value}).then(() => { this.vnApp.showSuccess(this.$translate.instant('Data saved!')); }); } saveMana(value) { - let query = `/api/Claims/${this.$stateParams.id}/updateClaim`; + let query = `/api/Claims/${this.$stateParams.id}/updateClaimAction`; this.$http.post(query, {isChargedToMana: value}).then(() => { this.vnApp.showSuccess(this.$translate.instant('Data saved!'));