3
Database.DMLOptions dm = new Database.DMLOptions();
dm.EmailHeader.triggerUserEmail = true;

Task t = new Task(Subject='Test Task', ActivityDate=date.today(), OwnerId='00590000000wND2');
database.insert(new Task[]{t}, dm);

Email Notifications are enabled for user in My Settings:

enter image description here

Global Settings for Allow User to control Notifications also Enabled:

enter image description here

Based on these settings the Email Notification should have received by the User. And the OwnerId passed in the code is NOT the Logged In User, so the code should have triggered email notifications. Please correct me if I'm wrong, but it looks like something is broken here. The code sends out Email Notifications ONLY when I've disabled the Enable User Control Over Task Assignment Notifications globally for all users.

After doing more debugging I found that normal APEX does work fine but the issue exist in Batch Apex.

Try following Visualforce Page/Classes. The Notifications work in case of button calling controller class function but does not work when another button calls the same function using Batch Apex.

Visualforce Page Code:

<apex:page controller="NotificationsTest">
<apex:form>
    <apex:commandButton action="{!createTask}" value="Create New Task" />
    <apex:commandButton action="{!createTaskBatch}" value="Create New Task (batch)" />
</apex:form>
</apex:page>

APEX Controller Class:

public with sharing class NotificationsTest {
    public NotificationsTest() {

    }
    public void createTask() {
        Database.DMLOptions dm = new Database.DMLOptions();
        dm.EmailHeader.triggerUserEmail = true;

        Task t = new Task(Subject='Test Task', ActivityDate=date.today(), OwnerId='00590000003uTpH');
        database.insert(new Task[]{t}, dm);
    }

    public void createTaskBatch() {
        NotificationsTestBatch taskBatch = new NotificationsTestBatch();
        Database.ExecuteBatch( taskBatch );
    }
}

Batch APEX Class:

global with sharing class NotificationsTestBatch implements Database.Batchable<SObject>, Database.Stateful{

    /**
    * Constructor
    */
    public NotificationsTestBatch() {

    }

    /**
    * Use the start method to collect the records or objects to be passed to the interface method execute
    */
    global Iterable<sObject> start( Database.BatchableContext bc ){         
        return [select Id, Name from Account];
    }

    /**
    *
    * @param bc
    * @param data
    */
    global void execute( Database.BatchableContext bc, List<SObject> data ){
        try{
            NotificationsTest n = new NotificationsTest();
            n.createTask();
        }catch(Exception e){

            AsyncApexJob a = [Select Id, Status, NumberOfErrors, JobItemsProcessed,
                                TotalJobItems, CreatedBy.Email,ExtendedStatus
                                from AsyncApexJob where Id =
                                :bc.getJobId()];
            // If there were any errors Send an email to the Apex job's submitter 
            // notifying of job completion       
            Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
            String[] toAddresses = new String[] {a.CreatedBy.Email};
            mail.setToAddresses(toAddresses);
            mail.setSubject('EXCEPTION during Batch creation  ' + a.Status);
            mail.setPlainTextBody ('The batch Apex job processed ' + a.TotalJobItems + ' batches.\n\nError :'+e+'\n\nError Detail: '+e.getStackTraceString()+'\nLine Number: '+e.getLineNumber()+'\nType: '+e.getTypeName());

            Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });

        }
    }

    /**
    *
    */

    global void finish(Database.BatchableContext BC){/**/}

}

When I click "Create Task" button, it initiates a normal APEX class function, and in that way I receive Task Assignment Notification.

But when I click "Create Task (batch)" button, it initiates a Batch apex call to the function and that does not send any Task Assignment Notification. I don't see anywhere in the docs that confirms this theory, by logic, the notifications should work correctly even from Batch Apex, as it is APEX Api.

Based on this documentation:

http://docs.releasenotes.salesforce.com/nl-nl/winter15/release-notes/rn_sales_activities_notifications_task_assignment.htm

EDIT - 3-May-2015 : It definitely was a bug in platform, but no one recognized it. I could very well reproduce it following code posted in here, but a quick test in Summer '15 Pre-release organization revealed that it has been fixed. I could not reproduce it Summer 15 Org but could reproduce that Batch Apex generated Tasks were not sending Task Notifications.

2

I see three issues here:

  1. createTask() doesn't really belong in the controller class - it is a service available to both VF and batch use cases and belongs in a service layer - see Separation of Concerns | service layer
  2. Your execute() method needs to batch (bulk) create Tasks and insert once, not do DML for each data in execute()'s scope
  3. Your Tasks are created without a whoId or whatId

Note you can also support partial update successes if desired by using the optAllOrNone argument to `Database.insert(..)' - but if you do so, no exception is thrown. See doc:

You can do so by passing an additional second Boolean parameter. If you specify false for this parameter and if a record fails, the remainder of DML operations can still succeed. Also, instead of exceptions, a result object array (or one result object if only one sObject was passed in) is returned containing the status of each operation and any errors encountered. By default, this optional parameter is true, which means that if at least one sObject can’t be processed, all remaining sObjects won’t and an exception will be thrown for the record that causes a failure.

| improve this answer | |
  • Thanks for your input @crop1645. I would like to clarify first, the sample code I added is a prototype sample only to reproduce the issue its not a production level code. I just wanted to make my case that Task Notifications are sending out in usual Controller-VF relationship but not in Batch Apex relationship. Also, the original code of my app is spanned over multiple classes and you can relax about catching errors as I am doing that but to keep this example clean I removed that part. Thirdly, missing Who/What ID does not matter, notifications are sent to Assigned Owner only. – VarunC Apr 25 '15 at 4:04
  • And if you follow the example I've set above, notifications are sent for same Task if we use normal controller function, but for same Task, notifications are not sent from Batch Apex. The idea of batch apex here is "asynchronous" operation, which is broken in some way here, while synchronous operation is working fine. And moreover, there are no Errors occurring, since the Tasks are created from both operations correctly and I can See them in "My Tasks" Home Page Component for the User who is Assigned the tasks. – VarunC Apr 25 '15 at 4:05
  • Varun - didn't mean to impugn your technical skills and sorry I lumped you in with other posters who are more 'newbie' in SFDC conventions. Reading your post more closely suggests you have sufficient evidence to file a support case – cropredy Apr 26 '15 at 15:45
  • no worries, we're cool :-) .. I am in fact glad at least after waiting for long someone responded... I've opened up sfdc case, but I suspect they usually close all Dev related cases without even considering a reason. – VarunC Apr 26 '15 at 17:36
  • if you have premier support, I've found that they will in fact research it - provided you give them access to your dev environment and a reproducible test case - it may take 2 weeks to get a response, which could very well be "Known Issue" or "Works as Designed". In the former case, unless enough users are affected, when it gets fixed could be a long time – cropredy Apr 26 '15 at 18:50

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.