[SalesForce] Code in a @future method not working

I am trying to write a trigger that will transfer attachments from a Task object to the related Opportunity object from emails & attachments using Salesforce for Outlook. I have the basic trigger code written to do the transfer. But after some research I found that the WhatId is not available after insert when created from SFO. I found that you can call a @future method to then complete the transfer if the WhatId is Null.

The problem is that in the @future method I am looping through the list of tasks collected from the Ids passed to it. I am then querying to find the attachments linked to the task. I know I should not put SOQL inside the loop but a subquery would not allow the select of the body of the attachments. I will clean it up later. But I still do not understand why the reference to the task iteration variable in the select statement will not return any results. The exact same loop structure and select are in the base trigger and work fine.

Like I said I will clean this up to be better code, but I am trying to finish this for a demo that will show we can modify the default actions of Salesforce for Outlook as far as the attachments go.

I will include both the trigger code and class code along with a sample of the log.

        trigger Task_Transfer_Attachments on Task (after insert, after undelete) {
    //Create a List to store the Ids of Attachments to be deleted
    List<Id> forDeletionIds = new List<Id>();
    List<Id> tasks = new List<Id>();
    //List<Attachment> AttachToUpdate = new List<Attachment>();
    for (Task t : trigger.new){
        String taskWhatId = String.valueof(t.WhatId);
        if (taskWhatId == null){
             tasks.add(t.Id);
             System.debug('~~~~~~ WhatId String =' + t.WhatId ); 
             Continue;
        }
        //Get the attachments for the task
            System.debug('~~~~~~ Parent String =' + t.WhatId ); 
        for(Attachment AttachToUpdate :  [select id,name,body from Attachment where parentid = :t.Id ]){
            //Check if the task is related to an opportunity
            if (taskWhatId.substring(0,3) == '006' ){   
                    Attachment newA = New Attachment(
                        Name = AttachToUpdate.Name,
                        Body = AttachToUpdate.Body,
                        //ContentType = 'image/jpeg',
                        //Description = 'Account Photo',
                        OwnerId = t.OwnerId,
                        ParentId = t.WhatId
                    );
                    //Insert the new Attachment
                    insert newA;
                    //Add the now duplicate Attachment ID to a list
                    forDeletionIds.add(AttachToUpdate.Id); 
                //}
            }
        }
    }
    //Call a @future method to transfer attchments created by SFO
    if (tasks.size() > 0) {
        System.debug('~~~~~~ Call Future Method =' + tasks ); 
        Task_Transfer_Future.FutureTransferAttachMethod(tasks);
    }
    //List and then delete all duplicate Attachments
    List<Attachment> forDeletion = [SELECT Id FROM Attachment WHERE Id IN :forDeletionIds];
    delete forDeletion;
    }

public with sharing class Task_Transfer_Future {
 @future
    public static void FutureTransferAttachMethod(List<id> taskIds){
        List<Id> forDeletionIds = new List<Id>();
        list <id> tasks = taskIds;
        //list <Attachment> AttachToUpdate = new list <Attachment>();
        list <task> theTasks  = [select Id, WhatId, OwnerId from task  where ID IN :tasks];
        for (task t : theTasks){
            String taskWhatId = String.valueof(t.WhatId);
            //Get the attachments for the task
                System.debug('~~~~~~ What ID = ' + t.WhatId + ' t.Id = ' + t.id ); 
            list <Attachment> AttachToUpdate = [select id,name,body from Attachment where parentid = :t.id ];
            for(Attachment a : AttachToUpdate ){
                if (taskWhatId.substring(0,3) == '006' ){ 
                    System.debug('~~~~~~ Loop Attach  =' + a.Id );   
                        Attachment newA = New Attachment(
                            Name = a.Name,
                            Body = a.Body,
                            OwnerId = t.OwnerId,
                            ParentId = t.WhatId
                        );
                        //Insert the new Attachment
                        insert newA;
                        //Add the now duplicate Attachment ID to a list
                        forDeletionIds.add(a.Id); 
                }
            }
        }
        //List and then delete all duplicate Attachments
        List<Attachment> forDeletion = [SELECT Id FROM Attachment WHERE Id IN :forDeletionIds];
        delete forDeletion;
    }
}

Log sample:

    |USER_DEBUG|[11]|DEBUG|~~~~~~ What ID = 0067000000azvv8AAA t.Id = 00TV0000008DqwuMAC
    SYSTEM_METHOD_EXIT|[11]|System.debug(ANY)
    SOQL_EXECUTE_BEGIN|[12]|Aggregations:0|SELECT id, name, body FROM Attachment WHERE parentid = :tmpVar1
    SOQL_EXECUTE_END|[12]|Rows:0

Best Answer

It seems like your list<Id> tasks will always be a list of null values if there are any at all. I think this line in your trigger:

if (taskWhatId == null){

Should be changed to

if (taskWhatId != null){

Now it will be gathering the Tasks that have WhatIds. Currently it is only gathering if the Task has no WhatId, then sending such a Task to the future method.

Related Topic