+ Start a Discussion
ColealarsColealars 

Trying to update multiple fields on OpportunityLineItem record from Product2

I’m trying to update fields on the OpportunityLineItem record from fields on Product2.  Am I supposed to be using a multidimensional map to accomplish this task?  If so,  can someone get me started?  If not, can you get me on the right path?  See code below.

trigger oppLineItem_prod_data_trigger2 on OpportunityLineItem (before insert, before update) { Set<String> opportunityLineItemIDs = new Set<String>(); //We create a list for all opportunityLineItem records we will ultimately update to //enable us to perfoirm a single bulk update List<OpportunityLineItem> updtOpportunityLineItems = new List<OpportunityLineItem>(); //We loop through the updated records to get the Id, and add it to the set for(OpportunityLineItem oli : trigger.new) { if(!opportunityLineItemIDs.contains(oli.Id)) { opportunityLineItemIDs.add(oli.Id); } //This is our holding list for opportunityLineItem and the associated Product2 attributes OpportunityLineItem[] opportunityLineItems = new List<OpportunityLineItem>(); //We can now add the product2 attributes to the opportunityLineItems list created right above opportunityLineItems = [SELECT pricebookentry.product2.sbu_abbr__c, pricebookentry.product2.bu_abbr__c FROM OpportunityLineItem ]; //Old code //[Select Id, product2.sbu_abbr__c, product2.bu_abbr__c //From PricebookEntry //where id in '01u30000000M4EcAAK']; Map<Id, OpportunityLineItem []> oliProdAttributes = new Map<Id, OpportunityLineItem[]>(); //Old code //Place the data from the query into the map // Now use the map to set the appropriate attribute on every OpportunityLineItem processed by the trigger. //for (OpportunityLineItem oli : Trigger.new){ // oli.bu_abbr__c = entries.get(oli.pricebookEntryId).product2.bu_abbr__c; // oli.sbu_abbr__c = entries.get(oli.pricebookEntryId).product2.sbu_abbr__c; } for (OpportunityLineItem o :opportunityLineItems) { oliProdAttributes.put(o.Id, o.sbu_abbr__c, o.bu_abbr__c); } //Once we have updated the opportunityLineItem based on the data in Product2, we add it to //the opportunityLineItems list we created at the beginning updtOpportunityLineItems.add(oli); } //Once the account for loop has finished, we execute once single update of OpportunityLineItem update updtOpportunityLineItems; }

 

ThomasTTThomasTT

Hum... I didn't think anybody else was doing this... copying fields from Product2 to OpporutnityItem... OpportunityLineItem.PriceBookEntry.Product2.TheField__c seemed good enought to me... anyway,

 

If this is after insert/update,

 

 

OpportunityLineItem[] oliList = [select sbu_abbr__c, bu_abbr__c, pricebookentry.product2.sbu_abbr__c, pricebookentry.product2.bu_abbr__c FROM OpportunityLineItem where id in :opportunityLineItemIDs];

for(OpportunityLineItem oli : oliList) {
oli.sbu_addr__c = oli.pricebookentry.product2.sbu_abbr__c;

oli.bu_abbr__c = oli.pricebookentry.product2.bu_abbr__c;
}

update oliList;

 

 is enought. If it's before insert/update, you want to put the value in the Trigger.new[i] and you want to avoid governor limit, then you just cache PriceBookEntry Objects (Trigger.new doesn't have related object infromation (just the foreign key), so I don't think you can get PriceBookEntry.Product2Id without your own query).

 

Set<Id> idSetPBE = new Set<Id>();
for(OpportunityLineItem oli : trigger.new) {
if(oli.PriceBookEntryId != null){
idSetPBE.add(oli.PriceBookEntryId);
}
}

Map<id, PriceBookEntry> pbeMap = new Map<id, PriceBookEntry>([
SELECT
id, Product2.id, Product2.bu_abbr__c, Product2.sbu_abbr__c
FROM
PriceBookEntry
WHERE
id in :idSetPBE
]);

for(OpportunityLineItem oli : trigger.new) {
if(pbeMap.containsKey(oli.PriceBookEntryId)){
oli.bu_addr__c = pbeMap.get(oli.PriceBookEntryId).Product2.bu_addr__c;
oli.sbu_addr__c = pbeMap.get(oli.PriceBookEntryId).Product2.sbu_addr__c;
}
}

 

Is there such a thing as "multiple dimension Map"? I wish there could be... 

 

ThomasTT

Message Edited by ThomasTT on 09-26-2009 09:27 AM