+ Start a Discussion
Alex Wong 4Alex Wong 4 

How to write a trigger for renaming attachments in custom objects?

I am quite new for salesofrce and I want to write a trigger to modify attachments name after user inserting the attachments. For my situation, my page is form for public input their information. It includes 3 question that requires users to insert attachments. One question can allow users to upload 1-3 attachmetns, and the other two require only 1. Since I want to classify them from the their name, I want a trigger to rename the attachments after insert. Thank you for your great effort.
Best Answer chosen by Alex Wong 4
VineetKumarVineetKumar
Something like this :
objAttachment.Name = Artist.Id+'_'+UserInfo.getName()+'_'+String.valueOf(system.today())+'_Q';

All Answers

VineetKumarVineetKumar
Can you share your code here?
Yes you have to write a trigger on Attachment, running in after insert context.
Alex Wong 4Alex Wong 4
My code is here:
public class extattachfile {
    Public attachment objAttachment{get;set;}
    Public attachment objAttachment2{get; set;}
    Public attachment objAttachment3{get; set;}
    Public attachment objAttachmentt{get; set;}
    Public attachment objAttachments{get; set;}
    Public Artist__c artist{get; set;}
    Public extattachfile(apexpages.standardcontroller stdCon) {
        objAttachment = new Attachment();
        objAttachment2 = new Attachment();
        objAttachment3 = new Attachment();
        objAttachmentt = new Attachment();
        objAttachments = new Attachment();
        artist= new Artist__c ();
    }
    public PageReference save() {
        Boolean checkAttachment = false;
        Boolean isValidUrl = true;
        if(artist.Id == null){
            if(artist.Website__c != null){
                Pattern emailPattern = Pattern.compile('^((http|https)://)??(www[.])??([a-zA-Z0-9]|-)+?([.][a-zA-Z0-9(-|/|=|?)??]+?)+?$');
                Boolean isMatch = emailPattern.matcher(artist.Website__c).matches();
                if(!isMatch){
                    objAttachment.Body = null;
objAttachment2.Body = null;
objAttachment3.Body = null;
objAttachmentt.Body = null;
objAttachments.Body = null;
                    ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR, 'Please provide a valid Website URL.'));
                    isValidUrl = false;
                }
            }
            if(artist.Facebook__c != null){
                Pattern emailPattern = Pattern.compile('^((http|https)://)??(www[.])??([a-zA-Z0-9]|-)+?([.][a-zA-Z0-9(-|/|=|?)??]+?)+?$');
                Boolean isMatch = emailPattern.matcher(artist.Facebook__c).matches();
                if(!isMatch){
                    objAttachment.Body = null;
objAttachment2.Body = null;
objAttachment3.Body = null;
objAttachmentt.Body = null;
objAttachments.Body = null;
                    ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR, 'Please provide a valid Facebook URL.'));
                    isValidUrl = false;
                }
            }
            if(artist.SoundCloud__c != null){
                Pattern emailPattern = Pattern.compile('^((http|https)://)??(www[.])??([a-zA-Z0-9]|-)+?([.][a-zA-Z0-9(-|/|=|?)??]+?)+?$');
                Boolean isMatch = emailPattern.matcher(artist.SoundCloud__c).matches();
                if(!isMatch){
                    objAttachment.Body = null;
objAttachment2.Body = null;
objAttachment3.Body = null;
objAttachmentt.Body = null;
objAttachments.Body = null;
                    ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR, 'Please provide a valid Soundcloud URL.'));
                    isValidUrl = false;
                }
            }
            if(artist.YouTube__c != null){
                Pattern emailPattern = Pattern.compile('^((http|https)://)??(www[.])??([a-zA-Z0-9]|-)+?([.][a-zA-Z0-9(-|/|=|?)??]+?)+?$');
                Boolean isMatch = emailPattern.matcher(artist.YouTube__c).matches();
                if(!isMatch){
                    objAttachment.Body = null;
objAttachment2.Body = null;
objAttachment3.Body = null;
objAttachmentt.Body = null;
objAttachments.Body = null;
                    ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR, 'Please provide a valid Youtube URL.'));
                    isValidUrl = false;
                }
            }
            if(isValidUrl){
                insert artist;
            }else{
                return null;
            }
        }
        List<Attachment> attachmentList = new List<Attachment>();
        if(objAttachment.Body != null){
            objAttachment.ParentId = artist.id;
            attachmentList.add(objAttachment);
            checkAttachment = true;
        }
        if(objAttachment2.Body != null){
            objAttachment2.ParentId = artist.id;
            attachmentList.add(objAttachment2);
            checkAttachment = true;
        }
        if(objAttachment3.Body != null){
            objAttachment3.ParentId = artist.id;
            attachmentList.add(objAttachment3);
            checkAttachment = true;
        }          
        List<Attachment> attachmentListother = new List<Attachment>();
        if(objAttachmentt.Body != null){
            objAttachmentt.ParentId = artist.id;
            attachmentList.add(objAttachmentt);
        }
        if(objAttachments.Body != null){
            objAttachments.ParentId = artist.id;
            attachmentList.add(objAttachments);
        }
        Insert attachmentListother;
        if(attachmentList.size() > 0 && checkAttachment){
            insert attachmentList;
            attachmentList = null;
            // if successfully inserted new contact, then displays the thank you page.
            return Page.ack;
        }else{
            ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR, 'Please attach at least one photo attachment.'));
            return null;
        }             
    }
}

 
VineetKumarVineetKumar
you can update the objAttachment.Name field with your custom name
Alex Wong 4Alex Wong 4
How can I achieve this? 
Example:
There should be 3 type of attachment, A, B and C. For example, team A submit the form. I want the attachments to be TeamA_A.
Thank you.
VineetKumarVineetKumar
What is TeamA_A, is this the user?
Alex Wong 4Alex Wong 4
3 Questions: QA, QB, QC
If the user is call UserA, I want the name of the attachments input become UserA_QA, UserA_QB and UserA_QC.
Thank you.
VineetKumarVineetKumar
You can do something like :
if(objAttachment.Body != null){
    objAttachment.ParentId = artist.id;
    objAttachment.Name = UserInfo.getUserName+'_QA';
    attachmentList.add(objAttachment);
    checkAttachment = true;
}
if(objAttachment2.Body != null){
    objAttachment2.ParentId = artist.id;
    objAttachment.Name = UserInfo.getUserName+'_QB';
    attachmentList.add(objAttachment2);
    checkAttachment = true;
}
if(objAttachment3.Body != null){
    objAttachment3.ParentId = artist.id;
    objAttachment.Name = UserInfo.getUserName+'_QC';
    attachmentList.add(objAttachment3);
    checkAttachment = true;
}
Alex Wong 4Alex Wong 4
Sorry, what is "UserInfo.getUserName" stands for?
Alex Wong 4Alex Wong 4
And one more question. How can I get the id of the record when the user insert the record? Because at this moment I have another idea for the attachment name. The name should be (RecordID)_(UserName)_(DateOfCreate). Since this form is public, there are no know users. 
Data for UserName should be the data insert by the public and the data will be inserted into a field of custom object (API Name: Artist_English_Name__c)
Thank you.
 
VineetKumarVineetKumar
My bad, it is supposed to be UserInfo.getName() - gives the name of the logged in user
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_userinfo.htm
VineetKumarVineetKumar
For appending the Id, you will have to write a trigger on Attachment object, to prefix the attachment Id to the name
Alex Wong 4Alex Wong 4
How a trigger can achieve this? And where should we call the trigger?
To be specify, the format of name should be like this: (RecordID)_(UserName)_(DateOfCreate)_(QA). Can a trigger identify which attachment belongs to which question?
VineetKumarVineetKumar
I assume that by recordId you mean the record Id of the attachment that is inserting
Alex Wong 4Alex Wong 4
Sorry for making you misunderstand it. 
(RecordID)_(UserName)_(DateOfCreate)_(Q)
RecordID is the name of the record of custom object.
UserName is the data insert by users in the field "Artist_English_Name__c"
DateOfCreate is the date of creating the record of custom object.
Q is the question that the attachment belongs to.
Because I want to trace back the attachment ie owned by who and which question. 
Really appreciate your effort, thank you.
VineetKumarVineetKumar
Something like this :
objAttachment.Name = Artist.Id+'_'+UserInfo.getName()+'_'+String.valueOf(system.today())+'_Q';
This was selected as the best answer
Alex Wong 4Alex Wong 4
Big thanks!!! I modify it to :
objAttachment.Name = artist.Id+'_'+artist.Artist_Group_Name_English__c+'_'+String.valueOf(system.today())+'_Attachment1';
One last thing, how can I get file format of the attachment and paste it to the end of the file name? The above method seems to delete the file format in the name. Because when I export the attachement, I need the file name indicating the file type to recover the whole file, otherwise, it will be like this. 
User-added image
The method is below:
https://help.salesforce.com/apex/HTViewSolution?id=000007269&language=en_US

Thank you!
 
VineetKumarVineetKumar
You need to set the content type of the attachment,
https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_objects_attachment.htm
objAttachment.contentType = 'application/msword';
Below link you can refer for the valid values:
http://salesforce.stackexchange.com/questions/102542/valid-values-for-contenttype​ (http://salesforce.stackexchange.com/questions/102542/valid-values-for-contenttype)
And this link as well
http://help.salesforce.com/HTViewSolution?id=000187992&language=en_US
Alex Wong 4Alex Wong 4
But I do not know what type of attachment I will recieve. Is there any method to keep the letter after the "." in the original name, then paste the name of what we have done so far? Thank you.
Alex Wong 4Alex Wong 4
At this stage, I can only achieve this:

Here is my code:
objAttachmentt.Name = artist.Id+'_'+artist.Artist_Group_Name_English__c+'_'+String.valueOf(system.today())+'_Technical'+'_'+objAttachmentt.Name;

The example:
"a002800000i5q8UAAQ_Alex_2016-08-03_Technical_field2.png"

With this code, I can retain the the file type in the name. But I still want to delete the original attachment name ("field2" in this case), coz it may be too long for the name. Is there any way to only mantain ".png" in this case, instead of "field2.png"?

Thank you.
VineetKumarVineetKumar
from where is field2 coming, can you share the code from your class?
Alex Wong 4Alex Wong 4
Oh sorry for making you confused. field2 is the name of the png. Or you assume the photo is call "photo.png". 
Here is the recent result: "a002800000i5q8UAAQ_Alex_2016-08-03_Technical_photo.png"
with this code: 
objAttachmentt.Name = artist.Id+'_'+artist.Artist_Group_Name_English__c+'_'+String.valueOf(system.today())+'_Technical'+'_'+objAttachmentt.Name;
But I want it to be: ""a002800000i5q8UAAQ_Alex_2016-08-03_Technical.png""

Thank you.
VineetKumarVineetKumar
They way you are setting the name is wrong, it will always append field2 to the name, it should be something like this
objAttachmentt.Name = artist.Id+'_'+artist.Artist_Group_Name_English__c+'_'+String.valueOf(system.today())+'_Technical';
objAttachmentt.contentType="image/png";
Setting the content type will automatically append png to the name.
Alex Wong 4Alex Wong 4
Sorry VineetKumar... png is just only an example. I really can't expect which type of attachment will the users upload. They may upload zip, pdf, jpg, png etc. How can I solve this problem? Thank you.