+ Start a Discussion
Ganesh BollinaGanesh Bollina 

Fetching stageName on Opportunity in the start method for Batch Class

I have a scenario where i need to find the stageName of the Oppty. The query is not returning the stageName, here is my code

global class UpdatePartnerAccountForOppty implements Database.Batchable<sObject>{

   global Database.QueryLocator start(Database.BatchableContext BC){
      return Database.getQueryLocator('SELECT id, Partner__c FROM Opportunity ');
   }

   global void execute(Database.BatchableContext BC, List<sObject> scope){
          Set<Id> accountIdSet = new Set<Id>(); 
          Set<Id> accountWonIdSet = new Set<Id>();
          
          List<Opportunity> opptys = new List<Opportunity>([SELECT Id,Partner__c, StageName FROM Opportunity]); 
          for (Opportunity opp: opptys) {
            if (opp.Partner__c != null) {
             accountIdSet.add(opp.Partner__c);
             system.debug('****PartnerAccount1***'+accountIdSet);
            } 
            if (opp.Partner__c != null && opp.StageName == 'Closed Won') {
            accountWonIdSet.add(opp.Partner__c);
            system.debug('****PartnerAccount2***'+accountIdSet);
           }      
        }     
      OppHandlerUpdateAccount.CalTotalReferralsForAccount(accountIdSet);
      OppHandlerUpdateAccount.CalTotalWonReferralsForAccount(accountWonIdSet);     
    }

   global void finish(Database.BatchableContext BC){
   }
}
Best Answer chosen by Ganesh Bollina
Naresh YadavNaresh Yadav
Hi Ganesh Bollina

See the below code.

global class UpdatePartnerAccountForOppty implements Database.Batchable < sObject > {

      
    global Database.QueryLocator start(Database.BatchableContext BC) {   
        return Database.getQueryLocator('SELECT id, Partner__c, StageName FROM Opportunity ');  
    }

      
    global void execute(Database.BatchableContext BC, List < sObject > scope) {     
        Set < Id > accountIdSet = new Set < Id > ();      
        Set < Id > accountWonIdSet = new Set < Id > ();            
        //List<Opportunity> opptys = new List<Opportunity>([SELECT Id,Partner__c, StageName FROM Opportunity]); 
             
        if (scope.size() > 0) {        
            for (Opportunity opp: scope) {  
    
                if (opp.Partner__c != null) {       
                    accountIdSet.add(opp.Partner__c);       
                    system.debug('****PartnerAccount1***' + accountIdSet);      
                }       
                if (opp.Partner__c != null && opp.StageName == 'Closed Won') {      
                    accountWonIdSet.add(opp.Partner__c);      
                    system.debug('****PartnerAccount2***' + accountIdSet);      
                }       
            }      
            OppHandlerUpdateAccount.CalTotalReferralsForAccount(accountIdSet);   
            OppHandlerUpdateAccount.CalTotalWonReferralsForAccount(accountWonIdSet);​     
        }     
    }

      
    global void finish(Database.BatchableContext BC) {  }
}

Let me know if it is help you out.
Peace.

All Answers

Naresh YadavNaresh Yadav
Hi Ganesh Bollina

See the below code.

global class UpdatePartnerAccountForOppty implements Database.Batchable < sObject > {

      
    global Database.QueryLocator start(Database.BatchableContext BC) {   
        return Database.getQueryLocator('SELECT id, Partner__c, StageName FROM Opportunity ');  
    }

      
    global void execute(Database.BatchableContext BC, List < sObject > scope) {     
        Set < Id > accountIdSet = new Set < Id > ();      
        Set < Id > accountWonIdSet = new Set < Id > ();            
        //List<Opportunity> opptys = new List<Opportunity>([SELECT Id,Partner__c, StageName FROM Opportunity]); 
             
        if (scope.size() > 0) {        
            for (Opportunity opp: scope) {  
    
                if (opp.Partner__c != null) {       
                    accountIdSet.add(opp.Partner__c);       
                    system.debug('****PartnerAccount1***' + accountIdSet);      
                }       
                if (opp.Partner__c != null && opp.StageName == 'Closed Won') {      
                    accountWonIdSet.add(opp.Partner__c);      
                    system.debug('****PartnerAccount2***' + accountIdSet);      
                }       
            }      
            OppHandlerUpdateAccount.CalTotalReferralsForAccount(accountIdSet);   
            OppHandlerUpdateAccount.CalTotalWonReferralsForAccount(accountWonIdSet);​     
        }     
    }

      
    global void finish(Database.BatchableContext BC) {  }
}

Let me know if it is help you out.
Peace.
This was selected as the best answer
Ravi Dutt SharmaRavi Dutt Sharma
Hey Ganesh,

You are not querying the StageName field in start method, then how can you expect the StageName to be returned in the query. Another point here is that why are you doing another query in execute method? The scope paramter of execute method contains the result returned by start method. You can use the scope variable instead of doing another query. You code should be something like below :
 
global class UpdatePartnerAccountForOppty implements Database.Batchable<sObject>{

   global Database.QueryLocator start(Database.BatchableContext BC){
      return Database.getQueryLocator('SELECT id, Partner__c,StageName FROM Opportunity ');
   }

   global void execute(Database.BatchableContext BC, List<Opportunity> scope){
          Set<Id> accountIdSet = new Set<Id>(); 
          Set<Id> accountWonIdSet = new Set<Id>();
          
          for (Opportunity opp: scope) {
            if (opp.Partner__c != null) {
             accountIdSet.add(opp.Partner__c);
             system.debug('****PartnerAccount1***'+accountIdSet);
            } 
            if (opp.Partner__c != null && opp.StageName == 'Closed Won') {
            accountWonIdSet.add(opp.Partner__c);
            system.debug('****PartnerAccount2***'+accountIdSet);
           }      
        }     
      OppHandlerUpdateAccount.CalTotalReferralsForAccount(accountIdSet);
      OppHandlerUpdateAccount.CalTotalWonReferralsForAccount(accountWonIdSet);     
    }

   global void finish(Database.BatchableContext BC){
   }
}

 
Ganesh BollinaGanesh Bollina
I have Included the SatgeName in the start method and the query itself is not returning the StageName
Ganesh BollinaGanesh Bollina
This is my updated code and it's not working either..

global class UpdatePartnerAccountForOppty implements Database.Batchable<sObject>{

   global Database.QueryLocator start(Database.BatchableContext BC){
      return Database.getQueryLocator('SELECT id,StageName, Partner__c FROM Opportunity ');
   }

   global void execute(Database.BatchableContext BC, List<sObject> scope){
          Set<Id> accountIdSet = new Set<Id>(); 
          Set<Id> accountWonIdSet = new Set<Id>();
          
           if (scope.size() > 0) { 
          List<Opportunity> opptys = (List<Opportunity>)scope; 
          for (Opportunity opp: opptys) {
            if (opp.Partner__c != null) {
             accountIdSet.add(opp.Partner__c);
             system.debug('****PartnerAccount1***'+accountIdSet);
            } 
            if (opp.Partner__c != null && opp.StageName == 'Closed Won') {
            accountWonIdSet.add(opp.Partner__c);
            system.debug('****PartnerAccount2***'+accountIdSet);
           }      
        }     
      OppHandlerUpdateAccount.CalTotalReferralsForAccount(accountIdSet);
      OppHandlerUpdateAccount.CalTotalWonReferralsForAccount(accountWonIdSet);     
    }
  }
   global void finish(Database.BatchableContext BC){
   }
}
Naresh YadavNaresh Yadav
Hi Ganesh Bollina

There is no need to typecast it. You can directly use it or directly loop through it.

Like
for (Opportunity opp: scope) {

}

 
Ganesh BollinaGanesh Bollina
Hi Naresh,
 This is the error thrown while saving
Loop variable must be of type SObject at line 13 column 28

and In the logs i see it's not returning the StageName: when the execution starts it's ignoring the StageName

13:11:23:023 SOQL_EXECUTE_BEGIN [7]|Aggregations:0|SELECT id, Partner__c FROM Opportunity
Ravi Dutt SharmaRavi Dutt Sharma
Check the FLS of StageName for SysAdmin profile. Is it visible to SysAdmin? 
Naresh YadavNaresh Yadav
Use this code.
global class UpdatePartnerAccountForOppty implements Database.Batchable < sObject > {

      
    global Database.QueryLocator start(Database.BatchableContext BC) {   
        return Database.getQueryLocator('SELECT id, Partner__c, StageName FROM Opportunity ');  
    }

      
    global void execute(Database.BatchableContext BC, List < Opportunity> scope) {     
        Set < Id > accountIdSet = new Set < Id > ();      
        Set < Id > accountWonIdSet = new Set < Id > ();            
        //List<Opportunity> opptys = new List<Opportunity>([SELECT Id,Partner__c, StageName FROM Opportunity]); 
             
        if (scope.size() > 0) {        
            for (Opportunity opp: scope) {      
                if (opp.Partner__c != null) {       
                    accountIdSet.add(opp.Partner__c);       
                    system.debug('****PartnerAccount1***' + accountIdSet);      
                }       
                if (opp.Partner__c != null && opp.StageName == 'Closed Won') {      
                    accountWonIdSet.add(opp.Partner__c);      
                    system.debug('****PartnerAccount2***' + accountIdSet);      
                }       
            }      
            OppHandlerUpdateAccount.CalTotalReferralsForAccount(accountIdSet);   
            OppHandlerUpdateAccount.CalTotalWonReferralsForAccount(accountWonIdSet);​     
        }     
    }

      
    global void finish(Database.BatchableContext BC) {  }
}

 
Ganesh BollinaGanesh Bollina
It is set to visible
Ganesh BollinaGanesh Bollina
I am tworking on dev sandbox and i think there is some weird things
going on.. When i moved the same code to UAT it worked fine..