I've button when i click on it it generates new file , i want to attach that file to email The problem i'm facing is that i found duplicate attachments when i click on button twice , 3 attached file when i click on button 3rd time .. ..


 public void sendPDF() {
    PageReference pdf = Page.CRequest2;

    Attachment attach = new Attachment();

    Blob body;


        if(!test.isRunningTest()) body = pdf.getContentAsPDF();
        if(test.isRunningTest()) body = Blob.valueof('Some random String');
        system.debug('got the body');

        ContentVersion contVer = new ContentVersion(Title='Goldstar Request  '+this.catrequest.Account__r.Name + ' ' + this.catreq.Name , VersionData = EncodingUtil.base64Decode('Unit Test Attachment Body'), PathOnClient ='/Catalog.pdf');
        List<ContentDocumentLink> docLinks = [
                SELECT Id, ContentDocumentId 
                FROM ContentDocumentLink 
                WHERE LinkedEntityId = :this.catrequest.id
        // check if file already exists, 
        // if yes, insert a newer ContentVersion by specifying the ContentDocumentId
        if (!docLinks.isEmpty()) {
            contVer.ContentDocumentId = docLinks[0].ContentDocumentId;

        // if file didn't exists before
        // insert a new ContentDocumentLink
        if (docLinks.isEmpty()) {
            ContentDocumentLink contentlink = new ContentDocumentLink();
            contentlink.LinkedEntityId = this.catrequest.Id;
            contentlink.ContentDocumentId = [SELECT ContentDocumentId FROM ContentVersion WHERE Id =:contVer.Id].ContentDocumentId;
            contentlink.ShareType = 'V';
            insert contentlink;

         //Now email the catalog Request
        String currentUserEmail = UserInfo.getUserEmail();
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        String[] toAddresses = new String[]{currentUserEmail,'SamplesGS@goldstar-europe.com'};


      // String plainBody = 'https://goldstar1.lightning.force.com/'+this.catrequest.id;
        // string formattedDate = this.catrequest.Request_Date__c.day() +'/'+this.catrequest.Request_Date__c.month() +'/'+this.catrequest.Request_Date__c.year();
       String subject = 'Goldstar Request : ' +this.catrequest.account__r.BillingCountry  +', ' + this.catrequest.Requested_By_Internal__r.FirstName  +' '+ this.catrequest.Requested_By_Internal__r.LastName +', Distributor : '+ this.catrequest.account__r.name+' '+this.catrequest.Name ;

      List<Messaging.EmailFileAttachment> attachments = new List<Messaging.EmailFileAttachment>();

        if(contVer != null){
            Messaging.EmailFileAttachment attachment = new Messaging.EmailFileAttachment();

        //query for any files attached to the catalog request and include them in the email
    set<id> docIds = new set<id>();

        list<contentdocumentlink> links = [Select Id,contentdocument.id from ContentDocumentLink where LinkedEntityId = :this.catrequest.id];
        For(contentdocumentlink l: links){
        list<contentversion> versions = [SELECT ContentDocumentId,VersionData,FileExtension,FileType,Id,Title FROM ContentVersion where ContentDocumentId IN: docids];

        for(contentversion a: versions){
            Messaging.Emailfileattachment efa = new Messaging.Emailfileattachment();
        if(!attachments.isEmpty()) mail.setFileAttachments(attachments);

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

        this.catrequest.Request_Last_Sent__c = system.now();
        update this.catrequest;
    } catch (Exception e) {
        status = e.getMessage();
        system.debug('error ' + e.getMessage());

another thing : when i upload file manualy and try to generate new file i couldn't file the file i've upload as attachement ..


A single File (ContentDocument) can have many Versions (ContentDocumentVersion) which all link to the same record (ContentDocumentLink). Your code is pulling all the versions for the record which will include current and old versions. The easiest fix is to include isLatest to only pull the latest version of files.

List<ContentVersion> versions = [SELECT ContentDocumentId,VersionData,FileExtension,FileType,Id,Title FROM ContentVersion where ContentDocumentId IN: docids AND IsLatest = true];

To explain further, you're creating a new version of the same file in your code with every button click (assuming the file already exists).

When you send the email, you're querying all versions. This is why you pull 2 when you click the button twice.

I would also suggest you specify in your query to exclude the title of the file you expect to be there when building the other attachments on the email. You don't want to re-query the file you are already attaching to the email. Since you know the title you can utilize it in the query for ContentDocumentLink

List<ContentDocumentLink> links = [Select Id,contentdocument.id from ContentDocumentLink where LinkedEntityId = :this.catrequest.id AND ContentDocument.Title != 'your created file title'];
  • when user attached file manually to salesforce , they can't find it attached in the email - can you explain why ? – user81938 May 29 '20 at 10:14
  • Based on this question - everything is on a button click? I'd suggest you add some System.debug logs to your code and getting debug logs to confirm how many files/attachments the code is pulling or looping through. I can see you create an attachment in the beginning if contVer != null but you never add it the attachments list so it's never added to the email. – Kris Goncalves May 29 '20 at 11:02
  • it works fine for system administrators , but not for users with other profiles .. – user81938 May 29 '20 at 11:09
  • Ok then that tells you the issue... access/permission to the uploaded files. This is a different question though as you have to go through who the uploaded files are shared with and your Salesforce file settings – Kris Goncalves May 29 '20 at 11:29
  • Can you please tell me which system permission should i enable to these users? – user81938 May 29 '20 at 11:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy