SalesForce for Domino Dogs 1: Profile Documents

Following on from the Initial Session “Salesforce for Domino Dogs” that Paul Mooney and I did at Engage and a modified version of which that has just been presented at #DNUG I figured that a series of dev articles on how you would do a job in Salesforce that you had always taken from granted in Domino might be a good idea, because:

  1. It would give an honest way of comparing features between the 2 systems shorn of the hype/marketing/platform bashing, that frankly gets on my thungers from both sides.
  2. It will hopefully help people trying to integrate the 2 systems.
  3. As IBM are one of the largest Salesforce consultancies in the world, it is something a champion should do.
  4. The Salesforce community is very short on this kind of thing given its size in comparison to traditional IBM communities and with people like René in it I want to try and help improve it.

These articles are not in any order and are not meant to represent any form of training guide.

So lets get started, first up: Profile Documents!!


In Domino you tend to store config settings for an app in a profile document1 for all your one off settings

To get the same features in Salesforce you use a ‘custom setting’ which does exactly the same job and has one huge advantage over using a normal Salesforce custom object that could do the same job.

(It should be noted that Domino profiles are nothing like Salesforce profiles)

To create a custom setting, go into Setup and search for “Custom Settings”


Click on the “New” button, and fill in some sane details, for normal configs i.e. stuff you would use system wide, select a setting type of “List”, if you want to use them for things like default values in fields and formulas then select “Hierarchy”


Click ‘Save’ and you now have a custom setting object, you can add one or more fields to it just as you would any other object in Salesforce

Added all the fields you want?, lets put in some data. if you go back to the list of custom settings you will see that you now have a “manage” link, click this

Then click “New”


Fill in the fields just like you would on a normal form, if this is a Setting there is only going to be one of, I tend to give it the same title as the name of the object to keep things simple, in this case “General Settings”, if you are going to use it multiple times than give it a name that will make sense in the context of your code


All done. now we can use the setting in our code and see the reason why we would use them vs. a normal custom object.

As you can see from the code below, you don’t have to use a Select statement, which means getting the settings wont count against your apex limits, HORRAY!!!

You just have to create a new instance of the setting object then you can just “getInstance” with the Name of the object you created to get the document back.

General_Settings__c generalSettings = General_Settings__c.getInstance('General Settings');
String thirdPartAppURL = '';
if (null != generalSettings) {
     thirdPartAppURL = generalSettings.Third_Part_App_URL__c;
} 

Simples..

  1. Well you are supposed to, but you never do thanks to the evil caching and the fact the are are a sod to just copy around, so you end up with a config document and a view you store them in.[]

Editable salesforce templates’

Editing an email that is generated via an Saleforce email template BEFORE it is sent is something that I have had a few clients grumble over, the feature is baked into the Quote object which makes sense, but you try telling clients they cant have it for Order objects….

So this is a basic solution that gets round this problem and is the basic set-up for expanding it to solve all the issues, in this case I am solving the most common issue I have come access, in that you are generating a order recept or delivery note pdf using the ‘renderAs=”PDF”‘ option in an email template and want to send the email with a custom message to one or more people that you decide at the time of sending.

To do that we are going to create a new visual force page that resembles a normal email and use it to fill in the details before we generate the email template

 

 

1) Create a new email custom object

This is just a basic object with the fields we need for the email, and a lookup field to the parent Order


Note: For brevity I’m leaving out the creation of the layout for the custom object and the adding of the related list to the Order Layout

2) Add some extra Fields to your Order object

These are the temporary fields that we are using to actually send the template email, resist the urge to set the To/CC/BCC as email fields as that will stop you having multiple recipients.

 

Obviously these fields have to be editable to all but not part of the order layouts so they don’t show up.

3) Create a new “Template Editor” Visualforce Page

This page is as simple or complex as you can want it, my one here takes email address separated by a comma but yours can be a really posh contact lookup

 

<apex:page controller="sendOrderPDFEmail">
    <apex:messages />
    <apex:pageBlock title="Email for Order: {!order.Name}">
    <p>Fill out the fields below and click "Send email"</p>
    <apex:form ><br/><br/>
        <apex:outputLabel value="Template To Attach" for="chooseTemplate"/>: <br/>
        <apex:selectList id="chooseTemplate" value="{!template}" size="1">
            <apex:selectOption itemValue="Template1" itemLabel="Template1"/>
            <apex:selectOption itemValue="Template2" itemLabel="Template2"/>
            <apex:selectOption itemValue="Template3" itemLabel="Template3"/>
        </apex:selectList>
        <br/><br/>  
        <apex:outputLabel value="To" for="To"/>: <br/>
        <apex:inputText value="{!to}" id="To" maxlength="255" style="width: 300px;"/>
        <br/><br/>  
        <apex:outputLabel value="CC" for="CC"/>: <br/>
        <apex:inputText value="{!cc}" id="CC" maxlength="255" style="width: 300px;"/>
        <br/><br/> 
        <apex:outputLabel value="BCC" for="BCC"/>: <br/>
        <apex:inputText value="{!bcc}" id="BCC" maxlength="255" style="width: 300px;"/>
        <br/><br/> 
        <apex:outputLabel value="Subject" for="Subject"/>: <br/>
        <apex:inputText value="{!subject}" id="Subject" maxlength="255" style="width: 500px;"/>
        <br/><br/>
        <apex:outputLabel value="Body" for="Body"/>: <br/>        
        <apex:inputTextarea value="{!body}" id="Body" richText="true" rows="20"/>
        <br/><br/>
        <apex:commandButton value="Send Email" action="{!send}"/>
    </apex:form>
    </apex:pageBlock>
</apex:page>

 

4) Create the “Send” code (don’t forget to create your test code).

I have just put comments on the code, as its not complex and follows the flow chart at the top of the blog.

public class sendOrderPDFEmail {
    public String template { get; set; }
    public String cc { get; set; }
    public String bcc { get; set; }
    public String to { get; set; }
    public String subject { get; set; }
    public String body { get; set; }
    public Account contactLookup { get; set; }
    private final Order order;
    public sendOrderPDFEmail() {
        //Get the Id of the order that we are working on
        template = '';
        String OrderId = ApexPages.currentPage().getParameters().get('id');
        order = [SELECT Name, ID
        FROM Order
        WHERE Id = :OrderId];
    }
    public Order getOrder() {
        return order;
    }
    public PageReference send() {
    if( !String.isBlank(cc)) {
        cc = cc.trim();
    }
    if( !String.isBlank(bcc)) {
        bcc = bcc.trim();
    }
    if( !String.isBlank(to)) {
        to = to.trim();
    }
    //Mail email Order object
    orderemail__c con = new orderemail__c(
        Address_CC__c=cc,
        Address_BCC__c=bcc,
        Address_to__c=to,
        Body__c=body,
        parent_order__c=order.id,
        Subject__c=subject,
        Template__c=template
        );
    insert con;
    //Store the temp values in the Order
    order.le_Address_BCC__c=bcc;
    order.le_Address_CC__c=cc;
    order.le_Address_to__c=to;
    order.le_Body__c=body;
    order.le_Subject__c=subject;
    order.le_Template__c=template;
    update order;
    if ( String.isBlank(to) ) {
         to = 'test@test.com';
     }
     // Construct the list of emails we want to send
     List<Messaging.SingleEmailMessage> lstMsgs = new List<Messaging.SingleEmailMessage>();
     Messaging.SingleEmailMessage msg = new Messaging.SingleEmailMessage();
     //set the email tempalte from the name chossen on the email form
     EmailTemplate[] emailTemplate = [select id from EmailTemplate where Name=:template];
     if (emailTemplate.size() > 0) {
          msg.setTemplateId( emailTemplate[0].id );
     } else {
         msg.setPlainTextBody('No Template Provided');
     }
     // Trim and convert the comma delimted string to a suitable recipiant list for the email.
     String[] trimmedtoarray;
     if (!String.isBlank(to)) {
        String[] toarray = to.split(',');
        trimmedtoarray = new String[toarray.size()];
        Integer k = 0;
        for (String singlEmail: toarray) {
           trimmedtoarray[k++] = singlEmail.trim();
        }
        msg.setToAddresses(trimmedtoarray);
     }
     if (!String.isBlank(cc)) {
         String[] ccarray = cc.split(',');
         String[] trimmedccarray = new String[ccarray.size()];
         Integer i = 0;
         for (String singlEmail: ccarray) {
             trimmedccarray[i++] = singlEmail.trim();
         }
         msg.setCcAddresses(trimmedccarray);
     }
     if (!String.isBlank(bcc)) {
         String[] bccarray = bcc.split(',');
         String[] trimmedbccarray = new String[bccarray.size()];
         Integer j = 0;
         for (String singlEmail: bccarray) {
            trimmedbccarray[j++] = singlEmail.trim();
         }
         msg.setBccAddresses(trimmedbccarray);
     }
     // Templates do need an object (Contact that he pdf will be used to generate against) for things like first name etc
     // So we are going to pick the first contact on the to list.
     Contact c = [select id, Email from Contact where email = :trimmedtoarray[0] limit 1];
     msg.setWhatId( order.id );
     msg.setTargetObjectId(c.id);
     lstMsgs.add(msg);
     //Send the email
     Messaging.sendEmail(lstMsgs);
    // clear out the temp fields we used to generate the email.
    order.le_Address_CC__c='';
    order.le_Address_BCC__c='';
    order.le_Address_to__c='';
    order.le_Body__c='';
    order.le_Subject__c='';
    order.le_Template__c='';
    update order;
        //Send the user back to the Order
        PageReference backToQuotePage = new PageReference('/' + order.id);
        backToQuotePage.setRedirect(true);
        return backToQuotePage;
    }
}

##### 5) Create a button in the Order object to launch your “Email” screen

##### 6) Update your Email template
Now update your email templates to use the “le_Body__c” and “le_Subject__c” fields for their email contents,

<messaging:emailTemplate recipientType="Contact"
    relatedToType="Order"
    subject="{!RelatedTo.le_Subject__c}"
    replyTo="orders@XXXX.com">
    <messaging:htmlEmailBody >
        <html>
        <c:EmailStyle />
        <body>
            <apex:outputText value="{!RelatedTo.le_Body__c}" escape="false"/>
        </body>
        </html>
    </messaging:htmlEmailBody>
    <messaging:plainTextEmailBody >
    <apex:outputText value="{!RelatedTo.le_Body__c}" escape="false"/>
    </messaging:plainTextEmailBody>
<messaging:attachment renderAs="PDF" filename="GeneratedEmail.pdf">
      <style>
      @page {
      size: A4 landscape;
      margin-top: 1.0cm;
      margin-left: 1.0cm;
      margin-right: 1.0cm;
      margin-bottom: 7cm;
        @bottom-center {
          content: element(footer);
        }
      }
      </style>
        <html>
        <c:EmailStyle />
        <body>
        //POSH PDF STUFF HERE
        </body>
        </html>
</messaging:attachment>
</messaging:emailTemplate>

Note:

So PDF’s generated by Email templates in Salesforce are not saved and you cant get hold of them, so we are not saving them in the custom email object, if you do need that, then you will need to convert your email templates to visual force pages then render as PDFs and save them in the custom objects.