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
SF Dev CenoSF Dev Ceno 

From Process Builder To Trigger: Invoke Apex Class From Trigger

All,
I'm attempting to simply invoke my apex class from a trigger instead of the process builder. How do I invoke the following class in my trigger? It doesn't fire, yet my debug log shows the objIds.size() = 1.

Class:
global class WR_UpdateGeo {
   @InvocableMethod
   
   public static void getAccountIds(List<Id> objIds) {
     
      //Get the sObject token from the first ID
      Schema.SObjectType token = objIds[0].getSObjectType();
      Schema.DescribeSObjectResult dr = token.getDescribe();
       
      String Scountry = 'country';   
      if (dr.getName() == 'account')
         Scountry = 'BillingCountry';  
      
      // Construct query dynamically.
      String queryString = 'SELECT id, ' + Scountry + ' FROM ' + dr.getName() + ' WHERE ';
      for(ID objId : objIds) {
            queryString += 'Id=\'' + objId + '\' OR ';
          }  
            
      queryString = queryString.subString(0, queryString.length() - 4);
      sObject[] objDBList = Database.query(queryString);
       
       // GEO
       String geo = '';
        List<Country_GEO_Mapping__c> lst_countryGeoMapping = [SELECT Country_Name__c, GEO_Name__c FROM Country_GEO_Mapping__c ];
        Map<String, String> map_countryGeoMapping = new Map<String, String>();
      
        for(Country_GEO_Mapping__c    cg: lst_CountryGeoMapping){
            map_countryGeoMapping.put(cg.Country_Name__c, cg.GEO_Name__c);
          }
            
       // Update the GEO on the sObjects
       for(Integer i = 0; i < objDBList.size(); i++) {
          
          if (dr.getName() == 'account') {
              if(map_countryGeoMapping.containsKey(String.valueOf(objDBList[i].get('BillingCountry')))) {
                 geo = map_countryGeoMapping.get(String.valueOf(objDBList[i].get('BillingCountry'))); }
                 objDBList[i].put('GEO__c', geo);
               }
              //geo = 'APAC';}
             //objDBList[i].put('GEO__c', Utility_Class.FindGeoFromCountry(String.valueOf(objDBList[i].get('BillingCountry'))));
           
          else {
             if(map_countryGeoMapping.containsKey(String.valueOf(objDBList[i].get('country')))) {
                 geo = map_countryGeoMapping.get(String.valueOf(objDBList[i].get('country')));  }
                 objDBList[i].put('GEO__c', geo);
               }
             //objDBList[i].put('GEO__c', Utility_Class.FindGeoFromCountry(String.valueOf(objDBList[i].get('country')))); 
        }       
        
       Database.SaveResult[] srList = Database.update(objDBList, false);
    }
}

Trigger:
trigger WR_BeforeLead on Lead (before insert, before update) {
    List<Id> objIds = new List<Id>();

    if (Trigger.isBefore && Trigger.isUpdate) {
        for(Lead l : Trigger.New){
			if(l.Id != null) {
				objIds.add(l.Id);
			}
		}

		if(objIds.size() > 0){
			System.debug(objIds.size());
			WR_UpdateGeo.getAccountIds(objIds);
		}
	}
}

Best Answer chosen by SF Dev Ceno
ashishashish
if the value is getting update in Debug Logs but its not commiting the record .then the  problem lies here ( Database.SaveResult[] srList = Database.update(objDBList, false);.
Below Link will definately help you out with this problem!!
https://salesforce.stackexchange.com/questions/54425/problem-with-database-update

All Answers

ashishashish
Hi,
You are facing this proble because Triggers can’t reference invocable methods.
so i would suggest you to make apex Trigger and a Action class and call this class from your Trigger.

Thanks 
Ashish 
Mark this answer best if it helps you!!
SF Dev CenoSF Dev Ceno
Well that's good to know! Can't I just remove the InvocableMethod annotation then?
ashishashish
Hi,
Yes that should also work ,defifning  triggers  in a class will help to know the flows better and manage plus it will help you to add methods later in the same trigger class which we generally call Helper Classes.you can take the help of below Link.
http://blog.mirketa.com/salesforce-developer-guide-use-of-helperhandler-class-to-manage-trigger-execution/

thanks
SF Dev CenoSF Dev Ceno

Hey Ashish,

I commented out the InvocableMethod annotation, confirmed the objIds.size() > 0, yet it's still not updating the Geo field on the Lead. Any ideas why this wouldn't execute the update?

global class WR_UpdateGeo {
   //@InvocableMethod
   
   public static void getAccountIds(List<Id> objIds) {
     
      //Get the sObject token from the first ID
      Schema.SObjectType token = objIds[0].getSObjectType();
      Schema.DescribeSObjectResult dr = token.getDescribe();
       
      String Scountry = 'country';
      if (dr.getName() == 'account')
         Scountry = 'BillingCountry';
      
      // Construct query dynamically.
      String queryString = 'SELECT id, ' + Scountry + ' FROM ' + dr.getName() + ' WHERE ';
      for(ID objId : objIds) {
            queryString += 'Id=\'' + objId + '\' OR ';
          }

      queryString = queryString.subString(0, queryString.length() - 4);
      sObject[] objDBList = Database.query(queryString);
       
       // GEO
       String geo = '';
        List<Country_GEO_Mapping__c> lst_countryGeoMapping = [SELECT Country_Name__c, GEO_Name__c FROM Country_GEO_Mapping__c ];
        Map<String, String> map_countryGeoMapping = new Map<String, String>();
      
        for(Country_GEO_Mapping__c    cg: lst_CountryGeoMapping) {
            map_countryGeoMapping.put(cg.Country_Name__c, cg.GEO_Name__c);
            System.debug(cg.GEO_Name__c);
          }

       // Update the GEO on the sObjects
       for(Integer i = 0; i < objDBList.size(); i++) {
          
          if (dr.getName() == 'account') {
              if(map_countryGeoMapping.containsKey(String.valueOf(objDBList[i].get('BillingCountry')))) {
                 geo = map_countryGeoMapping.get(String.valueOf(objDBList[i].get('BillingCountry')));
               }
                 objDBList[i].put('GEO__c', geo);
               }

              //geo = 'APAC';}
             //objDBList[i].put('GEO__c', Utility_Class.FindGeoFromCountry(String.valueOf(objDBList[i].get('BillingCountry'))));
           
          else {
             if(map_countryGeoMapping.containsKey(String.valueOf(objDBList[i].get('country')))) {
                 geo = map_countryGeoMapping.get(String.valueOf(objDBList[i].get('country')));
                 System.debug(String.valueOf(objDBList[i].get('country')));
               }
                 objDBList[i].put('GEO__c', geo);
                 System.debug(String.valueOf(objDBList[i].get('GEO__c')));
               }
             //objDBList[i].put('GEO__c', Utility_Class.FindGeoFromCountry(String.valueOf(objDBList[i].get('country'))));
        }

       Database.SaveResult[] srList = Database.update(objDBList, false);
    }
}
 
trigger WR_UpdateGeo on Lead (before insert, before Update) {
	List<Id> objIds = new List<Id>();

	if(Utility_Class.isDM()) {
        return;
    }
    	if (Trigger.isUpdate) {
      		//11.15.17 Invoke Geo From Trigger Instead of Process Builder
			for(Lead l : Trigger.New){
				if(l.Country != NULL){
					objIds.add(l.Id);
				}
			}

			if(objIds.size() > 0){
				System.debug('Size of objIds is' + objIds.size());
				WR_UpdateGeo.getAccountIds(objIds);
			}
      }
}
ashishashish
i try to figuere out the problem in the code and i find out some faults in the code. im was not able to understand what r u tryin to do at this point "51   -> objDBList[i].put('GEO__c', geo);" possibly where i think the problem lies
 
SF Dev CenoSF Dev Ceno
This is supposed to grab the value of the Country field from the Lead and, using the Custom Setting, update the Geo__c field based on that value. But that field is not updating. For instance, if the Country field is Australia, the Geo__c field should update to APAC. Debug log below is returning the correct values, but not updating the field. 
10:37:13:944 USER_DEBUG [54]|DEBUG|Australia
10:37:13:944 USER_DEBUG [57]|DEBUG|APAC
ashishashish
if the value is getting update in Debug Logs but its not commiting the record .then the  problem lies here ( Database.SaveResult[] srList = Database.update(objDBList, false);.
Below Link will definately help you out with this problem!!
https://salesforce.stackexchange.com/questions/54425/problem-with-database-update
This was selected as the best answer