Thursday, 31 May 2018

Omniscript - Typeahead with Time Slots

global with sharing class CreateAppointmentOSController implements vlocity_ins.VlocityOpenInterface {
    public Boolean invokeMethod(String methodName, Map<String, Object> input, Map<String, Object> outMap, Map<String, Object> options){
        boolean flag=false;
        System.debug('---invokeMethod---');
        System.debug('input: '+input);
        System.debug('methodName: '+methodName);
        if(methodName.equals('getFreeSlots')){
            flag=getFreeSlots(input,outMap,options);
        }
        return flag;
    }
    public boolean getFreeSlots(Map<String, Object> input, Map<String, Object> outMap, Map<String, Object> options){
        boolean flag=true;
        Map<String,Object> AppointmentDetails=new Map<String,Object>();
        if(input.containsKey('AppointmentDetails'))
            AppointmentDetails=(Map<String,Object>)input.get('AppointmentDetails');
        Date startDate;
        if(AppointmentDetails.containsKey('StartDate')){
            String startDatestr=(String)AppointmentDetails.get('StartDate');
            //Take only date from 2018-05-30T18:30:00.000Z
            if(startDatestr.contains('T')){
                startDate=Date.valueOf(startDatestr.split('T')[0]);
            }
        }
        String ownerId=UserInfo.getUserId();
        List<Map<String,String>> lookupoptions=new List<Map<String,String>>();
        List<String> ctlist=new List<String>();
        List<Event> evtlist=EmptyEventSlotManager.FindAllfreeSlots(startDate, ownerId);       
        String[] endTime;
        String[] startTime;
       
        for(Event e:evtlist){
            try{
                startTime=String.valueOf(e.ActivityDateTime).subStringAfter(' ').split(':'); //get hour
                endTime=String.valueOf(e.EndDateTime).subStringAfter(' ').split(':'); //get hour
            }catch(Exception ex){
                system.debug('Exception: '+ex);
            }
           
            String tm='';
            if(Integer.valueOf(endTime[0])<=12)
                tm=' AM';
            else
                tm=' PM';
           
            Integer hh=Integer.valueOf(startTime[0]);
            Integer mm=Integer.valueOf(startTime[1]);                   
            String mmstr=String.valueOf(mm);
            for(integer i=1;i<=4;i++){  // 4x1/2 hr = 2hrs 
                if(mm==0)                   
                    mmstr=String.valueOf(mm+'0');
                lookupoptions.add(new Map<String,String>{'OwnerId'=>String.valueOf(ownerId),'startTime'=>String.valueOf(hh+':'+mmstr+tm)});
                mm+=30;
                //1 hour completed
                if(mm>=60){
                    mm=0;
                    hh++;
                }
                mmstr=String.valueOf(mm);
            }
        }
        outMap.put('suggestions',lookupoptions);
        return flag;
    }
}

Thursday, 24 May 2018

Salesforce - Empty Event Slot Manager

public class EmptyEventSlotManager {
    public static List<Event> freeslots=new List<Event>();
    public static void createSlots(Date p_startDate,Id p_userId){
        System.debug('---createSlots---');
        List<Event> busyslots=[SELECT ActivityDateTime,EndDateTime
                               FROM Event
                               WHERE ownerId=:p_userId
                               AND activitydate=:p_startDate
                               ORDER BY ActivityDateTime];
        System.debug('busyslots: '+busyslots.size());
        // 8 AM - 6 PM => 10 hrs x 60 = 480 minutes + last slot (2 hrs) = 10 hrs
        for(integer minute=0;minute<600;minute++){
            if(!isBusyslot(minute,busyslots)){
                freeslots.add(getSlot(minute,p_startDate,p_userId));
                minute+=119; // add two hours - 1, for next increment
            }
        }
        System.debug('freeslots: '+freeslots.size());
        insert freeslots;
    }
    public static boolean isBusyslot(Integer p_minute,List<Event> p_busyslots){
        boolean flag=false; 
        //check start_time
        for(Event e:p_busyslots){
            if(isWithinSlot(p_minute+480,e)){
                flag=true;
        System.debug('---isBusyslot---');
                break;
            }
        }
        //check end_time
        for(Event e:p_busyslots){
            for(integer i=1;i<=119;i++){
            if(isWithinSlot(p_minute+480+i,e)){
                flag=true;
        System.debug('---isBusyslot---');
                break;
            }
            }
        } 
        if(p_minute+480+119 > 600+480){
            flag=true;
        }
        return flag;
    }
    public static Event getSlot(Integer p_minute,Date p_startDate,Id p_userId){
        System.debug('---getSlot---');
        Date myDate = p_startDate;
        Time activity_start_myTime = Time.newInstance(0, (p_minute+480), 0, 0);  // + 8 AM
        Time activity_end_myTime = Time.newInstance(0, (p_minute+480+119), 0, 0); // + 8 AM + 2 hrs
        DateTime activity_start_dt = DateTime.newInstance(myDate, activity_start_myTime);       
        DateTime activity_end_dt = DateTime.newInstance(myDate, activity_end_myTime);
        //create event
        Event ev=new Event();
        ev.OwnerId=p_userId;
        ev.ActivityDate=p_startDate;
        ev.ActivityDateTime=activity_start_dt;
        ev.EndDateTime=activity_end_dt;
        ev.Subject='Free slot';
        return ev;
    }
    public static boolean isWithinSlot(integer p_mins,Event e){
        boolean flag=false;
        integer e_start_min=(e.ActivityDateTime.hour()*60)+e.ActivityDateTime.minute();
        integer e_end_min=(e.EndDateTime.hour()*60)+e.EndDateTime.minute();
        System.debug('p_mins: '+p_mins+' e_start_min: '+e_start_min+' e_end_min: '+e_end_min);
        //end time duration is less than 2hrs       
        //if((e_start_min+120)>e_end_min)
         //   e_end_min=e_start_min+120;
        // between start and end minutes
        if(p_mins>=e_start_min
           && p_mins<=e_end_min){
               flag=true;             
               System.debug('---isWithinSlot---');       
           }
        return flag;
    }
}

Wednesday, 23 May 2018

Salesforce - Update childs with same changes when they are made at parent events of records



trigger EventTrigger on Event (after insert,after update) {
    if(Trigger.isInsert){
        if(Trigger.isAfter){
            EventTriggerHelper.callFutureChildEventCreation(Trigger.New);
        }
    }
    if(Trigger.isUpdate){
        if(Trigger.isAfter){
            EventTriggerHelper.callFutureChildEventUpdation(Trigger.New);
        }
    }
}








public class EventTriggerHelper {
    public static void callFutureChildEventCreation (List<Event> newList){
        List<String> eligibleList = new List<String>();
        String devRecordTypeId = Schema.SObjectType.Event.getRecordTypeInfosByName().get('Campus Visit Meeting').getRecordTypeId();
        for(Event evt: newList){
            if(evt.recordTypeId == devRecordTypeId)
            {
                eligibleList.add(evt.Id);
            }
        }
        if(eligibleList.size() > 0)
        createChildEvents(eligibleList);
    }
    public static void callFutureChildEventUpdation (List<Event> newList){
        List<String> eligibleList = new List<String>();
        String devRecordTypeId = Schema.SObjectType.Event.getRecordTypeInfosByName().get('Campus Visit Meeting').getRecordTypeId();
        for(Event evt: newList)
        {
            if(evt.recordTypeId == devRecordTypeId
               && evt.Parent_Event__c == NULL)
            {
                eligibleList.add(evt.Id);
            }
        }
        if(eligibleList.size() > 0)
        updateChildEvents(eligibleList);
    }
    @future
    public static void createChildEvents(List<String> idsList){
        system.debug('EventTriggerHelper.createChildEvents');
        List<Event> eligibleList = new List<Event>();
        List<Event> newEvents = new List<Event>();
        String devRecordTypeId = Schema.SObjectType.Event.getRecordTypeInfosByName().get('Child Campus Visit Meetings').getRecordTypeId();
       
        String Query = getEventQuery();
        Query += ' WHERE Id IN : idsList';
        List<Event> newList = (List<Event>) Database.query(Query);
        for(Event evt: newList){
            if(evt.EventWhoIds != NULL
               && evt.EventWhoIds.size() > 0)
            {
                eligibleList.add(evt);
            }
        }
        if(eligibleList.size() == 0){
            system.debug('No Match');
            return;
        }
        system.debug(JSON.serializePretty(eligibleList));
        for(Event evt: eligibleList){
            for(String contactId: evt.EventWhoIds){
                if(contactId != evt.WhoId){
                    Event newEvt = evt.clone(false, //preserveId,
                                             true, //isDeepClone,
                                             true, //preserveReadonlyTimestamps,
                                             false); //preserveAutonumber);
                    newEvt.whoId = contactId;
                    newEvt.Parent_Event__c = evt.Id;
                    newEvt.RecordTypeId = devRecordTypeId;
                    newEvents.add(newEvt);
                }
            }
        }
        insert newEvents;
        system.debug(JSON.serializePretty(newEvents));
    }
    @future
    public static void updateChildEvents(List<String> idsList){
        system.debug('EventTriggerHelper.updateChildEvents');
        List<Event> eligibleList = new List<Event>();
        List<Event> newEvents = new List<Event>();
        Set<String> fieldNames = new Set<String>();
        Map<String, Schema.SObjectField> m = Schema.SObjectType.Event.fields.getMap();
        for(String fieldName: m.keySet()){
            Schema.SObjectField sfd = m.get(fieldName);
            schema.DescribeFieldResult dfr = sfd.getDescribe();
           // if(!dfr.isCalculated())
            if(!dfr.isCalculated()
               && dfr.isUpdateable()){
                fieldNames.add(fieldName);
            }
        }
       
        String devRecordTypeId = Schema.SObjectType.Event.getRecordTypeInfosByName().get('Child Campus Visit Meetings').getRecordTypeId();
       
        String Query = getEventQuery();
        Query += ' WHERE Id IN : idsList';
        List<Event> newList = (List<Event>) Database.query(Query);
       
        Query = getEventQuery();
        Query += ' WHERE Parent_Event__c IN : idsList';
        List<Event> newChildList = (List<Event>) Database.query(Query);
       
        Map<Id,List<Event>> childEventsMap = new Map<Id,List<Event>>();
        for(Event evt: newChildList){
            if(!childEventsMap.containsKey(evt.Parent_Event__c))
                childEventsMap.put(evt.Parent_Event__c,new List<Event> ());
            childEventsMap.get(evt.Parent_Event__c).add(evt);
        }
        System.debug('childEventsMap: '+childEventsMap);
       
        for(Event evt: newList){
            if(evt.EventWhoIds != NULL
               && evt.EventWhoIds.size() > 0
               && childEventsMap.get(evt.Id) != NULL)
            {
                eligibleList.add(evt);
            }
        }
        System.debug('eligibleList: '+eligibleList);
        if(eligibleList.size()>0)
        System.debug('childEventsMap.get(evt.Parent_Event__c): '+childEventsMap.get(eligibleList[0].Parent_Event__c));
        if(eligibleList.size() == 0){
            system.debug('No Match');
            return;
        }
        //system.debug(JSON.serializePretty(eligibleList));
        for(Event evt: eligibleList)
        {
           
           // for(Event cEvt: childEventsMap.get(evt.Parent_Event__c))
           for(Event cEvt: childEventsMap.get(evt.Id))
            {
                for(String fieldName: fieldNames)
                {
                    if(evt.get(fieldName) != NULL)
                    {
                         cEvt.put(fieldName,evt.get(fieldName));
                    }
                }
                newEvents.add(cEvt);
            }
        }
        update newEvents;
    }
    public static String getEventQuery(){
        String fields = '';
        for(String fieldName: Schema.SObjectType.Event.fields.getMap().keySet()){
            fields += fieldName;
            fields += ', ';
        }
        fields += 'EventWhoIds ' ;
        String Query = 'SELECT ';
        Query += fields;
        Query += ' FROM Event';
        return Query;
    }
}

Monday, 21 May 2018

Salesforce - Schedule a class to create a record after n number of days and send an email template to the owner email.



 public static void scheduleTaskCreationJob(Task p_task,Integer days,EmailTemplate p_etemplate,String targetObjectId){       
        System.debug('---scheduleTaskCreationJob---');
        String day2=String.valueOf(datetime.now()+days);
        String time_str=day2.substringAfter(' '); //2018-05-06 15:33:41, get time only 
        String month=day2.subStringBefore(' ').split('-')[1];
        string day=day2.subStringBefore(' ').split('-')[2];
        String[] ctime=time_str.split(':');                           
        String sch = ctime[2]+' '+ctime[1]+' '+ctime[0]+' '+day+' '+month+' ?'; 
        System.debug('sch: '+sch);
        System.schedule('SalesProcessScheduler', sch, new SalesProcessScheduler(p_task,String.valueof(days+1),p_etemplate,targetObjectId));
    }       





global class SalesProcessScheduler implements Schedulable {
    public static Task tsk;
    public static String day;
    public static EmailTemplate emailTemplate;
    public static String targetObjectId;
    global void execute(SchedulableContext ctx) {
        createNewTask();
    }
    public static void createNewTask(){
        System.debug('---createNewTask---');
        Task t=new Task();
        t.Subject='Day '+day;
        t.WhoId=tsk.WhoId;
        t.Status='Not Started';
        insert t;       
        sendEmailTemplate(emailTemplate,tsk.whoId);
    }
    public SalesProcessScheduler(Task p_task,String p_day,EmailTemplate p_emailTemplate,String p_targetObjectId){
        tsk=p_task;
        day=p_day;
        emailTemplate=p_emailTemplate;
        targetObjectId=p_targetObjectId;
    }
    public static void sendEmailTemplate(EmailTemplate p_etemplate,String targetObjectId){
        System.debug('---sendEmailTemplate---');
        Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();
        List<String> emaillist=new List<String>();
        // emaillist.add(email);
        message.toAddresses = emaillist;
        //message.ccAddresses = new List<String> {label.Off_Boarding_CC_Email_addresses};       
        message.setTargetObjectId(targetObjectId);
        message.setSenderDisplayName('Lead Sales Process');
        message.setUseSignature(false);
        message.setBccSender(false);
        message.setSaveAsActivity(false);       
        EmailTemplate et=p_etemplate;           
        message.setTemplateId(et.id);       
        Messaging.SingleEmailMessage[] messages =
            new List<Messaging.SingleEmailMessage> {message};
                Messaging.SendEmailResult[] results = Messaging.sendEmail(messages);       
        if (results[0].success) {
            System.debug('The email was sent successfully.');
        } else {
            System.debug('The email failed to send: '
                         + results[0].errors[0].message);
        }
    }
}

Salesforce - Send Email template with Apex Coding



//Email will be sent to target object's email

public static void sendEmailTemplate(EmailTemplate p_etemplate,String targetObjectId){
        Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();
        List<String> emaillist=new List<String>();
        // emaillist.add(email);
        message.toAddresses = emaillist;
        //message.ccAddresses = new List<String> {label.Off_Boarding_CC_Email_addresses};       
        message.setTargetObjectId(targetObjectId);
        message.setSenderDisplayName('Lead Sales Process');
        message.setUseSignature(false);
        message.setBccSender(false);
        message.setSaveAsActivity(false);       
        EmailTemplate et=p_etemplate;           
        message.setTemplateId(et.id);       
        Messaging.SingleEmailMessage[] messages =
            new List<Messaging.SingleEmailMessage> {message};
                Messaging.SendEmailResult[] results = Messaging.sendEmail(messages);       
        if (results[0].success) {
            System.debug('The email was sent successfully.');
        } else {
            System.debug('The email failed to send: '
                         + results[0].errors[0].message);
        }
    }

Sunday, 20 May 2018

Salesforce - Get Present Time and Week Day with Apex Coding



         //2018-05-06 15:33:41, get time only
         String presenttime=String.valueOf(datetime.now()).substringAfter(' ');
         System.assertEquals('15:33:41',presenttime);




public String getWeekDay(){
        String dayOfWeek='';       
        // Cast the Date variable into a DateTime
        DateTime myDateTime = (DateTime) System.today();
        dayOfWeek = myDateTime.format('E');
        // dayOfWeek is Sun, Mon, Tue, Wed, Thu, Fri, Sat.
        return dayOfWeek;
    }