You need to sign in to do that
Don't have an account?
Gabe Rothman 8
Need help mapping productId to pricebookentryid
Hey all,
I'm working a bit of code to automatically re-add products to an opportunity if they get deleted as a result of the user changing the pricebook. I experimented with trying to clone the OLIs in a beforeDelete trigger, but couldn't get that work, I assume becuase updating the pricebook deleted the newly created clones in addition to the old products.
Instead I've built a custom object called OLI_Clone__c for which records are inserted every time a new OLI is added to an oppty and then deleted later when the oppty goes to closed won or closed lost. Basically, when the pricebook updates on the oppty, the code queries back to the OLI_Clone__c records associated with the oppty and then uses the data stored there to recreate the OLIs. The biggest challenge is that I can't create a lookup to ProcebookEntry on a custom object so I had to create a lookup to Product and then use a combination of the Opportunity's new Pricebook Id and the OLI_Clone__c's product Id to query for the correct PricebookEntry.
I've been able to get a list of PricebookEntryIds, but I can't figure out how get the correct PricebookEntryId for each OLI_Clone__c without querying for it inside of my for loop, which is obviously a big no no. I do know that I should be using a map, but I am relatively novice coder, and I just can't seem to get the syntax right.
Thanks in advance for your help!
I've pasted my service class below with a few comments:
I'm working a bit of code to automatically re-add products to an opportunity if they get deleted as a result of the user changing the pricebook. I experimented with trying to clone the OLIs in a beforeDelete trigger, but couldn't get that work, I assume becuase updating the pricebook deleted the newly created clones in addition to the old products.
Instead I've built a custom object called OLI_Clone__c for which records are inserted every time a new OLI is added to an oppty and then deleted later when the oppty goes to closed won or closed lost. Basically, when the pricebook updates on the oppty, the code queries back to the OLI_Clone__c records associated with the oppty and then uses the data stored there to recreate the OLIs. The biggest challenge is that I can't create a lookup to ProcebookEntry on a custom object so I had to create a lookup to Product and then use a combination of the Opportunity's new Pricebook Id and the OLI_Clone__c's product Id to query for the correct PricebookEntry.
I've been able to get a list of PricebookEntryIds, but I can't figure out how get the correct PricebookEntryId for each OLI_Clone__c without querying for it inside of my for loop, which is obviously a big no no. I do know that I should be using a map, but I am relatively novice coder, and I just can't seem to get the syntax right.
Thanks in advance for your help!
I've pasted my service class below with a few comments:
public with sharing class autoAddProductsAfterPBChange { //create a filter to listen for a change in the pricebook below public static list<opportunity> filterOpp(map<id, opportunity> oldMap, list<opportunity> newList) { list<opportunity> temp=new list<opportunity>(); for (opportunity newOpp : newList){ if (oldMap.get(newOpp.id).PriceBook2Id != newOpp.PriceBook2Id){ temp.add(newOpp); } } return temp; } //find the pricebook entries and recreate the OLIs public static void autoAdd(list<Opportunity> opps){ Opportunity opp = new Opportunity(); Pricebook2 pb = new Pricebook2(); for(Opportunity opp2 : opps){ opp.id = opp2.Id; pb.id = opp2.Pricebook2Id; } list<OLI_Clone__c> olics = [SELECT Quantity__c, Additional_Discount_off_List__c, Manual_Discount__c, Opportunity__c, Product__c, Sales_Price__c, Service_Term_in_Months__c FROM OLI_Clone__c WHERE Opportunity__c =: opp.id]; list<Id> prodids = new list<Id>(); for(OLI_Clone__c olicprod : olics){ prodids.add(olicprod.Product__c); } List<PricebookEntry>pbeids = [SELECT Id, Product2Id FROM PricebookEntry WHERE Product2Id in: prodids AND Pricebook2Id =: pb.id]; Map<Id, PricebookEntry> pbeMap = new Map<Id, PricebookEntry>(pbeids); // Is this map correct? list<OpportunityLineItem>toInsert = new list<OpportunityLineItem>(); for(OLI_Clone__c olic : olics){ if(pbeMap.containsKey(olic.Product__c)){ OpportunityLineItem oli = new OpportunityLineItem(); PricebookEntry pbe = pbeMap.get(); // I know I need to be "getting" something here but I'm not sure how to structure the syntax, and I'm not sure that my map above is configured correctly either. Basically I need to get the correct PricebookEntryId based on the Product__c field on the OLI_Clone__c in this loop and the parent Opportunity's pricebook. oli.Quantity = olic.Quantity__c; oli.UnitPrice = olic.Sales_Price__c; toInsert.add(oli); } } insert toInsert; } }
All Answers