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
MaheemSamMaheemSam 

Bulify the code

Hi,
   
   Below trigger is working fine on a single transaction can we change this code to handle bulk load logic. Please suggest me
  
Trigger convertToUSD on Opportunity (before update){
     
  Try 
   {
       List<String> oppiso = new List<String>();  
       List<date> cdate = new List<date>();
      
      for(Opportunity o : trigger.new) 
        {
         oppiso.add(o.CurrencyIsoCode);
         cdate.add(o.closedate);
        }
    
        Double cts = [SELECT ConversionRate FROM DatedConversionRate 
                 where isocode IN :oppiso and 
                       startdate <= :cdate 
                 order by startdate desc limit 1].conversionRate;
                 
                  
       for(Opportunity ops : trigger.new) 
       {
        ops.CURRENCY_RATE__c = cts;
       }
    }
 
    catch (Exception e)
    {
        system.debug(e);
        for(Opportunity ops : trigger.new) 
        {
        ops.CURRENCY_RATE__c = null;
        }
    }  
}
Thanks
Sam
 
Best Answer chosen by MaheemSam
Amit Chaudhary 8Amit Chaudhary 8
Some best pratice for you
1) Try to use set to avoid duplicate values
2) Always try to fatch only related record in SOQL with "Where".
3) Use Map to avoid multipe SOQL
4) Alway use containsKey method before getting any value from MAP

Update your code like below
Trigger convertToUSD on Opportunity (before update){
		
		// dnt use List. Use Set to avoid duplicate record
		Set<String> setOppIos = new Set<String>();  
		for(Opportunity o : trigger.new) {
			if(o.CurrencyIsoCode != null){
				setOppIos.add(o.CurrencyIsoCode);
			}	
        }

		if(setOppIos.size() > 0 ){
			// Dnt Query all record , try to add where in query
			List<DatedConversionRate>  listDateConvRate = [ SELECT isocode ,startdate  ,ConversionRate  
															FROM DatedConversionRate 
															WHERE isocode IN :setOppIos ]; 
		
			// use Map with List of DatedConversionRate as you are using date as well
			Map<String, List<DatedConversionRate> > MapRates = new Map< String, List<DatedConversionRate> >();
			For(DatedConversionRate d:listDateConvRate ) {
				if( MapRates.containsKey(d.isocode) ) {
					List<DatedConversionRate> lstDateConv = MapRates.get(d.isocode);
					lstDateConv.add(d);
				}
				else {
					List<DatedConversionRate> lstDateConv = new List<DatedConversionRate>();
					lstDateConv.add(d);
					MapRates.put(d.isocode,lstDateConv);
				}
			}
					
			for(Opportunity o : trigger.new) {
				if(o.CurrencyIsoCode!= null && MapRates.containsKey(o.CurrencyIsoCode) ) {
					List<DatedConversionRate> listDc = MapRates.get(o.CurrencyIsoCode); 
					for( DatedConversionRate dcr : listDc){
						if(dcr.startdate < = o.closedate ){
							o.CURRENCY_RATE__c = dcr.ConversionRate;
						}
					}
				}
			}     			
		}
}

Let us know if this will help you
 

All Answers

Raj VakatiRaj Vakati
Try this appraoch ...  This is the Sample code and may not work as expected ..

 
Trigger convertToUSD on Opportunity (before update){
 
Try 
{
   List<String> oppiso = new List<String>();  
   List<date> cdate = new List<date>();
  
  for(Opportunity o : trigger.new) 
	{
	 oppiso.add(o.CurrencyIsoCode);
	 cdate.add(o.closedate);
	}

   List<DatedConversionRate> dcs =  [SELECT isocode ,startdate  ,ConversionRate FROM DatedConversionRate ];
	  Map<String,DatedConversionRate> rates = new Map< String,DatedConversionRate>();
	  for(DatedConversionRate d:dcs){
		rates.put(d.isocode  , DatedConversionRate);
	  }
	  for(Opportunity o : trigger.new) 
	{
		if(o.CurrencyIsoCode!=NULL){
			DatedConversionRate dc = rates.get('o.CurrencyIsoCode'); 
			o.CURRENCY_RATE__c = dc.ConversionRate;

		}
	  
	}         
	
}


}

 
Amit Chaudhary 8Amit Chaudhary 8
Some best pratice for you
1) Try to use set to avoid duplicate values
2) Always try to fatch only related record in SOQL with "Where".
3) Use Map to avoid multipe SOQL
4) Alway use containsKey method before getting any value from MAP

Update your code like below
Trigger convertToUSD on Opportunity (before update){
		
		// dnt use List. Use Set to avoid duplicate record
		Set<String> setOppIos = new Set<String>();  
		for(Opportunity o : trigger.new) {
			if(o.CurrencyIsoCode != null){
				setOppIos.add(o.CurrencyIsoCode);
			}	
        }

		if(setOppIos.size() > 0 ){
			// Dnt Query all record , try to add where in query
			List<DatedConversionRate>  listDateConvRate = [ SELECT isocode ,startdate  ,ConversionRate  
															FROM DatedConversionRate 
															WHERE isocode IN :setOppIos ]; 
		
			// use Map with List of DatedConversionRate as you are using date as well
			Map<String, List<DatedConversionRate> > MapRates = new Map< String, List<DatedConversionRate> >();
			For(DatedConversionRate d:listDateConvRate ) {
				if( MapRates.containsKey(d.isocode) ) {
					List<DatedConversionRate> lstDateConv = MapRates.get(d.isocode);
					lstDateConv.add(d);
				}
				else {
					List<DatedConversionRate> lstDateConv = new List<DatedConversionRate>();
					lstDateConv.add(d);
					MapRates.put(d.isocode,lstDateConv);
				}
			}
					
			for(Opportunity o : trigger.new) {
				if(o.CurrencyIsoCode!= null && MapRates.containsKey(o.CurrencyIsoCode) ) {
					List<DatedConversionRate> listDc = MapRates.get(o.CurrencyIsoCode); 
					for( DatedConversionRate dcr : listDc){
						if(dcr.startdate < = o.closedate ){
							o.CURRENCY_RATE__c = dcr.ConversionRate;
						}
					}
				}
			}     			
		}
}

Let us know if this will help you
 
This was selected as the best answer