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
Lukesh KarmoreLukesh Karmore 

help me with this trigger below

i m writing trigger, created custom field  on product object  Total Quantity and Available Quantity .
i have to fill Available Quantity field when opportunityLineItem is Created
code is successfully deployed but not update  Available Quantity field

trigger AvailableQuantityonProductTrigger on OpportunityLineitem (after insert) {
    integer remainingQuantity=0;
    set<id> oliIds=new set<id>();
for(OpportunityLineitem o:Trigger.new){
    if(o.Quantity!=null){
    oliIds.add(o.id);
    }
 }
 list<OpportunityLineitem> oliList=[SELECT id,Quantity,Product2.Name,Product2.Total_Quantity__c,
 Product2.Available_Quantity__c FROM OpportunityLineitem WHERE id IN:oliIds];
 for(OpportunityLineitem oli:oliList){
    if(oli.Quantity!=null){
         remainingQuantity=integer.valueOf(oli.Product2.Total_Quantity__c) - integer.valueOf(oli.Quantity);
     }
     else{
         remainingQuantity=0;  
     }
     if(remainingQuantity!=null){
     oli.Product2.Available_Quantity__c=integer.valueOf(remainingQuantity);
     }
}
update oliList;
}
Thank you
Suraj Tripathi 47Suraj Tripathi 47
Hi Lukesh,

Check this code it may help you. 
//Class
public class UpdateProductSold {
    public static void countsoldproduct(map<id,opportunity> oppmap)
    {
        try
        {
            List<opportunitylineitem> oli=new List<opportunitylineitem>();
            set<id> pid=new set<id>();
            
            
            oli=[select product2id,opportunityid,quantity from opportunitylineitem where opportunityid IN:oppmap.keySet()];
            
            for(opportunitylineitem op:oli)
            {
                pid.add(op.product2id);
            }
            
            map<id,product2> productmap=new map<id,product2>([select id,Numberofproductsold__c from product2 where Id IN:pid]);
            System.debug(productmap);
            
            for(opportunitylineitem obj:oli)
            {
                if(oppmap.get(obj.opportunityid).stageName=='closed Won')
                {
                    
                    productmap.get(obj.product2id).Numberofproductsold__c=productmap.get(obj.product2id).Numberofproductsold__c+obj.Quantity;
                }
            }
            
            System.debug(productmap);
            
            List<product2> prolist=new List<product2>();
            for(id eachid:productmap.keySet())
            {
                product2 p_obj=new product2();
                p_obj.Id=eachid;
                p_obj.Numberofproductsold__c=productmap.get(eachid).Numberofproductsold__c;
                
                prolist.add(p_obj);
                
            }
            System.debug(prolist);
            update prolist;
            
            
        }
        catch(Exception e)
        {
            System.debug('Exception due to---> : '+e.getMessage()+' ---> :  '+e.getLineNumber()+'---->: '+e.getCause());
        }
    }
    
}
//Trigger
trigger UpdateSoldProduct on Opportunity (after insert,after update) {
   
            UpdateProductSold.countsoldproduct(trigger.newMap);
    
   

}
If you find your Solution then mark this as the best answer. 

Thank you!

Regards 
Suraj Tripathi
Olivier Van den NestOlivier Van den Nest
Hi Lukesh,

I see what you try to do: you want to update the OLIs using 'update oliList'. However you need to update the products, not the OLIs.
So something like this:

List<OpportunityLineItem> oliList = [SELECT Id, Product2, Quantity FROM OpportunityLineItem WHERE Id IN :oliIds];

Set<Id> productIds = new Set<Id>();
Map<Id, Integer> productIdToOLIQuantityMap = new Map<Id, Integer>();

for(OpportunityLineItem o : oliList) {
productIds.add(o.Product2);
productIdToOLIQuantityMap.put(o.Product2, o.Quantity);
}

List<Product2> products = [SELECT Id, Available_Quantity__c, Total_Quantity__c FROM Product2 WHERE Id IN :productIds];

for(Product2 p : products) {
p.Available_Quantity__c = p.Total_Quantity__c - productIdToOLIQuantityMap.get(p.Id);
}

update products;

Make sure to mark as best answer if it helps you :)
Vijay NagellaVijay Nagella
Hi Lukesh,

Please find the Working Code.
 
trigger AvailableQuantityonProduct on OpportunityLineItem (after insert) {
    
    Map<Id,decimal> oliMap = new Map<Id,decimal>();
    
    for(OpportunityLineItem oli : Trigger.new){
        if(oli.Product2Id != Null && oli.Quantity != Null){
            oliMap.put(oli.Product2Id,oli.Quantity);
        }
    }
    
    List<Product2> Products = [SELECT Id,Name,Available_Quantity__c,Total_Quantity__c FROM Product2 WHERE Id IN :oliMap.keySet()];
    
    for(Product2 prod : Products){
        
        if(prod.Total_Quantity__c == prod.Available_Quantity__c){
            prod.Available_Quantity__c = integer.valueOf(prod.Total_Quantity__c) - integer.valueOf(oliMap.get(prod.id));
        }
        else if (prod.Available_Quantity__c > integer.valueOf(oliMap.get(prod.id))) {
            prod.Available_Quantity__c = integer.valueOf(prod.Available_Quantity__c) - integer.valueOf(oliMap.get(prod.id));
        }
        
        
    }
    
    
    if(!Products.isEmpty() && Products.size() > 0){
        update Products;
    }
    
    
}

Thanks,
Vijay,
Solution Architect,
Steadfast Consultancy Services​​​​​​​
Lukesh KarmoreLukesh Karmore
Thanks for your valuable reply  Suraj Tripathi , Olivier van den Nest , Vijay Nagella
 
Lukesh KarmoreLukesh Karmore
 Hey below is my code, its successfully deployed  but not worked, after delete OpportunityLineItem i have to add deleted Quantity to available quantity.

trigger MaintainAvailableQuantity_AfterDeleteOpportunityLineItem on OpportunityLineitem (after delete) {
set<id> OliIds=new  set<id>();
for(OpportunityLineitem o:Trigger.old){
    OliIds.add(o.id);
}
list<OpportunityLineitem> ItemList=[SELECT Quantity,product2.Available_Quantity__c,product2.Total_Quantity__c FROM OpportunityLineitem WHERE id IN :OliIds];
set<id> productIds=new set<id>();
map<Id,Decimal> productMapIds=new map<Id,Decimal>();
for(OpportunityLineitem i:ItemList ){
    productIds.add(i.product2Id);
    productMapIds.put(i.product2Id,i.Quantity);
}
list<product2> productList=[SELECT Id,Total_Quantity__c,Available_Quantity__c FROM Product2 WHERE Id IN:productIds];
for(product2 p:productList){
p.Available_Quantity__c=Integer.valueOf(p.Available_Quantity__c)+Integer.valueOf(productMapIds.get(p.id));
}
update productList;
}
Thank you
Vijay NagellaVijay Nagella
Hi Lukesh,

Please find the Working Code.
 
trigger MaintainAvailableQuantity_AfterDeleteOpportunityLineItem on OpportunityLineitem (after delete) {

	Map<Id,decimal> oliMap = new Map<Id,decimal>();

	if(trigger.isAfter && trigger.isDelete){
        
        for(OpportunityLineItem oli : Trigger.old){
            // Check if the Opportunity Line Item has
            // a Product and the Quantity is Defined.
            if(oli.Product2Id != Null && oli.Quantity != Null){
                oliMap.put(oli.Product2Id, oli.Quantity);
            }
        }
        
        List<Product2> Products = [SELECT Id,Name,Total_Quantity__c,Available_Quantity__c FROM Product2 WHERE Id IN :oliMap.keySet() ];
        
        
        for(Product2 prod : Products){
            
            prod.Available_Quantity__c =  prod.Available_Quantity__c + oliMap.get(prod.id);
            
        }
        
        if(Products != Null && Products.size() > 0){
            update products;
        }      
        
        
    }
	
}

Thanks,
Vijay,
Solution Architect,
Steadfast Consultancy Services​​​​​​​
Vijay NagellaVijay Nagella
Hi Lukesh,

If it resolved your Issue please mark it as the best answer. 

Thanks,
Vijay,
Solution Architect,
Steadfast Consultancy Services​​​​​​​