0

I'm new to Apex Developing and I'm facing pretty strange issue with my code.

I've recently write queueable class to check custom checkbox on Case Alert_view__c. The idea is that checkbox will be set to FALSE, when all milestones of Case are completed (IsCompleted==true).

Here goes my code:

global class QueueableCaseAlertRemoval implements Queueable {
global void execute(QueueableContext context) {
    CaseAlertRemoval();
}
public void CaseAlertRemoval(){

    List<Case> casesWithAlert = [SELECT Id, Alert_view__c, (SELECT Id, IsCompleted, CompletionDate, CaseId FROM CaseMilestones)
                                 FROM Case 
                                 WHERE Alert_view__c=true];

    List<Case> casesToUpdate = new List<Case>();    

    //Check case with alert and make alert unchecked when all milestones are completed
    for(Case c : casesWithAlert){

       Boolean isAllCompleted = true;
       for(CaseMilestone cm : c.casemilestones){
           isAllCompleted &= cm.IsCompleted;
       }

       if(isAllCompleted){
           casesToUpdate.add(new Case(Id = c.Id, Alert_view__c = false)); 
       } 

    }

    try{
        if(!casesToUpdate.isEmpty()){
            update casesToUpdate;
        }
    } catch(Exception e) {
        for(Case c : casesToUpdate){
            c.adderror(e.getMessage());
        }
    }
}     

}

This code passed successfully my tests and I've added it to the queue just by calling my queueable class. The problem is... It doesn't work. Checkbox remains TRUE when all milestones are complete. Maybe I've added wrong this method to queue? I really don't know.

I'll be very pleased if someone more experienced will find out what is wrong with this class, because me and my team colleagues can't figure it out.

Thanks a lot!

1

addError is meaningless in this context, because it won't be reported anywhere. Also, you're in a normal asynchronous context, which means you're still limited by certain rules, such as the 10k DML row limit and the 50k SOQL row limit. You need to check your debug logs to see if an exception was thrown. If your intent is to process the entire database, you'll want to use Batchable instead of Queueable in order to break the task up into smaller transactions. That aside, your code is unnecessarily complex; you could probably do this:

global class BatchableCaseAlertRemovable implements Database.Batchable<SObject> {
    global Database.QueryLocator start(Database.BatchableContext context) {
        return Database.getQueryLocator([SELECT Id FROM Case WHERE Alert_View__c = TRUE]);
    }
    global void execute(Database.BatchableContext context, Case[] scope) {
        Set<Id> completedCases = new Map<Id, AggregateResult>(
             [SELECT CaseId Id FROM CaseMilestone
              WHERE CaseId IN :scope AND IsCompleted = FALSE
              GROUP BY CaseId]
        ).keySet();
        Case[] updatedCases = new Case[0];
        for(Case record: scope) {
            if(!completedCases.containsKey(record.Id)) {
                updatedCases.add(record);
                record.Alert_View__c = false;
            }
        }
        Database.SaveResult[] results = Database.update(updatedCases, false);
        // Process errors here
    }
    global void finish(Database.BatchableContext context) {
    }
}

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.