This is the section
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 tempaltetry {
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);}
Thanks,<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>
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
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<apex:page standardController="Account" extensions="PageAsEmail">
<h1>
Bottling Summary for {!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>
In the template there you wont have to send as attachment but as a body so just your template would look like below:
Hope it helps.<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>