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
Tom EbenhochTom Ebenhoch 

Opportunity Trigger Help

Good morning,

I have an apex trigger on opportunities that creates a new opportunity for the next year when a specific "sales stage" is selected. I recently updated the trigger to fire when the Closed/Won sales stage is selected OR Membership Started is selected. The problem is that the Membership Started stage is changed at a later date to Closed/Won, which will create a duplicate new opportunity (we only want 1 new opp). Does anyone have any advice? I have been stuck for a few days. My code is shown below:

 public static void createNextYearOpp(List<Opportunity> newlist, Map<Id, Opportunity> oldMap){
        Map<String, Schema.RecordTypeInfo> recordTypeInfo = Schema.SObjectType.Opportunity.getRecordTypeInfosByName();      
        list<Opportunity> newYearOppList = new list<Opportunity>();
        map<Id,Opportunity> originalOppIdToCloneOpp = new map<Id,Opportunity>();
        
        for(Opportunity opp : newList){
            if(oldMap != null && oldMap.get(opp.id).StageName != opp.StageName && opp.StageName == 'Closed/Won'|| opp.StageName =='Membership Started PIP'
                    && opp.Buy_Type__c == 'Security Benchmarks' && opp.Prospect_Type__c == 'SB New Business'
                    && opp.Membership_Start_Date__c != null) {
                Opportunity newOpp = new Opportunity();
                Id recordId = recordTypeInfo.get(opp.Prospect_Type__c).getRecordTypeId();
                newOpp.RecordTypeId = recordId;
                newOpp.name = opp.CloseDate.addYears(1).year() + ' ' + opp.name.subString(4);
                newOpp.Prospect_Type__c = 'SB Renewal';
                newOpp.CloseDate = opp.Membership_Start_Date__c.addYears(1);
                newopp.Membership_Start_Date__c = opp.Membership_Start_Date__c.addYears(1);
                newopp.Buy_Type__c = opp.Buy_Type__c;
                newOpp.AccountId = opp.AccountId;
                newOpp.NextStep = opp.NextStep;
                newOpp.Follow_up_Date__c = opp.Follow_up_Date__c;
                newOpp.CIS_CAT_Trial__c = opp.CIS_CAT_Trial__c;
                newOpp.Billing_Cycle__c = opp.Billing_Cycle__c;
                newOpp.Priority__c = opp.Priority__c;
                newOpp.Membership_Category__c = opp.Membership_Category__c;
                newOpp.OwnerId = opp.OwnerId;
                newOpp.Legacy_Membership_Fee__c = opp.Legacy_Membership_Fee__c;
                newOpp.TotalOpportunityQuantity = opp.TotalOpportunityQuantity;
                newOpp.Probability = opp.Probability;
                newOpp.Reason_Lost__c = opp.Reason_Lost__c;
                newOpp.Forecast__c = opp.Forecast__c;
                newOpp.LeadSource = opp.LeadSource;
                newOpp.Description = opp.Description;
                newOpp.Legacy_Created_By__c = opp.Legacy_Created_By__c;
                newOpp.Legacy_Created_Date__c = opp.Legacy_Created_Date__c;
                newOpp.Campaign = opp.Campaign;
                newOpp.Amount = opp.Amount;
                newOpp.StageName = 'To Be Invoiced';
                system.debug('@@ '+newOpp.name);
                //newYearOppList.add(newOpp);
                originalOppIdToCloneOpp.put(opp.Id,newOpp);
            }            
        }
UC InnovationUC Innovation
You could have a checkbox field that gets checked when an opportunity goes to "Closed/Won", and look for that checkbox before creating a new opportunity when the stage is "Membership Started". You can design a simple workflow to populate that checkbox.