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
GMASJGMASJ 

Update value using map

Hi, 

 I am trying to update the billing country in account below is the trigger updating in AFTER update event. 

 But I am getting below error 
Error: Invalid Data. 
Review all error messages below to correct your data.
Apex trigger AccountTrigger caused an unexpected exception, contact your administrator: AccountTrigger: execution of AfterUpdate caused by: System.NullPointerException: Attempt to de-reference a null object: ()

 
  Trigger. 
  
trigger AccountTrigger on Account (Before Insert, Before Update,
                                   After Insert, After Update ) {

   if(Trigger.isAfter){  
      OpportunityAccountUtils.ProcessAcctCountryCode(Trigger.newMap, Trigger.oldMap);   
    }
                                               
}

Helpe Class
public class OpportunityAccountUtils {

  public static void ProcessAcctCountryCode(Map<id, Account> newMap, Map<id, Account> oldMap) {
    List<Account> ActLst = new List<Account>();
    Map<String, Country_Code__c> MapCountryCode = new Map<String, Country_Code__c>([SELECT Country_Code__c, Country_Name__c FROM Country_Code__c]);  
    
    for(Account Act : newMap.values()){
      Act.billingcountry = MapCountryCode.get(Act.billingcountry).Country_Code__c;
      ActLst.add(Act);
     }
    
     if(!ActLst.isEmpty()){
       Update ActLst;
     }  
    
    } 
  }

Please suggest me what is the issue with the code. 

Thanks
Sudhir
Best Answer chosen by GMASJ
GMASJGMASJ
Thank You all for all your help I was able to resolve this on my own  Below code is working I will beed to make few modification. 
 
trigger AccountTrigger on Account (Before Insert, Before Update,After Insert, After Update) {

 //if(Trigger.isAfter && Trigger.isUpdate){           
       //OpportunityAccountUtils.ProcessAcctCountryCode(Trigger.newMap , Trigger.oldMap); 
   // }  
   
  Map<string, string> MapCountry = new Map<string, string>();  
   
  for(Country_Code__c CC :  [SELECT  Country_Name__c,Country_Code__c FROM Country_Code__c ]){
     MapCountry.put(cc.Country_Name__c,cc.Country_Code__c);
  
   }
   
  if(Trigger.isbefore){  
    for(Account Act : Trigger.new){
      Act.Billingcountry = MapCountry.get(Act.Billingcountry);
     } 
  }
   
   
                                             
}

Thanks
Sudhir

All Answers

RKSalesforceRKSalesforce
Hi SUdhir,

I think you need to make changes in your helper class.
public class OpportunityAccountUtils {

    public static void ProcessAcctCountryCode(Map<id, Account> newMap, Map<id, Account> oldMap) {
        List<Account> ActLst = new List<Account>();
        Map<String, Country_Code__c> MapCountryCode = new Map<String, Country_Code__c>();
        for(Country_Code__c countryCode : [SELECT Id, Country_Name__c FROM Country_Code__c]){
            MapCountryCode.put(countryCode.Country_Name__c, Country_Code__c);
        }  
    
    for(Account Act : newMap.values()){
        Act.billingcountry = MapCountryCode.get(Act.billingcountry);
        ActLst.add(Act);
    }
    
    if(!ActLst.isEmpty()){
        Update ActLst;
    }  
    
    } 
}
Please let me know if helped.

Regards,
Ramakant
GMASJGMASJ
Thanks Ramakant for you help, I was getting below error with your code of MAP 

Error: Compile Error: Method does not exist or incorrect signature: void put(String, String) from the type Map<String,Country_Code__c> at line 7 column 28

Later I changed it to as below 
public class OpportunityAccountUtils {

    public static void ProcessAcctCountryCode(Map<id, Account> newMap, Map<id, Account> oldMap) {
      List<Account> ActLst = new List<Account>();
      Map<String, string> MapCountryCode = new Map<String, string>();
      for(Country_Code__c countryCode : [SELECT Id, Country_Name__c,Country_Code__c FROM Country_Code__c]){
            MapCountryCode.put(countryCode.Country_Name__c, countryCode.Country_Code__c);
      }  
    
    for(Account Act : newMap.values()){
        Act.billingcountry = MapCountryCode.get(Act.billingcountry);
        ActLst.add(Act);
    }
    
    if(!ActLst.isEmpty()){
        Update ActLst;
    }  
    
    } 
}

There was no error in code but I am getting error while updating the account. 

Error: Invalid Data. 
Review all error messages below to correct your data.
Apex trigger AccountTrigger caused an unexpected exception, contact your administrator: AccountTrigger: execution of AfterUpdate caused by: System.FinalException: Record is read-only: ()

I will be updating the billingcountry though which the code code should be updated in the same field Please let me know how to fix this issue. 

Thanks
Sudhir
 
RKSalesforceRKSalesforce
Hi Sudhir,

Please change your trigger as below:
trigger AccountTrigger on Account (Before Insert, Before Update ) {

   if(Trigger.isAfter){  
      OpportunityAccountUtils.ProcessAcctCountryCode(Trigger.newMap, Trigger.oldMap);   
    }
                                               
}

Hope this will work.

Please mark as best answer if helped.

Regards,
Ramakant​
GMASJGMASJ
Hi Ramakant, 

    Why are we removing After Insert, After update even from trigger. 

If I removed event and run it not updating no changes. 

If I included after insert, after update event I am still getting the same error. 

Error: Invalid Data. 
Review all error messages below to correct your data.
Apex trigger AccountTrigger caused an unexpected exception, contact your administrator: AccountTrigger: execution of AfterUpdate caused by: System.FinalException: Record is read-only: ()

Thanks
Sudhir



 
Sharad SoniSharad Soni
Hi sudhir,

Right now i wrote a code with static values but you can replace it with your custom setting . Whole code is working in after event , here is the code

public class AccountTriggerHelper {

    public static void updateAcc(Map<Id ,Account> newAccMap) {
        
        if(newAccMap.size() > 0) {
            
            List<Account> acc = new List<Account>();
            for(Account ac : [Select Id , BillingCountry FROM Account WHERE Id IN: newAccMap.keySet()] ) {
                if(ac.billingCOuntry == 'India') {
                    ac.billingCountry = 'USA';
                    acc.add(ac);
                }
            }
            if(Acc.size() > 0)
                update acc;
            
            
        }
    }
}
GMASJGMASJ
Hi Sharad, 

   Thanks for you reply your code doesn't seems to be working I am setill having a readonly issue when trigger is fired. 

  When I run the below anonimious block it is workign fine when i convert it toa  trigger it is not working 
Map<String, String> MapCountryCode = new Map<String, String>();
List<Account> ActLst = new List<Account>();

for(Country_Code__c countryCode : [SELECT Id, Country_Name__c,Country_Code__c FROM Country_Code__c]){
  MapCountryCode.put(countryCode.Country_Name__c,countryCode.Country_Code__c);
}


for(Account Act : [select billingcountry from account where id = '0018000001D8iGD']){
   MapCountryCode.get(Act.BillingCountry);
   system.debug(Act.Billingcountry); 
   system.debug(MapCountryCode.get(Act.BillingCountry)); 
   Act.Billingcountry =  MapCountryCode.get(Act.BillingCountry);
    ActLst.add(Act); 
}

   Update ActLst;

Thanks
Sudhir
Sharad SoniSharad Soni
Please send your whole trigger along with it provide me some brief idea of your custom setting.
 
GMASJGMASJ
Hi Sharad, 

    I did not use custom setting have created a custom object and using it for country code 

Trigger
trigger AccountTrigger on Account (Before Insert, Before Update,After Insert, After Update) {

  /*  if(Trigger.isAfter){
      if(Trigger.isUpdate){
        OpportunityAccountUtils.ProcessAcctCountryCode(Trigger.newMap, Trigger.oldMap); 
        }
     } */
     
   set<id> actid = new set<id>();
   for(Account Act: Trigger.new){
       actid.add(act.id);
    }    
    
    if(Trigger.isAfter){           
       OpportunityAccountUtils.FutProcessAcctCountryCode(Actid); 
    }                                             
}
Helper Class
public class OpportunityAccountUtils {

    @future(callout=true)
    public static void FutProcessAcctCountryCode(Set<id> setId){
      Map<String, String> MapCountryCode = new Map<String, String>();
      List<Account> lstAccount = [select id, billingcountry from account where id in :setId]; 
       
       for(Country_Code__c countryCode : [SELECT Id, Country_Name__c,Country_Code__c FROM Country_Code__c]){
        MapCountryCode.put(countryCode.Country_Name__c,countryCode.Country_Code__c);
       }
       
       for( Account acc : lstAccount ){
         //Acc.Billingcountry =  MapCountryCode.get(Acc.BillingCountry);
         Acc.Billingcountry = 'India';
        }
  
       update lstAccount;
       
    }
    
    public static void ProcessAcctCountryCode(Map<id, Account> newMap, Map<id, Account> oldMap) {
      
      Map<String, String> MapCountryCode = new Map<String, String>();
      List<Account> ActLst = new List<Account>();

      for(Country_Code__c countryCode : [SELECT Id, Country_Name__c,Country_Code__c FROM Country_Code__c]){
        MapCountryCode.put(countryCode.Country_Name__c,countryCode.Country_Code__c);
       }

      for(Account Act : newMap.values()){
         MapCountryCode.get(Act.BillingCountry);
         system.debug(Act.Billingcountry); 
         system.debug(MapCountryCode.get(Act.BillingCountry)); 
         Act.Billingcountry =  MapCountryCode.get(Act.BillingCountry);
         ActLst.add(Act); 
        }

    Update ActLst;
     }   
     
     
  }

Tired using @Furture method its not working please suggest a best approach to achive 

Thanks
Sudhir
 
Sharad SoniSharad Soni
I did not take the look of your future method because it is not making sense. the Read only error that  u are getting is because you are making the changes in "newMap" values which is only a read-only map , also u have to check indiviual condition for both insert and update event because  using only "Trigger.isAfter" will take your trigger to run recursively .

Below mentioned code is working fine in my org paste it as it is but make the changes in your country code accordingly. I think from now you will not suffer any problem.

Trigger:--

trigger Trigger_Account on Account (Before Insert, Before Update,After Insert, After Update) {

  //  AccountTriggerHelper.updateAcc(Trigger.newMap);
 /* set<id> actid = new set<id>();
   for(Account Act: Trigger.new){
       actid.add(act.id);
    }    */
    
    if(Trigger.isAfter && Trigger.isInsert){           
       AccountTriggerHelper.ProcessAcctCountryCode(Trigger.newMap , Trigger.oldMap); 
    }   
}



Helper class :--

    public static void ProcessAcctCountryCode(Map<id, Account> newMap, Map<id, Account> oldMap) {
      
      Map<String, String> MapCountryCode = new Map<String, String>();
      List<Account> ActLst = new List<Account>();
         MapCountryCode.put('India','91');

      for(Account Act : [Select Id , BillingCountry FROM Account WHERE Id IN: newMap.keySet()]){
         MapCountryCode.get(Act.BillingCountry);
         
         Act.Billingcountry =  MapCountryCode.get(Act.BillingCountry);
         ActLst.add(Act); 
        }

    Update ActLst;
     } 

Mark it best answer if it helps you.

Thanks 
Sharad
 
GMASJGMASJ
Hi Sharad, 

   Thanks for you reply there is no error in your code but it is still not updating the billingcountry since I am looking the same field to populate the code might be because of that it is not updating can you please suggest.

Trigger
trigger AccountTrigger on Account (Before Insert, Before Update,After Insert, After Update) {

 if(Trigger.isAfter && Trigger.isInsert){           
       OpportunityAccountUtils.ProcessAcctCountryCode(Trigger.newMap , Trigger.oldMap); 
    }                                            
}

 Helper Class
public class OpportunityAccountUtils {

  public static void ProcessAcctCountryCode(Map<id, Account> newMap, Map<id, Account> oldMap) {
      
      Map<String, String> MapCountryCode = new Map<String, String>();
      List<Account> ActLst = new List<Account>();

      for(Country_Code__c countryCode : [SELECT Id, Country_Name__c,Country_Code__c FROM Country_Code__c]){
        MapCountryCode.put(countryCode.Country_Name__c,countryCode.Country_Code__c);
       } 

     /* Map<String, String> MapCountryCode = new Map<String, String>();
      List<Account> ActLst = new List<Account>();
         MapCountryCode.put('India','91');*/

      for(Account Act : [Select Id , BillingCountry FROM Account WHERE Id IN: newMap.keySet()]){
         MapCountryCode.get(Act.BillingCountry);
         
         Act.Billingcountry =  MapCountryCode.get(Act.BillingCountry);
         ActLst.add(Act); 
        }

    Update ActLst;
     }   
     
     
  }

Thanks
Sudhir​
GMASJGMASJ
Thank You all for all your help I was able to resolve this on my own  Below code is working I will beed to make few modification. 
 
trigger AccountTrigger on Account (Before Insert, Before Update,After Insert, After Update) {

 //if(Trigger.isAfter && Trigger.isUpdate){           
       //OpportunityAccountUtils.ProcessAcctCountryCode(Trigger.newMap , Trigger.oldMap); 
   // }  
   
  Map<string, string> MapCountry = new Map<string, string>();  
   
  for(Country_Code__c CC :  [SELECT  Country_Name__c,Country_Code__c FROM Country_Code__c ]){
     MapCountry.put(cc.Country_Name__c,cc.Country_Code__c);
  
   }
   
  if(Trigger.isbefore){  
    for(Account Act : Trigger.new){
      Act.Billingcountry = MapCountry.get(Act.Billingcountry);
     } 
  }
   
   
                                             
}

Thanks
Sudhir
This was selected as the best answer