From cc3e27246a4f24edf523ab6e4ece61760002085b Mon Sep 17 00:00:00 2001 From: Igor Pavlov Date: Thu, 26 Jul 2018 11:45:42 +0100 Subject: [PATCH] PCHR-4019: Allow self approver to choose request status --- .../shared/controllers/request.controller.js | 46 ++++--- .../controllers/request.controller.spec.js | 118 ++++++++++++++---- .../leave-request-popup-body.html | 2 +- .../leave-request-popup-footer.html | 2 +- 4 files changed, 129 insertions(+), 39 deletions(-) diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/src/leave-absences/shared/controllers/request.controller.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/src/leave-absences/shared/controllers/request.controller.js index ca440a411af..d05084278da 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/src/leave-absences/shared/controllers/request.controller.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/src/leave-absences/shared/controllers/request.controller.js @@ -38,7 +38,7 @@ define([ var childComponentsCount = 0; var initialLeaveRequestAttributes = {}; // used to compare the change in leaverequest in edit mode var listeners = []; - var loggedInContactId = ''; + var loggedInContact; var NO_ENTITLEMENT_ERROR = 'No entitlement'; var role = ''; var tabs = []; @@ -95,7 +95,7 @@ define([ initAvailableStatusesMatrix(); initListeners(); - return loadLoggedInContactId() + return loadLoggedInContact() .then(initIsSelfRecord) .then(function () { return $q.all([ @@ -248,7 +248,7 @@ define([ * If manager or admin have changed the status through dropdown, assign the same before calling API */ function changeStatusBeforeSave () { - if (vm.isSelfRecord) { + if (vm.isSelfRecord && !vm.isSelfLeaveApprover) { vm.request.status_id = vm.requestStatuses[sharedSettings.statusNames.awaitingApproval].value; } else if (vm.canManage) { vm.request.status_id = vm.newStatusOnSave || vm.request.status_id; @@ -287,6 +287,15 @@ define([ return getLeaveType() !== 'toil' && !vm.request.change_balance; } + /** + * Checks if the currently logged in user is a leave approver + * + * @return {Promise} + */ + function checkIfContactIsSelfLeaveApprover () { + return loggedInContact.checkIfSelfLeaveApprover(); + } + /** * Closes the error alerts if any */ @@ -530,7 +539,7 @@ define([ */ function initIsSelfRecord () { var isSectionMyLeave = $rootScope.section === 'my-leave'; - var isMyOwnRequest = +loggedInContactId === +_.get(vm, 'leaveRequest.contact_id'); + var isMyOwnRequest = +loggedInContact.id === +_.get(vm, 'leaveRequest.contact_id'); var isNewRequest = !_.get(vm, 'leaveRequest.id'); vm.isSelfRecord = isSectionMyLeave && (isMyOwnRequest || isNewRequest); @@ -594,7 +603,7 @@ define([ if (vm.request) { attributes = vm.request.attributes(); } else if (!vm.canManage) { - attributes = { contact_id: loggedInContactId }; + attributes = { contact_id: loggedInContact.id }; } return attributes; @@ -613,7 +622,16 @@ define([ // If the user is creating or editing their own leave, they will be // treated as a staff regardless of their actual role. if (vm.isSelfRecord) { - return; + return checkIfContactIsSelfLeaveApprover() + .then(function (isSelfLeaveApprover) { + if (!isSelfLeaveApprover) { + return; + } + + role = 'admin'; + vm.isSelfLeaveApprover = true; + vm.canManage = true; + }); } return checkPermissions(sharedSettings.permissions.admin.administer) @@ -767,10 +785,11 @@ define([ * * @return {Promise} */ - function loadLoggedInContactId () { - return Session.get().then(function (value) { - loggedInContactId = value.contactId; - }); + function loadLoggedInContact () { + return Contact.getLoggedIn() + .then(function (_loggedInContact_) { + loggedInContact = _loggedInContact_; + }); } /** @@ -791,15 +810,12 @@ define([ .then(function (contacts) { vm.managedContacts = _.remove(contacts.list, function (contact) { // Removes the admin from the list of contacts - return contact.id !== loggedInContactId; + return contact.id !== loggedInContact.id; }); }); } else { // In any other case (including managing) - return Contact.find(loggedInContactId) - .then(function (contact) { - return contact.leaveManagees(); - }) + return loggedInContact.leaveManagees() .then(function (contacts) { vm.managedContacts = contacts; }); diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/test/shared/controllers/request.controller.spec.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/test/shared/controllers/request.controller.spec.js index f9b154c35e6..6c42698d660 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/test/shared/controllers/request.controller.spec.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/test/shared/controllers/request.controller.spec.js @@ -22,7 +22,7 @@ describe('LeaveRequestCtrl', function () { var $log, $rootScope, controller, modalInstanceSpy, $scope, $q, dialog, $controller, $provide, sharedSettings, AbsenceTypeAPI, AbsencePeriodAPI, LeaveRequestInstance, - Contact, ContactAPIMock, EntitlementAPI, LeaveRequestAPI, pubSub, + Contact, ContactInstance, ContactAPIMock, EntitlementAPI, LeaveRequestAPI, pubSub, requiredTab, WorkPatternAPI, LeaveRequestService; var role = 'staff'; // change this value to set other roles @@ -65,7 +65,7 @@ }])); beforeEach(inject(function (_$log_, _$controller_, _$rootScope_, _$q_, _dialog_, - _AbsenceTypeAPI_, _AbsencePeriodAPI_, _Contact_, _EntitlementAPI_, _Entitlement_, + _AbsenceTypeAPI_, _AbsencePeriodAPI_, _Contact_, _ContactInstance_, _EntitlementAPI_, _Entitlement_, _LeaveRequestInstance_, _LeaveRequest_, _LeaveRequestAPI_, _pubSub_, _WorkPatternAPI_, _LeaveRequestService_) { $log = _$log_; @@ -75,6 +75,7 @@ dialog = _dialog_; Contact = _Contact_; + ContactInstance = _ContactInstance_; EntitlementAPI = _EntitlementAPI_; LeaveRequestAPI = _LeaveRequestAPI_; WorkPatternAPI = _WorkPatternAPI_; @@ -117,6 +118,8 @@ beforeEach(inject(function () { leaveRequest = LeaveRequestInstance.init(); leaveRequest.contact_id = CRM.vars.leaveAndAbsences.contactId.toString(); + + spyOn(ContactInstance, 'checkIfSelfLeaveApprover').and.returnValue($q.resolve(false)); initTestController({ leaveRequest: leaveRequest }); })); @@ -576,6 +579,7 @@ leaveRequest.contact_id = CRM.vars.leaveAndAbsences.contactId.toString(); $rootScope.section = 'my-leave'; + initTestController({ leaveRequest: leaveRequest }); expectedStatusValue = optionGroupMock.specificValue('hrleaveandabsences_leave_request_status', 'value', '3'); @@ -1342,33 +1346,57 @@ }); }); - describe('user edits their own leave request popup', function () { + describe('when user edits their own leave request', function () { var leaveRequest; - ['staff', 'manager', 'admin'].forEach(function (permissionsRole) { - testRoleForSelfRecord(permissionsRole); + beforeEach(function () { + $rootScope.section = 'my-leave'; + leaveRequest = LeaveRequestInstance.init(); }); - /** - * Tests the role for the self record and expects it to be "staff" - * - * @param {String} permissionsRole (staff|manager|admin) - */ - function testRoleForSelfRecord (permissionsRole) { - describe('when user is ' + permissionsRole, function () { + describe('basic tests', function () { + beforeEach(function () { + spyOn(ContactInstance, 'checkIfSelfLeaveApprover').and.returnValue($q.resolve(false)); + }); + + ['staff', 'manager', 'admin'].forEach(function (permissionsRole) { beforeEach(function () { - $rootScope.section = 'my-leave'; role = permissionsRole; - leaveRequest = LeaveRequestInstance.init(); initTestController({ leaveRequest: leaveRequest }); }); it('sets the staff role', function () { - expect(controller.isRole('staff')).toBeTruthy(); + expect(controller.isRole('staff')).toBe(true); }); }); - } + }); + + describe('when user is a self leave approver', function () { + beforeEach(function () { + spyOn(ContactInstance, 'checkIfSelfLeaveApprover').and.returnValue($q.resolve(true)); + }); + + ['staff', 'manager', 'admin'].forEach(function (permissionsRole) { + beforeEach(function () { + role = permissionsRole; + + initTestController({ leaveRequest: leaveRequest }); + }); + + it('sets the "admin" role', function () { + expect(controller.isRole('admin')).toBe(true); + }); + + it('sets the `isSelfLeaveApprover` public property to `true`', function () { + expect(controller.isSelfLeaveApprover).toBe(true); + }); + + it('sets the `canManage` public property to `true`', function () { + expect(controller.canManage).toBe(true); + }); + }); + }); }); describe('checking if it is a self record', function () { @@ -1399,7 +1427,7 @@ }); }); - describe('and the user is checking my own request', function () { + describe('and the user is checking their own leave request', function () { beforeEach(function () { leaveRequest.id = _.uniqueId(); leaveRequest.contact_id = loggedInContactId; @@ -1412,13 +1440,59 @@ }); }); - describe('and the user creates a new request for themselves', function () { - beforeEach(function () { - initTestController({ mode: 'create', leaveRequest: leaveRequest }); + describe('and the user creates a new leave request for themselves', function () { + describe('basic tests', function () { + beforeEach(function () { + initTestController({ mode: 'create', leaveRequest: leaveRequest }); + }); + + it('sets is self record as true', function () { + expect(controller.isSelfRecord).toBe(true); + }); }); - it('sets is self record as true', function () { - expect(controller.isSelfRecord).toBe(true); + describe('when user is a self leave approver', function () { + beforeEach(function () { + spyOn(ContactInstance, 'checkIfSelfLeaveApprover').and.returnValue($q.resolve(true)); + }); + + ['staff', 'manager', 'admin'].forEach(function (permissionsRole) { + beforeEach(function () { + role = permissionsRole; + + initTestController({ mode: 'create', leaveRequest: leaveRequest }); + }); + + it('sets the `isSelfLeaveApprover` public property to `true`', function () { + expect(controller.isSelfLeaveApprover).toBe(true); + }); + + it('sets the `canManage` public property to `true`', function () { + expect(controller.canManage).toBe(true); + }); + + describe('when the user submits a leave request with the "Approved" status', function () { + var approvalStatus; + beforeEach(function () { + approvalStatus = optionGroupMock.specificValue('hrleaveandabsences_leave_request_status', 'value', '1'); + + LeaveRequestAPI.isValid.and.returnValue($q.resolve()); + LeaveRequestAPI.create.and.returnValue($q.resolve({ id: '1' })); + controller.request.status_id = approvalStatus; + + controller.submit(); + $scope.$digest(); + }); + + it('keeps the status unamended', function () { + expect(controller.request.status_id).toEqual(approvalStatus); + }); + + it('calls corresponding API end points', function () { + expect(LeaveRequestAPI.create).toHaveBeenCalled(); + }); + }); + }); }); }); }); diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/leave-request-popup/leave-request-popup-body.html b/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/leave-request-popup/leave-request-popup-body.html index 2bb9fd4ea23..4f569de51a2 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/leave-request-popup/leave-request-popup-body.html +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/leave-request-popup/leave-request-popup-body.html @@ -75,7 +75,7 @@
diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/leave-request-popup/leave-request-popup-footer.html b/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/leave-request-popup/leave-request-popup-footer.html index b2c190820da..04f20d13e7d 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/leave-request-popup/leave-request-popup-footer.html +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/leave-request-popup/leave-request-popup-footer.html @@ -8,7 +8,7 @@ Delete