2

My opportunity has some attachments. I would like to send them via email. If I hit on "Attach File" button of "Send an Email" page, then File Location lookup filter window, dialog appears, however I am not able to find any of the attachments.

Any idea? Why I don't see the attachments in the file location lookup filter?

Any help really appreciated!enter image description here

1

There are a number of places where files can be stored in an org. Files, Documents, Content, Attachments, Static Resource, and more each are slightly different.

There is a help topic that goes through the difference between these.

In the case of attaching a file to an email, Attachment is not something you can use. Why you can't send an attachment that is already related to that record? I don't have a good explanation for that, other than, no one has thought of building that feature.

But the simple answer to you question is, that's not how email attachments work.

So what would it make this happen? You would need to create some custom functionality using Visualforce and Apex. But this would be a complex enough task that this is not suited to a Stack Exchange answer.

There is an idea on Idea exchange that you can vote up to get Salesforce to add this feature. https://success.salesforce.com/ideaView?id=08730000000BplZ

  • Peter thanks for replying. The tasks is, Make a user ability to send an email with opportunity attachments. – Ruslan Vekua Dec 22 '14 at 8:01
  • Ah. Better to ask for specifically what you want! You appear to be pretty new to Stack Exchange. Here's a link to the instructions on best practices on asking questions: salesforce.stackexchange.com/help/how-to-ask. I will amend my answer. – pchittum Dec 22 '14 at 8:14
  • Many thanks Peter. Actually, I could find a solution which does what I need exactly. – Ruslan Vekua Dec 22 '14 at 12:29
1

I found a solution. I created a custom "Send an Email" apex page there a user can choose any of opportunity attachment and send it via email, for this functionality I have created an apex controller that can send an email with the attachments.

Here is my solution, note the code is not refactored but functionality is doing what I need exactly,

Apex page:

<apex:page controller="EmailOpportunityAttachment">

<script type="text/javascript">

var delim = ";";
function lookupPick2(editPage, p2_lkid, p2, contactId, contactName, cas4, accountName, cas4_lkid, accountId, h){
    document.getElementsByClassName('p2')[0].value = contactName;
    document.getElementById('p2_lkid').value = contactId;
    closePopup();
}
function pickupValue(additionalToValue, ccValue, bccValue) {
    //var editPage = document.getElementsByClassName('editPage')[0];
    var p24 = document.getElementsByClassName('p24')[0];
    var p4 = document.getElementsByClassName('p4')[0];
    var p5 = document.getElementsByClassName('p5')[0];
    if(additionalToValue != '') {
        if (p24.value != '') {
            p24.value += delim;
        }
        p24.value += additionalToValue;
    }
    if(ccValue != '') {
        if (p4.value != '') {
            p4.value += delim;
        }
        p4.value += ccValue;
    }
    if(bccValue != '') {
        if (p5.value != '') {
           p5.value += delim;
        }
        p5.value += bccValue;
    }
    closePopup();
}

function openDocumentUpload(e) {
   setLastMousePosition(e);
   openPopup('/widg/filepicker_fs.jsp?lktp=015&mode=1&eid=00Yg0000000aN7g&utype=00P&omode=1&otype=2', 'doc', 450, 450, 'width=450,height=450,scrollbars=yes,toolbar=no,status=no,directories=no,menubar=no,resizable=1', true);
}

function attachPhxAttachment(e){
    var selector = document.getElementById('attS');
    var splt = selector.value.split('##');
    var id = splt[0];
    var size = splt[1];
    var tr = document.getElementById('tr_' + id);
    var fileStr = document.getElementById('fileStr');
    fileStr.innerHTML += tr.outerHTML;
    populateAttIds();
}

function populateAttIds(){    
    var hiddenDv = document.getElementsByClassName('attDvBlock')[0];
    var hiddenAttIds = hiddenDv.getElementsByClassName('hiddenAttIds');
    var inps = document.getElementsByClassName('attIds')[0];

    inps.value = '';   
    if(hiddenAttIds && hiddenAttIds.length > 0){
        for(var i=0; i < hiddenAttIds.length; i++){
            inps.value += hiddenAttIds[i].value + delim;
        }
    }
}    

function submitFormNoSave() {
    var nosave = document.getElementById('nosave');
    var save = document.getElementById('save');
    nosave.value = '1';
    save.value = 'nosave';
    submitForm();
}

function submitForm() {
    var editPage = document.getElementById('editPage');
    editPage.submit();
}

    function deletePhxAttachment(event) {
        if (window.confirm('Are you sure?')) {
            var elem = event.target.parentNode.parentNode;
            elem.parentNode.removeChild(elem);
            populateAttIds();
        }
    }
</script>


    <apex:sectionHeader title="Task" subtitle="Send an Email"/>

    <apex:form id="editPage" onsubmit="if (window.ffInAlert) { return false; }" styleClass="editPage">

        <input type="hidden" name="cancelURL" id="cancelURL" value="/{!opptyId}" />
        <input type="hidden" name="id" id="id" value="00Yg0000000aN7g" />
        <input type="hidden" name="docancel" id="docancel" value="0" />
        <input type="hidden" name="new_template" id="new_template" value="0" />
        <input type="hidden" name="nosave" id="nosave" value="0" />
        <input type="hidden" name="save" id="save" value="0" />
        <input type="hidden" name="retURL" id="retURL" value="/{!opptyId}" />
        <input type="hidden" name="rtype" id="rtype" value="003" />
        <input type="hidden" name="p2_lktp" id="p2_lktp" value="003" />
        <input type="hidden" name="p2_lkold" id="p2_lkold" value="" />
        <input type="hidden" name="p2_lkid" id="p2_lkid" value="" />
        <input type="hidden" name="p2_lspf" id="p2_lspf" value="0" />
        <input type="hidden" name="p2_lspfsub" id="p2_lspfsub" value="0" />
        <input type="hidden" name="p2_mod" id="p2_mod" value="0" />
        <input type="hidden" name="template_id" id="template_id" value="000000000000000" />

        <apex:pageblock id="mail" mode="edit"> 
            <apex:pageBlockButtons >                
                <apex:commandButton value="Send" action="{!sendEmail}" id="sendEmailBtn" />
                <input type="button" class="btn" value="Select Template" id="sendEmailBtn" />
                <input value="Attach File" class="btn" title="Attach File (New Window)" name="attach" onclick="openDocumentUpload(event)" type="button" />
                <input type="button" class="btn" value="Check Spelling" id="sendEmailBtn" />
                <input type="button" class="btn" value="Cancel" id="cancelBtn" />
            </apex:pageBlockButtons>

            <apex:pageblockSection>
                <apex:outputText styleClass="err" value="{!errorMsg}"/> 
                <apex:outputText styleClass="success" value="{!successMsg}"/> 
            </apex:pageblockSection>

            <apex:pageblockSection columns="1" title="Edit Email">

                <apex:pageBlockSectionItem >
                    <apex:outputLabel value="From" styleClass="bld"/>
                    <apex:outputpanel layout="block" styleClass="requiredInput">
                        <apex:outputpanel layout="block" styleClass="requiredBlock" />
                        <apex:selectList id="p26" value="{!ffrom}" size="1">
                            <apex:selectOptions value="{!contacts}"></apex:selectOptions>
                         </apex:selectList>
                    </apex:outputpanel>
                </apex:pageBlockSectionItem>

                <apex:pageBlockSectionItem>
                    <apex:outputLabel value="To:" styleClass="bld"/>
                    <apex:pageBlockSectionItem>
                    <apex:inputText  value="{!to}" maxlength="255" onchange="getElementByIdCS('p2_lkid').value='';getElementByIdCS('p2_mod').value='1';" size="20" styleClass="p2" />
                    <a href="javascript: openLookup('/_ui/common/data/LookupPage?lkfm=editPage&lknm=p2&lktp=' + getElementByIdCS('p2_lktp').value,670,'1','&lksrch=' + escapeUTF(getElementsByClassName('p2')[0].value.substring(0, 80)))" id="p2_lkwgt" onclick="setLastMousePosition(event)" title="To Lookup (New Window)">
                    <img src="/s.gif" alt="To Lookup (New Window)" class="lookupIconOn" onblur="this.className = 'lookupIcon';" onfocus="this.className = 'lookupIconOn';" onmouseout="this.className = 'lookupIcon';this.className = 'lookupIcon';" onmouseover="this.className = 'lookupIconOn';this.className = 'lookupIconOn';" title="To Lookup (New Window)" /></a>
                    </apex:pageBlockSectionItem>
                </apex:pageBlockSectionItem>

                <apex:pageblockSectionItem>
                    <apex:outputLabel value="Related To" styleClass="bld"/>
                    <apex:pageblockSectionItem>
                        <apex:selectList size="1" style="width: 250px">
                            <apex:selectOptions value="{!relatedTo}"></apex:selectOptions>
                            <apex:selectOptions value="{!relatedTo}"></apex:selectOptions>
                            <apex:selectOptions value="{!relatedTo}"></apex:selectOptions>
                         </apex:selectList>
                         <apex:inputText maxlength="255" style="margin-left: 4px;" value="{!relatedTo}" />
                    </apex:pageblockSectionItem>

                </apex:pageblockSectionItem>

                <apex:pageblockSectionItem >
                    <apex:outputlink value="javascript: openPopup('/_ui/core/email/author/EmailCCBccLookup?id={!opptyId}', 'CCBCCLookup', 420, 490, 'width=420,height=490,toolbar=no,status=no,directories=no,menubar=no,resizable=yes,scrollable=no', true);" id="p24_lkwgt" onclick="setLastMousePosition(event)" title="Additional To Lookup (New Window)">Aditional To:</apex:outputlink>
                    <apex:pageBlockSectionItem >
                        <apex:inputTextArea value="{!additionalTo}" cols="62" rows="2" styleClass="p24" />
                        <apex:outputlink value="javascript: openPopup('/_ui/core/email/author/EmailCCBccLookup?id={!opptyId}', 'CCBCCLookup', 420, 490, 'width=420,height=490,toolbar=no,status=no,directories=no,menubar=no,resizable=yes,scrollable=no', true);" id="p24_lkwgt" onclick="setLastMousePosition(event)" title="Additional To Lookup (New Window)">
                             <img src="/s.gif" alt="Additional To Lookup (New Window)" class="lookupIcon" onblur="this.className = 'lookupIcon';" onfocus="this.className = 'lookupIconOn';" onmouseout="this.className = 'lookupIcon';this.className = 'lookupIcon';" onmouseover="this.className = 'lookupIconOn';this.className = 'lookupIconOn';" title="Additional To Lookup (New Window)" />
                        </apex:outputlink>
                    </apex:pageBlockSectionItem>
                </apex:pageblockSectionItem>            

                <apex:pageblockSectionItem >
                    <apex:outputlink value="#" target="_blank">CC:</apex:outputlink>
                    <apex:pageBlockSectionItem >  
                        <apex:inputTextArea value="{!cc}" cols="62" id="p4" rows="2" title="CC" styleClass="p4" />              
                        <apex:outputlink value="javascript: openPopup('/_ui/core/email/author/EmailCCBccLookup?id={!opptyId}', 'CCBCCLookup', 420, 490, 'width=420,height=490,toolbar=no,status=no,directories=no,menubar=no,resizable=yes,scrollable=no', true);" id="p4_lkwgt" onclick="setLastMousePosition(event)" title="CC Lookup (New Window)">
                            <img src="/s.gif" alt="CC Lookup (New Window)" class="lookupIcon" onblur="this.className = 'lookupIcon';" onfocus="this.className = 'lookupIconOn';" onmouseout="this.className = 'lookupIcon';this.className = 'lookupIcon';" onmouseover="this.className = 'lookupIconOn';this.className = 'lookupIconOn';" title="CC Lookup (New Window)" />
                        </apex:outputlink>
                    </apex:pageBlockSectionItem>
                </apex:pageblockSectionItem>

                <apex:pageBlockSectionItem >
                    <apex:outputlink value="#" target="_blank">BCC:</apex:outputlink>
                    <apex:pageBlockSectionItem>
                        <apex:inputTextArea value="{!bcc}" cols="62" id="p5" rows="2" title="BCC" styleClass="p5" />                
                        <apex:outputlink value="javascript: openPopup('/_ui/core/email/author/EmailCCBccLookup?id={!opptyId}', 'CCBCCLookup', 420, 490, 'width=420,height=490,toolbar=no,status=no,directories=no,menubar=no,resizable=yes,scrollable=no', true);" id="p5_lkwgt" onclick="setLastMousePosition(event)" title="BCC Lookup (New Window)">
                            <img src="/s.gif" alt="BCC Lookup (New Window)" class="lookupIcon" onblur="this.className = 'lookupIcon';" onfocus="this.className = 'lookupIconOn';" onmouseout="this.className = 'lookupIcon';this.className = 'lookupIcon';" onmouseover="this.className = 'lookupIconOn';this.className = 'lookupIconOn';" title="BCC Lookup (New Window)" />
                        </apex:outputlink>
                    </apex:pageBlockSectionItem>
                </apex:pageBlockSectionItem>

                <apex:pageblockSectionItem >
                    <apex:outputLabel value="Subject" styleClass="bld"/>
                    <apex:outputpanel layout="block" styleClass="requiredInput">
                        <apex:outputpanel layout="block" styleClass="requiredBlock"/>
                        <apex:inputText value="{!subject}" maxlength="100" size="70"/>
                    </apex:outputpanel>    
                </apex:pageblockSectionItem>

                <apex:pageblockSectionItem >
                    <apex:outputLabel value="Message" styleClass="bld"/>
                    <apex:inputTextArea value="{!message}" rows="15" cols="93" richText="false"/>
                </apex:pageblockSectionItem>

            </apex:pageblockSection>

            <div id="test" style="width: 500px; margin: 20px 0 0 19%;">
                <select id="attS" name="attS" style="width: 400px;">
                    <apex:repeat value="{!attachments}" var="att" id="theRepeat">
                        <option value="{!att.Id}##{!att.BodyLength}">{!att.Name}</option>
                    </apex:repeat>
                </select>
               <input value="Attach File" class="btn" id="attachFile" name="attachFile" onclick="attachPhxAttachment(event)" type="button" />
               <div style="margin: 10px 0 0 0;">
                   <input style="display:none;" value="Attach File" class="btn" title="Attach File (New Window)" id="attach" name="attach" onclick="openDocumentUpload(event)" type="button" />
               </div>
           </div>
        </apex:pageblock> 



<div class="bRelatedList">
<!-- Begin ListElement -->

<!-- motif: Home -->

<!-- WrappingClass -->
<div class="listRelatedObject homeBlock">
    <div class="bPageBlock brandSecondaryBrd secondaryPalette">
        <div class="pbHeader">
            <table border="0" cellpadding="0" cellspacing="0"><tbody>
                <tr>
                    <td class="pbTitle">
                        <img src="/s.gif" alt="" width="12" height="1" class="minWidth" title="" style="margin-right: 0.25em;margin-right: 0.25em;margin-right: 0.25em;margin-right: 0.25em;margin-right: 0.25em;" />
                        <h3>Attachments</h3>
                    </td>
                    <td class="pbButton">
                        <input value="Attach File" class="btn" name="attach" onclick="openDocumentUpload(event)" title="Attach File (New Window)" type="button" />
                    </td>
                    <td class="pbHelp">&nbsp;</td>
                </tr>
                </tbody>
            </table>
        </div>
        <div class="pbBody attDvBlock">
            <table class="list" border="0" cellspacing="0" cellpadding="0">
                <tbody id="fileStr">
                <tr class="headerRow">
                    <th class="actionColumn" scope="col">Action</th>
                    <th scope="col" class=" zen-deemphasize">File</th>
                    <th scope="col" class=" zen-deemphasize">Size</th>
                </tr>
                </tbody>
            </table>
        </div>
        <div class="pbFooter secondaryPalette">
            <div class="bg"></div>
        </div>
    </div>
</div>
            <div class="listElementBottomNav"></div>
                <!-- End ListElement -->
</div>

        <div class="hiddenDv" style="display:none !important;"> 
            <table class="list" border="0" cellspacing="0" cellpadding="0">
                <tbody>
                <apex:repeat value="{!attachments}" var="att2" id="trFileRepeat">                
                    <tr id="tr_{!att2.Id}" class="dataRow even last first highlight" onblur="if (window.hiOff){hiOff(this);}" onfocus="if (window.hiOn){hiOn(this);}" onmouseout="if (window.hiOff){hiOff(this);}" onmouseover="if (window.hiOn){hiOn(this);}">
                        <td class="actionColumn">
                            <a href="javascript:;" class="actionLink" onclick="deletePhxAttachment(event)">Del</a>
                        </td>
                        <th scope="row" class=" dataCell  ">
                            <a href="/servlet/servlet.FileDownload?file={!att2.Id}" target="_TOP">{!att2.Name}</a>
                            <input type="hidden" value="{!att2.Id}" class="hiddenAttIds" />
                        </th>
                        <td class=" dataCell  ">{!att2.BodyLength} bytes</td>
                    </tr> 
                </apex:repeat>
                </tbody>
            </table>
        </div>
        <apex:inputText value="{!attachmentIds}" styleClass="attIds" style="" />
    </apex:form>
 </apex:page>

Apex controller:

public class EmailOpportunityAttachment{

    public String to {get;set;}
    public String additionalTo {get;set;}
    public String relatedTo {get;set;}
    public String cc {get;set;}
    public String bcc {get;set;}
    public String ffrom {get;set;}
    public String message {get;set;}
    public String subject {get;set;}
    public String errorMsg{get;set;} 
    public String successMsg{get;set;}
    public List<String> addresses {get;set;}
    public String opptyId {get;set;}
    public String accountId {get;set;}
    public String attachmentIds {get;set;}
    public boolean flagToSendMail;
    private static final String DEL = ';';


    public EmailOpportunityAttachment(){
        this.opptyId = ApexPages.currentPage().getParameters().get('opptyId');
        this.accountId = ApexPages.currentPage().getParameters().get('accountId');
    }

    public List<SelectOption> contacts {
        get {
            List<SelectOption> contacts = new List<SelectOption>();
            List<Contact> cnts = [select Id, Name, Email from Contact where Account.Id =: this.accountid];
            for (Contact cnt: cnts) {
                contacts.add(new SelectOption(cnt.Id, '"' + cnt.Name + '" <' + cnt.Email + '>'));
            }
        return contacts;
        }
        set;
    }


    public Attachment[] getAttachments(){
      return  [select id, Name, BodyLength, Body from Attachment where parent.id =: this.opptyId];
    }

    public List<Attachment> getAttachmentsByIds(final String[] ids){
        String sql = ' select Id, Name, Body, ContentType from Attachment where Name=\'DDDDDDDDDDDDDD\' ';
        boolean found = false;
        if(null != ids && ids.size() > 0){
            for(String id: ids){
                sql += ' OR Id=';
                sql += '\'';
                sql += id;
                sql += '\'';
            }            
            found = true;
        }
        //System.debug(sql);
        return found ? (List<Attachment>)Database.query(sql) : null;
    }


    public String getEmailByUserName(final String userName){
      return [select Email from Contact where Name =: userName limit 1].Email;
    }

    public PageReference sendEmail() {
        PageReference pageRef = new PageReference('/'+this.opptyId);

        if(subject == '' || message == ''){
            errorMsg = 'Please enter subject and message.';
            return null;
        }

        if(to != '' || additionalTo != '' || cc != '' || bcc != ''){
            List<String> toAddresses = new List<String>();
            List<String> ccAddresses = new List<String>();
            List<String> bccAddresses = new List<String>();

            List<String> tmpAddr = new List<String>();
            if(additionalTo.contains(DEL)){
                toAddresses = additionalTo.split(DEL);
                for(String tmp:toAddresses){
                    tmpAddr.add(tmp);
                }
            }else if(additionalTo != '') {
                toAddresses.add(additionalTo);
                tmpAddr.add(additionalTo);
            }

            if(to != ''){
                final String emailAddr = getEmailByUserName(to);
                toAddresses.add(emailAddr);
                tmpAddr.add(emailAddr);
            }

            if(cc.contains(DEL)){
                ccAddresses = cc.split(DEL);
                for(String tmp:ccAddresses){
                    tmpAddr.add(tmp);
                }
            }else if(cc != ''){
                ccAddresses.add(cc);
                tmpAddr.add(cc);
            }
            if(bcc.contains(DEL)){
                bccAddresses = bcc.split(DEL);
                for(String tmp:bccAddresses){
                    tmpAddr.add(tmp);
                }
            }else if(bcc != ''){
                bccAddresses.add(bcc);
                tmpAddr.add(bcc);
            }

            /* Checking whether mail ids are valid */
            addresses = tmpAddr;
            for(String tempStr:addresses){
                if(!Pattern.matches('[a-zA-Z0-9._-]+@[a-zA-Z]+.[a-zA-Z]{2,4}', tempStr)){
                    errorMsg = 'Check To, CC and BCC addresses';
                    successMsg = '';
                    flagToSendMail = false;      
                    break;          
                }else{
                    flagToSendMail = true;
                }           
            } 

            /* Sending Mail */
            if(flagToSendMail == true){
                Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
                if(toAddresses != null){
                    email.setToAddresses(toAddresses);
                }
                if(ccAddresses != null){
                    email.setccAddresses(ccAddresses);
                }
                if(bccAddresses != null){
                    email.setbccAddresses(bccAddresses);
                }             
                email.setSubject(subject);  
                email.setHtmlBody(message);

                List<Messaging.EmailFileAttachment> attachs = null;

                if('' != attachmentIds){
                    final String[] attachIds = attachmentIds.split(DEL);
                    if(null != attachIds && attachIds.size() > 0){
                       final List<Attachment> attechments = getAttachmentsByIds(attachIds);
                        if(null != attechments && attechments.size() > 0){
                            attachs = new List<Messaging.EmailFileAttachment>();
                            Messaging.EmailFileAttachment attach = null;
                            for(Attachment att: attechments){
                                attach = new Messaging.EmailFileAttachment();
                                attach.setContentType(att.contentType);
                                attach.setFileName(att.Name);
                                attach.setInline(false);
                                attach.setBody(att.Body);
                                attachs.add(attach);
                                attach = null;
                            }
                        }                        
                    }
                }

                if(null != attachs && attachs.size() > 0){
                    email.setFileAttachments(attachs);
                }

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

                errorMsg = '';
                successMsg = 'Mail sent successfully to following recipients';
                return pageRef; 
            }else{
                return null;
            }
        }else{
            errorMsg = 'Please enter To or CC or BCC address';
            return null;
        }
    }

}
  • This would be really useful if you were to post more details about this. Where did you find it? Is it an open source project, app exchange app, blog post? If you get it working, what is good about it, what isn't...as this exists right now it is not an answer that is helpful to anyone...which is the goal of Stack Exchange. Here is the "how to answer" help page for guidance. salesforce.stackexchange.com/help/how-to-answer Glad you found a solution. Thanks! – pchittum Dec 22 '14 at 13:25
  • I will post the code here once I finish it. Thanks! – Ruslan Vekua Dec 22 '14 at 13:36

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.