function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
shyam Sundar 101shyam Sundar 101 

Help me on trigger

When opportunity is closed won and based on the quantity which i give in opportunity line item .. The customer field QtyOnHand__c in Product2 should get changed with the amount of quantity which i select... 


trigger RemainingQuant on OpportunityLineItem (after insert,before update) {

    set<id> PIds = new set<id>();
    set<id> Oids = new set<id>();
   for(OpportunityLineItem opli : Trigger.new){
       PIds.add(opli.Product2Id);
   }
     list<Product2> pList = [select id, name , QtyOnHand__c from Product2 where Id IN : PIds];  
     list<Opportunity> olist = [select id, name, StageName from Opportunity where Id IN : Oids]; 
     for(Opportunity o : olist){
     for(Product2 p : pList){
      
         for(OpportunityLineItem op : Trigger.new){
             if(p.id == op.product2Id && op.OpportunityId== o.id){
             if(o.StageName == 'Closed Won'){
               
                 if(Trigger.isInsert){
                     if(op.Quantity > p.QtyOnHand__c){
                         op.Quantity.addError(' no availability of stock in Product ');
                     }
                     }
                 
                    p.QtyOnHand__c-= op.Quantity;
                 

                
}                 
                 if(Trigger.isUpdate){
                                     
                     p.QtyOnHand__c += (Trigger.oldMap.get(op.Id).Quantity).intValue();
                        
                     if(op.Quantity > p.QtyOnHand__c){
                         op.addError(' no availability of stock in Product ');
                     } 
                     p.QtyOnHand__c-=op.Quantity;
                     
                 }
             }
             
       }
    }
    update pList;
  
}
}
Ajay K DubediAjay K Dubedi
Hi Shyam,
Here you need to write a trigger on Opportunity when the opportunity is updated.  
Try this Trigger and handler class:

Trigger:
trigger OpportunityTrigger on Opportunity (before Update) {
    if(trigger.IsUpdate && trigger.IsBefore) {
        OpportunityTrigger_handler.checkStage(trigger.new, trigger.oldMap);
    }
}



Handler:
public class OpportunityTrigger_handler {
    public static void checkStage(List<Opportunity> oppList, Map<Id, Opportunity>OppOldMap) {
        try {
            Set<Id> opIdSet = new Set<Id>();
            Set<Id> productIdSet = new Set<Id>();
            List<Product2> prodListToUpdate = new List<Product2>();
            Map<Id, Id> prodIdVsOLIIdMap = new Map<Id, Id>();
            for(Opportunity op : oppList) {
                if(op.StageName == 'Closed Won' && OppOldMap.get(op.Id).StageName != 'Closed Won' && op.HasOpportunityLineItem) {
                    opIdSet.add(op.Id);
                }
            }
            if(opIdSet.size() > 0) {
                Map<Id, OpportunityLineItem> oliMap = new Map<Id, OpportunityLineItem>([SELECT Id, Quantity, Product2Id FROM OpportunityLineItem WHERE OpportunityId IN : opIdSet AND Quantity != null]);
                for(OpportunityLineItem oli : oliMap.values()) {
                    productIdSet.add(oli.Product2Id);
                }
                if(productIdSet.size() > 0) {
                    prodListToUpdate = [SELECT Id, QtyOnHand__c FROM Product2 WHERE Id IN : productIdSet];
                }
                
                if(oliMap.size() > 0) {
                    for(Id i : oliMap.Keyset()) {
                        if(!prodIdVsOLIIdMap.containsKey(oliMap.get(i).Product2Id)) {
                            prodIdVsOLIIdMap.put(oliMap.get(i).Product2Id, i);
                        }
                    }
                }
                if(prodIdVsOLIIdMap.size() > 0 && prodListToUpdate.size() > 0) {
                    for(Product2 pord : prodListToUpdate) {
                        if(prodIdVsOLIIdMap.containsKey(pord.Id)) {
                            if(pord.QtyOnHand__c != null) {
                                pord.QtyOnHand__c = pord.QtyOnHand__c + oliMap.get(prodIdVsOLIIdMap.get(pord.Id)).Quantity;
                            }
                            else {
                                pord.QtyOnHand__c = oliMap.get(prodIdVsOLIIdMap.get(pord.Id)).Quantity;
                            }
                        }
                    }
                    update prodListToUpdate;
                }
            }
        } catch (Exception e) {
            System.debug('Get Exception on line number  --------' +
                         e.getLineNumber() + ' due to following ' +e.getMessage());
        }
    }
}


I hope you find the above solution helpful. If it does, please mark as Best Answer to help others too.
Thanks,
Ajay Dubedi
 
shyam Sundar 101shyam Sundar 101
Hi Ajay,

Thanks for the reply but it work Opposite. If closed won the Quantity is getting added with the QtyOnhand__c..

Any one help me If the stage is closed lost I have to update with the previous value if the QtyOnHand__c field in product2
 
Ajay K DubediAjay K Dubedi
Hi Shyam,
Can you please explain what is exactly your requirement.
If you want to do the same with when the opportunity Stage is Closed Lost, You have to change the condition in line number 9 in the handler class as:
if(op.StageName == 'Closed Lost' && OppOldMap.get(op.Id).StageName != 'Closed Lost'&& op.HasOpportunityLineItem)

Thanks,
Ajay Dubedi
shyam Sundar 101shyam Sundar 101
Its working good ji . As you said if i change the line 9 it is working good ..But i need what is like once i choose the quantity in OPPORTUNITY LINE ITEM. It has to get reduced and once it is closed won good no issues. But if incase Closed Lost again the QtyOnHand__c has to get added with the available number of value which i chose in Opportunity Line item
shyam Sundar 101shyam Sundar 101
Hi Ajay,

Kindly have a look. 
Thanks.
Ajay K DubediAjay K Dubedi
Hi Shyam,
So in this case when the Opportunity is 'Closed Lost' then the number of quantity of Opportunity line item is added with the related Product QtyOnHand__c field.
As per your requirement, you need to write two triggers. 1st one is for Opportunity line item when the OpportunityLineItem is inserted and 2nd one is for Opportunity when the Opportunity is updated as it's stage is 'Closed Lost'.
Thanks,
Ajay Dubedi