SmartIT_Extensions/BMC/smart-it-full-helix/scripts/app/ticket/draft-ticket-controller.js

1744 lines
104 KiB
JavaScript

"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();
});
}]);
})();