![lightning component](https://images.forcetalks.com/wp-content/uploads/2020/06/12185046/lightning-component.png)
Files, Attachments And Notes Salesforce Lightning Components | Force.com
Download Notes & Attachments from Force.com Site of Lightning Component
Create an email alert that will be sent to the Opportunity Owner. This email will be when the opportunity is closed won. Email Template :
Hi [Owner Name],
The [Opportunity Name] is now closed-won. You can the attachments from the following Link :
[Site Link]
Thanks.
Salesforce Automation
The Site link will be an open VF page including (Lightning component). This component will show all the files attached to the opportunity record in a table format. Also, the user will be able to download these attachments.
[Table]
[FileName1] [FileSize] [Download Button]
[FileName2] [FileSize] [Download Button]
[Table]
Don't forget to check out: Salesforce lightning:treegrid - The Developer Guide
Solution:
Step 1: Create a workflow which sends an email alert with text template (binding opp owner Name, Opp Name and site link which concatenate with opp.id) to opportunity owner on the given criteria whose opportunity stage is closeWon
Email template body:
Hi {!Opportunity.OwnerFullName},
The {!Opportunity. Name} is now closed-won. You can the attachments from the following Link :
http://flowdisplay-developer-edition.ap16.force.com/EmbedComponentsForSites?id={!Opportunity. Id}
Thanks.
Salesforce Automation
> Opportunity owners receive this email template/body and click on given siteLink (with their particular opportunity id) and they get a lightning component which embeds in the Visualforce page.
Step 2: Create a Visualforce page which get the particular opportunity id from the URL of siteLink and passes this id in the lightning component to show the relative notes and attachment on this opportunity in the table
GetIdFromUrl.apxc
public class GetIdFromUrl { public String currentRecordId {get;set;} public String parameterValue {get;set;} // public Opportunity opp{get;set public GetIdFromUrl(ApexPages.StandardController controller) { currentRecordId = ApexPages.CurrentPage().getparameters().get('id'); system.debug('currentRecordId======='+currentRecordId); //acc = [select id ,name, AccountNumber, Type, Industry from Account where id =: currentRecordId ]; parameterValue = ApexPages.CurrentPage().getparameters().get('nameParam')
>currentRecordId : In GetIdFromUrl.apxc class is used to get the opportunity id from the URL
Visualforce Page: EmbedComponentsForSites.vfp
<apex:page standardController="Opportunity" extensions="GetIdFromUrl" showQuickActionVfHeader="false" showHeader="false" sidebar="false"> <apex:pageBlock > <apex:pageBlockSection title="Current account record Id is : {!currentRecordId}" collapsible="false"> </apex:pageBlockSection> </apex:pageBlock> <apex:includeLightning /> <div id="FlipcardContainer" /> <script> $Lightning.use("c:ContactListApp", function() { $Lightning.createComponent("c:FileAttachmentComponent", { recordId : '{!currentRecordId}' }, "FlipcardContainer", function(cmp) { console.log('Component created, do something cool here'); }); }); </script> </apex:page>
> recordId : '{!currentRecordId}': In above visualforce page currentRecordId (opportunity id retrieve from URL) is passed to the lightning component:FileAttachmentComponent which retrieve their related notes and attachments of the opportunity in the table with required details.
Step 3: Create a table in the Lightning Component which includes fileName, fileSize and Download button
Lightning component: FileAttachmentComponent.cmp
<aura:component implements="forceCommunity:availableForAllPageTypes" access="global" controller="FileAttachment"> <!--aura doInit handler--> <aura:handler name="init" value="{!this}" action="{!c.doInit}"/> <!--aura attributes--> <aura:attribute name="Baseurl" type="String" /> <aura:attribute name="recordId" type="Id" /> <aura:attribute name="selectedDocumentId" type="string"/> <aura:attribute name="lstContentDoc" type="List"/> <aura:attribute name="hasModalOpen" type="boolean" default="false"/> id===={!v.recordId} <!-- Custom DataTable to Display List Of Available ContentDocuments Start--> <table class="slds-table slds-table_cell-buffer slds-table_bordered"> <thead> <tr class="slds-line-height_reset"> <th class="slds-text-title_caps" scope="col"> <div class="slds-truncate" title="Title">Title</div> </th> <th class="slds-text-title_caps" scope="col"> <div class="slds-truncate" title="size">size(bytes)</div> </th> </tr> </thead> <tbody> <aura:iteration items="{!v.lstContentDoc}" var="CD"> <tr> <th scope="row"> <div class="slds-truncate" title="{!CD.Name}"> <a onclick="{!c.getSelected}" data-Id="{!CD.Id}">{!CD.Name}</a> </div> </th> <th scope="row"> <div class="slds-truncate" title="{!CD.BodyLength}"> <a onclick="{!c.getSelected}" data-Id="{!CD.Id}">{!CD.BodyLength}</a> </div> </th> <th scope="row"> <div class="slds-truncate" title="{!CD.ParentId}">{!CD.ParentId}</div> </th> <th scope="row"> <!-- <a href="{!'/sfc/servlet.shepherd/document/download/'+CD.Id}" target="_blank" download="{!CD.Name}">Download</a> <a href="{!'/servlet/servlet.FileDownload?file='+CD.Id}" target="_blank">Download</a> --> <a href="{!v.Baseurl}" data-id="{!CD.Id}" onclick = "{!c.downloadfile}" >Download</a> </th> </tr> </aura:iteration> </tbody> </table> <!-- Custom DataTable to Display List Of Available ContentDocuments End--> <!--###### FILE PREVIEW MODAL BOX START ######--> <aura:if isTrue="{!v.hasModalOpen}"> <section onclick="{!c.closeModel}" role="dialog" aria-modal="true" class="slds-modal slds-fade-in-open"> <div class="slds-modal__container"> <div class="slds-modal__content slds-p-around_medium slds-text-align_center" style="background: transparent;"> <div style="width: 50%; margin: 0 auto; text-align: left"> <!--<lightning:fileCard> to preview file using content document Id --> <lightning:fileCard fileId="{!v.selectedDocumentId}"/> </div> </div> </div> </section> <div class="slds-backdrop slds-backdrop_open"></div> </aura:if> <!--###### FILE PREVIEW MODAL BOX END ######--> </aura:component>
Check out another amazing blog by Aditya here: Send .csv File to Another Org in Salesforce
FileAttachmentComponentController.js :
({ /*call apex controller method "fetchContentDocument" to get salesforce file records*/ doInit : function(component, event, helper) { var recordId = component.get("v.recordId"); var action = component.get("c.fetchContentDocument"); console.log('recordid####:'+recordId); action.setParams({ "recordId":recordId }); console.log('recordid1####:'+recordId); action.setCallback(this, function(response) { var state = response.getState(); console.log('state======'+response.getState()); if (state === "SUCCESS") { console.log('data======1'+response.getReturnValue()); component.set('v.lstContentDoc', response.getReturnValue()); } else if (state === "INCOMPLETE") { // do something } else if (state === "ERROR") { var errors = response.getError(); if (errors) { if (errors[0] && errors[0].message) { console.log("Error message: " + errors[0].message); } } else { console.log("Unknown error"); } } }); $A.enqueueAction(action); }, // to download the file downloadfile : function (component, event, helper){ var id = event.target.getAttribute("data-id"); console.log('id===='+id); var action = component.get("c.DownloadAttachment"); console.log('actiondownload####:'+action); action.setParams({ "recordId" : id }); console.log('id==2256=='+id); action.setCallback(this, function(b){ component.set("v.Baseurl", b.getReturnValue()); console.log('URLLLLL'+b.getReturnValue()); }) $A.enqueueAction(action); }, // display modle and set seletedDocumentId attribute with selected record Id getSelected : function(component,event,helper){ component.set("v.hasModalOpen" , true); component.set("v.selectedDocumentId" , event.currentTarget.getAttribute("data-Id")); }, closeModel: function(component, event, helper) { // for Close Model, set the "hasModalOpen" attribute to "FALSE" component.set("v.hasModalOpen", false); component.set("v.selectedDocumentId" , null); }, })
FileAttachment.apxc :
public class FileAttachment { @AuraEnabled public static List<ContentVersion> fetchContentDocument(Id recordId){ system.debug('recordId=='+recordId); //List<Attachment> attachMent = [SELECT id, Name, ParentId FROM Attachment Where ParentId =: recordId]; Set<Id> cdIds = new Set<Id>(); /*ContentDocumentLink cdl = new ContentDocumentLink(); cdl.ContentDocumentId = '0062w000002NO8AAAW'; cdl.LinkedEntityId = recordId; cdl.ShareType = 'V'; cdl.Visibility = 'AllUsers'; insert cdl;*/ for(ContentDocumentLink cl : [SELECT ContentDocumentId, LinkedEntityId FROM ContentDocumentLink WHERE LinkedEntityId = :recordId]){ cdIds.add(cl.ContentDocumentId); system.debug('cl=='+cl); system.debug('cdIds=='+cdIds); } //list<ContentDocument> attachMent = new list<ContentDocument>([SELECT id, Title, ContentSize FROM ContentDocument Where Id In :cdIds]); list<ContentVersion> attachMent = new list<ContentVersion>([SELECT id FROM ContentVersion Where ContentDocumentId In :cdIds]); system.debug('attachMent===='+attachMent); system.debug('attachMent'+attachMent); return attachMent; } @AuraEnabled public static string DownloadAttachment(String recordId) { system.debug('recordId====in'+recordId); ContentVersion oldCV = [Select Id,Title from ContentVersion Where ContentDocumentId=:recordId and IsLatest = true ]; System.Debug('Old LV INitial :'+ oldCV.Id); String fullFileURL = URL.getSalesforceBaseUrl().toExternalForm(); String URlDownload = fullFileURL+'/sfc/servlet.shepherd/version/download/'+oldCV.Id; system.debug('Download URL:' +URlDownload); return URlDownload; } } /* * Set<Id> cdIds = new Set<Id>(); for(ContentDocumentLink cl : [SELECT ContentDocumentId, LinkedEntityId FROM ContentDocumentLink WHERE LinkedEntityId =: recordId]){ cdIds.add(cl.ContentDocumentId); system.debug('cl=='+cl); system.debug('cdIds=='+cdIds); } //list<ContentDocument> attachMent = new list<ContentDocument>([SELECT id, Title, ContentSize FROM ContentDocument Where Id In :cdIds]); list<ContentDocument> attachMent = new list<ContentDocument>([SELECT id, Title, ContentSize FROM ContentDocument Where ContentDocumentId In :cdIds]); system.debug('attachMent===='+attachMent); */
> Opportunity owner got id from the url and passed it as a parameter in the backend(apex control) to retrieve contentDocument to use this id in select query. The apex controller method fetchContentDocument gets the notes and attachments of the opportunity and shows it in the table of lightning components.
> In the table of lightning components there are multiple notes and attachments with fileName, fileSize and Download button.
> When opportunity owner click on Download button, they got the id of that particular file and passes it to backend method DownloadAttachment to use this id in Select query to retrieve the content version id (fileId) and concatenate it with baseURL:
String URlDownload = fullFileURL+'/sfc/servlet.shepherd/version/download/'+oldCV.Id;
Where fullFileURL is baseURL.
Reference: sfdcmonkey