"use strict"; /** * Created by Abhranil Naha on 7/19/2017. */ (function () { 'use strict'; angular.module('layoutConfigModule') .directive('editableLayoutSection', function () { return { restrict: 'E', replace: true, transclude: true, scope: { editModeAllowed: '=', ticket: '=', metadata: '=', editButtonLabel: '=', isDraft: '=', isFullVersion: '=', hasRelatedCis: '=?', fromCopyChange: '=?' }, templateUrl: 'views/layout-configuration/layout-section/editable-layout-section.html', controller: ['$element', '$transclude', '$scope', '$timeout', 'events', 'ticketModel', 'expressionEventManager', 'objectValueMapperService', 'createTicketModel', '$q', 'i18nService', 'systemAlertService', '$state', 'feedModel', function ($element, $transclude, $scope, $timeout, events, ticketModel, expressionEventManager, objectValueMapperService, createTicketModel, $q, i18nService, systemAlertService, $state, feedModel) { var childScope, transcludedContent; var forms = []; var combinedChanges = {}; var ticketBeforeEdit; var getUpdateRiskPromise = $q.when.bind(null, { status: 200 }); $scope.editMode = false; $scope.isNew = false; $scope.dataSaving = false; $scope.editableContentInvalid = false; $scope.isChildEditProgress = false; $transclude(function (clone, scope) { childScope = scope; childScope.handleExternalEditClick = function () { $scope.onEditButtonClick(); }; // perform manual transclusion var editableContentHolder = $element.find('div.editable-content-section__content'); editableContentHolder.append(clone); // find forms if any exist var formArray = editableContentHolder.find('form'); if (formArray.length) { _.forEach(formArray, function (element) { forms.push(element.name); }); } transcludedContent = clone; }); $scope.$on(events.DISABLE_EDITPARENT, function (event, childEditMode) { $scope.isChildEditProgress = childEditMode; }); objectValueMapperService.changeMode(0, true, $scope.ticket); childScope.$on(events.PROVIDER_SHOW_LOADING, function () { $scope.dataSaving = true; }); childScope.$on(events.PROVIDER_HIDE_LOADING, function () { $scope.dataSaving = false; }); childScope.$on(events.EDIT_STATUS_CLICK, function () { if ($scope.isFullVersion && !$scope.isChildEditProgress) { $scope.onEditButtonClick(); $timeout(function () { var sField = $element.find('.status-bar__section'); if (sField.length) { sField[0].focus(); $('.editable-layout-section__content').scrollTop(sField[0].offsetTop); } }, 100); } }); /** * Handle edit click */ $scope.onEditButtonClick = function () { var elementId = getElementId(); resetState(); childScope.$broadcast(events.TOGGLE_EDIT_MODE, elementId); $scope.$emit(events.TOGGLE_EDIT_MODE, elementId); $scope.editMode = !$scope.editMode; childScope.editMode = !childScope.editMode; childScope.isFullVersion = !childScope.isFullVersion; childScope.editModeAllowed = !childScope.editModeAllowed; ticketBeforeEdit = angular.copy($scope.ticket); $timeout(updateRequiredFieldsLabelVisibility); $timeout(focusFirstInput, 100); objectValueMapperService.changeMode(1); }; if ($state.params && $state.params.editMode) { $scope.onEditButtonClick(); } function focusFirstInput() { $element.find('input[type="text"]').first().focus(); } /** * Handle required fields error click */ $scope.onErrorClick = function () { var requiredElements = $element.find('.ng-invalid-required'); var isErrorOnStatus = $element.find('.status-bar__error'); if (requiredElements.length || isErrorOnStatus.length) { requiredElements[0].focus(); return false; } }; /** * Handle save click */ $scope.onSaveClick = function () { var changes = collectChanges(); if (changes) { updateTicketData(changes); } }; $scope.$on(events.SAVE_TICKET_DRAFT, $scope.onSaveClick); $scope.isSaveValid = function () { var requiredElements = $element.find('.ng-invalid-required'); return requiredElements.length ? false : true; }; /** * Handle cancel click */ $scope.onCancelClick = function () { childScope.$broadcast(events.DISCARD_CHANGES); $scope.$emit(events.EDIT_COMPLETE); childScope.isFullVersion = !childScope.isFullVersion; childScope.editModeAllowed = !childScope.editModeAllowed; closeEditMode(); expressionEventManager.handleTicketLoad(); }; $scope.editableContentIsInvalid = function () { var result = false; if (forms && forms.length) { try { _.forEach(forms, function (formName) { var form = _.get(childScope, formName) || childScope[formName]; result = result || form.$invalid; }); } catch (error) { //ignore it } } $scope.editableContentInvalid = result; return result; }; function collectChanges() { var allFieldsList = objectValueMapperService.getFieldList(); var changesList = { customFields: {} }; var categories = []; var resCategories = []; _.forEach(allFieldsList, function (field, fieldName) { if (field.type === FieldVO.prototype.DESCRIPTION) { if (!isEmptyAndEqual(ticketBeforeEdit[field.name], field.value.desc) && field.value.desc !== ticketBeforeEdit[field.name]) { changesList.desc = field.value.desc; } } else if (field.type === FieldVO.prototype.PERSON_SITE) { var fieldValue = field.value.site; if (!fieldValue) { fieldValue = { name: "", id: null, attributeMap: { siteAddress: null, regionName: field.value.region ? field.value.region.name : null, siteGroupName: field.value.siteGroup ? field.value.siteGroup.name : null, companyName: field.value.company && field.value.company.name || null } }; } var customerSite = ticketBeforeEdit.customer.site; if (customerSite && (customerSite.name !== fieldValue.name || customerSite.siteGroup !== fieldValue.attributeMap.siteGroupName || customerSite.region !== fieldValue.attributeMap.regionName)) { var siteAddress = {}, site = void 0; if (fieldValue.attributeMap.siteAddress) { siteAddress.address = fieldValue.attributeMap.siteAddress.address || ''; siteAddress.city = fieldValue.attributeMap.siteAddress.city || ''; siteAddress.country = fieldValue.attributeMap.siteAddress.country || ''; siteAddress.state = fieldValue.attributeMap.siteAddress.state || ''; siteAddress.street = fieldValue.attributeMap.siteAddress.street || ''; siteAddress.zip = fieldValue.attributeMap.siteAddress.zip || ''; } site = { address: siteAddress, companyName: fieldValue.attributeMap.companyName, name: fieldValue.name, region: fieldValue.attributeMap.regionName || '', siteGroup: fieldValue.attributeMap.siteGroupName || '', siteId: fieldValue.attributeMap.siteId }; var customer = void 0; if (!changesList.customer) { customer = ticketBeforeEdit.customer; customer.site = site; } else { customer = changesList.customer; customer.site = site; } changesList.customer = customer; } else if (customerSite && !fieldValue) { var siteAddress = {}, site = void 0; siteAddress.address = ''; siteAddress.city = ''; siteAddress.country = ''; siteAddress.state = ''; siteAddress.street = ''; siteAddress.zip = ''; site = { address: siteAddress, companyName: '', name: '', region: field.value.region && field.value.region.name ? field.value.region.name : '', siteGroup: field.value.siteGroup && field.value.siteGroup.name ? field.value.siteGroup.name : '', siteId: null }; var customer = void 0; if (!changesList.customer) { customer = { loginId: ticketBeforeEdit.customer.loginId, site: site }; } else { customer = changesList.customer; customer.site = site; } changesList.customer = customer; } } else if (field.type === FieldVO.prototype.PERSON_NAME) { var person = {}; if (field.isAssigneeWidget()) { var fetchGroupName = field.name + "SupportGroups"; var supportGroup = _.find(allFieldsList, { name: fetchGroupName }); if ((field.value && field.value.loginId !== ticketBeforeEdit[field.primaryKey].loginId) || (supportGroup && supportGroup.value && supportGroup.value.supportGroups !== ticketBeforeEdit[supportGroup.primaryKey].name)) { if ($scope.isDraft) { changesList[field.primaryKey] = field.value; } else { var attributesMap = getAssignmentDataForSave(field); _.extend(changesList, attributesMap); } } } else { var checkFieldName = field.name === 'requestedFor' ? 'customer' : field.name; if (!field.value && ticketBeforeEdit[checkFieldName]) { changesList[checkFieldName] = { isDeleted: true }; return; } if (field.value.loginId && field.value.loginId !== ticketBeforeEdit[checkFieldName].loginId) { if (field.isCustomerWidget() || field.isContactWidget()) { person = angular.copy(field.value); } if (changesList[checkFieldName] && changesList[checkFieldName].site) { //This case gets executed if person site is already populated by site fields / widget person.site = changesList[checkFieldName]; } else { //Person site will get loaded later by the site widget or by fields of the broken widget //Person site shouldnt be populated in the person widget person && delete person.site; } changesList[checkFieldName] = person; } if (field.name === 'requestedFor') { if (field.value.loginId && field.value.loginId !== ticketBeforeEdit[checkFieldName].loginId) { var tempCompanyLoc = objectValueMapperService.getExactValueByFieldName('company'); if (tempCompanyLoc) { changesList.locationCompany = { name: tempCompanyLoc }; } else { changesList.locationCompany = { name: field.value && field.value.company.name }; } } } } } else if (field.type === FieldVO.prototype.TICKET_LOCATION) { var widgetMembers = objectValueMapperService.getWidgetMembers(field.name); var fieldValues = {}; var objectMapper = { siteId: 'siteId', siteRegion: 'region', siteName: 'name', siteGroup: 'siteGroup' }; _.each(widgetMembers, function (member) { var ootbMappingKey = $scope.metadata.ootbMapping[member]; ootbMappingKey = _.last(ootbMappingKey); var oldValue = _.get(ticketBeforeEdit, ootbMappingKey); var mapperKey = objectMapper[member]; if (oldValue !== field.value[mapperKey]) { fieldValues[mapperKey] = field.value[mapperKey]; } }); if (!_.isEmpty(fieldValues)) { fieldValues.siteId = field.value.siteId; changesList.location = fieldValues; } } else if (field.type === FieldVO.prototype.POI_LOCATION) { changesList.poiId = field.value ? field.value.poiId : ''; } else if (field.type === FieldVO.prototype.CATEGORY_COMPANY || field.name === 'locationCompany') { var locationCompany = ticketBeforeEdit.locationCompany && ticketBeforeEdit.locationCompany.name; if (!isEmptyAndEqual(locationCompany, field.value) && field.value !== locationCompany) { changesList.locationCompany = field.value ? { name: field.value } : ''; } } else if (field.type === FieldVO.prototype.AFFECTED_ASSET) { if (field.value.ci === null || (ticketBeforeEdit[field.name] && field.value.ci.reconciliationId === ticketBeforeEdit[field.name].reconciliationId)) { return; } else { if (field.name === 'causalCI') { if (field.value.ci.name === undefined || field.value.ci.name === null || field.value.ci.name === '') { changesList.causalCI = ''; } else { if ($scope.isDraft) { changesList.causalCI = field.value.ci; } else { changesList.causalCI = field.value.ci.name; } } if (field.value.ci.reconciliationId === undefined || field.value.ci.reconciliationId === null || field.value.ci.reconciliationId === '') { changesList.causalCIreconId = ''; } else { changesList.causalCIreconId = field.value.ci.reconciliationId; } if (field.value.isCheckedValue && !(field.value.ci.name === undefined || field.value.ci.name === null || field.value.ci.name === '') && (ticketBeforeEdit[field.name] && field.value.ci.reconciliationId !== ticketBeforeEdit[field.name].reconciliationId)) { field.value.isCheckedValue = true; field.value.oldDataValue = field.value.ci; } else if (field.value.oldDataValue) { changesList.previousCausalCI = field.value.oldDataValue.name; changesList.previousCausalCIreconId = field.value.oldDataValue.reconciliationId; } } if (field.name === 'impactedService') { if (field.value.ci.name === undefined || field.value.ci.name === null || field.value.ci.name === '') { changesList.impactedService = ''; } else { if ($scope.isDraft) { changesList.impactedService = field.value.ci; } else { changesList.impactedService = field.value.ci.name; } } if (field.value.ci.reconciliationId === undefined || field.value.ci.reconciliationId === null || field.value.ci.reconciliationId === "") { changesList.impactedServiceReconId = ""; } else { changesList.impactedServiceReconId = field.value.ci.reconciliationId; } if (field.value.isCheckedValue) { field.value.isCheckedValue = true; field.value.oldDataValue = field.value.ci; } else if (field.value.oldDataValue) { changesList.previousImpactedService = field.value.oldDataValue.name; changesList.previousImpactedServiceReconId = field.value.oldDataValue.reconciliationId; } } } } else if (field.type === FieldVO.prototype.CATEGORY_FIELD && field.value) { var tierList = {}, categoryName = field.getCategorizationPropertyName(); _.forEach(field.value.listOfTiers, function (element) { tierList[element.name] = element.selectedValue; }); var category = { name: categoryName, tiers: tierList }; var isDirty = false; var currentCategory; _.forEach(ticketBeforeEdit.allCategories, function (previousCategory) { if (previousCategory.name === categoryName) { currentCategory = previousCategory; } }); _.forEach(currentCategory.listOfTiers, function (tier) { _.forEach(field.value.listOfTiers, function (element) { if (element.name === tier.name) { if (tier.selectedValue !== element.selectedValue) { isDirty = true; } } }); }); if (isDirty) { if (categoryName === 'operational' || categoryName === 'product') { categories.push(category); changesList.categorizations = categories; } else { resCategories.push(category); changesList.resCategorizations = resCategories; } } } else if (field.type === FieldVO.prototype.PRIORITY) { if (field.value.impact.name !== ticketBeforeEdit.impact || field.value.urgency.name !== ticketBeforeEdit.urgency || field.value.priority.name !== ticketBeforeEdit.priority) { var priorityFields = { impact: field.value.impact.name, urgency: field.value.urgency.name, priority: field.value.priority.name }; angular.extend(changesList, priorityFields); } } else if (field.isSupportGroupWidget()) { if (!ticketBeforeEdit[field.primaryKey] && field.value || ((field.value && ticketBeforeEdit[field.primaryKey]) && (field.value.assignedToGroup || field.value.id !== ticketBeforeEdit[field.primaryKey].id))) { if ($scope.isDraft) { changesList[field.primaryKey] = field.value; } else { var supportGroupAttributesMap = {}, supportField; if (field.primaryKey === 'supportGroup') { supportGroupAttributesMap = { group: field.value.name, groupId: field.value.id }; //assignee doesn't change however support group changed to different company group if (!changesList.company && field.value && field.value.company && field.value.company.name) { supportGroupAttributesMap.company = field.value.company.name; } if (!changesList.organization && field.value && field.value.organization) { supportGroupAttributesMap.organization = field.value.organization; } if (field.value && field.value.cognitiveFlag) { supportGroupAttributesMap.cognitiveFlag = field.value.cognitiveFlag; } } else if (field.primaryKey === 'managerGroup') { supportGroupAttributesMap = { managerGroup: field.value.name, managerGroupId: field.value.id }; //manager doesn't change however manager group changed to different company group if (!changesList.managerCompany && field.value && field.value.company && field.value.company.name) { supportGroupAttributesMap.managerCompany = field.value.company.name; } if (!changesList.managerOrganization && field.value && field.value.organization) { supportGroupAttributesMap.managerOrganization = field.value.organization; } } else if (field.primaryKey === 'coordinatorGroup') { supportGroupAttributesMap = { coordinatorGroup: field.value.name, coordinatorGroupId: field.value.id }; //coordinator doesn't change however coordinator group changed to different company group if (!changesList.coordinatorCompany && field.value && field.value.company && field.value.company.name) { supportGroupAttributesMap.coordinatorCompany = field.value.company.name; } if (!changesList.coordinatorOrganization && field.value && field.value.organization) { supportGroupAttributesMap.coordinatorOrganization = field.value.organization; } } _.extend(changesList, supportGroupAttributesMap); if (field.name === 'assigneeSupportGroups') { supportField = allFieldsList.assignee; } else if (field.name === 'changeCoordinatorSupportGroups') { supportField = allFieldsList.assigneeName; } else if (field.name === 'changeManagerSupportGroups' || field.name === 'requestManagerSupportGroups') { supportField = allFieldsList.managerName; } if (supportField && supportField.value !== '' && supportField.dataType !== 'widget') { _.extend(changesList, getAssignmentDataForSave(supportField)); } } } } else if (field.type === FieldVO.prototype.TICKET_RISK) { if (field.name === FieldVO.prototype.WIDET_NAMES.changeRisk) { var name = _.last(field.members).name; //Also checked for condition if user has changed the radio but didn't change the value if (field.value.mode === 'manual' && (field.value[name] !== ticketBeforeEdit[name] || field.riskIsUserSpecified !== ticketBeforeEdit.riskIsUserSpecified)) { changesList[name] = field.value[name]; } if (field.modeCheck === true && field.value.mode === 'auto') { var ticket = { questionResponses: field.value.questionResponses, company: $scope.ticket.company, id: $scope.ticket.id }; if ($scope.fromCopyChange) { changesList["questionResponses"] = ticket.questionResponses; } else { getUpdateRiskPromise = createTicketModel.saveRiskResponse.bind(createTicketModel, ticket, true); } } } } else if (fieldName === 'status' || fieldName === 'statusReason' || fieldName === 'taskStatus' || fieldName === 'taskStatusReason') { if (field.value === null || typeof field.value !== 'object' || !_.isEmpty(field.value)) { var ootbMappingKey = $scope.metadata.ootbMapping[field.name]; ootbMappingKey = _.last(ootbMappingKey); var oldValue = _.get(ticketBeforeEdit, ootbMappingKey); if (!isEmptyAndEqual(oldValue, field.value) && oldValue !== field.value) { if ($scope.isDraft) { _.set(changesList, ootbMappingKey, field.value); } else { if ($scope.ticket.type === EntityVO.TYPE_CHANGE && fieldName === 'status') { var changeCoordinator = objectValueMapperService.getValueByFieldName('changeCoordinator'), changeManager = objectValueMapperService.getValueByFieldName('changeManager'), assigneeName = objectValueMapperService.getValueByFieldName('assigneeName'), managerName = objectValueMapperService.getValueByFieldName('managerName'), params; if (field.value !== 'Draft') { if ((!_.isEmpty(changeCoordinator) && changeCoordinator.loginId) || assigneeName || ($scope.ticket.timing === "Latent" && $scope.ticket.enableAssginmentEngineIntegration)) { changesList[fieldName] = field.value; } else { params = [i18nService.getLocalizedString('change.detail.changeCoordinator')]; systemAlertService.error({ text: i18nService.getLocalizedStringwithParams('ticket.notification.draft.missingField', params), clear: false }); changesList = null; return false; } if (field.value !== 'Request For Authorization' && field.value !== 'Request For Change' && field.value !== 'Planning In Progress' && field.value !== 'Rejected' && field.value !== "Pending" && field.value !== "Cancelled") { if ((!_.isEmpty(changeManager) && changeManager.loginId) || managerName || ($scope.ticket.timing === "Latent" && $scope.ticket.enableAssginmentEngineIntegration)) { changesList[fieldName] = field.value; } else { params = [i18nService.getLocalizedString('change.detail.changeManager')]; systemAlertService.error({ text: i18nService.getLocalizedStringwithParams('ticket.notification.draft.missingField', params), clear: false }); changesList = null; return false; } } } else { //Case: user could be switching back from forward state - back to draft changesList[fieldName] = field.value; } } else if (fieldName === 'taskStatus') { changesList['status'] = field.value; } else if (fieldName === 'taskStatusReason') { changesList['statusReason'] = field.value; } else { changesList[fieldName] = field.value || ''; } } } else if (oldValue === field.value) { if ($scope.isDraft) { _.set(changesList, ootbMappingKey, field.value); } else if ((fieldName === 'status' || fieldName === 'taskStatus') && combinedChanges['status']) { delete combinedChanges['status']; } else if ((fieldName === 'statusReason' || fieldName === 'taskStatusReason') && combinedChanges['statusReason']) { delete combinedChanges['statusReason']; } else if ((fieldName === 'statusReason') && changesList['status']) { //If status is changed but status reason is same changesList['statusReason'] = field.value; } } } } else { if (field.dataType === FieldVO.prototype.DATA_TYPE_WIDGET) { if (fieldName === FieldVO.prototype.IMPACTED_AREAS) { for (var ootbKeyVal in field.value) { if (field.value.hasOwnProperty(ootbKeyVal)) { changesList[ootbKeyVal] = field.value[ootbKeyVal]; } } } else { for (var ootbKey in field.value) { if (field.value.hasOwnProperty(ootbKey)) { var oldVal; var dirtyFlag = false; var isDateInstance = false; if ($scope.metadata.ootbMapping[ootbKey]) { var ootbMapKey = _.last($scope.metadata.ootbMapping[ootbKey]); oldVal = _.get(ticketBeforeEdit, ootbMapKey); if ((field.value[ootbKey] instanceof Date) || (oldVal instanceof Date)) { isDateInstance = true; if ((Date.parse(oldVal) !== Date.parse(field.value[ootbKey]))) { dirtyFlag = true; } } else if (oldVal !== field.value[ootbKey]) { dirtyFlag = true; } if (dirtyFlag) { var primaryKey = _.head(ootbMapKey.split('.')); if (!changesList[primaryKey]) { changesList[primaryKey] = _.cloneDeep(ticketBeforeEdit[primaryKey]); //Below condition applicable only for customer widget. //Dont see any other use case. But have made it generic. if (allFieldsList.site && allFieldsList.site.dataType === 'widget' && ticketBeforeEdit[primaryKey] && ticketBeforeEdit[primaryKey].site) { changesList[primaryKey].site = setPersonSite(changesList[primaryKey].site); } } if (isDateInstance) { if (field.value[ootbKey] === null) { _.set(changesList, ootbMapKey, null); } else { _.set(changesList, ootbMapKey, field.value[ootbKey].valueOf()); } } else { if (oldVal !== field.value[ootbKey]) { _.set(changesList, ootbMapKey, (field.value[ootbKey] ? field.value[ootbKey] : '')); } } } } else { oldVal = ticketBeforeEdit[ootbKey]; if (oldVal !== field.value[ootbKey]) { changesList[fieldName] = field.value[ootbKey]; } } } } } } else if (field.name === 'assignee' || field.name === 'assigneeName' || field.name === 'managerName') { if (field.value && ((field.name === 'assignee' || field.name === 'assigneeName') && field.assigneeLoginId !== ticketBeforeEdit.assignee.loginId) || (field.name === 'managerName' && field.assigneeLoginId !== ticketBeforeEdit.manager.loginId)) { if ($scope.isDraft) { if (field.name === 'assignee' || field.name === 'assigneeName') { changesList.assignee = { fullName: field.value, loginId: field.assigneeLoginId }; } else if (field.name === 'managerName') { changesList.manager = { loginId: field.assigneeLoginId, fullName: field.value }; } } else { _.extend(changesList, getAssignmentDataForSave(field)); } } } else { //Using _.isEmpty for field.value directly gives false positives for values true/false, 0/1 if (field.value === null || typeof field.value !== 'object' || !_.isEmpty(field.value) || (field.hasDataTypeValueFormat() && field.ootb)) { if (field.ootb) { //SW00540515 - for the case of edit incident, we need to pass 'resNote' instead of 'resolution' var keyOOTBMapping = field.name === 'resolution' ? ['resNote'] : $scope.metadata.ootbMapping[field.name]; var valueOld = getFieldValue(field.name, keyOOTBMapping, ticketBeforeEdit); if (!isEmptyAndEqual(valueOld, field.value) && valueOld !== field.value) { setFieldValue(changesList, field, ticketBeforeEdit, keyOOTBMapping, categories, resCategories); } if (field.name === 'resolution' && isEmptyAndEqual(valueOld, field.value) && valueOld !== field.value) { setFieldValue(changesList, field, ticketBeforeEdit, keyOOTBMapping, categories, resCategories); } } else { if ((!!$scope.ticket.isDraft || (ticketBeforeEdit.customFields[fieldName] !== field.value)) && ((ticketBeforeEdit.customFields[fieldName]) || (field.value)) || ((field.dataType === 'integer' || field.dataType === 'decimal' || field.dataType === 'real') && field.value === 0) || (field.isCheckboxField() && field.value === 0)) { //no literal check for null == undefined scenario if (!!$scope.ticket.isDraft || !field.isCheckboxField()) { changesList.customFields[fieldName] = field.value; } else if (!$scope.ticket.isDraft && field.isCheckboxField() && ticketBeforeEdit.customFields[fieldName] !== field.value && !(ticketBeforeEdit.customFields[fieldName] === undefined && field.value === -1)) { changesList.customFields[fieldName] = field.value; } } } } else if (field.value !== null && typeof field.value === 'object') { if (!field.ootb && (field.dataType === FieldVO.prototype.DATA_TYPE_DATE || field.dataType === FieldVO.prototype.DATA_TYPE_DATE_TIME || field.dataType === FieldVO.prototype.DATA_TYPE_TIME)) { if (ticketBeforeEdit.customFields[fieldName] !== field.getValue()) { changesList.customFields[fieldName] = field.getValue(); } } } } } //required for populate different value field //populate only if populate wit different field is not in view. //Otherwise it will sent to server as a normal allFieldList iteration. if (field.linkedFieldExist() && !allFieldsList[field.valueField]) { var ootbMapKey_1 = $scope.metadata.ootbMapping[field.valueField]; if (ootbMapKey_1 && ootbMapKey_1.length) { _.set(changesList, _.last(ootbMapKey_1), field.getLinkedValue()); } else { changesList.customFields[field.valueField] = field.getLinkedValue(); } } }); _.forEach(changesList, function (field, key) { if (field && field.isDeleted) { changesList[key] = {}; } }); function setPersonSite(givenSite) { givenSite.companyName = givenSite.companyName || angular.noop; givenSite.name = givenSite.name || ''; givenSite.regionName = givenSite.regionName || ''; givenSite.siteGroupName = givenSite.siteGroupName || ''; givenSite.siteId = givenSite.siteId || null; if (givenSite.address) { givenSite.address.address = givenSite.address.address || ''; givenSite.address.city = givenSite.address.city || ''; givenSite.address.country = givenSite.address.country || ''; givenSite.address.state = givenSite.address.state || ''; givenSite.address.street = givenSite.address.street || ''; givenSite.address.zip = givenSite.address.zip || ''; } else { givenSite.address = { address: '', city: '', country: '', state: '', street: '', zip: '' }; } return givenSite; } return changesList; } function isEmptyAndEqual(oldValue, newValue) { if ((oldValue === null || oldValue === undefined || oldValue === "") && (newValue === null || newValue === undefined || newValue === "")) { return true; } } function getFieldValue(name, ootbMappingKey, ticket) { //Ticket attachment object contains ArrayBuffer propery which is not supported by _.cloneDeep() var ticketCopy = angular.copy(ticket); if (name.indexOf('CategoryTier') !== -1 || name === 'resProductName') { if (!ticketCopy.categorizations.tiers) { ticketCopy.categorizations.tiers = {}; ticketCopy.categorizations.forEach(function (categorization) { _.extend(ticketCopy.categorizations.tiers, categorization.tiers); }); } if (ticketCopy.resCategorizations && !ticketCopy.resCategorizations.tiers) { ticketCopy.resCategorizations.tiers = {}; ticketCopy.resCategorizations.forEach(function (resCategorization) { _.extend(ticketCopy.resCategorizations.tiers, resCategorization.tiers); }); } } return _.get(ticketCopy, _.last(ootbMappingKey)); } function setFieldValue(changesList, field, ticket, ootbMappingKey, categories, resCategories) { //Ticket attachment object contains ArrayBuffer propery which is not supported by _.cloneDeep() var ticketCopy = angular.copy(ticket), category, newCategory; if (ootbMappingKey && (_.last(ootbMappingKey).indexOf('categorizations') !== -1 || _.last(ootbMappingKey).indexOf('resCategorizations') !== -1)) { category = _.find(ticketCopy.allCategories, function (categoryTiers) { return _.findIndex(categoryTiers.listOfTiers, function (tier) { return tier.name === field.name && tier.selectedValue !== field.value; }) > -1; }); if (category) { newCategory = _.find((category.name === 'operational' || category.name === 'product') ? categories : resCategories, { name: category.name }); if (!newCategory) { newCategory = { name: category.name, tiers: {} }; if (category.name === 'operational' || category.name === 'product') { categories.push(newCategory); } else { resCategories.push(newCategory); } } newCategory.tiers[field.name] = field.value; if (category.name === 'operational' || category.name === 'product') { changesList.categorizations = categories; } else { changesList.resCategorizations = resCategories; } } } else { if (field.value === null && !field.hasDataTypeValueFormat()) { field.value = ""; } if (field.hasDataTypeValueFormat()) { field.value = field.value && field.value.valueOf(); } _.set(changesList, _.last(ootbMappingKey), field.value); } } /** * Generates data object for saving assignment, for different types of assignment widgets. * It is using 'primaryKey' property, which is populated on field value initialization * * @param {FieldVO} field * @return {Object} * */ function getAssignmentDataForSave(field) { var attributesMap = {}; if (field.primaryKey === 'assignee' || ((field.name === 'assignee' || field.name === 'assigneeName') && field.assigneeLoginId)) { if (field.value.autoAssign) { attributesMap = field.value; } else { if (field.value.loginId) { attributesMap = { loginId: field.value.loginId, fullName: field.value.fullName, group: field.value.supportGroup ? field.value.supportGroup : '', groupId: field.value.supportGroupId ? field.value.supportGroupId : field.value.groupId, company: field.value.company && field.value.company.name ? field.value.company.name : '', organization: field.value.organization ? field.value.organization : '', autoAssign: false }; } else if (field.assigneeLoginId) { attributesMap = { loginId: field.assigneeLoginId, fullName: field.value }; } } } else if (field.primaryKey === 'manager' || (field.name === 'managerName' && field.assigneeLoginId)) { if (field.value.managerAutoAssign) { attributesMap = field.value; } else { if (field.value.loginId) { attributesMap = { managerLoginId: field.value.loginId, managerFullName: field.value.fullName, managerGroup: field.value.supportGroup ? field.value.supportGroup : '', managerCompany: field.value.company.name ? field.value.company.name : '', managerOrganization: field.value.organization ? field.value.organization : '', managerGroupId: field.value.supportGroupId || field.value.groupId ? field.value.supportGroupId || field.value.groupId : '', managerAutoAssign: false }; } else if (field.assigneeLoginId) { attributesMap = { managerLoginId: field.assigneeLoginId, managerFullName: field.value }; } } } else if (field.primaryKey === 'coordinator') { if (field.value.coordinatorAutoAssign) { attributesMap = { coordinatorLoginId: field.value.loginId, coordinatorFullName: field.value.fullName, coordinatorGroup: field.value.supportGroup ? field.value.supportGroup : '', coordinatorCompany: field.value.company.name ? field.value.company.name : '', coordinatorOrganization: field.value.organization ? field.value.organization : '', coordinatorGroupId: field.value.supportGroupId ? field.value.supportGroupId : '', coordinatorAutoAssign: false }; } } return attributesMap; } function updateTicketData(eventData) { startSaving(); if (eventData && _.size(eventData)) { angular.extend(combinedChanges, eventData); } if (_.size(combinedChanges)) { console.log('combined changes object:'); console.log(combinedChanges); var saveImpactedAreaspromise, deleteImpactedAreaspromise; if (eventData.addedImpactedAreas && eventData.addedImpactedAreas.length) { saveImpactedAreaspromise = ticketModel.saveImpactedAreas($scope.ticket.id, $scope.ticket.type, eventData.addedImpactedAreas).then(function () { var impactedAreas = objectValueMapperService.getFieldByName(FieldVO.prototype.IMPACTED_AREAS); impactedAreas.value.addedImpactedAreas.length = 0; }); } if (eventData.removedImpactedAreas && eventData.removedImpactedAreas.length) { deleteImpactedAreaspromise = ticketModel.deleteImpactedAreas($scope.ticket.id, $scope.ticket.type, eventData.removedImpactedAreas).then(function () { var impactedAreas = objectValueMapperService.getFieldByName(FieldVO.prototype.IMPACTED_AREAS); impactedAreas.value.removedImpactedAreas.length = 0; }); } // perform update if ($scope.isDraft) { if ((combinedChanges.categorizations && combinedChanges.categorizations.length) || (combinedChanges.resCategorizations && combinedChanges.resCategorizations.length)) { _.each($scope.ticket.allCategories, function (category) { var categoryFromCombined = _.find((category.name === 'operational' || category.name === 'product') ? combinedChanges.categorizations : combinedChanges.resCategorizations, { name: category.name }); if (categoryFromCombined) { _.each(category.listOfTiers, function (tier) { if (categoryFromCombined.tiers && categoryFromCombined.tiers[tier.name] !== tier.selectedValue) { if (_.has(categoryFromCombined.tiers, tier.name)) { tier.selectedValue = categoryFromCombined.tiers[tier.name]; } else { if (tier.selectedValue) { categoryFromCombined.tiers[tier.name] = tier.selectedValue; } } } }); } else { var newCategotization = { name: category.name, tiers: {} }; _.each(category.listOfTiers, function (tier) { if (tier.selectedValue) { newCategotization.tiers[tier.name] = tier.selectedValue; } }); if (!_.isEmpty(newCategotization.tiers)) { if (category.name === 'operational' || category.name === 'product') { if (!combinedChanges.categorizations) { combinedChanges.categorizations = []; } combinedChanges.categorizations.push(newCategotization); } else { if (!combinedChanges.resCategorizations) { combinedChanges.resCategorizations = []; } combinedChanges.resCategorizations.push(newCategotization); } } } }); } if (combinedChanges.resNote !== undefined) { combinedChanges.resolution = combinedChanges.resNote; } angular.extend($scope.ticket, combinedChanges); handleSaveAllChangesSuccess({ ticket: $scope.ticket }); } else { var updateTicketPromise = ticketModel.update($scope.ticket.id, $scope.ticket.type, combinedChanges, true); $q.all({ ticket: updateTicketPromise, saveImpactedAreas: saveImpactedAreaspromise, deleteImpactedAreas: deleteImpactedAreaspromise }).then(updateRiskAndSave, handleSaveAllChangesFault); } } else { console.log('nothing changed or child sections saved themselves, closing edit mode'); handleSaveAllChangesSuccess({}); } } //To address both the defects SW00566555 and SW00558530, we need to make update call first and then risk response call. function updateRiskAndSave(response) { if (response.ticket.status !== 500) { getUpdateRiskPromise().then(function (riskResponse) { if (riskResponse && riskResponse.additionalInformation) { angular.extend(response.ticket, { questionResponses: riskResponse.additionalInformation.questionResponses, riskLevel: riskResponse.additionalInformation.riskLevel, riskIsUserSpecified: riskResponse.additionalInformation.riskIsUserSpecified }); } if (riskResponse.status !== 500) { handleSaveAllChangesSuccess(response); } else { handleSaveAllChangesFault(response); } }); } else { handleSaveAllChangesFault(response); } } /** * Handle successful update * * @param {Object} response */ function handleSaveAllChangesSuccess(response) { var updatedTicket = response.ticket; var riskUpdate = response.risks; if (updatedTicket.status !== 500) { if ($scope.isDraft) { childScope.$broadcast(events.AFTER_SAVED_CHANGES, updatedTicket); } else { if (updatedTicket.attachments && updatedTicket.attachments.length) { var attachments = ticketModel.getAttachmentsInfo(updatedTicket.id, updatedTicket.type); attachments.then(function (res) { updatedTicket.attachments = res; childScope.$broadcast(events.AFTER_SAVED_CHANGES, updatedTicket); }); } else { childScope.$broadcast(events.AFTER_SAVED_CHANGES, updatedTicket); } } if (updatedTicket) { $scope.$emit(events.AFTER_SAVED_CHANGES, updatedTicket); } if (_.isObject(riskUpdate)) { childScope.$broadcast(events.AFTER_RISK_UPDATE); } finishSaving(); } else { handleSaveAllChangesFault(response); } } function handleSaveAllChangesFault(response) { combinedChanges = {}; var foundError = response.ticket || response.saveImpactedAreas || response.deleteImpactedAreas; if (foundError && foundError.data) { systemAlertService.error({ text: foundError.data.error || error, clear: false, displayOnStateChange: true }); } $scope.dataSaving = false; } function startSaving() { $scope.dataSaving = true; } function finishSaving() { $scope.dataSaving = false; resetState(); $scope.$parent.$parent.$parent.dirty = false; closeEditMode(); $scope.$emit(events.EDIT_COMPLETE); childScope.isFullVersion = !childScope.isFullVersion; childScope.editModeAllowed = !childScope.editModeAllowed; } function resetState() { combinedChanges = {}; ticketBeforeEdit = {}; } function updateRequiredFieldsLabelVisibility() { $scope.hasRequiredFields = hasRequiredFields(); } function hasRequiredFields() { return $element.find('div.editable-content-section__content .required').length; } function getElementId() { return $element[0].id; } function closeEditMode() { $scope.editMode = false; childScope.editMode = false; objectValueMapperService.changeMode(0); } childScope.$on(events.RISK_MODE_AUTO, function (event, obj) { childScope.$broadcast(events.RISK_LEVEL_CHANGE, { isRequired: false }); $scope.$emit(events.WORKNOTE_REQUIRED, { isRequired: false }); }); childScope.$on(events.WIDGET_VALUE_CHANGE, function (event, obj) { console.log('Widget value changed :' + obj.fieldName); if (!obj.isCalledFromSetProp) { expressionEventManager.handleOOTBFieldValueChange(obj.fieldName, obj.action, obj.source); } if (obj.source !== 'fromTicketLoad') { if (obj.memberName) { if (_.isArray(obj.memberName)) { _.forEach(obj.memberName, function (member) { expressionEventManager.handleFieldChangeForActions(member); }); } else { expressionEventManager.handleFieldChangeForActions(obj.memberName); } } } if (obj.fieldName === EntityVO.FIELD_CHANGE_RISK) { handleRiskLevelChange({ fieldName: obj.fieldName, fieldValue: obj.fieldValue }); } if (obj.fieldName === EntityVO.TYPE_STATUS) { handleIncidentRules(obj); } }); function handleIncidentRules(obj) { if (obj.fieldValue == "Resolved" && $scope.ticket.CIRequiredOnResolved) { handleServiceCI({ isRequired: true, name: 'causalCI' }); } else { handleServiceCI({ isRequired: false, name: 'causalCI' }); } } function handleServiceCI(data) { childScope.$broadcast(events.SERVICECI_REQUIRED, { isRequired: data.isRequired, name: data.name }); } function handleRiskLevelChange(data) { if ($scope.ticket.riskRulesConfigured) { childScope.$broadcast(events.RISK_LEVEL_CHANGE, { isRequired: changeReasonRequired(data) }); } if ($scope.ticket.riskRulesConfigured) { $scope.$emit(events.WORKNOTE_REQUIRED, { isRequired: checkNoteRequired(data) }); } } function changeReasonRequired(data) { var changeReasonRequired = false; _.forEach($scope.ticket.riskLevelForChangeReason, function (riskLevel) { if (riskLevel === data.fieldValue) { changeReasonRequired = true; } }); return changeReasonRequired; } function checkNoteRequired(data) { var isNoteRequired = false; _.forEach($scope.ticket.riskLevelForNote, function (riskLevel) { if (riskLevel === data.fieldValue) { isNoteRequired = true; } }); return isNoteRequired; } childScope.$on(events.FIELD_VALUE_CHANGE, function (event, field) { console.log('Field value changed :' + field.name); if (!field.isCalledFromSetProp) { expressionEventManager.handleFieldChange(field.name); } if (field.source !== 'fromTicketLoad') { expressionEventManager.handleFieldChangeForActions(field.name); } }); childScope.$on(events.CUSTOM_FIELD_VALUE_CHANGE, function () { childScope.$broadcast(events.REFRESH_FIELD_VALUES); }); $scope.$on(events.CHANGE_TO_EDIT_MODE, function (event, data) { $scope.onEditButtonClick(); }); /* * Handle Ticket load event * Place any code which requires to be done when all fields are loaded */ var noOfFieldAreasAttached = 0, totalFieldArea; childScope.$on(events.FIELD_AREA_ATTACHED, function () { totalFieldArea = totalFieldArea || $element.find('.panel-field-area').length; noOfFieldAreasAttached++; if (totalFieldArea === noOfFieldAreasAttached) { console.log('All custom-area directives are loaded!'); expressionEventManager.handleTicketLoad(); } }); $scope.$on('$destroy', function () { transcludedContent.remove(); childScope.$destroy(); }); if ($scope.isDraft) { $timeout($scope.onEditButtonClick, 0); } }] }; }); })();