+ Start a Discussion
Andrew TelfordAndrew Telford 

Visualforce Email Template Not Showing Custom Object Values (SingleEmailMessage)

I have an issue where I am sending out SingleEmailMessage on mass using a visualforce enail template. Some of the information is in a custom object c0_mailout__c which I have in the email template as the relatedtotype. When I execite the script to test it, the email that I receive doesn't have the related details I am after (ci_mailout__c.file_password__c, ci_mailout_file_name__c). In debugging, I note that the relatedto ID doesn't appear to be present when the email is generated.

Based on this, I believe that my script isn't passing the relatedto information that the template requires. Is there a way using SingleEmailMessage to pass the relatedtoid to the email template?

Apex Class CI_Mailout
//------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------
//--
//--	Name:
//--	CI_MailOut
//--
//--	Purpose:
//--	Used in conjunction with CI_Mailout__c
//--
//--	Created by:
//--	Andrew Telford
//--
//--	Date:
//--	2016-06-02
//--
//------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------

PUBLIC class CI_MailOut {

	PUBLIC CI_Mailout() {}

	PUBLIC ID mailoutID { get; set; }
	PUBLIC ID contactID { get; set; }
	PUBLIC LIST<CI_MAILOUT__C> objPasswords{ get; set; }

    PUBLIC LIST <ci_mailout__c> objMailout;
	PUBLIC LIST <attachment> objAttachment;
	PUBLIC LIST <Messaging.SingleEmailMessage> msgList = new List <Messaging.SingleEmailMessage> ();
	PUBLIC LIST <CI_MAILOUT__C> updateMailout = NEW LIST<CI_MAILOUT__C>();
	PUBLIC LIST <EmailTemplate> objtemplate_email;
	PUBLIC LIST <EmailTemplate> objtemplate_password;

    PUBLIC STRING strTemplate_Initial;
	PUBLIC STRING strTemplate_Password;
	PUBLIC STRING strEmailFrom;
	PUBLIC STRING template_email_id;
	PUBLIC STRING template_password_id;

    STRING thisScript = 'CI_Mailout.apxc: ';

	//------------------------------------------------------------------------------------------------------
	//
	//--	get_mail_attachment
	//--
	//--	Use:
	//--	This is used as a component for visual force emails generated from ci_mailout__c
	//
	//------------------------------------------------------------------------------------------------------
	PUBLIC LIST<attachment> get_mail_attachment()
	{
		LIST<attachment> objAttachments;
		objAttachments = [SELECT ID FROM Attachment WHERE ParentID = :mailoutID];
		RETURN objAttachments;
	}

	PUBLIC LIST<CI_MAILOUT__C> getPassword()
	{
		objPasswords = [SELECT recipient_first_name__c, recipient_last_name__c, File_Name__c, File_Password__c FROM CI_MAILOUT__C WHERE ID = :mailoutID];
        SYSTEM.DEBUG(thisScript + 'getPassword - objPasswords size: ' + objPasswords.size());
		RETURN objPasswords;
	}

	//------------------------------------------------------------------------------------------------------
	//--
	//--	send_mailout
	//--
	//--	Use:
	//--	This is the process to actually send the email and will be triggered by a scheduled APEX
	//--
	//--
	//------------------------------------------------------------------------------------------------------
	PUBLIC VOID send_mailout(STRING mailOutName)
	{
		//--	Our variables
		BOOLEAN sndSuccess = FALSE;
		
		strTemplate_Initial = mailOutName;
		strTemplate_Password = mailOutName + ' - Password';

		//--	Set the FROM email address
		for(OrgWideEmailAddress owa : [select id, Address, DisplayName from OrgWideEmailAddress]) 
		{
			strEmailFrom = owa.id;
		} 

		//--	Get the details of who we are going to send to
		objMailout = [SELECT Id, contact__c, contact__r.Name, recipient_first_name__c, recipient_last_name__c, caps__r.AccountID__c, file_password__c, email_address__c FROM ci_mailout__c WHERE Sent__c = FALSE AND Mailout_name__c = :strTemplate_Initial ORDER BY Policy_count__C Desc LIMIT 500];
		SYSTEM.debug(thisScript + 'Size of Mailout: ' + objMailout.size());

		//--	Get the Mailtemplate that we are going to use
		objTemplate_email = [SELECT id, Name FROM EmailTemplate WHERE Name = :strTemplate_Initial];
		FOR(EmailTemplate thistemplate_email: objTemplate_email)
		{
			template_email_id = thisTemplate_email.id;
			SYSTEM.debug(thisScript + 'Initial Template: ' + thisTemplate_email.Name);
		}

		objTemplate_password = [SELECT id, Name FROM EmailTemplate WHERE Name = :strTemplate_Password];
		FOR(EmailTemplate thistemplate_password: objTemplate_password)
		{
			template_password_id = thistemplate_password.id;
			SYSTEM.debug(thisScript + 'Password Template: ' + thistemplate_password.Name);
		}

		FOR (ci_mailout__c thisMailOut: objMailout) {
		SYSTEM.debug(thisScript + 'Looping through the mailout data');
			Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
			email.setTargetObjectId(thisMailOut.contact__c);
			email.setTemplateId(template_email_id);
			email.setSaveAsActivity(true);
			email.setToAddresses(new String[] { thisMailout.email_address__c });
			email.setTreatTargetObjectAsRecipient(FALSE);
			email.setUseSignature(FALSE);
			email.setOrgWideEmailAddressId(strEmailFrom);

		//--	Get the Email Attachment
			objAttachment = [SELECT ID, Name, ContentType, body FROM attachment WHERE ParentId = :thisMailOut.Id];
			SYSTEM.debug(thisScript + 'No Attachments: ' + objAttachment.size());
			if( objAttachment.size() > 0)
			{
				FOR(attachment thisAttachment: objAttachment)
				{
					SYSTEM.debug(thisScript + 'Looping through Attachment');
					Messaging.EmailFileAttachment efa = new Messaging.EmailFileAttachment();
					efa.setFileName(thisAttachment.Name);
					efa.setBody(thisAttachment.body);
					efa.setContentType(thisAttachment.ContentType);
					email.setFileAttachments(new Messaging.EmailFileAttachment[] {efa});
				}
			}

			msgList.add(email);

			SYSTEM.debug(thisScript + 'Check if we have a password template');
			IF ( objTemplate_password.size() > 0 )
			{
				SYSTEM.debug(thisScript + 'Creating Password Email');
				Messaging.SingleEmailMessage email_pass = new Messaging.SingleEmailMessage();
				email_pass.setToAddresses(new String[] { thisMailout.email_address__c });
				email_pass.setTreatTargetObjectAsRecipient(FALSE);
				email_pass.setTargetObjectId(thisMailOut.contact__c);
				email_pass.setTemplateId(template_password_id);
				email_pass.setSaveAsActivity(true);
				email_pass.setUseSignature(FALSE);
				email_pass.setOrgWideEmailAddressId(strEmailFrom);
				msgList.add(email_pass);
			}
		}

		SYSTEM.DEBUG(thisScript + 'Message List size: ' + msgList.size());
		IF( msgList.size() > 0 )
		{
			List<Messaging.SendEmailResult> results = Messaging.sendEmail( msgList, false );
			IF(!results.get(0).isSuccess())
			{
   				SYSTEM.DEBUG(thisScript + 'This was unsuccessful: ' + results[0].getErrors().get(0).getMessage());
			}
			ELSE
			{
   				FOR( CI_MAILOUT__C thisMailout: objMailOut)
				{
					thisMailout.Sent__C = TRUE;
					thisMailout.Sent_Date__c = SYSTEM.now();
					updateMailout.add( thisMailout );
				}

				IF( !updateMailout.isEmpty() )
				{
					update updateMailout;
				}
			}
			System.debug(thisScript +  results );
		}
	}
}



VisualForce Component ci_mailout_password
<apex:component controller="CI_MailOut" access="global">
    <apex:attribute name="mailID"
        type="Id"
        description="Mailout Reference"
        assignTo="{!mailoutID}" />

        <apex:repeat value="{!Password}" var="p">

            <p>Dear {!p.Recipient_First_Name__c}</p>
            <p>Here is your password to access your CommInsure client list. These clients will shortly receive information about CommInsure’s enhancement to medical definitions.</p>
            <ul>
                <li>File Name: {!p.File_Name__c} </li>
                <li>Password: {!p.File_Password__c}</li>
            </ul>
        </apex:repeat>
</apex:component>



Visualforce Email Template
<messaging:emailTemplate subject="File password for enhancement of medical definitions communications to CommInsure clients" recipientType="Contact" relatedToType="CI_Mailout__c" replyTo="">

    <messaging:HtmlEmailBody >
        <html>
            <head>
                <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
                <meta name="viewport" content="width=device-width, initial-scale=1.0" />
                <meta name="format-detection" content="telephone=no" />
                <meta name="format-detection" content="date=no" />
                <meta name="format-detection" content="address=no" />
                <meta name="format-detection" content="time=no" />
                <c:ci_email_style_sheet />
            </head>
            <body style="-moz-osx-font-smoothing: grayscale; -ms-text-size-adjust: 100%; -webkit-font-smoothing: antialiased; -webkit-tap-highlight-color: transparent; -webkit-text-size-adjust: none; -webkit-touch-callout: none; margin: 0px; padding: 0px; width: 100% !important">



<!--    Email Header - End  -->

<!--    Email Content   -->
                                                                                        <h3>File password for enhancement of medical definitions communications to CommInsure clients</h3>
<p>Related to: {!RelatedTo.Id}</p><!-- DEBUG-->
<p>Related Name: {!relatedTo.Name}</p><!-- DEBUG-->

<c:CI_MailOut_Password mailID="{!relatedTo.id}" />
<p>If you have any questions, please contact your Business Development Manager.</p>

<!--    Email Content - End -->

<!--    Email Signature -->
<c:ci_email_signature />
<p>&nbsp;</p>
<p>&nbsp;</p>

<!--    Email Footer    -->

            </body>
        </html>
    </messaging:HtmlEmailBody>
</messaging:emailTemplate>

 
Best Answer chosen by Andrew Telford
Andrew TelfordAndrew Telford
Ok ,,,,

With a bit more searching, I was able to pass the ci_mailout__c id that the email template needs by adding the singleemailmessage attribute of
email_pass.setWhatId(thisMailout.id);
and 
email.setWhatId(thisMailout.id);

Hope that helps anyone out there that needs this functionality