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.

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).

| improve this answer | |
  • Awesome, I can't thank you enough! The solution and explanation were great! Thank you so much for helping me out! – Matheus Antonio Jan 19 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.');
        }
    }     
} 
| improve this answer | |
  • 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! – Matheus Antonio Jan 19 at 20:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.