0

how's it going?

Basically what I need is to prevent a task being created when a case status is 'Closed'.I'm struggling with my code, I just can't get the right Id of the case where I'm creating a task. I'm going to explain what I did and what I got so far:

  1. Take a look at the first picture below, and see that the Case id is "5003i000001nd7YAAQ" and the "Status" field is populated with "Closed".

enter image description here

  1. I clicked on the option "New Task" in the related list "Open Activities" and then I tried to create a task. Then the trigger message error pops up. It's ok by then...

enter image description here

...but when I was viewing the debug log (Code 1) I noticed that the Case id was not equals to "5003i000001nd7YAAQ", it was actually "5003i000001nd7KAAQ".

After trying to create a new task the trigger was activated

I tried a lot of things to get this over, but I just couldn't get this done. I don't know another way of meeting this goal unless using trigger, but I'm a newbie at coding. I used "before insert" to my trigger. Look at my first and second code below:

Code 1

Trigger CaseClosed on Task(Before Insert) {    
    List<Case> mySOQL = [SELECT Status FROM Case WHERE Status = 'Closed'];

    String temp0 = mySOQL[0].status; String temp1 = mySOQL[0].Id;
    System.debug(temp0); 
    System.debug(temp1);

    for (Task a : Trigger.new) {
        if('Closed'.equals(temp0)){
            a.addError('Is not allowed to create tasks when a case is closed.');
        }               
    }      
} 

Code 2 - It also didn't return the right case Id

Trigger CaseClosed on Task(Before Insert) {    
                List<Task> lstTask = [SELECT WhatId FROM Task 
                                      WHERE What.Type = 'Case'
                                      ORDER BY SystemModStamp ASC];
                System.debug(lstTask);    
            }

This two codes were the closest I've got. I tried other things, but they were way off the mark. Could you please help me out? I don't know what to do.

2 Answers 2

3

You need to filter by the WhatId for the records. The ID you got was some random case in the database that was closed. Here's what you're looking for:

trigger preventTaskOnClosedCase on Task (before insert) {
    Set<Id> caseIds = new Set<id>();
    for(Task record: Trigger.new) {
        if(record.WhatId != null && record.WhatId.getSObjectType() == Case.sObjectType) {
            caseIds.add(record.WhatId);
        }
    }
    if(caseIds.isEmpty()) {
        return; // Not dealing with any cases this time
    }
    caseIds.retainAll(
    new Map<Id, Case>([
        SELECT Id FROM Case WHERE Id = :caseIds AND IsClosed = TRUE
    ]).keySet()
    );
    for(Task record: Trigger.new) {
        if(caseIds.contains(record.WhatId)) {
            record.addError('You may not create a task on a closed case.');
        }
    }
}

This is what I call the Aggregate Query Update Pattern. You aggregate the values to query from the database (lines 3-7), then query the database (lines 11-15), then perform an "update" (in this case, an error message) (lines 16-20).

1
  • Awesome, I can't thank you enough! The solution and explanation were great! Thank you so much for helping me out! Commented Jan 19, 2020 at 15:40
0

You need to use the WhatId in order to get the related cases.

See my comments inline:

Trigger CaseClosed on Task(Before Insert) {    

    Set<Id> caseIds = new Set<Id>(); 
    Set<Id> closeCaseIds = new Set<Id>(); 
    //get all the case ids that are related to the new tasks
    for (Task t : Trigger.new) {
        if(t.WhatId != null && String.valueOf(t.WhatId).startsWith('500')){
            caseIds.add(t.WhatId);
        }
    }
    //make sure that you only query the related cases and not all of them (note the Id in : caseIds)
    // We query only closed cases that are associated to the Trigger.New which means all the new tasks
    List<Case> mySOQL = [SELECT Status FROM Case WHERE IsClosed = True AND Id  in : caseIds]; 
    //load all the case ids into a set, this will help because then we can use the Contains() function
    for(Case c : mySOQL){
        closeCaseIds.add(c.Id);
    }
    //for each task, check if the set contains the WhatId (i.e. the case id). If it does contain, it means that the task was added to a closed case so we throw an error
    for(Task t : Trigger.new){
        if(closeCaseIds.contains(t.WhatId)){
            t.addError('Is not allowed to create tasks when a case is closed.');
        }
    }     
} 
1
  • Thank you so much for helping me! Both explanations were so good, I really liked it! Both codes worked well, and now I got it how to make this works. And again, thank you! Commented Jan 19, 2020 at 20:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .