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
Franco DFranco D 

Opportunity to delete duplicate

Hello all,

I am new to Apex Code and I am trying to build a trigger to the following task.
Each time we insert new Opportunities throug a bulk insert, we have Opportunites in the system that are listed as scheduled, that are equal or same as Opportunities Won. So I want my trigger to delete the scheduled Opportunity that is equal to the Won Opportunity.

When the Opportunity is inserted it will check three fields that need to all match for Opportunity scheduled to be deleted.
StageName = "Peformed" Which is always the case when inserting new bulk Opportunites 
Contact_ID = "Contact_ID"  Which is the first field it should look for to find a duplicate Opportunity.
ClosedDate = "Date" Which is the date we enter for the Opportunity that will match the scheduled Opportunity
 
Example Giving: New Opportunity Inserted: 
StageName = Performed 
ContactID = John Doe
ClosedDate = 2/13/2017

Found Scheduled Opportunity to be deleted:
Stage Name = Scheduled
ContactID = John Doe
ClosedDate = 2/13/2017

Here is what i have so far: 

trigger myTrigger on Opportunity (before insert) {

    for (Opportunity opp : Trigger.new){
    
        if (opp.StageName = 'Performed'){
        
        Opportunity Opp = new Opportunity();
        
        Opp.StageName      = 'Surgery Performed';
        Opp.ContactID         = 'Check for same ContactID;
        Opp.ClosedDate      =  'Check for same ClosedDate;
       
        delete opp;
        }
    }
}

Sorry for my ignorance and lack of knowledge in this topic, i know this may seem very silly to ask, but I am desperate to know if this can be done by a trigger and not to be manually searched to find a duplicate to delete.

Thank you in advance.
DixitDixit
you need to query those opps that match with your 3 fields.

 list<Opportunity> Opps = [SELECT id FROM opportunity WHERE stagefield =: newoppevaluating.stafefield AND contactID = :newoppevaluating.contacID AND closedDate = :newoppevaluating.closedDate];

if(Opps.size()>0){
   delete opps;
}

your  for (Opportunity opp : Trigger.new){   } is the name you give to the actual opp which fired the trigger, so i would use a diferent name for this and the one you created later in the code. In mi example would be

 for (Opportunity newoppevaluating : Trigger.new){ }

but i always use:  for (Opportunity newoppevaluating : Trigger.new){ }

check out this link: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_context_variables.htm
DixitDixit
but i always use:  for (Opportunity run : Trigger.new){ }  *
 
Franco DFranco D
Thank you very much for your help. I changed the code to the following:

trigger myTrigger on Opportunity (before insert) {

for (Opportunity NewOpp : Trigger.new){
    
        List<Opportunity> Opps = [SELECT Id FROM Opportunity WHERE StageName =: NewOpp.StageName AND AccountID =: NewOpp.AccountID AND CloseDate =: NewOpp.CloseDate];
        
        if (Opps.size() >0){
            delete Opps;
        }
    }
}

I did not get any errors, but when i insert a new Opportunity identical to a previous one, it does not delete any.
Franco DFranco D
I actually had to take out ContactID because I am really trying to reference the Contact Name, but I don't know how to reference it. 

I removed it from the code and just left StageName and ClosedDate and it work. YES!

Now how would I make the code to only delete one Opportunity duplicate. Let's say for example there are two scheduled Opportunities and one Opportunity Performed, I would just one to match one to one, and not delete both scheduled. Is this possible? Or does it have to delete all duplicates.
Lumina SoftwareLumina Software
create a list for each kind of opp. 
iterate the list you got and compare the fields to know which one will you insert and wich you delete.

I don't know if for your case the "closed date" should work for decide which should be the one to insert, so add an "order by CreatedDate DESC" to your query. 

debug your list, it should be on ascending order, so the first one should be the higher.... Add the first element to a new list and the others (1 or more) to another list. Insert the first list and delete those ones on the second. 

trigger myTrigger on Opportunity (before insert) {

list<opportunity> insertopps = new list<opportunity>();
list<opportunity> deleteopps = newlist<opportunity>();

for (Opportunity NewOpp : Trigger.new){
    
        List<Opportunity> Opps = [SELECT Id FROM Opportunity WHERE StageName =: NewOpp.StageName AND AccountID =: NewOpp.AccountID AND CloseDate =: NewOpp.CloseDate ORDER BY closeDate DESC];
        

if(Opps.size()> 0){
 insertopps.add(Opps[0]);
}
       
While(integer i=1; i < opps.size(); i++){
     deleteopps.add(Opps[i]);
}

 if(insertopps.size() > 0){
 insert insertopps;
}

 if(deleteopps.size()>0){
 delete deleteopps;
}
    }
}


i don't know if that would work, but i will give it a try. 
Franco DFranco D
Tried the following code, but it keeps giving me this error message "Error: Compile Error: unexpected token: '(' at line 3 column 51"

trigger myTrigger on Opportunity (before insert) {

list<opportunity> insertopps = newlist<opportunity>();
list<opportunity> deleteopps = newlist<opportunity>();

for (Opportunity NewOpp : Trigger.new){
    
        List<Opportunity> Opps = [SELECT Id FROM Opportunity WHERE StageName =: NewOpp.StageName AND CloseDate =: NewOpp.CloseDate ORDER BY closeDate DESC];
        

if(Opps.size()> 0){
 insertopps.add(Opps[0]);
}
       
While(integer i=1; i < opps.size(); i++){
     deleteopps.add(Opps[i]);
}

 if(insertopps.size() > 0){
 insert insertopps;
}

 if(deleteopps.size()>0){
 delete deleteopps;
}
    }
}