function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Vida YirenkyiVida Yirenkyi 

help fix code

Ladies and Gentlemen,

Could you help fix this code please and show me where the unexpected token is please, the error Error: Invalid Data. 
Review all error messages below to correct your data.
Apex trigger LeastCompetitorPrice caused an unexpected exception, contact your administrator: LeastCompetitorPrice: execution of BeforeUpdate caused by: System.ListException: List index out of bounds: 7000: Trigger.LeastCompetitorPrice: line 36, column 1

trigger LeastCompetitorPrice on Opportunity (After insert, after update) {
    Integer highestPricePosition;
    Integer highestPrice;
    for(Opportunity opp : Trigger.new){
        //Add all our prices in a list in order of competitor
        List<Decimal> competitorPrices = new List<Decimal>();
        competitorPrices.add(opp.Competitor_1_Price__c);
        competitorPrices.add(opp.Competitor_2_Price__c);
        competitorPrices.add(opp.Competitor_3_Price__c);
        
        //Add all our competitors in a list in order
        List<String> competitors = new List<String>();
        competitors.add(opp.Competitor_1__c);
        competitors.add(opp.Competitor_2__c);
        competitors.add(opp.Competitor_3__c);
        
        //Loop through all competitors to find the position of the lowest price
        Decimal lowestPrice;
        Decimal highestPrices;
                Integer lowestPricePosition;
        for(integer i = 0; i<=competitorPrices.size(); i++){
            Decimal currentPrice = competitorPrices.get(i);
            if(lowestPrice == null || currentPrice > lowestPrice){
                  highestPrices = currentPrice;
                  lowestPricePosition = i;                
                            }
           if(highestPrices == null || currentPrice > highestPrices)
               highestPrices = currentPrice.intvalue();
                if(lowestPrice == null || currentPrice < highestPrices)
                  highestPricePosition = i;
               }
           }
        }
        //Populate the leading competitor field with the competitor
         // matching the lowest price position
         //opp.Leading_Competitor__c = competitors.get(lowestPricePosition);
         opp.Least_Competitor__c = competitorPrices.get(lowestPricePosition);
         opp.HighestPrice__c = competitorPrices.get(highestPrices.intvalue());

I am trying to insert the price of the highest competitor in the HighestPrice__c field.
Thank you
Vida



 
Best Answer chosen by Vida Yirenkyi
Anthony SpoerlAnthony Spoerl
Sorry, an important thing I missed pointing out is that your if statement on line 22 will always resolve to true, which is really the core of the problem here. With an or statement, if either check is true, the whole statement will be considered true. Breaking apart your if check the first half, 
highestPrices == null
is always true because highestPrices is never being set. Similarly, the second half, 
currentPrice > highestPrices

will always be false, for the same reason.
The simple fix for this is that you should be setting highestPrices whenever you find a highest price, so your if statement starting at line 22 should look like this altogether:

if(highestPrices == null || currentPrice > highestPrices){
    opp.HighestPrice__c = currentPrice;
    highestPrices = currentPrice;
}

Line three will set highestPrices to the price you just got from competitorPrices (and saved into currentPrice) so that the next time you do your check, you will have all the information you need.

Hope that wasn't too much information for you, best of luck!

All Answers

Anthony SpoerlAnthony Spoerl
Just at a quick glance, this line 
for(integer i = 0; i<=competitorPrices.size(); i++){

will put you out of bounds on the last run of the loop. So you could potentially be setting lowestPricePosition to an out of bounds index and causing this error.

Try changing your assertion to

i < competitorPrices.size()
Vida YirenkyiVida Yirenkyi
Thank you Anthony,

I changed it like below and and at least I am not getting the errors anymore but I still can't populate the highest  in  opp.HighestPrice__c 
Vida YirenkyiVida Yirenkyi
 Sorry forgot to paste the code:


//Loop through all competitors to find the position of the lowest price
        Decimal lowestPrice;
        Decimal highestPrices;
                Integer lowestPricePosition;
        for(integer i = 0; i<competitorPrices.size();i=10){
            Decimal currentPrice = competitorPrices.get(i);
            if(lowestPrice == null || currentPrice > lowestPrice){
                  highestPrices = currentPrice;
                  lowestPricePosition = i;

                            }
           if(highestPrices == null || currentPrice > highestPrices){
                  highestPrices = currentPrice.intvalue();
               if(lowestPrice == null || currentPrice > highestPrices)
                  highestPricePosition = i;
           }
        }
         //Populate the leading competitor field with the competitor
         // matching the lowest price position
         opp.Leading_Competitor__c = competitors.get(lowestPricePosition); 
         opp.HighestPrice__c = competitorPrices.get(highestPrices.intvalue());
    }}
Anthony SpoerlAnthony Spoerl
Do you want to set HighestPrice__c to the actual value of highestPrices? If so, you could remove the competitorPrices.get() part and just do:
opp.HighestPrice__c = highestPrices;

If you do need to get the value from your competitorPrices list for some reason, you will want to use the index of the highestPrice, not the value itself, so more like this:
 

opp.HighestPrice__c = competitorPrices.get(highestPricePosition);

Also a quick side note, you're doing the same check twice for your highest price code, you could remove the second if statement:
if(highestPrices == null || currentPrice > highestPrices){
   highestPrices = currentPrice.intvalue();
   if(lowestPrice == null || currentPrice > highestPrices)
       highestPricePosition = i;
}
--->
if(highestPrices == null || currentPrice > highestPrices){
   highestPrices = currentPrice.intvalue();
   highestPricePosition = i;
}
Vida YirenkyiVida Yirenkyi
Thank you Anthony, below is where I am now, I even managed to solve a null pointer exception!!! but code is not populating opp.HighestPrice__c field yet

trigger LeastCompetitorPrice on Opportunity (before insert, before update) {
    Integer highestPricePosition;
    Decimal highestPrices;
    for(Opportunity opp : Trigger.new){
        //Add all our prices in a list in order of competitor
        List<Decimal> competitorPrices = new List<Decimal>();
        competitorPrices.add(opp.Competitor_1_Price__c);
        competitorPrices.add(opp.Competitor_2_Price__c);
        competitorPrices.add(opp.Competitor_3_Price__c);
        
        //Add all our competitors in a list in order
        List<String> competitors = new List<String>();
        competitors.add(opp.Competitor_1__c);
        competitors.add(opp.Competitor_2__c);
        competitors.add(opp.Competitor_3__c);
        
        //Loop through all competitors to find the position of the lowest price
        Decimal lowestPrice;
       //Decimal highestPrices;
        Integer highestPricePositions;
      
        for(integer i = 0; i<competitorPrices.size();i++){
           Decimal currentPrice = competitorPrices.get(i);
           if(highestPrices == null || currentPrice > highestPrices){
                  opp.HighestPrice__c = highestPrices;
                     opp.HighestPrice__c = competitorPrices.get(highestPricePosition);
              if(lowestPrice == null || currentPrice > highestPrices)
                  highestPricePositions = i;
              
               
           }
        }
         //Populate the leading competitor field with the competitor
         // matching the lowest price position
        // opp.Leading_Competitor__c = competitors.get(lowestPricePosition); 
        
        
        
    }}
 
Vida YirenkyiVida Yirenkyi
Thank you Anthony, below is where I am now, I even managed to solve a null pointer exception!!! but code is not populating opp.HighestPrice__c field yet. I just tried to check for a response and found that, my reply has been marked as best answer. it is not, I still need help! trigger LeastCompetitorPrice on Opportunity (before insert, before update) { Integer highestPricePosition; Decimal highestPrices; for(Opportunity opp : Trigger.new){ //Add all our prices in a list in order of competitor List competitorPrices = new List(); competitorPrices.add(opp.Competitor_1_Price__c); competitorPrices.add(opp.Competitor_2_Price__c); competitorPrices.add(opp.Competitor_3_Price__c); //Add all our competitors in a list in order List competitors = new List(); competitors.add(opp.Competitor_1__c); competitors.add(opp.Competitor_2__c); competitors.add(opp.Competitor_3__c); //Loop through all competitors to find the position of the lowest price Decimal lowestPrice; //Decimal highestPrices; Integer highestPricePositions; for(integer i = 0; i highestPrices){ opp.HighestPrice__c = highestPrices; opp.HighestPrice__c = competitorPrices.get(highestPricePosition); if(lowestPrice == null || currentPrice > highestPrices) highestPricePositions = i; } } //Populate the leading competitor field with the competitor // matching the lowest price position // opp.Leading_Competitor__c = competitors.get(lowestPricePosition); }}
Anthony SpoerlAnthony Spoerl

Great! Making progress. I'm not sure why you're response would be set as accepted, you might have clicked it on accident? Before I can work some more on what is causing your issue, would you mind posting your code in a code sample block (button marked <> in the text editor bar) for me? I'm having trouble parsing your code as you posted it, when I put it in a text editor it ended up like this:

trigger LeastCompetitorPrice on Opportunity (before insert, before update) {
    Integer highestPricePosition;
    Decimal highestPrices;
    for(Opportunity opp : Trigger.new){
        //Add all our prices in a list in order of competitor
        List competitorPrices = new List();
        competitorPrices.add(opp.Competitor_1_Price__c);
        competitorPrices.add(opp.Competitor_2_Price__c);
        competitorPrices.add(opp.Competitor_3_Price__c);
        //Add all our competitors in a list in order
        List competitors = new List();
        competitors.add(opp.Competitor_1__c);
        competitors.add(opp.Competitor_2__c);
        competitors.add(opp.Competitor_3__c);
        //Loop through all competitors to find the position of the lowest price
        Decimal lowestPrice;
        //Decimal highestPrices;
        Integer highestPricePositions;
        for(integer i = 0; i highestPrices){
            opp.HighestPrice__c = highestPrices;
            opp.HighestPrice__c = competitorPrices.get(highestPricePosition);
            if(lowestPrice == null || currentPrice > highestPrices)
                highestPricePositions = i;
        }
    }
    //Populate the leading competitor field with the competitor
    // matching the lowest price position
    // opp.Leading_Competitor__c = competitors.get(lowestPricePosition); 
}

I'm guessing it's a copy/paste mistake, but the for loop on line 19 is not formatted right, and I'm having trouble figuring out what it should be doing.

Vida YirenkyiVida Yirenkyi
trigger LeastCompetitorPrice on Opportunity (before insert, before update) {
    Integer highestPricePosition;
    Decimal highestPrices;
    Decimal lowestPrice;
    for(Opportunity opp : Trigger.new){
        //Add all our prices in a list in order of competitor
        List<Decimal> competitorPrices = new List<Decimal>();
        competitorPrices.add(opp.Competitor_1_Price__c);
        competitorPrices.add(opp.Competitor_2_Price__c);
        competitorPrices.add(opp.Competitor_3_Price__c);
        
        //Add all our competitors in a list in order
        List<String> competitors = new List<String>();
        competitors.add(opp.Competitor_1__c);
        competitors.add(opp.Competitor_2__c);
        competitors.add(opp.Competitor_3__c);
        
        //Loop through all competitors to find the position of the highest price
                   
        for(integer i = 0; i<competitorPrices.size();i++){
           Decimal currentPrice = competitorPrices.get(i);
           if(highestPrices == null || currentPrice > highestPrices){
                  opp.HighestPrice__c = highestPrices;
			system.debug(highestPrices);
                     opp.HighestPrice__c = competitorPrices.get(highestPrices);
              if(lowestPrice == null || currentPrice > highestPrices)
                  highestPricePositions = i;
                             
           }
        }
         //Populate the leading highestPrice field with the highest price
         // matching the highest price position
        // opp.Leading_Competitor__c = competitors.get(highestPricePosition); 
        
        
        
    }}

Hi Anthony,

Thank you for looking into this,  for some reason I don't have the reply button only Answer .
Vida YirenkyiVida Yirenkyi
Hi Anthony, Thank you for looking into this, I have re-sent the code using
Anthony SpoerlAnthony Spoerl
Thank, that's much better. It looks like you're never actually assigning highestPrices to anything, which would make lines 23 and 25 either do nothing or cause an error. I would expect the System.Debug on line 24 to always output NULL, is this what is happening?

I believe what you intend to happen is more like this
for(integer i = 0; i<competitorPrices.size();i++){
    Decimal currentPrice = competitorPrices.get(i);
    if(highestPrices == null || currentPrice > highestPrices){
          // save currentPrice as the highest seen so far
          highestPrices = currentPrice;
          // save position of highestPrice in competitorPrices?
          highestPricePosition = i;
    }
}
// Set HighestPrice__c on Opportunity only after highest possible price is found
 opp.HighestPrice__c = highestPrices;

Because you have the decimal value of the highestPrice already, you shouldn't need to get it from the competitorPrices list again, so you should be able to remove the highestPricePosition = i; part.
Vida YirenkyiVida Yirenkyi
Hello Anthony, Thank you so much for your, much appreciated. I have replaced accordingly but for some strange reason, still not working. Best regards Vida
Vida YirenkyiVida Yirenkyi
Hi Anthony, Thank you so much for your help, it's working now. best regards Vida
Anthony SpoerlAnthony Spoerl
Sorry for not responding earlier, I've been out of town for a few days. Glad to hear it's working though!
Vida YirenkyiVida Yirenkyi
Thank you for the response Anthony, I really appreciate your explanations. the code is populating opp.HighestPrice__c but, you know there's always a but, the loop seems stuck on competitorPrices.add(opp.Competitor_3_Price__c); because even when I update the field with the lowest price, that is the value it picks up. Could you help me get to the bottom of this please. Many thanks Vida
Anthony SpoerlAnthony Spoerl

Haha, no worries. Programming is a game of patience. I hate to keep asking this, but would you mind posting the code as you have it now again? I just want to make sure I'm on the same page.

You mean that HighestPrice__c is always picking up the price from opp.Competitor_3_Price__c, correct? That would lead me to believe that either an if statement or your competitorPrices list is wrong. Maybe try doing a system.debug(competitorPrices) before your for loop on line 20 and see what you get.

Vida YirenkyiVida Yirenkyi
Thank you Anthony, code not working properly can easily ruin a whole week!! and I must understand these things. Its my objective this year.
trigger LeastCompetitorPrice on Opportunity (before insert, before update) {
    Integer highestPricePosition;
    Decimal highestPrices;
    Decimal lowestPrice;
    for(Opportunity opp : Trigger.new){
        //Add all our prices in a list in order of competitor
        List<Decimal> competitorPrices = new List<Decimal>();
        competitorPrices.add(opp.Competitor_1_Price__c);
        competitorPrices.add(opp.Competitor_2_Price__c);
        competitorPrices.add(opp.Competitor_3_Price__c);
        
        //Add all our competitors in a list in order
        List<String> competitors = new List<String>();
        competitors.add(opp.Competitor_1__c);
        competitors.add(opp.Competitor_2__c);
        competitors.add(opp.Competitor_3__c);
        
        //Loop through all competitors to find the position of the highest price
                   
        for(integer i = 0; i<competitorPrices.size();i++){
           Decimal currentPrice = competitorPrices.get(i);
           if(highestPrices == null || currentPrice > highestPrices){
                  //opp.HighestPrice__c = highestPrices;
		    opp.HighestPrice__c = competitorPrices.get(i);
              if(lowestPrice == null || currentPrice >= highestPrices)
                  highestPricePosition = i;
                             
           }
        }
         //Populate the leading highestPrice field with the highest price
         // matching the highest price position
       //opp.HighestPrice__c = competitorPrices.get(highestPrices); 
        
        
        
    }}


 
Vida YirenkyiVida Yirenkyi
Yes it's always picking from opp.Competitor_3_Price__c
Anthony SpoerlAnthony Spoerl

Ah, okay I believe I see what is happening, I'll try to explain the problem in this post first and then walk you through a solution, if you need any more clarification on anything, just let me know, I'm not sure how great I am explaining some of these concepts.

So, your competitorPrices is a list of three numbers, let's say it looks like this: [100.00, 200.00, 150.00] this list is indexed from 0 - 2, so doing a competitorPrices.get(0) will give you 100.00, competitorPrices.get(1) will give 200.00, etc. For your example, 100.00 would be equal to opp.Competitor_1_Price__c, and so on.

When your for loop is iterating over each index, you are performing this statement

opp.HighestPrice__c = competitorPrices.get(i);
This means that for every loop will be setting opp.HighestPrice__c to the value from competitorPrices. Since i = 2 will always be the last loop you hit, your HighestPrice__c will always end up with competitorPrices.get(2), which happens to be where opp.Competitor_2_Price__c is saved.
Anthony SpoerlAnthony Spoerl
Sorry, an important thing I missed pointing out is that your if statement on line 22 will always resolve to true, which is really the core of the problem here. With an or statement, if either check is true, the whole statement will be considered true. Breaking apart your if check the first half, 
highestPrices == null
is always true because highestPrices is never being set. Similarly, the second half, 
currentPrice > highestPrices

will always be false, for the same reason.
The simple fix for this is that you should be setting highestPrices whenever you find a highest price, so your if statement starting at line 22 should look like this altogether:

if(highestPrices == null || currentPrice > highestPrices){
    opp.HighestPrice__c = currentPrice;
    highestPrices = currentPrice;
}

Line three will set highestPrices to the price you just got from competitorPrices (and saved into currentPrice) so that the next time you do your check, you will have all the information you need.

Hope that wasn't too much information for you, best of luck!
This was selected as the best answer
Vida YirenkyiVida Yirenkyi
Thank you so much Anthony, all that detail is exactly what I need!!! It's working perfectly now.  I have printed the explanation for my revision, it makes sense. I'll carry on practicing and I'll be back when I get stuck again so do look out for me.

Best regards

Vida  
Vida YirenkyiVida Yirenkyi
Good day all,
Please help fix this formula
Case(
    (ISPICKVAL($User.Sales_Team__c, "Investment Sales", 'Investment Sales'),
    (ISPICKVAL($User.Sales_Team__c, "Wealth", 'Wealth'),
    (ISPICKVAL($User.Sales_Team__c, "EMEA", 'EMEA'),
    (ISPICKVAL($User.Sales_Team__c, "Strategic Alliance", 'Strategic Alliance'),
    (ISPICKVAL($User.Sales_Team__c, "Key Account", 'Key Account'),
    (ISPICKVAL($User.Sales_Team__c, "Property", 'Property'),
    (ISPICKVAL($User.Sales_Team__c, "Sales Support", 'Sales Support', 0))

))))))))

thanks