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
wcwill978wcwill978 

Prevent duplicate records from being created with opportunity trigger

Hi,

 

I have been staring at this trigger trying to figure out how to include some logic that allows it to only create one record per opportunity. The trigger runs when a deal is closed won and has service. Basically what the trigger does is create an ESU record on the account, what we've been seeing is that sometimes when the trigger is fired it creates two records per opportunities. I need to somehow add some logic into the trigger to allow only one record per opportunity.

 

I read somewhere that I should do a "map" to pull the oppty ID into it and check t see if the record exists if not create a new one if it does then update it. So each opppty will have only one ESU tied to it. The ESU record has a relationship to the oppty.  The trigger is below as a comment (exceeeded character limite!)

 

Can someone help me with this please or show me how would I go about adding this into the existing trigger.

 

Thank you

 

wcwill978wcwill978

trigger createProServRecords on Opportunity (after update)
{       
    List<ID> oppIDs = new List<ID>();
    List<OpportunityLineItem> tmpOLIs = new List<OpportunityLineItem>();
    Set<Id> pbeIDs = new Set<ID>();
    Map<ID, Opportunity> oppInfo = new Map<ID, Opportunity>();
    Map<ID, List<OpportunityLineItem>> oppProducts = new Map<ID, List<OpportunityLineItem>>();
    Map<ID, String> pbeNames = new Map<ID, String>();
   
    Opportunity tmpOpp = new Opportunity();
    Service_Unit__c tmpSU = new Service_Unit__c();
    ProService_Order__c tmpPSO = new ProService_Order__c();
   
    List<Service_Unit__c> newSURecords = new List<Service_Unit__c>();
    List<ProService_Order__c> newPSORecords = new List<ProService_Order__c>();
   
    Decimal qty1U = 0;
    Decimal qty5U = 0;
    Decimal qty10U = 0;
    Decimal qty20U = 0;
    Decimal totalUnits = 0;
   
    Decimal amt1U = 0.00;
    Decimal amt5U = 0.00;
    Decimal amt10U = 0.00;
    Decimal amt20U = 0.00;
    Decimal totalAmount = 0.00;
   
    Decimal units = 0;
    String skuName;
    Date today = System.today();
           
    // Make a list of Closed/Won Opportunities in this trigger that previously weren't Closed/Won
    for (Opportunity thisOpp : trigger.new)
        if(thisOpp.StageName == 'Closed Won' && Trigger.oldMap.get(thisOpp.id).StageName != 'Closed Won')
            oppIDs.add(thisOpp.ID);

    if(!oppIDs.isEmpty())
    {
        // Get Stage and AccountID for these Opportunities
        for (Opportunity loopOpp : [SELECT ID, StageName, AccountID FROM Opportunity WHERE ID IN :oppIDs])
            oppInfo.put(loopOpp.ID,loopOpp.clone());
       
        // Make a map of Line Items (and a set of PriceBookEntry IDs) for these Opportunities   
        for (OpportunityLineItem loopOLI : [SELECT PriceBookEntryId, SmartCalc_Class__c, Quantity, extAcqAmt__c, OpportunityID FROM OpportunityLineItem where OpportunityID IN :oppIDs])
        {
            // Only bother if it's a PS SKU
            if(loopOLI.SmartCalc_Class__c == 'Professional Service')
            {
                pbeIDs.add(loopOLI.PriceBookEntryId);
                tmpOLIs.clear();
               
                // Check if Key exists in Map
                if (oppProducts.containsKey(loopOLI.OpportunityID))
                {
                    tmpOLIs = oppProducts.get(loopOLI.OpportunityID);
                }
               
                // Add the new OLI into the list
                tmpOLIs.add(loopOLI);
               
                // A Put will always overwrite the Pair Returned, so use a copy
                oppProducts.put(loopOLI.OpportunityID,tmpOLIs.clone());
            }
        }       
       
        // Make a map of PriceBookEntryIds to Product Names
        for (PriceBookEntry loopPBE : [SELECT Id, Name FROM PriceBookEntry WHERE ID in :pbeIDs])
            pbeNames.put(loopPBE.ID, loopPBE.Name);
           
        //System.Debug('OppIDs:'+oppIDs+':');
        //System.Debug('PBEIDs:'+pbeIDs+':');
        //System.Debug('OppInfo:'+oppInfo+':');
        //System.Debug('OppProducts:'+oppProducts+':');
        //System.Debug('PBENames:'+pbeNames+':');
       
        // Skip all calculations if no PS Products
        if(!oppProducts.isEmpty())
        {
            // Get list of Opp Line Items for each Opp
            for(ID loopOppId : oppIDs)
            {
                // Reset tmpSU record (only one per Opp)
                tmpSU.clear();
               
                // Reset ESU info for each Opp
                totalUnits = 0;
                totalAmount = 0.00;
               
                tmpOLIs = oppProducts.get(loopOppId);
               
                // Go through list of Line Items and create records if need be
                for(OpportunityLineItem tmpOLI: tmpOLIs)
                {
                    // Reset tmpPSO record (could be multiple per Opp)
                    tmpPSO.clear();
                   
                    skuName = pbeNames.get(tmpOLI.PriceBookEntryId);
                    System.Debug('SKU:'+skuName+':');

wcwill978wcwill978

if (skuName.startsWith('PS-ESU-'))
                    {
                        // Determine SKU Units from SKU Name
                        units = Decimal.valueOf(skuName.replace('PS-ESU-',''));
                       
                        if(units == 1)
                        {
                          qty1U += tmpOLI.Quantity;
                          amt1U += tmpOLI.extAcqAmt__c;
                        }
                        else if(units == 5)
                        {
                          qty5U += tmpOLI.Quantity;
                          amt5U += tmpOLI.extAcqAmt__c;
                        }
                        else if(units == 10)
                        {
                          qty10U += tmpOLI.Quantity;
                          amt10U += tmpOLI.extAcqAmt__c;
                        }
                        else if(units == 20)
                        {
                          qty20U += tmpOLI.Quantity;
                          amt20U += tmpOLI.extAcqAmt__c;
                        }
                       
                        totalUnits += (units * tmpOLI.Quantity);
                        totalAmount += tmpOLI.extAcqAmt__c;
                    }
                    else
                    {
                        tmpOpp = oppInfo.get(loopOppId);
                        tmpPSO.Account__c = tmpOpp.AccountID;
                        tmpPSO.Opportunity__c = tmpOpp.Id;
                        tmpPSO.Part_Number__c = skuName;
                        tmpPSO.P_O_Amount__c = tmpOLI.extAcqAmt__c;
                        tmpPSO.Quantity__c = tmpOLI.Quantity;
                        tmpPSO.Date_Entered__c = today;
                        tmpPSO.Status__c = 'New';
                       
                        newPSORecords.add(tmpPSO.clone());
                    }                  
                }
               
                if (totalUnits > 0)
                {
                    tmpOpp = oppInfo.get(loopOppId);
                    tmpSU.Account__c = tmpOpp.AccountID;
                    tmpSU.Opportunity__c = tmpOpp.Id;
                    tmpSU.P_O_Amount__c = totalAmount;
                    tmpSU.Total_Units_Purchased__c = totalUnits;
                    tmpSU.Date_Entered__c = today;
                    tmpSU.Status__c = 'New';
                   
                    tmpSU.X1_Unit_Qty__c = qty1U;
                    tmpSU.X5_Unit_Qty__c = qty5U;
                    tmpSU.X10_Unit_Qty__c = qty10U;
                    tmpSU.X20_Unit_Qty__c = qty20U;
           
            tmpSU.X1_Unit_Total__c = amt1U;
            tmpSU.X5_Unit_Total__c = amt5U;
            tmpSU.X10_Unit_Total__c = amt10U;
            tmpSU.X20_Unit_Total__c = amt20U;
                   
                    newSURecords.add(tmpSU.clone());
                }
            }
           
            try
            {
                System.Debug('newSUs:'+newSURecords+':');
                System.Debug('newPSOs:'+newPSORecords+':');
                insert newSURecords;
                insert newPSORecords;
            }
            catch (Exception e)
            {
                System.Debug('ERROR! :'+e);
            }
        }
    }
}