0

While in a trigger, I want to iterate over all Opportunities (opptys) and their related OpportunityLineItems (olis). This is the pseudo code I use, and problem I face is how do I iterate over all the olis, while already looping in the oppty FOR loop

 //prepare the list of oppties ids
   Id[] oppids = new Id[]{};
   for(Opportunity opp : Trigger.new) {
   oppids.add(opp.Id);
   }

Now to create a map of all the opptys and their olis: I am not sure this is correct map, or should it be opportunitylineitem object.

 map<id, Opportunity> opptys = new Map<ID, Opportunity>([SELECT Id, (SELECT id, 
         Discount, listprice, name, 
         opportunityid, Product2Id, unitprice, 
         Quantity,totalprice FROM opportunityLineItems) FROM Opportunity WHERE Id in :oppids]);

This is the FOR loop

for(Opportunity opp : Trigger.new) {

And while in the loop, I want to go over all the olis.

Current code is:

for ( OpportunityLineItem oli : opptys.get(opp.Id) )
        {
            .....
            jsGen.writeNumberField('ListPrice', oli.ListPrice);
            ....
        }

which throws an error that

Loop must iterate over a collection type: SOBJECT:Opportunity

Which is understood, as I have a map of opptys.

However, if I change the for to be of opptys:

for ( Opportunity oli : opptys.get(opp.Id) )
        {
            .....
            jsGen.writeNumberField('ListPrice', oli.ListPrice);
            ....
        }

The error is (and correct) that ListPrice is NOT a field in Opportunity - which is true. But ListPrice field is in the MAP (the select has this field)

Also, the smarttext shows ListPrice - as of OpportunityLineItemField

enter image description here

So My Loops/For/Maps are misplaced somewhere, how do I iterate over them ?

2

Since opportunityLineItems is a level 'deeper' then opportunity, you need to do an inner loop through the opportunityLineItems of the Opportunity that your have picked from the map:

for ( Opportunity o : opptys.get(opp.Id) )
        {

            for ( OpportunityLineItem oli : o.OpportunityLineItems) )
                {
                    .....
                    jsGen.writeNumberField('ListPrice', oli.ListPrice);
                    ....       
                }
            ....
        }
0

You no need to have a map to maintain it. Just go one level down and have the child objects

for(Opportunity opp : Trigger.new) {
    for(OpportunityLineItem oli : opp.OpportunityLineItems){
        //do stuff
    }
}

You may need to check the correct relationship name in the WSDL.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.