"use strict"; (function () { 'use strict'; angular.module('ticketModule') .controller('DraftTicketController', ['$scope', '$rootScope', '$state', '$q', '$log', '$stateParams', 'ticketModel', 'metadataModel', 'smartRecorderModel', 'categoriesService', 'ticketActionService', 'systemAlertService', 'userModel', 'i18nService', '$window', 'feedModel', '$timeout', 'events', 'screenConfigurationModel', 'ticketTemplateModel', 'srdModel', '$filter', '$injector', 'relationModel', 'relationService', 'configurationModel', 'layoutConfigurationModel', 'objectValueMapperService', 'permissionModel', 'createTicketModel', 'localStorageService', 'attachmentService', 'utilityFunctions', function ($scope, $rootScope, $state, $q, $log, $stateParams, ticketModel, metadataModel, smartRecorderModel, categoriesService, ticketActionService, systemAlertService, userModel, i18nService, $window, feedModel, $timeout, events, screenConfigurationModel, ticketTemplateModel, srdModel, $filter, $injector, relationModel, relationService, configurationModel, layoutConfigurationModel, objectValueMapperService, permissionModel, createTicketModel, localStorageService, attachmentService, utilityFunctions) { // TODO: get rid of $scope soup // TODO: simplify this class var statusWorkNote = '', activeErrorNotification, sortedQuestionDefinitions = [], showAffectedServiceRelation = false, screenName, prevState = { name: 'smartRecorder', params: {} }, errorQuickCreate = $stateParams.error; if ($stateParams.isSrcLiveChat === 'true') { $scope.liveChatWindow = window.opener; } var dataExists = !_.isEmpty(ticketModel.cache.draft), isRelatedDraft = !_.isEmpty(ticketModel.cache.relatedDraft), relatedDraftInfo = isRelatedDraft ? angular.copy(ticketModel.cache.relatedDraft) : null; $scope.forms = {}; $scope.isDraft = true; $scope.activityFlag = false; $scope.resourceFlag = true; $scope.formIsValid = true; $scope.loggedInUserId = userModel.userId; $scope.isCategoriesEmpty = false; $scope.relatedDraftInfo = relatedDraftInfo; $scope.formContainsInvalidFields = createTicketModel.formContainsInvalidFields; function generateStartupData() { $scope.state = { dataIsLoading: true }; $scope.relationCounters = { tickets: 0, 'linked-items': 0 }; $scope.basicData = {}; $scope.metadata = {}; $scope.globalMetadata = {}; $scope.isFullVersion = true; $scope.numberOfRelatedTasks = 0; $scope.numberOfLinkedResources = 0; $scope.editHeader = false; $scope.isContactCollapsed = true; if ($state.params.isCopyChange) { $scope.type = EntityVO.TYPE_CHANGE; screenName = screenConfigurationModel.getScreenNameByTicketType($scope.type); } else { if (dataExists) { $scope.type = ticketModel.cache.draft.type; if (ticketModel.cache.draft.relationship) { $scope.relationship = angular.copy(ticketModel.cache.draft.relationship); } smartRecorderModel.smartRecorderData = {}; } else { $scope.type = smartRecorderModel.smartRecorderData.type; } screenName = screenConfigurationModel.getScreenNameByTicketType($scope.type); $scope.template = smartRecorderModel.smartRecorderData.template; var mentionedPersons = _.filter(smartRecorderModel.smartRecorderData.confirmedItems, { relationship: 'mentioned' }); if (mentionedPersons.length) { if ($scope.type !== EntityVO.TYPE_SERVICEREQUEST) { $scope.activityFlag = true; $scope.resourceFlag = false; $timeout(function () { $scope.$broadcast(events.SET_TICKET_DRAFT_MENTIONED); }, 2000); } } } objectValueMapperService.clearMap($scope.type); $scope.hasEditPermission = permissionModel.hasPermissionForTicket($scope.type); } $scope.ticketActions = { assign: function ($event, singleEditMode, role) { var activeRole = role; if ($scope.type == EntityVO.TYPE_CHANGE) { if (role === 'manager') { activeRole = $scope.type + role; } else if (role === 'ticketassignee') { activeRole = $scope.type + 'coordinator'; } } handleAssignment($event, null, singleEditMode, activeRole); }, assignToMe: function ($event, role, singleEditMode) { var ticket = _.cloneDeep($scope.basicData); var assigneeRole = role; var assigneeSupportGroup = ticket.supportGroup; if (role === 'ticketassignee') { if (ticket.type === EntityVO.TYPE_WORKORDER) { assigneeRole = 'workorderassignee'; } else { assigneeRole = ''; } } else if (role === 'workordermanager') { assigneeSupportGroup = ticket.managerGroup; } else if (role === 'problemcoordinator') { assigneeSupportGroup = ticket.coordinatorGroup; } ticketModel.getTicketAssigneePersons(ticket.type, assigneeRole).then(function (persons) { persons = _.uniqBy(persons.results, function (person) { return person.loginId && person.supportGroupId; }); var person = persons.length === 1 ? persons[0] : _.find(persons, { supportGroupId: assigneeSupportGroup.id }); if (person && person.loginId) { updateAssignment(person, assigneeRole || role, singleEditMode); } else { handleAssignment($event, role, singleEditMode); } }); }, editStatus: function ($event) { ticketActionService.showEditStatusDialog($scope.basicData, true, false).result.then(function (statusData) { statusWorkNote = statusData.worknote; var attachments = _.cloneDeep($scope.basicData.attachments); //basicData is passed by reference to multiple directives and basicdata refers cache. Copy is changing reference and directives not able to refresh values of draft ticket. //ticketModel.cache[$scope.basicData.id] = angular.copy($scope.basicData); ticketModel.cache[$scope.basicData.id].attachments = attachments; if (ticketModel.cache[$scope.basicData.id].desc === '' && $scope.basicData.desc !== '') { ticketModel.cache[$scope.basicData.id].desc = $scope.basicData.desc; } ticketModel.refreshStatus($scope.basicData.id, $scope.basicData.type, statusData, $scope.basicData); $event.currentTarget.focus(); }, function () { $event.currentTarget.focus(); }); }, editHeader: function (data) { if (data) { if ($scope.basicData.summary !== data.summary) { $scope.basicData.summary = data.summary; } $scope.basicData.priority = data.priority.name; if ($scope.type === EntityVO.TYPE_INCIDENT) { $scope.basicData.impact = data.impact.name; $scope.basicData.urgency = data.urgency.name; } if ($scope.type === EntityVO.TYPE_PROBLEM || $scope.type === EntityVO.TYPE_KNOWNERROR) { $scope.basicData.impact = data.impact.name; $scope.basicData.urgency = data.urgency.name; $scope.basicData.targetDate = moment(data.targetDate).valueOf(); } } $scope.editHeader = false; }, editCustomerCard: function (data) { if (data) { var customer = _.find(data, { type: 'customer' }), contact = _.find(data, { type: 'contact' }); $scope.basicData.customer = customer ? customer.data : {}; $scope.basicData.contact = contact ? contact.data : {}; } return $q.when(1); } }; $scope.clearCategories = function (selectedServiceType) { $scope.$broadcast(events.CLEAR_ALL_CATEGORIES, selectedServiceType); }; function handleAssignment($event, role, singleEditMode, activeRole) { ticketActionService.showAssignDialog($scope.basicData, true, role, activeRole).result.then(function (result) { completeAssignment(result, singleEditMode, role); $event.currentTarget.focus(); }, function () { $event.currentTarget.focus(); }); } function updateAssignment(person, role, singleEditMode) { var response = {}; if (role === 'workordermanager' || role === 'problemcoordinator') { response.manager = { id: person.id, loginId: person.loginId, fullName: person.fullName, supportGroup: person.supportGroup, groupId: person.supportGroupId, company: person.company, organization: person.organization }; response.managerGroup = { id: person.supportGroupId, name: person.supportGroup, organization: person.organization, company: person.company }; } else { response.assignee = { id: person.id, loginId: person.loginId, fullName: person.fullName, supportGroup: person.supportGroup, groupId: person.supportGroupId, company: person.company, organization: person.organization }; response.group = { id: person.supportGroupId, name: person.supportGroup, organization: person.organization, company: person.company }; } completeAssignment(response, singleEditMode); } function completeAssignment(result, singleEditMode, role) { var ticket = $scope.basicData; if (result.autoAssign) { ticket.assignee = {}; ticket.supportGroup = {}; } else { if (result.assignee) { ticket.assignee = result.assignee; } if (result.group) { ticket.supportGroup = result.group; } } if (result.managerAutoAssign) { ticket.manager = {}; ticket.managerGroup = {}; } else { if (result.manager) { ticket.manager = result.manager; } if (result.managerGroup) { ticket.managerGroup = result.managerGroup; } } if (result.coordinatorAutoAssign) { ticket.coordinator = {}; ticket.coordinatorGroup = {}; } else { if (result.manager) { ticket.coordinator = result.manager; } if (result.managerGroup) { ticket.coordinatorGroup = result.managerGroup; } } if (_.size(result.changes)) { screenConfigurationModel.updateTicketData(ticket, result.changes); if (!singleEditMode) { var targetPanelId = screenConfigurationModel.composePanelId(ticket.type, 'Assignment'); $scope.$broadcast(events.REFRESH_FIELD_VALUES, { panelId: targetPanelId, ticket: ticket }); } } if ([EntityVO.TYPE_INCIDENT, EntityVO.TYPE_WORKORDER, EntityVO.TYPE_CHANGE].indexOf($scope.basicData.type) !== -1) { $scope.$broadcast(events.TICKET_ASSIGNEES_UPDATED, ticket, !singleEditMode, role); } } $scope.enableHeaderEdit = function () { $scope.editHeader = true; }; $scope.disableDuplicateOfEdit = function () { $scope.basicData.accessMappings.detailsEditAllowed = false; $scope.basicData.accessMappings.statusEditAllowed = false; $scope.basicData.accessMappings.relationsEditAllowed = false; }; function fetchResolutionCategories(generalCategories) { var resProductCategoryData, resOperationCategoryData, categorizations = [], resCategoryCheck, resProductCategoryCheck; _.forEach(generalCategories, function (category) { if (category.name === EntityVO.CATEGORY_OPERATIONAL) { resOperationCategoryData = {}; resOperationCategoryData.name = EntityVO.CATEGORY_RESOLUTION; if (category.tiers.operationCategoryTier1) { resOperationCategoryData.tiers = {}; resOperationCategoryData.tiers.resOperationCategoryTier1 = category.tiers.operationCategoryTier1; if (category.tiers.operationCategoryTier2) { resOperationCategoryData.tiers.resOperationCategoryTier2 = category.tiers.operationCategoryTier2; if (category.tiers.operationCategoryTier3) { resOperationCategoryData.tiers.resOperationCategoryTier3 = category.tiers.operationCategoryTier3; } } } } else if (category.name === EntityVO.CATEGORY_PRODUCT) { resProductCategoryData = {}; resProductCategoryData.name = EntityVO.CATEGORY_RESOLUTION_PRODUCT; if (category.tiers.productCategoryTier1) { resProductCategoryData.tiers = {}; resProductCategoryData.tiers.resProductCategoryTier1 = category.tiers.productCategoryTier1; if (category.tiers.productCategoryTier2) { resProductCategoryData.tiers.resProductCategoryTier2 = category.tiers.productCategoryTier2; if (category.tiers.productCategoryTier3) { resProductCategoryData.tiers.resProductCategoryTier3 = category.tiers.productCategoryTier3; if (category.tiers.productName) { resProductCategoryData.tiers.resProductName = category.tiers.productName; } if (category.tiers.productModelVersion) { resProductCategoryData.tiers.resProductModelVersion = category.tiers.productModelVersion; } } } } } }); var params = { entityType: $scope.basicData.type, criteria: { depends: { id: $scope.basicData.id }, company: $scope.basicData.company, serviceType: $scope.basicData.serviceType } }; if (resOperationCategoryData && resOperationCategoryData.tiers && resOperationCategoryData.tiers.resOperationCategoryTier1) { var resOperationParams = _.cloneDeep(params), operationCategoryTiers; resOperationParams.categoryType = EntityVO.CATEGORY_RESOLUTION; _.merge(resOperationParams.criteria.depends, resOperationCategoryData.tiers); _.forEach($scope.basicData.allCategories, function (category) { if (category.name === EntityVO.CATEGORY_OPERATIONAL) { operationCategoryTiers = categoriesService.collectTiersValues(category.listOfTiers); } }); if (operationCategoryTiers && operationCategoryTiers.operationCategoryTier1) { _.merge(resOperationParams.criteria.depends, operationCategoryTiers); } resCategoryCheck = categoriesService.checkCategoryTierData(resOperationParams); resCategoryCheck.then(function (response) { if (response === true) { categorizations.push(resOperationCategoryData); } }); } if (resProductCategoryData && resProductCategoryData.tiers && resProductCategoryData.tiers.resProductCategoryTier1) { var resProductParams = _.cloneDeep(params); resProductParams.categoryType = EntityVO.CATEGORY_RESOLUTION_PRODUCT; _.merge(resProductParams.criteria.depends, resProductCategoryData.tiers); resProductCategoryCheck = categoriesService.checkCategoryTierData(resProductParams); resProductCategoryCheck.then(function (response) { if (response === true) { categorizations.push(resProductCategoryData); } }); } return $q.all([resCategoryCheck, resProductCategoryCheck]).then(function () { return categorizations; }); } $scope.saveDraftChange = function () { $scope.$broadcast(events.SAVE_TICKET_DRAFT); doCopyChange(); }; /** * Update ticket draft * */ $scope.saveDraft = function (knowledgeDetails) { var createData = $scope.getCreateData(knowledgeDetails); save(createData); }; $scope.getCreateData = function (knowledgeDetails) { if (!objectValueMapperService.isShelvedParentEmpty()) { objectValueMapperService.unshelveParent($scope.type); } $scope.$broadcast(events.SAVE_TICKET_DRAFT); $scope.state.dataIsLoading = true; var result, createData, ticket; //start - fix for SW00550252 if ($scope.basicData.causalCI === '') { delete $scope.basicData.causalCI; delete $scope.basicData.causalCIreconId; } if ($scope.basicData.impactedService === '') { delete $scope.basicData.impactedService; delete $scope.basicData.impactedServiceReconId; } //end if (($scope.type === EntityVO.TYPE_INCIDENT || $scope.type === EntityVO.TYPE_WORKORDER) && $scope.basicData.customer) { var site = objectValueMapperService.getFieldByName('site'); if (site && site.dataType !== 'widget') { if ($scope.basicData.customer.site) { delete $scope.basicData.customer.site.siteId; delete $scope.basicData.customer.site.address; if (!objectValueMapperService.getFieldByName('region')) { delete $scope.basicData.customer.site.region; } if (!objectValueMapperService.getFieldByName('siteGroup')) { delete $scope.basicData.customer.site.siteGroup; } } } } if ($scope.type === EntityVO.TYPE_INCIDENT) { result = categoriesService.collectValues($scope.basicData.allCategories, $scope.basicData, null, true); $scope.basicData.categorizations = result.categorizations; $scope.basicData.resCategorizations = result.resCategorizations; if (knowledgeDetails && knowledgeDetails.updateCategories) { $scope.basicData.categorizations = knowledgeDetails.categorizations; createData = _.cloneDeep($scope.basicData); delete createData.accessMappings; if (createData.customer.accessMappings) { delete createData.customer.accessMappings; } if (createData.contact && createData.contact.accessMappings) { delete createData.contact.accessMappings; } } else { createData = _.cloneDeep($scope.basicData); delete createData.accessMappings; if (createData.customer.accessMappings) { delete createData.customer.accessMappings; } if (createData.contact && createData.contact.accessMappings) { delete createData.contact.accessMappings; } } if (createData.customFields.hasOwnProperty('reportedSource') && createData.customFields.reportedSource === null) { delete createData.customFields.reportedSource; } } else if ($scope.type === EntityVO.TYPE_WORKORDER) { result = categoriesService.collectValues($scope.basicData.allCategories, $scope.basicData, null, true); $scope.basicData.categorizations = result.categorizations; ticket = $scope.basicData; if (ticket.customer.accessMappings) { delete ticket.customer.accessMappings; } createData = { id: ticket.id, displayId: ticket.displayId, summary: ticket.summary, customer: ticket.customer, desc: ticket.desc, status: ticket.status, categorizations: ticket.categorizations, type: EntityVO.TYPE_WORKORDER }; if (ticket.priority) { createData.priority = ticket.priority; } if (ticket.location && ticket.location.poiId) { createData.location = { poiId: ticket.location.poiId }; } if (ticket.locationCompany) { createData.locationCompany = ticket.locationCompany; } if (ticket.contact && ticket.contact.id) { createData.contact = ticket.contact; } if (ticket.impactedService) { createData.impactedService = ticket.impactedService; } if (ticket.scheduledStartDate) { createData.scheduledStartDate = moment(ticket.scheduledStartDate).valueOf(); } if (ticket.scheduledEndDate) { createData.scheduledEndDate = moment(ticket.scheduledEndDate).valueOf(); } if (ticket.actualStartDate) { createData.actualStartDate = moment(ticket.actualStartDate).valueOf(); } if (ticket.actualEndDate) { createData.actualEndDate = moment(ticket.actualEndDate).valueOf(); } if (ticket.supportGroup) { createData.supportGroup = ticket.supportGroup; } if (ticket.assignee) { createData.assignee = ticket.assignee; } if (ticket.managerGroup) { createData.managerGroup = ticket.managerGroup; } if (ticket.manager) { createData.manager = ticket.manager; } if (ticket.templateId) { createData.templateId = ticket.templateId; } if (ticket.templateName) { createData.templateName = ticket.templateName; } if (ticket.woAutomationStatus !== null && ticket.woAutomationStatus !== undefined && ticket.woAutomationStatus !== '') { createData.woAutomationStatus = ticket.woAutomationStatus; } if (ticket.attachments) { createData.attachments = ticket.attachments; } // prepare custom field values if (_.size(ticket.customFields)) { createData.customFields = ticket.customFields; } //prepare dynamic field values if (ticket.dynamicFields) { createData.dynamicFields = ticket.dynamicFields; } } else if ($scope.type === EntityVO.TYPE_SERVICEREQUEST) { // unlike create incident in Galileo, MyIT Service request create is very // unforgiving on the amount data being sent. So here we need to make sure // min require set is sent on the create createData = {}; if (!$scope.basicData.isAttributeHidden.requiredDate && $scope.basicData.requiredDate) { if ($rootScope.timezone) { createData.requiredDate = utilityFunctions.convertToUserPreferenceTimezone($scope.basicData.requiredDate, $rootScope.timezone); createData.requiredDate = moment(createData.requiredDate).valueOf(); } else { createData.requiredDate = moment($scope.basicData.requiredDate).valueOf(); } if (createData.requiredDate < moment().valueOf()) { systemAlertService.error({ text: i18nService.getLocalizedString('create.ticket.invalid.requiredDate'), clear: false }); $scope.state.dataIsLoading = false; return; } } createData.displayId = $scope.basicData.displayId; createData.id = $scope.basicData.id; createData.summary = $scope.basicData.summary; createData.desc = $scope.basicData.desc; createData.requestTemplateTitle = $scope.basicData.requestTemplateTitle; createData.requestTemplateId = $scope.basicData.requestTemplateId; // TODO Backend currently does not support create SR on customer and contact with no loginId. We need to use loginId for now since // requestagain rest call always returns customer.id value as the personId value, which will cause the subsequent SR create to fail createData.customer = { loginId: $scope.basicData.customer.loginId }; createData.contact = $scope.basicData.contact ? { loginId: $scope.basicData.contact.loginId } : { loginId: $scope.basicData.customer.loginId }; if (!$scope.basicData.isAttributeHidden.quantity) { createData.quantity = $scope.basicData.quantity; } createData.questionResponses = []; _.forEach($scope.basicData.questionDefinitions, function (question) { // we should only send answers for visible questions and hidden questions that user never needs to answer if (question.visibility || question.isHidden) { var answer; // Only include hidden fields, if their parent question has been answered if (question.isHidden && question.parentId) { var parentQuestion = _.find($scope.basicData.questionDefinitions, { id: question.parentId }), hasMetAllConditions = calculateConditionalQuestionVisibility(parentQuestion, question, false); if (!hasMetAllConditions) { return question; } } if (question.format === 'CHECK_BOXES' && question.answer) { if (angular.isArray(question.answer)) { answer = question.answer.join(';'); } } else if ((question.format === 'CHECK_BOXES' || question.format === 'STATIC_MENU' || question.format === 'QUERY_MENU' || question.format === 'RADIO_BUTTONS') && !question.answer) { var defaultValue = []; _.forEach(question.options, function (option) { if (option.isDefault) { defaultValue.push(option.value); } }); answer = defaultValue.join(';'); } else if (question.format === 'DATE_TIME' || question.format === 'DATE_ONLY' || question.format === 'TIME_ONLY') { answer = question.answer ? convertDateTimeAnswerToISO8601(question.answer) : null; } else { answer = question.answer; // srdRadioQuestion and srdCheckboxQuestion are resetting child question answers, // when their answer is getting changed. Since we are not showing hidden fields // we should maintain their defaultValue if (question.isHidden && !answer) { answer = question.defaultValue; } } createData.questionResponses.push({ questionId: question.id, value: answer, order: question.sortOrder }); } }); } else if ($scope.type === EntityVO.TYPE_PROBLEM) { result = categoriesService.collectValues($scope.basicData.allCategories, $scope.basicData); $scope.basicData.categorizations = result.categorizations; $scope.basicData.rootCause = $scope.basicData.rootCause ? $scope.basicData.rootCause : null; $scope.basicData.impact = $scope.basicData.impact ? $scope.basicData.impact : _.last($scope.metadata.impacts).name; $scope.basicData.urgency = $scope.basicData.urgency ? $scope.basicData.urgency : _.last($scope.metadata.urgencies).name; $scope.basicData.investigationDriver = $scope.basicData.investigationDriver ? $scope.basicData.investigationDriver : _.head($scope.metadata.investigationDrivers).name; createData = _.cloneDeep($scope.basicData); delete createData.accessMappings; } else if ($scope.type === EntityVO.TYPE_KNOWNERROR) { result = categoriesService.collectValues($scope.basicData.allCategories, $scope.basicData); $scope.basicData.categorizations = result.categorizations; $scope.basicData.rootCause = $scope.basicData.rootCause ? $scope.basicData.rootCause : null; createData = _.cloneDeep($scope.basicData); delete createData.accessMappings; } return createData; }; function doCopyChange() { createTicketModel.currentTicket = $scope.basicData; if (($state.params.hasRelatedCis || createTicketModel.currentTicket.impactedService) && !configurationModel.disableImpactAnalysis) { showImpactAnalysisModal(); } else { proceedWithCreateChange(); } } function showImpactAnalysisModal() { return systemAlertService.modal({ type: 'info', title: i18nService.getLocalizedString('create.change.wizard.confirmImpactAnalysis.title'), text: i18nService.getLocalizedString('create.change.wizard.confirmImpactAnalysis.text'), details: i18nService.getLocalizedString('create.change.wizard.confirmImpactAnalysis.text2'), additionalInfo: i18nService.getLocalizedString('create.change.wizard.confirmImpactAnalysis.text3'), buttons: [ { text: i18nService.getLocalizedString('impact.analysis.button.submitWithImpactAnalysisWindow'), data: true }, { text: i18nService.getLocalizedString('impact.analysis.button.submitWithoutImpactAnalysisWindow'), data: false } ] }).result.then(doClosurefn, doDismissFn); } //Handle Modal closed by Escape key function doDismissFn() { $scope.$broadcast(events.CHANGE_TO_EDIT_MODE); } function doClosurefn(data) { proceedWithCreateChange(data); } function proceedWithCreateChange(impactAnalysisFlag) { $scope.$broadcast(events.PROVIDER_SHOW_LOADING); var createData = createTicketModel.collectTicketChanges($scope.metadata); createData.parentId = $scope.basicData.parentId; if (!_.isEmpty($scope.basicData.templateId)) { createData.templateId = $scope.basicData.templateId; } if (!_.isEmpty($scope.basicData.timing)) { createData.timing = $scope.basicData.timing; } if (!_.isEmpty($scope.basicData.timingReason)) { createData.timingReason = $scope.basicData.timingReason; } var result = categoriesService.collectValues($scope.basicData.allCategories, $scope.basicData, null, true); createData.categorizations = result.categorizations; if (feedModel.pendingWorkNote) { var workInfo = {}; workInfo.worknote = feedModel.pendingWorkNote.noteText; workInfo.access = feedModel.pendingWorkNote.access; workInfo.workInfoType = feedModel.pendingWorkNote.workInfoType; createData.workInfo = workInfo; if (feedModel.pendingWorkNote.attachments && feedModel.pendingWorkNote.attachments.length) { createData.attachments = feedModel.pendingWorkNote.attachments; } } if (createData.summary) { createData.summary = createData.summary.replace(/\u00a0/g, ' '); } if (!createData.riskIsUserSpecified) { delete createData.riskLevel; } createTicketModel.currentTicket.questionResponses = createData.questionResponses ? createData.questionResponses : ''; $scope.basicData.riskIsUserSpecified = createData.riskIsUserSpecified; delete createData.questionDefinitions; delete createData.questionResponses; createData.scheduledStartDate = $scope.basicData.scheduledStartDate && $scope.basicData.scheduledStartDate.valueOf() || createData.scheduledStartDate; createData.scheduledEndDate = $scope.basicData.scheduledEndDate && $scope.basicData.scheduledEndDate.valueOf() || createData.scheduledEndDate; createData.actualStartDate = $scope.basicData.actualStartDate && $scope.basicData.actualStartDate.valueOf() || createData.actualStartDate; createData.actualEndDate = $scope.basicData.actualEndDate && $scope.basicData.actualEndDate.valueOf() || createData.actualEndDate; createData.targetDate = $scope.basicData.targetDate && $scope.basicData.targetDate.valueOf() || createData.targetDate; if ($scope.basicData.createdfromParentTemplate !== null) { createData.createdfromParentTemplate = $scope.basicData.createdfromParentTemplate; } if ($scope.basicData.copyTasks !== null) { createData.copyTasks = $scope.basicData.copyTasks; } createTicketModel.createChangeRequestV2(createData) .then(function (change) { var promisesList = []; promisesList.push(createTicketModel.saveImpactedAreas(createTicketModel.currentTicket.id, EntityVO.TYPE_CHANGE, createTicketModel.currentTicket.impactedAreas)); if (!createData.riskIsUserSpecified) { promisesList.push(createTicketModel.saveRiskResponse(createTicketModel.currentTicket)); } promisesList.push(createTicketModel.saveDocuments(createTicketModel.currentTicket)); promisesList = _.flatten(promisesList); if (promisesList.length > 0) { //$scope.state.dataIsLoading = true; $q.all(promisesList).finally(function () { createTicketModel.onChangeCreateSuccess(change, impactAnalysisFlag); $timeout(function () { systemAlertService.success({ text: i18nService.getLocalizedString('copychange.general.message2'), clear: true, hide: 10000 }); }, 500); $state.go($scope.type, { id: change.id }); }); } }).catch(function (error) { showErrorMessage(error); $scope.$broadcast(events.PROVIDER_HIDE_LOADING); $scope.$broadcast(events.CHANGE_TO_EDIT_MODE); }).finally(function () { $scope.$broadcast(events.PROVIDER_HIDE_LOADING); }); } function showErrorMessage(error) { if (error) { var errorData = _.isObject(error) ? error.data : { error: error }; if (activeErrorNotification) { var notification = _.find(systemAlertService.alertStack, { key: activeErrorNotification.key }); if (notification) { notification.close(); } } activeErrorNotification = systemAlertService.error({ text: errorData.detailMessage || error.data.error, clear: false }); } } /** * Save ticket * * @param ticketData */ function save(ticketData) { ticketData.summary = ticketData.summary.replace(/\u00a0/g, ' '); if (ticketData.desc) { ticketData.desc = ticketData.desc.replace(/\u00a0/g, ' '); } if (_.isString(ticketData.contact) && _.isEmpty(ticketData.contact)) { ticketData.contact = {}; } ticketModel.saveDraft($scope.type, ticketData).then(function (response) { var saveRelationsPromise = $q.when(1); var relations = []; if ($scope.type === EntityVO.TYPE_PROBLEM || $scope.type === EntityVO.TYPE_KNOWNERROR) { $scope.basicData.id = response.ticketData.id; } if ($stateParams.isSrcLiveChat === 'true' && $scope.liveChatWindow) { var livechatTicketData = { type: $scope.basicData.type, id: $scope.basicData.id, displayId: $scope.basicData.displayId, chatSessionId: $scope.basicData.chatSessionId, summary: $scope.basicData.summary }; var ticketDataEvent = { eventData: { livechatTicketData: livechatTicketData }, event: events.TICKET_CREATED_FROM_DRAFT }; $scope.liveChatWindow.postMessage(ticketDataEvent, window.location && window.location.origin); //NOSONAR } if (relationModel.cache[$scope.basicData.id]) { relations = transformRelations($scope.basicData.id, $scope.basicData.displayId, relationModel.cache[$scope.basicData.id]); } if (relatedDraftInfo && relatedDraftInfo.fromType === EntityVO.TYPE_PROBLEM && relatedDraftInfo.type === EntityVO.TYPE_KNOWNERROR) { relatedDraftInfo.relationship = RelationItemVO.TYPE_INITIATEDBY; } //create 'Created By' relationship if created from another(source) ticket if (isRelatedDraft) { relations.push({ id: relatedDraftInfo.id, relationshipType: (relatedDraftInfo.relationship) ? relatedDraftInfo.relationship : RelationItemVO.TYPE_CREATEDBY, tag: RelationItemVO.TAG_LINKEDITEM, type: relatedDraftInfo.fromType, desc: relatedDraftInfo.fromContext.summary // source ticket summary }); } if (relations.length) { saveRelationsPromise = relationModel.addRelation({ uuid: $scope.basicData.id, type: $scope.type }, relations); } saveRelationsPromise.then(onSaveDraftSuccess); }).catch(function (error) { showErrorMessage(error); $scope.state.dataIsLoading = false; $scope.$broadcast(events.HIDE_TICKET_DRAFT_LOADER); }); } function processStatusWorkNote() { if (statusWorkNote && statusWorkNote.length > 0) { var activityItem = { type: $scope.type, id: $scope.basicData.id }; var noteData = {}; noteData.noteText = statusWorkNote; return feedModel.saveNote(activityItem, noteData); } return $q.when(1); } /** * Process pending work note * * @param ticket */ function processPendingWorkNoteFor(ticket) { return feedModel.processPendingWorkNote(ticket) || $q.when(1); } $scope.cancelNotification = function () { $scope.currentState = $state.current; $state.go(prevState.name, _.isEmpty(prevState.params) ? '' : prevState.params); }; $scope.cancelCopyChange = function () { $state.go('change', { id: $state.params.copyChangeId }); }; function onSaveDraftSuccess() { if (relationModel.cache[$scope.basicData.id]) { delete relationModel.cache[$scope.basicData.id]; } if (relatedDraftInfo && relatedDraftInfo.fromType === EntityVO.TYPE_ASSET) { delete relationModel.cache[relatedDraftInfo.id]; } var statusWorkNote = processStatusWorkNote(); var pendingWorkNotePromise = processPendingWorkNoteFor($scope.basicData); $scope.dirty = false; delete ticketModel.cache[$scope.basicData.id]; if ($scope.draftNotificationInstance) { systemAlertService.dismissAlert($scope.draftNotificationInstance.key); } $timeout(function () { systemAlertService.success({ text: $filter('i18n')('ticket.notification.save.message'), hide: 10000 }); }, 500); var params = { id: $scope.basicData.id }; $q.all([statusWorkNote, pendingWorkNotePromise]).then(function () { $scope.state.dataIsLoading = false; $state.go($scope.type, params, { location: 'replace' }); }); } $scope.saveResource = function (data) { var dataExist = _.find(relationModel.cache[$scope.basicData.id], function (obj) { return obj.id === data.id; }); if (dataExist === undefined) { relationModel.markRelationForAdd($scope.basicData.id, data); if (data.relationshipType === EntityVO.TYPE_DUPLICATEOF) { $scope.state.dataIsLoading = true; var impact, urgency, priority; if (!_.isEmpty(objectValueMapperService.getValueByFieldName('priority'))) { impact = objectValueMapperService.getValueByFieldName('priority').impact.name; urgency = objectValueMapperService.getValueByFieldName('priority').urgency.name; priority = objectValueMapperService.getValueByFieldName('priority').priority.name; } var actionData = { customerLoginId: $scope.basicData.customer.id, desc: objectValueMapperService.getValueByFieldName('desc').desc, summary: objectValueMapperService.getValueByFieldName('summary'), impact: impact, urgency: urgency, priority: priority }; if ($scope.isDraft && $scope.basicData) { actionData.displayId = $scope.basicData.displayId; actionData.id = $scope.basicData.id; } var impactedService = objectValueMapperService.getValueByFieldName('impactedService'); if (impactedService.ci) { actionData.impactedService = impactedService.ci.name; actionData.serviceCIReconId = impactedService.ci.reconciliationId; } if ($scope.basicData.type === EntityVO.TYPE_INCIDENT) { actionData.createData = $scope.getCreateData(); } ticketModel.applyAction(data.id, EntityVO.TYPE_INCIDENT, EntityVO.ACTION_DUPLICATE, actionData).then(function (response) { if (!_.isEmpty(response)) { $scope.dirty = false; actionData = response[0].items[0]; $scope.state.dataIsLoading = false; $state.go(EntityVO.TYPE_INCIDENT, { id: actionData.id }); } }).catch(function (error) { $scope.state.dataIsLoading = false; $scope.basicData.accessMappings.detailsEditAllowed = true; }); } else if (data.resourceToResolve) { $scope.basicData.status = { value: 'Resolved', reason: 'No Further Action Required' }; $scope.basicData.resolution = data.title; if (!$scope.basicData.summary) { $scope.basicData.summary = $scope.basicData.desc.substring(0, 100); } $scope.saveDraft(); } } }; $scope.unrelateResource = function (data) { relationModel.markRelationForDelete($scope.basicData.id, data); }; function saveToTicketFromRs(event, relationItem) { angular.extend(relationItem, { tag: EntityVO.TYPE_RESOURCE, relationshipType: RelationItemVO.TYPE_RELATEDTO }); relationModel.markRelationForAdd($scope.basicData.id, relationItem); } function removeFromTicketFromRs(event, relationItem) { relationModel.markRelationForDelete($scope.basicData.id, relationItem); } function resolveTicketFromRs(event, relationItem, knowledgeDetails) { $scope.basicData.status = { value: 'Resolved', reason: 'No Further Action Required' }; objectValueMapperService.getFieldByName('status').value = 'Resolved'; objectValueMapperService.getFieldByName('statusReason').value = 'No Further Action Required'; objectValueMapperService.getFieldByName('resolution').value = knowledgeDetails.title; $scope.basicData.resolution = relationItem.title; if (!$scope.basicData.summary) { $scope.basicData.summary = $scope.basicData.desc.substring(0, 100); } $scope.saveDraft(knowledgeDetails); } function markTicketAsDuplicateFromRs(event, relationItem) { angular.extend(relationItem, { tag: EntityVO.TYPE_LINKEDITEM, relationshipType: EntityVO.TYPE_DUPLICATEOF }); relationModel.cache[$scope.basicData.id].push(relationItem); } $scope.initProfile = function () { $scope.isCopyChange = $state.params.isCopyChange; if (!smartRecorderModel.smartRecorderData && !dataExists && !$state.params.isCopyChange) { $state.go('smartRecorder'); return; } generateStartupData(); $scope.initEvents(); if ($scope.isCopyChange) { initCopyChange(); } else { $scope.initDetails(); } if (dataExists) { delete ticketModel.cache.draft; } }; /** * Returns true if panel has custom fields * * @param panelId * @return {boolean} */ $scope.hasCustomFields = function (panelId) { var panel = screenConfigurationModel.getPanelById(panelId); return panel && panel.hasCustomFields(); }; $scope.editDisabledFor = function (sectionId) { return $scope.activeEditableSectionId && $scope.activeEditableSectionId !== sectionId; }; /** * Handler for toggling edit mode * * @param event * @param editableContentSectionId */ function handleToggleEditMode(event, editableContentSectionId) { $scope.activeEditableSectionId = editableContentSectionId; if (editableContentSectionId === 'ticket-header') { $scope.enableHeaderEdit(); } } function handleEditComplete() { $scope.activeEditableSectionId = null; } /** * thansform relations to save to ticket * * @param ticketId * @param displayId * @param relations */ function transformRelations(ticketId, displayId, relations) { var transformedRelations = []; for (var i = 0; i < relations.length; i++) { var relation = relations[i]; if (relation.type === EntityVO.TYPE_TASK) { continue; } relation = new RelationItemVO().build(relation); relation.parentId = ticketId; relation.isPoi = undefined; relation.realObject = undefined; relation.entityLink = undefined; relation.details = { parentDisplayId: displayId }; if (!relation.tag) { relation.tag = EntityVO.TYPE_RESOURCE; } if (!relation.relationshipType) { relation.relationshipType = EntityVO.TYPE_RELATEDTO; } transformedRelations.push(relation); } return transformedRelations; } function initAlertForDirtyDraft() { $scope.$on('$stateChangeStart', function (event, toState, toParams) { if ($scope.dirty) { event.preventDefault(); var modalInstance = systemAlertService.modal({ title: i18nService.getLocalizedString('common.notification.dirty.title'), text: i18nService.getLocalizedString('common.notification.dirty.message'), buttons: [ { text: i18nService.getLocalizedString('common.notification.dirty.button1'), data: { stateName: toState.name, stateParams: toParams } }, { text: i18nService.getLocalizedString('common.notification.dirty.button2') } ] }); modalInstance.result.then(function (data) { if (!_.isEmpty(data)) { $scope.dirty = false; postWindowCloseMessageToLiveChat(); var modalStack = $injector.get('$modalStack'); modalStack.dismissAll(); $state.transitionTo(data.stateName, data.stateParams, { location: 'replace' }); } else { if ($scope.type === EntityVO.TYPE_SERVICEREQUEST && $scope.isCrossLaunchRequest) { srdModel.launchAIF(true, // createNew true, // historyBackOnCancel $scope, $scope.template.name, $scope.template.templateObject.crossLaunchURL, $scope.basicData.customer.id, $scope.basicData.contact ? $scope.basicData.contact.id : null); } } }); } }); } function convertDateTimeAnswerToISO8601(answer) { var result; if (answer.date && answer.time) { if ($rootScope.timezone) { answer.date = utilityFunctions.convertToUserPreferenceTimezone(answer.date, $rootScope.timezone); answer.time = utilityFunctions.convertToUserPreferenceTimezone(answer.time, $rootScope.timezone); } var time = moment(answer.time); result = moment(answer.date) .hour(time.hour()) .minute(time.minute()); } else { if ($rootScope.timezone) { answer = utilityFunctions.convertToUserPreferenceTimezone(answer, $rootScope.timezone); } result = moment(answer); } return result.format(); } function handleShownAssignmentBlade($event, data) { var isAssignToMeAction = false, originalEvent = data.originalEvent; if (data) { isAssignToMeAction = !!data.assignToMe; var assigneeRole = data.role; if (assigneeRole === 'manager' || assigneeRole === 'coordinator') { assigneeRole = $scope.type + assigneeRole; } else if (assigneeRole === 'assignee') { if ($scope.type === EntityVO.TYPE_CHANGE) { assigneeRole = $scope.type + 'coordinator'; } else { assigneeRole = 'ticketassignee'; } } if (isAssignToMeAction) { ticketActionService.assignToMe(originalEvent, assigneeRole, !data.saveSelection, $scope.basicData, $scope); } else { ticketActionService.assign(originalEvent, !data.saveSelection, $scope.basicData, $scope, assigneeRole); } } else { $log.warn('Could not open assignment blade. Required Event data is missing. '); return; } } function initCopyChange() { var riskRulePromise; $scope.dirty = true; objectValueMapperService.setCopyChangeTicket(); initAlertForDirtyDraft(); $timeout(function () { systemAlertService.warning({ text: i18nService.getLocalizedString('copychange.general.message'), hide: 10000 }); }, 500); var metadataPromise = metadataModel.getMetadataByType($scope.type).then(function (metadata) { var riskLevelList = []; $scope.metadata = metadata || {}; _.forEach($scope.metadata.riskLevels, function (riskLevelObj) { riskLevelList.push(riskLevelObj.name); }); riskRulePromise = ticketModel.getChangeRiskRules($state.params.ticket.company && $state.params.ticket.company.name).then(function (data) { if (data && data.workNoteRequiredForRisk) { $scope.basicData.riskRulesConfigured = true; $scope.basicData.riskLevelForNote = _.takeRight(riskLevelList, riskLevelList.length - riskLevelList.indexOf(data.workNoteRequiredForRisk)); } if (data && data.changeReasonRequiredForRisk) { $scope.basicData.riskRulesConfigured = true; $scope.basicData.riskLevelForChangeReason = _.takeRight(riskLevelList, riskLevelList.length - riskLevelList.indexOf(data.changeReasonRequiredForRisk)); } }); }); var globalMetadataPromise = metadataModel.getMetadataByType(EntityVO.TYPE_GLOBAL).then(function (globalMetadata) { $scope.globalMetadata = globalMetadata || {}; showAffectedServiceRelation = $scope.globalMetadata.configurationParameters.affectedServiceRelation; }); var screenLayoutPromise = layoutConfigurationModel.loadScreenLayout(screenName) .then(function (screenLayout) { $scope.screenLayout = screenLayout; /* Code to hide impacted area section*/ var impactedAreas = screenConfigurationModel.getFieldByName(screenName, 'impactedAreas'); if (impactedAreas) { var panel = _($scope.screenLayout.panels) .thru(function (coll) { return _.union(coll, _.map(coll, 'panels')); }) .flatten() .find({ id: impactedAreas.panelId }); if (panel && panel.children.length == 0) { _.remove($scope.screenLayout.panels, { name: 'impactedAreasSection' }); } } }); var promises = [].concat([ metadataPromise, globalMetadataPromise, screenLayoutPromise, riskRulePromise ]); $q.all(promises).then(function () { $scope.basicData = $state.params.ticket; $scope.basicData.fromCopyChange = true; $scope.basicData.isDraft = true; $scope.basicData.riskLevel = ''; $scope.basicData.isFullVersion = $scope.isFullVersion; $scope.type = EntityVO.TYPE_CHANGE; $scope.state.dataIsLoading = false; if (_.isEmpty($scope.basicData.status)) { $scope.basicData.status['value'] = "Draft"; } var allEntityCategories = $scope.basicData.categorizations; $scope.basicData.allCategories = categoriesService.populateCategories(allEntityCategories, $scope.metadata); $scope.basicData.noCategories = (_.filter($scope.basicData.allCategories, 'valueToShow')).length; $scope.addNote = { inputText: "" }; }); } $scope.initEvents = function () { $scope.$on(events.TOGGLE_EDIT_MODE, handleToggleEditMode); $scope.$on(events.EDIT_COMPLETE, handleEditComplete); $scope.$on(events.SAVE_TO_TICKET_FROM_RS, saveToTicketFromRs); $scope.$on(events.REMOVE_FROM_TICKET_FROM_RS, removeFromTicketFromRs); $scope.$on(events.RESOLVE_TICKET_FROM_RS, resolveTicketFromRs); $scope.$on(events.MARK_AS_DUPLICATE_OF_FROM_RS, markTicketAsDuplicateFromRs); $scope.$on(events.DRAFT_TICKET_RESOURCE_RELATED, function (event, relations) { for (var i = 0; i < relations.length; i++) { $scope.saveResource(relations[i]); } }); $scope.$on(events.DRAFT_TICKET_RESOURCE_UNRELATED, removeFromTicketFromRs); $scope.$on(events.SHOW_ASSIGN_TICKET_BLADE, handleShownAssignmentBlade); $scope.$on(events.WORKNOTE_REQUIRED, function (event, data) { $scope.isNoteRequired = data.isRequired; }); }; $scope.initDetails = function () { $scope.dirty = true; $timeout(function () { if (errorQuickCreate) { systemAlertService.error({ text: errorQuickCreate, hide: 10000 }); } $scope.draftNotificationInstance = systemAlertService.warning({ text: $filter('i18n')('ticket.notification.draft.message'), hide: 10000 }); $scope.draftNotificationInstance.result .finally(function () { $scope.draftNotificationInstance = null; }); }, 500); initAlertForDirtyDraft(); if (smartRecorderModel.smartRecorderData && smartRecorderModel.smartRecorderData.desc) { smartRecorderModel.smartRecorderData.desc = smartRecorderModel.smartRecorderData.desc.replace(/\u00a0/g, ' '); } var templateId = !_.isEmpty($scope.template) ? $scope.template.id : null; if (templateId && $scope.template.templateObject.isCrossLaunchRequest) { $scope.basicData.customer = smartRecorderModel.smartRecorderData.customer; $scope.basicData.company = { name: smartRecorderModel.smartRecorderData.customer.company.name }; if (!_.isEmpty(smartRecorderModel.smartRecorderData.contact)) { $scope.basicData.contact = smartRecorderModel.smartRecorderData.contact; } $scope.basicData.desc = smartRecorderModel.smartRecorderData.desc; $scope.isCrossLaunchRequest = true; $scope.state.dataIsLoading = false; $scope.basicData.id = 'draft'; srdModel.launchAIF(true, // createNew true, // historyBackOnCancel $scope, $scope.template.name, $scope.template.templateObject.crossLaunchURL, $scope.basicData.customer.id, $scope.basicData.contact ? $scope.basicData.contact.id : null); return; } var companyName = smartRecorderModel.smartRecorderData.customer && smartRecorderModel.smartRecorderData.customer.company && smartRecorderModel.smartRecorderData.customer.company.name; var basicDataPromise = ticketModel.getDraft($scope.type, templateId, smartRecorderModel.smartRecorderData.desc, companyName, null, smartRecorderModel.smartRecorderData.customer).then(function (data) { $scope.itemId = data.id; ticketModel.cache[$scope.itemId] = angular.copy(data); if (isRelatedDraft) { delete ticketModel.cache.relatedDraft; } }); var metadataPromise = metadataModel.getMetadataByType($scope.type).then(function (metadata) { $scope.metadata = metadata || {}; }); var globalMetadataPromise = metadataModel.getMetadataByType(EntityVO.TYPE_GLOBAL).then(function (globalMetadata) { $scope.globalMetadata = globalMetadata || {}; showAffectedServiceRelation = $scope.globalMetadata.configurationParameters.affectedServiceRelation; }); var screenLayoutPromise = layoutConfigurationModel.loadScreenLayout(screenName) .then(function (screenLayout) { $scope.screenLayout = screenLayout; }); var screenConfigurationPromise = $q.resolve({}); if ($scope.type !== 'request') { screenConfigurationPromise = screenConfigurationModel.isV2CompatibleScreen(screenName) ? screenConfigurationModel.loadScreenConfigurationByName(screenName) : screenConfigurationModel.loadScreenConfigurationAndCustomFieldLabels(screenName, $scope.type); } var promises = [].concat([ basicDataPromise, metadataPromise, globalMetadataPromise, screenLayoutPromise, screenConfigurationPromise ]); if ($scope.type !== EntityVO.TYPE_SERVICEREQUEST) { promises.push(screenConfigurationModel.loadScreenConfigurationByName(screenName)); } $q.all(promises).then(function () { var allEntityCategories; $scope.basicData = ticketModel.cache[$scope.itemId] ? angular.copy(ticketModel.cache[$scope.itemId]) : {}; $scope.basicData.isFullVersion = $scope.isFullVersion; $scope.basicData.isDraft = true; if ($scope.type === EntityVO.TYPE_INCIDENT) { var customerCompany = smartRecorderModel.smartRecorderData.customer ? smartRecorderModel.smartRecorderData.customer.company.name : $scope.basicData.company.name; if (smartRecorderModel.smartRecorderData && smartRecorderModel.smartRecorderData.template && smartRecorderModel.smartRecorderData.template.name) { $scope.basicData.templateName = smartRecorderModel.smartRecorderData.template.name; } if (_.isEmpty(customerCompany) && $stateParams.isSrcLiveChat === 'true') { customerCompany = $scope.basicData.customer && $scope.basicData.customer.company && $scope.basicData.customer.company.name; } ticketModel.getIncidentRules(customerCompany).then(function (data) { $scope.basicData.serviceCIRequired = data.serviceCIRequired == "true" ? true : false; $scope.basicData.CIRequiredOnResolved = data.CIRequiredOnResolved == "true" ? true : false; if ($scope.basicData.serviceCIRequired) { $scope.$broadcast(events.SERVICECI_REQUIRED, { isRequired: true, name: "impactedService" }); } else { $scope.$broadcast(events.SERVICECI_REQUIRED, { isRequired: false, name: "impactedService" }); } if (data.applyCognitiveForSupportGroup) { $scope.basicData.applyCognitiveForSupportGroup = data.applyCognitiveForSupportGroup; $scope.$broadcast(events.APPLY_COGNITIVE_SG, { applyCognitive: data.applyCognitiveForSupportGroup }); } }); } if ($scope.type !== EntityVO.TYPE_WORKORDER) { relationModel.cache[$scope.itemId] = []; } if (!_.isEmpty(smartRecorderModel.smartRecorderData.status)) { $scope.basicData.status = smartRecorderModel.smartRecorderData.status; } if (!_.isEmpty(smartRecorderModel.smartRecorderData.resolution)) { $scope.basicData.resolution = smartRecorderModel.smartRecorderData.resolution; } if (!_.isEmpty(smartRecorderModel.smartRecorderData.assignee)) { $scope.basicData.assignee = smartRecorderModel.smartRecorderData.assignee; } if (!_.isEmpty(smartRecorderModel.smartRecorderData.customer)) { $scope.basicData.customer = smartRecorderModel.smartRecorderData.customer; $scope.basicData.company = { name: smartRecorderModel.smartRecorderData.customer.company.name }; } if (!_.isEmpty($scope.basicData.customer) && !objectValueMapperService.getFieldByName('locationCompany')) { $scope.basicData.locationCompany = { name: $scope.basicData.customer.company.name }; } if (!_.isEmpty(smartRecorderModel.smartRecorderData.contact)) { $scope.basicData.contact = smartRecorderModel.smartRecorderData.contact; } if (smartRecorderModel.smartRecorderData.desc) { var ticketNotes = $scope.basicData.desc ? $scope.basicData.desc + ' ' : ''; $scope.basicData.desc = smartRecorderModel.smartRecorderData.desc; if (ticketNotes.trim()) { $scope.basicData.desc += '\n' + ticketNotes; } $scope.basicData.desc.trim(); if ($scope.type === EntityVO.TYPE_PROBLEM && !$scope.basicData.summary) { $scope.basicData.summary = smartRecorderModel.smartRecorderData.desc.substring(0, 100); } } if (_.isEmpty($scope.basicData.company) && (isRelatedDraft || $stateParams.isSrcLiveChat === 'true')) { var companyName = ($scope.basicData.customer && $scope.basicData.customer.company && $scope.basicData.customer.company.name) || (relatedDraftInfo && relatedDraftInfo.fromContext && relatedDraftInfo.fromContext.company && relatedDraftInfo.fromContext.company.name); $scope.basicData.company = { name: companyName }; } if ($scope.type === EntityVO.TYPE_INCIDENT || $scope.type === EntityVO.TYPE_PROBLEM || $scope.type === EntityVO.TYPE_KNOWNERROR) { var priorityField; if ($scope.type === EntityVO.TYPE_INCIDENT) { priorityField = screenConfigurationModel.getFieldByName(screenName, 'priority'); } if (!$scope.basicData.priority && (($scope.type === EntityVO.TYPE_INCIDENT && priorityField && priorityField.isWidget()) || $scope.type === EntityVO.TYPE_PROBLEM || $scope.type === EntityVO.TYPE_KNOWNERROR)) { if (smartRecorderModel.smartRecorderData.impact && smartRecorderModel.smartRecorderData.urgency) { var impact = _.find($scope.metadata.impacts, { index: +smartRecorderModel.smartRecorderData.impact }); var urgency = _.find($scope.metadata.urgencies, { index: +smartRecorderModel.smartRecorderData.urgency }); $scope.basicData.impact = impact && impact.name || _.last($scope.metadata.impacts).name; $scope.basicData.urgency = urgency && urgency.name || _.last($scope.metadata.urgencies).name; } else { $scope.basicData.impact = _.last($scope.metadata.impacts).name; $scope.basicData.urgency = _.last($scope.metadata.urgencies).name; } ticketModel.getPriority($scope.basicData.company.name, $scope.basicData.impact, $scope.basicData.urgency, $scope.type) .then(function (data) { $scope.basicData.priority = data; }); } } if ($scope.type === EntityVO.TYPE_WORKORDER) { if (!$scope.basicData.priority) { $scope.basicData.priority = _.last($scope.metadata.priorities).name; } if (templateId) { relationModel.getRelations($scope.itemId, $scope.type).then(function () { if (!_.isEmpty(smartRecorderModel.smartRecorderData.causalCI)) { // since work order does not support affected CI, if affected CI was specified in // smart recorder, it will be handled as related CI var relatedAsset = smartRecorderModel.smartRecorderData.causalCI; $scope.saveResource({ id: relatedAsset.reconciliationId, type: EntityVO.TYPE_ASSET, tag: EntityVO.TYPE_LINKEDITEM, desc: relatedAsset.name, relationshipType: EntityVO.TYPE_RELATEDTO, parentId: $scope.itemId, displayId: $scope.basicData.displayId, realObject: { name: relatedAsset.name, assetType: relatedAsset.assetType, classId: relatedAsset.classId, status: relatedAsset.status, reconciliationId: relatedAsset.reconciliationId, manufacturer: relatedAsset.manufacturer, model: relatedAsset.product.model } }); } }); } else { if (!_.isEmpty(smartRecorderModel.smartRecorderData.causalCI)) { // since work order does not support affected CI, if affected CI was specified in // smart recorder, it will be handled as related CI relationModel.cache[$scope.itemId] = []; var relatedAsset = smartRecorderModel.smartRecorderData.causalCI; $scope.saveResource({ id: relatedAsset.reconciliationId, type: EntityVO.TYPE_ASSET, tag: EntityVO.TYPE_LINKEDITEM, desc: relatedAsset.name, relationshipType: EntityVO.TYPE_RELATEDTO, parentId: $scope.itemId, displayId: $scope.basicData.displayId, realObject: { name: relatedAsset.name, assetType: relatedAsset.assetType, classId: relatedAsset.classId, status: relatedAsset.status, reconciliationId: relatedAsset.reconciliationId, manufacturer: relatedAsset.manufacturer, model: relatedAsset.product.model } }); } } } if ($scope.type === EntityVO.TYPE_PROBLEM) { if (userModel.userFullData.availableForAssignment) { $scope.availableForAssignment = userModel.userFullData.availableForAssignment; } else { userModel.getFullCurrentUserData().then(function () { $scope.availableForAssignment = userModel.userFullData.availableForAssignment; }); } if (smartRecorderModel.smartRecorderData.investigationDriver) { $scope.basicData.investigationDriver = smartRecorderModel.smartRecorderData.investigationDriver; } else { $scope.basicData.investigationDriver = $scope.basicData.investigationDriver ? $scope.basicData.investigationDriver : _.head($scope.metadata.investigationDrivers).name; } } if ($scope.type === EntityVO.TYPE_INCIDENT) { if (smartRecorderModel.smartRecorderData.template && smartRecorderModel.smartRecorderData.template.templateObject) { $scope.basicData.serviceType = smartRecorderModel.smartRecorderData.template.templateObject.serviceType; } else if (!$scope.basicData.serviceType) { $scope.basicData.serviceType = $scope.metadata.types[0].name; } } if ($scope.type === EntityVO.TYPE_INCIDENT || $scope.type === EntityVO.TYPE_WORKORDER || $scope.type === EntityVO.TYPE_PROBLEM || $scope.type === EntityVO.TYPE_KNOWNERROR) { if (!$scope.basicData.status.value) { $scope.basicData.status.value = $scope.metadata.statuses[0].name; } if ($scope.type !== EntityVO.TYPE_WORKORDER && !_.isEmpty(smartRecorderModel.smartRecorderData.causalCI)) { $scope.basicData.causalCI = {}; $scope.basicData.causalCI.name = smartRecorderModel.smartRecorderData.causalCI.name; $scope.basicData.causalCI.reconciliationId = smartRecorderModel.smartRecorderData.causalCI.reconciliationId; $scope.basicData.causalCI.classId = smartRecorderModel.smartRecorderData.causalCI.classId; $scope.basicData.resCategorizations = _.map($scope.basicData.resCategorizations, function (category) { var match = _.find(smartRecorderModel.smartRecorderData.causalCI.product.categorizations, function (productCat) { return productCat.name === 'product' && category.name === 'resolutionProduct'; }); if (match && match.tiers) { category.tiers.resProductCategoryTier1 = match.tiers.productCategoryTier1; category.tiers.resProductCategoryTier2 = match.tiers.productCategoryTier2; category.tiers.resProductCategoryTier3 = match.tiers.productCategoryTier3; category.tiers.resProductName = match.tiers.productName; category.tiers.resProductModelVersion = match.tiers.productModelVersion; } return category; }); } allEntityCategories = $scope.basicData.categorizations; if (!_.isEmpty(smartRecorderModel.smartRecorderData.impactedService)) { $scope.basicData.impactedService = {}; $scope.basicData.impactedService.name = smartRecorderModel.smartRecorderData.impactedService.name; $scope.basicData.impactedService.reconciliationId = smartRecorderModel.smartRecorderData.impactedService.reconciliationId; $scope.basicData.impactedService.classId = smartRecorderModel.smartRecorderData.impactedService.classId; var productCategory = _.find(allEntityCategories, { name: 'product' }); if (productCategory !== null) { productCategory.company = smartRecorderModel.smartRecorderData.impactedService.company; productCategory.tiers = _.head(smartRecorderModel.smartRecorderData.impactedService.product.categorizations).tiers; productCategory.cognitiveFlag = false; } } if (!_.isEmpty(smartRecorderModel.smartRecorderData.relatedAsset)) { _.forEach(smartRecorderModel.smartRecorderData.relatedAsset, function (relatedAsset) { $scope.saveResource({ id: relatedAsset.reconciliationId, type: EntityVO.TYPE_ASSET, tag: EntityVO.TYPE_LINKEDITEM, desc: relatedAsset.name, relationshipType: EntityVO.TYPE_RELATEDTO, parentId: $scope.itemId, displayId: $scope.basicData.displayId, realObject: { name: relatedAsset.name, assetType: relatedAsset.assetType, classId: relatedAsset.classId, status: relatedAsset.status, reconciliationId: relatedAsset.reconciliationId, manufacturer: relatedAsset.manufacturer, model: relatedAsset.product.model } }); }); } if (!!$scope.basicData.resCategorizations && $scope.basicData.isClosed()) { allEntityCategories = $scope.basicData.categorizations.concat($scope.basicData.resCategorizations); } else if ($scope.basicData.type === EntityVO.TYPE_INCIDENT) { $scope.basicData.categorizations.push(_.find($scope.basicData.resCategorizations, { 'name': 'resolutionProduct' })); $scope.basicData.categorizations.push(_.find($scope.basicData.resCategorizations, { 'name': 'resolution' })); allEntityCategories = $scope.basicData.categorizations; } $scope.basicData.allCategories = categoriesService.populateCategories(allEntityCategories, $scope.metadata); _.forEach($scope.basicData.allCategories, function (category) { category.dirty = true; }); $scope.basicData.noCategories = (_.filter($scope.basicData.allCategories, 'valueToShow')).length; $scope.activeSection = 'resources'; } else if ($scope.type === EntityVO.TYPE_SERVICEREQUEST) { if ($scope.template && $scope.template.templateObject) { var now = new Date().getTime(); var turnaroundTimeUnit = $scope.template.templateObject.turnaroundTimeUnits === 'TURN_AROUND_TIME_UNITS_DAYS' ? 'days' : 'hours'; var turnAroundTime = moment(now).add($scope.template.templateObject.turnaroundTime, turnaroundTimeUnit); $scope.basicData.expectedDate = moment(turnAroundTime).toDate(); } $scope.servReqRequiredDatePicker = { open: false }; $scope.servReqDatePickerOptions = { startingDay: configurationModel.getWeekStartingDay(), 'show-weeks': false, minDate: moment().year(1970).month(0).date(1), maxDate: moment().year(2038).month(0).date(18) }; $scope.basicData.requiredDate = ''; $scope.openDatePicker = function (calendar) { calendar.open = true; }; // it is possible to have srd with no questions, in this case, the form should be valid by default if ($scope.basicData.questionDefinitions.length === 0) { $scope.numOfRequiredFieldMissing = 0; $scope.answerIsValid = true; $scope.numOfRequiredAnswerMissing = 0; } if (!$scope.basicData.isAttributeHidden.quantity) { $scope.basicData.quantity = 1; //$scope.$watch('basicData.quantity', updateValidityFlag); } var mentionedPersons = _.filter(smartRecorderModel.smartRecorderData.confirmedItems, { relationship: 'mentioned' }); if (!configurationModel.showNameInSmartRecorderCreateTicket && mentionedPersons.length) { var mentionedText = mentionedPersons.length === 1 ? i18nService.getLocalizedString('createNew.ticket.mentionedPerson') : i18nService.getLocalizedString('createNew.ticket.mentionedPersons'); var persons = []; _.forEach(mentionedPersons, function (mentionedPerson) { persons.push(mentionedPerson.displayName); }); $scope.basicData.desc += ' ' + persons.join(', ') + ' ' + mentionedText; } _.forEach($scope.basicData.questionDefinitions, function (question) { if ($scope.basicData.questionResponses) { // if there are questionResponses return, this is a request again draft // needs to pre-populate answers with the previous response question.prepopulate = true; var questionResponses = $scope.basicData.questionResponses; _.forEach(questionResponses, function (questionResponse) { if (questionResponse.questionId === question.id) { if (question.format === 'CHECK_BOXES') { if (questionResponse.value) { question.answer = questionResponse.value.split(';'); } else { question.answer = []; } } else if (question.format === 'STATIC_MENU' || question.format === 'QUERY_MENU' || question.format === 'RADIO_BUTTONS') { question.answer = questionResponse.value; question.answerLabel = questionResponse.displayValue; } else if (question.format === 'RANGE_CHOICE') { question.answer = parseInt(questionResponse.value, 10); } else { question.answer = questionResponse.value; } return false; } }); if (question.format === 'CHECK_BOXES' && !question.answer) { question.answer = []; } } else { // preset answers with default values, if any if (question.format === 'CHECK_BOXES') { question.answer = []; _.forEach(question.options, function (option) { if (option.isDefault) { question.answer.push(option.value); } }); } else if (question.format === 'STATIC_MENU' || question.format === 'QUERY_MENU' || question.format === 'RADIO_BUTTONS') { _.forEach(question.options, function (option) { if (option.isDefault) { question.answer = option.value; question.answerLabel = option.label; } }); } else { question.answer = question.defaultValue; } } question.parentId = null; question.conditionValues = ''; question.children = []; question.visibility = true; question.validate = false; if (question.format === 'TEXT' && (!question.maxLineCount || question.maxLineCount < 1)) { question.maxLineCount = 1; } if (question.maxLength === 0) { question.maxLength = null; } }); _.each($scope.basicData.conditionalQuestions, function (cMapping) { _.each($scope.basicData.questionDefinitions, function (question) { if (cMapping.questionnaireId === question.questionnaireId) { if (!question.parentId) { question.parentId = cMapping.parentQuestionId; } question.conditionValues += (question.conditionValues.length) ? ';' + cMapping.questionConditionValues : cMapping.questionConditionValues; } }); }); _.each(_.filter($scope.basicData.questionDefinitions, { parentId: null }), function (pQuestion) { pQuestion.level = 0; pQuestion.hasAnswer = answerIsNotEmpty(pQuestion.answer); if (pQuestion.isHidden) { pQuestion.visibility = false; } searchQuestionsTree(pQuestion, pQuestion.id, pQuestion.level); }); sortQuestionsByOrder($scope.basicData.questionDefinitions); ticketTemplateModel.processDynamicQuestions($scope.basicData.requestTemplateId, $scope.basicData.questionDefinitions); } $scope.relationCache = relationModel.cache[$scope.itemId]; $scope.$watchCollection('relationCache', function () { updateRelationCounters(); }, true); // For service request, any previously selected relationship from smart recorder will be disgarded if (!_.isEmpty(smartRecorderModel.smartRecorderData.confirmedResourceList) && $scope.type !== EntityVO.TYPE_SERVICEREQUEST) { if ($scope.type === EntityVO.TYPE_WORKORDER) { // For work order, only keep knowledge resource selected previously from smart recorder _.each(_.filter(smartRecorderModel.smartRecorderData.confirmedResourceList, { type: EntityVO.TYPE_KNOWLEDGE }), function (relation) { relationModel.markRelationForAdd($scope.basicData.id, relation); }); } else { relationModel.markRelationForAdd($scope.basicData.id, smartRecorderModel.smartRecorderData.confirmedResourceList); } } }).finally(function () { $scope.state.dataIsLoading = false; $scope.displayProfileSupportPanel = true; ticketModel.cache[$scope.basicData.id] = angular.copy($scope.basicData); }); //Set a level for questions to enable hide or show question depending on its parent question's answer function searchQuestionsTree(parentQuestion, parentId, level) { level++; _.each(_.filter($scope.basicData.questionDefinitions, { parentId: parentId }), function (question) { question.level = level; parentQuestion.children.push(question); question.visibility = calculateConditionalQuestionVisibility(parentQuestion, question, true); if (matchConditionValues(parentQuestion, question) && parentQuestion.hasAnswer) { question.hasAnswer = answerIsNotEmpty(question.answer); } else { question.hasAnswer = false; } searchQuestionsTree(question, question.id, level); }); } }; function answerIsNotEmpty(answer) { return answer !== null && typeof answer !== 'undefined' && answer !== ''; } function calculateConditionalQuestionVisibility(parentQuestion, question, skipHiddenQuestion) { return (question.isHidden === !skipHiddenQuestion) && matchConditionValues(parentQuestion, question) && !parentQuestion.isHidden && parentQuestion.visibility; } function matchConditionValues(parentQuestion, question) { if (parentQuestion.format === 'RADIO_BUTTONS' || parentQuestion.format === 'STATIC_MENU') { return question.conditionValues === parentQuestion.answer; } else if (parentQuestion.format === 'CHECK_BOXES' && parentQuestion.answer) { return parentQuestion.answer.sort().join(';') === question.conditionValues.split(';').sort().join(';'); } return false; } function sortQuestionsByOrder(questions) { //get all level 0 and sort them var firstLevelQuestions = _.filter(questions, { level: 0 }); firstLevelQuestions.sort(sortByOrder); sortedQuestionDefinitions = sortedQuestionDefinitions.concat(firstLevelQuestions); //get next level for all level 0 and sort them recursively sortSubLevelQuestions(firstLevelQuestions, 0); $scope.basicData.questionDefinitions = sortedQuestionDefinitions; } function sortSubLevelQuestions(currentLevelQuestions, level) { level++; _.each(currentLevelQuestions, function (question) { var nextLevelQuestions = _.filter($scope.basicData.questionDefinitions, { parentId: question.id, level: level }); if (nextLevelQuestions.length) { nextLevelQuestions.sort(sortByOrder); var index = _.findIndex(sortedQuestionDefinitions, { id: question.id }); var splitQuestionsAtIndex = _.slice(sortedQuestionDefinitions, ++index); sortedQuestionDefinitions = _.slice(sortedQuestionDefinitions, 0, index).concat(nextLevelQuestions).concat(splitQuestionsAtIndex); sortSubLevelQuestions(nextLevelQuestions, level); } }); } function sortByOrder(x, y) { var order1 = x.sortOrder; var order2 = y.sortOrder; return ((order1 < order2) ? -1 : ((order1 > order2) ? 1 : 0)); } function updateRelationCounters() { $scope.relationCounters.tasks = relationService.getRelatedTasks($scope.relationCache).length; $scope.relationCounters.linkedItems = relationService.getRelatedLinkedItems($scope.relationCache, $scope.basicData, showAffectedServiceRelation).length; } function postWindowCloseMessageToLiveChat() { // post message to live chat if ($stateParams.isSrcLiveChat === 'true' && $scope.liveChatWindow) { $scope.liveChatWindow.postMessage({ event: events.DRAFT_TICKET_CLOSED }, window.location && window.location.origin); //NOSONAR } } $scope.countInvalidFields = function () { var invalidFields = 0; $scope.formIsValid = true; _.forEach($scope.forms, function (form) { if (form && form.$error.required) { if (form.layoutForm && form.layoutForm.$error.required) { // special handling for Incident invalidFields += form.layoutForm.$error.required.length; } else { invalidFields += form.$error.required.length; } } if (form && !form.$valid) { $scope.formIsValid = false; } }); return invalidFields; }; window.addEventListener('beforeunload', function (event) { if (event) { postWindowCloseMessageToLiveChat(); } }); $scope.initProfile(); var unBindStateChangeSuccess = $scope.$on('$stateChangeSuccess', function (ev, to, toParams, from, fromParams) { prevState.name = from.name; if (fromParams) { prevState.params = fromParams; } }); $scope.$on('$destroy', function () { unBindStateChangeSuccess(); }); }]); })();