function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion

Visual Force Email Bug

I have created a trigger that sends a Visual Force email template. There are basically two cases that cause the trigger to fire and send the email. In one case everything works fine. In the second case the email is sent but arrives blank. The two cases are as follows:


The email works fine for this case:

1: When an opportunity is updated to a certain stage or higher and has an OpportunityProduct of a specific type. (We use a custom OpportunityProduct__c object). Phrased in our internal terms...when an eBooks opportunity is updated from a stage below 80% to be 80% or higher.


The email arrives blank for this case:

2. When an opportunity is inserted at 80% or higher and is then assigned the specific product type(in this case ebooks)


I have done some debugging, and the result has been greater confusion. In particular, I used a systemAssert to verify that the send email method that I pass the Opportunity to from the trigger actually exists just before the line that sends the email. The opportunity is there in both cases. I then used the same systemAssert to verify that the email has all of the required parameters. All of the parameters are there in both cases, and they are all the same. So why wouldn't the emails arrive the same?



marcRecordAlert on Opportunity (after update) { for(ID opptyID : Trigger.newMap.keySet()) { Opportunity oppty = [select id, Name, Probability, ProductSummary__c, StageName, RecordType.Name, Owner.BusinessChannel__c from Opportunity where ID =:opptyID]; if(null!=oppty.ProductSummary__c) { if(((oppty.Probability>=80) && (oppty.ProductSummary__c.Contains('eBooks Collection')) && (oppty.Owner.BusinessChannel__c == 'Licensing Sales') ) &&( (null == Trigger.oldMap.get(opptyID).ProductSummary__c) ||(Trigger.oldMap.get(opptyID).ProductSummary__c.Contains('eBooks Collection')==false) ||(Trigger.oldMap.get(opptyId).Probability<80) ) ){ Opportunity_Handler OH = new Opportunity_Handler(); OH.marcRecordAlert(oppty); } } } }


public void marcRecordAlert(Opportunity oppty) { Messaging.SingleEmailMessage marcEmail = new Messaging.SingleEmailMessage(); Emailtemplate et = [select id from Emailtemplate Where Name='MARC Records Alert' AND TemplateType='visualforce' Limit 1]; marcEmail.setTemplateID(et.ID); User soa = [select ID, email from User Where Name='SOA']; marcEmail.setTargetObjectID(soa.ID); marcEmail.setWhatID(oppty.ID); //marcEmail.setToAddresses(new String[] {}); marcEmail.setCcAddresses(new String[]{''}); marcEmail.setReplyTo(''); marcEmail.setSenderDisplayName('Sales Operations Americas'); marcEmail.setSaveAsActivity(false); //System.assert(false,'This is the marcEmail'+marcEmail); try {

Messaging.sendEmail(new Messaging.SingleEmailMessage[] { marcEmail }); } catch (Exception me){ System.assert(false,'Send email failed with this error: '+me); } }



<messaging:emailTemplate subject="MARC Records Alert" recipientType="User" relatedToType="Opportunity"> <messaging:htmlEmailBody > <html> <body> <p>Greetings:</p> <p><em>{!relatedTo.Account.Name}</em> has just accepted a proposal for the following products.</p> <p>Please contact <em>{!relatedTo.Contact__r.Name}</em> at <em>{!relatedTo.Contact__r.Email}</em> to make sure they have the appropriate MARC records</p> <p>If there is no contact information then please contact the owner of this Opportunity: <em>{!relatedTo.Owner.Name}</em>.</p> <apex:datatable cellpadding="5" var="prods" value="{!relatedTo.Products__r}"> <apex:column value="{!prods.lc_Product__r.Name}" headerValue="Product Name"/> <apex:column value="{!prods.lc_Product__r.PriceListYear__c}" headerValue="Price List Year"/> </apex:datatable> You can review the full Opportunity details by following this link: <a href="{!relatedTo.ID}" id="theLink">{!relatedTo.ID}</a> </body> </html> </messaging:htmlEmailBody> </messaging:emailTemplate>