function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
salesforce_hoonigansalesforce_hoonigan 

Open and Closed Activity Counter Class and Trigger Help

Hi,

I am currently building an Task Counter and I was able to achieve this by counting the Activity History and Open Activity using the current code. My new requirement is to count the number of Activities whether an Activity is a Call or an Email, I will base the criteria by Task Type (ex. Emai, Call - Connected, Call - Not Connected). So basically, I will have a total of 4 fields. 
1. Completed Activities - Call, 
2. Open Activities - Call, 
3. Completed Activities - Email, 
4. Open Activities - Email

I hope you could assist me on modifying my code please.

APEX CLASS
public class ActivityUtils {
     
    //config
     
    String fieldToUpdate = 'Completed_Activities__c'; //this field must be added to each object we're updating
    String fieldOpenToUpdate = 'Open_Activities__c'; //this field must be added to each object we're updating
     
    //state
    set<id> leadIds;
    set<id> provIds;
     
    public ActivityUtils(sObject[] records) {
        leadIds = new set<id>();
        provIds = new set<id>();
        captureWhatAndWhoIds(records);
    }
     
    public void updateLeadActivityCount() {
        if(leadIds.size() == 0) return;
        updateActivityCount('Lead','WhoId', getStringFromIdSet(leadIds));
                updateActivityHistory('Lead','WhoId', getStringFromIdSet(leadIds));
 
    }
    public void updateProvisioningActivityCount() {
        if(provIds.size() == 0) return;
        updateActivityCount('Provisioning__c','WhatId', getStringFromIdSet(provIds));
                updateActivityHistory('Provisioning__c','WhatId', getStringFromIdSet(provIds));
 
    }

    private void updateActivityCount(String objToUpdate, String queryFld, String updateIds) {
        string strQuery = 'SELECT Id, (SELECT Id FROM OpenActivities) FROM ' + objToUpdate + ' WHERE Id IN (' + updateIds + ')';
        sObject[] sobjects = new list<sobject>();
        for(sObject so : database.query(strQuery)) {
            OpenActivity[] oActivities = so.getSObjects('OpenActivities');
            Integer openActivityCount = oActivities == null ? 0 : oActivities.size();
            sObject obj = createObject(objToUpdate, so.Id);
            obj.put(fieldOpenToUpdate, openActivityCount);
            sobjects.add(obj);
            system.debug('openActivityCount: ' + openActivityCount);
        }
        update sobjects;
    }
      
    private void updateActivityHistory(String objToUpdate, String queryFld, String updateIds) {
        string strQuery = 'SELECT Id, (SELECT Id FROM ActivityHistories) FROM ' + objToUpdate + ' WHERE Id IN (' + updateIds + ')';       
System.debug(strQuery);
        sObject[] sobjects = new list<sobject>();
        for(sObject so : database.query(strQuery)) {
            ActivityHistory[] oActivities = so.getSObjects('ActivityHistories');
            Integer closedActivityCount = oActivities == null ? 0 : oActivities.size();
            sObject obj = createObject(objToUpdate, so.Id);
            obj.put(fieldToUpdate, closedActivityCount);
            sobjects.add(obj);
            system.debug('ActivityHistoryCount: ' + closedActivityCount);
        }
        update sobjects;
    }
     
    private void captureWhatAndWhoIds(sObject[] objects) {
        for(sObject o : objects) {
            Id whatId = (Id)o.get('WhatId');
            Id whoId = (Id)o.get('WhoId');
            if(whatId != null) {
                String objectName = getObjectNameFromId(whatId);
                if(objectName == 'provisioning') provIds.add(whatId);
            }
            if(whoId != null) {
                String objectName = getObjectNameFromId(whoId);
                if(objectName == 'lead') leadIds.add(whoId);
            }
        }
    }
     
    private String getObjectNameFromId(Id objId) {
        String preFix = String.valueOf(objId).left(3).toLowercase();
        if(prefix == '00q') return 'lead';
        if(prefix == 'a02') return 'provisioning';
        return '';
    }
     
    private String getStringFromIdSet(set<id> idSet) {
        string idString = '';
        for(Id i : idSet) idString+= '\'' + i + '\',';
        return idString == '' ? idString : idString.left(idString.length()-1); //If idString contains some ids we want to ensure we strip out the last comma
    }
     
    //The main part of the method below was taken from //Taken from http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_dynamic_dml.htm
    //However we've modified this to accept an object id
    private sObject createObject(String typeName, Id objId) {
        Schema.SObjectType targetType = Schema.getGlobalDescribe().get(typeName);
        if (targetType == null) {
            // throw an exception
        }
         
        // Instantiate an sObject with the type passed in as an argument
        //  at run time.
        return targetType.newSObject(objId);
    }
     
}

TRIGGER
 
trigger ActivityCounterTrigger on Task (after insert, after update, after delete, after undelete) {
     
    sObject[] triggerRecords;
    if(!trigger.isDelete) triggerRecords = trigger.new;
    else triggerRecords = trigger.old;
     
    //Update Open Activity Count
    ActivityUtils au = new ActivityUtils(triggerRecords);
    au.updateLeadActivityCount();
    au.updateProvisioningActivityCount();
}

Thanks in advance.