Friday, 25 August 2017

Auto-populate emails in "Additionalto,BCC" section of Conga Composer email sending window

Hello Awesome Developers,

Today I am coming with the interesting blog of ADMIN+DEVELOPMENT thing.

I hope all of you know about the document generation tool conga composer which
merge the data into templates for pixel-perfect proposals, quotes and more in Word,
PowerPoint, Excel, HTML emails & PDF's.

How conga composer work?
1) Configure template, email template, conga query etc with conga field format
2) Create custom button to launch the conga app along with required parameters
    like templateId etc

You can visit https://support.getconga.com for more details on this.

Our Scenario :
We have following custom object structure :
 Class__c                                                                   Participants__c
 Name                                                                        Contact - (Lookup to contact)
                                                                                   Class - (Lookup to Class__c)

So 1 class can have many participants.

Before the class begins the user needs to send the announcement email to participants.
For example, Salesforce Training is the class with 10 enrollments.Before class begins
user suppose to send announcement email to all of the participant's using configured
conga email template.

General Conga Configuration :
1. Configure conga email templates with conga fields.(Field coming from Class object (Merge Field))
2. Create a custom detail page button on Class__c object with content source as URL 
   and enter the URL (This you will find in conga documentation)
    For conga 8 it is :

/apex/APXTConga4__Conga_Composer?serverUrl={!API.Partner_Server_URL_290}&id={!Class__c.Id}

3. This will result as follows :




4. On-click of this button the conga composer window will launch and you will need
    to select the template and click "Merge and Email" producing the following result





Our Challenge : 

Auto-populate the "to" or "AdditionalTo" or "BCC" 
with Emails of Enrollments.

As per conga documentation, you can add following parameters in the custom button URL
1) EmailToId : Contact Or LeadId
2) EmailAdditionalTo : Email Address

Since the number of enrollments (with contact lookup) are not fixed so we can not use option 1.

In the option 2, we can give comma separated list of emails
(In our case List of Enrollment__r.Contact__r.Email)

Solution :
1. Create a long text field (Enrollment Emails) at a Class level which will store a comma
    separated list of emails captured from the enrollments once it's inserted, updated, deleted.

2. Trigger on Enrollment to update the class with the enrollment emails.

3. Change the conga button URL to :

/apex/APXTConga4__Conga_Composer?serverUrl={!API.Partner_Server_URL_290}&id={!SFDC_Class__c.Id}&EmailAdditionalTo={!Class__c.Enrollment_Emails__c}


Above will result in the following :



In case you want to emails in BCC then use EmailBCC parameter.


Trigger code you will find at this link : 

https://docs.google.com/document/d/1W85Z_Iqdcqq9Sq9W8Bq42vBdOmCUjBar5gQE0I1D6eQ/edit?usp=sharing

The above solution will work in lighting as well :)

Happy Coding !!!! 







Friday, 11 August 2017

Multi VF Page Redirects Using Single Controller

Hi Awesome Developers,

Have you ever thought of redirecting to multiple pages using a single controller, here is what I have come up with the scenarios of redirecting to different pages using same controller.

Scenario 1:
Main Page
<apex:page standardController="Account" extensions="PageRedirectDemo">
    <apex:form>
         <apex:inputtext value="{!strReceivedText}" /> <br/>
         <apex:inputtext value="{!objAccount.Id}" />
         <apex:commandbutton action="{!redirect}" value="Redirect"/>
   </apex:form>
</apex:page>

Controller :
public with sharing class PageRedirectDemo
{
   public string strReceivedText{get;set;}
   public Account objAccount{get;set;}

   public PageRedirectDemo(ApexPages.StandardController stdController){
         objAccount = (Account)stdController.getRecord();
   }

   public pagereference redirect(){
      PageReference ref = new PageReference('/apex/RedirectedPage'+'?id='+objAccount.Id);
      ref.setRedirect(false);
      return ref;
   }

}

Redirected Page
<apex:page standardController="Account" extensions="PageRedirectDemo">
 <apex:outputLabel>Value received from Page 1</apex:outputLabel> <br/>
 <apex:outputText> {!strReceivedText } </apex:outputText>
</apex:page>

Output :











The above will work well if I keep the signature of second page same as first. Now I have changed the signature of the second page as below and added empty constructor in the controller.

<apex:page controller="PageRedirectDemo">
 <apex:outputLabel>Value received from Page 1</apex:outputLabel><br/>
 <apex:outputText> {!strReceivedText } </apex:outputText> <br/>
  <apex:outputtext value="{!objAccount.Id}" />
</apex:page>

public with sharing class PageRedirectDemo
{
   public string strReceivedText{get;set;}
   public Account objAccount{get;set;}

   public PageRedirectDemo(){
   }
   public PageRedirectDemo(ApexPages.StandardController stdController){
         objAccount = (Account)stdController.getRecord();
   }

   public pagereference redirect(){
      PageReference ref = new PageReference('/apex/RedirectedPage'+'?id='+objAccount.Id);
      ref.setRedirect(false);
      return ref;
   }

}

You can see the values are not set due to change in signature,










Scenario 3 :
MainPage :
<apex:page controller="PageRedirectDemo">
    <apex:form>
         <apex:inputtext value="{!strReceivedText}" /> <br/>
         <apex:commandbutton action="{!redirect}" value="Redirect"/>
</apex:form>
</apex:page>

public with sharing class PageRedirectDemo
{
   public string strReceivedText{get;set;}
   public PageRedirectDemo(){
   }

   public pagereference redirect(){
      PageReference ref = new PageReference('/apex/RedirectedPage');
      ref.setRedirect(false);
      return ref;
   }

}

RedirectedPage
<apex:page controller="PageRedirectDemo">
 <apex:outputLabel>Value received from Page 1</apex:outputLabel><br/>
 <apex:outputText> {!strReceivedText } </apex:outputText> <br/>
</apex:page>

Output :













*IMP : Observe the URL in each scenario :)

Happy Redirecting ;)


Make custom button calling web-service static method working in Lightning

Hi Folks,

Recently we switched our classic Salesforce edition into Lightning edition.

The custom button calling visual-force page worked fine in lightning but the custom button executing Javascript or calling the Webservice method are not even displayed on the page layout as it's a known thing in Lightning.

We have a custom button calling Webservice method and we have two options to make it working in lightning.
1. Create a lighting component and call it using quick action. (For this we need to enable custom domain)

2.We can call a visual-force page and execute our method using the action attribute.
   (No need to enable custom domain)

Let us see how point 2 will actually work :

Suppose we have following code in the custom button
--------------------------------------------------------------------------------------------------------------------
{!REQUIRESCRIPT("/soap/ajax/29.0/connection.js")}
{!REQUIRESCRIPT("/soap/ajax/29.0/apex.js")}

sforce.apex.execute("SurveySender","sendSurvey",{OppId:"{! Opportunity.Id}"});
alert("Survey Sending Started");


Apex Class :
global class SurveySender {
    webservice static void sendSurvey(Id OppId) {
       system.debug('>>>>>>>>>Method Executed>>>>>>>>>>>'+pOppId);            
    }
}
---------------------------------------------------------------------------------------------------------------------

To work it in lightning :

1. Convert global class as below :

global class SurveySender {

   public Opportunity objOpp;

   global SurveySender(ApexPages.StandardController stdController){
        objOpp = (Opportunity)stdController.getRecord();
   }
   
    public pagereference sendEmail(){
      sendSurvey(objOpp.Id);
      return new pagereference(url.getsalesforcebaseurl().toexternalform()+'/'+objOpp.Id);
    }

   webservice static void sendSurvey(Id OppId) {
       system.debug('>>>>>>>>>Method Executed>>>>>>>>>>>'+OppId);            
    }
}


2. Create a Visualforce page with a standard controller :

<apex:page standardController="Opportunity" extensions="SurveySender"
   action="{!sendEmail}">
</apex:page>

3. Convert custom button behavior to Display in existing window without sidebar or header
    Select content source to the Visualforce page created in step 2.

4. Now the button will behave same like the webservice method.


Happy Coding !!!!