0

I have a requirement where i need to update amount pipeline field in accounnt object for the newly created account the value need to be come from sum of opportunities associated with that particular account.

following batch class written by me can some one help here

public class AccountNewlyCreated implements Database.Batchable<sobject>
        {
    public decimal sum;
    public database.QueryLocator start(database.batchablecontext bc)
    {
        string query ='select id,name,(select name,id from opportunities) from account where CreatedDAte =Today';
        //system.debug('sum'+query);
        return Database.getQueryLocator(query);

    }
         public void execute(Database.BatchableContext bc, List<sObject> scope)

         {  
           // AggregateResult[] gr =[SELECT SUM(Amount) optyamt FROM Opportunity];
            list<account> accountupdate =new list<account>();
            for(account acc:accountupdate)
                 {
             if(Opportunity.AccountId == Account.Id)
             {

                   AggregateResult[] gr= [SELECT SUM(Amount) optyamt FROM Opportunity]; 
                 system.debug('value:'+gr);
                     for(Opportunity opp:gr)
                     {   
                         Account accm =new Account();
                         sum =(Decimal)opp.get(optyamt);
                         accm.Pipeline__c =sum;
                     }

                 }
                 update(acc);
             }

}
    public void finish(Database.BatchableContext bc) {
    System.debug(logginglevel.FINEST, 'FINISHED BATCHING.');
}         

           }

Following error received in my batch class Variable does not exist: optyamt

Thanks Pb

1 Answer 1

2

Your code actually has a number of problems, though, so let's clean it up:


public decimal sum;

Useless variable. This variable, if you did need it, should be in the correct scope, close to the point where you actually use it.


    string query ='select id,name,(select name,id from opportunities) from account where CreatedDAte =Today';

Do not use strings for a query when an inline query will work.

Do not use sub-queries in this query locator for performance reasons.

Do not include fields in the query that you will never use.


        list<account> accountupdate =new list<account>();

Do not use a separate list to update records, unless you need to.


        for(account acc:accountupdate)

You're iterating over an empty list you just created. The records you wanted were in scope.


         if(Opportunity.AccountId == Account.Id)

You're trying to compare two sObjectField tokens. This will never be true, so would never execute.


               AggregateResult[] gr= [SELECT SUM(Amount) optyamt FROM Opportunity]; 

Do not query inside a loop.

You did not query by the Account ID, so you're actually getting the sum for every opportunity in the database.

                 for(Opportunity opp:gr)

An AggregateResult is not an Opportunity, so this would be a compile error.


                     Account accm =new Account();
                     sum =(Decimal)opp.get(optyamt);
                     accm.Pipeline__c =sum;

You didn't include the record Id, so...

             update(acc);

This update would fail.

Do not perform DML in a loop.


Here's the fully cleaned up version of your batch.

public class AccountNewlyCreated implements Database.Batchable<sObject> {
    public Database.QueryLocator start(Database.BatchableContext context) {
        return Database.getQueryLocator([
            SELECT Id FROM Account WHERE CreatedDate = TODAY
        ]);
    }
    public void execute(Database.batchableContext context, Account[] scope) {
        Map<Id, AggregateResult> results = new Map<Id, AggregateResult>([
            SELECT AccountId Id, SUM(Amount) amt FROM Opportunity WHERE AccountId = :scope GROUP BY AccountId
        ]);
        for(Account record: scope) {
            AggregateResult amount = results.get(record.Id);
            if(amount != null) {
                record.Pipeline__c = (Decimal)amount.get('amt');
            } else {
                record.Pipeline__c = null;
            }
        }
        update scope;
    }
    public void finish(Database.BatchableContext bc) {
        System.debug(logginglevel.FINEST, 'FINISHED BATCHING.');
    }         
}
1

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .