+ Start a Discussion
Kathryn BullockKathryn Bullock 

Trigger to Disallow two Opportunities of Similar Type

Is it possible to create a trigger that will allow no one, except system administrators, to create two opportunities of the same type on the Account object?  So, if someone has already created an equipment opportunity, another person could not create another equipment opportunity on the account.  I had originally thought this would be a validation rule and now I have no idea what to do.  Please advise.
Best Answer chosen by Kathryn Bullock
Avishek Nanda 14Avishek Nanda 14
Hi Kathryn,

Basically, you can have a Before inserting trigger to check any Identical Opportunity in the Database If You Find any Block that Opportunity being Created Using Trigger.Add Error Method.  Create a Unique String (Combination of Any Field of Opportunity) Check against the database If-Match Find then block. Sample Trigger Below. Here Field 1, 2,3 are Example. You change the Filed accordingly to your need. Here in the Below Code and am getting the Values from Trigger.New and String in Variable and Querying the Database and Checking the same Combination. The Furst Can be Eliminated if you Create a Custom Field Which would Update the same using a Formula or Workflow. 

Trigger: 
trigger OpportunityTrigger on Opportunity (before insert) {
    if(Trigger.isBefore && Trigger.isInsert){
        DedupeCasesHandler.deDupeCases
            }
}
Handler Class. 
public class DedupeCasesHandler {
    public static void deDupeCases (List<Opportunity> Opps){
        
        Set<String> setUnique 			= New Set<String>();
        Set<String> setUniqueDataBase 	= New Set<String>();
        Set<String> Field1 				= New Set<String>();
        Set<String> Field2 				= New Set<String>();
        Set<String> Field3 			= New Set<String>();
        Set<String> Field4 			= New Set<String>();
        
        
        For (Opportunity objOpp : Opps){
            If(objOpp.Field1 !=Null && objOpp.Field2 !=Null && objOpp.Field3 != Null && objOpp.Field4 !=Null){
                Field1.add(objOpp.Field1);
                Field2.add(objOpp.Field2);
                Field3.add(objOpp.Field3);
                Field4.add(objOpp.Field4);
                
                String strKey = objOpp.Field1+ '_' +objOpp.Field1+ '_' +objOpp.Field1+ '_' +objOpp.Field1;
                if(strKey != null && strKey != '')
                    setUnique.add(strKey);
                system.debug('setUnique' +setUnique);
            }
        }
        if(!setUnique.isEmpty()){
            system.debug('Im here');
            For (Opportunity objOpp : [SELECT Id,Field1,Field2,Field3,Field4]){
                String strKeyDataBase = objOpp.Field1+ '_' +objOpp.Field2+ '_' +objOpp.Field3+ '_' +objOpp.Field4;	
                setUniqueDataBase.add(strKeyDataBase);
                system.debug('setUniqueDataBase'+setUniqueDataBase); 
            }
        }
        For(Opportunity objOpp : Opps){
            IF(objOpp.Field1 !=Null && objOpp.Field1 !=Null && objOpp.Field1 != Null && objOpp.Field1 !=Null){
                String strKey = objOpp.Field1+ '_' +objOpp.Field2+ '_' +objOpp.Field3+ '_' +objOpp.Field4;
                if(!setUniqueDataBase.isEmpty() && setUniqueDataBase.contains(strKey)){
                    objOpp.addError('Duplicate Opportunity Found Contact the Salesforce Administrator'); 
                }
            }
        }
    }
}

Please Mark this as the best answer if this resolves your query. 

All Answers

Sagar PatilSagar Patil
Hi Kathryn,

Kindly follow below steps to acheive this requirement.

1. Create Roll up summary field on account object and choose Summarized Object as Opportunity also roll up type as COUNT so that It will keep count of no of opp associated with that account.
2. Write the trigger on Opportunity object as below.
 
trigger Error1 on Opportunity (before insert) {

   for(Opportunity o: Trigger.new)
      {
        if(o.accountid!=null)
        {
          Account a=[select id, Oppo__c from Account where id =:o.accountid limit 1];
          Profile p = [SELECT Id, Name FROM Profile WHERE Id=:userinfo.getProfileId() LIMIT 1];
          if(a.Oppo__c>=1 && p.Name <>'System Administrator')
          {
           o.addError('You cant create Opp now');
          }
        }
      }
}
3. This will prevent the user whose profile is other than System admin to create more than one Opp record on the Account. 

Kindly mark this answer as best answer if it helps you.

Regards,
Sagar
 
Sagar PatilSagar Patil
In above code, Oppo__c  is roll up summary field on account object. Kindly use the name which you will give to roll up summary field other than that there is no change in the trigger.
Kathryn BullockKathryn Bullock
Thank you for this!  Is there a way to create this where I can have two opportunities, just not two of the same kind?
Kathryn BullockKathryn Bullock
Also, will I need to create an Apex class in order to clear the Code Coverage Error for this trigger?
Avishek Nanda 14Avishek Nanda 14
Hi Kathryn,

Basically, you can have a Before inserting trigger to check any Identical Opportunity in the Database If You Find any Block that Opportunity being Created Using Trigger.Add Error Method.  Create a Unique String (Combination of Any Field of Opportunity) Check against the database If-Match Find then block. Sample Trigger Below. Here Field 1, 2,3 are Example. You change the Filed accordingly to your need. Here in the Below Code and am getting the Values from Trigger.New and String in Variable and Querying the Database and Checking the same Combination. The Furst Can be Eliminated if you Create a Custom Field Which would Update the same using a Formula or Workflow. 

Trigger: 
trigger OpportunityTrigger on Opportunity (before insert) {
    if(Trigger.isBefore && Trigger.isInsert){
        DedupeCasesHandler.deDupeCases
            }
}
Handler Class. 
public class DedupeCasesHandler {
    public static void deDupeCases (List<Opportunity> Opps){
        
        Set<String> setUnique 			= New Set<String>();
        Set<String> setUniqueDataBase 	= New Set<String>();
        Set<String> Field1 				= New Set<String>();
        Set<String> Field2 				= New Set<String>();
        Set<String> Field3 			= New Set<String>();
        Set<String> Field4 			= New Set<String>();
        
        
        For (Opportunity objOpp : Opps){
            If(objOpp.Field1 !=Null && objOpp.Field2 !=Null && objOpp.Field3 != Null && objOpp.Field4 !=Null){
                Field1.add(objOpp.Field1);
                Field2.add(objOpp.Field2);
                Field3.add(objOpp.Field3);
                Field4.add(objOpp.Field4);
                
                String strKey = objOpp.Field1+ '_' +objOpp.Field1+ '_' +objOpp.Field1+ '_' +objOpp.Field1;
                if(strKey != null && strKey != '')
                    setUnique.add(strKey);
                system.debug('setUnique' +setUnique);
            }
        }
        if(!setUnique.isEmpty()){
            system.debug('Im here');
            For (Opportunity objOpp : [SELECT Id,Field1,Field2,Field3,Field4]){
                String strKeyDataBase = objOpp.Field1+ '_' +objOpp.Field2+ '_' +objOpp.Field3+ '_' +objOpp.Field4;	
                setUniqueDataBase.add(strKeyDataBase);
                system.debug('setUniqueDataBase'+setUniqueDataBase); 
            }
        }
        For(Opportunity objOpp : Opps){
            IF(objOpp.Field1 !=Null && objOpp.Field1 !=Null && objOpp.Field1 != Null && objOpp.Field1 !=Null){
                String strKey = objOpp.Field1+ '_' +objOpp.Field2+ '_' +objOpp.Field3+ '_' +objOpp.Field4;
                if(!setUniqueDataBase.isEmpty() && setUniqueDataBase.contains(strKey)){
                    objOpp.addError('Duplicate Opportunity Found Contact the Salesforce Administrator'); 
                }
            }
        }
    }
}

Please Mark this as the best answer if this resolves your query. 
This was selected as the best answer
Kathryn BullockKathryn Bullock
User-added image
So that trigger would be able to prevent a situation like this?  Also, is it possible to write in a portion of the trigger that could allow that opportunity type to be created after 90 days?
Kathryn BullockKathryn Bullock
Also, how would I write in the system administrator exception to that code?
Avishek Nanda 14Avishek Nanda 14


@ Kathryn Bullock,

IN Trigger.New You can add IF Condition to check System Admin
AND To Check 90 Days. You Can add the AND condition while querying the Data Base 
SELECT Id,Fields FROM Case  WHERE CreatedDate = LAST_90_DAYS
The Query output would come null if Opp Created us more than 90 Days so the System will Create a new one.