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
Bob_zBob_z 

Visualforce email template with opportunity activity history information

I am trying to create a visualforce email template that shows information from a opportunity and all of the records activity history. I cannot figure out the code. Is there a way to convert the activity record id to text or display individual fields from the opportunity activity history? I am new at this so please forgive me. The code is below.  HELP!

 

 

 

<messaging:emailTemplate subject="Testing Visualforce Email Template" recipientType="User" relatedToType="Opportunity">
<messaging:HtmlEmailBody >
Account Name : {!Relatedto.Name} <br/>
Account Description : {!Relatedto.Description} <br/>
Customer Type: {!relatedTo.Customer_Type__c}<br/>
Activity: {!relatedTo.ActivityHistories}
</messaging:htmlEmailBody>
</messaging:emailTemplate>

<messaging:emailTemplate subject="Testing Visualforce Email Template" recipientType="User" relatedToType="Opportunity"><messaging:HtmlEmailBody >Account Name : {!Relatedto.Name} <br/>Account Description : {!Relatedto.Description} <br/>
Customer Type: {!relatedTo.Customer_Type__c}<br/>
Activity: {!relatedTo.ActivityHistories}
</messaging:htmlEmailBody></messaging:emailTemplate>

Best Answer chosen by Admin (Salesforce Developers) 
sfdcfoxsfdcfox

What you need is a pageBlockTable, dataTable, dataList, or repeat component. As an example:

 

 

    <messaging:plainTextEmailBody >
Here is the activity history for the opportunity "{!RelatedTo.Name}":
        <apex:repeat value="{!RelatedTo.ActivityHistories}" var="ActivityHistory">
{!ActivityHistory.ActivityDate}: "{!ActivityHistory.Subject}" ({!ActivityHistory.Status})
        </apex:repeat>
    </messaging:plainTextEmailBody>

"Value" is the list of records we wish to iterate over, while "var" is the name of a single instance in the repeating area. In my example, ActivityHistory is what I chose to name the variable, and it is valid only inside the repeat component. You may wish to refer to the component reference or the Visualforce Developer's Guide for additional information.

 

All Answers

sfdcfoxsfdcfox

What you need is a pageBlockTable, dataTable, dataList, or repeat component. As an example:

 

 

    <messaging:plainTextEmailBody >
Here is the activity history for the opportunity "{!RelatedTo.Name}":
        <apex:repeat value="{!RelatedTo.ActivityHistories}" var="ActivityHistory">
{!ActivityHistory.ActivityDate}: "{!ActivityHistory.Subject}" ({!ActivityHistory.Status})
        </apex:repeat>
    </messaging:plainTextEmailBody>

"Value" is the list of records we wish to iterate over, while "var" is the name of a single instance in the repeating area. In my example, ActivityHistory is what I chose to name the variable, and it is valid only inside the repeat component. You may wish to refer to the component reference or the Visualforce Developer's Guide for additional information.

 

This was selected as the best answer
Bob_zBob_z

Thank you very much, it worked like a charm.

Bob_zBob_z

How would i add a opportunity contact? Do i need to go through the contact role?

sfdcfoxsfdcfox

Yes, Opportunity Contact roles link contacts to opportunities.

Bob_zBob_z

I'm sorry I can not figure out how to get the information such as phone numbers, email address, etc. I have tried every wording possible for the field name.  If you could point me in the right direction I would appreciate it.  Can I query the contact role object with in the visualforce page somehow?

sfdcfoxsfdcfox

 

<messaging:emailTemplate subject="Test Opportunity Type" recipientType="Contact" relatedToType="Opportunity">
    <messaging:plainTextEmailBody >
        <apex:repeat value="{!RelatedTo.OpportunityContactRoles}" var="ContactRole">
            {!ContactRole.Contact.Name} ((!ContactRole.Contact.Account.Name}): {!ContactRole.Contact.Email}
        </apex:repeat>
    </messaging:plainTextEmailBody>
</messaging:emailTemplate>

You reference the Contact information through OpportunityContactRole.Contact. In this newly updated example, above, I reference the Name and Email of the contact. Of course, you can use any standard or custom field on the record. If you want the Contact's Account details, use OpportunityContactRole.Contact.Account. I have provided an example of this as well; you can use any account standard or custom field here as well.

 

kcrawfordIMSkcrawfordIMS

Thanks for all the input sfdcfox!

 

I'm looking to create a workflow and use this VF email template example you gave, but I'm wondering how I would send it to a specific contact role on the opportunity. for example if the contact role was listed as "lawyer"

 

Thanks,

 

 

Newbie Alert

Bob_zBob_z

That is a good question, I am trying to figure out how to send a time based workflow email alert to the primary contact from an opportunity and I am having no luck right now.  Any help would be greatly appreciated

sfdcfoxsfdcfox

This post applies to both inquiries posted after the solution.

 

You can't use the TIme Based Workflow feature for contact roles. Instead, you could:

 

* Use a Scheduled Apex Code interface, and have it periodically scan for records that meet a criteria to send the email. You can have the Workflow Rule use a Field Update to mark the records you'd like to notify. The Scheduled Apex Code piece can uncheck the boxes after a successful run.

* Use a Trigger that runs when a checkbox is checked. Use Time Based Workflow to check the box (triggers run even from Field Updates). You can use the @future method to send your data at some point after the box is checked, whcih is always "as soon as possible," usually within a few seconds to a few minutes.

* Copy the primary contact to a custom field on the opportunity using a trigger and/or Scheduled Apex Code setup. Have the Workflow Alert send an email to the contact named in this field. You'll want to stagger the Time Based Workflow with the Scheduled Apex Code so that the lookup field you use is correct at the time of mailing. The Time Based Workflow should try and schedule itself to run a couple of hours after the next scheduled Scheduled Apex Code run.

* Override the Contact Roles page with a Visualforce page, and have that page copy the primary contact to the opportunity so it is always consistent. Use the Time Based Workflow rule as normal, no Scheduled or Batch Apex Code required, but you do need an extension and a Visualforce page.

 

There's a few ways to do this, and none of them are necessarily 'wrong," although you will suffer tradeoffs depending on the type of setup you use. For example, using Scheduled Apex Code with Time Based Workflow means that a race condition could occur, so you would want to minimize that risk by determining how to best schedule them to work together. There's probably some other solutions that would work as well, depending on resources. For example, Outbound Messaging could notify an external server when it's time to send emails, and that server can query for then-current information.

 

The major problem here is that you will need a developer to implement any of these solutions, if you can't write it yourself. There's a lot of vendors out there that will do that, and most of them are pretty reasonably priced.