You need to sign in to do that
Don't have an account?
Error runing a Batch process: Apex CPU time limit exceeded
global class EvergreenOppoRevenueScheduleBatch implements Database.Batchable<sObject> {
String query;
id firstId = null;
global Database.QueryLocator start(Database.BatchableContext BC) {
/*This SOQL gets all the records (Evergreen Opportunities) on the sObject (OpportunityLineItemSchedule)
WHERE OpportunityLineItem.Opportunity.StageName = 'Contract Executed'
and OpportunityLineItem.Opportunity.TFBA__c = True
and OpportunityLineItem.Opportunity.Contract_Status__c <> 'Cancelled'
and OpportunityLineItem.Opportunity.Contract_Status__c <> 'Renewed'
and OpportunityLineItem.Cancellation_Date__c = null
and OpportunityLineItem.HasRevenueSchedule = True
and OpportunityLineItem.PricebookEntry.Product2.Media__r.Automatic_Revenue_Schedule__c = True
This query can get up to 50,000,000 records
*/
return Database.getQueryLocator([SELECT OpportunityLineItemId, ScheduleDate, OpportunityLineItem.Number_of_Billings__c, OpportunityLineItem.Discounted_Rate__c From OpportunityLineItemSchedule Where OpportunityLineItem.Opportunity.StageName = 'Contract Executed' and OpportunityLineItem.Opportunity.TFBA__c = True and OpportunityLineItem.Opportunity.Contract_Status__c <> 'Cancelled' and OpportunityLineItem.Opportunity.Contract_Status__c <> 'Renewed' and OpportunityLineItem.Cancellation_Date__c = null and OpportunityLineItem.HasRevenueSchedule = True and OpportunityLineItem.PricebookEntry.Product2.Media__r.Automatic_Revenue_Schedule__c = True Order By OpportunityLineItemId DESC]);
}
List<OpportunityLineItemSchedule> addrecs = new List<OpportunityLineItemSchedule>();
/*This is the Loop for the Query scope*/
global void execute(Database.BatchableContext BC, List<OpportunityLineItemSchedule> scope) {
/*Creating a unique ID Set of the all Opportunities*/
Set<ID> oppProductId = new Set<ID>();
For (OpportunityLineItemSchedule recuni : scope) {
oppProductId.add(recuni.OpportunityLineItemId );
}
/*Creating a list of all Max Date for each opportunity line item Ids product from the OpportunityLineItemSchedule sObject using the unique list */
AggregateResult[] groupedResults = [SELECT Max(ScheduleDate) MaxDate, OpportunityLineItemId oppid FROM OpportunityLineItemSchedule Where OpportunityLineItemId in :oppProductId Group By OpportunityLineItemId Order By OpportunityLineItemId];
/*Looping through all the unique Ids to get the Discounted Rate and Number of Billings */
For (OpportunityLineItem opprec : [Select id , Discounted_Rate__c, Number_of_Billings__c From OpportunityLineItem where id in :oppProductId Order By Id]) {
Date maxDatevar;
String stridLineItem;
Id idLineItem;
/*For each record now go throught the following loop find the Max Date. When the Max Date is found get out to the loop */
For (AggregateResult ar :groupedResults) {
stridLineItem = String.ValueOf(ar.get('oppid'));
idLineItem = Id.ValueOf(stridLineItem);
If (opprec.Id == idLineItem) {
maxDatevar = Date.valueOf(ar.get('MaxDate'));
if (date.today() >= MaxDatevar){
Integer Days = 0;
Date oldServiDate = MaxDatevar;
Days = Date.daysInMonth(oldServiDate.year(), oldServiDate.month());
oldServiDate = oldServiDate + Days;
for (Integer countBillings = 1 ; countBillings <= opprec.Number_of_Billings__c; countBillings++ ){
OpportunityLineItemSchedule oppS = new OpportunityLineItemSchedule();
oppS.OpportunityLineItemId = idLineItem;
oppS.Type = 'Revenue';
oppS.ScheduleDate = oldServiDate;
oppS.Revenue = opprec.Discounted_Rate__c;
Days = Date.daysInMonth(oldServiDate.year(), oldServiDate.month());
oldServiDate = oldServiDate + Days;
addrecs.add(oppS);
}
}
break; /*Exit the loop after the record is found.*/
}
}
}
Insert addrecs; /*Insert all the records on the OpportunityLineItemSchedule*/
}
global void finish(Database.BatchableContext BC) {
}
}
I think problem is my nested loop, base on the info that I found online. Any ideas how to fix this issue?
Thanks.
String query;
id firstId = null;
global Database.QueryLocator start(Database.BatchableContext BC) {
/*This SOQL gets all the records (Evergreen Opportunities) on the sObject (OpportunityLineItemSchedule)
WHERE OpportunityLineItem.Opportunity.StageName = 'Contract Executed'
and OpportunityLineItem.Opportunity.TFBA__c = True
and OpportunityLineItem.Opportunity.Contract_Status__c <> 'Cancelled'
and OpportunityLineItem.Opportunity.Contract_Status__c <> 'Renewed'
and OpportunityLineItem.Cancellation_Date__c = null
and OpportunityLineItem.HasRevenueSchedule = True
and OpportunityLineItem.PricebookEntry.Product2.Media__r.Automatic_Revenue_Schedule__c = True
This query can get up to 50,000,000 records
*/
return Database.getQueryLocator([SELECT OpportunityLineItemId, ScheduleDate, OpportunityLineItem.Number_of_Billings__c, OpportunityLineItem.Discounted_Rate__c From OpportunityLineItemSchedule Where OpportunityLineItem.Opportunity.StageName = 'Contract Executed' and OpportunityLineItem.Opportunity.TFBA__c = True and OpportunityLineItem.Opportunity.Contract_Status__c <> 'Cancelled' and OpportunityLineItem.Opportunity.Contract_Status__c <> 'Renewed' and OpportunityLineItem.Cancellation_Date__c = null and OpportunityLineItem.HasRevenueSchedule = True and OpportunityLineItem.PricebookEntry.Product2.Media__r.Automatic_Revenue_Schedule__c = True Order By OpportunityLineItemId DESC]);
}
List<OpportunityLineItemSchedule> addrecs = new List<OpportunityLineItemSchedule>();
/*This is the Loop for the Query scope*/
global void execute(Database.BatchableContext BC, List<OpportunityLineItemSchedule> scope) {
/*Creating a unique ID Set of the all Opportunities*/
Set<ID> oppProductId = new Set<ID>();
For (OpportunityLineItemSchedule recuni : scope) {
oppProductId.add(recuni.OpportunityLineItemId );
}
/*Creating a list of all Max Date for each opportunity line item Ids product from the OpportunityLineItemSchedule sObject using the unique list */
AggregateResult[] groupedResults = [SELECT Max(ScheduleDate) MaxDate, OpportunityLineItemId oppid FROM OpportunityLineItemSchedule Where OpportunityLineItemId in :oppProductId Group By OpportunityLineItemId Order By OpportunityLineItemId];
/*Looping through all the unique Ids to get the Discounted Rate and Number of Billings */
For (OpportunityLineItem opprec : [Select id , Discounted_Rate__c, Number_of_Billings__c From OpportunityLineItem where id in :oppProductId Order By Id]) {
Date maxDatevar;
String stridLineItem;
Id idLineItem;
/*For each record now go throught the following loop find the Max Date. When the Max Date is found get out to the loop */
For (AggregateResult ar :groupedResults) {
stridLineItem = String.ValueOf(ar.get('oppid'));
idLineItem = Id.ValueOf(stridLineItem);
If (opprec.Id == idLineItem) {
maxDatevar = Date.valueOf(ar.get('MaxDate'));
if (date.today() >= MaxDatevar){
Integer Days = 0;
Date oldServiDate = MaxDatevar;
Days = Date.daysInMonth(oldServiDate.year(), oldServiDate.month());
oldServiDate = oldServiDate + Days;
for (Integer countBillings = 1 ; countBillings <= opprec.Number_of_Billings__c; countBillings++ ){
OpportunityLineItemSchedule oppS = new OpportunityLineItemSchedule();
oppS.OpportunityLineItemId = idLineItem;
oppS.Type = 'Revenue';
oppS.ScheduleDate = oldServiDate;
oppS.Revenue = opprec.Discounted_Rate__c;
Days = Date.daysInMonth(oldServiDate.year(), oldServiDate.month());
oldServiDate = oldServiDate + Days;
addrecs.add(oppS);
}
}
break; /*Exit the loop after the record is found.*/
}
}
}
Insert addrecs; /*Insert all the records on the OpportunityLineItemSchedule*/
}
global void finish(Database.BatchableContext BC) {
}
}
I think problem is my nested loop, base on the info that I found online. Any ideas how to fix this issue?
Thanks.
All Answers