1

I need to write a process to handle the following:

  1. Retrieve all price book entries for the standard price book
  2. Retrieve all price book entries for non-standard price books that have a matching product2Id in the above list (1).
  3. For each non-standard entry in (2), update values on the object to match those with its corresponding match in list (1). Then set a custom Is_Synchornsied__c boolean value on the associated non-standard price book to true.

Ive had a few attempts at this and my most recent is getting an APEX CPU time limit exception. Could anyone assist me me with the most efficient way to achieve the above please.

What i have so far:

 //get standard price book
   pricebook2 SPB = [SELECT Id FROM Pricebook2 WHERE IsActive = true AND 
IsStandard = true]; 
   String SPBId = SPB.Id;

   //get book entries for the standard price book
   List<pricebookEntry> StandardPBEntries = [SELECT Id, Name, Pricebook2Id,
                                        Product2Id, UnitPrice, UseStandardPrice, 
                                        ProductCode,Is_Negotiated__c 
                                        FROM PricebookEntry WHERE priceBook2Id = :SPBId];  

   //prep list of entries for final update at end outside of any loop;
   List<pricebookEntry> listForEntryUpdate = new List<pricebookEntry>();
   List<pricebook2> listForBookUpdate = new List<pricebook2>();

//create list of standard entry Product2Id's 
Set<Id> product2IdsSet = new Set<Id>();
for(pricebookEntry StandardEntry : StandardPBEntries){            
   product2IdsSet.add(StandardEntry.Product2Id);                
}

//look for matches
List<pricebookEntry> Matches = [SELECT Id, Name, Pricebook2Id, Product2Id, IsActive, Is_Negotiated__c FROM PricebookEntry 
                                        where product2id IN: product2IdsSet and isactive = true and Is_Negotiated__c = false
                                        AND priceBook2Id IN (SELECT Id FROM Pricebook2 WHERE IsActive = true AND IsStandard = false 
                                        and Is_Syncronised__c = false)];

//for each match update values based on the standard entry with the same product2Id
        for(pricebookEntry aMatch : Matches){                                                             
                      for(pricebookEntry standard : StandardPBEntries){ 
                            If(standard.product2Id == aMatch.product2Id){
                             aMatch.UnitPrice = standard.Unitprice;
                             aMatch.UseStandardPrice = standard.UseStandardPrice;                                                
                            }

                     // aMatch.pricebook2.Is_Syncronised__c = true; 
                     // listForEntryUpdate.add(aMatch); 
                     // listForBookUpdate.add(aMatch.pricebook2);   
                      }                                             
        }        
1
  • Just an FYI, I have since added a break in the inner for when a match is found to improve it slightly but im sure theres still a better way.
    – AndrewG
    Jul 7, 2017 at 9:28

1 Answer 1

0

Hope this should help you to a good extent, otherwise for really a huge number of records processing through Batch would require:

//get standard price book

pricebook2 SPB = [SELECT Id FROM Pricebook2 WHERE IsActive = true AND IsStandard = true]; String SPBId = SPB.Id;

//get book entries for the standard price book

List StandardPBEntries = [SELECT Id, Name, Pricebook2Id, Product2Id, UnitPrice, UseStandardPrice, ProductCode,Is_Negotiated__c FROM PricebookEntry WHERE priceBook2Id = :SPBId];

//prep list of entries for final update at end outside of any loop;

List listForEntryUpdate = new List(); List listForBookUpdate = new List();

//create list of standard entry Product2Id's

Map product2IdPBEMap = new Map();

for(PricebookEntry StandardEntry : StandardPBEntries){
product2IdPBEMap.put(StandardEntry.Product2Id, StandardEntry);
}

//look for matches

List Matches = [SELECT Id, Name, Pricebook2Id, Product2Id, IsActive, Is_Negotiated__c FROM PricebookEntry where product2id IN: product2IdPBEMap.keySet() and isactive = true and Is_Negotiated__c = false AND priceBook2Id IN (SELECT Id FROM Pricebook2 WHERE IsActive = true AND IsStandard = false and Is_Syncronised__c = false)];

//for each match update values based on the standard entry with the same product2Id

for(pricebookEntry aMatch : Matches){
PricebookEntry standardPBEMatch = product2IdPBEMap.get(aMatch.Product2Id); aMatch.UnitPrice = standardPBEMatch.Unitprice; aMatch.UseStandardPrice = standardPBEMatch.UseStandardPrice;
aMatch.pricebook2.Is_Syncronised__c = true; listForEntryUpdate.add(aMatch); listForBookUpdate.add(aMatch.pricebook2);
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .