+ Start a Discussion
DodiDodi 

Help with updating Accounts via a list

Dear Gurus,

 

I am having some trouble with the following class. I am trying to update individual account records with the Net_Proceeds_USD__c, Net_Proceeds_LC__c, Net_Proceeds_FC__c values. Everything works fine up to the point where I am actually updating the account. Currently this compiles fine, but during runtime it updates all the accounts with the same value. So it does not appear that I am updating from my list correctly. Below is the code, I have also put comments where the problem is occuring. Any advise is appreciated!

 

 

global class RollUpNetProceeds {
          
                 webService static void setNetProceeds(){
                    Integer salesForecastCount;            
                    Integer accountCount;            
                    
                    //get number of accounts
                    accountCount = [Select count() FROM Account];
                     //get Sales and Forecast record count            
                    salesForecastCount = [Select count() FROM Sales_Forecasts__c];
                    System.debug('Account record count is ' + accountCount);
                    System.debug('Sales and Forecast record count is ' + salesForecastCount);
                    ///put all accounts in a list
                    List<Account> accountList = new List<Account>();  
                    accountList = [Select a.Id, a.Name, a.Net_Proceeds_USD__c, a.Net_Proceeds_LC__c, a.Net_Proceeds_FC__c From Account a];
                    Integer accountListSize = accountList.size();
                    Integer salesForecastListSize;
                    System.debug('Account List size is ' + accountListSize);
                    
                    List<Sales_Forecasts__c> aSalesForecastList = new List<Sales_Forecasts__c>();
                
                    ///iterate through list of accounts
                    for (Integer a = 0; a < accountListSize; a++) {
                        //System.debug('Account Id is ' + accountList.get(a).Id);
                        //put individual Sales and Forecast records into a list
                        
                        aSalesForecastList = [Select Net_Proceeds_FC__c , Net_Proceeds_USD__c, Net_Proceeds_LC__c from Sales_Forecasts__c where Account__c = :accountList.get(a).Id];
                        
                        salesForecastListSize = aSalesForecastList.size();
        
                        ///set up variables for totals
                        Decimal accountTotalNetProceedsFC = 0;
                        Decimal accountTotalNetProceedsLC = 0;
                        Decimal accountTotalNetProceedsUSD = 0;
                        String tempAccountTotalNetProceedsLC;
                        
                        ///iterate through list of Sales and Forecast records and sum totals per Account
                        for (Integer b = 0; b < salesForecastListSize; b++) {
                        
                            tempAccountTotalNetProceedsLC = aSalesForecastList.get(b).Net_Proceeds_LC__c;
                            Integer i = tempAccountTotalNetProceedsLC.length();
                            String tempLC = tempAccountTotalNetProceedsLC.substring(4, i);
                            
                            accountTotalNetProceedsFC = accountTotalNetProceedsFC + aSalesForecastList.get(b).Net_Proceeds_FC__c;
                            accountTotalNetProceedsLC = accountTotalNetProceedsLC + decimal.valueOf(tempLC);
                            accountTotalNetProceedsUSD = accountTotalNetProceedsUSD + aSalesForecastList.get(b).Net_Proceeds_USD__c;
    
                            
                        }
                            System.debug(' Total FC Net Proceed Value for Account: '+ accountList.get(a).Name +  ' is ' + accountTotalNetProceedsFC);
                            System.debug(' Total LC Net Proceed Value for Account: '+ accountList.get(a).Name +  ' is ' + accountTotalNetProceedsLC);
                            System.debug(' Total USD Net Proceed Value for Account: '+ accountList.get(a).Name +  ' is ' +  accountTotalNetProceedsUSD);
                           
 ////Problem starts here, incorrect accounts are being updated. Same values will apply to all accounts                           

for(Account account: accountList) {
                                account.Net_Proceeds_USD__c = accountTotalNetProceedsUSD;
                                account.Net_Proceeds_FC__c = accountTotalNetProceedsFC;
                                account.Net_Proceeds_LC__c = accountTotalNetProceedsLC.toPlainString();
                            }
                            update accountList;
                            
            
                    } // close acct loop
                    
                
                 } // webservice
                                                     
}

Best Answer chosen by Admin (Salesforce Developers) 
DodiDodi

Below is the working solution

 

///////////////////////////////////// Properway to code the class to avoid governors////////////////////////

 

global class RollUpNetProceeds2 {

    webService static void setNetProceeds()
    {
        /*
        This Map will store the AccountId and
        all the RELATED Sales Forecast records.
        */
        Map<Id,List<Sales_Forecasts__c>> mapForecastAccount = new Map<Id,List<Sales_Forecasts__c>>();
    
        
        //Get All your accounts and store them
        //in Map<Id,Account>
        Map<Id,Account> mapAccount = new Map<Id,Account>([Select a.Id, a.Name, a.Net_Proceeds_USD__c,a.Net_Proceeds_LC__c,a.Net_Proceeds_FC__c From Account a]);//
        
        /*Collect the data and store it in map.
          This for loop will query the data in the batch of 200
          If you are sure that record count will not cross governors
          then you can query them in one go.
         */
        
        for(List<Sales_Forecasts__c> lstForecast : [Select Net_Proceeds_FC__c , Net_Proceeds_USD__c, Net_Proceeds_LC__c, Account__c from Sales_Forecasts__c])
        {        
            if(lstForecast != null && lstForecast.size() > 0)
            {
                for(Sales_Forecasts__c objForecast : lstForecast)
                {
                    if(!mapForecastAccount.containsKey(objForecast.Account__c))
                    {
                        List<Sales_Forecasts__c> lstSalesForecast = new List<Sales_Forecasts__c>();
                        lstSalesForecast.add(objForecast);
                        mapForecastAccount.put(objForecast.Account__c,lstSalesForecast);
                    }
                    else
                    {
                        List<Sales_Forecasts__c> lstSalesForecast = mapForecastAccount.get(objForecast.Account__c);
                        if(lstSalesForecast != null)
                            lstSalesForecast.add(objForecast);
                    }    
                }
                system.debug('Forecast Account:::' +mapForecastAccount);
            }
        }
                    
        List<Account> lstAccountsToUpdate = new List<Account>();
        
        // Do the counting
        for(Account objAcc : mapAccount.values())
        {
            List<Sales_Forecasts__c> lstForecastVal = mapForecastAccount.get(objAcc.Id);
            if(lstForecastVal != null && lstForecastVal.size() > 0)
            {
                //We have to Re-calculate following values
                //So we are setting up the initials as 0.
                objAcc.Net_Proceeds_USD__c  = 0;
                objAcc.Net_Proceeds_FC__c = 0;
                objAcc.Net_Proceeds_LC__c = 0;
                
                for(Sales_Forecasts__c objForecast : lstForecastVal)
                {
                    if(objForecast.Net_Proceeds_USD__c == null )
                        objForecast.Net_Proceeds_USD__c = 0;
                    
                    if(objForecast.Net_Proceeds_FC__c == null)
                       objForecast.Net_Proceeds_FC__c = 0;
                                        
                    //if(objForecast.Net_Proceeds_LC__c == null)
                    //   objForecast.Net_Proceeds_LC__c = 0;
                                        
                    objAcc.Net_Proceeds_USD__c += objForecast.Net_Proceeds_USD__c;                        
                    objAcc.Net_Proceeds_FC__c += objForecast.Net_Proceeds_FC__c;
                    
                    if(objForecast.Net_Proceeds_LC__c != null && objForecast.Net_Proceeds_LC__c != '')
                    {
                        Integer i = objForecast.Net_Proceeds_LC__c.length();
                        String tempLC = objForecast.Net_Proceeds_LC__c.substring(4, i);
                        objAcc.Net_Proceeds_LC__c += decimal.valueof(tempLC);
                    }
                }
            }
                        
            //After counting add to List.
            System.debug('Adding Account::' +objAcc.Name);
            System.debug('Net_Proceeds_USD__c Count::' +objAcc.Net_Proceeds_USD__c);
            System.debug('Net_Proceeds_FC__c  Count::' +objAcc.Net_Proceeds_FC__c);
            System.debug('Net_Proceeds_LC__c Count::' +objAcc.Net_Proceeds_LC__c);
            lstAccountsToUpdate.add(objAcc);
        }
        
        //Finally update the List.
        if(lstAccountsToUpdate.size() > 0)
            update lstAccountsToUpdate;
            
        //Check governors
        System.debug('Rows Count::' + Limits.getDMLRows());
        System.debug('Rows Count Remaining For Context::' + Limits.getLimitDMLRows());
        System.debug('DML Statements Count::' + Limits.getDMLStatements());    
        System.debug('DML Statements Remaining For Context::' + Limits.getLimitDMLStatements());
        System.debug('Query Count::'+ Limits.getQueries());
        System.debug('Query Remaining For Context::'+ Limits.getLimitQueries());
        System.debug('Script Statements::' + Limits.getScriptStatements());
        System.debug('Script Statements Remaining For Context::' + Limits.getLimitScriptStatements());
    }
}

All Answers

MandyKoolMandyKool

Hi Dodi,

 

Could please explain in detail what exactly you are trying to do in this class?

Also explain what Net_Proceeds_USD__c, Net_Proceeds_LC__c, Net_Proceeds_FC__c fields are?

 

I will help you to write the class :)

DodiDodi

Hi Kulkarni,

 

the  Net_Proceeds_USD__c, Net_Proceeds_LC__c, Net_Proceeds_FC__c fields are maintainted on 2 objects Account(Parent) & Sales and Forecasts(Child). So for example, I can have an account with multiple Sales&Forecast records, I am trying to sum up the values of these fields accross all the child records and sum them up at the account level. The totals are working, I am just having trouble wrting the results back to the account object properly. Please note, I cannot use roll-up summary fields, because we are needing to sum some items that are coming over as text. Longer term, I wil attempt to roll up the information to the parent accounts as well. But right now, I am not updating the individual accounts correctly.

 

MandyKoolMandyKool

Hi Dodi,

 

I got your requirement. I will try to write a code for you as the code return by you does lots of SOQL calls, which is not good as in future u may hit the governors. 

I will try to code your class, which you can refer and improve your coding(It does not mean that i am super coder. we all have room for improvements :) )

 

Also you can add me to your gtalk or skype as its easy to discuss the things there through chat ( my gmail id is mandar19.kulkarni@gmail.com). I think very soon Force.com will have its own chatroom for developers and tht will be awesome!!!

DodiDodi

I wanted to udate this positng with the solution....Thanks for the help Kulkarni, you have been extremley helpful. There are two versions of this class, one that is coded in such a way that will hit governors......the second is the appropriate way to avoid governors(posted in next post).

 

/////////////////////// Improper way to code the class////////////////////

 

global class RollUpNetProceeds {
          
                webService static void setNetProceeds(){
                    Integer salesForecastCount;         
                    Integer accountCount;           
                    
                    //get number of accounts
                    accountCount = [Select count() FROM Account];
                    //get Sales and Forecast record count           
                    salesForecastCount = [Select count() FROM Sales_Forecasts__c];
                    System.debug('Account record count is ' + accountCount);
                    System.debug('Sales and Forecast record count is ' + salesForecastCount);
                    ///put all accounts in a list
                    List<Account> accountList = new List<Account>();  
                    accountList = [Select a.Id, a.Name, a.Net_Proceeds_USD__c, a.Net_Proceeds_LC__c, a.Net_Proceeds_FC__c From Account a];
                    Integer accountListSize = accountList.size();
                    Integer salesForecastListSize;
                    System.debug('Account List size is ' + accountListSize);
                    
                    List<Sales_Forecasts__c> aSalesForecastList = new List<Sales_Forecasts__c>();
                
                    ///iterate through list of accounts
                    for (Integer a = 0; a < accountListSize; a++) {
                        //System.debug('Account Id is ' + accountList.get(a).Id);
                        //put individual Sales and Forecast records into a list
                        
                        aSalesForecastList = [Select Net_Proceeds_FC__c , Net_Proceeds_USD__c, Net_Proceeds_LC__c from Sales_Forecasts__c where Account__c = :accountList.get(a).Id];
                        
                        salesForecastListSize = aSalesForecastList.size();
        
                        ///set up variables for totals
                        Decimal accountTotalNetProceedsFC = 0;
                        Decimal accountTotalNetProceedsLC = 0;
                        Decimal accountTotalNetProceedsUSD = 0;
                        String tempAccountTotalNetProceedsLC;
                        
                        ///iterate through list of Sales and Forecast records and sum totals per Account
                        for (Integer b = 0; b < salesForecastListSize; b++) {
                        
                            tempAccountTotalNetProceedsLC = aSalesForecastList.get(b).Net_Proceeds_LC__c;
                            Integer i = tempAccountTotalNetProceedsLC.length();
                            String tempLC = tempAccountTotalNetProceedsLC.substring(4, i);
                            
                            accountTotalNetProceedsFC = accountTotalNetProceedsFC + aSalesForecastList.get(b).Net_Proceeds_FC__c;
                            accountTotalNetProceedsLC = accountTotalNetProceedsLC + decimal.valueOf(tempLC);
                            accountTotalNetProceedsUSD = accountTotalNetProceedsUSD + aSalesForecastList.get(b).Net_Proceeds_USD__c;
                
                        }
                            System.debug(' Total FC Net Proceed Value for Account: '+ accountList.get(a).Name +  ' is ' + accountTotalNetProceedsFC);
                            System.debug(' Total LC Net Proceed Value for Account: '+ accountList.get(a).Name +  ' is ' + accountTotalNetProceedsLC);
                            System.debug(' Total USD Net Proceed Value for Account: '+ accountList.get(a).Name +  ' is ' +  accountTotalNetProceedsUSD);
                            
                            Account ac = [Select a.Net_Proceeds_USD__c, a.Net_Proceeds_LC__c, a.Net_Proceeds_FC__c From Account a WHERE a.id = :accountList.get(a).Id];
                        
                            ac.Net_Proceeds_USD__c = accountTotalNetProceedsUSD;
                            ac.Net_Proceeds_FC__c = accountTotalNetProceedsFC;
                            ac.Net_Proceeds_LC__c = accountTotalNetProceedsLC;
                            
                            update ac;
                            
                        
                    } // close acct loop
                    
            
                } // webservice

 

 

 

DodiDodi

Below is the working solution

 

///////////////////////////////////// Properway to code the class to avoid governors////////////////////////

 

global class RollUpNetProceeds2 {

    webService static void setNetProceeds()
    {
        /*
        This Map will store the AccountId and
        all the RELATED Sales Forecast records.
        */
        Map<Id,List<Sales_Forecasts__c>> mapForecastAccount = new Map<Id,List<Sales_Forecasts__c>>();
    
        
        //Get All your accounts and store them
        //in Map<Id,Account>
        Map<Id,Account> mapAccount = new Map<Id,Account>([Select a.Id, a.Name, a.Net_Proceeds_USD__c,a.Net_Proceeds_LC__c,a.Net_Proceeds_FC__c From Account a]);//
        
        /*Collect the data and store it in map.
          This for loop will query the data in the batch of 200
          If you are sure that record count will not cross governors
          then you can query them in one go.
         */
        
        for(List<Sales_Forecasts__c> lstForecast : [Select Net_Proceeds_FC__c , Net_Proceeds_USD__c, Net_Proceeds_LC__c, Account__c from Sales_Forecasts__c])
        {        
            if(lstForecast != null && lstForecast.size() > 0)
            {
                for(Sales_Forecasts__c objForecast : lstForecast)
                {
                    if(!mapForecastAccount.containsKey(objForecast.Account__c))
                    {
                        List<Sales_Forecasts__c> lstSalesForecast = new List<Sales_Forecasts__c>();
                        lstSalesForecast.add(objForecast);
                        mapForecastAccount.put(objForecast.Account__c,lstSalesForecast);
                    }
                    else
                    {
                        List<Sales_Forecasts__c> lstSalesForecast = mapForecastAccount.get(objForecast.Account__c);
                        if(lstSalesForecast != null)
                            lstSalesForecast.add(objForecast);
                    }    
                }
                system.debug('Forecast Account:::' +mapForecastAccount);
            }
        }
                    
        List<Account> lstAccountsToUpdate = new List<Account>();
        
        // Do the counting
        for(Account objAcc : mapAccount.values())
        {
            List<Sales_Forecasts__c> lstForecastVal = mapForecastAccount.get(objAcc.Id);
            if(lstForecastVal != null && lstForecastVal.size() > 0)
            {
                //We have to Re-calculate following values
                //So we are setting up the initials as 0.
                objAcc.Net_Proceeds_USD__c  = 0;
                objAcc.Net_Proceeds_FC__c = 0;
                objAcc.Net_Proceeds_LC__c = 0;
                
                for(Sales_Forecasts__c objForecast : lstForecastVal)
                {
                    if(objForecast.Net_Proceeds_USD__c == null )
                        objForecast.Net_Proceeds_USD__c = 0;
                    
                    if(objForecast.Net_Proceeds_FC__c == null)
                       objForecast.Net_Proceeds_FC__c = 0;
                                        
                    //if(objForecast.Net_Proceeds_LC__c == null)
                    //   objForecast.Net_Proceeds_LC__c = 0;
                                        
                    objAcc.Net_Proceeds_USD__c += objForecast.Net_Proceeds_USD__c;                        
                    objAcc.Net_Proceeds_FC__c += objForecast.Net_Proceeds_FC__c;
                    
                    if(objForecast.Net_Proceeds_LC__c != null && objForecast.Net_Proceeds_LC__c != '')
                    {
                        Integer i = objForecast.Net_Proceeds_LC__c.length();
                        String tempLC = objForecast.Net_Proceeds_LC__c.substring(4, i);
                        objAcc.Net_Proceeds_LC__c += decimal.valueof(tempLC);
                    }
                }
            }
                        
            //After counting add to List.
            System.debug('Adding Account::' +objAcc.Name);
            System.debug('Net_Proceeds_USD__c Count::' +objAcc.Net_Proceeds_USD__c);
            System.debug('Net_Proceeds_FC__c  Count::' +objAcc.Net_Proceeds_FC__c);
            System.debug('Net_Proceeds_LC__c Count::' +objAcc.Net_Proceeds_LC__c);
            lstAccountsToUpdate.add(objAcc);
        }
        
        //Finally update the List.
        if(lstAccountsToUpdate.size() > 0)
            update lstAccountsToUpdate;
            
        //Check governors
        System.debug('Rows Count::' + Limits.getDMLRows());
        System.debug('Rows Count Remaining For Context::' + Limits.getLimitDMLRows());
        System.debug('DML Statements Count::' + Limits.getDMLStatements());    
        System.debug('DML Statements Remaining For Context::' + Limits.getLimitDMLStatements());
        System.debug('Query Count::'+ Limits.getQueries());
        System.debug('Query Remaining For Context::'+ Limits.getLimitQueries());
        System.debug('Script Statements::' + Limits.getScriptStatements());
        System.debug('Script Statements Remaining For Context::' + Limits.getLimitScriptStatements());
    }
}

This was selected as the best answer