1

I know that this error is fed up, but i'm really doesn't know what i'm doing wrong?

So the process: The batch starts every day and checks the value of FirstDateOfMonth__c = Today() and update the field FrstDayOfMnth__c = True. After the record gets value True in the FrstDayOfMnth__c the trigger fires.

The bacth process:

global class ITAssetProcessingBatch implements Database.Batchable<sobject>{
global String [] email = new String[] {'VBakanov@bcsprime.com'};
  public String query = 'Select id from IT_Asset__c';

//Start Method
global Database.Querylocator start (Database.BatchableContext BC) {
return Database.getQueryLocator('SELECT id, Name, FirstDateOfMonth__c,   FrstDayOfMnth__c, Status__c FROM IT_Asset__c WHERE FirstDateOfMonth__c = Today AND Status__c = \'Activated\'');//Query which will be determine the scope of Records fetching the same
}

//Execute method
global void execute (Database.BatchableContext BC, List<sobject> scope) {
List<IT_Asset__c> ITAList = new List<IT_Asset__c>();
List<IT_Asset__c> updtaedITAList = new List<IT_Asset__c>();
for (sObject objScope: scope) { 
    IT_Asset__c newObjScope = (IT_Asset__c)objScope ;
    newObjScope.FrstDayOfMnth__c = true;
    updtaedITAList.add(newObjScope);
    System.debug('Value of UpdatedITAList'+updtaedITAList);
} 
    if (updtaedITAList != null && updtaedITAList.size()>0) {
        Database.update(updtaedITAList); System.debug('List Size '+updtaedITAList.size());
    }
}

//Finish Method
global void finish(Database.BatchableContext BC){

}
}

Trigger before update:

Trigger ITAssetCashFlowCreate on IT_Asset__c (before update)
{
 List<Cash_Flow__c> sub=new List<Cash_Flow__c>();
 for(IT_Asset__c it : Trigger.new)
 {
       if(it.FrstDayOfMnth__c == true)
       {
               Cash_Flow__c cf=new Cash_Flow__c();
               cf.CurrencyIsoCode=it.CurrencyIsoCode;
               cf.Date__c=System.today();
               cf.IT_Asset__c=it.Id;
               cf.RecordTypeId='012b0000000UOay';
               cf.Account__c=it.Account__c;
               cf.Amount__c=-1*it.Total_Asset_Cost_mth__c;
               cf.Cost_Category__c='IT Cost';
               cf.Business_Line_picklist__c=it.Business_Line__c;
               cf.Cost_Center__c=it.Cost_Center_new__c;
               cf.Cost_Line__c=it.Cost_Line_new__c;
               cf.IT_Code__c=it.IT_Code_lookup__c;
               cf.Vendor__c=it.Vendor__c;
               cf.BCS_Entity__c=it.BCS_Entity__c;
               cf.Comment__c='Monthly cost autogenerated';                   

               sub.add(cf);
        }
        if(sub.size()>0)
        upsert sub;
     if(it.FrstDayOfMnth__c == true){
            it.FrstDayOfMnth__c=false;
     }
 }
}

Trigger before insert (that cause the error) :

trigger CashFlowIntegration on Cash_Flow__c (before insert) {

CurrencyType RUB = [SELECT ConversionRate, ISOCode FROM CurrencyType WHERE ISOCode = 'RUB' Limit 1];
CurrencyType USD = [SELECT ConversionRate, ISOCode FROM CurrencyType WHERE ISOCode = 'USD' Limit 1];
// Error in the line //CurrencyType GBP = [SELECT ConversionRate, ISOCode FROM CurrencyType WHERE ISOCode = 'GBP' Limit 1];
CurrencyType EUR = [SELECT ConversionRate, ISOCode FROM CurrencyType WHERE ISOCode = 'EUR' Limit 1];
CurrencyType CHF = [SELECT ConversionRate, ISOCode FROM CurrencyType WHERE ISOCode = 'CHF' Limit 1];
Account Acc = [SELECT id FROM Account WHERE Name = 'Test Technical' Limit 1];

Set<String> AccNum = new Set<String>();   
Map<Id, Schema.RecordTypeInfo> rt_map = Schema.getGlobalDescribe().get('Cash_Flow__c').getDescribe().getRecordTypeInfosById();

for (Cash_Flow__c CF : trigger.new){    
    if(rt_map.get(CF.recordTypeID).getName().containsIgnoreCase('Revenue')){ 
        AccNum.add(CF.AccNumber__c);     
    }
}

    Map<String, Account_Number__c> AccountNumbers = new Map<String, Account_Number__c>();

        List <Account_Number__c> rec = [ SELECT Account_No__c, Account__c FROM Account_Number__c WHERE Account_No__c IN :AccNum Limit 1];     
        List <Account_Number__c> rec2 = [ SELECT Account_Number_Old__c, Account__c FROM Account_Number__c WHERE Account_Number_Old__c IN :AccNum Limit 1];
        List <Account_Number__c> rec3 = [ SELECT Acronym__c, Account__c FROM Account_NUmber__c WHERE Acronym__c IN :AccNum Limit 1];    

        if (rec != NULL){
        for (Account_Number__c record : rec){ 
            AccountNumbers.put(record.Account_No__c, record);
            }
        }
        if (rec2 != NULL){
        for (Account_Number__c record2 : rec2){       
          AccountNumbers.put(record2.Account_Number_Old__c, record2);
            }  
        }
        if (rec3 != NULL){
        for (Account_Number__c record3 : rec3) {
            AccountNumbers.put(record3.Acronym__c, record3);
            }
        }

for (Cash_Flow__c CF : trigger.new){
        Account_Number__c siteAccount = AccountNumbers.get(CF.AccNumber__c);
        Id parentId = (siteAccount == null) ? null : siteAccount.Id;
        Id accId = (siteAccount == null) ? null :siteAccount.Account__c;
        CF.Amount__c = CF.Amount__c.abs();
            if(rt_map.get(CF.recordTypeID).getName().containsIgnoreCase('Revenue')){
                CF.Account_Number__c = parentId;
                CF.Account__c = accId;
            }
            else {
                CF.Account_Number__c = NULL;
                CF.Account__c = NULL; 
            }    
            if(CF.CurrencyISOCode == RUB.ISOCode){
                CF.Amount_USD__c = CF.Amount__c * USD.ConversionRate ;
                CF.RUB2USD_Rate__c = USD.ConversionRate;
            } 
            if(CF.CurrencyIsoCode == USD.ISOCode){
                CF.Amount_USD__c = CF.Amount__c;
                CF.RUB2USD_Rate__c = USD.ConversionRate;
            }
            if(CF.CurrencyIsoCode == GBP.ISOCode){
                CF.Amount_USD__c = (CF.Amount__c * USD.ConversionRate)/GBP.ConversionRate;
                CF.RUB2CURR_Cash_Flow_Rate__c = GBP.ConversionRate;
            }   
            if(CF.CurrencyIsoCode == EUR.ISOCode){
                CF.Amount_USD__c = (CF.Amount__c * USD.ConversionRate)/EUR.ConversionRate;
                CF.RUB2CURR_Cash_Flow_Rate__c = EUR.ConversionRate;
            }   
            if(CF.CurrencyIsoCode == CHF.ISOCode){
                CF.Amount_USD__c = (CF.Amount__c * USD.ConversionRate)/CHF.ConversionRate;
                CF.RUB2CURR_Cash_Flow_Rate__c = CHF.ConversionRate;
            }            
        if (accId == NULL){
            CF.Account__c = Acc.Id;
        }
    }
}

I try to move the SOQL outside the for loop, but it doesn't resolve the error. Don't know why the error occurs in this line becouse that lines is outside the for loop?

Can somebody help me?

  • 1
    This code is very inefficient, but I see nothing to suggest that it'd run up against the limits. You'll need to get your debug logs and figure out what's going on. Try salesforce.stackexchange.com/questions/106664, get some debug logs, and you'll know where the culprit is. – sfdcfox Jul 22 '16 at 12:30
  • Have you check to make certain you have a currency type and conversion rate specified for GBP? BTW, I'd combine those queries on currency type into one and have them output as a map. – crmprogdev Jul 22 '16 at 12:32
  • 1
    @sfdcfox I think he was getting the too many SOQL prior to moving the queries outside the for loop, then ran into this issue. It's not clear, but that's what it appears like from looking at his code. – crmprogdev Jul 22 '16 at 12:34
  • One more idea: is that single trigger on the Cash_Flow__c object? Do you have any workflows/process builders there? – kurunve Jul 22 '16 at 12:41
  • 1
    @Viktor I suggest you double check that you've posted the correct code you were using when you received the too many SOQL error. Other option is to reduce your batch size. You may be generating far more Cash_Flow__c records per batch than you think. – crmprogdev Jul 22 '16 at 13:16
3

The problem is that the upsert sub; statement is inside the for(IT_Asset__c it : Trigger.new) wich inserts the latest cashflow and updates all cashflows previously on the list. Since you're inserting one by one, the Cash Flow trigger runs a lot of times and runs all queries again.

Change you code so it looks like this:

for(IT_Asset__c it : Trigger.new)
{
       if(it.FrstDayOfMnth__c == true)
       {
            it.FrstDayOfMnth__c=false;

           Cash_Flow__c cf=new Cash_Flow__c();
           //all other fields                 

           sub.add(cf);
        }
}
if(sub.size()>0) insert sub;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.