You need to sign in to do that
Don't have an account?
Urgent Help with a Trigger
Hey ,
Need help with a trigger . Below is a trigger on products which is not firing at all i checked the debug log also and its not there . Once a opportunity is Won or Won-Future Activation date and the product code contains 'FF' the trigger should fire and Update a field on account called Fit Finder Status to 'Active'.The thing is products and opportunities are not directly related although products are shown under a related list under Opportunities.There are also Pricebook and PricebookEntry in the schema .PricebookEntry is related to Opportunities.The Code saves without errors . Can anyone please help since I am still new to these kind of triggers.
Thanks and Regards
trigger FFStatusA on Product2 (after update , after insert ) {
ID ID1;
ID ID2;
ID ID3;
ID ID4;
Opportunity O = [ Select AccountId , Pricebook2Id from Opportunity where Pricebook2Id =:ID4];
ID1=O.AccountId;
ID2=O.Pricebook2Id;
PricebookEntry Pe = [Select Pricebook2Id , ProductCode from PricebookEntry where Pricebook2Id=:ID2];
ID3 = Pe.Pricebook2Id;
Account acc = [Select Id , Name from Account where Id =:ID1];
ID4 = Acc.Id;
String pc = Pe.ProductCode;
String f ='FF';
Boolean Result = pc.Contains(f);
for (Product2 p :Trigger.new){
//If (acc.Id ==o.AccountId && Pe.Pricebook2Id ==O.Pricebook2Id ){
// && Result == True
If ( (O.StageName== 'Won' || O.StageName=='Won - Future Activation Date' )&& Result == True ){
acc.Fit_Finder_Status__pc = 'Active';
}
// }
}
database.update(acc);
}
It sounds like you want this trigger to be on the Opportunity object and not the Product2 object. The initiating event is when the opportunity is inserted/update with a StageName of "Won" or "Won Future Activation" (or something like that). From there, the trigger can query the related products to verify if the specific FF product is associated. Then complete its logic.
I would agree with aalbert about this being an Opportunity trigger, not a Product2 trigger.
That being said, you also have an execution order issue that will cause your trigger never to update any record.
You initize an ID variable called ID4, then, on the next line, you do a soql query for an opportunity where the pricebookid = ID4, but ID4 has no value yet. This would cause your Opportunity "O" to be null. Also, the way this soql is constructed, it is likely that you will get more than one opportunity returned with the same pricebookid, and you cannot set a single Opportunity equal to a list result.
Hi Aalbert /Jim ,
Sorry for not replying earlier , since the issue was on hold. I had actually tried writing the trigger on Opportunity earlier but the trigger gave me a null pointer exception when I tried querying the Product Object saying no product was available, which I believe is due to the fact that we are associating an Opportunity with a product once an opportunity is created . Please correct me If I am missing something since I am not very experienced at this level of apex coding . Would it help if I were to write the trigger on Opportunity Product ??
Thanks and Regards
This is a bit of a tricky scenario. If you use trigger on the OLI then it wouldn't fire when the FF product exists and the stage is changed to the Won or Future-Won, unless you had other rules in place that prevented products from being added or changed when the opportunity was in these stages.
I would still suggest that you use an Opportunity trigger, you should only need after update because after insert, there would never be any products included.
If I remember correctly, adding a product will still cause the opportunity update trigger to fire. If you post the code you have for the Opportunity trigger, it would be easier to debug.
Hi Jim,
I will post my code in little while from now .But I had another query which came up , i noticed through the Salesforce Schema in Eclipse that the Product and Opportunity are not directly related to each other , is there some other way of relating them and then querying for the Product Code ?
Thanks a ton !!
You are correct that the "Product' is not related directly to the opportunity. Each Opportuntiy will have 0 or more OpportunityLineItems (OLI), each of these OLIs will have a PricebooEntryID. The PricebookEntry object will have a Product2ID, which is how the product is related to the opportunity. This is done so a single product can have many different pricing options defined, and based on which pricebooks are shared to the user, different pricing is displayed.
So, you will need to do some relational queries and possibly some maps to get from the Opportunity to the Product.
Thanks a lot JIm for explaining the relationships ,I really appreciate your help. Another query I had was are Opportunity Products and Opportunity Line Item the same thing , the reason I ask is when I was writing a trigger under Opportunity Products the first line on the trigger was , trigger triggername on OpportunityLineItem instead of Opportunity Products . Also one more thing I noticed that the Product Code was a Standard Field in Opportunity Product but when I tried to retrieve the Product Code using a SOQL query on Opportunity LineItem in the trigger I wrote under Opportunity Products it gave me an error saying No such column existed on Opportunity Line Item. Would have any idea on these ?
Thanks and Best Regards
Yes, Opportunity Product (shown via the UI) is called OpportunityLineItem via Apex. As for the Product Code on the Opportunity Product, I think that SFDC is doing some internal mapping of the field, that is why you see it in the UI, but not in APEX.
You can get to it with a relational query:
but I am not positive if that product code and the one on the product2 object are the same.
Give it a try and see if you are getting what you might expect.
Hi Jim
I wrote my Trigger as below on the Opportunity as we discussed . But it is giving me a NullPointerException at below line . Can you please help me .
Thanks and Regards
trigger FFStatus on Opportunity (after update) {
Opportunity Opp;
List <OpportunityLineItem> OLIPEMAP = new List <OpportunityLineItem> ();
OLIPEMAP = [Select o.PricebookEntryId ,o.PricebookEntry.ProductCode from OpportunityLineItem o where o.OpportunityId =: Opp.Id ]; <---here is the Exception
for (Opportunity Op :Trigger.new){
for ( OpportunityLineItem oli : OLIPEMAP ){
String pc = Oli.PricebookEntry.ProductCode;
String f ='FF';
Boolean Result = pc.Contains(f);
If ( (Op.StageName== 'Won' || Op.StageName=='Won - Future Activation Date' ) && Result == True ){
Account a;
a.Fit_Finder_Status__c = 'Active';
}
}
}
}
Well, to start with, the reason you are getting the null pointer is becase your opportunity Opp is not defined to anything. You have declared an Opportunity variable called Opp, but it is assigned to any existing opportunity. You did the same type of thing with the Account object.
You need to use the Trigger.new list to reference the actual opportunity or opportunties that caused the trigger to fire in the first place.
See how this works for you:
Hi Jim,
I actually got an error for the below line as follows ,
Best Regards
Error :
llegal assignment from LIST<Account> to MAP<Id,Account> at line 10 column 5
Map<ID,Account> ACCTMAP = new Map<ID,Account>(); //create a map list of accounts with the Account ID as the key
ACCTMAP= [select id,Fit_Finder_Status__c from Account where id in:AcctIDs];
That should have worked. I am just typing this in, so you may need to do some clean up to get it to compile.
Try it this way:
hey Jim,
I am sorry if i am troubling you too much but i am not sure why i am getting the below error .
Thanks and Regards
System.NullPointerException: Attempt to de-reference a null object: Trigger.FFStatus: line 26, column
for (Opportunity Op :Trigger.new){
for ( OpportunityLineItem oli : OLIOPPMAP.get(Op.id) ){ <<--------- Here is the Exception
String pc = oli.PricebookEntry.ProductCode;
Boolean Result = pc.Contains(f);
if ( (Op.StageName== 'Won' || Op.StageName=='Won - Future Activation Date' ) && Result == True ){
Account tmpAccount = ACCTMAP.get(Op.AccountID);
tmpAccount.Fit_Finder_Status__c = 'Active';
updACCT.add(tmpAccount);
}
}
}
My guess would be that you have an Opportunity being updated that has no products at all.
This error handling should catch that scenario (basically, ignore any opportunities with no products added:
Actually the above error was when I was inserting(creating) a new opportunity .That one disappeared and now when I tried adding a product it gave me the below error .
Error :
SObject row was retrieved via SOQL without querying the requested field: OpportunityLineItem.OpportunityId: Trigger.FFStatus: line 16, column 34
List<Account> updACCT = new List<Account>(); //accounts in this list will get updated
Map <ID,List<OpportunityLineItem>> OLIOPPMAP = new Map <ID,List<OpportunityLineItem>> (); //create a map list of OLI with the Opportunity ID as the key, note that each opp could have more than one OLI
for(OpportunityLineItem oli: [Select o.PricebookEntryId ,o.PricebookEntry.ProductCode from OpportunityLineItem o where o.OpportunityId in :Trigger.New ]){
if(OLIOPPMAP.containsKey(oli.OpportunityID)) { <<<----------------- Here is the exception.
OLIOPPMAP.get(oli.OpportunityID).add(oli);
}else{
OLIOPPMAP.put(oli.OpportunityID,new List<OpportunityLineItem>{oli});
}
}
Hopefully, you are starting to get an idea of how this all works by looking at the changes that I have been making to debug the issues.
Hi Jim,
Yes I am understanding the changes you are making to debug the issues and also higly appreciate the time and effort you have taken to help me out here. But I am still not able to figure out how to get rid of these Null pointer Exceptions as I got another one below.Is there a some standard technique to resolve these , since until now by trial and error I was able get rid of most of my errors.
Thanks and Regards
System.NullPointerException: Attempt to de-reference a null object: Trigger.FFStatus: line 29, column 34
for (Opportunity Op :Trigger.new){
if(OLIOPPMAP.containsKey(Op.id)){
for ( OpportunityLineItem oli : OLIOPPMAP.get(Op.id) ){
String pc = oli.PricebookEntry.ProductCode;
Boolean Result = pc.Contains(f); <<---------- Null pointer here.
if ( (Op.StageName== 'Won' || Op.StageName=='Won - Future Activation Date' ) && Result == True ){
Account tmpAccount = ACCTMAP.get(Op.AccountID);
tmpAccount.Fit_Finder_Status__c = 'Active';
updACCT.add(tmpAccount);
}
}
}
}
Hi Jim,
I beleive the Error is due to the fact that the trigger is firing off when I am first trying to insert the first product and I believe the line does not have a product code to assign to string pc and hence the error.
Regards
Null Pointer Exceptions are difficult to address, but not impossible. what you need to do is to look at where the issue is occuring and determine why. As in your example, you believe you have an OLI with a null Product Code. Next evaluate why this happened? Do you allow the Product Code to be null in production? Why is your example null? If you don't allow nulls in this field, it is a test data error, if you do, then you need to account for it in your code, maybe something like this:
We do allow some product codes to be null I am guessing , since I have not gone through all of them .But the last error seemed to be because I was trying to retrieve the Product before I had added the Product itself. So anyways the code seems to be working fine for now pending testing approval .There was a additional condition which the business users gave me so I included that and am posting the code below. I wanted to convey my utmost thanks to you, without your patience, effort and help I think I would never have been able to do this . May be someday I can help someone like me and pass on the goodwill. :-))
Thanks and Best Regards
trigger FFStatus on Opportunity (after update) {
String f ='FF';
String r='RT';
Set<ID> OppIDs = new Set<ID>();
Set<ID> AcctIDs = new Set<ID>();
for(Opportunity o:Trigger.New){
OppIDs.add(o.id);
AcctIDs.add(o.accountid);
}
Map<ID,Account> ACCTMAP = new Map<ID,Account>([select id,Fit_Finder_Status__c from Account where id in:AcctIDs]); //create a map list of accounts with the Account ID as the key
List<Account> updACCT = new List<Account>(); //accounts in this list will get updated
Map <ID,List<OpportunityLineItem>> OLIOPPMAP = new Map <ID,List<OpportunityLineItem>> (); //create a map list of OLI with the Opportunity ID as the key, note that each opp could have more than one OLI
for(OpportunityLineItem oli: [Select o.PricebookEntryId ,o.PricebookEntry.ProductCode,OpportunityID from OpportunityLineItem o where o.OpportunityId in :Trigger.New ]){
if(OLIOPPMAP.containsKey(oli.OpportunityID)){
OLIOPPMAP.get(oli.OpportunityID).add(oli);
}else{
OLIOPPMAP.put(oli.OpportunityID,new List<OpportunityLineItem>{oli});
}
}
for (Opportunity Op :Trigger.new){
if(OLIOPPMAP.containsKey(Op.id)){
for ( OpportunityLineItem oli : OLIOPPMAP.get(Op.id) ){
String pc;
if(oli.PricebookEntry.ProductCode<>null){
pc = oli.PricebookEntry.ProductCode;
}else{
pc ='';
}
Boolean Result = pc.Contains(f);
Boolean ResultR = pc.Contains(r);
if ( (Op.StageName== 'Won' || Op.StageName=='Won - Future Activation Date' ) && Result == True ){
Account tmpAccount = ACCTMAP.get(Op.AccountID);
tmpAccount.Fit_Finder_Status__c = 'Active';
tmpAccount.Fit_Finder_Program__c='Paying - Reg Customer';
updACCT.add(tmpAccount);
}else{if ( (Op.StageName== 'Won' || Op.StageName=='Won - Future Activation Date' ) && ResultR == True ){
Account tmpAccountR= ACCTMAP.get(Op.AccountID);
tmpAccountR.Fit_Finder_Status__c = 'Active';
tmpAccountR.Fit_Finder_Program__c='Right Track';
updACCT.add(tmpAccountR);
}
}
}
}
}
try{
update updACCT;
}catch(DMLException d){
system.debug('\n\nERROR UPDATING ACCOUNTS: '+d.getDMLMessage(0));
}
}
hey Jim,
I think I should have waited before the testing was complete , I ran into another exception as below .I had some additional conditions given to me which I added in the code .It worked good couple of times and when I tried to add another Product with FF Product Code to the list which already had an RT Product Code Product , it broke down.
Regards
FFStatus: execution of AfterUpdate caused by: System.ListException: Duplicate id in list: 001P000000FEbeqIAD: Trigger.FFStatus: line 61, column 9
Ah, another bad assumption on my part. I didn't know that an opportunity could have more than one FF product included on it.
The List collection will allow duplicates to be added, but the update method won't allow duplicates to be updated.
What we need to do is to add the items to a Set, which requires uniqueness, and then at the end add the set to a list for updating (we can't update a Set directly.
You will need to create a set of accounts
add the proper accounts in your if statement section, and then add the full set of unique accounts to the list to be updated:
I think you might need some work on your if else logic, the way the loop works, you could never have the same OLI with pc contains f and pc contains r, each one could only have one value. If you need to check for both, this would be much more complex, I am not sure of the logic off the top of my head.
Hopefully, this get's you close, and you can focus on how to clean up the if logic.
Good Luck!!
Hi Jim ,
Thanks a lot for the suggestions , but I just am not able to get rid of the duplicate Id bug as below. Please can you give me some more pointers since I am at a loss how to resolve this problem.
Thanks and Regards
FFStatus: execution of AfterUpdate caused by: System.ListException: Duplicate id in list: 001P000000FEbeqIAD: Trigger.FFStatus: line 64, column 9
trigger FFStatus on Opportunity (after update) {
String f ='FF';
String r='RT';
Set<ID> OppIDs = new Set<ID>();
Set<ID> AcctIDs = new Set<ID>();
for(Opportunity o:Trigger.New){
OppIDs.add(o.id);
AcctIDs.add(o.accountid);
}
Map<ID,Account> ACCTMAP = new Map<ID,Account>([select id,Fit_Finder_Status__c from Account where id in:AcctIDs]); //create a map list of accounts with the Account ID as the key
List<Account> updACCT = new List<Account>(); //accounts in this list will get updated
Set<Account> AcctSet = new Set<Account>();
Map <ID,List<OpportunityLineItem>> OLIOPPMAP = new Map <ID,List<OpportunityLineItem>> (); //create a map list of OLI with the Opportunity ID as the key, note that each opp could have more than one OLI
for(OpportunityLineItem oli: [Select o.PricebookEntryId ,o.PricebookEntry.ProductCode,OpportunityID from OpportunityLineItem o where o.OpportunityId in :Trigger.New ]){
if(OLIOPPMAP.containsKey(oli.OpportunityID)){
OLIOPPMAP.get(oli.OpportunityID).add(oli);
}else{
OLIOPPMAP.put(oli.OpportunityID,new List<OpportunityLineItem>{oli});
}
}
for (Opportunity Op :Trigger.new){
if(OLIOPPMAP.containsKey(Op.id)){
for ( OpportunityLineItem oli : OLIOPPMAP.get(Op.id) ){
String pc;
if(oli.PricebookEntry.ProductCode<>null){
pc = oli.PricebookEntry.ProductCode;
}else{
pc ='';
}
Boolean Result = pc.Contains(f);
Boolean ResultR = pc.Contains(r);
if ( (Op.StageName== 'Won' || Op.StageName=='Won - Future Activation Date' ) && Result == True ){
Account tmpAccount = ACCTMAP.get(Op.AccountID);
tmpAccount.Fit_Finder_Status__c = 'Active';
tmpAccount.Fit_Finder_Program__c='Paying - Reg Customer';
AcctSet.add(tmpAccount);
} else{if ( ((Op.StageName== 'Won' || Op.StageName=='Won - Future Activation Date' ) && ResultR == True)){
Account tmpAccountR = ACCTMAP.get(Op.AccountID);
tmpAccountR.Fit_Finder_Status__c = 'Active';
tmpAccountR.Fit_Finder_Program__c='Right Track';
AcctSet.add(tmpAccountR);
}
else{if((Op.StageName== 'Won' || Op.StageName=='Won - Future Activation Date' ) && (ResultR == True && Result == True) ){
Account tmpAccountRF= ACCTMAP.get(Op.AccountID);
tmpAccountRF.Fit_Finder_Status__c = 'Active';
tmpAccountRF.Fit_Finder_Program__c='Right Track';
AcctSet.add(tmpAccountRF);
}
}
}
updACCT.addall(AcctSet);
}
}
}
try{
update updACCT; <<-------- Same Place ,same error.
}catch(DMLException d){
system.debug('\n\nERROR UPDATING ACCOUNTS: '+d.getDMLMessage(0));
}
}
I think I see what the issue is. You need to move the updACCT.addall(AcctSet); outside of the for loop that is processing the opportunities. Basically, put it on the line above the try{
That should eliminate your duplicates.
Jim,
I tried as below but I am getting same error at the same line no . Any more pointers, you could suggest ? :)
Thanks
trigger FFStatus on Opportunity (after update) {
String f ='FF';
String r='RT';
Set<ID> OppIDs = new Set<ID>();
Set<ID> AcctIDs = new Set<ID>();
for(Opportunity o:Trigger.New){
OppIDs.add(o.id);
AcctIDs.add(o.accountid);
}
Map<ID,Account> ACCTMAP = new Map<ID,Account>([select id,Fit_Finder_Status__c from Account where id in:AcctIDs]); //create a map list of accounts with the Account ID as the key
List<Account> updACCT = new List<Account>(); //accounts in this list will get updated
Set<Account> AcctSet = new Set<Account>();
Map <ID,List<OpportunityLineItem>> OLIOPPMAP = new Map <ID,List<OpportunityLineItem>> (); //create a map list of OLI with the Opportunity ID as the key, note that each opp could have more than one OLI
for(OpportunityLineItem oli: [Select o.PricebookEntryId ,o.PricebookEntry.ProductCode,OpportunityID from OpportunityLineItem o where o.OpportunityId in :Trigger.New ]){
if(OLIOPPMAP.containsKey(oli.OpportunityID)){
OLIOPPMAP.get(oli.OpportunityID).add(oli);
}else{
OLIOPPMAP.put(oli.OpportunityID,new List<OpportunityLineItem>{oli});
}
}
for (Opportunity Op :Trigger.new){
if(OLIOPPMAP.containsKey(Op.id)){
for ( OpportunityLineItem oli : OLIOPPMAP.get(Op.id) ){
String pc;
if(oli.PricebookEntry.ProductCode<>null){
pc = oli.PricebookEntry.ProductCode;
}else{
pc ='';
}
Boolean Result = pc.Contains(f);
Boolean ResultR = pc.Contains(r);
if ( (Op.StageName== 'Won' || Op.StageName=='Won - Future Activation Date' ) && Result == True ){
Account tmpAccount = ACCTMAP.get(Op.AccountID);
tmpAccount.Fit_Finder_Status__c = 'Active';
tmpAccount.Fit_Finder_Program__c='Paying - Reg Customer';
AcctSet.add(tmpAccount);
} else{if ( ((Op.StageName== 'Won' || Op.StageName=='Won - Future Activation Date' ) && ResultR == True)){
Account tmpAccountR = ACCTMAP.get(Op.AccountID);
tmpAccountR.Fit_Finder_Status__c = 'Active';
tmpAccountR.Fit_Finder_Program__c='Right Track';
AcctSet.add(tmpAccountR);
}
else{if((Op.StageName== 'Won' || Op.StageName=='Won - Future Activation Date' ) && (ResultR == True && Result == True) ){
Account tmpAccountRF= ACCTMAP.get(Op.AccountID);
tmpAccountRF.Fit_Finder_Status__c = 'Active';
tmpAccountRF.Fit_Finder_Program__c='Right Track';
AcctSet.add(tmpAccountRF);
}
}
}
}
}
}
updACCT.addall(AcctSet);
try{
update updACCT;
}catch(DMLException d){
system.debug('\n\nERROR UPDATING ACCOUNTS: '+d.getDMLMessage(0));
}
}
That doesn't make any sense to me. It shouldn't be possible to get that error.
What I would typically do next is use debug statements to look at the data to see if I could find the issue.
You add the system.debug statements to your code, and then open the system log when you execute your test.
Here is some example of debug output you could use. You might also want to code some debug "loops" to show the actual values in the AcctSET and UpdACCT to see where the duplicate might be coming from.
I am curious if you have considered in your design to write this trigger; What happens if there are 2 opportuntiies on the same account, one with the FF and one without?
Hi Jim ,
I am gonna try that out right now , but just to answer your question . If theAccount has even a single Opportunity with FF code the field is updated to active and Pay-Reg Customer and if the Account has FF frirst and then a RT opportunitiy is added the field is updated to active and Right Track and vice versa.Also a single opportunity can have two Products RT and FF and a single product which is RTFF, for RT and RTFF it should update to active and Right Track and for FF to active and Pay-Reg Customer and again same as above the order in which they come the updates are made .I just got this clarified with BA . Would this change the way we have written my trigger significantly ?
Thanks a lot and Best Regards .
Hi Jim,
Sorry to keep bothering you again and again . But I ran the code which u gave me and checked the debug and system logs and below is what I got from the debug log. I also changed my if else construct syntactically but I am still getting the same error. I reposting the code below if you could help me I woild be really greateful
Thanks and Regards
My code :- It seems at the end of the third loop it is adding the same account again .
String f ='FF';
String r='RT';
Set<ID> OppIDs = new Set<ID>();
Set<ID> AcctIDs = new Set<ID>();
for(Opportunity o:Trigger.New){
OppIDs.add(o.id);
AcctIDs.add(o.accountid);
}
Map<ID,Account> ACCTMAP = new Map<ID,Account>([select id,Fit_Finder_Status__c from Account where id in:AcctIDs]); //create a map list of accounts with the Account ID as the key
//Added these for debugging
system.debug('\n\n');//puts a blank line in the debug output
system.debug('\n\nGOT ' + OppIDs.size() + ' Unique Opportunities in this trigger.');
system.debug('\n\nGOT ' + AcctIDs.size() + ' Unique Accounts in this trigger.');
system.debug('\n\n');//puts a blank line in the debug output
//end debug section 1
List<Account> updACCT = new List<Account>(); //accounts in this list will get updated
Set<Account> AcctSet = new Set<Account>();
Map <ID,List<OpportunityLineItem>> OLIOPPMAP = new Map <ID,List<OpportunityLineItem>> (); //create a map list of OLI with the Opportunity ID as the key, note that each opp could have more than one OLI
for(OpportunityLineItem oli: [Select o.PricebookEntryId ,o.PricebookEntry.ProductCode,OpportunityID from OpportunityLineItem o where o.OpportunityId in :Trigger.New ]){
if(OLIOPPMAP.containsKey(oli.OpportunityID)){
OLIOPPMAP.get(oli.OpportunityID).add(oli);
}else{
OLIOPPMAP.put(oli.OpportunityID,new List<OpportunityLineItem>{oli});
}
}
for (Opportunity Op :Trigger.new){
if(OLIOPPMAP.containsKey(Op.id)){
for ( OpportunityLineItem oli : OLIOPPMAP.get(Op.id) ){
String pc;
if(oli.PricebookEntry.ProductCode<>null){
pc = oli.PricebookEntry.ProductCode;
}else{
pc ='';
}
Boolean Result = pc.Contains(f);
Boolean ResultR = pc.Contains(r);
if ( (Op.StageName== 'Won' || Op.StageName=='Won - Future Activation Date' ) && Result == True ){
Account tmpAccount = ACCTMAP.get(Op.AccountID);
tmpAccount.Fit_Finder_Status__c = 'Active';
tmpAccount.Fit_Finder_Program__c='Paying - Reg Customer';
AcctSet.add(tmpAccount);
system.debug('\n\nAcctSet has' +AcctSet.size() + ' records');
}
else if ( ((Op.StageName== 'Won' || Op.StageName=='Won - Future Activation Date' ) && ResultR == True)){
Account tmpAccountR = ACCTMAP.get(Op.AccountID);
tmpAccountR.Fit_Finder_Status__c = 'Active';
tmpAccountR.Fit_Finder_Program__c='Right Track';
AcctSet.add(tmpAccountR);
system.debug('\n\nAcctSet has' +AcctSet.size() + ' records');
}
else if((Op.StageName== 'Won' || Op.StageName=='Won - Future Activation Date' ) && (ResultR == True && Result == True) ){
Account tmpAccountRF= ACCTMAP.get(Op.AccountID);
tmpAccountRF.Fit_Finder_Status__c = 'Active';
tmpAccountRF.Fit_Finder_Program__c='Right Track';
AcctSet.add(tmpAccountRF);
system.debug('\n\nAcctSet has' +AcctSet.size() + ' records');
}
}
}
}
//start Debug section 2
system.debug('\n\nAcctSet has' +AcctSet.size() + ' records');
// end Debug Section 2
updACCT.addall(AcctSet);
//start Debug section 3
system.debug('\n\nupdACCT has ' +updACCT.size() + ' records');
//updACCT should have the same number of items as AcctSET does
//end Debug Section 3
try{
update updACCT;
}catch(DMLException d){
system.debug('\n\nERROR UPDATING ACCOUNTS: '+d.getDMLMessage(0));
}
}
The only thing I can see is the Set is getting 2 accounts added to it, it must not think they are equivelant because they are coming from the map.
What you will need to do is refactor your if logic so that you only add an account to the list once, or some code to take the resulting list from your if statements and make sure there is only one unique entry for each account.
Sorry I can't offer more, but I am tied up on a project myself.
Hi Jim ,
Thanks a lot for all your help .
Thanks and Regards