-1

I have a custom object called Server_Order__c used in my customer portal which is mirrored to the Opportunities object, as well as mirroring the data I would also like to mirror any attachments that are uploaded.

A 'Service Order' object is a child of Opportunities object, each record contains a Opportunity__c foriegn key.

Here is my apex trigger as of now, but it does not seem to work.

trigger CopyAttachmentstoOpps on Attachment (after insert) {

    List<Attachment> insertAttList = new List<Attachment>();

    for (Attachment att:Trigger.new) {           
        String parentIdString = String.valueof(att.parentId);
        Service_Order__c oppId = [SELECT Opportunity__c FROM Service_Order__c WHERE ID = :att.parentId];
        system.debug('The ID is' + oppId);

        Attachment b = att.clone();
        b.parentid = parentIdString;
        insertAttList.add(b);                 
    }            
}

EDIT
My initial code has a trigger on Service Order updates, however the way Salesforce works when an attachment is uploaded it is stored in a child object hence no updates are made to the parent. I have modified my code accordingly but I am still unable to get it to work.

1

3 Answers 3

8
+50

I can see a number of things wrong with your initial code, and even your desired working trigger has a couple of issues with it.

In your initial code, you are setting the Parent ID of the Attachment to be that of the Service Order rather than the Opportunity, thus creating another attachment on the Service Order rather than the Opportunity (in fact, I'm surprised you didn't end up with some recursion errors doing this).

The second issue I see with your code is that it is not bulkified (however unlikely it is that multiple attachments are added at the same time, it is not inconceivable that it won't happen).

In your answer, I see that you are checking the object type is the correct one you are interested in, but the way in which you have done it means it will only work on the current org (which I am guessing is a Sandbox or DE) in which case it is possible that it could break when you deploy to production.

Here is a version that addresses those issues:

trigger CopyAttachmentsToOpps on Attachment (after insert) {

    // collect a set of Sales Order 'parent' IDs from the attachments inserted
    Set<Id> salesOrderIds = new Set<Id>();
    for(Attachment file : Trigger.new) {

        // only collect those that are for the Service_Order__c object (others can be ignored)
        if(file.ParentId.getSObjectType() == Service_Order__c.getSObjectType()) {
            salesOrderIds.add(file.ParentId);
        }
    }


    if(!salesOrderIds.isEmpty()) {

        // find the Opportunity to which the Service_Order__c relates
        Map<Id,Service_Order__c> serviceOrderMap = new Map<Id,Service_Order__c>([Select Opportunity__c From Service_Order__c Where Id IN :salesOrderIds]);        

        List<Attachment> attachments = new List<Attachment>();

        for(Attachment file : Trigger.new) {
            Attachment newFile = file.clone();
            newFile.ParentId = serviceOrderMap.get(file.ParentId).Opportunity__c;
            attachments.add(newFile);
        }
        // finally, insert the cloned attachments
        insert attachments;
    }


}
1

Here is your error : ParentId = :Trigger.new[0].name];

Attachment[] attList = [select id, name, body from Attachment 
                        where  ParentId = :Trigger.new[0].name];

This is code which helps you. And when ever you update the record Service_Order__c new attachment is created under opportunity if Service_Order__c contains any attachment.

trigger CopyAttachments  on Service_Order__c (after update) 
{
    List<Attachment> insertAttList = new List<Attachment>();
    Set<id> parentRecordId = Trigger.newMap.keySet();
    Map<String,List<Attachment>> parentWithAttachment= new Map<string,List<Attachment>>();

    for(Attachment att : [select id, name,parentId, body from Attachment where ParentId in :parentRecordId ])
    {
        if(parentWithAttachment.containsKey(att.parentId) )
        {
            List<Attachment> t = parentWithAttachment.get(att.parentId);
            t.add(att);
            parentWithAttachment.put(att.parentId,t);
        }else{
            List<Attachment> t = new List<Attachment>();
            t.add(att); 
            parentWithAttachment.put(att.parentId,t);
        }
    }

    for(String s : parentWithAttachment.keySet())
    {
        for(Attachment a :parentWithAttachment.get(s))
        {
            Attachment  b = a.clone();
            b.parentid = Trigger.newMap.get(s).Opportunity__c;
            insertAttList.add(b); 
        }
    }

    if(insertAttList.size()>0)
    insert insertAttList;

}
5
  • Just to make sure I am actually creating the trigger and the right action, does adding just an Attachment (via Notes & Attachments) equate to the Service Order being updated? because I have tried your code and it is not working. Commented Jul 9, 2014 at 15:48
  • I posted again code and it is working at my end just changed the object(Parent_Object__c to your object name) and field (protecitonTest__Contact__c to opportunity__c)
    – D-Horse
    Commented Jul 9, 2014 at 16:01
  • I've tried both codes, neither of them work. I have tried to find the debug messages in my log (via Developer Console) but nothing is there. As I mentioned earlier, when simply attachments are added to the record is the record itself updated or are the Attachments uploaded to its own object linking back to Service Orders object? Commented Jul 10, 2014 at 9:05
  • Just done some more testing, as I thought (fault on my part) the attachments get copied over when the contents of the record is updated/modified but not simply when an attachment has been added to the record. I believe attachments are uploaded to their own object and linked back bia parentId. I have updated my question. Commented Jul 10, 2014 at 9:28
  • Yes attachment are uploaded at their own object they just have reference to parent object. And when attachment is uploaded under a record, that record will not update only attachment is uplaoded as attachment is child object for that record.
    – D-Horse
    Commented Jul 10, 2014 at 10:04
0

Hi run my below code and it is working at my end

Parent_Object__c is object in my org and I am updating the record of this protecitonTest__Contact__c is field on Parent_Object__c object where my newly attachment is created.

trigger CopyAttachments  on Parent_Object__c  (after update) 
{

   //    stack exchange questiong 
    List<Attachment> insertAttList = new List<Attachment>();
    Set<id> parentRecordId = Trigger.newMap.keySet();
    Map<Id,List<Attachment>> parentWithAttachment= new Map<id,List<Attachment>>();

    system.debug('::::::::::::'+parentRecordId );    
    for(Attachment att : [select id, name,parentId, body from Attachment where ParentId in :parentRecordId ])
    {
        if(parentWithAttachment.containsKey(att.parentId) )
        {
            List<Attachment> t = parentWithAttachment.get(att.parentId);
            t.add(att);
            parentWithAttachment.put(att.parentId,t);
        }else{
            List<Attachment> t = new List<Attachment>();
            t.add(att); 
            parentWithAttachment.put(att.parentId,t);
        }
    }
    system.debug('::::::::::::'+parentWithAttachment);    


    for(String s : parentWithAttachment.keySet())
    {
        for(Attachment a :parentWithAttachment.get(s))
        {
            Attachment  b = a.clone();
            b.parentid = Trigger.newMap.get(s).protecitonTest__Contact__c;
            insertAttList.add(b); 
        }
    }
     system.debug(':::insertAttList:::::::::'+insertAttList);    
    if(insertAttList.size()>0)
    insert insertAttList;

}
2
  • This isn't going to work since the trigger event is going to be on the attachment object not the parent object. Commented Jul 16, 2014 at 0:13
  • Yes you are right Ralph, I think I did some mistake to understand the question, I just wrote above code when user update parent record.
    – D-Horse
    Commented Jul 16, 2014 at 5:12

You must log in to answer this question.

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