I am updating a large amount of opportunity line items. We have a margin text field and when our costs for the product changes, we need this text field to change. We have a formula field but we have to see the margin when in multi line edit. The issue that I am having is that there are summary fields on Account from Opps and Opps from Opp line items. So when I do the update, the account is locked from the latest update. Although the summary field amount is not changing, I suppose there is a process to double check and lock the record. Does anyone know how to get around this. I am posting my code below.
I have read the previous posts to the same question and For Update does not work even if I use for accounts.
Trigger:
trigger MasterProductTrigger on Product2 (
before insert, after insert,
before update, after update,
before delete, after delete) {
if (Trigger.isBefore) {
if (Trigger.isInsert) {
}
if (Trigger.isUpdate) {
}
if (Trigger.isDelete) {
// Call class logic here!
}
}
if (Trigger.IsAfter) {
if (Trigger.isInsert) {
}
if (Trigger.isUpdate) {
ProductChanges checker =
new ProductChanges(Trigger.oldMap, Trigger.newMap);
checker.LandingCostChange();
if(TriggerContextUtility.isFirstRun()){
}
}
if (Trigger.isDelete) {
// Call class logic here!
}
}
}
Helpers:
public class ProductChanges{
// These variables store Trigger.oldMap and Trigger.newMap
Map<Id, Product2> oldProds;
Map<Id, Product2> newProds;
List<Product2> acctsToUpdate = new List<Product2>();
// This is the constructor
// A map of the old and new records is expected as inputs
public ProductChanges(Map<Id, Product2> oldTriggerProds, Map<Id, Product2> newTriggerProds) {
oldProds = oldTriggerProds;
newProds = newTriggerProds;
}
// The one method your master trigger will call
public void LandingCostChange() {
//get a new list of products that the landing costs have changed
List<Product2> plandchange = new List<Product2>();
for(Product2 p : newProds.values()){
Product2 o = oldProds.get(p.Id);
if(o.Cost__c != p.Cost__c && p.IsActive == true){
plandchange.add(p);
}
}
//send product list to future method so that the oppline items that need changed will be changed.
String jsonString = json.serialize(plandchange);
ProductLandingCosts.UpdateOppLines(jsonString);
}
}
global class ProductLandingCosts{
@future
public static void UpdateOppLines(String jsonString) {
//set list for the products that landing costs had a change
List<Product2> prods =
(List<Product2>)Json.deserialize(jsonString,List<Product2>.class);
//query all the oppline items that have matching products. and sort by
//account and then opportuntity to avoid
//lock records issue
List<OpportunityLineItem> lines = [Select Id,OpportunityId,
Opportunity.AccountId,Margin__c,MarginText__c,
Landing_Cost2__c,Product2Id, Product2.Cost__c from
OpportunityLineItem where Product2Id In: prods
ORDER BY Opportunity.AccountId,OpportunityId ];
//set a list for update
List<OpportunityLineItem> lineitems = new List<OpportunityLineItem>();
line.MarginText__c = String.valueOf(line.Margin__c)+'%';
Line.Landing_Cost2__c = Line.Product2.Cost__c;
lineitems.add(Line);
}
TriggerContextUtility.setFirstRunFalse();
update lineitems;
}