"use strict"; /** * Created by igor.samulenko on 7/24/2014. */ (function () { 'use strict'; angular.module('myitsmApp') .directive('editAffectedAssets', ['events', function (events) { return { restrict: 'E', templateUrl: 'views/common/edit-affected-assets.html', replace: true, scope: { ticket: '=', metaData: '=', isDraft: '=', updateIsHandledByParent: '=' }, controller: ['$scope', '$state', 'assetService', 'ticketModel', 'categoriesService', '$timeout', function ($scope, $state, assetService, ticketModel, categoriesService, $timeout) { $scope.type = $scope.ticket.type; var ticket = $scope.ticket; var metaData = $scope.metaData; var editedData = {}; if ($scope.type !== EntityVO.TYPE_WORKORDER && $scope.type !== EntityVO.TYPE_CHANGE && $scope.type !== EntityVO.TYPE_RELEASE && ticket.causalCI) { if (ticket.causalCI) { editedData.selectedAsset = ticket.causalCI && ticket.causalCI.name ? ticket.causalCI : ''; } } if ($scope.type !== EntityVO.TYPE_CHANGE || $scope.type !== EntityVO.TYPE_RELEASE && ticket.impactedService) { if (ticket.impactedService) { editedData.selectedService = ticket.impactedService.name; } } if (editedData.selectedAsset) { editedData.oldAssetValue = editedData.selectedAsset; if (editedData.oldAssetValue !== null) { editedData.isAssetRetained = true; } } var state = { pendingAffectedServiceChange: false, pendingAffectedAssetChange: false }; $scope.state = state; $scope.onAffectedServiceChange = function () { state.pendingAffectedServiceChange = true; $scope.state.isServiceTooltipOpen = false; }; $scope.$watch('editedData.selectedService', function () { if (editedData && _.isObject(editedData.selectedService)) { $scope.onAffectedServiceChange(); $scope.$emit(events.AFFECTED_SERVICE_UPDATED, editedData.selectedService); } }, true); $scope.onAffectedAssetChange = function () { state.pendingAffectedAssetChange = true; $scope.state.isAssetTooltipOpen = false; }; $scope.$watch('editedData.selectedAsset', function () { if (editedData && _.isObject(editedData.selectedAsset)) { if (!editedData.selectedAsset.name) { editedData.selectedAsset = ''; return; } $scope.onAffectedAssetChange(); $scope.$emit(events.AFFECTED_ASSET_UPDATED, editedData.selectedAsset); } }); /** * Handle successful affected assets update * * @param response */ function handleSuccessAffectedAssetsUpdate(response) { if (_.isEmpty(response)) { return; } ticket.impactedService = response.impactedService && response.impactedService.name ? response.impactedService : {}; ticket.causalCI = response.causalCI && response.causalCI.name ? response.causalCI : {}; //On categories edit update ticket.categorizations = angular.copy(response.categorizations); var allEntityCategories = ticket.categorizations; if (!!ticket.resCategorizations && ticket.isClosed()) { allEntityCategories = ticket.categorizations.concat(response.resCategorizations); } else if (ticket.type === EntityVO.TYPE_INCIDENT) { ticket.categorizations.push(_.find(response.resCategorizations, { 'name': 'resolutionProduct' })); ticket.categorizations.push(_.find(response.resCategorizations, { 'name': 'resolution' })); allEntityCategories = ticket.categorizations; } ticket.allCategories = categoriesService.populateCategories(allEntityCategories, metaData); ticket.noCategories = (_.filter(ticket.allCategories, 'valueToShow')).length; } /** * Handle successful affected service update * * @param response */ function handleSuccessAffectedServiceUpdate(response) { if (_.isEmpty(response)) { return; } if (state.pendingAffectedServiceChange) { $scope.$emit(events.AFFECTED_SERVICE_UPDATE_SAVED); } } $scope.editedData = editedData; /** * Collect changes * @returns {Object} */ function collectChanges() { var changes = {}; var selectedService = editedData.selectedService; if (state.pendingAffectedServiceChange) { if (angular.isObject(selectedService)) { changes.impactedService = selectedService.name; changes.impactedServiceReconId = selectedService.reconciliationId; } else { changes.impactedService = ''; changes.impactedServiceReconId = ''; } } if ($scope.type !== EntityVO.TYPE_WORKORDER && state.pendingAffectedAssetChange) { var selectedAsset = editedData.selectedAsset; if (angular.isObject(selectedAsset)) { changes.causalCI = selectedAsset.name; changes.causalCIreconId = selectedAsset.reconciliationId; if (!editedData.isAssetRetained && editedData.oldAssetValue) { changes.previousCausalCI = editedData.oldAssetValue.name; changes.previousCausalCIreconId = editedData.oldAssetValue.reconciliationId; } editedData.oldAssetValue = selectedAsset; } else { changes.causalCI = ''; changes.causalCIreconId = ''; editedData.oldAssetValue = null; } editedData.isAssetRetained = true; } return changes; } /** * Update affected service and asset * @param changes * @returns {*} */ function updateAffectedAssets(changes) { return ticketModel.update(ticket.id, ticket.type, changes); } function applyChanges() { ticket = $scope.ticket; //ticket value gets updated in case of status change. if (angular.isObject(editedData.selectedService)) { ticket.impactedService = editedData.selectedService; } else if (editedData.selectedService === '') { ticket.impactedService = {}; } if (angular.isObject(editedData.selectedAsset)) { ticket.causalCI = editedData.selectedAsset; } else if (editedData.selectedAsset === '') { ticket.causalCI = {}; } } /** * Save changes * @returns {*} */ $scope.save = function () { var changes = collectChanges(); var isDraft = $scope.isDraft; var singleMode = !$scope.updateIsHandledByParent; $scope.$emit(events.SAVE_CHANGES_REQUEST, changes, singleMode || isDraft); if (_.size(changes)) { if (isDraft) { applyChanges(); closeEditor(); } else { if (singleMode) { updateAffectedAssets(changes) .then(function (response) { handleSuccessAffectedAssetsUpdate(response); closeEditor(); }); } } } else { closeEditor(); } }; /** * Cancel pending changes */ $scope.cancel = function () { if ($scope.type !== EntityVO.TYPE_WORKORDER && $scope.type !== EntityVO.TYPE_CHANGE && $scope.type !== EntityVO.TYPE_RELEASE && ticket.causalCI) { editedData.selectedAsset = (!_.isEmpty(ticket.causalCI) && ticket.causalCI) || ""; } if ($scope.type !== EntityVO.TYPE_CHANGE && ticket.impactedService) { editedData.selectedService = ticket.impactedService.name || ""; } clearPendingChangeFlags(); }; $scope.getListOfAffectedAssets = function (term) { var company = (([EntityVO.TYPE_CHANGE, EntityVO.TYPE_RELEASE, EntityVO.TYPE_PROBLEM, EntityVO.TYPE_KNOWNERROR].indexOf(ticket.type) >= 0) ? ticket.company.name : ticket.customer.company.name); $scope.affectedAssetDataLoading = true; return assetService.getListOfAssetsForCompany(term, company, ticket.type, ticket.customer && ticket.customer.id) .then(function (response) { $scope.state.exceedsAssetChunkSize = response[0].items[0].exceedsChunkSize; $scope.state.isAssetTooltipOpen = $scope.state.exceedsAssetChunkSize; $timeout(function () { $scope.state.isAssetTooltipOpen = false; }, 10000); return response[0].items[0].objects; }) .finally(function () { $scope.affectedAssetDataLoading = false; }); }; $scope.getListOfAffectedServices = function (term) { var company = ([EntityVO.TYPE_CHANGE, EntityVO.TYPE_RELEASE, $scope.getListOfAffec, EntityVO.TYPE_PROBLEM, EntityVO.TYPE_KNOWNERROR].indexOf(ticket.type) >= 0 ? ticket.company.name : ticket.customer.company.name); $scope.affectedServiceDataLoading = true; return assetService.getListOfAssetsByTypeForCompany(term, 'Business Service', company, ticket.type, ticket.customer && ticket.customer.id) .then(function (response) { $scope.state.exceedsServiceChunkSize = response[0].items[0].exceedsChunkSize; $scope.state.isServiceTooltipOpen = $scope.state.exceedsServiceChunkSize; $timeout(function () { $scope.state.isServiceTooltipOpen = false; }, 10000); return response[0].items[0].objects; }) .finally(function () { $scope.affectedServiceDataLoading = false; }); }; $scope.clearSelectedService = function () { editedData.selectedService = ''; $scope.onAffectedServiceChange(); }; $scope.clearSelectedAsset = function () { editedData.selectedAsset = ''; $scope.onAffectedAssetChange(); }; function clearPendingChangeFlags() { state.pendingAffectedAssetChange = false; state.pendingAffectedServiceChange = false; } /** * Handle toggle to edit mode event */ function handleToggleEditMode() { // prepare edit data editedData.selectedService = ticket.impactedService && ticket.impactedService.name || ''; editedData.selectedAsset = (!_.isEmpty(ticket.causalCI) && ticket.causalCI) || ''; clearPendingChangeFlags(); } /** * Handle save changes event */ function handleSaveChanges() { $scope.save(); } function closeEditor() { if (!$scope.updateIsHandledByParent || $scope.isDraft) { $scope.$emit(events.SAVE_CHANGES_COMPLETE); } clearPendingChangeFlags(); } /** * Handle save all changes event * @param event * @param eventData */ function handleSaveAllChangesComplete(event, eventData) { handleSuccessAffectedAssetsUpdate(eventData); handleSuccessAffectedServiceUpdate(eventData); clearPendingChangeFlags(); } /** * Handle discard changes */ function handleDiscardChanges() { $scope.cancel(); } function refreshFields(event, company) { if (ticket.company !== company) { editedData.selectedService = ''; editedData.selectedAsset = ''; state.pendingAffectedAssetChange = true; state.pendingAffectedServiceChange = true; ticket.company = company; } else { handleToggleEditMode(); } } $scope.$on(events.CLEAR_AFFECTED_SERVICE, refreshFields); $scope.$on(events.TOGGLE_EDIT_MODE, handleToggleEditMode); $scope.$on(events.SAVE_CHANGES, handleSaveChanges); $scope.$on(events.SAVE_ALL_CHANGES_COMPLETE, handleSaveAllChangesComplete); $scope.$on(events.DISCARD_CHANGES, handleDiscardChanges); }] }; }]); }());