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
davidCe17icdavidCe17ic 

Trigger to Flag potential duplicate Cases in Salesforce

I am new to triggers in SFDC and have created a trigger to flag potential duplicate Cases. I am querying the SuppliedEmail, ContactId and IsClosed values on Cases. It works when a Contact creates a new Case in SFDC when they already have a case open, however if I close/delete,  the potential duplicate case, the checkbox remains ticked. I was trying to use an after insert, after update action but was receiving a System.FinalException: Record is read-only error. Any help is appreciated. 

 

Here is the code:

 

trigger PotentialDupe on Case (before insert, before update) {
List<Case> DupeCases = new List<Case>();
for (Case c : Trigger.new){

Case [] cases = [SELECT id, ContactId, SuppliedEmail, isClosed FROM Case WHERE SuppliedEmail = :c.SuppliedEmail AND ContactId = :c.ContactId AND isClosed = FALSE];

if (cases.size() > 0) {
c.Potential_Duplicate_Case__c = TRUE;
}else
c.Potential_Duplicate_Case__c = FALSE;
}
update DupeCases;
}

k_bentsenk_bentsen

Although I can't say for certain, my guess is that the IsClosed field remains flagged as TRUE until after the DML operation completes, so your SOQL query would still return a record during "before" execution. Again, it's just speculation, so I don't really know. Also, the reason you get the exception is you cannot directly assign values to a record during "after" execution, you must use DML operations to update the record.

 

I would also suggest that you move your SOQL outside your loop as that is a best practice to avoid hitting governor limits. The structure I generally follow with my triggers is (in this example for Case): 

 

 

trigger CaseTrigger (<DML operation(s)>){
    List<Id> casesIds = new List<Id>();
    for(Case c: Trigger.new){
        if(c meets criteria for trigger)
            casesIds.add(c.Id);
    }
    if(!caseIds.isEmpty()){
        Case [] casesToUpsert = [Select Id, FIELDS from Case where Id IN :caseIds];
        for(Case c: casesToUpsert){
            <perform logic, make changes to field values for c>
        }
        <DML operation> casesToUpsert;
    }
}

Here's a very help guide on some simply yet important Apex best practices: http://wiki.developerforce.com/page/Apex_Code_Best_Practices This may be (one of) your first trigger(s) but if you're as much of a Salesforce enthuasist as many others on these boards, I'm sure it won't be your last :) Hopefully this guide can get you started on re-writing your trigger. 

 

 

sambasamba

1. The Trigger may appear an infinite loop.

2. Don't put DML to for statement.

 

Please tell me If you have any questions.

 

 

Thanks,

Samba

 

Jasmeen Kaur 22Jasmeen Kaur 22
Hi davidCe17ic 

Did you find the solution of this problem. I am also having exactly the same issue.

Thanks 
Jas
Michael Johnson 136Michael Johnson 136
You cannot do an update close in a "before" statement. Changes you make to the record before update/insert are done on the record itself and do not require an additional "update record;".

Second, DupCases as above is an update list of cases, no cases are ever added to this list. I would just take out the entire List<Case> DupeCases = new List<Case>(); line and the update clause to this list and it should check the box on the new case. This could be constructed much better but at least it will function as you intend.