Thursday, 28 June 2018

Salesforce - Data Aggregation with Apex

global class LeadSharePerformanceTrackBatch implements Database.Batchable<sObject>,Database.Stateful, Schedulable {
    public List<Round_Robin_Client__c> round_robin_list;
    global void scheduleMe() {
        String CRON=System.Label.LeadSharePerformanceTrackBatch_CRON;
        //Run the batch daily at 10 PM
        system.schedule('LeadSharePerformanceTrackBatch__'+DateTime.now(), CRON, new LeadSharePerformanceTrackBatch());   
    }
    global void execute(SchedulableContext sc){
        LeadSharePerformanceTrackBatch batch=new LeadSharePerformanceTrackBatch();
        ID batchprocessid=Database.executeBatch(batch);
    }
    //query RoundRobin records
    global Database.QueryLocator start(Database.BatchableContext BC) {       
        round_robin_list=new List<Round_Robin_Client__c>();
        //Query RoundRobin with recently created 90 Leadshares
        String query = 'SELECT '+ showFields('Round_Robin_Client__c')+         
            ', (SELECT Id,assigned__c,round_robin__c,date__c FROM Leadshare__r ORDER BY lastmodifieddate DESC LIMIT 90) '+
            'FROM Round_Robin_Client__c '+
            'WHERE Active_Lead_Type__c!=NULL'+
            ' AND Status__c=\'Active\'';
        System.debug('query: '+query);
        return Database.getQueryLocator(query);
    }
    global void execute(Database.BatchableContext BC, List<Round_Robin_Client__c> scope) {
        //Add all records of each batch
        round_robin_list.addAll(scope);
    } 
    global void finish(Database.BatchableContext BC) {
        Set<Id> spIdset=new Set<Id>();
        set<String> leadtypeset=new Set<String>();
        for(Round_Robin_Client__c rc:round_robin_list){
            spIdset.add(rc.originator__c);
            leadtypeset.add(rc.Active_Lead_Type__c);
        }
        //Create Leadshare records
        List<Leadshare__c> leadshares=getLeadSharesWithStatistics(getNewLeadshares(round_robin_list),spIdset,leadtypeset);
        if(leadshares.size()>0){
            insert leadshares;
            System.debug('Total Leadshares created today: '+leadshares.size());
        }     
    }
    public String showFields(String sobjectname) {
        //fields.clear();
        String fields='';
        system.debug('name' + sobjectname);
        Map <String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
        Map <String, Schema.SObjectField> fieldMap =  schemaMap.get(sobjectname).getDescribe().fields.getMap();
        for(Schema.SObjectField sfield : fieldMap.Values())
        {
            schema.describefieldresult dfield = sfield.getDescribe();
            // system.debug(dfield.getname()+'=>'+dfield.getLabel());
            fields+=dfield.getName()+',';
        }
        fields=fields.removeEnd(',');
        System.debug('fields: '+fields);
        return fields;
    } 
    public static List<LeadShare__c> getLeadSharesWithStatistics(List<LeadShare__c> p_lslist,Set<Id> p_spIdset,Set<String> p_leadtypeset){
        List<LeadShare__c> parentList = p_lslist;
        List<LeadShare__c> leadshare_list = new List<LeadShare__c>();   
        Set<String> stagesSet=new Set<String>();
        Set<Id> salesRepIdSet=new Set<Id>();
        Set<String> leadActiveTypeset=new Set<String>();
        // Include selective stages for calculation
        stagesSet=new Set<String>{'Initial Contact','Invalid Lead','Lost','Closed','Initial - to Retry','Overcome Objections','Ready to Close','Promised To Buy'};
    salesRepIdSet=p_spIdset;
        leadActiveTypeset=p_leadtypeset;
        Map<String,Integer> TotalLeadsMap=new Map<String,Integer>();
        for(AggregateResult ar:[SELECT count(Id) counter,Sales_Rep__c,Primary_Interest__c
                                FROM SEOX3_Client__c
                                WHERE Sales_Rep__c IN:salesRepIdSet
                                AND Prospective_Stage__c IN:stagesSet
                                AND Primary_Interest__c IN:p_leadtypeset
                                group by Sales_Rep__c,Primary_Interest__c]){
                                    TotalLeadsMap.put((String)ar.get('Sales_Rep__c')+'_'+(String)ar.get('Primary_Interest__c'),(Integer)ar.get('counter'));
                                }
        System.debug('TotalLeadsMap: '+TotalLeadsMap);
       
         Map<String,Integer> TotalLeadsTodayMap=new Map<String,Integer>();
        for(AggregateResult ar:[SELECT count(Id) counter,Sales_Rep__c,Primary_Interest__c,Lastmodified_Date_part__c
                                FROM SEOX3_Client__c
                                WHERE Sales_Rep__c IN:salesRepIdSet
                                AND Prospective_Stage__c IN:stagesSet
                                AND Primary_Interest__c IN:p_leadtypeset
                                group by Sales_Rep__c,Primary_Interest__c,Lastmodified_Date_part__c]){
                                    TotalLeadsTodayMap.put(ar.get('Sales_Rep__c')+'_'+ar.get('Primary_Interest__c')+'_'+ar.get('Lastmodified_Date_part__c'),(Integer)ar.get('counter'));
                                }
        System.debug('TotalLeadsTodayMap: '+TotalLeadsTodayMap);
       
        //Getting Count of client record on the Basis of Prospective_Stage__c.
        List<AggregateResult> arrList = [SELECT COUNT(Id) counter, Prospective_Stage__c,Primary_Interest__c,Sales_Rep__c,Lastmodified_Date_part__c 
                                         FROM SEOX3_Client__c
                                         WHERE Sales_Rep__c IN:salesRepIdSet
                                         AND Prospective_Stage__c IN:stagesSet
                                         AND Primary_Interest__c IN:p_leadtypeset
                                         group by Prospective_Stage__c, Primary_Interest__c,Sales_Rep__c,Lastmodified_Date_part__c];
       
        //Map For getting StageName and its count.
        Map<String, Integer> prospectiveStagesMap = new Map<String, Integer>();       
        //Filling Stage and count in Map.
        for (AggregateResult ar : arrList) {                       
            prospectiveStagesMap.put(ar.get('Prospective_Stage__c')+'_'+ar.get('Sales_Rep__c')+'_'+ar.get('Primary_Interest__c')+'_'+ar.get('Lastmodified_Date_part__c'),(Integer)ar.get('counter'));
        }
        System.debug('prospectiveStagesMap: '+prospectiveStagesMap); 
       
        // if (!Test.isRunningTest()){
        for(LeadShare__c ls : parentList){
            // Initial Contact (Uncalled) %
            if(prospectiveStagesMap.get('Initial Contact'+'_'+ls.Sales_Rep__c+'_'+ls.Active_Lead_Type__c+'_'+ls.Date__c) != null )
                ls.Initial_Contact__c = prospectiveStagesMap.get('Initial Contact'+'_'+ls.Sales_Rep__c+'_'+ls.Active_Lead_Type__c+'_'+ls.Date__c);
            else
                ls.Initial_Contact__c = 0;
            // Invalid %
            if(prospectiveStagesMap.get('Invalid Lead'+'_'+ls.Sales_Rep__c+'_'+ls.Active_Lead_Type__c+'_'+ls.Date__c) != null )
                ls.Invalid_Lead__c = prospectiveStagesMap.get('Invalid Lead'+'_'+ls.Sales_Rep__c+'_'+ls.Active_Lead_Type__c+'_'+ls.Date__c);
            else
                ls.Invalid_Lead__c = 0;
            // Lost %
            if(prospectiveStagesMap.get('Lost'+'_'+ls.Sales_Rep__c+'_'+ls.Active_Lead_Type__c+'_'+ls.Date__c) != null )
                ls.Lost__c = prospectiveStagesMap.get('Lost'+'_'+ls.Sales_Rep__c+'_'+ls.Active_Lead_Type__c+'_'+ls.Date__c);
            else
                ls.Lost__c = 0;
            // Closed %
            if(prospectiveStagesMap.get('Closed'+'_'+ls.Sales_Rep__c+'_'+ls.Active_Lead_Type__c+'_'+ls.Date__c) != null)
                ls.Closed__c = prospectiveStagesMap.get('Closed'+'_'+ls.Sales_Rep__c+'_'+ls.Active_Lead_Type__c+'_'+ls.Date__c);
            else
                ls.Closed__c = 0;
            // Retry %
            if(prospectiveStagesMap.get('Initial - to Retry'+'_'+ls.Sales_Rep__c+'_'+ls.Active_Lead_Type__c+'_'+ls.Date__c) != null)
                ls.Initial_to_Retry__c = prospectiveStagesMap.get('Initial - to Retry'+'_'+ls.Sales_Rep__c+'_'+ls.Active_Lead_Type__c+'_'+ls.Date__c);
            else
                ls.Initial_to_Retry__c = 0;
            //Overcome %
            if(prospectiveStagesMap.get('Overcome Objections'+'_'+ls.Sales_Rep__c+'_'+ls.Active_Lead_Type__c+'_'+ls.Date__c) != null)
                ls.Overcome_Objections__c = prospectiveStagesMap.get('Overcome Objections'+'_'+ls.Sales_Rep__c+'_'+ls.Active_Lead_Type__c+'_'+ls.Date__c);
            else
                ls.Overcome_Objections__c = 0;
            //Ready %
            if(prospectiveStagesMap.get('Ready to Close'+'_'+ls.Sales_Rep__c+'_'+ls.Active_Lead_Type__c+'_'+ls.Date__c) != null )
                ls.Ready_to_Close__c = prospectiveStagesMap.get('Ready to Close'+'_'+ls.Sales_Rep__c+'_'+ls.Active_Lead_Type__c+'_'+ls.Date__c);
            else
                ls.Ready_to_Close__c = 0;
            //Promised_to_Buy_Per__c
            if(prospectiveStagesMap.get('Promised To Buy'+'_'+ls.Sales_Rep__c+'_'+ls.Active_Lead_Type__c+'_'+ls.Date__c) != null)
                ls.Promised_to_Buy__c = prospectiveStagesMap.get('Promised To Buy'+'_'+ls.Sales_Rep__c+'_'+ls.Active_Lead_Type__c+'_'+ls.Date__c);
            else
                ls.Promised_to_Buy__c = 0;
            ls.Working__c=ls.Initial_to_Retry__c+ls.Overcome_Objections__c+ls.Promised_to_Buy__c+ls.Ready_to_Close__c;
            ls.Total_Leads_Sales_Rep_Lead_Type__c=TotalLeadsMap.get(ls.Sales_Rep__c+'_'+ls.Active_Lead_Type__c);           
            ls.No_of_Leads_Worked_Modified__c=TotalLeadsTodayMap.get(ls.Sales_Rep__c+'_'+ls.Active_Lead_Type__c+'_'+(ls.Date__c));
            leadshare_list.add(ls);
        }
        //  }     
        return leadshare_list;
    }
    global List<Leadshare__c> getNewLeadShares(List<Round_Robin_Client__c> p_round_robin_list){
        List<Leadshare__c> lead_shares_list=new List<Leadshare__c>();       
        //Create a Map for each Active_Lead_Type__c
        Map<String,List<Round_Robin_Client__c>> lead_type_map=new Map<String,List<Round_Robin_Client__c>>();
        for(Round_Robin_Client__c r:p_round_robin_list){
            //Add key if it is not exists
            if(!lead_type_map.containsKey(r.Active_Lead_Type__c+'_'+String.valueOf(r.Lastmodifieddate).split(' ')[0])){
                lead_type_map.put(r.Active_Lead_Type__c+'_'+String.valueOf(r.Lastmodifieddate).split(' ')[0],new List<Round_Robin_Client__c>());
            }
            //Add round robin records with same Active_Lead_Type__c
            if(lead_type_map.containsKey(r.Active_Lead_Type__c+'_'+String.valueOf(r.Lastmodifieddate).split(' ')[0])){               
                lead_type_map.get(r.Active_Lead_Type__c+'_'+String.valueOf(r.Lastmodifieddate).split(' ')[0]).add(r);
            }
        }
        System.debug('lead_type_map: '+lead_type_map);
        //create leadshare for each round robin record
        for(String ky:lead_type_map.keyset()){
            //Process each round robin
            for(Round_Robin_Client__c r:lead_type_map.get(ky)){
                Leadshare__c ls=new Leadshare__c();
                //ls.Name='Leadshare__'+System.today().format();                   
                if(r.Assigned__c!=null){
                    try{
                        ls.Round_robin__c=(r.Assigned__c/getSum(lead_type_map.get(ky)))*100;
                    }catch(Exception ex){
                        //division by zero error occured, initialize it to zero
                        ls.Round_robin__c=0;
                    }
                }
               
                ls.Date__c=system.today();
                ls.RoundRobin__c=r.Id;
                ls.Active_Lead_Type__c=r.Active_Lead_Type__c;
                ls.Sales_Rep__c=r.Originator__c;
                if(r.Skipped__c!=null)
                    ls.Skipped__c=String.valueOf(r.Skipped__c);
                ls.Total_Hits__c=r.Total_Hits__c;
                ls.Weight__c=r.Weight__c;
                ls.Workload__c=r.WorkLoad__c;
                ls.assigned__c=r.Assigned__c;
                //Add statistics from Originator
                /* 
ls.Contacted_Leads_for_Last__c=r.Originator__r.Contacted_Leads_for_Last__c;
ls.Calls_Duration_for_Last__c=r.Originator__r.Calls_Duration_for_Last__c;
ls.Calls_Number_for_Last__c=r.Originator__r.Calls_Number_for_Last__c;
ls.Invalid_Rate__c=r.Originator__r.Invalid_Rate__c;
ls.New_Leads_for_Last__c=r.Originator__r.New_Leads_for_Last__c;
ls.Lost_Rate__c=r.Originator__r.Lost_Rate__c;
ls.Closed_Rate__c=r.Originator__r.Closed_Rate__c;
ls.Calls_for_last_24h__c=r.Originator__r.Calls_for_last_24h__c;
ls.Time_on_Phone_for_Last_24h__c=r.Originator__r.Time_on_Phone_for_Last_24h__c;
ls.Initial_Contact__c=r.Originator__r.Initial_Contact__c;
ls.Initial_Contact_per__c=r.Originator__r.Initial_Contact_per__c;
ls.Overcome_Objections__c=r.Originator__r.Overcome_Objections__c;
ls.Overcome_Objections_per__c=r.Originator__r.Overcome_Objections_per__c;
ls.Promised_to_Buy__c=r.Originator__r.Promised_to_Buy__c;
ls.Promised_to_Buy_Per__c=r.Originator__r.Promised_to_Buy_Per__c;
ls.Ready_to_Close__c=r.Originator__r.Ready_to_Close__c;
ls.Ready_to_Close_per__c=r.Originator__r.Ready_to_Close_per__c;
ls.Closed__c=r.Originator__r.Closed__c;
ls.Closed_Per__c=r.Originator__r.Closed_Per__c;
ls.Lost__c=r.Originator__r.Lost__c;
ls.Lost_Per__c=r.Originator__r.Lost_Per__c;
ls.Save_for_Later__c=r.Originator__r.Save_for_Later__c;
ls.Save_for_Later_Per__c=r.Originator__r.Save_for_Later_Per__c;
ls.Invalid_Lead__c=r.Originator__r.Invalid_Lead__c;
ls.Invalid_Lead_Per__c=r.Originator__r.Invalid_Lead_Per__c;
ls.Closing_Rate_for_Last_30_Days__c=r.Originator__r.Closing_Rate_for_Last_30_Days__c;
ls.Closing_Rate_for_Last_60_Days__c=r.Originator__r.Closing_Rate_for_Last_60_Days__c;
ls.Closing_Rate_for_Last_90_Days__c=r.Originator__r.Closing_Rate_for_Last_90_Days__c;
ls.Closing_Rate_for_Last_120_Days__c=r.Originator__r.Closing_Rate_for_Last_120_Days__c;
ls.Closing_Rate_for_Last_180_Days__c=r.Originator__r.Closing_Rate_for_Last_180_Days__c;
ls.Total_of_Notes_for_Last_7_Days__c=r.Originator__r.Total_of_Notes_for_Last_7_Days__c;
ls.Total_of_Notes_for_Last_30_Days__c=r.Originator__r.Total_of_Notes_for_Last_30_Days__c;
ls.Total_of_E_Mails_Sent_for_Last_7_Days__c=r.Originator__r.Total_of_E_Mails_Sent_for_Last_7_Days__c;
ls.Total_of_E_Mails_Sent_for_Last_30_Days__c=r.Originator__r.Total_of_E_Mails_Sent_for_Last_30_Days__c;
ls.Total_of_SMS_Sent_for_Last_7_Days__c=r.Originator__r.Total_of_SMS_Sent_for_Last_7_Days__c;
ls.Total_of_SMS_Sent_for_Last_30_Days__c=r.Originator__r.Total_of_SMS_Sent_for_Last_30_Days__c;                 
ls.Average_of_Notes_Client_for_Last_7_Days__c=r.Originator__r.Average_of_Notes_per_Client_for_Last_7__c;
ls.Average_of_Notes_Client_for_Last_30_Days__c=r.Originator__r.Average_of_Notes_Client_for_Last_30_Days__c;
ls.Avg_of_E_Mails_Client_for_Last_7_Days__c=r.Originator__r.Avg_of_E_Mails_Client_for_Last_7_Days__c;
ls.Avg_of_E_Mails_Client_for_Last_30_Days__c=r.Originator__r.Avg_of_E_Mails_Client_for_Last_30_Days__c;
ls.Avg_of_SMS_Sent_Client_for_Last_7_Days__c=r.Originator__r.Avg_of_SMS_Sent_Client_for_Last_7_Days__c;
ls.Avg_of_SMS_Sent_Client_for_Last_30_Days__c=r.Originator__r.Avg_of_SMS_Sent_Client_for_Last_30_Days__c;
*/
                lead_shares_list.add(ls);               
            }           
        }       
        return lead_shares_list;
    }
   
    public Integer getSum(List<Round_Robin_Client__c> rrlist){
        Integer value=0;
        for(Round_Robin_Client__c r:rrlist){
            if(r.Total_Hits__c!=null)
                value+=Integer.valueOf(r.Total_Hits__c);
        }
        return value;
    }
}

No comments:

Post a Comment