I have a button that needs to make several webservice callouts and then use the resulting data to upsert a collection of OpportunityLineItems.
For each OpportuntiyLineItem there is also a collection of custom sObjects that also need to be upserted. Each of these custom objects has a field that contains the parent OpportunityLineItem id.
Due to the callouts I'm building up a list of OpportuntiyLineItems and a separate structure that maps from the OpportuntiyLineItem to the child custom sObjects.
The challenge in the separate structure is how to track the relationship between the OLIs and related custom sObjects when the OLI may not have an ID yet. A Map from the OpportunityLineItem.Id to a list of custom objects works fine for existing OLI, but doesn't help with new OLIs.
These isn't currently another unique field I can use to identify the OLI.
The core steps involved:
- SOQL to find the existing OLIs
- Web service callout to pull the data to update/create OLIs with
- Create a list of OLIs, either update an existing found OLI, or add a new OLI.
- SOQL to find the existing custom objects for existing OLIs
- Second web service callout to pull the data to update/create the child sObject
- Create a list of secondary sObjects to update/create for each OLI.
Here I need to maintain a relationship with the OLI to set the custom secondary object after the OLI has been inserted. - No more web service callouts can occur after the first upsert.
- Upsert List of OLIs
- For each OLI, set the OLI Id on each custom sObject.
- Combine all the custom sObject lists and Upsert complete list
Example data:
- New OLI 1
- New Custom sObject 4
- New Custom sObject 5
- New OLI 2
- New Custom sObject 6
- New OLI 3
- New Custom sObject 7
- New Custom sObject 8
With this data the first upsert would insert OLIs 1, 2, and 3. I then need to set the OLI.Id field:
- on custom sObjects 4 and 5 to the Id of OLI 1
- on custom sObject 6 to the Id of OLI 2
- on custom sObjects 7 and 8 to the Id of OLI 3
I'd initially tried using a Map keyed with the OpportunityLineItem, but that failed badly when any of the OLI fields were changed after it was added to the Map. The hash of the sObject changes and it can no longer be found in the Map keyset.
How can I keep track of the new OpportunityLineItems before and after insert so I can then insert related records?