Friday, 16 October 2015

Copy items between objects

Introduction

A recent project had the requirement of copying all new values from one custom object to another.

This was an interesting use case so I captured the Trigger for future use here.



Apex Class


/*
    This trigger performs the following:

    When a new record is created in NVMStatsSF__NVM_Call_Summary__c

    1) Check whether the Task Field is populated on the Call Summary
    2) If there is a Task ID on the Call Summary then we will delete the original task (as information has been copied to NVMStatsSF__NVM_Call_Summary__c)
    3) Check whether any new call data has been brought in that isn't already in STCDR__ShoreTel_Connection__c - do this via the GUID
    4) Push new call data to STCDR__ShoreTel_Connection__c (Custom Call Logging Object at Yelp)

    */

trigger NVMUpdateShoreTel on NVMStatsSF__NVM_Call_Summary__c (after insert, after update) {

    Set<String> taskIDs = new Set<String>();
    Set<String> GUIDs = new Set<String>();
    List<STCDR__ShoreTel_Connection__c> newShoreTelConnectionRecords = new List<STCDR__ShoreTel_Connection__c>();

    Boolean isNewTaskInfo = false;
    for (NVMStatsSF__NVM_Call_Summary__c summ : Trigger.new) {
        //Always safe to create the data for newly inserted summaries
        isNewTaskInfo = Trigger.isInsert;
        if (summ.NVMStatsSF__TaskExists__c &&
            summ.NVMStatsSF__TaskID__c != null &&
            summ.NVMStatsSF__TaskID__c!= ''
        ) {
            if(!isNewTaskInfo) {
                if(!(Trigger.oldMap.get(summ.Id)).NVMStatsSF__TaskExists__c) {
                    //we are updating and the Task Id was not there before this
                    isNewTaskInfo = true;
                }
            }
        }
        if (isNewTaskInfo) {
            taskIDs.add(summ.NVMStatsSF__TaskID__c);
            //Safe to assume all fields would be populated?
            STCDR__ShoreTel_Connection__c sstc = new STCDR__ShoreTel_Connection__c();
            sstc.STCDR__Duration_seconds__c = summ.NVMStatsSF__Total_Call_Duration__c;
            sstc.STCDR__Account__c = summ.NVMStatsSF__Related_Account__c;
            sstc.STCDR__CallGUID__c = summ.NVMStatsSF__CallGuid__c;
            //Set Inbound or Outbound (or Case)
            sstc.STCDR__Call_Type__c = summ.NVMStatsSF__Interaction_Type__c.split(' ')[0];
            sstc.STCDR__Connect_Time__c = summ.NVMStatsSF__CallTime__c;
            sstc.STCDR__Contact__c = summ.NVMStatsSF__Related_Contact__c;
            sstc.STCDR__Dialed_number__c = summ.NVMStatsSF__CLID__c;
            sstc.STCDR__Disconnect_Time__c = summ.NVMStatsSF__CallEndTime__c;
            sstc.STCDR__Duration_seconds__c = summ.NVMStatsSF__Total_Call_Duration__c;
            sstc.STCDR__Hold_Time_seconds__c = summ.NVMStatsSF__Consult_Time__c;
            sstc.STCDR__Lead__c = summ.NVMStatsSF__Related_Lead__c;
            sstc.STCDR__Ring_Time_seconds__c = summ.NVMStatsSF__Agent_Ring_Duration__c;
             
            if (summ.NVMStatsSF__Agent_Talk_Time__c != null && summ.NVMStatsSF__Agent2_Transfer_Time__c !=null) {
             sstc.STCDR__Talk_Time_seconds__c = summ.NVMStatsSF__Agent_Talk_Time__c + summ.NVMStatsSF__Agent2_Transfer_Time__c;
          }
          else {
             sstc.STCDR__Talk_Time_seconds__c = 0;
             }
        
            sstc.STCDR__User__c = summ.NVMStatsSF__Agent__c;
            sstc.STCDR__WG_Queue_Duration_Seconds__c = summ.NVMStatsSF__Queue_Duration__c;
            sstc.NVM_Call_Summary__c = summ.id;
            newShoreTelConnectionRecords.add(sstc);
        }
    }


    if (!taskIDs.isEmpty()) { 
 
    List<Database.SaveResult> res = Database.insert(newShoreTelConnectionRecords, false);
    //Loop through results;
 
        for (Database.SaveResult sr : res) {
      if (sr.isSuccess()) {
         // Operation was successful, so get the ID of the record that was processed
         System.debug('Successfully inserted account. Account ID: ' + sr.getId());
      } //end if
      else {
         // Operation failed, so get all errors                
          for(Database.Error err : sr.getErrors()) {
              System.debug('The following error has occurred.');                    
              System.debug(err.getStatusCode() + ': ' + err.getMessage());
              System.debug('Account fields that affected this error: ' + err.getFields());
         } //end else
     } //end for
}  //end if
       
        List<Task> toDelete = new List<Task>();
        for (Id taskId : taskIDs) {
            toDelete.add(new Task(Id = taskId));
        }
        System.debug(toDelete.size() + ' Task records to delete');

        if (!toDelete.isEmpty()) {
            try {
                Database.delete(toDelete);
                Database.emptyRecycleBin(toDelete);
            } catch (Exception e) { 
                System.debug('An error happened, as predicted!');
            }
        }
    }
} //end of Trigger

Test Class
@isTest
private class NVMUpdateShoreTelTest {

    static testMethod void testCallSummariesOnInsert() {
        //Test creating new NVMStatsSF__NVM_Call_Summary__c
        //Test creating new Task
        //Test creating new STCDR__ShoreTel_Connection__c 

        /*
        * If NVMStatsSF__NVM_Call_Summary__c does is not populated do nothing
        * If NVMStatsSF__NVM_Call_Summary__c has a Task ID then go find matching Task
        * If NVMStatsSF__NVM_Call_Summary__c has details
        */

        // Insert 20 Tasks
        List<Task> testTasks = new List<Task>();
        for (Integer j = 0; j < 20; j++) {
            Task v = new Task();
            v.CallObject = '123456' +j;
            testTasks.add(v);
        }//end for
        
       try {
            insert testTasks;
        } catch (Exception e) { 
           System.debug('An error happened inserting testTasks');
           System.assert(false, 'Exception ' + e);
        }

        //Assert that our Tasks inserted ok
        List<Task> taskResults = [select Id from Task];
        System.assertEquals(20, taskResults.size());

        List<NVMStatsSF__NVM_Call_Summary__c> callSummaries = new List<NVMStatsSF__NVM_Call_Summary__c>();

        // Insert 20 NVMStatsSF__NVM_Call_Summary__c with GUID
        for (Integer i = 0; i < 20; i++) {
        NVMStatsSF__NVM_Call_Summary__c u = new NVMStatsSF__NVM_Call_Summary__c();
            u.NVMStatsSF__TaskExists__c = False;
            u.NVMStatsSF__TaskID__c = ' ';
            u.NVMStatsSF__CallGuid__c = '014f7ab2-e221-e0c3-af75-14a632e0f4ab' +i;
            //Get current user ID
            u.NVMStatsSF__Agent__c = UserInfo.getUserId(); 
            u.NVMStatsSF__Queue_Duration__c = 60;
            u.NVMStatsSF__Total_Call_Duration__c = 60;
            //u.NVMStatsSF__Related_Account__c;
            u.NVMStatsSF__Interaction_Type__c= 'Inbound';
       u.NVMStatsSF__CallTime__c = Date.newInstance(2008,11,20);
      //u.NVMStatsSF__Related_Contact__c;
       u.NVMStatsSF__CLID__c = '1234567';
       u.NVMStatsSF__CallEndTime__c = Date.newInstance(2008,11,20);
       u.NVMStatsSF__Total_Call_Duration__c = 120;
       u.NVMStatsSF__Consult_Time__c = 100;
       //u.NVMStatsSF__Related_Lead__c;
       u.NVMStatsSF__Agent_Ring_Duration__c = 10;
       u.NVMStatsSF__Agent_Talk_Time__c = 30;
            u.NVMStatsSF__Agent2_Transfer_Time__c = 30;
       u.NVMStatsSF__Agent__c =  UserInfo.getUserId(); 
            u.NVMStatsSF__Queue_Duration__c = 60;

            callSummaries.add(u);
        }

           // Update the database
        try {
            insert callSummaries;
        } catch (Exception e) { 
            System.debug('An error happened inserting callSummaries');
            

        }


        
        //Test Call Summary Update was successful
        List<NVMStatsSF__NVM_Call_Summary__c> callSummaryResults2 = [select Id from NVMStatsSF__NVM_Call_Summary__c where 
    NVMStatsSF__TaskExists__c = true];
        System.assertEquals(0, callSummaryResults2.size());
        
        //Assert that the ShoreTel object updated ok
        List<STCDR__ShoreTel_Connection__c> shoreTelResults = [select Id from STCDR__ShoreTel_Connection__c];
        System.assertEquals(20, shoreTelResults.size());
    }
    static testMethod void testCallSummariesOnUpdate() {

        //We need to go update a few records to simulate adding the Task
        List<NVMStatsSF__NVM_Call_Summary__c> updateCallSummaryResults = [select Id from NVMStatsSF__NVM_Call_Summary__c];
        System.debug(updateCallSummaryResults.size());

        //Loop through results and update Task ID and Task Exists
        for(NVMStatsSF__NVM_Call_Summary__c a : updateCallSummaryResults){
            a.NVMStatsSF__TaskExists__c = True;
            a.NVMStatsSF__TaskID__c = '123456' + a;
            a.NVMStatsSF__CallGuid__c = '123456' +a;
        }

        // Update the database
        try {
            update updateCallSummaryResults;
        } catch (Exception e) { 
            System.debug('An error happened updating updateCallSummaryResults');
      System.assert(false, 'Exception ' + e);

        }

        //Test Call Summary Update was successful
        List<NVMStatsSF__NVM_Call_Summary__c> callSummaryResults2 = [select Id from NVMStatsSF__NVM_Call_Summary__c where NVMStatsSF__TaskExists__c = true];
        System.assertEquals(0, callSummaryResults2.size());

        //Now that the Call Summaries have Task IDs the Trigger should delete the Tasks - lets test this
        List<Task> taskResults2 = [select Id from Task];
        System.assertEquals(0, taskResults2.size());
    }
}

Icon from Recep Kütük from Iconfinder