Skip to main content
Hi,

This is really wierd.  I have an action that triggers a summary email to be sent when triggered.  The first time I click the action button the email gets sent but is blank.  The second time I click it the email is sent but has data in it.  I can't think what could possibly cause behavior like that.

This is the section

try {

PageReference displayPage = page.BottlingSummaryEmail_page;

Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();

String[] toAddresses = new String[] {};

toAddresses.add(userEmail);

Blob body;

string htmlBody;

try {

// returns the output of the page as a blob

body = displayPage.getContent();

system.debug('body should be fine');

// need to pass unit test -- current bug

} catch (VisualforceException e) {

system.debug('in the catch block');

body = Blob.valueOf('Some Text');

}

htmlBody = body.toString();

email.setHtmlBody(htmlBody);

email.setToAddresses(toAddresses);

email.setSubject('Bottling Summary for '); // + dateString);

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

} catch (exception e) { system.debug ('TastingRecap_class *** error in the send email and error = ' + e);}

of code where I send the summary email (I can provide the rest if needed)

and here is the visualforce page I call for the tempalte

 

<apex:repeat value="{!botLotMap}" var="shift">

<h1> Bottling Summary for Shift {!shift} </h1>

<table width="100%">

<th>Shift</th><th>Change Over</th><th>Operation</th> <th>Client</th><th>Brand</th><th>Cases</th><th>Cases per Hour</th><th>Notes</th>

<apex:repeat value="{!botLotMap[shift]}" var="v" >

<tr>

<td><apex:outputtext value="{!botLotMap[shift][v].Bottling_Shift__r.Bottling_Shift__c}" /></td>

<td><apex:outputtext value="{!botLotMap[shift][v].Type_of_Changeover__c}" /> </td>

<td><apex:outputtext value="{!botLotMap[shift][v].Labeled_Bottled__c}"/></td>

<td><apex:outputtext value="{!botLotMap[shift][v].Client_Lookup__r.name}" /></td>

<td><apex:outputtext value="{!botLotMap[shift][v].Brand__c}"/></td>

<td><apex:outputtext value="{!botLotMap[shift][v].Actual_Bottled__c}"/> </td>

<td><apex:outputtext value="{!botLotMap[shift][v].Cases_Per_Hour__c}"/></td>

<td><apex:outputtext value="{!botLotMap[shift][v].Notes__c}"/></td>

</tr>

</apex:repeat>

<tr><td colspan="4">Total</td><td>{!totalCasesBottled[shift]}</td><td></td><td></td><td></td></tr>

</table>

</apex:repeat>

</apex:page>

Thanks,

 
13 answers
  1. Feb 2, 2016, 9:42 PM
    I have done a sample POC for this and it seems like the state of the botLogMap is not getting set, this something we need to ask to Salesforce Support. Below is my POC code done for Contact:

    VF - SendPageAsEmail

    <apex:page standardController="Account" extensions="PageAsEmail">

    <apex:form >

    <apex:pageblock >

    <apex:commandButton value="Send Email" action="{!sendClientEmail}"/>

    </apex:pageblock>

    </apex:form>

    </apex:page>

    Apex Class 

    public class PageAsEmail {

    public Account accountObj {get;set;}

    String accountId;

    public List<Contact> listofContacts {get;set;}

    public Map<String, Map<String,COntact>> botLotMap {get;set;}

    public PageAsEmail(ApexPages.StandardController std) {

    accountId = ApexPages.currentPage().getParameters().get('id');

    if (accountId != NULL) {

    accountObj = [Select Id, Name, AccountNumber from Account where Id =: accountId];

    getContacts();

    } else {

    accountObj = new Account();

    }

    }

    public void getContacts() {

    listofContacts = [Select Id, Name, FirstName, LastName, EMail,AccountId,Phone from COntact where AccountId=: accountObj.Id];

    }

    public void sendClientEmail() {

    botLotMap = new Map<String, Map<string, COntact>>();

    for (Contact bot: listofContacts) {

    if(!botLotMap.containsKey(bot.AccountId)) {

    botLotMap.put(bot.AccountId, New Map<string, Contact>());

    }

    botLotMap.get(bot.AccountId).put(bot.id, bot);

    }

    PageReference displayPage = page.PageAsEmail;

    displayPage.setRedirect(false);

    Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();

    String[] toAddresses = new String[] {};

    toAddresses.add(UserInfo.getUserEmail());

    system.debug('botlotmap in the summary = ' + botLotMap);

    Blob body;

    string htmlBody;

    body = displayPage.getContent();

    system.debug('body should be fine');

    htmlBody = body.toString();

    email.setHtmlBody(htmlBody);

    email.setToAddresses(toAddresses);

    email.setSubject('Bottling Summary for ' + accountObj.Name); // + dateString);

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

    }

    }

    VF Page

    <apex:page standardController="Account" extensions="PageAsEmail">

    <h1>

    Bottling Summary for &nbsp; {!accountObj.Name}

    </h1>

    <br/>

    <style type="text/css"> table, th, td { border: 1px solid black; } </style>

    <apex:repeat value="{!botLotMap}" var="shift">

    <h1> Bottling Summary for Shift {!shift} </h1>

    <table width="100%">

    <th>

    <td>First Name</td>

    <td>Last Name</td>

    <td>Email</td>

    <td>Phone</td>

    </th>

    <apex:repeat value="{!botLotMap[shift]}" var="v" >

    <tr>

    <td><apex:outputtext value="{!botLotMap[shift][v].FirstName}" /></td>

    <td><apex:outputtext value="{!botLotMap[shift][v].LastName}" /> </td>

    <td><apex:outputtext value="{!botLotMap[shift][v].Email}"/></td>

    <td><apex:outputtext value="{!botLotMap[shift][v].Phone}" /></td>

    </tr>

    </apex:repeat>

    </table>

    </apex:repeat>

    </apex:page>

    Another workaround which I can suggest is create Visualforce email template and use a component inside the template to generate your body dynamically. Please follow my answer to this blog post for the sample code - https://developer.salesforce.com/forums/ForumsMain?id=906F0000000D6IfIAK

    In the template there you wont have to send as attachment but as a body so just your template would look like below:

    <messaging:emailTemplate subject="Opportunity '{!relatedTo.Name}' Detail with Products" recipientType="User"

    relatedTo="opportunity >

    <messaging:htmlEmailBody >

    Hi {!relatedTo.Owner.name} ,<br/>

    your opportunity '{!relatedTo.Name}' has beed closed won.<br/>

    Please find their products detail as below.

    <br/>

    <c:OpptyProduct opportunityId="{!relatedTo.Id}"></c:OpptyProduct><!--gives the reference of the component-->

    </messaging:htmlEmailBody>

    </messaging:emailTemplate>

    Hope it helps.
0/9000