/********************************************************
Developer: Cognizant Developer
Date: 20th Oct, 2017
Description: This apex class will be used as handler for S360_TeleSales_LeadTrigger.
Test Class: S360_TeleSales_IntegrationTest, S360_TeleSales_LeadTriggerHandler_Test
Change History
****************************************************************
Change# Last Modified By Date Description
****************************************************************
C1 Cognizant Developer 10-Jan-2018 Phone number formatting implemented : PR18000128
C2 Cognizant Developer 25-Jan-2018 Cancel request for lead id which got Status connected has already been send to Dialer before : PR18000128
C3 Cognizant Developer 02-Apr-2018 Case # 30992477 - IR14187969 - 2Way Connect
C4 Cognizant Developer 20-June-2018 Case # 32164661 JIRA# SP-460 PR18000128- Enhance Two Way Connect for Telesales- Sprint 3 changes for Scheduled Call
C5 Cognizant Developer 16-July-2018 Case # 33822571 2wayconnect Prod bug fix
//Latest changes
C6 Cognizant Developer 28-Apr-2018 Case #
****************************************************************
*/
public class S360_TeleSales_LeadTriggerHandler {
private static final string serviceEndPoint = System.Label.S360_TeleSales_ServiceURL;
private static final string tokenEndpoint = System.Label.S360_TeleSales_TokenEndpoint;
private static final string notificationBatchEndpoint = System.Label.S360_TeleSales_NotificationBatchEndpoint;
private static final string RenotificationBatchEndpoint = System.Label.S360_TeleSales_ReNotificationBatchEndpoint;//C6
private static final string cancelEndpoint = System.Label.S360_Telesales_Cancel_Endpoint; //C2
private static final string username = System.Label.S360_TeleSales_Username;
private static final string password = System.Label.S360_TeleSales_Password;
private static final string principle = System.Label.S360_TeleSales_Principal;
private static final string securityTokenPassword = System.Label.S360_TeleSales_SecurityTokenPassword;
private static final string encoding = 'UTF-8';
//Process the Leads and Generate Payload
public static void ProcessRequest(List<Lead> Leads)
{
System.debug('TeleSales : Total Lead : ' + Leads.size());
//Filter Leads that's assigned to Queue and find unique set of OwnerId's
Set<Id> ownerIds = new Set<Id>();
for(Lead objLead : Leads)
{
if(objLead.OwnerId != NULL && objLead.OwnerId.getSObjectType() == Group.SObjectType)
{
ownerIds.add(objLead.OwnerId);
}
}
System.debug('TeleSales : Total Unique QueueIds : ' + ownerIds.size());
//Fetch Queue Names
Map<Id, Group> queueMap = new Map<Id, Group>([SELECT Id, Name FROM Group WHERE Id IN :ownerIds]);
//Fetch Allowed Queue Names From Custom Settings
List<S360_TeleSales_QueueFilter__c> lstQueueFilter = S360_TeleSales_QueueFilter__c.getall().values();
Set<string> lstAllowedQueues = new Set<String>();
for (S360_TeleSales_QueueFilter__c queueName : lstQueueFilter)
{
lstAllowedQueues.add(queueName.Name);
}
System.debug('TeleSales : Queue in Custom Settings : ' + lstAllowedQueues.size());
//Identify Leads assigned to specific Queues
List<Lead> allowedLeads = new List<Lead>();
for(Lead objLead : Leads)
{
if(objLead.OwnerId != NULL && objLead.OwnerId.getSObjectType() == Group.SObjectType && objLead.Preferred_Method_of_Contact__c!='Email')//C4 Change Added Preferred Method check
{
if(queueMap.containsKey((objLead.OwnerId)))
{
Group objQueue = queueMap.get(objLead.OwnerId);
if(lstAllowedQueues.contains(objQueue.Name))
{
allowedLeads.add(objLead);
}
}
}
}
System.debug('TeleSales : Total Allowed Leads To Process : ' + allowedLeads.size());
//Fetch Campaign - Lead Mapping
List<CampaignMember> lstCampaignMember = [SELECT CampaignId, LeadId FROM CampaignMember WHERE LeadId IN :allowedLeads];
Set<Id> campaignIds = new Set<Id>();
Map<Id, Id> leadCampaignMap = new Map<Id, Id>();
for(CampaignMember cmpMember : lstCampaignMember)
{
if(cmpMember.LeadId != null && cmpMember.CampaignId != null)
{
leadCampaignMap.put(cmpMember.LeadId, cmpMember.CampaignId);
campaignIds.add(cmpMember.CampaignId);
}
}
//Fetch Campaign
Map<Id, Campaign> campaignMap = new Map<Id, Campaign>([SELECT Id, Name FROM Campaign WHERE Id IN :campaignIds]);
//Fetch unique set of Bank Id's
Set<Id> partnerIds = new Set<Id>();
for(Lead objLead : allowedLeads)
{
if(objLead.Bank_Lookup__c != NULL)
{
partnerIds.add(objLead.Bank_Lookup__c);
}
}
//Fetch Banks
Map<Id, Bank__c> partnerMap = new Map<Id, Bank__c>([SELECT Id, Name FROM Bank__c WHERE Id IN :partnerIds]);
//Generate Notification XML
String notificationBatch = GenerateNotificationBatch(allowedLeads, partnerMap, queueMap);
System.debug('TeleSales : Notification Batch XML : ' + notificationBatch);
//Generate Payload and Send Notification
if(!Test.isRunningTest()) {
if(!System.isFuture() && !System.isBatch()) {
SendNotificationToDialer(notificationBatch);
}
}
//Update Back the Leads Sent To Dialer
List<Lead> leadsToUpdate = [SELECT Id, Dialer_Activity_Status__c FROM Lead WHERE Id IN :allowedLeads];
for(Lead objLead : leadsToUpdate)
{
objLead.Dialer_Activity_Status__c = 'Sent To Dialer';
}
update leadsToUpdate;
}
//Generate Notification Batch XML
private static String GenerateNotificationBatch(List<Lead> Leads, Map<Id, Bank__c> partnerMap, Map<Id, Group> queueMap)
{
//Get all Business Hour details
BusinessHours businessHour = [SELECT Id, TimeZoneSidKey FROM BusinessHours WHERE Name = 'S360_TeleSales_BusinessHours'];
//C4 Changes start
String dlNumber = '';
//C4 changes end
Dom.Document requestPayload = new Dom.Document();
Dom.XmlNode batchSubmission = requestPayload.createRootElement('batchSubmission', null, null);
Dom.XmlNode notifications = batchSubmission.addChildElement('notifications', null, null);
List<S360_AutoDialer_DialerLogDetail__c> lstDialerLog = new List<S360_AutoDialer_DialerLogDetail__c>();
String strSchTime;
for(Lead objLead : Leads)
{
strSchTime='';// C5 changes
dlNumber = '';// C5 changes
string regExp = '[\\s()-]';// C5 changes
string phone = '';// C5 changes
S360_AutoDialer_DialerLogDetail__c objDialerLog = new S360_AutoDialer_DialerLogDetail__c();
objDialerLog.RecordTypeId = Schema.SObjectType.S360_AutoDialer_DialerLogDetail__c.getRecordTypeInfosByName().get('TeleSales').getRecordTypeId();
if(objLead != null ){
try{
if(objLead.Best_Call_Time__c != NULL && objLead.Best_Call_Time__c != '' && !objLead.Best_Call_Time__c.equalsIgnoreCase('Immediately')
&& !objLead.Best_Call_Time__c.equalsIgnoreCase('Anytime') && !objLead.Best_Call_Time__c.equalsIgnoreCase('M-F 9-5')){ //C5 changes
// C5 changes start
strSchTime = getScheduledTime(objLead.Best_Call_Time__c);
if(strSchTime=='999'){
dlNumber = 'SMB1';
}else{
dlNumber = 'SMB4';
}
// C5 changes end
}
else{
dlNumber = 'SMB1';
}
} catch(exception e){
dlNumber = 'SMB1';
}
}
Dom.XmlNode notification = notifications.addChildElement('notification', null, null);
String xsd = 'http://www.w3.org/2001/XMLSchema';
String xsi = 'http://www.w3.org/2001/XMLSchema-instance';
notification.setNamespace('xsd', xsd);
notification.setNamespace('xsi', xsi);
notification.setAttribute('clientNotificationId', objLead.Id);
notification.setAttribute('serviceClass', dlNumber);//c4 changes
notification.setAttribute('postProcessingGroup', 'Telesales');
notification.setAttribute('pacingGroup', dlNumber);//c4 changes
objDialerLog.clientNotificationId__c = objLead.Id;
objDialerLog.ServiceClass__c = dlNumber;
objDialerLog.PostProcessingGroup__c = 'Telesales';
objDialerLog.PacingGroup__c = dlNumber;
//C4 changes start
if(objLead != null ){
if(dlNumber == 'SMB4'){ //Schedule Call //c5 changes
notification.setAttribute('delayedDelivery', strSchTime);
objDialerLog.DelayedDelivery__c = strSchTime;
}
else if(dlNumber == 'SMB1'){ //UnSchedule Call //c5 changes
Datetime now = DateTime.now();
DateTime nextDayMorning = BusinessHours.nextStartDate(businessHour.Id, now);
//If Now() is between 8AM - 5PM EST, deliver with a buffer of 30 minutes, else deliver it next day 8AM EST
if(BusinessHours.isWithin(businessHour.Id, now))
{
DateTime delayedDelivery = now.addMinutes(Integer.valueOf(System.Label.S360_TeleSales_BufferDelay));
notification.setAttribute('delayedDelivery', delayedDelivery.format('MM/dd/yyyy HH:mm:ss', businessHour.TimeZoneSidKey));
objDialerLog.DelayedDelivery__c = delayedDelivery.format();
}
else
{
notification.setAttribute('delayedDelivery', nextDayMorning.format('MM/dd/yyyy HH:mm:ss', businessHour.TimeZoneSidKey));
objDialerLog.DelayedDelivery__c = nextDayMorning.format();
}
}
if(!string.isBlank(objLead.Phone))
{
phone = objLead.Phone.replaceAll(regExp, ''); //C1
}
}//C4 Changes end
Dom.XmlNode phoneNumbers = notification.addChildElement('contactAddresses', null, null);
Dom.XmlNode workPhoneNumber = phoneNumbers.addChildElement('contactAddress', null, null);
workPhoneNumber.setAttribute('serialize', 'true');
workPhoneNumber.setAttribute('type', 'Work');
if(!string.isBlank(phone))
{
workPhoneNumber.addTextNode(phone);
}
else
{
workPhoneNumber.addTextNode('');
}
Dom.XmlNode homePhoneNumber = phoneNumbers.addChildElement('contactAddress', null, null);
homePhoneNumber.setAttribute('serialize', 'true');
homePhoneNumber.setAttribute('type', 'Home');
if(!string.isBlank(phone))
{
homePhoneNumber.addTextNode(phone);
}
else
{
homePhoneNumber.addTextNode('');
}
objDialerLog.contactAddress_Value__c = phone;
//C6-Changes Start
//need to to check before this record Partner is EMPSor not then proceed this process
boolean timediff=getScheduledTimediff(objLead.Preffered_Contact__c);
Dom.XmlNode timevarainces = notification.addChildElement('TimevarData', null, null);
Dom.XmlNode Morethan1hr = timevarainces.addChildElement('Deviceval', null, null);
if(timediff){
//Morethan1hr.setAttribute('serialize', 'true');
//Morethan1hr.setAttribute('type', 'Work');
}else{
//Morethan1hr.setAttribute('serialize', 'true');
//Morethan1hr.setAttribute('type', 'Work');
}
//C6-Changes End
Dom.XmlNode applications = notification.addChildElement('applications', null, null);
Dom.XmlNode application = applications.addChildElement('application', null, null);
//C4 chages start
if(objLead != null ){
if(dlNumber == 'SMB4'){ //c5 changes
application.setAttribute('name', 'Telesales SAMS Scheduled');
objDialerLog.Application_Name__c = 'Telesales SAMS Scheduled';
}
else{
application.setAttribute('name', 'Telesales Digital');
objDialerLog.Application_Name__c = 'Telesales Digital';
}
}
//C4cChchangesnd
Dom.XmlNode attachments = notification.addChildElement('attachments', null, null);
Dom.XmlNode attachment = attachments.addChildElement('attachment', null, null);
attachment.setAttribute('attachmentType', 'event');
Dom.XmlNode data = attachment.addChildElement('data', null, null);
data.setAttribute('sourceDataType', 'text/xml');
Dom.XmlNode eventDocument = data.addChildElement('eventDocument', null, null);
eventDocument.setAttribute('responseCode', '');
string twcNS = 'http://www.fdc.com/TWCXMLSchema';
string twcPrefix = 'twc';
Dom.XmlNode dataRecord = eventDocument.addChildElement('DataRecord', twcNS, twcPrefix);
Dom.XmlNode variableData = dataRecord.addChildElement('VariableData', twcNS, twcPrefix);
Dom.XmlNode dataElementCampaign = variableData.addChildElement('DataElement', twcNS, twcPrefix);
dataElementCampaign.setAttribute('name', 'CampaignName');
dataElementCampaign.addTextNode('Telesales Digital');
objDialerLog.DataElement_CampaignName__c = 'Telesales Digital';
Dom.XmlNode dataElementAuthParam = variableData.addChildElement('DataElement', twcNS, twcPrefix);
dataElementAuthParam.setAttribute('name', 'AuthenticationParameters');
string authParams = PopulateUserData(objLead, partnerMap, queueMap);
dataElementAuthParam.addTextNode(authParams);
objDialerLog.DataElement_AuthenticationParameters__c = authParams;
Dom.XmlNode indexedFields = notification.addChildElement('indexedFields', null, null);
Dom.XmlNode recordType = indexedFields.addChildElement('field', null, null);
recordType.setAttribute('name', 'RecordType');
//C4 Chchangestart
if(objLead != null){
if(dlNumber == 'SMB4'){ //c5 changes
recordType.addTextNode('Scheduled');
objDialerLog.Indexfield_RecordType__c = 'Scheduled';
}
else{
recordType.addTextNode('Unscheduled');
objDialerLog.Indexfield_RecordType__c = 'Unscheduled';
}
}
//C4 Changechanges
Dom.XmlNode leadIds = indexedFields.addChildElement('field', null, null);
leadIds.setAttribute('name', 'CRM_Call_ID');
leadIds.addTextNode(objLead.Id);
objDialerLog.Indexfield_CRM_Call_ID__c = objLead.Id;
lstDialerLog.add(objDialerLog);
}
insert lstDialerLog;
return requestPayload.toXmlString();
}
//Populate Authentication Parameters
private static string PopulateUserData(Lead objLead, Map<Id, Bank__c> partnerMap, Map<Id, Group> queueMap)
{
string userData = '';
if(!string.isBlank(objLead.Type_of_Business__c))
{
userData += 'Business_Name=' + objLead.Type_of_Business__c + '|';
userData += 'Type_of_Business=' + objLead.Type_of_Business__c + '|';
userData += 'Business_Type=' + objLead.Type_of_Business__c + '|';
}
else
{
userData += 'Business_Name=|';
userData += 'Type_of_Business=|';
userData += 'Business_Type=|';
}
if(!string.isBlank(objLead.Products_Services_Requested__c))
{
userData += 'Suite_of_Interest=' + objLead.Products_Services_Requested__c + '|';
userData += 'Business_Needs=' + objLead.Products_Services_Requested__c + '|';
}
else
{
userData += 'Suite_of_Interest=|';
userData += 'Business_Needs=|';
}
if(!string.isBlank(objLead.FirstName))
{
userData += 'First_Name=' + objLead.FirstName + '|';
}
else
{
userData += 'First_Name=|';
}
if(!string.isBlank(objLead.LastName))
{
userData += 'Last_Name=' + objLead.LastName + '|';
}
else
{
userData += 'Last_Name=|';
}
if(!string.isBlank(objLead.Email))
{
userData += 'Email=' + objLead.Email + '|';
userData += 'Email_Address=' + objLead.Email + '|';
}
else
{
userData += 'Email=|';
userData += 'Email_Address=|';
}
if(!string.isBlank(objLead.Phone))
{
userData += 'Phone=' + objLead.Phone + '|';
userData += 'Phone_Number=' + objLead.Phone + '|';
}
else
{
userData += 'Phone=|';
userData += 'Phone_Number=|';
}
if(!string.isBlank(objLead.Preferred_Method_of_Contact__c))
{
userData += 'Preferred_Method_of_Contact=' + objLead.Preferred_Method_of_Contact__c + '|';
userData += 'Preferred_Contact_Method=' + objLead.Preferred_Method_of_Contact__c + '|';
}
else
{
userData += 'Preferred_Method_of_Contact=|';
userData += 'Preferred_Contact_Method=|';
}
if(!string.isBlank(objLead.State))
{
userData += 'State=' + objLead.State + '|';
}
else
{
userData += 'State=|';
}
if(!string.isBlank(objLead.Company))
{
userData += 'Company=' + objLead.Company + '|';
userData += 'Business_Name=' + objLead.Company + '|';
}
else
{
userData += 'Company=|';
userData += 'Business_Name=|';
}
if(!string.isBlank(objLead.Comments__c))
{
userData += 'Comments=' + objLead.Comments__c + '|';
}
else
{
userData += 'Comments=|';
}
if(objLead.Bank_Lookup__c != null && partnerMap.containsKey(objLead.Bank_Lookup__c))
{
userData += 'Partner_Lookup=' + partnerMap.get(objLead.Bank_Lookup__c).Name + '|';
}
else
{
userData += 'Partner_Lookup=|';
}
if(!string.isBlank(objLead.Lead_Type_c__c))
{
userData += 'Lead_Type=' + objLead.Lead_Type_c__c + '|';
}
else
{
userData += 'Lead_Type=|';
}
if(!string.isBlank(objLead.LeadSource))
{
userData += 'Lead_Source=' + objLead.LeadSource + '|';
}
else
{
userData += 'Lead_Source=|';
}
if(objLead.OwnerID != null && queueMap.containsKey(objLead.OwnerID))
{
userData += 'Lead_Owner=' + queueMap.get(objLead.OwnerID).Name + '|';
}
else
{
userData += 'Lead_Owner=|';
}
if(!string.isBlank(objLead.Marketing_Brand_ID__c))
{
userData += 'Marketing_Brand ID=' + objLead.Marketing_Brand_ID__c + '|';
}
else
{
userData += 'Marketing_Brand ID=|';
}
if(!string.isBlank(objLead.Campaign_Custom__c))
{
userData += 'Campaign=' + objLead.Campaign_Custom__c + '|';
}
else
{
userData += 'Campaign=|';
}
if(!string.isBlank(objLead.Marketing_Offer_Code__c))
{
userData += 'Marketing_Offer_Code=' + objLead.Marketing_Offer_Code__c + '|';
}
else
{
userData += 'Marketing_Offer_Code=|';
}
if(!string.isBlank(objLead.Marketing_PPC_Keyword__c))
{
userData += 'Marketing_PPC_Keyword=' + objLead.Marketing_PPC_Keyword__c + '|';
}
else
{
userData += 'Marketing_PPC_Keyword=|';
}
if(!string.isBlank(objLead.Original_Marketing_Activity__c))
{
userData += 'Original_Marketing_Activity=' + objLead.Original_Marketing_Activity__c + '|';
}
else
{
userData += 'Original_Marketing_Activity=|';
}
if(!string.isBlank(objLead.Referral_Region__c))
{
userData += 'Referral_Region=' + objLead.Referral_Region__c + '|';
}
else
{
userData += 'Referral_Region=|';
}
if(!string.isBlank(objLead.Referral_Market__c))
{
userData += 'Referral_Market=' + objLead.Referral_Market__c + '|';
}
else
{
userData += 'Referral_Market=|';
}
if(!string.isBlank(objLead.Referral_Division__c))
{
userData += 'Referral_Division=' + objLead.Referral_Division__c + '|';
}
else
{
userData += 'Referral_Division=|';
}
if(!string.isBlank(objLead.Title))
{
userData += 'Title=' + objLead.Title + '|';
}
else
{
userData += 'Title=|';
}
if(!string.isBlank(objLead.Best_Call_Time__c))
{
userData += 'Best_Time_to_Call=' + objLead.Best_Call_Time__c + '|';
}
else
{
userData += 'Best_Time_to_Call=|';
}
if(!string.isBlank(objLead.Bank_Industry__c))
{
userData += 'Industry=' + objLead.Bank_Industry__c + '|';
}
else
{
userData += 'Industry=|';
}
if(!string.isBlank(objLead.Credit_Card_Volume__c))
{
userData += 'Annual_Sales_Volume=' + objLead.Credit_Card_Volume__c + '|';
}
else
{
userData += 'Annual_Sales_Volume=|';
}
if(!string.isBlank(objLead.Current_Credit_Card_Acceptor__c))
{
userData += 'Accept_Cards=' + objLead.Current_Credit_Card_Acceptor__c + '|';
}
else
{
userData += 'Accept_Cards=|';
}
if(!string.isBlank(objLead.Lead_Source_Most_Recent__c))
{
userData += 'Current_Processor=' + objLead.Lead_Source_Most_Recent__c + '|';
}
else
{
userData += 'Current_Processor=|';
}
if(objLead.Total_Card_Volume__c != NULL)
{
userData += 'MC_VI_Volume=' + objLead.Total_Card_Volume__c + '|';
}
else
{
userData += 'MC_VI_Volume=|';
}
if(!string.isBlank(objLead.PostalCode))
{
userData += 'Zip_Code=' + objLead.PostalCode + '|';
}
else
{
userData += 'Zip_Code=|';
}
userData += 'Already_a_Clover_Merchant=' + objLead.Existing_Customer__c + '|';
if(objLead.OwnerID != null && queueMap.containsKey(objLead.OwnerID))
{
string qName = queueMap.get(objLead.OwnerID).Name;
if(qName.toUpperCase().contains('SAM'))
{
userData += 'pop_type=TELESAMS|';
}
else
{
userData += 'pop_type=TELEGEN|';
}
}
else
{
userData += 'pop_type=TELEGEN|';
}
userData += 'lead_number=' + objLead.Id + '|';
userData += 'Sales_Volume=NONE|';
userData += 'Product=TELESALES DIGITAL|';
userData += 'Device=NONE|';
if(queueMap.containsKey(objLead.OwnerID))
{
if(queueMap.get(objLead.OwnerID).Name == 'SAMS Club Triage')
{
userData += 'Alliance=SAMS|';
}
else
{
userData += 'Alliance=GEN|';
}
}
userData += 'Language=EN-US';
return userData;
}
//Send Notification Batch to Dialer
@future(callout=true)
private static void SendNotificationToDialer(String NotificationBatch)
{
//Request Token for Authentication
RequestToken();
//Generate & Send BatchNotification Payload
Payload notificationPayload = GeneratePayload(NotificationBatch);
SendNotificationBatch(notificationPayload);
}
//Generate Notification Batch Payload
private static Payload GeneratePayload(String NotificationBatch)
{
Dom.Document authPayload = new Dom.Document();
Dom.XmlNode authenticationNode = authPayload.createRootElement('authentication', null, null);
Dom.XmlNode principleNode = authenticationNode.addChildElement('principle', null, null);
principleNode.addTextNode(principle);
Dom.XmlNode passwordNode = authenticationNode.addChildElement('password', null, null);
passwordNode.addTextNode(securityTokenPassword);
Payload payload = new Payload();
payload.SecurityToken = authPayload.toXmlString();
payload.BatchDataXml = NotificationBatch;
System.debug('TeleSales : Notification Payload : ' + payload);
return payload;
}
private static String secToken;
//Request Token API Call
@TestVisible
private static HTTPResponse RequestToken()
{
HttpRequest req = new HttpRequest();
HTTPResponse res = new HTTPResponse();
Http http = new Http();
//Set HTTPRequest Method
req.setMethod('POST');
//Set HTTPRequest header properties
req.setHeader('Content-Type', 'application/x-www-form-urlencoded');
req.setEndpoint(serviceEndPoint + tokenEndpoint);
req.setCompressed(false);
string body = 'username=' + EncodingUtil.urlEncode(username, encoding) +
'&password=' + EncodingUtil.urlEncode(password, encoding) +
'&grant_type=password';
//Set the HTTPRequest body
req.setBody(body);
try {
//Execute web service call
res = http.send(req);
if(res!=null){
secToken=res.getBody();
system.debug('###secToken==='+secToken);
}
System.debug('Integration - Token Callout Response : ' + res.toString());
System.debug('Integration - Token Callout Status : ' + res.getStatus());
System.debug('Integration - Token Callout Status Code : ' + res.getStatusCode());
} catch(System.CalloutException e) {
System.debug('Integration - Token Callout Exception : ' + e.getMessage());
}
return res;
}
//Send Notification Batch API Call
@TestVisible
private static HTTPResponse SendNotificationBatch(Payload payload)
{
HttpRequest req = new HttpRequest();
HTTPResponse res = new HTTPResponse();
Http http = new Http();
//Set HTTPRequest Method
req.setMethod('POST');
//Set HTTPRequest header properties
req.setHeader('Content-Type', 'application/json');
req.setEndpoint(serviceEndPoint + notificationBatchEndpoint);
req.setCompressed(false);
string body = JSON.serialize(payload);
//Set the HTTPRequest body
req.setBody(body);
try {
//Execute web service call
res = http.send(req);
System.debug('Integration - Notification Batch Callout Response : ' + res.toString());
System.debug('Integration - Notification Batch Callout Status : ' + res.getStatus());
System.debug('Integration - Notification Batch Callout Status Code : ' + res.getStatusCode());
} catch(System.CalloutException e) {
System.debug('Integration - Notification Batch Callout Exception : ' + e.getMessage());
}
return res;
}
//Wrapper class for Notification Batch Payload
public class Payload
{
public string SecurityToken;
public string BatchDataXml;
}
//C2 Changes :::::::::::::::: START ::::::::::::::::::::::::::::
public static void sendCancelRequestToDialer(Map<Id, Lead> leadOldMap, Map<Id, Lead> leadNewMap){
//C3-Start
List<S360_TeleSales_QueueFilter__c> lstQueueFilters = S360_TeleSales_QueueFilter__c.getall().values();
Set<string> ValidQueues = new Set<String>();
Set<Id> ValidQueueids = new Set<Id>();
List<Group> validgroups= New List<Group>();
if(lstQueueFilters.size()>0){
for (S360_TeleSales_QueueFilter__c queueName : lstQueueFilters)
{
ValidQueues.add(queueName.Name);
}
}
System.debug('Queue Names***'+ValidQueues);
validgroups=[SELECT Name,id FROM Group where Type='Queue' and Name IN:ValidQueues];
if(validgroups.size()>0){
for(Group qid:validgroups){
ValidQueueids.add(qid.id);
}
}
System.debug('Queue IDs***'+ValidQueueids);
// Fetch the Leads for which Dialer Status has changed
Set<Id> leadIdSet=new Set<Id>();
List<Lead> RescduldLeads = new List<Lead>();//C6 Change
for(Id leadID : leadNewMap.keySet())
{
Lead newLead = leadNewMap.get(leadID);
Lead oldLead = leadOldMap.get(leadID);
System.debug('Lead is***'+newLead);
//C6 Changes-Start
if(newLead!=null && oldLead!=null && newLead.Preffered_Contact__c != oldLead.Preffered_Contact__c)//Need to add Partner and owner checks
{
RescduldLeads.add(objLead);
}
System.debug('Total Allowed Leads To reProcess : ' + RescduldLeads.size());
//C6 Changes-END
if(((!ValidQueueids.contains(newLead.OwnerID)) && ValidQueueids.contains(oldLead.OwnerID)) || (newLead!=null && oldLead!=null && newLead.Status != oldLead.Status &&
(newLead.Status == 'Contacted'||newLead.Status == 'Unqualified'||newLead.Status == 'Qualified') && (newLead.Dialer_Activity_Status__c=='Sent To Dialer')))
{
leadIdSet.add(newLead.id);
}
}
//C3-End
S360_AutoDialer_DialerLogDetail__c objDialerlogdetail= new S360_AutoDialer_DialerLogDetail__c();
objDialerlogdetail.RecordTypeId = Schema.SObjectType.S360_AutoDialer_DialerLogDetail__c.getRecordTypeInfosByName().get('TeleSales').getRecordTypeId();
if(!Test.isRunningTest() && leadIdSet.size()>0)
{
objDialerlogdetail.clientNotificationId__c = String.valueOf(leadIdSet);
insert objDialerlogdetail;
CancelInteraction(leadIdSet);
}
//C6 Changes Start
if(RescduldLeads.size()>0){
ProcessRequest(RescduldLeads);
}
//C6 Changes end
}
//Send Cancel Request API Call
public static HTTPResponse SendCancelRequest(CancelPayload payload)
{
HttpRequest req = new HttpRequest();
HTTPResponse res = new HttpResponse();
Http http = new Http();
//Set HTTPRequest Method
req.setMethod('POST');
//Set HTTPRequest header properties
req.setHeader('Content-Type', 'application/json');
if(secToken!=null && secToken!=''){
req.setHeader('Authorization', secToken);
}
req.setEndpoint(serviceEndPoint + cancelEndpoint);
req.setCompressed(false);
string body = JSON.serialize(payload);
System.debug('Request body : ' + body);
System.debug('req : ' + req);
//Set the HTTPRequest body
req.setBody(body);
try {
//Execute web service call
res = http.send(req);
System.debug('Integration - Cancel Callout Response : ' + res.toString());
System.debug('Integration - Cancel Callout Status : ' + res.getStatus());
System.debug('Integration - Cancel Callout Status Code : ' + res.getStatusCode());
} catch(System.CalloutException e) {
System.debug('Integration - Cancel Callout Exception : ' + e.getMessage());
}
return res;
}
//Cancel Interaction
@future(callout=true)
public static void CancelInteraction(Set<Id> leadIdentifier)
{
List<S360_Act_GenericUtility.ServiceResponse> parseRes = new List <S360_Act_GenericUtility.ServiceResponse>();
if(Test.isRunningTest()){
S360_Act_GenericUtility.ServiceResponse testResponse = new S360_Act_GenericUtility.ServiceResponse('ResultCode','0');
parseRes.add(testResponse);
}
else{
RequestToken();
HTTPResponse res = new HttpResponse();
CancelPayload payload = new CancelPayload();
system.debug('Value sent ::: ' + String.valueOf(leadIdentifier));
List<Id> LeadIds = new List<Id>();
LeadIds.addAll(leadIdentifier);
if(LeadIds != null && !LeadIds.isEmpty()){
Id leadId = LeadIds[0];
system.debug('Single Lead Id ' + leadId);
payload.CaseId = String.valueOf(leadId);
}
res = SendCancelRequest(payload);
System.debug('Integration - Token Callout Response Body for Cancel Notification: ' + res.getBody());
//Parse dialer response
parseRes = S360_Act_GenericUtility.parseJSON(res.getBody());
system.debug('parseRes Telesales:::'+parseRes);
}
//Fetch lead details
List<Lead> lstLeads = [SELECT Id, Dialer_Activity_Status__c
FROM Lead WHERE Id IN :leadIdentifier];
system.debug('lstLeads Inside Integration:::'+ lstLeads);
//Mark boolean field true if dialer send success response
Boolean CancelledSuccess = false;
for(S360_Act_GenericUtility.ServiceResponse item : parseRes)
{
if(item!=null){
if(item.tag == 'ResultCode' && item.value == '0')
{
CancelledSuccess= true;
system.debug('CancelledSuccess::'+CancelledSuccess);
}
}
}
//Update lead status after getting success cancel response from dialer
if(CancelledSuccess)
{
for(Lead leadRecord : lstLeads)
{
leadRecord.Dialer_Activity_Status__c = 'Cancelled';
}
update lstLeads;
}
}
//Wrapper Class for Cancel Payload
public class CancelPayload
{
//2way connect is using CaseId as the attribute to get the details for unique record. Lease Id is passing to this Case Id
public string CaseId;
}
//C2 Changes :::::::::::::::: END ::::::::::::::::::::::::::::
//C4 Changes : PR16004639 2Way Connect Enhancement Sprint 3. Scheduled Calls
/**************
Method Name : getScheduledTime
Method parameters : String besttime
Functionality : This method checks the BestTimeToCall value(Eg: 9 AM , 12 PM ) and returns concatenated value of BestTimeToCall time with next day date in 'MM/DD/YYYY H:M:S' format
*************/
public static String getScheduledTime(String besttime){
String schdatetime='';
Datetime schdate=system.now();
SYSTEM.DEBUG('schdate'+schdate);
if(besttime.toUpperCase().contains('MORNING')) // C5 changes
schdatetime ='09:00:00';
else if(besttime.toUpperCase().contains('AFTERNOON'))// C5 changes
schdatetime = '13:00:00';
else if(besttime.toUpperCase().contains('EVENING'))// C5 changes
schdatetime ='18:00:00';
else if(besttime.equalsIgnoreCase('6pm - 8pm'))
schdatetime ='19:00:00';
else {
// C5 changes start
String[] splitByColon;
if(besttime.contains(':') && (besttime.equalsIgnoreCase('am')||besttime.equalsIgnoreCase('pm')))
splitByColon = besttime.split(':');
else
return '999';
Integer hoursValue = Integer.valueof((splitByColon[0].trim().isnumeric())?splitByColon[0].trim():'999');
if(hoursValue==999)
return '999';
//C5 changes end
String[] splitForMins = splitByColon[1].split(' ');
if(splitForMins[1].equalsIgnoreCase('pm')){
if(hoursValue!=12) //c4 changes
hoursValue = hoursValue + 12;
schdatetime=String.valueOf(hoursValue)+':'+splitForMins[0]+':'+'00';
}
else{
schdatetime=String.valueOf(hoursValue);
if(schdatetime != null && schdatetime != '' && schdatetime.length()==1)
schdatetime='0'+ schdatetime+':'+splitForMins[0]+':'+'00';
else //C5 changes
schdatetime=schdatetime+':'+splitForMins[0]+':'+'00'; // C5 changes
}
}
SYSTEM.DEBUG('schdatetime'+schdatetime);
String[] splitbyspace=string.valueof(schdate.format('MM/dd/yyyy HH:mm:ss', 'America/New_York')).split(' ');
String[] splitByColonPre=string.valueof(splitbyspace[1]).split(':');
SYSTEM.DEBUG('splitbyspace'+splitbyspace);
SYSTEM.DEBUG('splitByColonPre'+splitByColonPre);
String[] splitByColonSch=schdatetime.split(':');
Integer[] curr=new Integer[splitByColonPre.size()];
Integer[] sch=new Integer[splitByColonSch.size()];
for(integer i=0;i<splitByColonPre.size();i++)
{
curr[i]=integer.valueof(splitByColonPre[i]);
sch[i]=integer.valueof(splitByColonSch[i]);
}
Integer sumcurr=(curr[0]*3600)+(curr[1]*60)+(curr[2]*1);
Integer sumsch=(sch[0]*3600)+(sch[1]*60)+(sch[2]*1);
sySTEM.DEBUG('sumcurr'+sumcurr);
sySTEM.DEBUG('sumsch'+sumsch);
if(sumcurr>=sumsch)
schdatetime=schdate.adddays(1).format('MM/dd/yyyy')+' '+schdatetime;
else
schdatetime=schdate.format('MM/dd/yyyy')+' '+schdatetime;
return schdatetime;
}
//C4 Changes :::::::::::::::: END ::::::::::::::::::::::::::::
//C6-Changes Start
/**************
Method Name : getScheduledTimediff
Method parameters : String besttime
Functionality : to calculate time differnce between Preferred time to contact and current time
*************/
public static Boolean getScheduledTimediff(Datetime Prefeeredtimeis){
Boolean timediff;
Datetime Currenttime=system.now();
//Prefeeredtimeis-Currenttime is greterthan 1hr return true else false;
return true
}
//C6-Changes End
}
Developer: Cognizant Developer
Date: 20th Oct, 2017
Description: This apex class will be used as handler for S360_TeleSales_LeadTrigger.
Test Class: S360_TeleSales_IntegrationTest, S360_TeleSales_LeadTriggerHandler_Test
Change History
****************************************************************
Change# Last Modified By Date Description
****************************************************************
C1 Cognizant Developer 10-Jan-2018 Phone number formatting implemented : PR18000128
C2 Cognizant Developer 25-Jan-2018 Cancel request for lead id which got Status connected has already been send to Dialer before : PR18000128
C3 Cognizant Developer 02-Apr-2018 Case # 30992477 - IR14187969 - 2Way Connect
C4 Cognizant Developer 20-June-2018 Case # 32164661 JIRA# SP-460 PR18000128- Enhance Two Way Connect for Telesales- Sprint 3 changes for Scheduled Call
C5 Cognizant Developer 16-July-2018 Case # 33822571 2wayconnect Prod bug fix
//Latest changes
C6 Cognizant Developer 28-Apr-2018 Case #
****************************************************************
*/
public class S360_TeleSales_LeadTriggerHandler {
private static final string serviceEndPoint = System.Label.S360_TeleSales_ServiceURL;
private static final string tokenEndpoint = System.Label.S360_TeleSales_TokenEndpoint;
private static final string notificationBatchEndpoint = System.Label.S360_TeleSales_NotificationBatchEndpoint;
private static final string RenotificationBatchEndpoint = System.Label.S360_TeleSales_ReNotificationBatchEndpoint;//C6
private static final string cancelEndpoint = System.Label.S360_Telesales_Cancel_Endpoint; //C2
private static final string username = System.Label.S360_TeleSales_Username;
private static final string password = System.Label.S360_TeleSales_Password;
private static final string principle = System.Label.S360_TeleSales_Principal;
private static final string securityTokenPassword = System.Label.S360_TeleSales_SecurityTokenPassword;
private static final string encoding = 'UTF-8';
//Process the Leads and Generate Payload
public static void ProcessRequest(List<Lead> Leads)
{
System.debug('TeleSales : Total Lead : ' + Leads.size());
//Filter Leads that's assigned to Queue and find unique set of OwnerId's
Set<Id> ownerIds = new Set<Id>();
for(Lead objLead : Leads)
{
if(objLead.OwnerId != NULL && objLead.OwnerId.getSObjectType() == Group.SObjectType)
{
ownerIds.add(objLead.OwnerId);
}
}
System.debug('TeleSales : Total Unique QueueIds : ' + ownerIds.size());
//Fetch Queue Names
Map<Id, Group> queueMap = new Map<Id, Group>([SELECT Id, Name FROM Group WHERE Id IN :ownerIds]);
//Fetch Allowed Queue Names From Custom Settings
List<S360_TeleSales_QueueFilter__c> lstQueueFilter = S360_TeleSales_QueueFilter__c.getall().values();
Set<string> lstAllowedQueues = new Set<String>();
for (S360_TeleSales_QueueFilter__c queueName : lstQueueFilter)
{
lstAllowedQueues.add(queueName.Name);
}
System.debug('TeleSales : Queue in Custom Settings : ' + lstAllowedQueues.size());
//Identify Leads assigned to specific Queues
List<Lead> allowedLeads = new List<Lead>();
for(Lead objLead : Leads)
{
if(objLead.OwnerId != NULL && objLead.OwnerId.getSObjectType() == Group.SObjectType && objLead.Preferred_Method_of_Contact__c!='Email')//C4 Change Added Preferred Method check
{
if(queueMap.containsKey((objLead.OwnerId)))
{
Group objQueue = queueMap.get(objLead.OwnerId);
if(lstAllowedQueues.contains(objQueue.Name))
{
allowedLeads.add(objLead);
}
}
}
}
System.debug('TeleSales : Total Allowed Leads To Process : ' + allowedLeads.size());
//Fetch Campaign - Lead Mapping
List<CampaignMember> lstCampaignMember = [SELECT CampaignId, LeadId FROM CampaignMember WHERE LeadId IN :allowedLeads];
Set<Id> campaignIds = new Set<Id>();
Map<Id, Id> leadCampaignMap = new Map<Id, Id>();
for(CampaignMember cmpMember : lstCampaignMember)
{
if(cmpMember.LeadId != null && cmpMember.CampaignId != null)
{
leadCampaignMap.put(cmpMember.LeadId, cmpMember.CampaignId);
campaignIds.add(cmpMember.CampaignId);
}
}
//Fetch Campaign
Map<Id, Campaign> campaignMap = new Map<Id, Campaign>([SELECT Id, Name FROM Campaign WHERE Id IN :campaignIds]);
//Fetch unique set of Bank Id's
Set<Id> partnerIds = new Set<Id>();
for(Lead objLead : allowedLeads)
{
if(objLead.Bank_Lookup__c != NULL)
{
partnerIds.add(objLead.Bank_Lookup__c);
}
}
//Fetch Banks
Map<Id, Bank__c> partnerMap = new Map<Id, Bank__c>([SELECT Id, Name FROM Bank__c WHERE Id IN :partnerIds]);
//Generate Notification XML
String notificationBatch = GenerateNotificationBatch(allowedLeads, partnerMap, queueMap);
System.debug('TeleSales : Notification Batch XML : ' + notificationBatch);
//Generate Payload and Send Notification
if(!Test.isRunningTest()) {
if(!System.isFuture() && !System.isBatch()) {
SendNotificationToDialer(notificationBatch);
}
}
//Update Back the Leads Sent To Dialer
List<Lead> leadsToUpdate = [SELECT Id, Dialer_Activity_Status__c FROM Lead WHERE Id IN :allowedLeads];
for(Lead objLead : leadsToUpdate)
{
objLead.Dialer_Activity_Status__c = 'Sent To Dialer';
}
update leadsToUpdate;
}
//Generate Notification Batch XML
private static String GenerateNotificationBatch(List<Lead> Leads, Map<Id, Bank__c> partnerMap, Map<Id, Group> queueMap)
{
//Get all Business Hour details
BusinessHours businessHour = [SELECT Id, TimeZoneSidKey FROM BusinessHours WHERE Name = 'S360_TeleSales_BusinessHours'];
//C4 Changes start
String dlNumber = '';
//C4 changes end
Dom.Document requestPayload = new Dom.Document();
Dom.XmlNode batchSubmission = requestPayload.createRootElement('batchSubmission', null, null);
Dom.XmlNode notifications = batchSubmission.addChildElement('notifications', null, null);
List<S360_AutoDialer_DialerLogDetail__c> lstDialerLog = new List<S360_AutoDialer_DialerLogDetail__c>();
String strSchTime;
for(Lead objLead : Leads)
{
strSchTime='';// C5 changes
dlNumber = '';// C5 changes
string regExp = '[\\s()-]';// C5 changes
string phone = '';// C5 changes
S360_AutoDialer_DialerLogDetail__c objDialerLog = new S360_AutoDialer_DialerLogDetail__c();
objDialerLog.RecordTypeId = Schema.SObjectType.S360_AutoDialer_DialerLogDetail__c.getRecordTypeInfosByName().get('TeleSales').getRecordTypeId();
if(objLead != null ){
try{
if(objLead.Best_Call_Time__c != NULL && objLead.Best_Call_Time__c != '' && !objLead.Best_Call_Time__c.equalsIgnoreCase('Immediately')
&& !objLead.Best_Call_Time__c.equalsIgnoreCase('Anytime') && !objLead.Best_Call_Time__c.equalsIgnoreCase('M-F 9-5')){ //C5 changes
// C5 changes start
strSchTime = getScheduledTime(objLead.Best_Call_Time__c);
if(strSchTime=='999'){
dlNumber = 'SMB1';
}else{
dlNumber = 'SMB4';
}
// C5 changes end
}
else{
dlNumber = 'SMB1';
}
} catch(exception e){
dlNumber = 'SMB1';
}
}
Dom.XmlNode notification = notifications.addChildElement('notification', null, null);
String xsd = 'http://www.w3.org/2001/XMLSchema';
String xsi = 'http://www.w3.org/2001/XMLSchema-instance';
notification.setNamespace('xsd', xsd);
notification.setNamespace('xsi', xsi);
notification.setAttribute('clientNotificationId', objLead.Id);
notification.setAttribute('serviceClass', dlNumber);//c4 changes
notification.setAttribute('postProcessingGroup', 'Telesales');
notification.setAttribute('pacingGroup', dlNumber);//c4 changes
objDialerLog.clientNotificationId__c = objLead.Id;
objDialerLog.ServiceClass__c = dlNumber;
objDialerLog.PostProcessingGroup__c = 'Telesales';
objDialerLog.PacingGroup__c = dlNumber;
//C4 changes start
if(objLead != null ){
if(dlNumber == 'SMB4'){ //Schedule Call //c5 changes
notification.setAttribute('delayedDelivery', strSchTime);
objDialerLog.DelayedDelivery__c = strSchTime;
}
else if(dlNumber == 'SMB1'){ //UnSchedule Call //c5 changes
Datetime now = DateTime.now();
DateTime nextDayMorning = BusinessHours.nextStartDate(businessHour.Id, now);
//If Now() is between 8AM - 5PM EST, deliver with a buffer of 30 minutes, else deliver it next day 8AM EST
if(BusinessHours.isWithin(businessHour.Id, now))
{
DateTime delayedDelivery = now.addMinutes(Integer.valueOf(System.Label.S360_TeleSales_BufferDelay));
notification.setAttribute('delayedDelivery', delayedDelivery.format('MM/dd/yyyy HH:mm:ss', businessHour.TimeZoneSidKey));
objDialerLog.DelayedDelivery__c = delayedDelivery.format();
}
else
{
notification.setAttribute('delayedDelivery', nextDayMorning.format('MM/dd/yyyy HH:mm:ss', businessHour.TimeZoneSidKey));
objDialerLog.DelayedDelivery__c = nextDayMorning.format();
}
}
if(!string.isBlank(objLead.Phone))
{
phone = objLead.Phone.replaceAll(regExp, ''); //C1
}
}//C4 Changes end
Dom.XmlNode phoneNumbers = notification.addChildElement('contactAddresses', null, null);
Dom.XmlNode workPhoneNumber = phoneNumbers.addChildElement('contactAddress', null, null);
workPhoneNumber.setAttribute('serialize', 'true');
workPhoneNumber.setAttribute('type', 'Work');
if(!string.isBlank(phone))
{
workPhoneNumber.addTextNode(phone);
}
else
{
workPhoneNumber.addTextNode('');
}
Dom.XmlNode homePhoneNumber = phoneNumbers.addChildElement('contactAddress', null, null);
homePhoneNumber.setAttribute('serialize', 'true');
homePhoneNumber.setAttribute('type', 'Home');
if(!string.isBlank(phone))
{
homePhoneNumber.addTextNode(phone);
}
else
{
homePhoneNumber.addTextNode('');
}
objDialerLog.contactAddress_Value__c = phone;
//C6-Changes Start
//need to to check before this record Partner is EMPSor not then proceed this process
boolean timediff=getScheduledTimediff(objLead.Preffered_Contact__c);
Dom.XmlNode timevarainces = notification.addChildElement('TimevarData', null, null);
Dom.XmlNode Morethan1hr = timevarainces.addChildElement('Deviceval', null, null);
if(timediff){
//Morethan1hr.setAttribute('serialize', 'true');
//Morethan1hr.setAttribute('type', 'Work');
}else{
//Morethan1hr.setAttribute('serialize', 'true');
//Morethan1hr.setAttribute('type', 'Work');
}
//C6-Changes End
Dom.XmlNode applications = notification.addChildElement('applications', null, null);
Dom.XmlNode application = applications.addChildElement('application', null, null);
//C4 chages start
if(objLead != null ){
if(dlNumber == 'SMB4'){ //c5 changes
application.setAttribute('name', 'Telesales SAMS Scheduled');
objDialerLog.Application_Name__c = 'Telesales SAMS Scheduled';
}
else{
application.setAttribute('name', 'Telesales Digital');
objDialerLog.Application_Name__c = 'Telesales Digital';
}
}
//C4cChchangesnd
Dom.XmlNode attachments = notification.addChildElement('attachments', null, null);
Dom.XmlNode attachment = attachments.addChildElement('attachment', null, null);
attachment.setAttribute('attachmentType', 'event');
Dom.XmlNode data = attachment.addChildElement('data', null, null);
data.setAttribute('sourceDataType', 'text/xml');
Dom.XmlNode eventDocument = data.addChildElement('eventDocument', null, null);
eventDocument.setAttribute('responseCode', '');
string twcNS = 'http://www.fdc.com/TWCXMLSchema';
string twcPrefix = 'twc';
Dom.XmlNode dataRecord = eventDocument.addChildElement('DataRecord', twcNS, twcPrefix);
Dom.XmlNode variableData = dataRecord.addChildElement('VariableData', twcNS, twcPrefix);
Dom.XmlNode dataElementCampaign = variableData.addChildElement('DataElement', twcNS, twcPrefix);
dataElementCampaign.setAttribute('name', 'CampaignName');
dataElementCampaign.addTextNode('Telesales Digital');
objDialerLog.DataElement_CampaignName__c = 'Telesales Digital';
Dom.XmlNode dataElementAuthParam = variableData.addChildElement('DataElement', twcNS, twcPrefix);
dataElementAuthParam.setAttribute('name', 'AuthenticationParameters');
string authParams = PopulateUserData(objLead, partnerMap, queueMap);
dataElementAuthParam.addTextNode(authParams);
objDialerLog.DataElement_AuthenticationParameters__c = authParams;
Dom.XmlNode indexedFields = notification.addChildElement('indexedFields', null, null);
Dom.XmlNode recordType = indexedFields.addChildElement('field', null, null);
recordType.setAttribute('name', 'RecordType');
//C4 Chchangestart
if(objLead != null){
if(dlNumber == 'SMB4'){ //c5 changes
recordType.addTextNode('Scheduled');
objDialerLog.Indexfield_RecordType__c = 'Scheduled';
}
else{
recordType.addTextNode('Unscheduled');
objDialerLog.Indexfield_RecordType__c = 'Unscheduled';
}
}
//C4 Changechanges
Dom.XmlNode leadIds = indexedFields.addChildElement('field', null, null);
leadIds.setAttribute('name', 'CRM_Call_ID');
leadIds.addTextNode(objLead.Id);
objDialerLog.Indexfield_CRM_Call_ID__c = objLead.Id;
lstDialerLog.add(objDialerLog);
}
insert lstDialerLog;
return requestPayload.toXmlString();
}
//Populate Authentication Parameters
private static string PopulateUserData(Lead objLead, Map<Id, Bank__c> partnerMap, Map<Id, Group> queueMap)
{
string userData = '';
if(!string.isBlank(objLead.Type_of_Business__c))
{
userData += 'Business_Name=' + objLead.Type_of_Business__c + '|';
userData += 'Type_of_Business=' + objLead.Type_of_Business__c + '|';
userData += 'Business_Type=' + objLead.Type_of_Business__c + '|';
}
else
{
userData += 'Business_Name=|';
userData += 'Type_of_Business=|';
userData += 'Business_Type=|';
}
if(!string.isBlank(objLead.Products_Services_Requested__c))
{
userData += 'Suite_of_Interest=' + objLead.Products_Services_Requested__c + '|';
userData += 'Business_Needs=' + objLead.Products_Services_Requested__c + '|';
}
else
{
userData += 'Suite_of_Interest=|';
userData += 'Business_Needs=|';
}
if(!string.isBlank(objLead.FirstName))
{
userData += 'First_Name=' + objLead.FirstName + '|';
}
else
{
userData += 'First_Name=|';
}
if(!string.isBlank(objLead.LastName))
{
userData += 'Last_Name=' + objLead.LastName + '|';
}
else
{
userData += 'Last_Name=|';
}
if(!string.isBlank(objLead.Email))
{
userData += 'Email=' + objLead.Email + '|';
userData += 'Email_Address=' + objLead.Email + '|';
}
else
{
userData += 'Email=|';
userData += 'Email_Address=|';
}
if(!string.isBlank(objLead.Phone))
{
userData += 'Phone=' + objLead.Phone + '|';
userData += 'Phone_Number=' + objLead.Phone + '|';
}
else
{
userData += 'Phone=|';
userData += 'Phone_Number=|';
}
if(!string.isBlank(objLead.Preferred_Method_of_Contact__c))
{
userData += 'Preferred_Method_of_Contact=' + objLead.Preferred_Method_of_Contact__c + '|';
userData += 'Preferred_Contact_Method=' + objLead.Preferred_Method_of_Contact__c + '|';
}
else
{
userData += 'Preferred_Method_of_Contact=|';
userData += 'Preferred_Contact_Method=|';
}
if(!string.isBlank(objLead.State))
{
userData += 'State=' + objLead.State + '|';
}
else
{
userData += 'State=|';
}
if(!string.isBlank(objLead.Company))
{
userData += 'Company=' + objLead.Company + '|';
userData += 'Business_Name=' + objLead.Company + '|';
}
else
{
userData += 'Company=|';
userData += 'Business_Name=|';
}
if(!string.isBlank(objLead.Comments__c))
{
userData += 'Comments=' + objLead.Comments__c + '|';
}
else
{
userData += 'Comments=|';
}
if(objLead.Bank_Lookup__c != null && partnerMap.containsKey(objLead.Bank_Lookup__c))
{
userData += 'Partner_Lookup=' + partnerMap.get(objLead.Bank_Lookup__c).Name + '|';
}
else
{
userData += 'Partner_Lookup=|';
}
if(!string.isBlank(objLead.Lead_Type_c__c))
{
userData += 'Lead_Type=' + objLead.Lead_Type_c__c + '|';
}
else
{
userData += 'Lead_Type=|';
}
if(!string.isBlank(objLead.LeadSource))
{
userData += 'Lead_Source=' + objLead.LeadSource + '|';
}
else
{
userData += 'Lead_Source=|';
}
if(objLead.OwnerID != null && queueMap.containsKey(objLead.OwnerID))
{
userData += 'Lead_Owner=' + queueMap.get(objLead.OwnerID).Name + '|';
}
else
{
userData += 'Lead_Owner=|';
}
if(!string.isBlank(objLead.Marketing_Brand_ID__c))
{
userData += 'Marketing_Brand ID=' + objLead.Marketing_Brand_ID__c + '|';
}
else
{
userData += 'Marketing_Brand ID=|';
}
if(!string.isBlank(objLead.Campaign_Custom__c))
{
userData += 'Campaign=' + objLead.Campaign_Custom__c + '|';
}
else
{
userData += 'Campaign=|';
}
if(!string.isBlank(objLead.Marketing_Offer_Code__c))
{
userData += 'Marketing_Offer_Code=' + objLead.Marketing_Offer_Code__c + '|';
}
else
{
userData += 'Marketing_Offer_Code=|';
}
if(!string.isBlank(objLead.Marketing_PPC_Keyword__c))
{
userData += 'Marketing_PPC_Keyword=' + objLead.Marketing_PPC_Keyword__c + '|';
}
else
{
userData += 'Marketing_PPC_Keyword=|';
}
if(!string.isBlank(objLead.Original_Marketing_Activity__c))
{
userData += 'Original_Marketing_Activity=' + objLead.Original_Marketing_Activity__c + '|';
}
else
{
userData += 'Original_Marketing_Activity=|';
}
if(!string.isBlank(objLead.Referral_Region__c))
{
userData += 'Referral_Region=' + objLead.Referral_Region__c + '|';
}
else
{
userData += 'Referral_Region=|';
}
if(!string.isBlank(objLead.Referral_Market__c))
{
userData += 'Referral_Market=' + objLead.Referral_Market__c + '|';
}
else
{
userData += 'Referral_Market=|';
}
if(!string.isBlank(objLead.Referral_Division__c))
{
userData += 'Referral_Division=' + objLead.Referral_Division__c + '|';
}
else
{
userData += 'Referral_Division=|';
}
if(!string.isBlank(objLead.Title))
{
userData += 'Title=' + objLead.Title + '|';
}
else
{
userData += 'Title=|';
}
if(!string.isBlank(objLead.Best_Call_Time__c))
{
userData += 'Best_Time_to_Call=' + objLead.Best_Call_Time__c + '|';
}
else
{
userData += 'Best_Time_to_Call=|';
}
if(!string.isBlank(objLead.Bank_Industry__c))
{
userData += 'Industry=' + objLead.Bank_Industry__c + '|';
}
else
{
userData += 'Industry=|';
}
if(!string.isBlank(objLead.Credit_Card_Volume__c))
{
userData += 'Annual_Sales_Volume=' + objLead.Credit_Card_Volume__c + '|';
}
else
{
userData += 'Annual_Sales_Volume=|';
}
if(!string.isBlank(objLead.Current_Credit_Card_Acceptor__c))
{
userData += 'Accept_Cards=' + objLead.Current_Credit_Card_Acceptor__c + '|';
}
else
{
userData += 'Accept_Cards=|';
}
if(!string.isBlank(objLead.Lead_Source_Most_Recent__c))
{
userData += 'Current_Processor=' + objLead.Lead_Source_Most_Recent__c + '|';
}
else
{
userData += 'Current_Processor=|';
}
if(objLead.Total_Card_Volume__c != NULL)
{
userData += 'MC_VI_Volume=' + objLead.Total_Card_Volume__c + '|';
}
else
{
userData += 'MC_VI_Volume=|';
}
if(!string.isBlank(objLead.PostalCode))
{
userData += 'Zip_Code=' + objLead.PostalCode + '|';
}
else
{
userData += 'Zip_Code=|';
}
userData += 'Already_a_Clover_Merchant=' + objLead.Existing_Customer__c + '|';
if(objLead.OwnerID != null && queueMap.containsKey(objLead.OwnerID))
{
string qName = queueMap.get(objLead.OwnerID).Name;
if(qName.toUpperCase().contains('SAM'))
{
userData += 'pop_type=TELESAMS|';
}
else
{
userData += 'pop_type=TELEGEN|';
}
}
else
{
userData += 'pop_type=TELEGEN|';
}
userData += 'lead_number=' + objLead.Id + '|';
userData += 'Sales_Volume=NONE|';
userData += 'Product=TELESALES DIGITAL|';
userData += 'Device=NONE|';
if(queueMap.containsKey(objLead.OwnerID))
{
if(queueMap.get(objLead.OwnerID).Name == 'SAMS Club Triage')
{
userData += 'Alliance=SAMS|';
}
else
{
userData += 'Alliance=GEN|';
}
}
userData += 'Language=EN-US';
return userData;
}
//Send Notification Batch to Dialer
@future(callout=true)
private static void SendNotificationToDialer(String NotificationBatch)
{
//Request Token for Authentication
RequestToken();
//Generate & Send BatchNotification Payload
Payload notificationPayload = GeneratePayload(NotificationBatch);
SendNotificationBatch(notificationPayload);
}
//Generate Notification Batch Payload
private static Payload GeneratePayload(String NotificationBatch)
{
Dom.Document authPayload = new Dom.Document();
Dom.XmlNode authenticationNode = authPayload.createRootElement('authentication', null, null);
Dom.XmlNode principleNode = authenticationNode.addChildElement('principle', null, null);
principleNode.addTextNode(principle);
Dom.XmlNode passwordNode = authenticationNode.addChildElement('password', null, null);
passwordNode.addTextNode(securityTokenPassword);
Payload payload = new Payload();
payload.SecurityToken = authPayload.toXmlString();
payload.BatchDataXml = NotificationBatch;
System.debug('TeleSales : Notification Payload : ' + payload);
return payload;
}
private static String secToken;
//Request Token API Call
@TestVisible
private static HTTPResponse RequestToken()
{
HttpRequest req = new HttpRequest();
HTTPResponse res = new HTTPResponse();
Http http = new Http();
//Set HTTPRequest Method
req.setMethod('POST');
//Set HTTPRequest header properties
req.setHeader('Content-Type', 'application/x-www-form-urlencoded');
req.setEndpoint(serviceEndPoint + tokenEndpoint);
req.setCompressed(false);
string body = 'username=' + EncodingUtil.urlEncode(username, encoding) +
'&password=' + EncodingUtil.urlEncode(password, encoding) +
'&grant_type=password';
//Set the HTTPRequest body
req.setBody(body);
try {
//Execute web service call
res = http.send(req);
if(res!=null){
secToken=res.getBody();
system.debug('###secToken==='+secToken);
}
System.debug('Integration - Token Callout Response : ' + res.toString());
System.debug('Integration - Token Callout Status : ' + res.getStatus());
System.debug('Integration - Token Callout Status Code : ' + res.getStatusCode());
} catch(System.CalloutException e) {
System.debug('Integration - Token Callout Exception : ' + e.getMessage());
}
return res;
}
//Send Notification Batch API Call
@TestVisible
private static HTTPResponse SendNotificationBatch(Payload payload)
{
HttpRequest req = new HttpRequest();
HTTPResponse res = new HTTPResponse();
Http http = new Http();
//Set HTTPRequest Method
req.setMethod('POST');
//Set HTTPRequest header properties
req.setHeader('Content-Type', 'application/json');
req.setEndpoint(serviceEndPoint + notificationBatchEndpoint);
req.setCompressed(false);
string body = JSON.serialize(payload);
//Set the HTTPRequest body
req.setBody(body);
try {
//Execute web service call
res = http.send(req);
System.debug('Integration - Notification Batch Callout Response : ' + res.toString());
System.debug('Integration - Notification Batch Callout Status : ' + res.getStatus());
System.debug('Integration - Notification Batch Callout Status Code : ' + res.getStatusCode());
} catch(System.CalloutException e) {
System.debug('Integration - Notification Batch Callout Exception : ' + e.getMessage());
}
return res;
}
//Wrapper class for Notification Batch Payload
public class Payload
{
public string SecurityToken;
public string BatchDataXml;
}
//C2 Changes :::::::::::::::: START ::::::::::::::::::::::::::::
public static void sendCancelRequestToDialer(Map<Id, Lead> leadOldMap, Map<Id, Lead> leadNewMap){
//C3-Start
List<S360_TeleSales_QueueFilter__c> lstQueueFilters = S360_TeleSales_QueueFilter__c.getall().values();
Set<string> ValidQueues = new Set<String>();
Set<Id> ValidQueueids = new Set<Id>();
List<Group> validgroups= New List<Group>();
if(lstQueueFilters.size()>0){
for (S360_TeleSales_QueueFilter__c queueName : lstQueueFilters)
{
ValidQueues.add(queueName.Name);
}
}
System.debug('Queue Names***'+ValidQueues);
validgroups=[SELECT Name,id FROM Group where Type='Queue' and Name IN:ValidQueues];
if(validgroups.size()>0){
for(Group qid:validgroups){
ValidQueueids.add(qid.id);
}
}
System.debug('Queue IDs***'+ValidQueueids);
// Fetch the Leads for which Dialer Status has changed
Set<Id> leadIdSet=new Set<Id>();
List<Lead> RescduldLeads = new List<Lead>();//C6 Change
for(Id leadID : leadNewMap.keySet())
{
Lead newLead = leadNewMap.get(leadID);
Lead oldLead = leadOldMap.get(leadID);
System.debug('Lead is***'+newLead);
//C6 Changes-Start
if(newLead!=null && oldLead!=null && newLead.Preffered_Contact__c != oldLead.Preffered_Contact__c)//Need to add Partner and owner checks
{
RescduldLeads.add(objLead);
}
System.debug('Total Allowed Leads To reProcess : ' + RescduldLeads.size());
//C6 Changes-END
if(((!ValidQueueids.contains(newLead.OwnerID)) && ValidQueueids.contains(oldLead.OwnerID)) || (newLead!=null && oldLead!=null && newLead.Status != oldLead.Status &&
(newLead.Status == 'Contacted'||newLead.Status == 'Unqualified'||newLead.Status == 'Qualified') && (newLead.Dialer_Activity_Status__c=='Sent To Dialer')))
{
leadIdSet.add(newLead.id);
}
}
//C3-End
S360_AutoDialer_DialerLogDetail__c objDialerlogdetail= new S360_AutoDialer_DialerLogDetail__c();
objDialerlogdetail.RecordTypeId = Schema.SObjectType.S360_AutoDialer_DialerLogDetail__c.getRecordTypeInfosByName().get('TeleSales').getRecordTypeId();
if(!Test.isRunningTest() && leadIdSet.size()>0)
{
objDialerlogdetail.clientNotificationId__c = String.valueOf(leadIdSet);
insert objDialerlogdetail;
CancelInteraction(leadIdSet);
}
//C6 Changes Start
if(RescduldLeads.size()>0){
ProcessRequest(RescduldLeads);
}
//C6 Changes end
}
//Send Cancel Request API Call
public static HTTPResponse SendCancelRequest(CancelPayload payload)
{
HttpRequest req = new HttpRequest();
HTTPResponse res = new HttpResponse();
Http http = new Http();
//Set HTTPRequest Method
req.setMethod('POST');
//Set HTTPRequest header properties
req.setHeader('Content-Type', 'application/json');
if(secToken!=null && secToken!=''){
req.setHeader('Authorization', secToken);
}
req.setEndpoint(serviceEndPoint + cancelEndpoint);
req.setCompressed(false);
string body = JSON.serialize(payload);
System.debug('Request body : ' + body);
System.debug('req : ' + req);
//Set the HTTPRequest body
req.setBody(body);
try {
//Execute web service call
res = http.send(req);
System.debug('Integration - Cancel Callout Response : ' + res.toString());
System.debug('Integration - Cancel Callout Status : ' + res.getStatus());
System.debug('Integration - Cancel Callout Status Code : ' + res.getStatusCode());
} catch(System.CalloutException e) {
System.debug('Integration - Cancel Callout Exception : ' + e.getMessage());
}
return res;
}
//Cancel Interaction
@future(callout=true)
public static void CancelInteraction(Set<Id> leadIdentifier)
{
List<S360_Act_GenericUtility.ServiceResponse> parseRes = new List <S360_Act_GenericUtility.ServiceResponse>();
if(Test.isRunningTest()){
S360_Act_GenericUtility.ServiceResponse testResponse = new S360_Act_GenericUtility.ServiceResponse('ResultCode','0');
parseRes.add(testResponse);
}
else{
RequestToken();
HTTPResponse res = new HttpResponse();
CancelPayload payload = new CancelPayload();
system.debug('Value sent ::: ' + String.valueOf(leadIdentifier));
List<Id> LeadIds = new List<Id>();
LeadIds.addAll(leadIdentifier);
if(LeadIds != null && !LeadIds.isEmpty()){
Id leadId = LeadIds[0];
system.debug('Single Lead Id ' + leadId);
payload.CaseId = String.valueOf(leadId);
}
res = SendCancelRequest(payload);
System.debug('Integration - Token Callout Response Body for Cancel Notification: ' + res.getBody());
//Parse dialer response
parseRes = S360_Act_GenericUtility.parseJSON(res.getBody());
system.debug('parseRes Telesales:::'+parseRes);
}
//Fetch lead details
List<Lead> lstLeads = [SELECT Id, Dialer_Activity_Status__c
FROM Lead WHERE Id IN :leadIdentifier];
system.debug('lstLeads Inside Integration:::'+ lstLeads);
//Mark boolean field true if dialer send success response
Boolean CancelledSuccess = false;
for(S360_Act_GenericUtility.ServiceResponse item : parseRes)
{
if(item!=null){
if(item.tag == 'ResultCode' && item.value == '0')
{
CancelledSuccess= true;
system.debug('CancelledSuccess::'+CancelledSuccess);
}
}
}
//Update lead status after getting success cancel response from dialer
if(CancelledSuccess)
{
for(Lead leadRecord : lstLeads)
{
leadRecord.Dialer_Activity_Status__c = 'Cancelled';
}
update lstLeads;
}
}
//Wrapper Class for Cancel Payload
public class CancelPayload
{
//2way connect is using CaseId as the attribute to get the details for unique record. Lease Id is passing to this Case Id
public string CaseId;
}
//C2 Changes :::::::::::::::: END ::::::::::::::::::::::::::::
//C4 Changes : PR16004639 2Way Connect Enhancement Sprint 3. Scheduled Calls
/**************
Method Name : getScheduledTime
Method parameters : String besttime
Functionality : This method checks the BestTimeToCall value(Eg: 9 AM , 12 PM ) and returns concatenated value of BestTimeToCall time with next day date in 'MM/DD/YYYY H:M:S' format
*************/
public static String getScheduledTime(String besttime){
String schdatetime='';
Datetime schdate=system.now();
SYSTEM.DEBUG('schdate'+schdate);
if(besttime.toUpperCase().contains('MORNING')) // C5 changes
schdatetime ='09:00:00';
else if(besttime.toUpperCase().contains('AFTERNOON'))// C5 changes
schdatetime = '13:00:00';
else if(besttime.toUpperCase().contains('EVENING'))// C5 changes
schdatetime ='18:00:00';
else if(besttime.equalsIgnoreCase('6pm - 8pm'))
schdatetime ='19:00:00';
else {
// C5 changes start
String[] splitByColon;
if(besttime.contains(':') && (besttime.equalsIgnoreCase('am')||besttime.equalsIgnoreCase('pm')))
splitByColon = besttime.split(':');
else
return '999';
Integer hoursValue = Integer.valueof((splitByColon[0].trim().isnumeric())?splitByColon[0].trim():'999');
if(hoursValue==999)
return '999';
//C5 changes end
String[] splitForMins = splitByColon[1].split(' ');
if(splitForMins[1].equalsIgnoreCase('pm')){
if(hoursValue!=12) //c4 changes
hoursValue = hoursValue + 12;
schdatetime=String.valueOf(hoursValue)+':'+splitForMins[0]+':'+'00';
}
else{
schdatetime=String.valueOf(hoursValue);
if(schdatetime != null && schdatetime != '' && schdatetime.length()==1)
schdatetime='0'+ schdatetime+':'+splitForMins[0]+':'+'00';
else //C5 changes
schdatetime=schdatetime+':'+splitForMins[0]+':'+'00'; // C5 changes
}
}
SYSTEM.DEBUG('schdatetime'+schdatetime);
String[] splitbyspace=string.valueof(schdate.format('MM/dd/yyyy HH:mm:ss', 'America/New_York')).split(' ');
String[] splitByColonPre=string.valueof(splitbyspace[1]).split(':');
SYSTEM.DEBUG('splitbyspace'+splitbyspace);
SYSTEM.DEBUG('splitByColonPre'+splitByColonPre);
String[] splitByColonSch=schdatetime.split(':');
Integer[] curr=new Integer[splitByColonPre.size()];
Integer[] sch=new Integer[splitByColonSch.size()];
for(integer i=0;i<splitByColonPre.size();i++)
{
curr[i]=integer.valueof(splitByColonPre[i]);
sch[i]=integer.valueof(splitByColonSch[i]);
}
Integer sumcurr=(curr[0]*3600)+(curr[1]*60)+(curr[2]*1);
Integer sumsch=(sch[0]*3600)+(sch[1]*60)+(sch[2]*1);
sySTEM.DEBUG('sumcurr'+sumcurr);
sySTEM.DEBUG('sumsch'+sumsch);
if(sumcurr>=sumsch)
schdatetime=schdate.adddays(1).format('MM/dd/yyyy')+' '+schdatetime;
else
schdatetime=schdate.format('MM/dd/yyyy')+' '+schdatetime;
return schdatetime;
}
//C4 Changes :::::::::::::::: END ::::::::::::::::::::::::::::
//C6-Changes Start
/**************
Method Name : getScheduledTimediff
Method parameters : String besttime
Functionality : to calculate time differnce between Preferred time to contact and current time
*************/
public static Boolean getScheduledTimediff(Datetime Prefeeredtimeis){
Boolean timediff;
Datetime Currenttime=system.now();
//Prefeeredtimeis-Currenttime is greterthan 1hr return true else false;
return true
}
//C6-Changes End
}