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
Ashley Cobb 25Ashley Cobb 25 

Trigger creating duplicate cases

Hello!

I have been given the task of creating cases whenever a task with a specific subject is attached to a contact.  It works just fine for new contacts in the system, but every time marketing inserts new campaigns, a case is created for every past task with the subject as well.  So at times we can get 100+ cases created on old tasks.  The code that I am using is below:

Trigger:

trigger taskToCaseCreate on Task (after insert, after update) {
        if(checkRecursive.runOnce())
    {

    
    List<Task> newTaskList = new List<Task>();
    
    If (Trigger.isInsert){
        For(Task T: Trigger.new){
            If (T.WhoId != NULL){
                newTaskList.add(T);
            }
        }
    }
    
    If (Trigger.isUpdate){
        For(Task T : Trigger.new){
            String o = trigger.oldMap.get(T.ID).WhoID;
            If (T.WhoId != NULL && T.Subject.contains('Submitted Form')){
            If(Trigger.oldMap.get(T.Id).WhoId != Trigger.newMap.get(T.Id).WhoId && !o.startswith('003')){
                newTaskList.add(T);
            }
            }
        }
    }
    
       If(newTaskList.size() > 0){
    createCaseFromTask.createCaseFromTask(newTaskList);
    }
    }
}

Class:

public class createCaseFromTask {
    Public Static void createCaseFromTask(Task[] newTask){
        
        List<Case> newCase = new List<Case>();
        
         for (Task n:newTask){
             String s = n.WhoId;
             
                If(s.startswith('003') && n.subject.contains('Submitted Form') && (n.subject.contains('Demo') || n.Subject.contains('Contact'))){
                    Case c = new Case(ContactId = n.WhoId, Status = 'New', Subject = 'Demo Request');
                   // newCase.add(c);
                     Insert c;
                }     
                If(s.startswith('003') && n.subject.contains('Submitted Form') && n.subject.contains('Content Download')){
                    Case c = new Case(ContactId = n.WhoId, Status = 'New', Subject = 'Content Download');
                  //  newCase.add(c);
                     Insert c;
                  
                }
                If(s.startswith('003') && n.subject.contains('Submitted Form') && n.subject.contains('Webinar')){
                    Case c = new Case(ContactId = n.WhoId, Status = 'New', Subject = 'Webinar');
                  //  newCase.add(c);
                     Insert c;
                  
                }
                If(s.startswith('003') && n.subject.contains('Submitted Form') && n.subject.contains('Blog')){
                    Case c = new Case(ContactId = n.WhoId, Status = 'New', Subject = 'Subscribed to Blog Notifications');
                 //   newCase.add(c);
                     Insert c;
                   
                }  
                If(s.startswith('003') && n.subject.contains('Submitted Form') && !n.subject.contains('Blog') && !n.subject.contains('Webinar') && !n.subject.contains('Content Download') && !n.subject.contains('Demo') && !n.Subject.contains('Contact')){
                    Case c = new Case(ContactId = n.WhoId, Status = 'New', Subject = 'Submitted Form');
                  //  newCase.add(c);
                     Insert c;
                  
                } 
              //  Insert newCase;
                }
    }

}



To add to this, we insert everything into the system as a lead.  Then we have a piece of code that autoconverts the lead to a contact and deduplicates it in the process.  So marketing inserts their lists as leads, and then the leads run through the code, get converted to contacts, then merged.  It seems that when they merged, all the tasks are retriggered.  I tried turning the oldmap ID into a string and skipping it when the old ID is a contact as well but it is still creating the cases.  Any help would be much appreciated.

Thanks!
Best Answer chosen by Ashley Cobb 25
Alex EzhilarasanAlex Ezhilarasan

Finally..! 

There are 2 ways to fix this issue. 
1. Create a new checkbox field with default value as FALSE in Task. Create Case only if this field is FALSE from Trigger. Set this value to TRUE upon creating a Case via this process.  
2. Create a id field in Case object(which contains appropriate Task Id). Create Case records only for new Tasks based on this field.

check this following code. I used solution #2. I have modified the Trigger and Apex Class 

Apex Trigger
 

trigger taskToCaseCreate on Task (after insert, after update) {
    if(checkRecursive.runOnce())
    {
        Map<Id,Task> newIdTaskMap = new Map<Id,Task>();

        for( Task T : Trigger.New ){

            if( T.WhoId != NULL && T.WhoId.startswith('003') && T.Subject.contains('Submitted Form') && ( Trigger.isInsert || (Trigger.isUpdate && Trigger.oldMap.get(T.Id).WhoId != T.WhoId) )  ){

                newIdTaskMap.put(T.Id, T);
            }
        }

        for( Case c : [SELECT Id, Task_Id__c  FROM Case WHERE Task_Id__c IN :newIdTaskMap.keySet()] )
            newIdTaskMap.remove(Task_Id__c);
        
        If(newIdTaskMap.size() > 0){

            createCaseFromTask.createCaseFromTask(newIdTaskMap.values());
        }
    }
}
 

Apex Class
 

public class createCaseFromTask {
    
    Public Static void createCaseFromTask(Task[] newTask){
        
        List<Case> newCase = new List<Case>();
        
         for (Task n:newTask){
             
            If (n.subject.contains('Demo') || n.Subject.contains('Contact')){
                Case c = new Case(ContactId = n.WhoId, Status = 'New', Subject = 'Demo Request', Task_Id__c = T.Id);
               // newCase.add(c);
                 Insert c;
            }     
            If( n.subject.contains('Content Download')){
                Case c = new Case(ContactId = n.WhoId, Status = 'New', Subject = 'Content Download', Task_Id__c = T.Id);
              //  newCase.add(c);
                 Insert c;
              
            }
            If( n.subject.contains('Webinar')){
                Case c = new Case(ContactId = n.WhoId, Status = 'New', Subject = 'Webinar', Task_Id__c = T.Id);
              //  newCase.add(c);
                 Insert c;
              
            }
            If( n.subject.contains('Blog')){
                Case c = new Case(ContactId = n.WhoId, Status = 'New', Subject = 'Subscribed to Blog Notifications', Task_Id__c = T.Id);
             //   newCase.add(c);
                 Insert c;
               
            }  
            If(!n.subject.contains('Blog') && !n.subject.contains('Webinar') && !n.subject.contains('Content Download') && !n.subject.contains('Demo') && !n.Subject.contains('Contact')){
                Case c = new Case(ContactId = n.WhoId, Status = 'New', Subject = 'Submitted Form', Task_Id__c = T.Id);
              // newCase.add(c);
                 Insert c;
              
            } 
            //  Insert newCase;
        }
    }

}

Hope this helps!

Thanks,
Alex 

All Answers

Alex EzhilarasanAlex Ezhilarasan

Hi Ashley,

Add isConverted = False condition in update section. 

Like 

If (T.WhoId != NULL && T.Subject.contains('Submitted Form') && !T.isConverted )

Ashley Cobb 25Ashley Cobb 25
Hi Alex,

This trigger is on the task, not the lead.  So I cannot add !T.isConverted to it.  I do not want cases created for Leads though.  I want cases only created when a task is inserted on a contact, or when a lead is converted to a contact.  The problem is when the lead is converted and merged it is creating a case for every past task as well.  That is why I tried converting the oldmap ID into a string and then saying the string does not start with 003.  It hasn't worked though.

Hope that helps!
Alex EzhilarasanAlex Ezhilarasan

Let's update your existing code. if this is not work, I will try to upload a new code

Change from

String o = trigger.oldMap.get(T.ID).WhoID;
to 
String o = trigger.newMap.get(T.ID).WhoID;

 
Ashley Cobb 25Ashley Cobb 25
Hi Alex,

This did not do what I needed either.  Now it is not creating cases for converted contats at all. I need a middle ground, where it creates a case for a new task on a contact, and for the lead when it is converted into a contact.  But I want to make sure that none of the past tasks are creating duplicate cases.  Example below:

A contact exists in the system, and they have 3 forms that they submitted back in January (shows up as 3 "Submitted Form" tasks.  Then today they come into our system again as a lead and have submitted a new form (new task).  Our trigger then converts the lead into a contact and merges this contact with the old contact.  They should now have 4 cases associated with them in total, and that is what I am trying to achieve.  What is actually happening though, is when that contact is converted and merged, 4 new cases are created so that they have 7 associated with them (4 new and 3 from back in January).

Thanks!
Ashley
Alex EzhilarasanAlex Ezhilarasan

Finally..! 

There are 2 ways to fix this issue. 
1. Create a new checkbox field with default value as FALSE in Task. Create Case only if this field is FALSE from Trigger. Set this value to TRUE upon creating a Case via this process.  
2. Create a id field in Case object(which contains appropriate Task Id). Create Case records only for new Tasks based on this field.

check this following code. I used solution #2. I have modified the Trigger and Apex Class 

Apex Trigger
 

trigger taskToCaseCreate on Task (after insert, after update) {
    if(checkRecursive.runOnce())
    {
        Map<Id,Task> newIdTaskMap = new Map<Id,Task>();

        for( Task T : Trigger.New ){

            if( T.WhoId != NULL && T.WhoId.startswith('003') && T.Subject.contains('Submitted Form') && ( Trigger.isInsert || (Trigger.isUpdate && Trigger.oldMap.get(T.Id).WhoId != T.WhoId) )  ){

                newIdTaskMap.put(T.Id, T);
            }
        }

        for( Case c : [SELECT Id, Task_Id__c  FROM Case WHERE Task_Id__c IN :newIdTaskMap.keySet()] )
            newIdTaskMap.remove(Task_Id__c);
        
        If(newIdTaskMap.size() > 0){

            createCaseFromTask.createCaseFromTask(newIdTaskMap.values());
        }
    }
}
 

Apex Class
 

public class createCaseFromTask {
    
    Public Static void createCaseFromTask(Task[] newTask){
        
        List<Case> newCase = new List<Case>();
        
         for (Task n:newTask){
             
            If (n.subject.contains('Demo') || n.Subject.contains('Contact')){
                Case c = new Case(ContactId = n.WhoId, Status = 'New', Subject = 'Demo Request', Task_Id__c = T.Id);
               // newCase.add(c);
                 Insert c;
            }     
            If( n.subject.contains('Content Download')){
                Case c = new Case(ContactId = n.WhoId, Status = 'New', Subject = 'Content Download', Task_Id__c = T.Id);
              //  newCase.add(c);
                 Insert c;
              
            }
            If( n.subject.contains('Webinar')){
                Case c = new Case(ContactId = n.WhoId, Status = 'New', Subject = 'Webinar', Task_Id__c = T.Id);
              //  newCase.add(c);
                 Insert c;
              
            }
            If( n.subject.contains('Blog')){
                Case c = new Case(ContactId = n.WhoId, Status = 'New', Subject = 'Subscribed to Blog Notifications', Task_Id__c = T.Id);
             //   newCase.add(c);
                 Insert c;
               
            }  
            If(!n.subject.contains('Blog') && !n.subject.contains('Webinar') && !n.subject.contains('Content Download') && !n.subject.contains('Demo') && !n.Subject.contains('Contact')){
                Case c = new Case(ContactId = n.WhoId, Status = 'New', Subject = 'Submitted Form', Task_Id__c = T.Id);
              // newCase.add(c);
                 Insert c;
              
            } 
            //  Insert newCase;
        }
    }

}

Hope this helps!

Thanks,
Alex 
This was selected as the best answer
Ashley Cobb 25Ashley Cobb 25
Sorry for the delay!! 

This works!! I used the code you uploaded above and just had to make a couple of changes (Task_ID__c = n.ID) but otherwise this is working perfectly in the sanbox.  Will be uploading it to prod this weekend!