1982 lines
125 KiB
JavaScript
1982 lines
125 KiB
JavaScript
"use strict";
|
|
(function () {
|
|
'use strict';
|
|
angular.module('liveChatModule')
|
|
.controller('LiveChatController', ['$scope', '$rootScope', '$sce', 'i18nService', 'localStorageService', 'systemAlertService', '$window',
|
|
'configurationModel', 'authService', 'roles', 'userModel', 'events', 'metadataModel', 'ticketModel', 'relationModel', '$q', '$filter',
|
|
'$state', 'utilityFunctions', 'smartRecorderModel', 'searchService', 'feedModel', 'attachmentService', 'personModel', '$timeout', 'authModel',
|
|
'liveChatService', 'LIVE_CHAT_EVENTS', 'LIVE_CHAT_APP_EVENTS', 'permissionModel', 'knowledgeArticleModel',
|
|
function ($scope, $rootScope, $sce, i18nService, localStorageService, systemAlertService, $window, configurationModel, authService, roles, userModel, events, metadataModel, ticketModel, relationModel, $q, $filter, $state, utilityFunctions, smartRecorderModel, searchService, feedModel, attachmentService, personModel, $timeout, authModel, liveChatService, LIVE_CHAT_EVENTS, LIVE_CHAT_APP_EVENTS, permissionModel, knowledgeArticleModel) {
|
|
$scope.state = {
|
|
loadingLiveChat: true,
|
|
creatingTicket: false,
|
|
appModalEventConfirmWaiting: false
|
|
};
|
|
$scope.isDirtyFlag = true; // this is used to show the dirty message on state change
|
|
var lcDashboardTabId = 'liveChatDashboard';
|
|
var lcAgentConsoleTabId = 'liveChatAgentConsole';
|
|
var lcConsolePendingMsgKey = 'lcConsolePendingMsg'; // used to store the last pending message that Smart IT needs to send to LC, useful when a new tab is launched or on refresh
|
|
var CREATE_TICKET_TIMEOUT = 30000;
|
|
var summaryCharLimit = 100;
|
|
$scope.agentChats = [];
|
|
$scope.chatTicketDataForCreateMap = new Map();
|
|
$scope.createTicketInProgressForChatSessionSet = new Set();
|
|
$scope.hideForDashboard = false;
|
|
$scope.noOfDraftScreensOpen = 0;
|
|
$scope.userid = localStorageService.get('user.userId');
|
|
userModel.getFullCurrentUserData().then(function () {
|
|
$scope.user = userModel.userFullData;
|
|
$scope.context = {
|
|
company: $scope.user && $scope.user.company && $scope.user.company.name,
|
|
customerId: $scope.user.id,
|
|
id: EntityVO.TYPE_LIVE_CHAT,
|
|
type: EntityVO.TYPE_LIVE_CHAT,
|
|
summary: '',
|
|
status: '',
|
|
accessMappings: {
|
|
relationsEditAllowed: false,
|
|
duplicateActionAllowed: true
|
|
}
|
|
};
|
|
});
|
|
$scope.isWOInstalled = configurationModel.isServerApplicationEnabled(EntityVO.TYPE_WORKORDER)
|
|
&& authService.isAuthorized(roles.ITSM_AGENT_ROLE);
|
|
$scope.isIncidentCreateAllowed = true;
|
|
$scope.isWOCreateAllowed = true;
|
|
$scope.filterConfig = configurationModel.get('resource.filter');
|
|
$scope.filterConfigMap = _.keyBy($scope.filterConfig, 'name');
|
|
$scope.$on(events.PERSON_DATA_LOADED, chatCustomerDataLoaded);
|
|
$scope.$on(events.SELECT_TEMPLATE_FROM_RS, saveTemplate);
|
|
$scope.$on(events.UNSELECT_TEMPLATE_FROM_RS, unrelateTemplate);
|
|
$scope.$on(events.SHARE_KNOWLEDGE_TO_LIVE_CHAT, sendMessageToChat);
|
|
$scope.$on(events.SAVE_TO_TICKET_FROM_RS, saveToTicketFromRs);
|
|
$scope.$on(events.REMOVE_FROM_TICKET_FROM_RS, removeFromTicketFromRs);
|
|
$scope.$on(events.SEARCH_TEXT_CHANGED, saveSearchTextToselectedChatContext);
|
|
$scope.$on(events.RELATE_TICKET_TO_CHAT, saveTicketToChat);
|
|
$scope.$on(events.UNRELATE_TICKET_TO_CHAT, removeTicketFromChat);
|
|
$scope.$on(events.TICKET_ASSIGNEES_UPDATED_FROM_BLADE, handleAssignmentComplete);
|
|
function setTab() {
|
|
var customerTabElem = angular.element('#live__agent-customer-tab');
|
|
customerTabElem.find('a').click();
|
|
}
|
|
function sendChildMessage(message) {
|
|
var targetFrame = window.frames.liveChatFrame;
|
|
if (targetFrame !== undefined && targetFrame !== null) {
|
|
targetFrame.postMessage(message, $scope.eschatServerUrl);
|
|
console.log("Message Sent To Frame:" + JSON.stringify(message));
|
|
}
|
|
}
|
|
function uploadAttachmentsToWorkLog(attachments, chatSession) {
|
|
if (chatSession.sessionid === $scope.selectedChat.sessionid) {
|
|
if ($scope.selectedChat.ticket && $scope.selectedChat.ticket.ticketId) {
|
|
processWorkNote($scope.selectedChat.ticket.ticketId, $scope.selectedChat.ticket.ticketType, { text: i18nService.getLocalizedString('live.chat.attachment.worknote'), attachments: attachments });
|
|
}
|
|
}
|
|
else {
|
|
var agentChat = _.findIndex($scope.agentChats, { sid: chatSession.sessionid });
|
|
if ($scope.agentChats[agentChat] && $scope.agentChats[agentChat].selectedChatContext && $scope.agentChats[agentChat].selectedChatContext.ticket) {
|
|
processWorkNote($scope.agentChats[agentChat].selectedChatContext.ticket.ticketId, $scope.agentChats[agentChat].selectedChatContext.ticket.ticketType, { text: i18nService.getLocalizedString('live.chat.attachment.worknote'), attachments: attachments });
|
|
}
|
|
else if (chatSession && chatSession.metadata && chatSession.metadata.ticketid) {
|
|
var ticketInfo_1, params = {
|
|
search_text: chatSession.metadata.ticketid
|
|
}, jsonParams = {
|
|
types: ['tickets']
|
|
};
|
|
searchService.getGlobalSearchResults(params, jsonParams).then(function (response) {
|
|
if (!_.isEmpty(response.items) && response.items[0] && response.items[0].results && response.items[0].results.length) {
|
|
ticketInfo_1 = _.find(response.items[0].results, { displayId: chatSession.metadata.ticketid });
|
|
if (ticketInfo_1) {
|
|
processWorkNote(ticketInfo_1.ticketId, ticketInfo_1.ticketType, { text: i18nService.getLocalizedString('live.chat.attachment.worknote'), attachments: attachments });
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
function handleDraftCreateComplete(ticketData, chatSessionforCreate, relatedTicket) {
|
|
showQuickTicketCreateSuccess(ticketData.type, ticketData, chatSessionforCreate, 'createTicket', relatedTicket);
|
|
if (relatedTicket) {
|
|
//create duplicate relationship between tickets
|
|
var relatedTicketInfo = {};
|
|
relatedTicketInfo.desc = ticketData.summary;
|
|
relatedTicketInfo.displayId = ticketData.displayId;
|
|
relatedTicketInfo.id = relatedTicket.id;
|
|
relatedTicketInfo.parentDisplayId = relatedTicket.displayId;
|
|
relatedTicketInfo.tag = ticketData.type === EntityVO.TYPE_INCIDENT ? EntityVO.TYPE_RESOURCE : EntityVO.TYPE_LINKEDITEM;
|
|
relatedTicketInfo.relationshipType = EntityVO.TYPE_RELATEDTO;
|
|
relatedTicketInfo.type = ticketData.type;
|
|
addRelation(ticketData.id, ticketData.type, [relatedTicketInfo]);
|
|
}
|
|
}
|
|
function prepareDataForTicket(ticketData) {
|
|
//chat data to create a ticket
|
|
var chatLog = [], chatInlineNotes;
|
|
if (ticketData && ticketData.chatLog) {
|
|
//format chat log data for description
|
|
_.forEach(ticketData.chatLog, function (log) {
|
|
var chatLogObj, logText, tempElem = document.createElement('div');
|
|
tempElem.innerHTML = log.TEXT;
|
|
var decodedText = tempElem.innerText;
|
|
logText = decodedText.replace(/(<([^>]+)>)/ig, "");
|
|
chatLogObj = log.NAME + " (" + $filter('date')(log.UTCEPOCHTIMESTAMP, 'short') + "): " + logText + "\n" + "\n";
|
|
chatLog.push(chatLogObj);
|
|
});
|
|
chatLog = chatLog.join(' ');
|
|
chatLog = i18nService.getLocalizedString('live.chat.transcript.worknote') + "\n" + "\n" + chatLog;
|
|
}
|
|
if (ticketData && ticketData.chatNotes) {
|
|
chatInlineNotes = i18nService.getLocalizedString('live.chat.inline.notes.worknote') + "\n" + "\n" + ticketData.chatNotes;
|
|
}
|
|
return { chatLog: chatLog, chatInlineNotes: chatInlineNotes };
|
|
}
|
|
function requestNotificationPermission() {
|
|
var notificationAPISupported = true;
|
|
try {
|
|
if (!window.Notification) {
|
|
console.info("Notification API not supported on this platform");
|
|
notificationAPISupported = false;
|
|
}
|
|
}
|
|
catch (err) {
|
|
notificationAPISupported = false;
|
|
}
|
|
if (notificationAPISupported && window.Notification.permission === 'denied') {
|
|
console.info("Notification API permission denied.");
|
|
notificationAPISupported = false;
|
|
}
|
|
if (notificationAPISupported && window.Notification.permission !== 'granted') {
|
|
// permission is either default or not granted yet
|
|
window.Notification.requestPermission().then(function (permission) {
|
|
var needsPermission = true;
|
|
switch (permission) {
|
|
case 'granted':
|
|
needsPermission = false;
|
|
break;
|
|
case 'denied':
|
|
needsPermission = true;
|
|
break;
|
|
}
|
|
console.info("Notification API permission status= " + window.Notification.permission + ",needsPermission= " + needsPermission);
|
|
});
|
|
}
|
|
return notificationAPISupported;
|
|
}
|
|
var onLocalStorageChange = function ($event) {
|
|
if ($event && $event.key === 'ls.lcConsolePendingMsg') {
|
|
var pendingMsg = localStorageService.get(lcConsolePendingMsgKey);
|
|
if (pendingMsg) {
|
|
localStorageService.remove(lcConsolePendingMsgKey);
|
|
sendChildMessage(pendingMsg);
|
|
}
|
|
}
|
|
};
|
|
var liveChatListener = function (event) {
|
|
if (event && event.origin && !_.includes($scope.eschatServerUrl, event.origin) && !_.includes($scope.smartITURL, event.origin)) {
|
|
console.warn("Url Not allowed. event.origin does not match the eschat server url.\nevent.origin= "
|
|
+ event.origin + ' ,eschatServerUrl = ' + $scope.eschatServerUrl);
|
|
return;
|
|
}
|
|
if (!event || !event.data || !event.data.event ||
|
|
(_.includes($scope.allowedWindowEvents, event.data.event) !== true && _.includes(LIVE_CHAT_EVENTS, event.data.event) !== true)) {
|
|
console.warn("Ignoring. Not a LiveChat event.");
|
|
return;
|
|
}
|
|
if (event.data && event.data.event === LIVE_CHAT_EVENTS.sac_login_completed) {
|
|
$scope.title = window.document.title;
|
|
$scope.state.loadingLiveChat = false;
|
|
$scope.$apply();
|
|
if ($state.current.data.path === 'console') {
|
|
$window.tabId = lcAgentConsoleTabId;
|
|
onLocalStorageChange({ key: 'ls.lcConsolePendingMsg' });
|
|
}
|
|
else if ($state.current.data.path === 'dashboard') {
|
|
$window.tabId = lcDashboardTabId;
|
|
}
|
|
if (localStorageService.get($window.tabId) === "true") {
|
|
console.info('A Live chat tab for ' + $state.current.data.path + ' is already open. We recommend to close this tab');
|
|
}
|
|
else {
|
|
localStorageService.set($window.tabId, "true");
|
|
}
|
|
if (event.data.chatData && event.data.chatData.status !== 'error') {
|
|
requestNotificationPermission();
|
|
}
|
|
if (event.data.chatData && event.data.chatData.ticketConfigSettings) {
|
|
$scope.ticketCreationConfigCompanyMap = JSON.parse(event.data.chatData.ticketConfigSettings) || {};
|
|
}
|
|
}
|
|
else if (event.data && event.data.event === LIVE_CHAT_EVENTS.sac_login_expired) {
|
|
$scope.selectedChat = null;
|
|
$scope.agentChats = [];
|
|
window.location.reload();
|
|
}
|
|
else if (event.data && event.data.event === LIVE_CHAT_EVENTS.sac_launch_live_chat &&
|
|
event.data.chatData) {
|
|
// if the agent console tab is not already opened, then extract the path and open it in a new tab.
|
|
if (localStorageService.get(lcAgentConsoleTabId) !== "true" &&
|
|
event.data.chatData.toState === 'console') {
|
|
var url = $state.href('liveChatAgentConsole');
|
|
$window.open(url, '_blank', 'noopener, noreferrer');
|
|
}
|
|
// this message would be picked up by the agent console, and sent to LC
|
|
// if a new agent console tab has been opened, then this message would be read after successful login
|
|
// if the agent console tab was already open, then setting the value in localStorage would trigger a 'storage' event,
|
|
// which would then be sent to LC
|
|
var message = {
|
|
event: LIVE_CHAT_APP_EVENTS.app_display_chat,
|
|
data: { chatSessionId: event.data.chatData.sessionId }
|
|
};
|
|
localStorageService.set(lcConsolePendingMsgKey, message);
|
|
}
|
|
else if (event.data && event.data.event === LIVE_CHAT_EVENTS.sac_notify_on_change) {
|
|
console.log(event.data);
|
|
if ($scope.title && (event.data.chatData.showNotification === false || $scope.isBrowserTabFocus === true)) {
|
|
window.document.title = $scope.title;
|
|
console.debug('Live Chat sac_notify_on_change event but either notifications are disabled or browser tab is in focus. Ignoring event');
|
|
return;
|
|
}
|
|
var notificationAPISupported = requestNotificationPermission();
|
|
var hasFocus = window.document.hasFocus();
|
|
if ($scope.isBrowserTabFocus === false || hasFocus === false || event.data.chatData.showNotification === 'always') {
|
|
if (notificationAPISupported && Notification.permission === 'granted') {
|
|
var notificationOptions = event.data.chatData.options;
|
|
if (notificationOptions) {
|
|
var notificationTitle = event.data.chatData.notificationTitle || '';
|
|
var timeout = notificationOptions.timeout || 8;
|
|
var newNotification = new Notification(notificationTitle, notificationOptions);
|
|
if (navigator.userAgent.toLowerCase().indexOf('firefox') < 0) {
|
|
newNotification.onclick = function (event) {
|
|
event.preventDefault();
|
|
window.parent.focus();
|
|
window.focus();
|
|
};
|
|
}
|
|
setTimeout(function () {
|
|
newNotification.close();
|
|
}, timeout * 1000);
|
|
}
|
|
}
|
|
else {
|
|
console.info('Either Notification API not supported on this platform or permission not granted yet');
|
|
}
|
|
window.document.title = event.data.chatData.browserTitle + ' ' + $scope.title;
|
|
}
|
|
else if ($scope.title) {
|
|
window.document.title = $scope.title;
|
|
console.debug('Live Chat sac_notify_on_change event but Smart IT has focus. Ignoring event');
|
|
}
|
|
}
|
|
else if (event.data && event.data.event === LIVE_CHAT_EVENTS.sac_agent_chats) {
|
|
// if there are no chats, then clear everything in agent chats cache and the selected chat
|
|
if (!event.data || !event.data.chatData || !event.data.chatData.agentChats || !event.data.chatData.agentChats.length) {
|
|
$scope.selectedChat = null;
|
|
$scope.agentChats = [];
|
|
clearChatContext();
|
|
return;
|
|
}
|
|
//on load of live chat, cache all chats
|
|
if (!$scope.agentChats.length) {
|
|
$scope.agentChats = event.data.chatData.agentChats;
|
|
}
|
|
else {
|
|
//if any chat is removed from the list, remove it from the cache
|
|
var newAgentChats_1 = [];
|
|
_.forEach($scope.agentChats, function (chat) {
|
|
var validChat = _.findIndex(event.data.chatData.agentChats, { sid: chat.sid });
|
|
if (validChat !== -1) {
|
|
newAgentChats_1.push(chat);
|
|
}
|
|
else {
|
|
if ($scope.selectedChat && $scope.selectedChat.sessionid === chat.sid) {
|
|
clearChatContext();
|
|
}
|
|
}
|
|
});
|
|
$scope.agentChats = newAgentChats_1;
|
|
//if there are new chats, add them to the cache
|
|
_.forEach(event.data.chatData.agentChats, function (chat) {
|
|
if (_.findIndex($scope.agentChats, { sid: chat.sid }) === -1) {
|
|
$scope.agentChats.push(chat);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
else if (event.data && event.data.event === LIVE_CHAT_EVENTS.sac_on_request_chat_ticket_data) {
|
|
$scope.state.createTicketRequestPendingFromLC = false;
|
|
if ($scope.relateTicketToChatInProgress) {
|
|
relateChatToTicket($scope.relatedTicketData, event.data.chatData.session);
|
|
}
|
|
else {
|
|
proceedToCreateTicket(event.data.chatData.session, $scope.relatedTicketData);
|
|
}
|
|
}
|
|
else if (event.data && event.data.event === LIVE_CHAT_EVENTS.sac_notify_on_error) {
|
|
if ($scope.state.creatingTicket === true) {
|
|
$scope.state.creatingTicket = false;
|
|
systemAlertService.error({
|
|
text: $filter('i18n')('error.unknown'),
|
|
clear: false
|
|
});
|
|
}
|
|
var debugInfo = void 0;
|
|
if (event.data.chatData && event.data.chatData.sessionId) {
|
|
debugInfo = 'Live Chat error: Event - ' + event.data.event + ' Session Id - ' + event.data.chatData.sessionId;
|
|
}
|
|
else {
|
|
debugInfo = 'Live Chat error: Event - ' + event.data.event;
|
|
}
|
|
console.log(debugInfo);
|
|
}
|
|
else if (event.data && event.data.event === LIVE_CHAT_EVENTS.sac_files_uploaded && event.data.chatData.attachments) {
|
|
uploadAttachmentsToWorkLog(event.data.chatData.attachments, event.data.chatData);
|
|
}
|
|
else if (event.data && event.data.event === LIVE_CHAT_EVENTS.sac_session_context_change) {
|
|
var prevChatUser = $scope.selectedChat && $scope.selectedChat.user, prevChatCustomer = $scope.selectedChat && $scope.selectedChat.customer;
|
|
console.log(event.data);
|
|
$scope.selectedTemplate = null;
|
|
$scope.sessionID = event.data.chatData.sessionid;
|
|
$scope.context.selectedChat = true;
|
|
$scope.selectedChat = event.data.chatData;
|
|
$scope.selectedChat.user = event.data.chatData.metadata && (event.data.chatData.metadata.user || event.data.chatData.metadata.useremail);
|
|
if (event.data.chatData.metadata && event.data.chatData.metadata.appData) {
|
|
$scope.selectedChat.applicationData = JSON.parse(event.data.chatData.metadata.appData);
|
|
}
|
|
//set ticket data from app data for both create new ticket case and association with new ticket case
|
|
if ($scope.selectedChat.applicationData && $scope.selectedChat.applicationData.newTicketDetails) {
|
|
$scope.selectedChat.ticket = $scope.selectedChat.applicationData.newTicketDetails;
|
|
}
|
|
else if ($scope.selectedChat.applicationData && $scope.selectedChat.applicationData.ticketAssociationDetails
|
|
&& $scope.selectedChat.applicationData.ticketAssociationDetails.id) {
|
|
$scope.selectedChat.ticket = {
|
|
"ticketId": $scope.selectedChat.applicationData.ticketAssociationDetails.id,
|
|
"ticketDisplayId": $scope.selectedChat.applicationData.ticketAssociationDetails.displayId,
|
|
"ticketType": $scope.selectedChat.applicationData.ticketAssociationDetails.type
|
|
};
|
|
}
|
|
//load the pinned articles(stored in app data field on MCR) in Resources tab
|
|
if ($scope.selectedChat.applicationData && $scope.selectedChat.applicationData.pinnedArticles &&
|
|
$scope.selectedChat.applicationData.pinnedArticles.length) {
|
|
var promises_1 = [];
|
|
var articles_1 = [];
|
|
_.forEach($scope.selectedChat.applicationData.pinnedArticles, function (article) {
|
|
relationModel.cache[$scope.selectedChat.sessionid] = relationModel.cache[$scope.selectedChat.sessionid] &&
|
|
relationModel.cache[$scope.selectedChat.sessionid].length ? relationModel.cache[$scope.selectedChat.sessionid] : [];
|
|
var relationItemIdx = _.findIndex(relationModel.cache[$scope.selectedChat.sessionid], { id: article.id });
|
|
if (relationItemIdx === -1) {
|
|
var promise = void 0;
|
|
if (configurationModel.comaroundEnabled) {
|
|
var params = { search_text: article.title };
|
|
promise = knowledgeArticleModel.getHKMRecommendedKA({}, params).then(function (data) {
|
|
if (data && data.length > 0) {
|
|
_.forEach(data, function (obj) {
|
|
if (obj.id === article.id) {
|
|
articles_1.push(obj);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
else {
|
|
var params = { search_text: article.displayId };
|
|
var jsonParams = {
|
|
types: ['knowledge']
|
|
};
|
|
promise = searchService.getGlobalSearchResults(params, jsonParams).then(function (data) {
|
|
if (data.items[0] && data.items[0].results && data.items[0].results.length > 0) {
|
|
articles_1.push(data.items[0].results[0]);
|
|
}
|
|
});
|
|
}
|
|
promises_1.push(promise);
|
|
}
|
|
});
|
|
$q.all(promises_1).then(function () {
|
|
if (articles_1.length > 0) {
|
|
relationModel.cache[$scope.selectedChat.sessionid] = articles_1;
|
|
}
|
|
$scope.$broadcast(events.REFRESH_RECOMMENDED_KNOWLEDGE, { isFromLiveChat: true });
|
|
}, function (reason) {
|
|
console.log('Search pinned articles failed: ' + reason);
|
|
});
|
|
}
|
|
if ($scope.selectedChat.user === prevChatUser) {
|
|
$scope.$broadcast('personDataUpdated', true);
|
|
$scope.selectedChat.customer = prevChatCustomer;
|
|
$scope.selectedChat.customerCompany = prevChatCustomer && prevChatCustomer.company;
|
|
$scope.context.chatUserCompany = prevChatCustomer && prevChatCustomer.company && prevChatCustomer.company.name;
|
|
}
|
|
$scope.selectedChat.status = event.data.chatData.metadata && event.data.chatData.metadata.status;
|
|
$scope.selectedChat.queueType = event.data.chatData.metadata && event.data.chatData.metadata.queueType;
|
|
$scope.selectedChat.autoCreateTicketType = event.data.chatData.metadata && event.data.chatData.metadata.autoCreateTicketType;
|
|
$scope.selectedChat.autoCreateTemplateId = event.data.chatData.metadata && event.data.chatData.metadata.autoCreateTemplateId;
|
|
var agentChat_1 = _.findIndex($scope.agentChats, { sid: $scope.selectedChat.sessionid });
|
|
if (agentChat_1 !== -1) {
|
|
$scope.context.id = event.data.chatData.sessionid;
|
|
if ($scope.agentChats[agentChat_1].selectedChatContext) {
|
|
$scope.context.status = $scope.selectedChat.status;
|
|
$scope.context.accessMappings.relationsEditAllowed = $scope.context.status === 'Assigned' ? true : false;
|
|
$scope.context.summary = $scope.agentChats[agentChat_1].selectedChatContext.summaryText ||
|
|
($scope.selectedChat.applicationData && $scope.selectedChat.applicationData.searchText) ?
|
|
$scope.agentChats[agentChat_1].selectedChatContext.summaryText || $scope.selectedChat.applicationData.searchText : '';
|
|
if ($scope.agentChats[agentChat_1].selectedChatContext.selectedTemplate) {
|
|
$scope.context.selectedTemplate = $scope.agentChats[agentChat_1].selectedChatContext.selectedTemplate;
|
|
$scope.selectedTemplate = $scope.context.selectedTemplate;
|
|
}
|
|
else {
|
|
$scope.context.selectedTemplate = null;
|
|
$scope.selectedTemplate = null;
|
|
}
|
|
if ($scope.agentChats[agentChat_1].selectedChatContext.selectedKnowledge) {
|
|
$scope.context.selectedKnowledge = $scope.agentChats[agentChat_1].selectedChatContext.selectedKnowledge;
|
|
}
|
|
if ($scope.agentChats[agentChat_1].selectedChatContext.ticket) {
|
|
$scope.selectedChat.ticket = $scope.agentChats[agentChat_1].selectedChatContext.ticket;
|
|
}
|
|
else if ($scope.selectedChat.ticket) {
|
|
$scope.agentChats[agentChat_1].selectedChatContext.ticket = $scope.selectedChat.ticket;
|
|
}
|
|
else if (event.data.chatData.metadata.ticketid) {
|
|
var ticketInfo_2, params = {
|
|
search_text: event.data.chatData.metadata.ticketid
|
|
}, jsonParams = {
|
|
types: ['tickets']
|
|
};
|
|
searchService.getGlobalSearchResults(params, jsonParams).then(function (response) {
|
|
if (!_.isEmpty(response.items) && response.items[0] && response.items[0].results) {
|
|
ticketInfo_2 = _.find(response.items[0].results, { displayId: event.data.chatData.metadata.ticketid });
|
|
$scope.selectedChat.ticket = { ticketDisplayId: event.data.chatData.metadata.ticketid,
|
|
ticketType: event.data.chatData.metadata.tickettype,
|
|
ticketId: ticketInfo_2 && ticketInfo_2.id };
|
|
$scope.agentChats[agentChat_1].selectedChatContext.ticket = $scope.selectedChat.ticket;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
else {
|
|
$scope.context.status = $scope.selectedChat.status;
|
|
$scope.context.accessMappings.relationsEditAllowed = $scope.context.status === 'Assigned' ? true : false;
|
|
$scope.context.summary = $scope.selectedChat.applicationData && $scope.selectedChat.applicationData.searchText ?
|
|
$scope.selectedChat.applicationData && $scope.selectedChat.applicationData.searchText : '';
|
|
if ($scope.context.selectedTemplate) {
|
|
$scope.context.selectedTemplate = null;
|
|
$scope.selectedTemplate = null;
|
|
}
|
|
if ($scope.context.selectedKnowledge) {
|
|
$scope.context.selectedKnowledge = null;
|
|
}
|
|
$scope.agentChats[agentChat_1].selectedChatContext = _.cloneDeep($scope.context);
|
|
if ($scope.selectedChat.applicationData && $scope.selectedChat.applicationData.pinnedArticles &&
|
|
$scope.selectedChat.applicationData.pinnedArticles.length) {
|
|
$scope.agentChats[agentChat_1].selectedChatContext.selectedKnowledge = $scope.selectedChat.applicationData.pinnedArticles;
|
|
}
|
|
if ($scope.selectedChat.ticket) {
|
|
$scope.agentChats[agentChat_1].selectedChatContext.ticket = $scope.selectedChat.ticket;
|
|
}
|
|
else if (event.data.chatData.metadata.ticketid) {
|
|
var ticketInfo_3, params = {
|
|
search_text: event.data.chatData.metadata.ticketid
|
|
}, jsonParams = {
|
|
types: ['tickets']
|
|
};
|
|
searchService.getGlobalSearchResults(params, jsonParams).then(function (response) {
|
|
if (!_.isEmpty(response.items) && response.items[0] && response.items[0].results) {
|
|
ticketInfo_3 = _.find(response.items[0].results, { displayId: event.data.chatData.metadata.ticketid });
|
|
$scope.selectedChat.ticket = { ticketDisplayId: event.data.chatData.metadata.ticketid,
|
|
ticketType: event.data.chatData.metadata.tickettype,
|
|
ticketId: ticketInfo_3 && ticketInfo_3.id };
|
|
$scope.agentChats[agentChat_1].selectedChatContext.ticket = $scope.selectedChat.ticket;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
$scope.context.summary = '';
|
|
}
|
|
$scope.$broadcast(events.ON_SELECTED_LIVE_CHAT, $scope.context);
|
|
$scope.$apply();
|
|
setTab();
|
|
}
|
|
//display confirmation modal
|
|
else if (event.data.event && event.data.event === LIVE_CHAT_EVENTS.sac_open_confirmation_modal) {
|
|
showModalDialog(event.data);
|
|
}
|
|
//when chat is closed from SSP or when another agent transferred the chat
|
|
else if (event.data.event && (event.data.event === LIVE_CHAT_EVENTS.sac_session_cancelled
|
|
|| event.data.event === LIVE_CHAT_EVENTS.sac_session_transferred)) {
|
|
var confirmationData = {
|
|
confirmationEvent: event.data.event
|
|
}, ticketData = void 0;
|
|
var removeChat = _.findIndex($scope.agentChats, { sid: event.data.chatData.sessionid });
|
|
if (removeChat !== -1) {
|
|
ticketData = $scope.agentChats[removeChat] && $scope.agentChats[removeChat].selectedChatContext && $scope.agentChats[removeChat].selectedChatContext.ticket;
|
|
$scope.agentChats.splice(removeChat, 1);
|
|
}
|
|
if (ticketData && event.data.event === LIVE_CHAT_EVENTS.sac_session_cancelled) {
|
|
updateTicketAndRemoveChat(ticketData, confirmationData, event.data.chatData.session, true, event.data.chatData.sessionid);
|
|
}
|
|
else if (!ticketData && event.data.event === LIVE_CHAT_EVENTS.sac_session_cancelled) {
|
|
//create call log
|
|
createCallLog($scope.selectedChat, event.data.chatData.sessionid);
|
|
if ($scope.selectedChat && event.data.chatData.sessionid === $scope.selectedChat.sessionid) {
|
|
$scope.selectedChat = null;
|
|
event.data.chatData.sessionid = null;
|
|
}
|
|
}
|
|
else {
|
|
if ($scope.selectedChat.sessionid === event.data.chatData.sessionid) {
|
|
clearChatContext();
|
|
}
|
|
}
|
|
}
|
|
//When it fails to create the ticket, we open the draft screen in a new window which throws
|
|
//this event when the ticket creation is successful. This event is NOT coming from ESCHAT/Live Chat
|
|
else if (event.data.event && event.data.event === events.TICKET_CREATED_FROM_DRAFT) {
|
|
var chatSessionIdforCreate = event.data.eventData.livechatTicketData.chatSessionId, relatedTicket = $scope.relatedTicketData, chatSessionforCreate = void 0;
|
|
$scope.noOfDraftScreensOpen = --$scope.noOfDraftScreensOpen;
|
|
// in case we have attachments, then we don't want to override the chat session object
|
|
if ($scope.chatTicketDataForCreateMap && $scope.chatTicketDataForCreateMap.has(chatSessionIdforCreate)) {
|
|
chatSessionforCreate = $scope.chatTicketDataForCreateMap.get(chatSessionIdforCreate);
|
|
}
|
|
handleDraftCreateComplete(event.data.eventData.livechatTicketData, chatSessionforCreate, relatedTicket);
|
|
$scope.chatTicketDataForCreateMap.delete(chatSessionIdforCreate);
|
|
}
|
|
else if (event.data.event && event.data.event === events.DRAFT_TICKET_CLOSED) {
|
|
// event from draftTicketController and pwaTicketController on closing the draft ticket screen
|
|
$scope.noOfDraftScreensOpen = --$scope.noOfDraftScreensOpen;
|
|
}
|
|
else if (event.data.event && (event.data.event === events.LIVECHAT_CREATEINCIDENT_SUCCESS
|
|
|| event.data.event === events.LIVECHAT_CREATEWORKORDER_SUCCESS)) {
|
|
$scope.noOfDraftScreensOpen = --$scope.noOfDraftScreensOpen;
|
|
var ticketDataArr = event.data.eventData.split(';');
|
|
var livechatTicketData_1 = {};
|
|
_.forEach(ticketDataArr, function (entry) {
|
|
var val = entry.split('=');
|
|
livechatTicketData_1[val[0]] = val[1];
|
|
});
|
|
var chatSessionIdforCreate = livechatTicketData_1.chatSessionId, relatedTicket = $scope.relatedTicketData, chatSessionforCreate = void 0;
|
|
// in case we have attachments, then we don't want to override the chat session object
|
|
if ($scope.chatTicketDataForCreateMap && $scope.chatTicketDataForCreateMap.has(chatSessionIdforCreate)) {
|
|
chatSessionforCreate = $scope.chatTicketDataForCreateMap.get(chatSessionIdforCreate);
|
|
}
|
|
// need to do this if the complete ticket object is not returned from draft controller
|
|
if (!livechatTicketData_1.summary) {
|
|
var chatIndex = _.findIndex($scope.agentChats, { sid: chatSessionIdforCreate });
|
|
if (chatIndex !== -1) {
|
|
livechatTicketData_1.summary = $scope.agentChats[chatIndex].cleartextquestion.substring(0, summaryCharLimit);
|
|
}
|
|
}
|
|
handleDraftCreateComplete(livechatTicketData_1, chatSessionforCreate, relatedTicket);
|
|
$scope.chatTicketDataForCreateMap.delete(chatSessionIdforCreate);
|
|
}
|
|
};
|
|
var handleFocusChange = function ($event) {
|
|
if ($event.type === 'blur') {
|
|
$scope.isBrowserTabFocus = false;
|
|
}
|
|
else if ($event.type === 'focus') {
|
|
$scope.isBrowserTabFocus = true;
|
|
if ($scope.title) {
|
|
window.document.title = $scope.title;
|
|
}
|
|
}
|
|
};
|
|
var registerLiveChatListener = function () {
|
|
if ($window.addEventListener) {
|
|
$window.addEventListener('message', liveChatListener, false);
|
|
$window.addEventListener('focus', handleFocusChange, false);
|
|
$window.addEventListener('blur', handleFocusChange, false);
|
|
$window.addEventListener('storage', onLocalStorageChange, false);
|
|
}
|
|
};
|
|
var unregisterLiveChatListener = function () {
|
|
if ($window.removeEventListener) {
|
|
$window.removeEventListener('message', liveChatListener, false);
|
|
$window.removeEventListener('focus', handleFocusChange, false);
|
|
$window.removeEventListener('blur', handleFocusChange, false);
|
|
$window.removeEventListener('storage', onLocalStorageChange, false);
|
|
}
|
|
localStorageService.remove($window.tabId);
|
|
localStorageService.remove(lcConsolePendingMsgKey);
|
|
};
|
|
function init() {
|
|
var eschatServerConfiguration = configurationModel.get('eschatConfiguration');
|
|
var isESChatIntegrationEnabled = eschatServerConfiguration.enableESChatIntegration || configurationModel.enableESChatIntegration;
|
|
if (!configurationModel.isServerApplicationEnabled(EntityVO.TYPE_LIVE_CHAT) || !isESChatIntegrationEnabled) {
|
|
console.info('LiveChat.init() either Eschat application or ESChatIntegration is disabled. Navigating to dashboard.');
|
|
$state.go('dashboard');
|
|
return;
|
|
}
|
|
if (!eschatServerConfiguration.eschatServerUrl) {
|
|
//if the url to load live chat doesn't exist
|
|
$scope.showUnableToLoadMsg = true;
|
|
$scope.state.loadingLiveChat = false;
|
|
return;
|
|
}
|
|
else {
|
|
$scope.showUnableToLoadMsg = false;
|
|
}
|
|
if ($state.current.data.path === 'dashboard') {
|
|
$scope.hideForDashboard = true;
|
|
}
|
|
if (eschatServerConfiguration.eschatServerUrl) {
|
|
localStorageService.set('eschatServerUrl', eschatServerConfiguration.eschatServerUrl);
|
|
$scope.eschatServerUrl = eschatServerConfiguration.eschatServerUrl;
|
|
$scope.smartITURL = window.location && window.location.origin;
|
|
var path = $state.current.data.path;
|
|
var userPref = '';
|
|
if ($rootScope.locale) {
|
|
userPref = userPref + '&locale=' + $rootScope.locale;
|
|
}
|
|
if ($rootScope.timezone) {
|
|
userPref = userPref + '&timezone=' + $rootScope.timezone;
|
|
}
|
|
$scope.crossLaunchLiveChatURL = $sce.trustAsResourceUrl(eschatServerConfiguration.eschatServerUrl + '/#?uid=' + encodeURIComponent($scope.userid) + userPref + '&embedded=smartit&path=' + path);
|
|
}
|
|
$scope.assignTicketToLiveAgent = eschatServerConfiguration.assignTicketToLiveAgent;
|
|
$scope.allowedWindowEvents = [events.TICKET_CREATED_FROM_DRAFT,
|
|
events.LIVECHAT_CREATEINCIDENT_SUCCESS,
|
|
events.LIVECHAT_CREATEWORKORDER_SUCCESS,
|
|
events.DRAFT_TICKET_CLOSED];
|
|
registerLiveChatListener();
|
|
setTab();
|
|
initAlertForDirtyForm();
|
|
//get global metadata
|
|
metadataModel.getMetadataByType(EntityVO.TYPE_GLOBAL)
|
|
.then(function (metadata) {
|
|
$scope.createCallLogEnabled = metadata && metadata.configurationParameters && metadata.configurationParameters.enableSmartRecorderCallLog === 'true';
|
|
});
|
|
}
|
|
$scope.createTicket = function (ticketType) {
|
|
if (ticketType === EntityVO.TYPE_INCIDENT) {
|
|
$scope.draftType = 'draftIncident';
|
|
}
|
|
else if (ticketType === EntityVO.TYPE_WORKORDER) {
|
|
$scope.draftType = 'draftWorkorder';
|
|
}
|
|
var sessionId = $scope.selectedChat && $scope.selectedChat.sessionid;
|
|
if ($scope.isAutoCreateTicketEnabled === true) {
|
|
$scope.state.creatingTicket = false;
|
|
if (sessionId) {
|
|
if ($scope.createTicketInProgressForChatSessionSet.has(sessionId)) {
|
|
console.warn('Auto ticket creation already in progress for sessionId: ' + sessionId);
|
|
return;
|
|
}
|
|
$scope.createTicketInProgressForChatSessionSet.add(sessionId);
|
|
}
|
|
}
|
|
else {
|
|
$scope.state.creatingTicket = true;
|
|
}
|
|
$scope.ticketType = ticketType;
|
|
//start - send an event to eschat to get the chat info to create a ticket
|
|
var data = {
|
|
event: LIVE_CHAT_APP_EVENTS.app_request_chat_ticket_data,
|
|
data: { chatSessionId: sessionId }
|
|
};
|
|
sendChildMessage(data);
|
|
$scope.state.createTicketRequestPendingFromLC = true;
|
|
//end
|
|
$timeout(function () {
|
|
if ($scope.state.creatingTicket === true && $scope.state.createTicketRequestPendingFromLC === true) {
|
|
$scope.state.creatingTicket = false;
|
|
console.log('No response from live chat on create ticket for sessionId: ' + sessionId);
|
|
systemAlertService.error({
|
|
text: $filter('i18n')('error.unknown'),
|
|
clear: false
|
|
});
|
|
}
|
|
}, CREATE_TICKET_TIMEOUT);
|
|
};
|
|
function proceedToCreateTicket(chatSession, relatedTicket) {
|
|
var metadata, ticketDataFromDraft, templateId;
|
|
// Get metadata
|
|
var metadataPromise = metadataModel.getMetadataByType($scope.ticketType);
|
|
if (relatedTicket && (relatedTicket.templateGuid || relatedTicket.templateId)) {
|
|
templateId = relatedTicket.templateGuid || relatedTicket.templateId;
|
|
}
|
|
else if (!relatedTicket) {
|
|
var defaulTemplateFromConfig = $scope.selectedChatTicketConfig[$scope.ticketType].defaultTemplate;
|
|
if ($scope.selectedTemplate) {
|
|
templateId = $scope.selectedTemplate.id;
|
|
}
|
|
else if (defaulTemplateFromConfig) {
|
|
templateId = defaulTemplateFromConfig.id;
|
|
}
|
|
}
|
|
if (!_.isEmpty(ticketModel.cache.draft)) {
|
|
delete ticketModel.cache.draft;
|
|
}
|
|
var ticketDataPromise = ticketModel.getDraft($scope.ticketType, templateId);
|
|
$q.all([metadataPromise, ticketDataPromise]).then(function (results) {
|
|
metadata = results[0]; // metadata
|
|
ticketDataFromDraft = results[1]; // ticketdata
|
|
// if the draft call returns an empty response, this happens when the template is deleted in ITSM
|
|
if (!results[1] || !results[1].id) {
|
|
$scope.state.creatingTicket = false;
|
|
systemAlertService.error({
|
|
text: $filter('i18n')('error.unknown'),
|
|
clear: false
|
|
});
|
|
return;
|
|
}
|
|
if (templateId) {
|
|
ticketDataFromDraft.templateGuid = templateId;
|
|
}
|
|
ticketDataFromDraft.chatSessionId = $scope.selectedChat.sessionid;
|
|
//if the ticket is created from a ticket association and if the parent ticket doesn't use a template,
|
|
//then the below fields will be copied to the new ticket
|
|
if (relatedTicket && (relatedTicket.templateGuid || relatedTicket.templateId)) {
|
|
ticketDataFromDraft.summary = relatedTicket.summary;
|
|
ticketDataFromDraft.desc = relatedTicket.detailedDescription;
|
|
ticketDataFromDraft.priority = relatedTicket.priority;
|
|
if (relatedTicket && relatedTicket.categorizations) {
|
|
var operationalCat = _.find(relatedTicket.categorizations, { name: 'operational' });
|
|
var productCat = _.find(relatedTicket.categorizations, { name: 'product' });
|
|
ticketDataFromDraft.categorizations = [];
|
|
ticketDataFromDraft.categorizations.push(operationalCat);
|
|
ticketDataFromDraft.categorizations.push(productCat);
|
|
}
|
|
}
|
|
else {
|
|
ticketDataFromDraft.summary = $scope.selectedChat.metadata.title.substring(0, summaryCharLimit);
|
|
}
|
|
if (relatedTicket && relatedTicket.reportedSource) {
|
|
ticketDataFromDraft.reportedSource = relatedTicket.reportedSource;
|
|
}
|
|
else {
|
|
ticketDataFromDraft.reportedSource = 'Chat';
|
|
}
|
|
if ($scope.selectedChat.customer) {
|
|
ticketDataFromDraft.customer = $scope.selectedChat.customer;
|
|
}
|
|
if ($scope.ticketType === EntityVO.TYPE_INCIDENT && !ticketDataFromDraft.priority) {
|
|
if (!ticketDataFromDraft.impact) {
|
|
ticketDataFromDraft.impact = _.last(metadata.impacts).name;
|
|
}
|
|
if (!ticketDataFromDraft.urgency) {
|
|
ticketDataFromDraft.urgency = _.last(metadata.urgencies).name;
|
|
}
|
|
}
|
|
//auto-assign to agent if the ticket is being created without a template and it's not an association ticket
|
|
if (!templateId && $scope.assignTicketToLiveAgent) {
|
|
liveChatService.assignToMe('ticketassignee', ticketDataFromDraft, chatSession, $scope);
|
|
}
|
|
else {
|
|
handleAssignmentComplete('e', { ticket: ticketDataFromDraft, chatSession: chatSession });
|
|
}
|
|
});
|
|
}
|
|
function addRelation(uuid, type, relation) {
|
|
relationModel.addRelation({
|
|
uuid: uuid,
|
|
type: type
|
|
}, relation);
|
|
}
|
|
function addWorkNoteForTicket(session, ticket) {
|
|
var ticketData = { chatLog: session.chatlog, chatNotes: session.chatnotes, attachments: session.attachments };
|
|
var chatTicketData = prepareDataForTicket(ticketData);
|
|
if (chatTicketData.chatLog) {
|
|
processWorkNote(ticket.ticketId, ticket.ticketType, { text: chatTicketData.chatLog }, session.sessionid);
|
|
}
|
|
if (chatTicketData.chatInlineNotes) {
|
|
processWorkNote(ticket.ticketId, ticket.ticketType, { text: chatTicketData.chatInlineNotes }, session.sessionid);
|
|
}
|
|
if (session.attachments && session.attachments.length) {
|
|
var attachmentArray = session.attachments;
|
|
if (attachmentArray.length > 3) {
|
|
var attachmentLimit = 3, attachmentList = void 0;
|
|
for (var i = 0, j = attachmentArray.length; i < j; i += attachmentLimit) {
|
|
attachmentList = attachmentArray.slice(i, i + attachmentLimit);
|
|
uploadAttachmentsToWorkLog(attachmentList, session);
|
|
}
|
|
}
|
|
else {
|
|
uploadAttachmentsToWorkLog(attachmentArray, session);
|
|
}
|
|
}
|
|
}
|
|
function processWorkNote(ticketId, ticketType, note, sessionId) {
|
|
var workNote, ticketInfo = {
|
|
type: ticketType,
|
|
id: ticketId
|
|
};
|
|
if (note.attachments) {
|
|
workNote = {
|
|
noteText: note.text,
|
|
access: true,
|
|
type: 35000,
|
|
attachments: note.attachments
|
|
};
|
|
return attachmentService.addWorknoteWithAttachment(ticketInfo, workNote);
|
|
}
|
|
else {
|
|
workNote = {
|
|
noteText: note.text,
|
|
access: true,
|
|
workInfoType: 35000,
|
|
chatSessionId: sessionId
|
|
};
|
|
return feedModel.saveNote(ticketInfo, workNote);
|
|
}
|
|
}
|
|
function createCallLog(selectedChat, chatSessionIdToRemove) {
|
|
if (!$scope.createCallLogEnabled) {
|
|
selectedChat = null;
|
|
systemAlertService.success({ text: i18nService.getLocalizedString('live.chat.createCallLog.success'), clear: true, hide: 10000 });
|
|
return;
|
|
}
|
|
if (!chatSessionIdToRemove) {
|
|
$scope.state.creatingCallLog = true;
|
|
}
|
|
metadataModel.getMetadataByType(EntityVO.TYPE_SMART_RECORDER).then(function (results) {
|
|
if (selectedChat) {
|
|
if (results) {
|
|
$scope.eventTypes = results.callLogEventTypes;
|
|
}
|
|
var callLogData = {
|
|
persons: []
|
|
};
|
|
var dataObj = {};
|
|
if (selectedChat.customer) {
|
|
dataObj.personId = selectedChat.customer.personId;
|
|
dataObj.fullName = selectedChat.customer.fullName;
|
|
dataObj.personType = 'customer';
|
|
callLogData.persons.push(dataObj);
|
|
}
|
|
callLogData.description = selectedChat.metadata.title;
|
|
if (selectedChat.customerCompany) {
|
|
callLogData.company = selectedChat.customerCompany.name;
|
|
}
|
|
var chatCallLogObj = { label: "Chat", value: "Chat" };
|
|
var chatCallLogEventIndex = _.findIndex($scope.eventTypes, chatCallLogObj);
|
|
chatCallLogEventIndex = chatCallLogEventIndex !== -1 ? chatCallLogEventIndex : 0;
|
|
callLogData.callLogEventType = $scope.eventTypes && $scope.eventTypes[chatCallLogEventIndex];
|
|
callLogData.chatSessionId = selectedChat.sessionid;
|
|
smartRecorderModel.postCallLog(callLogData).then(function () {
|
|
if (!chatSessionIdToRemove) {
|
|
systemAlertService.success({ text: i18nService.getLocalizedString('live.chat.createCallLog.success'), clear: true, hide: 10000 });
|
|
$scope.state.creatingCallLog = false;
|
|
}
|
|
}, function (error) {
|
|
if (!chatSessionIdToRemove) {
|
|
systemAlertService.error({ text: (error && error.data && error.data.error) || error, clear: true, hide: 10000 });
|
|
$scope.state.creatingCallLog = false;
|
|
}
|
|
});
|
|
if (!chatSessionIdToRemove) {
|
|
$scope.selectedChat = null;
|
|
}
|
|
if (chatSessionIdToRemove && chatSessionIdToRemove === selectedChat.sessionid) {
|
|
$scope.selectedChat = null;
|
|
chatSessionIdToRemove = null;
|
|
}
|
|
selectedChat = null;
|
|
}
|
|
else {
|
|
console.error("Could not create a call log");
|
|
$scope.state.creatingCallLog = false;
|
|
}
|
|
});
|
|
}
|
|
function showQuickTicketCreateSuccess(ticketType, ticketData, chatSession, action, relatedTicket) {
|
|
// Save related resources.
|
|
var agentChatIndex = _.findIndex($scope.agentChats, { sid: chatSession.sessionid });
|
|
var selectedResourcesToSave;
|
|
if (chatSession.selectedResources) {
|
|
selectedResourcesToSave = chatSession.selectedResources;
|
|
}
|
|
var transformedRelations = saveRelatedResources(selectedResourcesToSave, chatSession.sessionid);
|
|
addResourceRelations(transformedRelations, ticketData, ticketData.id, (ticketType || $scope.ticketType));
|
|
var ticketDataForChat = { ticketType: ticketType, ticketDisplayId: ticketData.displayId, ticketId: ticketData.id };
|
|
if ($scope.selectedChat.sessionid === chatSession.sessionid) {
|
|
$scope.selectedChat.ticket = ticketDataForChat;
|
|
}
|
|
if (agentChatIndex !== -1) {
|
|
if ($scope.agentChats[agentChatIndex].selectedChatContext) {
|
|
$scope.agentChats[agentChatIndex].selectedChatContext.ticket = ticketDataForChat;
|
|
}
|
|
}
|
|
var msg;
|
|
if (action === 'createTicket') {
|
|
if (relatedTicket && relatedTicket.status && (relatedTicket.status.value === 'Resolved' || relatedTicket.status.value === 'Closed'
|
|
|| relatedTicket.status.value === 'Completed' || relatedTicket.status.value === 'Cancelled')) {
|
|
msg = $filter('i18n')('live.chat.closed.ticket.relate.success', [utilityFunctions.getTicketCreatedSuccessMessageWithLink(ticketData.id, ticketData.displayId, ticketType, true)]);
|
|
sendApplicationData(chatSession.sessionid, ticketDataForChat, relatedTicket);
|
|
}
|
|
else if (relatedTicket && relatedTicket.chatSessionId) {
|
|
msg = $filter('i18n')('live.chat.associated.ticket.relate.success', [utilityFunctions.getTicketCreatedSuccessMessageWithLink(ticketData.id, ticketData.displayId, ticketType, true)]);
|
|
sendApplicationData(chatSession.sessionid, ticketDataForChat, relatedTicket);
|
|
}
|
|
else {
|
|
msg = $filter('i18n')('smartrecorder.quickTicketCreate.success', [utilityFunctions.getTicketCreatedSuccessMessageWithLink(ticketData.id, ticketData.displayId, ticketType, true)]);
|
|
sendApplicationData(chatSession.sessionid, null, null, null, null, ticketData);
|
|
}
|
|
}
|
|
else if (action === 'updateTicket') {
|
|
msg = $filter('i18n')('live.chat.ticket.update.success', [utilityFunctions.getTicketCreatedSuccessMessageWithLink(ticketData.id, ticketData.displayId, ticketType, true)]);
|
|
sendApplicationData(chatSession.sessionid, ticketDataForChat);
|
|
}
|
|
systemAlertService.success({ text: msg, clear: true, hide: 10000, isHTML: true });
|
|
if (chatSession) {
|
|
addWorkNoteForTicket(chatSession, ticketDataForChat);
|
|
getServiceRequestId(ticketType, ticketData.id, ticketData.displayId, chatSession.sessionid);
|
|
}
|
|
$scope.$broadcast('personDataUpdated', true);
|
|
$scope.relatedTicketData = null;
|
|
}
|
|
function getServiceRequestId(parentTicketType, parentTicketId, parentDisplayId, sessionId, removeTicketAssociation) {
|
|
searchService.getRequestForRelatedTicket(parentTicketId).then(function (srData) {
|
|
//send the ticket data to eschat which will update the Master Chat Record form
|
|
var appData = {
|
|
data: { chatSessionId: sessionId, ticketId: parentDisplayId, ticketType: parentTicketType },
|
|
event: removeTicketAssociation ? LIVE_CHAT_APP_EVENTS.app_unrelate_ticket : LIVE_CHAT_APP_EVENTS.app_relate_ticket_to_chat
|
|
};
|
|
var ticketType = parentTicketType, ticketId = parentDisplayId;
|
|
if (srData && srData.appInstanceId === parentTicketId && srData.srDisplayId && srData.srDisplayId.length > 0) {
|
|
ticketType = EntityVO.TYPE_SERVICEREQUEST;
|
|
ticketId = srData.srDisplayId;
|
|
}
|
|
if (removeTicketAssociation) {
|
|
appData.data.endUserTicketType = ticketType;
|
|
appData.data.endUserTicketId = ticketId;
|
|
sendApplicationData(sessionId, null, null, removeTicketAssociation);
|
|
var messageToSend = $filter('i18n')('ticket.type.' + ticketType) + ' ' + ticketId + ' ' + $filter('i18n')('live.chat.ticket.unrelate.message');
|
|
appData.data.unRelateMessage = messageToSend;
|
|
sendChildMessage(appData);
|
|
$scope.state.creatingTicket = false;
|
|
}
|
|
else {
|
|
var message_1 = { type: ticketType, ticketId: ticketId };
|
|
if (srData && srData.srDisplayId) {
|
|
appData.data.endUserTicketType = EntityVO.TYPE_SERVICEREQUEST;
|
|
appData.data.endUserTicketId = srData.srDisplayId;
|
|
}
|
|
sendChildMessage(appData);
|
|
var messageToSend = $filter('i18n')('ticket.type.' + ticketType) + ' ' + ticketId + ' ' + $filter('i18n')('live.chat.ticket.message');
|
|
message_1.messageToSend = messageToSend;
|
|
$timeout(function () {
|
|
sendMessageToChat(null, message_1, sessionId);
|
|
$scope.state.creatingTicket = false;
|
|
$scope.createTicketInProgressForChatSessionSet.delete(sessionId);
|
|
}, 1000);
|
|
}
|
|
});
|
|
}
|
|
function sendApplicationData(sessionId, currentTicket, parentTicket, removeTicketAssociation, pinnedResources, newTicket) {
|
|
var ticketAssocData, pinnedResourcesData = [], searchTextData, newTicketData;
|
|
//store pinned articles in app data to load the pinned resources when a chat is either transfered or released
|
|
if (pinnedResources) {
|
|
if (pinnedResources.selectedKnowledge) {
|
|
var pinnedKA_1;
|
|
_.forEach(pinnedResources.selectedKnowledge, function (ka) {
|
|
pinnedKA_1 = {
|
|
id: ka.id,
|
|
displayId: ka.displayId,
|
|
type: EntityVO.TYPE_KNOWLEDGE
|
|
};
|
|
if (configurationModel.comaroundEnabled) {
|
|
pinnedKA_1.title = ka.title;
|
|
}
|
|
pinnedResourcesData.push(pinnedKA_1);
|
|
});
|
|
}
|
|
searchTextData = pinnedResources.summaryText || pinnedResources.summary;
|
|
}
|
|
else {
|
|
pinnedResourcesData = $scope.selectedChat.applicationData && $scope.selectedChat.applicationData.pinnedArticles;
|
|
searchTextData = $scope.selectedChat.applicationData && $scope.selectedChat.applicationData.searchText;
|
|
}
|
|
//this is in case of association (both update ticket and create ticket)
|
|
if (currentTicket) {
|
|
ticketAssocData = {
|
|
"parentId": parentTicket && parentTicket.id ? parentTicket.id : '',
|
|
"parentDisplayId": parentTicket && parentTicket.displayId ? parentTicket.displayId : '',
|
|
"parentType": parentTicket && parentTicket.type ? parentTicket.type : '',
|
|
"id": currentTicket.ticketId,
|
|
"displayId": currentTicket.ticketDisplayId,
|
|
"type": currentTicket.ticketType,
|
|
"associationType": parentTicket ? 'create' : 'update'
|
|
};
|
|
}
|
|
else {
|
|
ticketAssocData = $scope.selectedChat.applicationData && $scope.selectedChat.applicationData.ticketAssociationDetails;
|
|
}
|
|
if (removeTicketAssociation) {
|
|
$scope.selectedChat.applicationData.ticketAssociationDetails = {};
|
|
ticketAssocData = {};
|
|
pinnedResourcesData = $scope.selectedChat.applicationData && $scope.selectedChat.applicationData.pinnedArticles;
|
|
searchTextData = $scope.selectedChat.applicationData && $scope.selectedChat.applicationData.searchText;
|
|
}
|
|
//this is in case of create a new ticket by using the create ticket buttons
|
|
if (newTicket) {
|
|
newTicketData = {
|
|
"ticketId": newTicket.id,
|
|
"ticketDisplayId": newTicket.displayId,
|
|
"ticketType": newTicket.type
|
|
};
|
|
}
|
|
else {
|
|
newTicketData = $scope.selectedChat.applicationData && $scope.selectedChat.applicationData.newTicketDetails;
|
|
}
|
|
$scope.selectedChat.applicationData = { ticketAssociationDetails: ticketAssocData, pinnedArticles: pinnedResourcesData, searchText: searchTextData, newTicketDetails: newTicketData };
|
|
var applicationData = JSON.stringify($scope.selectedChat.applicationData);
|
|
var appData = {
|
|
data: { chatSessionId: sessionId, appData: applicationData },
|
|
event: LIVE_CHAT_APP_EVENTS.app_save_appData
|
|
};
|
|
console.log("Saving app data:" + JSON.stringify(appData));
|
|
sendChildMessage(appData);
|
|
}
|
|
function showQuickTicketCreateFailure(draftType, error, chatSession) {
|
|
$scope.noOfDraftScreensOpen = ++$scope.noOfDraftScreensOpen;
|
|
if ($scope.selectedChat && $scope.selectedChat.applicationData && $scope.selectedChat.applicationData.pinnedArticles) {
|
|
chatSession.selectedResources = $scope.selectedChat.applicationData.pinnedArticles;
|
|
}
|
|
$scope.chatTicketDataForCreateMap.set(chatSession.sessionid, chatSession);
|
|
$scope.createTicketInProgressForChatSessionSet.delete(chatSession.sessionid);
|
|
$scope.state.creatingTicket = false;
|
|
localStorageService.set('draft.ticket', ticketModel.cache.draft);
|
|
localStorageService.set('draft.ticket.error', (error && error.data && error.data.error) || error);
|
|
// prevent opening in new tab if the error is for unique index violation (https://jira.bmc.com/browse/DR931-742)
|
|
if (!error || !error.data || (error && error.data && error.data.error.indexOf('ERROR (382)') === -1)) {
|
|
var url = $state.href('liveChatDraft', { draftType: draftType });
|
|
$window.open(url, '_blank');
|
|
}
|
|
}
|
|
function saveTicketToChat(event, data) {
|
|
systemAlertService.modal({
|
|
type: 'info',
|
|
title: $filter('i18n')('live.chat.notification.title'),
|
|
text: $filter('i18n')('live.chat.ticket.relate.confirmation.message'),
|
|
buttons: [
|
|
{
|
|
text: $filter('i18n')('common.button.yes'),
|
|
data: true
|
|
},
|
|
{
|
|
text: $filter('i18n')('common.button.no'),
|
|
data: false
|
|
}
|
|
]
|
|
}).result.then(function (result) {
|
|
if (result) {
|
|
$scope.relatedTicketData = data.ticket;
|
|
//case 1 - if the ticket is resolved(INC) / completed(WO) or Cancelled or Closed OR if the ticket has a chat, create new ticket and use the same templated ID if it exists
|
|
//case 2 - if the ticket is open and does not have a chat, associate the chat to the ticket
|
|
if (data.ticket && (data.ticket.chatSessionId || (data.ticket.status && (data.ticket.status.value === 'Resolved' ||
|
|
data.ticket.status.value === 'Closed' || data.ticket.status.value === 'Completed' || data.ticket.status.value === 'Cancelled')))) {
|
|
//create a new ticket and relate them
|
|
$scope.createTicket(data.ticket.type);
|
|
}
|
|
else {
|
|
$scope.state.creatingTicket = true;
|
|
$scope.relateTicketToChatInProgress = true;
|
|
//start - send an event to eschat to get the chat info to create a ticket
|
|
var eventData = {
|
|
event: LIVE_CHAT_APP_EVENTS.app_request_chat_ticket_data,
|
|
data: { chatSessionId: data.chat && data.chat.sessionid }
|
|
};
|
|
sendChildMessage(eventData);
|
|
$scope.state.createTicketRequestPendingFromLC = true;
|
|
//end
|
|
$timeout(function () {
|
|
if ($scope.state.creatingTicket === true && $scope.state.createTicketRequestPendingFromLC === true) {
|
|
$scope.state.creatingTicket = false;
|
|
console.log('No response from live chat on saving ticket to chat');
|
|
systemAlertService.error({
|
|
text: $filter('i18n')('error.unknown'),
|
|
clear: false
|
|
});
|
|
}
|
|
}, CREATE_TICKET_TIMEOUT);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
function removeTicketFromChat(event, data) {
|
|
systemAlertService.modal({
|
|
type: 'info',
|
|
title: $filter('i18n')('live.chat.notification.title'),
|
|
text: $filter('i18n')('live.chat.ticket.unrelate.confirmation.message'),
|
|
buttons: [
|
|
{
|
|
text: $filter('i18n')('common.button.yes'),
|
|
data: true
|
|
},
|
|
{
|
|
text: $filter('i18n')('common.button.no'),
|
|
data: false
|
|
}
|
|
]
|
|
}).result.then(function (result) {
|
|
if (result) {
|
|
$scope.state.creatingTicket = true;
|
|
var ticketData = { chatSessionId: '' };
|
|
if (data.ticket.id) {
|
|
//update the ticket and clear the chat session
|
|
ticketModel.update(data.ticket.id, data.ticket.type, ticketData).then(function (response) {
|
|
if (response && response.data && response.data.error) {
|
|
systemAlertService.error({ text: response.data.error, clear: true, hide: 10000 });
|
|
$scope.state.creatingTicket = false;
|
|
return;
|
|
}
|
|
var msg = $filter('i18n')('live.chat.ticket.unrelate.success', [utilityFunctions.getTicketCreatedSuccessMessageWithLink(data.ticket.id, data.ticket.displayId, data.ticket.type, true)]);
|
|
systemAlertService.success({ text: msg, clear: true, hide: 10000, isHTML: true });
|
|
$scope.$broadcast('personDataUpdated', true);
|
|
if ($scope.selectedChat.sessionid) {
|
|
getServiceRequestId(data.ticket.type, data.ticket.id, data.ticket.displayId, $scope.selectedChat.sessionid, true);
|
|
}
|
|
var workNote = $filter('i18n')('live.chat.ticket.unrelate.worknote', [$scope.user.fullName]);
|
|
processWorkNote(data.ticket.id, data.ticket.type, { text: workNote });
|
|
if ($scope.selectedChat.applicationData && $scope.selectedChat.applicationData.ticketAssociationDetails &&
|
|
$scope.selectedChat.applicationData.ticketAssociationDetails.associationType === 'create') {
|
|
//remove relationship between tickets
|
|
var parent_1 = {}, relationToRemove = [];
|
|
parent_1.parentType = $scope.selectedChat.applicationData.ticketAssociationDetails.parentType;
|
|
parent_1.parentId = $scope.selectedChat.applicationData.ticketAssociationDetails.parentId;
|
|
var obj = {};
|
|
obj.id = $scope.selectedChat.applicationData.ticketAssociationDetails.id;
|
|
obj.type = $scope.selectedChat.applicationData.ticketAssociationDetails.type;
|
|
obj.details = { 'parentDisplayId': $scope.selectedChat.applicationData.ticketAssociationDetails.parentDisplayId };
|
|
obj.relationshipType = EntityVO.TYPE_RELATEDTO;
|
|
relationToRemove.push(obj);
|
|
relationModel.removeRelation(parent_1, relationToRemove);
|
|
//cancel the ticket
|
|
var confirmationData = {
|
|
confirmationEvent: LIVE_CHAT_APP_EVENTS.app_unrelate_ticket
|
|
};
|
|
updateTicketAndRemoveChat($scope.selectedChat.ticket, confirmationData, null, null, null, true);
|
|
}
|
|
var chatToUpdate = _.findIndex($scope.agentChats, { sid: $scope.selectedChat.sessionid });
|
|
if (chatToUpdate !== -1 && $scope.agentChats[chatToUpdate].selectedChatContext &&
|
|
$scope.agentChats[chatToUpdate].selectedChatContext.ticket) {
|
|
$scope.agentChats[chatToUpdate].selectedChatContext.ticket = null;
|
|
}
|
|
$scope.selectedChat.ticket = null;
|
|
});
|
|
}
|
|
else {
|
|
$scope.state.creatingTicket = false;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
function handleAssignmentComplete(event, data) {
|
|
var ticketDataFromDraft = data.ticket;
|
|
var chatSession = data.chatSession;
|
|
var relatedTicket = $scope.relatedTicketData;
|
|
// clone ticketdata as quickTicketCreateData will shorten data that is being sent to server
|
|
// and ticketDataFromDraft would be needed for draft in Edit Draft Screen.
|
|
var ticketData = _.cloneDeep(ticketDataFromDraft);
|
|
ticketData = quickTicketCreateData(ticketData, $scope.ticketType);
|
|
// quick create mode or open draft by default
|
|
var isDefaultDraftMode = $scope.selectedChatTicketConfig[$scope.ticketType].openDraftModeByDefault;
|
|
if (isDefaultDraftMode === true && $scope.isAutoCreateTicketEnabled === false) {
|
|
ticketModel.cache.draft = ticketDataFromDraft;
|
|
showQuickTicketCreateFailure($scope.draftType, null, chatSession);
|
|
}
|
|
else {
|
|
// Save draft
|
|
ticketModel.saveQuickTicketDraft($scope.ticketType, ticketData).then(function () {
|
|
handleDraftCreateComplete(ticketData, chatSession, relatedTicket);
|
|
}).catch(function (error) {
|
|
ticketModel.cache.draft = ticketDataFromDraft;
|
|
showQuickTicketCreateFailure($scope.draftType, error, chatSession);
|
|
});
|
|
}
|
|
}
|
|
function relateChatToTicket(ticket, session) {
|
|
$scope.relateTicketToChatInProgress = false;
|
|
var ticketData = { chatSessionId: session && session.sessionid };
|
|
if (ticket.id) {
|
|
//update the ticket with the chat session ID
|
|
ticketModel.update(ticket.id, ticket.type, ticketData).then(function (response) {
|
|
if (response && response.data && response.data.error) {
|
|
systemAlertService.error({ text: response.data.error, clear: true, hide: 10000 });
|
|
$scope.state.creatingTicket = false;
|
|
return;
|
|
}
|
|
showQuickTicketCreateSuccess(ticket.type, ticket, session, 'updateTicket');
|
|
});
|
|
}
|
|
}
|
|
function setTicketCreationConfig() {
|
|
$scope.selectedChatTicketConfig = {
|
|
'incident': {
|
|
defaultTemplate: { type: 'incidentTemplate', id: '' },
|
|
openDraftModeByDefault: false
|
|
},
|
|
'workorder': {
|
|
defaultTemplate: { type: 'workorderTemplate', id: '' },
|
|
openDraftModeByDefault: false
|
|
}
|
|
};
|
|
// go thru ticket config only if chat is assigned and has no ticket attached
|
|
if ($scope.selectedChat.status === 'Assigned') {
|
|
if (!$scope.ticketCreationConfigCompanyMap) {
|
|
$scope.isIncidentCreateAllowed = true;
|
|
$scope.isWOCreateAllowed = true;
|
|
$scope.selectedChat.allowedTicketTypes = [EntityVO.TYPE_INCIDENT, EntityVO.TYPE_WORKORDER];
|
|
return;
|
|
}
|
|
var companyName = $scope.context.company ? $scope.context.company.toLowerCase() : 'global';
|
|
var ticketTypesConfigList = $scope.ticketCreationConfigCompanyMap[companyName];
|
|
if (!ticketTypesConfigList) {
|
|
ticketTypesConfigList = $scope.ticketCreationConfigCompanyMap.global; //lowercase
|
|
}
|
|
if ($scope.selectedChat.ticket) {
|
|
var ticketType = $scope.selectedChat.ticket.ticketType;
|
|
if (ticketTypesConfigList[ticketType].openTicketOnClose) {
|
|
// adding option to force edit mode from config if 'forceEdit' value is set,
|
|
// till we don't allow edit mode OOTB
|
|
if (ticketTypesConfigList[ticketType].openTicketOnCloseMode !== 'view'
|
|
&& ticketTypesConfigList[ticketType].openTicketOnCloseMode !== 'forceEdit') {
|
|
// if mode value is incorrect, default to view
|
|
ticketTypesConfigList[ticketType].openTicketOnCloseMode = 'view';
|
|
}
|
|
$scope.selectedChatTicketConfig[ticketType].openTicketOnClose = ticketTypesConfigList[ticketType].openTicketOnClose;
|
|
$scope.selectedChatTicketConfig[ticketType].openTicketOnCloseMode = ticketTypesConfigList[ticketType].openTicketOnCloseMode;
|
|
}
|
|
}
|
|
else {
|
|
$scope.isAutoCreateTicketEnabled = ticketTypesConfigList.autoCreate || false;
|
|
// ignore the custom create options from MCR if auto create is not ON
|
|
if (!$scope.isAutoCreateTicketEnabled) {
|
|
$scope.selectedChat.autoCreateTicketType = undefined;
|
|
$scope.selectedChat.autoCreateTemplateId = undefined;
|
|
}
|
|
else {
|
|
$scope.autoCreateDefaultTicket = $scope.selectedChat.autoCreateTicketType;
|
|
}
|
|
if ($scope.autoCreateDefaultTicket !== EntityVO.TYPE_INCIDENT
|
|
&& $scope.autoCreateDefaultTicket !== EntityVO.TYPE_WORKORDER) {
|
|
// if auto create ticket type from MCR is invalid, then clear the incorrect values
|
|
// if auto create ticket type from MCR is invalid, then clear the incorrect values
|
|
// if auto create ticket type from MCR is invalid, then clear the incorrect values
|
|
// and ignore the template id from MCR as well
|
|
$scope.autoCreateDefaultTicket = null;
|
|
$scope.selectedChat.autoCreateTemplateId = undefined;
|
|
}
|
|
if ($scope.autoCreateDefaultTicket === null
|
|
&& (ticketTypesConfigList.autoCreateDefaultTicket === EntityVO.TYPE_INCIDENT
|
|
|| ticketTypesConfigList.autoCreateDefaultTicket === EntityVO.TYPE_WORKORDER)) {
|
|
// validate auto create default ticket type from config
|
|
$scope.autoCreateDefaultTicket = ticketTypesConfigList.autoCreateDefaultTicket;
|
|
}
|
|
if (ticketTypesConfigList && ticketTypesConfigList.hasOwnProperty(EntityVO.TYPE_INCIDENT)) {
|
|
var incidentTicketConfig = ticketTypesConfigList[EntityVO.TYPE_INCIDENT];
|
|
$scope.isIncidentCreateAllowed = (incidentTicketConfig.hideCreateOption === true) ? false : true;
|
|
$scope.selectedChatTicketConfig.incident.openDraftModeByDefault = incidentTicketConfig.openDraftModeByDefault || false;
|
|
// either manual creation of incident is allowed or incident is the default ticket type for autoCreate
|
|
var ticketTemplateId = $scope.selectedChat.autoCreateTemplateId || incidentTicketConfig.defaultTemplateId;
|
|
if (($scope.isIncidentCreateAllowed === true
|
|
|| ($scope.isAutoCreateTicketEnabled && $scope.autoCreateDefaultTicket === EntityVO.TYPE_INCIDENT))
|
|
&& ticketTemplateId) {
|
|
$scope.selectedChatTicketConfig.incident.defaultTemplate.id = ticketTemplateId;
|
|
}
|
|
}
|
|
else {
|
|
// we default to always showing the option
|
|
$scope.isIncidentCreateAllowed = true;
|
|
}
|
|
if ($scope.isWOInstalled && ticketTypesConfigList && ticketTypesConfigList.hasOwnProperty(EntityVO.TYPE_WORKORDER)) {
|
|
var woTicketConfig = ticketTypesConfigList[EntityVO.TYPE_WORKORDER];
|
|
$scope.isWOCreateAllowed = (woTicketConfig.hideCreateOption === true) ? false : true;
|
|
$scope.selectedChatTicketConfig.workorder.openDraftModeByDefault = woTicketConfig.openDraftModeByDefault || false;
|
|
// either manual creation of WO is allowed or WO is the default ticket type for autoCreate
|
|
var ticketTemplateId = $scope.selectedChat.autoCreateTemplateId || woTicketConfig.defaultTemplateId;
|
|
if (($scope.isWOCreateAllowed === true
|
|
|| ($scope.isAutoCreateTicketEnabled && $scope.autoCreateDefaultTicket === EntityVO.TYPE_WORKORDER))
|
|
&& ticketTemplateId) {
|
|
$scope.selectedChatTicketConfig.workorder.defaultTemplate.id = ticketTemplateId;
|
|
}
|
|
}
|
|
else if ($scope.isWOInstalled) {
|
|
// we default to always showing the option
|
|
$scope.isWOCreateAllowed = true;
|
|
}
|
|
else {
|
|
$scope.isWOCreateAllowed = false;
|
|
}
|
|
if ($scope.isAutoCreateTicketEnabled && $scope.autoCreateDefaultTicket) {
|
|
$scope.createTicket($scope.autoCreateDefaultTicket);
|
|
}
|
|
else if (!$scope.isAutoCreateTicketEnabled) {
|
|
// fetch templates only for tickets that we are displaying on UI
|
|
var ticketTypesAllowed = [];
|
|
if ($scope.isIncidentCreateAllowed) {
|
|
ticketTypesAllowed.push(EntityVO.TYPE_INCIDENT);
|
|
}
|
|
if ($scope.isWOInstalled && $scope.isWOCreateAllowed) {
|
|
ticketTypesAllowed.push(EntityVO.TYPE_WORKORDER);
|
|
}
|
|
// do not search templates if no ticket types are allowed
|
|
if (ticketTypesAllowed.length === 0) {
|
|
ticketTypesAllowed.push('none');
|
|
}
|
|
$scope.context.searchTicketTypes = ticketTypesAllowed;
|
|
$scope.selectedChat.allowedTicketTypes = ticketTypesAllowed;
|
|
// set template as selected in resources tab only if one ticket type is allowed
|
|
if (ticketTypesAllowed.length === 1) {
|
|
var isTemplateSelectedForChat = false;
|
|
var agentChatIndex = _.findIndex($scope.agentChats, { sid: $scope.selectedChat.sessionid });
|
|
if (agentChatIndex !== -1) {
|
|
if ($scope.agentChats[agentChatIndex].selectedChatContext && $scope.agentChats[agentChatIndex].selectedChatContext.selectedTemplate) {
|
|
isTemplateSelectedForChat = true;
|
|
}
|
|
}
|
|
if (!isTemplateSelectedForChat) {
|
|
// show default template as selected in resources tab
|
|
saveTemplate({}, $scope.selectedChatTicketConfig[ticketTypesAllowed[0]].defaultTemplate);
|
|
$scope.context.selectedTemplate = $scope.selectedTemplate;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function chatCustomerDataLoaded(event, person) {
|
|
if ($scope.selectedChat.user === person.id) {
|
|
$scope.selectedChat.customer = person;
|
|
$scope.selectedChat.customerCompany = person.company;
|
|
$scope.context.chatUserCompany = person.company && person.company.name;
|
|
// for templates, we want to use customer's company
|
|
$scope.context.company = $scope.context.chatUserCompany;
|
|
$scope.context.customerId = person.id;
|
|
// set ticket creation config whenever we switch a chat
|
|
setTicketCreationConfig();
|
|
}
|
|
else if ($scope.selectedChat.user !== personModel.personDetails.id) {
|
|
personModel.getPersonDetailsByID($scope.selectedChat.user)
|
|
.then(function (personDetails) {
|
|
personModel.personDetails = personDetails;
|
|
$scope.$broadcast('personDataUpdated');
|
|
});
|
|
console.warn('selected chat user id: ' + $scope.selectedChat.user + ', does not match with person id: ' + person.id);
|
|
}
|
|
}
|
|
function clearChatContext(removeChat) {
|
|
if (removeChat) {
|
|
var removeChat_1 = _.findIndex($scope.agentChats, { sid: $scope.selectedChat.sessionid });
|
|
if (removeChat_1 !== -1) {
|
|
$scope.agentChats.splice(removeChat_1, 1);
|
|
}
|
|
}
|
|
$scope.selectedChat = null;
|
|
$scope.$broadcast(events.ON_SELECTED_LIVE_CHAT);
|
|
personModel.personDetails = [];
|
|
$scope.$broadcast('personDataUpdated');
|
|
$timeout(function () {
|
|
$scope.state.appModalEventConfirmWaiting = false;
|
|
}, 1000);
|
|
}
|
|
// call back used by resource slice directive to save selected template
|
|
function saveTemplate(event, template) {
|
|
if ($scope.selectedChat && template && template.id) {
|
|
// allow the template to be set only if that ticket create is allowed
|
|
if (($scope.isWOCreateAllowed && template.type === 'workorderTemplate')
|
|
|| ($scope.isIncidentCreateAllowed && template.type === 'incidentTemplate')) {
|
|
$scope.selectedTemplate = template;
|
|
var agentChat = _.findIndex($scope.agentChats, { sid: $scope.selectedChat.sessionid });
|
|
if (agentChat !== -1) {
|
|
if ($scope.agentChats[agentChat].selectedChatContext) {
|
|
$scope.agentChats[agentChat].selectedChatContext.selectedTemplate = $scope.selectedTemplate;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// call back used by resource slice directive to delete previously selected template
|
|
function unrelateTemplate() {
|
|
if ($scope.selectedChat) {
|
|
$scope.selectedTemplate = null;
|
|
var agentChat = _.findIndex($scope.agentChats, { sid: $scope.selectedChat.sessionid });
|
|
if (agentChat !== -1) {
|
|
if ($scope.agentChats[agentChat].selectedChatContext) {
|
|
$scope.agentChats[agentChat].selectedChatContext.selectedTemplate = $scope.selectedTemplate;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// call back used by resource slice directive to save selected KA
|
|
function saveToTicketFromRs(event, relationItem, isKASharedWithUser) {
|
|
if ($scope.selectedChat) {
|
|
angular.extend(relationItem, {
|
|
tag: EntityVO.TYPE_RESOURCE,
|
|
relationshipType: RelationItemVO.TYPE_RELATEDTO,
|
|
isKASharedWithUser: isKASharedWithUser
|
|
});
|
|
var agentChatIdx = _.findIndex($scope.agentChats, { sid: $scope.selectedChat.sessionid });
|
|
if (agentChatIdx !== -1) {
|
|
if ($scope.agentChats[agentChatIdx].selectedChatContext) {
|
|
if ($scope.agentChats[agentChatIdx].selectedChatContext.selectedKnowledge) {
|
|
var isRelatedItem = _.findIndex($scope.agentChats[agentChatIdx].selectedChatContext.selectedKnowledge, { id: relationItem.id });
|
|
if (isRelatedItem === -1) {
|
|
$scope.agentChats[agentChatIdx].selectedChatContext.selectedKnowledge.push(relationItem);
|
|
}
|
|
}
|
|
else {
|
|
$scope.agentChats[agentChatIdx].selectedChatContext.selectedKnowledge = [];
|
|
$scope.agentChats[agentChatIdx].selectedChatContext.selectedKnowledge.push(relationItem);
|
|
}
|
|
}
|
|
}
|
|
//save pinned articles in app data field on MCR
|
|
sendApplicationData($scope.selectedChat.sessionid, null, null, null, $scope.agentChats[agentChatIdx].selectedChatContext);
|
|
relationModel.cache[$scope.selectedChat.sessionid] = relationModel.cache[$scope.selectedChat.sessionid] && relationModel.cache[$scope.selectedChat.sessionid].length ? relationModel.cache[$scope.selectedChat.sessionid] : [];
|
|
var relationItemIdx = _.findIndex(relationModel.cache[$scope.selectedChat.sessionid], { id: relationItem.id });
|
|
if (relationItemIdx === -1) {
|
|
relationModel.cache[$scope.selectedChat.sessionid].push(relationItem);
|
|
}
|
|
}
|
|
}
|
|
// call back used by resource slice directive to delete previously selected KA
|
|
function removeFromTicketFromRs(event, relationItem) {
|
|
if ($scope.selectedChat) {
|
|
var agentChatIdx = _.findIndex($scope.agentChats, { sid: $scope.selectedChat.sessionid });
|
|
if (agentChatIdx !== -1) {
|
|
if ($scope.agentChats[agentChatIdx].selectedChatContext &&
|
|
$scope.agentChats[agentChatIdx].selectedChatContext.selectedKnowledge) {
|
|
var removeIdx = _.findIndex($scope.agentChats[agentChatIdx].selectedChatContext.selectedKnowledge, { id: relationItem.id });
|
|
$scope.agentChats[agentChatIdx].selectedChatContext.selectedKnowledge.splice(removeIdx, 1);
|
|
}
|
|
}
|
|
//save pinned articles in app data field on MCR
|
|
sendApplicationData($scope.selectedChat.sessionid, null, null, null, $scope.agentChats[agentChatIdx].selectedChatContext);
|
|
if (relationModel.cache[$scope.selectedChat.sessionid] && relationModel.cache[$scope.selectedChat.sessionid].length > 0) {
|
|
var relationItemIdx = _.findIndex(relationModel.cache[$scope.selectedChat.sessionid], { id: relationItem.id });
|
|
relationModel.cache[$scope.selectedChat.sessionid].splice(relationItemIdx, 1);
|
|
}
|
|
}
|
|
}
|
|
function saveSearchTextToselectedChatContext(event, searchText) {
|
|
if ($scope.selectedChat) {
|
|
var agentChat = _.findIndex($scope.agentChats, { sid: $scope.selectedChat.sessionid });
|
|
if (agentChat !== -1) {
|
|
if ($scope.agentChats[agentChat].selectedChatContext) {
|
|
$scope.agentChats[agentChat].selectedChatContext.summaryText = searchText;
|
|
//save search text to app data on MCR
|
|
sendApplicationData($scope.selectedChat.sessionid, null, null, null, $scope.agentChats[agentChat].selectedChatContext);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// send message to chat conversation
|
|
function sendMessageToChat(event, message, sessionId) {
|
|
if (!$scope.selectedChat) {
|
|
return;
|
|
}
|
|
var messageToSend, chatSessionId;
|
|
//if sharing a KA
|
|
if (message.type === EntityVO.TYPE_KNOWLEDGE) {
|
|
if (!message.additionalInformation && !message.additionalInformation.crossLaunchURL) {
|
|
return;
|
|
}
|
|
else {
|
|
var midtierCrossLaunchURLForKA = message.additionalInformation && message.additionalInformation.crossLaunchURL;
|
|
var KAShareMsg = $filter('i18n')('live.chat.KA.sharedWithUser');
|
|
messageToSend = "<span>" + KAShareMsg + "<br><a href=\'" + midtierCrossLaunchURLForKA + "\' target=\'_blank\'>" + message.displayId + ": " + message.title + "</a><\/span>";
|
|
//shared articles should be saved to the ticket
|
|
saveToTicketFromRs(event, message, true);
|
|
chatSessionId = $scope.selectedChat.sessionid;
|
|
}
|
|
}
|
|
else {
|
|
messageToSend = message.messageToSend;
|
|
chatSessionId = sessionId;
|
|
}
|
|
var data = {
|
|
data: { chatSessionId: chatSessionId, messageToSend: messageToSend, type: message.type, ticketId: message.ticketId || message.displayId },
|
|
event: LIVE_CHAT_APP_EVENTS.app_send_message_to_chat
|
|
};
|
|
sendChildMessage(data);
|
|
}
|
|
function showModalDialog(data) {
|
|
var title = data.chatData.modalTitle, message, buttons, confirmationData = {
|
|
confirmationData: data.action.confirmationData,
|
|
confirmationEvent: data.action.confirmationEvent
|
|
};
|
|
if (data.action.confirmationEvent === LIVE_CHAT_APP_EVENTS.app_event_confirm_close_session
|
|
|| data.action.confirmationEvent === LIVE_CHAT_APP_EVENTS.app_event_confirm_abandon_session) {
|
|
if ($scope.selectedChat.ticket) {
|
|
if (data.action.confirmationEvent === LIVE_CHAT_APP_EVENTS.app_event_confirm_close_session) {
|
|
ticketModel.getTicketDetails($scope.selectedChat.ticket.ticketId, $scope.selectedChat.ticket.ticketType, true).then(function (response) {
|
|
if (response) {
|
|
if (response.status && response.status.value) {
|
|
if ((response.type === EntityVO.TYPE_INCIDENT && (response.status.value === 'Resolved'
|
|
|| response.status.value === 'Cancelled' || response.status.value === 'Closed')) ||
|
|
(response.type === EntityVO.TYPE_WORKORDER && (response.status.value === 'Completed'
|
|
|| response.status.value === 'Cancelled' || response.status.value === 'Closed'))) {
|
|
message = data.chatData && data.chatData.modalMessage ? data.chatData.modalMessage :
|
|
$filter('i18n')('live.chat.close.with.closed.ticket', [data.chatData.session.user.first_name, data.chatData.session.user.last_name]);
|
|
buttons = getButtonsForDialog(false, confirmationData, data);
|
|
openModalDialog(title, message, buttons, null, true);
|
|
}
|
|
else {
|
|
message = i18nService.getLocalizedString('live.chat.close.with.ticket');
|
|
buttons = getButtonsForDialog(true, confirmationData, data);
|
|
openModalDialog(title, message, buttons);
|
|
}
|
|
}
|
|
else {
|
|
//DRSMX-30719 - if the agent doesn't have access rights on the ticket, we will only close the chat and do nothing with the ticket
|
|
message = data.chatData && data.chatData.modalMessage ? data.chatData.modalMessage :
|
|
$filter('i18n')('live.chat.close.with.closed.ticket', [data.chatData.session.user.first_name, data.chatData.session.user.last_name]);
|
|
buttons = getButtonsForDialog(false, confirmationData, data);
|
|
openModalDialog(title, message, buttons, true);
|
|
}
|
|
}
|
|
else {
|
|
message = i18nService.getLocalizedString('live.chat.close.with.ticket');
|
|
buttons = getButtonsForDialog(true, confirmationData, data);
|
|
openModalDialog(title, message, buttons);
|
|
}
|
|
}).catch(function (error) {
|
|
message = i18nService.getLocalizedString('live.chat.close.with.ticket');
|
|
buttons = getButtonsForDialog(true, confirmationData, data);
|
|
openModalDialog(title, message, buttons);
|
|
});
|
|
}
|
|
else if (data.action.confirmationEvent === LIVE_CHAT_APP_EVENTS.app_event_confirm_abandon_session) {
|
|
message = i18nService.getLocalizedString('live.chat.abandon.with.ticket');
|
|
buttons = getButtonsForDialog(false, confirmationData, data);
|
|
openModalDialog(title, message, buttons);
|
|
}
|
|
}
|
|
else {
|
|
message = (data.action.confirmationEvent === LIVE_CHAT_APP_EVENTS.app_event_confirm_close_session) ?
|
|
i18nService.getLocalizedString('live.chat.close.without.ticket') :
|
|
i18nService.getLocalizedString('live.chat.abandon.without.ticket');
|
|
buttons = getButtonsForDialog(false, confirmationData, data);
|
|
openModalDialog(title, message, buttons);
|
|
}
|
|
}
|
|
else {
|
|
message = data.chatData.modalMessage;
|
|
buttons = getButtonsForDialog(false, confirmationData, data);
|
|
openModalDialog(title, message, buttons);
|
|
}
|
|
}
|
|
function getButtonsForDialog(showThreeBtns, confirmationData, sessionData) {
|
|
var buttons;
|
|
if (showThreeBtns) {
|
|
buttons = [
|
|
{
|
|
text: i18nService.getLocalizedString('common.button.yes'),
|
|
data: { option: 'yes', confirmationData: confirmationData, session: sessionData.chatData.session }
|
|
},
|
|
{
|
|
text: i18nService.getLocalizedString('common.button.no'),
|
|
data: { option: 'no', confirmationData: confirmationData, session: sessionData.chatData.session }
|
|
},
|
|
{
|
|
text: i18nService.getLocalizedString('common.button.cancel'),
|
|
data: false
|
|
}
|
|
];
|
|
}
|
|
else {
|
|
buttons = [
|
|
{
|
|
text: i18nService.getLocalizedString('common.button.yes'),
|
|
data: { option: 'yes', confirmationData: confirmationData, session: sessionData.chatData.session }
|
|
},
|
|
{
|
|
text: i18nService.getLocalizedString('common.button.cancel'),
|
|
data: false
|
|
}
|
|
];
|
|
}
|
|
return buttons;
|
|
}
|
|
function addResourceRelations(transformedRelations, ticketData, ticketId, ticketType) {
|
|
_.forEach(transformedRelations, function (relation) {
|
|
delete relation.isKASharedWithUser;
|
|
});
|
|
if (transformedRelations.length > 0) {
|
|
if (configurationModel.comaroundEnabled) {
|
|
var hkmKAList = _.remove(transformedRelations, { type: EntityVO.TYPE_KNOWLEDGE });
|
|
if (hkmKAList && hkmKAList.length) {
|
|
relationModel.bulkAddRelationHKM({
|
|
uuid: ticketData.displayId || ticketData.ticketDisplayId
|
|
}, hkmKAList);
|
|
}
|
|
}
|
|
if (transformedRelations.length > 0) {
|
|
addRelation(ticketId, ticketType, transformedRelations);
|
|
}
|
|
}
|
|
}
|
|
function openModalDialog(title, message, buttons, noAccessToTicket, isTicketClosed) {
|
|
systemAlertService.modal({
|
|
title: title,
|
|
text: message,
|
|
buttons: buttons
|
|
}).result.then(function (data) {
|
|
if (data) {
|
|
$scope.state.appModalEventConfirmWaiting = true;
|
|
var removeChat = _.findIndex($scope.agentChats, { sid: $scope.selectedChat.sessionid });
|
|
if (!noAccessToTicket) {
|
|
var ticketData = $scope.agentChats[removeChat] && $scope.agentChats[removeChat].selectedChatContext && $scope.agentChats[removeChat].selectedChatContext.ticket;
|
|
if (data.confirmationData.confirmationEvent === LIVE_CHAT_APP_EVENTS.app_event_confirm_close_session
|
|
|| data.confirmationData.confirmationEvent === LIVE_CHAT_APP_EVENTS.app_event_confirm_abandon_session) {
|
|
if (ticketData) {
|
|
if (data.option === 'yes' && !isTicketClosed) {
|
|
if (ticketData.ticketDisplayId || ticketData.ticketType || ticketData.ticketId) {
|
|
updateTicketAndRemoveChat(ticketData, data.confirmationData, data.session, null, null, null, true);
|
|
return;
|
|
}
|
|
}
|
|
else if (data.option === 'no' || isTicketClosed) {
|
|
addWorkNoteForTicket(data.session, ticketData);
|
|
if ($scope.agentChats[removeChat].selectedChatContext && $scope.agentChats[removeChat].selectedChatContext.selectedKnowledge) {
|
|
var transformedRelations = saveRelatedResources($scope.agentChats[removeChat].selectedChatContext.selectedKnowledge, $scope.selectedChat.sessionid);
|
|
addResourceRelations(transformedRelations, ticketData, ticketData.ticketId, ticketData.ticketType);
|
|
}
|
|
openTicketOnChatClose(ticketData.ticketId, ticketData.ticketType);
|
|
clearChatContext(true);
|
|
}
|
|
}
|
|
else {
|
|
//create call log
|
|
createCallLog($scope.selectedChat);
|
|
clearChatContext(true);
|
|
}
|
|
}
|
|
else if (data.confirmationData.confirmationEvent === LIVE_CHAT_APP_EVENTS.app_event_confirm_release_session) {
|
|
clearChatContext(true);
|
|
}
|
|
}
|
|
else {
|
|
clearChatContext(true);
|
|
}
|
|
sendChildMessage({
|
|
data: data.confirmationData.confirmationData,
|
|
event: data.confirmationData.confirmationEvent
|
|
});
|
|
}
|
|
});
|
|
}
|
|
function updateTicketAndRemoveChat(ticket, confirmationData, session, cancelledByEndUser, chatSessionIdToRemove, removeTicketAssociation, clearChat) {
|
|
var statusData;
|
|
metadataModel.getMetadataByType(ticket.ticketType).then(function (results) {
|
|
var ticketMetaData = results && results.statuses;
|
|
var status, statusReason, resNote;
|
|
//mark ticket as resolved
|
|
if (ticket.ticketType === EntityVO.TYPE_INCIDENT) {
|
|
if (confirmationData.confirmationEvent === LIVE_CHAT_APP_EVENTS.app_event_confirm_close_session) {
|
|
status = _.find(ticketMetaData, { name: 'Resolved' });
|
|
statusReason = _.find(status.statusReasons, { name: 'No Further Action Required' });
|
|
}
|
|
else {
|
|
status = _.find(ticketMetaData, { name: 'Cancelled' });
|
|
statusReason = _.find(status.statusReasons, { name: 'No longer a Causal CI' });
|
|
}
|
|
if (confirmationData.confirmationEvent === LIVE_CHAT_APP_EVENTS.app_event_confirm_close_session ||
|
|
confirmationData.confirmationEvent === LIVE_CHAT_EVENTS.sac_session_cancelled) {
|
|
resNote = $filter('i18n')('live.chat.close.resolution.note');
|
|
}
|
|
else if (confirmationData.confirmationEvent === LIVE_CHAT_APP_EVENTS.app_unrelate_ticket) {
|
|
resNote = $filter('i18n')('live.chat.ticket.unrelate.success', [ticket.ticketDisplayId]);
|
|
}
|
|
else {
|
|
resNote = $filter('i18n')('live.chat.abandon.resolution.note');
|
|
}
|
|
statusData = {
|
|
status: status.name,
|
|
statusReason: statusReason.name,
|
|
resNote: resNote
|
|
};
|
|
}
|
|
else if (ticket.ticketType === EntityVO.TYPE_WORKORDER) {
|
|
if (confirmationData.confirmationEvent === LIVE_CHAT_APP_EVENTS.app_event_confirm_close_session) {
|
|
status = _.find(ticketMetaData, { name: 'Completed' });
|
|
statusReason = _.find(status.statusReasons, { name: 'Successful' });
|
|
}
|
|
else {
|
|
status = _.find(ticketMetaData, { name: 'Cancelled' });
|
|
statusReason = confirmationData.confirmationEvent === LIVE_CHAT_EVENTS.sac_session_cancelled ?
|
|
_.find(status.statusReasons, { name: 'Cancelled by Requester' }) :
|
|
_.find(status.statusReasons, { name: 'Cancelled by Support' });
|
|
}
|
|
if (confirmationData.confirmationEvent === LIVE_CHAT_APP_EVENTS.app_event_confirm_close_session) {
|
|
resNote = $filter('i18n')('live.chat.close.resolution.note');
|
|
}
|
|
else if (confirmationData.confirmationEvent === LIVE_CHAT_APP_EVENTS.app_unrelate_ticket) {
|
|
resNote = $filter('i18n')('live.chat.ticket.unrelate.success', [ticket.ticketDisplayId]);
|
|
}
|
|
else {
|
|
resNote = $filter('i18n')('live.chat.abandon.resolution.note');
|
|
}
|
|
statusData = {
|
|
status: status.name,
|
|
statusReason: statusReason.name,
|
|
resNote: resNote
|
|
};
|
|
}
|
|
if (ticket.ticketId) {
|
|
ticketModel.update(ticket.ticketId, ticket.ticketType, statusData, cancelledByEndUser).then(function (response) {
|
|
if (removeTicketAssociation) {
|
|
return;
|
|
}
|
|
//if the chat was cancelled by the end user and if the agent does not have access to update the ticket, there will be an error.
|
|
//Trap the error and update the work notes and indicate the assignee to close the ticket
|
|
if (response && response.status === 500) {
|
|
var workNote = void 0;
|
|
if (cancelledByEndUser) {
|
|
workNote = $filter('i18n')('live.chat.cancel.enduser.worknote');
|
|
}
|
|
else {
|
|
workNote = resNote;
|
|
}
|
|
processWorkNote(ticket.ticketId, ticket.ticketType, { text: workNote });
|
|
}
|
|
//if there is no error, update work notes with chat log, chat inline notes and attachments
|
|
if (session) {
|
|
addWorkNoteForTicket(session, ticket);
|
|
}
|
|
var transformedRelations = saveRelatedResources(null, session.sessionid);
|
|
addResourceRelations(transformedRelations, ticket, ticket.ticketId, ticket.ticketType);
|
|
if (clearChat) {
|
|
openTicketOnChatClose(ticket.ticketId, ticket.ticketType);
|
|
sendChildMessage({
|
|
data: confirmationData.confirmationData,
|
|
event: confirmationData.confirmationEvent
|
|
});
|
|
if ($scope.selectedChat.sessionid === confirmationData.confirmationData) {
|
|
clearChatContext(true);
|
|
}
|
|
}
|
|
if (!chatSessionIdToRemove && $scope.selectedChat.sessionid === confirmationData.confirmationData) {
|
|
$scope.selectedChat = null;
|
|
return;
|
|
}
|
|
if ((chatSessionIdToRemove && chatSessionIdToRemove === $scope.selectedChat.sessionid) || $scope.selectedChat.sessionid === confirmationData.confirmationData) {
|
|
$scope.selectedChat = null;
|
|
}
|
|
});
|
|
}
|
|
else {
|
|
var ticketInfo_4, params = {
|
|
search_text: ticket.ticketDisplayId
|
|
}, jsonParams = {
|
|
types: ['tickets']
|
|
};
|
|
searchService.getGlobalSearchResults(params, jsonParams).then(function (response) {
|
|
if (!_.isEmpty(response.items) && response.items[0] && response.items[0].results && response.items[0].results.length) {
|
|
ticketInfo_4 = _.find(response.items[0].results, { displayId: ticket.ticketDisplayId });
|
|
ticketModel.update(ticketInfo_4.id, ticketInfo_4.type, statusData).then(function () {
|
|
if (removeTicketAssociation) {
|
|
return;
|
|
}
|
|
//update work notes
|
|
if (session) {
|
|
addWorkNoteForTicket(session, ticket);
|
|
}
|
|
//update the ticket with any selected KA
|
|
var transformedRelations = saveRelatedResources(null, session.sessionid);
|
|
addResourceRelations(transformedRelations, ticketInfo_4, ticketInfo_4.id, ticketInfo_4.type);
|
|
if (!chatSessionIdToRemove) {
|
|
$scope.selectedChat = null;
|
|
return;
|
|
}
|
|
if (chatSessionIdToRemove && chatSessionIdToRemove === $scope.selectedChat.sessionid) {
|
|
$scope.selectedChat = null;
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
function openTicketOnChatClose(ticketId, ticketType) {
|
|
var ticketConfig = $scope.selectedChatTicketConfig[ticketType];
|
|
var openTicketOnClose = ticketConfig.openTicketOnClose;
|
|
if (openTicketOnClose) {
|
|
$scope.hasEditPermission = permissionModel.hasPermissionForTicket(ticketType);
|
|
if (ticketConfig.openTicketOnCloseMode === 'forceEdit') {
|
|
ticketConfig.openTicketOnCloseMode = 'edit';
|
|
}
|
|
if ((ticketConfig.openTicketOnCloseMode === 'edit' && $scope.hasEditPermission)
|
|
|| (ticketConfig.openTicketOnCloseMode === 'view')) {
|
|
var url = $state.href('liveChatDraft', { id: ticketId, draftType: ticketType, launchMode: ticketConfig.openTicketOnCloseMode });
|
|
$window.open(url, '_blank', 'noopener, noreferrer');
|
|
}
|
|
}
|
|
}
|
|
function saveRelatedResources(selectedResourcesToSave, chatSessionId) {
|
|
// Save related resources.
|
|
var transformedRelations = [];
|
|
var relations;
|
|
if (selectedResourcesToSave) {
|
|
relations = selectedResourcesToSave;
|
|
}
|
|
else {
|
|
var agentChatIndex = _.findIndex($scope.agentChats, { sid: chatSessionId });
|
|
if (agentChatIndex !== -1) {
|
|
if ($scope.agentChats[agentChatIndex].selectedChatContext &&
|
|
$scope.agentChats[agentChatIndex].selectedChatContext.selectedKnowledge) {
|
|
relations = $scope.agentChats[agentChatIndex].selectedChatContext.selectedKnowledge;
|
|
}
|
|
}
|
|
}
|
|
if (relations) {
|
|
for (var relationCounter = 0; relationCounter < relations.length; relationCounter++) {
|
|
var relation = relations[relationCounter];
|
|
relation = new RelationItemVO().build(relation);
|
|
relation.isPoi = undefined;
|
|
relation.realObject = undefined;
|
|
relation.entityLink = undefined;
|
|
relation.isKASharedWithUser = relations[relationCounter].isKASharedWithUser;
|
|
if (!relation.tag) {
|
|
relation.tag = EntityVO.TYPE_RESOURCE;
|
|
}
|
|
if (!relation.relationshipType) {
|
|
relation.relationshipType = EntityVO.TYPE_RELATEDTO;
|
|
}
|
|
if (!relation.type) {
|
|
relation.type = EntityVO.TYPE_KNOWLEDGE;
|
|
}
|
|
transformedRelations.push(relation);
|
|
}
|
|
}
|
|
return transformedRelations;
|
|
}
|
|
function quickTicketCreateData(ticketData, ticketType) {
|
|
var createData, ticket;
|
|
delete ticketData.accessMappings;
|
|
if (ticketData.customer.accessMappings) {
|
|
delete ticketData.customer.accessMappings;
|
|
}
|
|
if (ticketType === EntityVO.TYPE_INCIDENT) {
|
|
if (ticketData.causalCI === '') {
|
|
delete ticketData.causalCI;
|
|
delete ticketData.causalCIreconId;
|
|
}
|
|
if (ticketData.impactedService === '') {
|
|
delete ticketData.impactedService;
|
|
delete ticketData.impactedServiceReconId;
|
|
}
|
|
if (ticketData.contact && ticketData.contact.accessMappings) {
|
|
delete ticketData.contact.accessMappings;
|
|
}
|
|
}
|
|
else if (ticketType === EntityVO.TYPE_WORKORDER) {
|
|
ticket = ticketData;
|
|
createData = {
|
|
id: ticket.id,
|
|
displayId: ticket.displayId,
|
|
summary: ticket.summary,
|
|
customer: ticket.customer,
|
|
desc: ticket.desc,
|
|
priority: ticket.priority,
|
|
status: ticket.status,
|
|
categorizations: ticket.categorizations,
|
|
type: EntityVO.TYPE_WORKORDER
|
|
};
|
|
if (ticket.reportedSource) {
|
|
createData.reportedSource = ticket.reportedSource;
|
|
}
|
|
if (ticket.location && ticket.location.poiId) {
|
|
createData.location = { poiId: ticket.location.poiId };
|
|
}
|
|
if (ticket.locationCompany) {
|
|
createData.locationCompany = ticket.locationCompany;
|
|
}
|
|
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.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;
|
|
}
|
|
if (ticket.chatSessionId) {
|
|
createData.chatSessionId = ticket.chatSessionId;
|
|
}
|
|
ticketData = createData;
|
|
}
|
|
return ticketData;
|
|
}
|
|
function initAlertForDirtyForm() {
|
|
var text;
|
|
$scope.$on('$stateChangeStart', function (event, toState, toParams) {
|
|
if ($scope.isDirtyFlag === true && !$scope.state.loadingLiveChat &&
|
|
(toState.name !== 'liveChatAgentConsole' || toState.name !== 'liveChatDashboard')) {
|
|
event.preventDefault();
|
|
if ($scope.noOfDraftScreensOpen > 0) {
|
|
text = $filter('i18n')('live.chat.data-loss.notification.dirty.message');
|
|
}
|
|
else {
|
|
text = i18nService.getLocalizedString('live.chat.notification.dirty.message');
|
|
}
|
|
var modalInstance = systemAlertService.modal({
|
|
title: i18nService.getLocalizedString('common.notification.dirty.title'),
|
|
text: text,
|
|
buttons: [
|
|
{
|
|
text: i18nService.getLocalizedString('common.labels.yes'),
|
|
data: {
|
|
stateName: toState.name,
|
|
stateParams: toParams
|
|
}
|
|
},
|
|
{
|
|
text: i18nService.getLocalizedString('common.labels.no')
|
|
}
|
|
]
|
|
});
|
|
modalInstance.result.then(function (data) {
|
|
if (!_.isEmpty(data)) {
|
|
$scope.isDirtyFlag = false;
|
|
$scope.noOfDraftScreensOpen = 0;
|
|
unregisterLiveChatListener();
|
|
$state.transitionTo(data.stateName, data.stateParams);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
init();
|
|
}
|
|
]);
|
|
})();
|