1744 lines
104 KiB
JavaScript
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();
|
|
});
|
|
}]);
|
|
})();
|