SmartIT_Extensions/BMC/smart-it-full-helix/scripts/app/live-chat/live-chat-controller.js

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