diff --git a/loopback/locale/es.json b/loopback/locale/es.json index d77b6d290..e58d55da0 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -84,6 +84,7 @@ "NO_AGENCY_AVAILABLE": "No hay una zona de reparto disponible con estos parámetros", "ERROR_PAST_SHIPMENT": "No puedes seleccionar una fecha de envío en pasado", "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", "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", diff --git a/modules/claim/back/methods/claim/isEditable.js b/modules/claim/back/methods/claim/isEditable.js new file mode 100644 index 000000000..2e9991584 --- /dev/null +++ b/modules/claim/back/methods/claim/isEditable.js @@ -0,0 +1,41 @@ +module.exports = Self => { + Self.remoteMethodCtx('isEditable', { + description: 'Check if a claim is editable', + accessType: 'READ', + accepts: [{ + arg: 'id', + type: 'number', + required: true, + description: 'the claim id', + http: {source: 'path'} + }], + returns: { + type: 'boolean', + root: true + }, + http: { + path: `/:id/isEditable`, + verb: 'get' + } + }); + + Self.isEditable = async(ctx, id) => { + const userId = ctx.req.accessToken.userId; + + const isSalesAssistant = await Self.app.models.Account.hasRole(userId, 'salesAssistant'); + + let claim = await Self.app.models.Claim.findById(id, { + fields: ['claimStateFk'], + include: [{ + relation: 'claimState' + }] + }); + + const isClaimResolved = claim && claim.claimState().code == 'resolved'; + + if (!claim || (isClaimResolved && !isSalesAssistant)) + return false; + + return true; + }; +}; diff --git a/modules/claim/back/methods/claim/specs/isEditable.spec.js b/modules/claim/back/methods/claim/specs/isEditable.spec.js new file mode 100644 index 000000000..ca419de4c --- /dev/null +++ b/modules/claim/back/methods/claim/specs/isEditable.spec.js @@ -0,0 +1,33 @@ +const app = require('vn-loopback/server/server'); + +describe('claim isEditable()', () => { + const salesPerdonId = 18; + const salesAssistantId = 21; + it('should return false if the given claim does not exist', async() => { + let ctx = {req: {accessToken: {userId: salesAssistantId}}}; + let result = await app.models.Claim.isEditable(ctx, 99999); + + expect(result).toEqual(false); + }); + + it('should not be able to edit a resolved claim for a salesPerson', async() => { + let ctx = {req: {accessToken: {userId: salesPerdonId}}}; + let result = await app.models.Claim.isEditable(ctx, 4); + + expect(result).toEqual(false); + }); + + it('should be able to edit a resolved claim for a salesAssistant', async() => { + let ctx = {req: {accessToken: {userId: salesAssistantId}}}; + let result = await app.models.Claim.isEditable(ctx, 4); + + expect(result).toEqual(true); + }); + + it('should be able to edit a claim for a salesAssistant', async() => { + let ctx = {req: {accessToken: {userId: salesPerdonId}}}; + let result = await app.models.Claim.isEditable(ctx, 1); + + expect(result).toEqual(true); + }); +}); diff --git a/modules/claim/back/models/claim-beginning.js b/modules/claim/back/models/claim-beginning.js index 839044112..19e5eb4eb 100644 --- a/modules/claim/back/models/claim-beginning.js +++ b/modules/claim/back/models/claim-beginning.js @@ -1,7 +1,30 @@ + +const UserError = require('vn-loopback/util/user-error'); +const LoopBackContext = require('loopback-context'); + module.exports = Self => { require('../methods/claim-beginning/importToNewRefundTicket')(Self); Self.validatesUniquenessOf('saleFk', { message: `A claim with that sale already exists` }); + + Self.observe('before save', async ctx => { + if (ctx.isNewInstance) return; + await claimIsEditable(ctx); + }); + + Self.observe('before delete', async ctx => { + if (ctx.isNewInstance) return; + await claimIsEditable(ctx); + }); + + async function claimIsEditable(ctx) { + const loopBackContext = LoopBackContext.getCurrentContext(); + const httpCtx = {req: loopBackContext.active}; + const isEditable = await Self.app.models.Claim.isEditable(httpCtx, ctx.where.id); + + if (!isEditable) + throw new UserError(`The current claim can't be modified`); + } }; diff --git a/modules/claim/back/models/claim.js b/modules/claim/back/models/claim.js index 234a95434..fba11cfb6 100644 --- a/modules/claim/back/models/claim.js +++ b/modules/claim/back/models/claim.js @@ -6,4 +6,5 @@ module.exports = Self => { require('../methods/claim/regularizeClaim')(Self); require('../methods/claim/uploadFile')(Self); require('../methods/claim/updateClaimAction')(Self); + require('../methods/claim/isEditable')(Self); }; diff --git a/modules/claim/front/detail/index.html b/modules/claim/front/detail/index.html index 6061146c3..9af8fd328 100644 --- a/modules/claim/front/detail/index.html +++ b/modules/claim/front/detail/index.html @@ -40,6 +40,7 @@ @@ -66,6 +67,7 @@ @@ -76,9 +78,13 @@ - - - + + diff --git a/modules/claim/front/detail/index.js b/modules/claim/front/detail/index.js index 591072e6e..d84090e52 100644 --- a/modules/claim/front/detail/index.js +++ b/modules/claim/front/detail/index.js @@ -28,6 +28,7 @@ class Controller extends Section { if (value) { this.calculateTotals(); this.isClaimEditable(); + this.isTicketEditable(); } } @@ -134,7 +135,7 @@ class Controller extends Section { }); } - isClaimEditable() { + isTicketEditable() { if (!this.claim) return; this.$http.get(`Tickets/${this.claim.ticketFk}/isEditable`).then(res => { @@ -142,6 +143,14 @@ class Controller extends Section { }); } + isClaimEditable() { + if (!this.claim) return; + + this.$http.get(`Claims/${this.claim.id}/isEditable`).then(res => { + this.isRewritable = res.data; + }); + } + updateDiscount() { const claimedSale = this.saleClaimed.sale; if (this.newDiscount != claimedSale.discount) { diff --git a/modules/claim/front/detail/index.spec.js b/modules/claim/front/detail/index.spec.js index d2c319f5b..5004ba7a1 100644 --- a/modules/claim/front/detail/index.spec.js +++ b/modules/claim/front/detail/index.spec.js @@ -17,9 +17,13 @@ describe('claim', () => { $httpBackend = _$httpBackend_; $httpBackend.whenGET('Claims/ClaimBeginnings').respond({}); $httpBackend.whenGET(`Tickets/1/isEditable`).respond(true); + $httpBackend.whenGET(`Claims/2/isEditable`).respond(true); const $element = angular.element(''); controller = $componentController('vnClaimDetail', {$element, $scope}); - controller.claim = {ticketFk: 1}; + controller.claim = { + ticketFk: 1, + id: 2} + ; controller.salesToClaim = [{saleFk: 1}, {saleFk: 2}]; controller.salesClaimed = [{id: 1, sale: {}}]; controller.$.model = crudModel; @@ -125,9 +129,9 @@ describe('claim', () => { }); }); - describe('isClaimEditable()', () => { - it('should check if the claim is editable', () => { - controller.isClaimEditable(); + describe('isTicketEditable()', () => { + it('should check if the ticket assigned to the claim is editable', () => { + controller.isTicketEditable(); $httpBackend.flush(); expect(controller.isEditable).toBeTruthy(); diff --git a/modules/claim/front/locale/es.yml b/modules/claim/front/locale/es.yml index 338342eb5..8dae33272 100644 --- a/modules/claim/front/locale/es.yml +++ b/modules/claim/front/locale/es.yml @@ -15,5 +15,4 @@ Show Pickup order: Ver orden de recogida Search claim by id or client name: Buscar reclamaciones por identificador o nombre de cliente Claim deleted!: Reclamación eliminada! claim: reclamación -Photos: Fotos - +Photos: Fotos \ No newline at end of file