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
Shruthi NarsiShruthi Narsi 

Trigger to auto sync products

I have used the below trigger to auto synce quoteline item products on select of syncing chekc box on quote but it is not getting synced. can anyone correct the code

trigger QuoteLineItemTrigger on Quotes__c (after update, after insert) {
    Set<Id> quoteIdsForOpportunitySync = new Set<Id>();
    Set<id> QuoteIds = new Set<id>();
    List<QuoteLineitem__c> quoteLineItemsForOpportunitySync = new List<QuoteLineitem__c>();
    List<OpportunityLineItem> opportunityLineItemsForOpportunitySync = new List<OpportunityLineItem>();
    Map<Id, Id> quoteIdToOpportunityIdMap = new Map<Id, Id>();
    Map<Id, QuoteLineitem__c> qliIdentifierToQuoteLineItemMap = new Map<Id, QuoteLineitem__c>();
    List<OpportunityLineItem> opportunityLineItemsToUpdate = new List<OpportunityLineItem>();
    List<Quotes__c> quotesToStopSyncing = new List<Quotes__c>();
    
    for(Quotes__c q : Trigger.new) {
        if(q.IsSyncing__c == true) {
            // we can use a set here to prevent duplication of quote ids
            quoteIdsForOpportunitySync.add(q.Id);
            // we're mapping the quote id to the opportunity id here
            // for use when we're iterating through the quote line items
            quoteIdToOpportunityIdMap.put(q.Id, q.OpportunityId__c);
            system.debug('OpportunityId__c '+q.ID);
        }
    }
    
    quoteLineItemsForOpportunitySync = [SELECT Id, QuotesId__c, Product2Id__c FROM QuoteLineitem__c WHERE QuotesId__c IN :quoteIdsForOpportunitySync];
    
    for(QuoteLineitem__c qli : quoteLineItemsForOpportunitySync) {
        Id opportunityId = quoteIdToOpportunityIdMap.get(qli.QuotesId__c);
        if(opportunityId != null) {
            // we could use a nested map but this solution will work using a constructed identifier
            // it also keeps the code slightly cleaner
            // using Product2Id__c isn't ideal in this situation and if the QuoteLineitem__c could store the
            // originating OpportunityLineItem Id it would simplify the solution considerably.
            String qliIdentifier = String.valueOf(opportunityId) + '-' + String.valueOf(qli.Product2Id__c);
            qliIdentifierToQuoteLineItemMap.put(qliIdentifier, qli);
        }
    }
    
    // find all the OpportunityLineItem that belong to any of related opportunites
    opportunityLineItemsForOpportunitySync = [SELECT Id,Name,OpportunityId, Product2Id FROM OpportunityLineItem WHERE OpportunityId IN :quoteIdToOpportunityIdMap.values()];
    
    for(OpportunityLineItem oli : opportunityLineItemsForOpportunitySync) {
        // now we reconstruct the identifier to match back to the map
        String oliIdentifier = String.valueOf(oli.OpportunityId) + '-' + String.valueOf(oli.Product2Id);
        QuoteLineitem__c relatedQli = qliIdentifierToQuoteLineItemMap.get(oliIdentifier);
        // only do the following steps if a matching QuoteLineitem__c is found
        if(relatedQli != null) {
            // as you haven't defined what to sync i've put an example description update
            // you can alter this to update any OpportunityLineItem field,
            // just make sure you add it to the query above
            oli.Description = relatedQli.QuotesId__c;
            opportunityLineItemsToUpdate.add(oli);
            
            // re-creating the quote here so we only update quotes that the sync has been sucessful
            Quotes__c q = new Quotes__c(
                Id = relatedQli.QuotesId__c,
                IsSyncing__c = false
            );
            
            quotesToStopSyncing.add(q);
        }
        System.debug('relatedQli.QuotesId__c ' + relatedQli.QuotesId__c ); 
    }
    
    // best practice is to wrap any updates in try - catch methods
    update opportunityLineItemsToUpdate;
    // we could also take advantage of the before trigger to prevent a further dml statement
    // however, this approach is closest to op's original so should be easier to understand
    update quotesToStopSyncing;
}
Below are snips for your reference

User-added image
User-added imageUser-added image
Rounak SharmaRounak Sharma
hello,
please refer the below code
trigger Product_Image_On_QuoteLineItem on QuoteLineItem (Before insert, Before update) 
{
    List<QuoteLineItem> quote = new List<QuoteLineItem>();
    Set<Id>productidSet =New Set<Id>();
    for(QuoteLineItem child : trigger.new)
    {
        if(child.Product2Id != null)
        {
            productidSet.add(child.Product2Id);   
            //quote.add(child.Product_Image__c = Product2Id.Product_Image__c);
        }      
    }
   Map<id,Product2>ProductMap=New Map<Id,Product2>([Select id,Product_Image__c From Product2 where id=:productidSet ]);
     for(QuoteLineItem child : trigger.new)
    {
        if(child.Product2Id != null && ProductMap.containskey(child.Product2Id))
        {
            child.Product_Image__c = ProductMap.get(child.Product2Id).Product_Image__c;
        }      
    }
}

Please let me know if it helps
thanks
Shruthi NarsiShruthi Narsi
I have made the changes, But getting errors

trigger QuoteLineItemTrigger on Quotes__c (Before insert, Before update) 
{
    List<QuoteLineitem__c> quote = new List<QuoteLineitem__c>();
    Set<Id>productidSet =New Set<Id>();
    for(Quotes__c  child : trigger.new)
    {
        if(child.IsSyncing__c != true)
        {
            productidSet.add(child.Product2__c);   
            //quote.add(child.Product_Image__c = Product2Id.Product_Image__c);
        }      
    }
   Map<id,Product2__c>ProductMap=New Map<Id,Product2__c>([Select id,Name From Product2__c where id=:productidSet ]);
     for(Quotes__c child : trigger.new)
    {
        if(child.Product2__c != null && ProductMap.containskey(child.Product2Id))
        {
            child.Product2__c = ProductMap.get(child.Product2Id__c).Name;
        }      
    }
}

User-added image
 
scott bell 2scott bell 2
You explained in a detailed way. Thanks for sharing this to us. QuickPayPortal is one of the most frequently accessed website on the internet. Quickpayportal is one of the best patient Medical Bill payment portals. https://quickpayportal.win