Find your content:

Search form

You are here

How to iterate over all Opptys and their line items- in bulk with map?

 
Share

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 ?


Attribution to: Saariko

Possible Suggestion/Solution #1

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);
                    ....       
                }
            ....
        }

Attribution to: Guy Clairbois

Possible Suggestion/Solution #2

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.


Attribution to: highfive
This content is remixed from stackoverflow or stackexchange. Please visit https://salesforce.stackexchange.com/questions/30435

My Block Status

My Block Content