Results 1 to 4 of 4
- 09-08-2011, 10:22 PM #1
Member
- Join Date
- Jan 2011
- Posts
- 7
- Rep Power
- 0
determine if account has child opportunities within specific date ranges
I'm using the salesforce language APEX which is derived from Java. I hope it is okay to post in this forum since APEX is almost identical to Java. If not, my apologies and feel free to ignore this post.
I've created a batch program that loops over all accounts and then loops over each accounts related child opportunities.
As I'm looping over the child opportunities, I want to first see if the account has any closed won opportunities within the last year. If I find a match then I want to set the account field Customer_Status__c to current.
If I don't find a match, then I want to check to see if there are any closed won opportunities within the last 2 years (24 months). If I find a match then I want to set the account field Customer_Status__c to prior active.
If I don't find a match, then I want to check to see if there are any closed won opportunities that are beyond 2 years and set the account field Customer_Status__c to prior inactive.
I'm looping over the accounts and related child opportunity records shown below (see code below)
Something is not quite right with my logic because when I run the batch program it is setting the account field correctly for some accounts, but then other accounts do not get the Customer Status field set even though it has a closed won opportunity that is within a date range that should cause the value to get set?Java Code:global class AccountCustomerStatusBatchUpdate implements Database.Batchable<Sobject>, Database.AllowsCallouts { //Public String query = 'Select Id, Customer_Status__c, (Select StageName, CloseDate From Opportunities Where StageName = \'Closed Won\' ORDER BY CloseDate DESC) From Account'; Public String query = 'Select Id, Customer_Status__c, (Select StageName, CloseDate From Opportunities Where isWon = True ORDER BY CloseDate DESC) From Account'; global database.querylocator start(Database.BatchableContext BC) { return Database.getQueryLocator(query); } global void execute(Database.BatchableContext BC, Sobject[] scope) { boolean found = false; Date beforeOneYear = date.newInstance(Date.today().Year() - 1, Date.today().Month(), Date.today().Day()); Date beforeTwoYear = date.newInstance(Date.today().Year() - 2, Date.today().Month(), Date.today().Day()); List<Account> AcctsToUpdate = new List<Account>(); for (Account master : (List<Account>)scope) { for (Opportunity o : master.Opportunities) { while(!found) { if (o.CloseDate >= beforeOneYear) { master.Customer_Status__c = 'Current'; AcctsToUpdate.add(master); found = true; } else if (o.CloseDate < beforeOneYear && o.CloseDate >= beforeTwoYear) { master.Customer_Status__c = 'Prior Active'; AcctsToUpdate.add(master); found = true; } else if (o.CloseDate < beforeTwoYear) { master.Customer_Status__c = 'Prior Inactive'; AcctsToUpdate.add(master); found = true; } } if (found) { break; } } } update AcctsToUpdate; } global void finish(Database.BatchableContext BC) { } }
Does anyone see a problem with the logic in my code that might cause that to happen?
Thanks for any help.
- 09-09-2011, 12:38 AM #2
Re: determine if account has child opportunities within specific date ranges
I haven't read your code thouroughly and have no idea if this is related to your problem or not but your logic is off. You stop executing the while loop when found gets set to true. Therefore it is impossible for you to get to the if statement unless found is true, thus the if statement will always be executed making it pointless.Java Code:while(!found) { } if (found) { break; }
- 09-09-2011, 02:32 AM #3
Member
- Join Date
- Jan 2011
- Posts
- 7
- Rep Power
- 0
Re: determine if account has child opportunities within specific date ranges
Thanks for replying to my post. I included the if statement to break out of the child for loop (master.Opportunities). My goal is to stop the the while loop when found is true, but also break out of the child for loop (master.Opportunities) and then begin the next loop sequence for Account (master).
So, for every account, I want to loop over all the child account records (opportunities). While I loop over the child records, if any of the conditions are met, I want to set the appropriate value, set found to true, exit the while loop and break out of the child loop (master.opportunities) and then begin the Account loop for the next master record. I do not need to loop over all the child opportunity records once one of the conditions are met because I'm setting the value on the account master record. That is why I included an ORDER BY CloseDate statement in the query so it is looking at the child records in descending order by close date (most recent to oldest date).
When I run the program, it sets the value for Customer Status on some of the account records, but not for others?
Let me know if that helps explain?
I modified my code and removed the if statement as you suggested.
Java Code:global class AccountCustomerStatusBatchUpdate implements Database.Batchable<Sobject>, Database.AllowsCallouts { //Public String query = 'Select Id, Customer_Status__c, (Select StageName, CloseDate From Opportunities Where StageName = \'Closed Won\' ORDER BY CloseDate DESC) From Account'; Public String query = 'Select Id, Customer_Status__c, (Select StageName, CloseDate From Opportunities Where isWon = True ORDER BY CloseDate DESC) From Account'; global database.querylocator start(Database.BatchableContext BC) { return Database.getQueryLocator(query); } global void execute(Database.BatchableContext BC, Sobject[] scope) { boolean found = false; Date beforeOneYear = date.newInstance(Date.today().Year() - 1, Date.today().Month(), Date.today().Day()); Date beforeTwoYear = date.newInstance(Date.today().Year() - 2, Date.today().Month(), Date.today().Day()); List<Account> AcctsToUpdate = new List<Account>(); for (Account master : (List<Account>)scope) { for (Opportunity o : master.Opportunities) { while(!found) { if (o.CloseDate >= beforeOneYear) { master.Customer_Status__c = 'Current'; AcctsToUpdate.add(master); found = true; } else if (o.CloseDate < beforeOneYear && o.CloseDate >= beforeTwoYear) { master.Customer_Status__c = 'Prior Active'; AcctsToUpdate.add(master); found = true; } else if (o.CloseDate < beforeTwoYear) { master.Customer_Status__c = 'Prior Inactive'; AcctsToUpdate.add(master); found = true; } } } } update AcctsToUpdate; } global void finish(Database.BatchableContext BC) { } }
- 09-11-2011, 04:01 PM #4
Member
- Join Date
- Jan 2011
- Posts
- 7
- Rep Power
- 0
Re: determine if account has child opportunities within specific date ranges
I figured it out. I needed to reset the boolean variable found = false at the start of the first for loop. Once found is equal to true in the while loop, it never got re-entered even when the next cycle of the for loop started for a new account record.
Java Code:for (Account master : (List<Account>)scope) { found = false;
Similar Threads
-
JSTL date format for specific locale
By mcadirci in forum JavaServer Pages (JSP) and JSTLReplies: 0Last Post: 03-28-2011, 09:30 AM -
Byte Ranges
By alessandro_ in forum NetworkingReplies: 2Last Post: 02-14-2010, 11:48 AM -
How to get value of specific child node
By sito42 in forum New To JavaReplies: 1Last Post: 07-13-2009, 12:00 PM -
Printing ranges of numbers using if/else statements
By russbuss106 in forum New To JavaReplies: 8Last Post: 03-05-2009, 05:03 AM -
Learning Tree Instructor Opportunities
By LearningTree in forum Jobs OfferedReplies: 0Last Post: 04-25-2007, 08:33 PM


LinkBack URL
About LinkBacks
Reply With Quote
Bookmarks