"use strict"; (function () { 'use strict'; angular.module('changeModule') .controller('CreateChangeV2Controller', ['$scope', '$state', '$http', 'metadataModel', 'userModel', 'createTicketModel', 'feedModel', '$q', 'ticketService', 'ticketTemplateModel', 'systemAlertService', 'ticketModel', 'localStorageService', 'ticketActionService', 'categoriesService', 'events', 'i18nService', 'screenConfigurationModel', 'fieldValidationModel', '$filter', 'editTicketDatesService', 'tabIds', 'searchModel', 'relationModel', 'configurationModel', 'layoutConfigurationModel', 'objectValueMapperService', '$log', '$timeout', function ($scope, $state, $http, metadataModel, userModel, createTicketModel, feedModel, $q, ticketService, ticketTemplateModel, systemAlertService, ticketModel, localStorageService, ticketActionService, categoriesService, events, i18nService, screenConfigurationModel, fieldValidationModel, $filter, editTicketDatesService, tabIds, searchModel, relationModel, configurationModel, layoutConfigurationModel, objectValueMapperService, $log, $timeout) { //Purpose of riskSectionValid field is to disable the submit button when Risk questions are loading. var riskSectionValid = true; if (!configurationModel.isServerApplicationEnabled(EntityVO.TYPE_CHANGE)) { $state.go('unauthorized'); return; } $scope.data = {}; $scope.linkedCount = 0; $scope.showNoRelatedCIWarning = false; $scope.tabIds = tabIds; $scope.draftTicket = { type: EntityVO.TYPE_CHANGE }; $scope.changeReasonRequired = false; $scope.isNoteRequired = false; $scope.isRelatedCR = !_.isEmpty(ticketModel.cache.relatedDraft); $scope.relatedDraftInfo = $scope.isRelatedCR ? ticketModel.cache.relatedDraft : null; $scope.loggedInUserId = userModel.userId; if ($scope.isRelatedCR) { delete ticketModel.cache.relatedDraft; } $scope.data.searches = []; $scope.selections = { companies: [] }; $scope.siteOptions = { company: { visible: false, attribute: 'companyName' }, region: { attribute: 'region' }, siteGroup: { attribute: 'siteGroup' }, site: { attribute: 'name' } }; var linkedCIs, previousTab, stateChangeStartUnsubscribe, riskRulesConfigured, riskLevelForChangeReason, riskLevelForNote, riskLevelList = []; function reset() { $scope.selectedMainTab = $scope.tabIds.main.template; $scope.state.selectedWizardTab = $scope.tabIds.wizard.basics; previousTab = null; $scope.data.searches = []; $scope.draftTicket.needsReloadingRiskQuestions = true; $scope.linkedCount = 0; $scope.template = { search: '', list: [], selected: {}, showSearchResults: false, preview: null }; $scope.datePickerOptions = { startingDay: 7, 'show-weeks': false, minDate: moment().year(1970).month(0).date(2), maxDate: moment().year(2038).month(0).date(18) }; $scope.draftCreated = false; $scope.draftTicket = { type: EntityVO.TYPE_CHANGE, scheduledStartDatePicker: { open: false }, scheduledEndDatePicker: { open: false }, actualStartDatePicker: { open: false }, actualEndDatePicker: { open: false }, targetDatePicker: { open: false }, customFields: {}, needsReloadingRiskQuestions: true }; defaultRequestedFor(userModel.userFullData); $state.go('createChange.selector'); } function init() { $scope.state = { dataIsLoading: true, templatesLoading: false, tooManyCompanies: false, lastUsedTemplatesLoading: true, savingCIs: false }; $scope.editMode = true; $scope.isNew = true; objectValueMapperService.clearMap(EntityVO.TYPE_CHANGE); initAlertForDirtyForm(); var storedTemplates = localStorageService.get('change.lastUsedTemplates'); $scope.lastUsedTemplates = storedTemplates ? storedTemplates : []; $scope.changeMetadata = {}; var metadataPromise = metadataModel.getMetadataByType(EntityVO.TYPE_CHANGE).then(function (metadata) { $scope.type = metadata.metadatatype; angular.extend($scope.changeMetadata, metadata); if (!$scope.changeMetadata.documentTypes || $scope.changeMetadata.documentTypes && $scope.changeMetadata.documentTypes.length === 0) { $http.get('mocks/change-request-metadata-document-types.json') .then(function (data) { $scope.changeMetadata.documentTypes = data.documentTypes; }); } }); var userPromise = userModel.getFullCurrentUserData().then(function () { searchModel.getOperatingCompanies(null, -1).then(function (response) { $scope.selections.companies = _.cloneDeep(response.companies); $scope.state.tooManyCompanies = response.exceedsChunkSize; }); }); var layoutConfigurationPromise = layoutConfigurationModel.loadScreenLayout(ScreenConfigurationVO.prototype.CREATE_CHANGE_SCREEN); // TODO[Alex H] - change screen name to create change screen, when it will be available. Keeping old screen name just to ensure create works var customFieldLabelsPromise = screenConfigurationModel .loadScreenConfigurationAndCustomFieldLabels(ScreenConfigurationVO.prototype.CREATE_CHANGE_SCREEN, EntityVO.TYPE_CHANGE); $q.all([metadataPromise, userPromise, layoutConfigurationPromise, customFieldLabelsPromise]).then(function (responses) { $scope.state.dataIsLoading = false; $scope.screenLayout = responses[2]; var fields = screenConfigurationModel.getEditableFieldsForScreen(ScreenConfigurationVO.prototype.CHANGE_REQUEST_SCREEN); var customFields = angular.copy(fields); $scope.basicsCustomFields = _.filter(customFields, { panelId: ScreenConfigurationVO.prototype.CHANGE_REQUEST_SCREEN + '.basics' }); $scope.datesCustomFields = _.filter($scope.screenLayout.panels, { name: 'datesSection' }); $scope.risksCustomFields = _.filter($scope.screenLayout.panels, { name: 'riskSection' }); $scope.showMailstopOnPersoncard = configurationModel.showMailstopOnPersoncard; $scope.showPhoneNumOnPersonCard = configurationModel.showPhoneNumOnPersonCard; reset(); }); } function getlastUsedTemplates(company) { $scope.state.lastUsedTemplatesLoading = true; $scope.currentRecentlyUsedTemplates = []; var templates = _.filter($scope.lastUsedTemplates, { forCompany: company }); if (templates.length) { ticketModel.getRecentlyUsedChangeTemplates(templates, $scope.changeMetadata).then(function (newTemplates) { $scope.state.lastUsedTemplatesLoading = false; if (newTemplates) { $scope.currentRecentlyUsedTemplates = newTemplates; } }).catch(function () { $scope.state.lastUsedTemplatesLoading = false; }); } else { $scope.state.lastUsedTemplatesLoading = false; } } function defaultRequestedFor(userdata) { $scope.draftTicket.customer = new PersonVO().build(userdata); $scope.setCompany(userdata.company); $scope.setLocation(userdata.site); } $scope.setCoordinator = function (coordinator) { $scope.draftTicket.assignee = coordinator; }; $scope.setCompany = function (company) { $scope.draftTicket.company = company; if (company.name !== $scope.draftTicket.customer.company.name) { $scope.setLocation({}); } getlastUsedTemplates(company.name); }; $scope.getCompaniesByName = function (name) { return searchModel.getCompaniesByText(name).then(function (response) { return { list: response.companies, exceedsChunkSize: response.exceedsChunkSize }; }); }; $scope.clearRequestedFor = function () { $scope.draftTicket.customer = null; }; $scope.validateRequestedFor = function () { if ($scope.draftTicket.customer && !$scope.draftTicket.customer.id) { $scope.draftTicket.customer = ''; } $scope.state.searchingPersons = false; }; $scope.setChangeLocation = function () { $scope.focusElement = false; return systemAlertService.modal({ title: i18nService.getLocalizedString('create.change.setRequestedForLocation.title'), text: i18nService.getLocalizedString('create.change.setRequestedForLocation.text'), buttons: [ { text: i18nService.getLocalizedString('common.button.yes'), data: true }, { text: i18nService.getLocalizedString('common.button.no'), data: false } ] }).result.then(function (data) { if (data) { $scope.setCompany($scope.draftTicket.customer.company); } $scope.focusElement = true; }); }; $scope.setCoordinatorGroup = function (coordinatorGroup) { $scope.draftTicket.supportGroup = coordinatorGroup; }; $scope.updateCoordinatorGroupCompany = function (coordinatoGroupCompany) { $scope.draftTicket.assignee.company = coordinatoGroupCompany; }; $scope.setLocation = function (location) { $scope.draftTicket.location = location; }; $scope.selectMainTab = function (tab) { $scope.selectedMainTab = tab; }; $scope.getList = function (type, term) { return createTicketModel.getList(type, term); }; $scope.getTemplateList = function (query) { return ticketTemplateModel.getChangeTemplateList(query, $scope.draftTicket.company.name, $scope.changeMetadata).then(function (data) { $scope.state.exceedsChunkSizeTemplates = data.exceedsChunkSize; $scope.state.isTooltipOpenTemplates = data.exceedsChunkSize; $timeout(function () { $scope.state.isTooltipOpenTemplates = false; }, 10000); return _.uniq(_.map(data.items, 'name')); }); }; $scope.getListPersons = function (type, term) { $scope.state.searchingPersons = true; return createTicketModel.getList(type, term).then(function (response) { $scope.exceedsChunkSizeRequestedFor = response.exceedsChunkSize; $scope.isTooltipOpenRequestedFor = true; $timeout(function () { $scope.isTooltipOpenRequestedFor = false; }, 10000); $scope.state.searchingPersons = false; return response.items; }); }; $scope.onInputFocusBlur = function () { $scope.isTooltipOpenRequestedFor = false; $scope.state.isTooltipOpenTemplates = false; $scope.isTooltipOpenPerson = false; }; $scope.getListPersonsByCompany = function (term) { $scope.state.searchingPersons = true; return createTicketModel.getPersonsByCompany(term, $scope.draftTicket.company.name).then(function (response) { $scope.exceedsChunkSizePerson = response.exceedsChunkSize; $scope.isTooltipOpenPerson = true; $timeout(function () { $scope.isTooltipOpenPerson = false; }, 10000); $scope.state.searchingPersons = false; return response.items; }); }; $scope.clearImpactedService = function () { $scope.draftTicket.impactedService = ''; }; $scope.updateTiming = function () { if ($scope.useTargetDateDisabled()) { $scope.draftTicket.useTargetDate = false; clearDates(); } }; $scope.getNextStepAriaLabel = function () { var ariaLabel = $filter('i18n')('create.change.wizard.nextStep'); switch ($scope.state.selectedWizardTab) { case 'basics': ariaLabel += ' ' + $filter('i18n')('create.change.wizard.tabs.ci'); break; case 'ci': ariaLabel += ' ' + $filter('i18n')('create.change.wizard.tabs.dates'); break; case 'dates': ariaLabel += ' ' + $filter('i18n')('create.change.wizard.tabs.risks'); break; case 'risks': ariaLabel += ' ' + $filter('i18n')('create.change.wizard.tabs.documents'); break; } return ariaLabel; }; function clearDates() { if ($scope.draftTicket.useTargetDate) { $scope.draftTicket.scheduledStartDate = null; $scope.draftTicket.scheduledEndDate = null; $scope.draftTicket.actualStartDate = null; $scope.draftTicket.actualEndDate = null; } else { $scope.draftTicket.targetDate = null; } } $scope.$watch('draftTicket.timing', function () { if ($scope.draftTicket && $scope.draftTicket.timing) { $scope.draftTicket.scheduledStartDate = $scope.isFieldDisabled('scheduledStartDate') ? null : $scope.draftTicket.scheduledStartDate; $scope.draftTicket.scheduledEndDate = $scope.isFieldDisabled('scheduledEndDate') ? null : $scope.draftTicket.scheduledEndDate; } }); $scope.useTargetDateDisabled = function () { return $scope.draftTicket.timing && ($scope.draftTicket.timing.name === 'Emergency' || $scope.draftTicket.timing.name === 'Latent' || $scope.draftTicket.timing.name === 'No Impact'); }; $scope.updatePriority = function (dataLoadingStatus) { $scope.state.dataIsLoading = true; ticketModel.getChangePriority($scope.draftTicket.company.name, $scope.draftTicket.impact, $scope.draftTicket.urgency).then(function (data) { if (!_.isEmpty(data)) { $scope.draftTicket.priority = _.find($scope.changeMetadata.priorities, { name: data }); $scope.priorityValid = true; } else { $scope.draftTicket.priority = ''; systemAlertService.error({ text: $filter('i18n')('create.change.wizard.basicDetails.priority.warning'), hide: 10000 }); $scope.priorityValid = false; } if (!dataLoadingStatus) { $scope.state.dataIsLoading = false; } }, function (errorData) { systemAlertService.warning({ text: errorData.error, hide: 10000 }); $scope.priorityValid = false; $scope.state.dataIsLoading = false; }); }; $scope.validatePriority = function () { if (!_.isEmpty($scope.draftTicket.priority)) { $scope.priorityValid = true; } }; $scope.nextStep = function () { var takeNext = false; _.forOwn($scope.tabIds.wizard, function (value, tabId) { if (takeNext) { takeNext = false; $scope.state.selectedWizardTab = tabId; return; } if (value === $scope.state.selectedWizardTab) { if ($scope.state.selectedWizardTab === 'ci') { if ($scope.showNoRelatedCIWarning === true && $scope.linkedCount === 0) { systemAlertService.warning({ text: $filter('i18n')('create.change.wizard.ci.warning.part'), hide: 10000 }); takeNext = false; $scope.showNoRelatedCIWarning = false; } else { takeNext = true; } } else { takeNext = true; } } }); }; $scope.changeWizardValid = function () { return $scope.invalidFormCount() === 0 && $scope.priorityValid && riskSectionValid; }; $scope.isDocumentTab = function () { return $scope.state.selectedWizardTab === $scope.tabIds.wizard.documents; }; $scope.invalidFormCount = function () { var count = 0; _.forOwn($scope.tabIds.wizard, function (value, tabId) { if (!$scope.formValid(tabId)) { count++; } }); return count; }; $scope.changeWizardDirty = function () { return $scope.dirtyFormCount() !== 0 || !_.isEmpty($scope.draftTicket.documents) || $scope.linkedCount !== 0; }; $scope.dirtyFormCount = function () { var count = 0; for (var tabId in $scope.tabIds.wizard) { if ($scope.formDirty(tabId)) { count++; } } return count; }; $scope.setChangeWizardPristine = function () { for (var tabId in $scope.tabIds.wizard) { if ($scope[tabId]) { $scope[tabId].$setPristine(); } } }; $scope.formValid = function (tabId) { return $scope[tabId] ? !$scope[tabId].$invalid : true; }; $scope.formDirty = function (tabId) { return $scope[tabId] ? $scope[tabId].$dirty : false; }; $scope.$on(events.CHANGE_WIZARD_FORM_STATE, function (event, form) { $scope[form.name] = $scope[form.name] || {}; if (typeof form.invalid !== 'undefined') { $scope[form.name].$invalid = form.invalid; } if (typeof form.dirty !== 'undefined') { $scope[form.name].$dirty = form.dirty; } }); $scope.getRecommendedTemplates = function () { if (_.isEmpty($scope.template.search)) { return; } $scope.state.templatesLoading = true; ticketTemplateModel.getChangeTemplateList($scope.template.search, $scope.draftTicket.company.name, $scope.changeMetadata).then(function (data) { $scope.template.list = data.items; }).finally(function () { $scope.state.templatesLoading = false; $scope.template.showSearchResults = true; }); }; $scope.handleKeyDown = function ($event, item) { if ($event.keyCode === 32) { // space key if ($scope.template.selected.id === item.id) { $scope.template.selected = ''; } else { $scope.template.selected = item; } $event.stopPropagation(); } }; $scope.createDraftChange = function () { $scope.state.dataIsLoading = true; getDraftPromise($scope.template.selected.id).then(function (response) { $scope.draftCreated = true; $scope.template.selected.forCompany = $scope.draftTicket.company.name; addToLastUsedTemplates($scope.template.selected); response.customer = $scope.draftTicket.customer; objectifyDraftTicket(response, true, true); //get related CI's if any attached to the template relationModel.getRelations(response.id, response.type, response.displayId).finally(function () { $scope.state.dataIsLoading = false; goToWizard(); }); }); }; $scope.createDraftChangeForClass = function (type) { $scope.state.dataIsLoading = true; getDraftPromise().then(function (response) { $scope.state.dataIsLoading = false; $scope.draftCreated = true; $scope.draftTicket.timing = type; objectifyDraftTicket(response, false); goToWizard(); }); }; function goToWizard() { $state.go('createChange.wizard'); _.forEach($scope.changeMetadata.riskLevels, function (riskLevelObj) { riskLevelList.push(riskLevelObj.name); }); ticketModel.getChangeRiskRules($scope.draftTicket.company && $scope.draftTicket.company.name).then(function (data) { if (data && data.workNoteRequiredForRisk) { riskRulesConfigured = true; riskLevelForNote = _.takeRight(riskLevelList, riskLevelList.length - riskLevelList.indexOf(data.workNoteRequiredForRisk)); } if (data && data.changeReasonRequiredForRisk) { riskRulesConfigured = true; riskLevelForChangeReason = _.takeRight(riskLevelList, riskLevelList.length - riskLevelList.indexOf(data.changeReasonRequiredForRisk)); } if ($scope.draftTicket.riskLevel) { riskRulesConfigured && checkNoteRequired({ fieldName: EntityVO.FIELD_CHANGE_RISK, fieldValue: $scope.draftTicket.riskLevel }); riskRulesConfigured && changeReasonRequired({ fieldName: EntityVO.FIELD_CHANGE_RISK, fieldValue: $scope.draftTicket.riskLevel }); } }); } function changeReasonRequired(data) { $scope.changeReasonRequired = false; if (riskLevelForChangeReason) { _.forEach(riskLevelForChangeReason, function (riskLevel) { if (riskLevel === data.fieldValue) { $scope.changeReasonRequired = true; } }); } } function checkNoteRequired(data) { $scope.isNoteRequired = false; if (riskLevelForNote) { _.forEach(riskLevelForNote, function (riskLevel) { if (riskLevel === data.fieldValue) { $scope.isNoteRequired = true; } }); } } function getDraftPromise(templateId) { if ($scope.isRelatedCR) { if ($scope.relatedDraftInfo.fromType === EntityVO.TYPE_ASSET) { return ticketService.getRelatedDraftFromAsset($scope.relatedDraftInfo.type, $scope.relatedDraftInfo.fromContext, templateId); } return ticketService.getDraftForRelated($scope.relatedDraftInfo.type, $scope.relatedDraftInfo.fromType, $scope.relatedDraftInfo.id, templateId); } else { return ticketService.getDraft(EntityVO.TYPE_CHANGE, templateId); } } function getLocationAsPerCompanySet() { if ($scope.draftTicket.customer && $scope.draftTicket.company.name === $scope.draftTicket.customer.company.name) { return $scope.draftTicket.customer.site; } else if ($scope.draftTicket.company.name === userModel.userFullData.company.name) { return userModel.userFullData.company.site; } else { return {}; } } function objectifyDraftTicket(response, useTemplate, dataLoadingStatus) { if (useTemplate) { if (response.company.name === $scope.draftTicket.company.name && !(_.isEmpty(response.location))) { $scope.draftTicket.location = response.location; } if (!(_.isEmpty($scope.template.selected.templateObject.changeType))) { $scope.draftTicket.changeType = $scope.template.selected.templateObject.changeType; } response.company = $scope.draftTicket.company; $scope.draftTicket = angular.extend($scope.draftTicket, response); if (!$scope.relatedDraftInfo) { $scope.relatedDraftInfo = { fromContext: {} }; } else if (!$scope.relatedDraftInfo.fromContext) { $scope.relatedDraftInfo.fromContext = {}; } $scope.draftTicket.desc = $scope.isRelatedCR ? ($scope.relatedDraftInfo.fromContext.desc && $scope.template.selected.desc ? $scope.template.selected.desc + ' ' + $scope.relatedDraftInfo.fromContext.desc : $scope.template.selected.desc || $scope.relatedDraftInfo.fromContext.desc) : $scope.template.selected.desc; if ($scope.isRelatedCR && !$scope.draftTicket.summary) { $scope.draftTicket.summary = $scope.template.selected.summary || $scope.relatedDraftInfo.fromContext.summary; } } else { $scope.draftTicket = angular.extend(response, $scope.draftTicket); response.location = getLocationAsPerCompanySet(); if (!$scope.draftTicket.customer && ($scope.draftTicket.company && $scope.draftTicket.company.name)) { $scope.draftTicket.customFields.company = $scope.draftTicket.company.name; } } if ($scope.draftTicket.impactedService && !$scope.draftTicket.impactedService.name) { $scope.draftTicket.impactedService = null; } createTicketModel.currentTicket = $scope.draftTicket; //SW00524973 fix for htis $scope.draftTicket.impact = $scope.draftTicket.impact ? _.head(_.filter($scope.changeMetadata.impacts, { name: $scope.draftTicket.impact.name || $scope.draftTicket.impact })).name : _.last($scope.changeMetadata.impacts).name; $scope.draftTicket.urgency = $scope.draftTicket.urgency ? _.head(_.filter($scope.changeMetadata.urgencies, { name: $scope.draftTicket.urgency.name || $scope.draftTicket.urgency })).name : _.last($scope.changeMetadata.urgencies).name; $scope.draftTicket.timing = $scope.draftTicket.timing ? _.head(_.filter($scope.changeMetadata.timings, { name: $scope.draftTicket.timing.name || $scope.draftTicket.timing })) : _.last($scope.changeMetadata.timings); if ($scope.draftTicket.timing && $scope.draftTicket.timing.timingReasons) { //should be set only if applicable for that timing $scope.draftTicket.timingReason = $scope.draftTicket.timingReason ? _.head(_.filter($scope.changeMetadata.timingReasons, { name: $scope.draftTicket.timingReason.name || $scope.draftTicket.timingReason })) : ''; $scope.draftTicket.timingReason = $scope.draftTicket.timingReason ? $scope.draftTicket.timingReason.name : $scope.draftTicket.timingReason; } if ($scope.draftTicket.riskLevel) { $scope.draftTicket.riskLevelSelectionMode = 'manual'; } else { $scope.draftTicket.riskLevelSelectionMode = 'auto'; } if ($scope.draftTicket.supportGroup && $scope.draftTicket.supportGroup.company && $scope.draftTicket.supportGroup.company.name) { var coordinatorCompany = $scope.draftTicket.supportGroup.company; if ($scope.draftTicket.assignee && $scope.draftTicket.assignee.company.name != coordinatorCompany.name) { /* DRSMX - 84241: Expressions do not work on assignment field when change coordinator company and logged in user 's company are different Fix: Update Coordinator Group Company from the Coordinator support group */ $scope.updateCoordinatorGroupCompany(coordinatorCompany); } } initPriority(dataLoadingStatus); //TODO: Should retrieve plans from metadata $scope.draftTicket.documents = []; $scope.draftTicket.allCategories = _.cloneDeep(categoriesService.populateCategories($scope.draftTicket.categorizations, $scope.changeMetadata)); if ($scope.draftTicket.location) { $scope.draftTicket.location.companyName = $scope.draftTicket.company.name; } } function initPriority(dataLoadingStatus) { if ($scope.draftTicket.priority) { $scope.draftTicket.priority = _.head(_.filter($scope.changeMetadata.priorities, { name: $scope.draftTicket.priority.name || $scope.draftTicket.priority })); $scope.priorityValid = true; } else { var lowestImpact = _.last($scope.changeMetadata.impacts); var lowestUrgency = _.last($scope.changeMetadata.urgencies); if ($scope.draftTicket.impact === lowestImpact.name && $scope.draftTicket.urgency === lowestUrgency.name) { $scope.draftTicket.priority = _.last($scope.changeMetadata.priorities).name; $scope.priorityValid = true; } else { if ($scope.isRelatedCR) { $scope.draftTicket.isRelatedCR = $scope.isRelatedCR; } $scope.updatePriority(dataLoadingStatus); } } } function addToLastUsedTemplates(template) { $scope.lastUsedTemplates.unshift(template); $scope.lastUsedTemplates = _.uniqBy($scope.lastUsedTemplates, function (item) { return item.id; }).splice(0, 50); localStorageService.set('change.lastUsedTemplates', $scope.lastUsedTemplates); } function hasUnlinkedCIs() { for (var i = 0; i < $scope.data.searches.length; i++) { if ($scope.data.searches[i].selectedCount > 0 && !$scope.data.searches[i].linked) { return true; } } return false; } $scope.createChangeRequest = function () { if (hasUnlinkedCIs()) { return systemAlertService.modal({ type: 'info', title: i18nService.getLocalizedString('create.change.wizard.header'), text: i18nService.getLocalizedString('create.change.wizard.ci.relateCIMessage'), buttons: [ { text: i18nService.getLocalizedString('common.button.continue'), data: true }, { text: i18nService.getLocalizedString('common.button.cancel'), data: false } ] }).result.then(function (data) { if (data) { startChangeCreate(); } }); } else { startChangeCreate(); } }; function startChangeCreate() { linkedCIs = getLinkedCIs(); if (linkedCIs.bulkCIsLinked.length > 0 || $scope.linkedCount >= 80) { return systemAlertService.modal({ type: 'info', title: i18nService.getLocalizedString('create.change.wizard.ci.confirmCIRelation.title'), text: i18nService.getLocalizedString('create.change.wizard.ci.confirmCIRelation.text'), buttons: [ { text: i18nService.getLocalizedString('common.button.continue'), data: true }, { text: i18nService.getLocalizedString('common.button.returnToScreen'), data: false } ] }).result.then(function (data) { if (data) { if (searchModel.disableImpactAnalysis || !(createTicketModel.currentTicket.accessMappings && createTicketModel.currentTicket.accessMappings.impactEditAllowed) || (linkedCIs.bulkCIsLinked.length === 0 && $scope.linkedCount === 0 && !$scope.draftTicket.impactedService)) { proceedWithCreateChange(); } else if (!searchModel.disableImpactAnalysis && createTicketModel.currentTicket.accessMappings && createTicketModel.currentTicket.accessMappings.impactEditAllowed && (linkedCIs.bulkCIsLinked.length > 0 || $scope.linkedCount > 0 || $scope.draftTicket.impactedService)) { showImpactAnalysisModal(); } } }); } else { if (searchModel.disableImpactAnalysis || !(createTicketModel.currentTicket.accessMappings && createTicketModel.currentTicket.accessMappings.impactEditAllowed) || (linkedCIs.bulkCIsLinked.length === 0 && $scope.linkedCount === 0 && !$scope.draftTicket.impactedService && !($scope.data.templateRelatedCIsData && $scope.data.templateRelatedCIsData.length > 0))) { proceedWithCreateChange(); } else if (!searchModel.disableImpactAnalysis && createTicketModel.currentTicket.accessMappings && createTicketModel.currentTicket.accessMappings.impactEditAllowed && (linkedCIs.bulkCIsLinked.length > 0 || $scope.linkedCount > 0 || $scope.draftTicket.impactedService || ($scope.data.templateRelatedCIsData && $scope.data.templateRelatedCIsData.length > 0))) { showImpactAnalysisModal(); } } } 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(function (data) { proceedWithCreateChange(data); }); } function proceedWithCreateChange(impactAnalysisFlag) { $scope.$broadcast(events.SAVE_TICKET_DRAFT); $scope.state.savingCIs = true; var timingField = objectValueMapperService.getFieldByName('timing'); if (timingField && timingField.value && timingField.value.name) { objectValueMapperService.setValueByFieldName('timing', timingField.value.name); } var changeData = createTicketModel.collectTicketChanges($scope.changeMetadata); if (changeData.summary) { changeData.summary = changeData.summary.replace(/\u00a0/g, ' '); } if (!(changeData.customer instanceof Object)) { changeData.customer = { fullName: changeData.customer }; } if ((changeData.riskLevel instanceof Object)) { changeData.riskLevel = changeData.riskLevel.name; } createTicketModel.currentTicket.questionResponses = changeData.questionResponses ? changeData.questionResponses : ''; delete changeData.questionDefinitions; delete changeData.questionResponses; changeData.changeType = $scope.draftTicket.changeType; changeData.scheduledStartDate = $scope.draftTicket.scheduledStartDate && $scope.draftTicket.scheduledStartDate.valueOf() || changeData.scheduledStartDate; changeData.scheduledEndDate = $scope.draftTicket.scheduledEndDate && $scope.draftTicket.scheduledEndDate.valueOf() || changeData.scheduledEndDate; changeData.actualStartDate = $scope.draftTicket.actualStartDate && $scope.draftTicket.actualStartDate.valueOf() || changeData.actualStartDate; changeData.actualEndDate = $scope.draftTicket.actualEndDate && $scope.draftTicket.actualEndDate.valueOf() || changeData.actualEndDate; changeData.targetDate = $scope.draftTicket.targetDate && $scope.draftTicket.targetDate.valueOf() || changeData.targetDate; if ($scope.draftTicket.templateId) { changeData.templateId = $scope.draftTicket.templateId; changeData.leadTime = $scope.draftTicket.leadTime; } if (feedModel.pendingWorkNote) { var workInfo = {}; workInfo.worknote = feedModel.pendingWorkNote.noteText; workInfo.access = feedModel.pendingWorkNote.access; workInfo.workInfoType = feedModel.pendingWorkNote.workInfoType; changeData.workInfo = workInfo; if (feedModel.pendingWorkNote.attachments && feedModel.pendingWorkNote.attachments.length) { changeData.attachments = feedModel.pendingWorkNote.attachments; } } createTicketModel.createChangeRequestV2(changeData) .then(function (change) { var promisesList = []; //Remove already set impacted area (Location is set as impacted area by backend during create) var savedImpactedArea = change.impactedAreas.length > 0 ? formatImpactedArea(change.impactedAreas[0]) : null; if (savedImpactedArea !== null) { _.remove(createTicketModel.currentTicket.impactedAreas, function (currentArea) { var formattedCurrentArea = formatImpactedArea(currentArea); return formattedCurrentArea === savedImpactedArea; }); } promisesList.push(createTicketModel.saveImpactedAreas(createTicketModel.currentTicket.id, EntityVO.TYPE_CHANGE, createTicketModel.currentTicket.impactedAreas)); if (!changeData.riskIsUserSpecified) { promisesList.push(createTicketModel.saveRiskResponse(createTicketModel.currentTicket)); } promisesList.push(createTicketModel.saveDocuments(createTicketModel.currentTicket)); promisesList = _.flatten(promisesList); if ($scope.isRelatedCR) { //create 'Created By' relationship if created from another(source) ticket var relateItem = { id: $scope.relatedDraftInfo.id, relationshipType: $scope.relatedDraftInfo.relationship ? $scope.relatedDraftInfo.relationship : RelationItemVO.TYPE_CREATEDBY, tag: RelationItemVO.TAG_LINKEDITEM, type: $scope.relatedDraftInfo.fromType, desc: $scope.relatedDraftInfo.fromContext.summary //source ticket summary }; if (relateItem.type === EntityVO.TYPE_RELEASE) { //var sequence = 1; relateItem.milestone = $scope.relatedDraftInfo.fromContext.milestone; // if($scope.relatedDraftInfo.fromContext.noOfRelatedItems[$scope.relatedDraftInfo.fromContext.milestone.name]) { // sequence = $scope.relatedDraftInfo.fromContext.noOfRelatedItems[$scope.relatedDraftInfo.fromContext.milestone.name]+1; // } //relateItem.details = { sequence : sequence}; relateItem.details = { sequence: $scope.relatedDraftInfo.sequence }; relateItem.tag = RelationItemVO.TAG_LINKEDITEM; relateItem.relationshipType = RelationItemVO.TYPE_MEMBEROF; relateItem.desc = $scope.relatedDraftInfo.fromContext.desc; relateItem.displayId = $scope.relatedDraftInfo.fromContext.displayId; relateItem.parentDisplayId = change.displayId; } linkedCIs.linkedItems.push(relateItem); } if (linkedCIs.linkedItems.length || $scope.data.templateRelatedCIsData.length) { _.forEach($scope.data.templateRelatedCIsData, function (item) { var obj = {}; obj.id = item.reconciliationId; obj.desc = item.desc; obj.relationshipType = item.relationshipType; obj.tag = item.tag; obj.type = item.ticketType; linkedCIs.linkedItems.push(obj); }); var promise = relationModel.addRelation({ uuid: change.id, type: EntityVO.TYPE_CHANGE }, linkedCIs.linkedItems); promisesList.push(promise); } if (linkedCIs.bulkCIsLinked.length > 0) { _.forEach(linkedCIs.bulkCIsLinked, function (relationInfo) { var ticket = { id: change.id, type: EntityVO.TYPE_CHANGE }; if (relationInfo.matchesCount > 100) { var searchCriteria = relationInfo.searchCriteria; searchCriteria.chunkInfo = { startIndex: 0, chunkSize: 50 }; var bulkRelatePromise = relationModel.relateBulkCI(ticket, relationInfo, searchCriteria) .then(function () { return onBulkRequestComplete(ticket, relationInfo); }); promisesList.push(bulkRelatePromise); } }); } if (stateChangeStartUnsubscribe) { stateChangeStartUnsubscribe(); } if (promisesList.length > 0) { $q.all(promisesList).catch(function (error) { if (error) { systemAlertService.error({ text: (error.data && error.data.error) || error, clear: true, displayOnStateChange: true }); } }).finally(function () { createTicketModel.onChangeCreateSuccess(change, impactAnalysisFlag); delete relationModel.cache[change.id]; $state.go(EntityVO.TYPE_CHANGE, { id: change.id }); }); } else { createTicketModel.onChangeCreateSuccess(change, impactAnalysisFlag); delete relationModel.cache[change.id]; $state.go(EntityVO.TYPE_CHANGE, { id: change.id }); } if (!_.isEmpty(ticketModel.cache.draft)) { delete ticketModel.cache.draft; } }) .catch(function (error) { $scope.state.savingCIs = false; error = error.data.detailMessage || error.data.error || error; systemAlertService.error({ text: error, clear: true }); }); } function getLinkedCIs() { var linkedCIs = [], bulkCIsLinked = []; _.forEach($scope.data.searches, function (search) { if (search.allQueryItemsRelation && search.allQueryItemsRelation.length > 0) { bulkCIsLinked = bulkCIsLinked.concat(search.allQueryItemsRelation); } _.forEach(search.results, function (item) { _.forEach(item.relations, function (relation) { if (search.allQueryItemsRelation && search.allQueryItemsRelation.length > 0) { if (_.find(search.allQueryItemsRelation, { relationshipType: relation })) { return; } } linkedCIs.push({ relationshipType: relation, tag: EntityVO.TYPE_LINKEDITEM, id: item.reconciliationId, type: EntityVO.TYPE_ASSET, desc: item.name }); }); }); }); return { linkedItems: linkedCIs, bulkCIsLinked: bulkCIsLinked }; } //Used for creating chain of CI relation requests function onBulkRequestComplete(ticket, relationInfo) { var searchCriteria = relationInfo.searchCriteria; searchCriteria.chunkInfo.startIndex += searchCriteria.chunkInfo.chunkSize; if (relationInfo.matchesCount > searchCriteria.chunkInfo.startIndex) { return relationModel.relateBulkCI(ticket, relationInfo, searchCriteria).then(function () { return onBulkRequestComplete(ticket, relationInfo); }); } else { return $q.when(1); } } $scope.clear = function () { if ($scope.changeWizardDirty()) { $state.go('createChange.selector'); } else { reset(); } }; $scope.$watch('draftTicket.riskLevelSelectionMode', function () { if ($scope.draftTicket.riskLevelSelectionMode === 'manual') { $scope.draftTicket.questionResponses = null; angular.forEach($scope.draftTicket.questionDefinitions, function (question) { question.selectedOption = null; }); } }); $scope.$watch('draftTicket.company', function () { if ($scope.draftTicket.company) { $scope.draftTicket.needsReloadingRiskQuestions = true; $scope.template = { search: '', list: [], selected: {}, showSearchResults: false, preview: null }; } }); $scope.$watch('draftTicket.allCategories', function (collection) { if (collection && categoriesService.isDirtyValues(collection) && !$scope.draftTicket.needsReloadingRiskQuestions) { $scope.draftTicket.needsReloadingRiskQuestions = true; if ($scope.draftTicket.questionDefinitions && $scope.draftTicket.questionResponses) { systemAlertService.warning({ text: $filter('i18n')('create.change.wizard.risks.riskQuestions.reloaded'), hide: 10000 }); } } }, true); $scope.$watch('state.selectedWizardTab', function () { if ($scope.state.selectedWizardTab && $scope.state.selectedWizardTab !== $scope.tabIds.wizard.basics && $scope.draftTicket.needsReloadingRiskQuestions) { $scope.draftTicket.categorizations = categoriesService.collectValues($scope.draftTicket.allCategories, $scope.draftTicket, null, true).categorizations; categoriesService.clearDirtyValues($scope.draftTicket.allCategories); $scope.draftTicket.needsReloadingRiskQuestions = false; $scope.draftTicket.reloadRiskQuestions = true; if (!$scope.draftTicket.riskLevel) { $scope.draftTicket.riskLevelSelectionMode = 'auto'; } } if (previousTab === $scope.tabIds.wizard.ci) { if (hasUnlinkedCIs()) { return systemAlertService.modal({ type: 'info', title: i18nService.getLocalizedString('create.change.wizard.header'), text: i18nService.getLocalizedString('create.change.wizard.ci.relateCIMessage'), buttons: [ { text: i18nService.getLocalizedString('common.button.continue'), data: true }, { text: i18nService.getLocalizedString('common.button.cancel'), data: false } ] }).result.then(function (data) { if (!data) { $scope.state.selectedWizardTab = $scope.tabIds.wizard.ci; } previousTab = null; }); } } if ($state.current.name.indexOf('wizard') !== -1) { var destinationState = "createChange.wizard"; if ($scope.state.selectedWizardTab === $scope.tabIds.wizard.dates) { destinationState += '.calendar.book'; } $state.go(destinationState); } previousTab = $scope.state.selectedWizardTab; }); $scope.isFieldRequired = function (field) { var fieldRequired = false; if ($scope.draftTicket.timing) { fieldRequired = fieldValidationModel.isFieldRequired(EntityVO.TYPE_CHANGE, 'Draft', $scope.draftTicket.timing.name, field); } return fieldRequired; }; $scope.isFieldDisabled = function (field) { var fieldDisabled = false; if ($scope.draftTicket.timing) { fieldDisabled = fieldValidationModel.isFieldDisabled(EntityVO.TYPE_CHANGE, 'Draft', $scope.draftTicket.timing.name, field); } return fieldDisabled; }; function formatImpactedArea(impactedArea) { var formattedImpactedArea = _.filter([ impactedArea.company.name, impactedArea.site ? impactedArea.site.region : null, impactedArea.site ? impactedArea.site.siteGroup : null, impactedArea.site ? impactedArea.site.name : null, impactedArea.organization, impactedArea.department ], function (item) { return item; }).join(' > '); return formattedImpactedArea; } ; function initAlertForDirtyForm() { stateChangeStartUnsubscribe = $scope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) { if (toState.name.indexOf('createChange.wizard') === -1 && $scope.changeWizardDirty()) { event.preventDefault(); if (!$scope.dirtyPopupCount || $scope.dirtyPopupCount === 0) { $scope.dirtyPopupCount = 1; displayDirtyFormAlert(toState, toParams); } } }); } function displayDirtyFormAlert(toState, toParams) { var modalInstance = systemAlertService.modal({ title: i18nService.getLocalizedString('common.notification.dirty.title'), text: i18nService.getLocalizedString('common.notification.dirty.message'), buttons: [ { text: i18nService.getLocalizedString('common.labels.yes'), data: { stateName: toState.name, stateParams: toParams } }, { text: i18nService.getLocalizedString('common.labels.no') } ] }); modalInstance.result.then(function (data) { $scope.dirtyPopupCount = 0; if (!_.isEmpty(data)) { for (var tabId in $scope.tabIds.wizard) { $scope.$broadcast(events.DISCARD_DOCUMENTS); $scope.linkedCount = 0; if ($scope[tabId]) { $scope[tabId].$dirty = false; } } if (data.stateName === 'createChange.selector') { reset(); } else { $state.transitionTo(data.stateName, data.stateParams); } } }); } function calculateTotalRelatedCICount(searches) { _.forEach(searches, function (search) { if (search.results && search.results.length > 0) { var itemsList = search.results; for (var i = 0; i < itemsList.length; i++) { if (itemsList[i].relations && itemsList[i].relations.length > 0) { if (!(search.allQueryItemsRelation && search.allQueryItemsRelation.length > 0)) { $scope.linkedCount++; } } } if (search.allQueryItemsRelation && search.allQueryItemsRelation.length > 0) { $scope.linkedCount += search.totalMatchCount; } } }); return $scope.linkedCount; } $scope.$on(events.LINKED_COUNT, function (e, searches) { $scope.linkedCount = 0; calculateTotalRelatedCICount(searches); }); $scope.$on(events.CI_SEARCH, function (e, searches) { $scope.linkedCount = 0; $scope.showNoRelatedCIWarning = true; calculateTotalRelatedCICount(searches); }); $scope.$watch('linkedCount', function () { $scope.draftTicket.linkedCIs = getLinkedCIs().linkedItems; }); $scope.$watch('draftTicket.impactedService', function () { if ($scope.draftTicket && _.isObject($scope.draftTicket.impactedService)) { $scope.$emit(events.AFFECTED_SERVICE_UPDATED, $scope.draftTicket.impactedService); } }); function handleShownAssignmentBlade($event, data) { var isAssignToMeAction = false, originalEvent = data.originalEvent, doNotSaveSelection = !data.saveSelection; if (data) { var assigneeRole = data.role; if (assigneeRole === 'manager') { assigneeRole = $scope.type + assigneeRole; } else if (assigneeRole === 'assignee') { assigneeRole = $scope.type + 'coordinator'; } isAssignToMeAction = !!data.assignToMe; if (isAssignToMeAction) { ticketActionService.assignToMe(originalEvent, assigneeRole, doNotSaveSelection, $scope.draftTicket, $scope); } else { ticketActionService.assign(originalEvent, doNotSaveSelection, $scope.draftTicket, $scope, assigneeRole); } } else { $log.warn('Could not open assignment blade. Required Event data is missing. '); return; } } $scope.$on(events.SHOW_ASSIGN_TICKET_BLADE, handleShownAssignmentBlade); $scope.$on(events.WIDGET_VALUE_CHANGE, function ($event, data) { if (data.fieldName === EntityVO.FIELD_CHANGE_RISK) { handleRiskLevelChange(data); } if (data.fieldName === EntityVO.FIELD_CHANGE_PRIORITY) { var chngPriorityField = objectValueMapperService.getFieldByName(EntityVO.FIELD_CHANGE_PRIORITY); if (chngPriorityField && chngPriorityField.value && chngPriorityField.value.priority.name) { $scope.priorityValid = true; } } }); $scope.$on(events.CUSTOM_FIELD_VALUE_CHANGE, function () { $scope.$broadcast(events.REFRESH_FIELD_VALUES); }); $scope.$on(events.RISK_QUESTION_LOADED, function () { riskSectionValid = true; handleRiskLevelChange({ workNoteNotRequired: true, changeReasonNotRequired: true }); }); $scope.$on(events.RISK_MODE_MANUAL, function () { riskSectionValid = true; }); $scope.$on(events.RELOAD_RISK_QUESTION, function () { if (objectValueMapperService.getFieldByName(FieldVO.prototype.WIDET_NAMES.changeRisk)) { riskSectionValid = false; } }); $scope.$on(events.FIELD_VALUE_CHANGE, function (event, field) { if (field.name === EntityVO.FIELD_RISK_LEVEL) { handleRiskLevelChange({ fieldName: field.name, fieldValue: field.value }); } }); function handleRiskLevelChange(data) { if (data.changeReasonNotRequired) { $scope.changeReasonRequired = false; } else { riskRulesConfigured && changeReasonRequired(data); } if (data.workNoteNotRequired) { $scope.isNoteRequired = false; } else { riskRulesConfigured && checkNoteRequired(data); } $scope.$broadcast(events.RISK_LEVEL_CHANGE, { isRequired: $scope.changeReasonRequired }); } init(); } ]); })();