Saturday, December 26, 2015

Using Ant to Deploy Salesforce Code

Use following steps to deploy Salesforce code using Ant

1. Install Java on your local machine
Go to http://www.oracle.com/technetwork/java/javase/downloads/index.html. And get the latest version of the Java JDK and install it on your machine.

 2. Install ANT in your local machine.
Go to http://ant.apache.org/bindownload.cgi and get these files to your local. Once these files are on your computer, there is no further installation required.

3. After installation of java and ANT, create following environment variable to set the path.
ANT_HOME -- give Ant location on your machine. For example in my machine I have stored ant in “C:\apache-ant-1.9.6” location
Add following at the end of path variable:
C:\Program Files\Java\jdk1.6.0\bin;%ANT_HOME%\bin

 4. Download Salesforce.jar file and add that file to your ant installation’s lib directory.
To download this Go to setup->Develop-> click on Tools -> and click on Force.com migration tool to download
After downloading extract the downloaded ZIP file and copy the ant-salesforce.jar file and paste it in Ant lib directory in your ant installation file.
5. Now Force.com migration tool installation is completed.

Use Migration tool to deploy components in Salesforce
To deploy metadata by using this migration tool we need prepare following 2 important files

Build.xml

<project name="Sample usage of Salesforce Ant tasks" default="test" basedir="." xmlns:sf="antlib:com.salesforce">
<property file="buildbatch.properties"/>
<property environment="env"/>
<target name="Deploymetadata">
<sf:deploy username="TDeployUsername" password="ToDeployPasswordalonwithSecuirtyToken" serverurl="https://test.salesforce.com" deployroot="CodeFolder"
 runAllTests="false" trace="true" pollWaitMillis="10000" maxPoll="100"/>
</target>

<target name="retrieveCode">
<sf:deploy username="SourceUsername" password="SourcePasswordalonwithSecuirtyToken" serverurl="https://test.salesforce.com" retrieveTarget="CodeFolder"/>
</target>

<target name="DeployCheckmetadata">
<sf:deploy username="TDeployUsername" password="ToDeployPasswordalonwithSecuirtyToken" serverurl="https://test.salesforce.com" deployroot="CodeFolder"
 checkOnly="true"/>
</target>
</project>

Package.xml: This file is a project manifest that lists all the components you want to retrieve or deploy in a single request.

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>*</members>
        <name>ApexClass</name>
    </types>
    <types>
        <members>*</members>
        <name>ApexComponent</name>
    </types>
    <types>
        <members>*</members>
        <name>ApexPage</name>
    </types>
    <types>
        <members>*</members>
        <name>ApexTrigger</name>
    </types>
    <types>
        <members>*</members>
        <name>StaticResource</name>
    </types>
    <version>30.0</version>
</Package>

How to run this script in command prompt
1. Open command prompt and enter file path of your build.xml file.
For example if my filed file in  “C:\Build”. Enter this command in command prompt “cd C:\Build”.
2. Now retrieve the code your local from source organization. To retrieve the components mentioned in your package.xml run the command “ant retrieveCode” which is mentioned in your build.xml
3. Once you have done with retrieving components to your local, now you can deploy those components to your target organization. To deploy your components run the command “ant deployCode”, which is mentioned in your build.xml file.


Update the same record in After Trigger context

Normally when you try to update a record in After Trigger Context you will get "Record is read only" Error.
Following is the workaround to prevent this

If we create a new instance of a SObject in the Apex Trigger in memory using the Id of the newly created record as provided in the After Trigger context, we can perform an Update DML statement and will not get a read only error. This is because in Apex, SObject is seen as a new reference (even though the records have the same SFDC ID) and therefore is eligible for DML operations

List<Contact>
newcontactlist = new List<Contact>();
if(triggerResultsMap.values().size() > 0){
                for(Contact actualContact : contactRecs.values()){
                                Contact dupecontact = triggerResultsMap.get(actualContact.Id);
                                //actualContact.Linked_Contact__c = dupecontact.Id; //This will Fail
                                Contact origContactUpdate = new Contact(Id=actualContact.Id, Linked_Contact__c = dupecontact.Id); //This will WORK
                                newcontactlist.add(origContactUpdate);
                }
                //update contactRecs.values(); //Update the Records -- this wil fail as we are updating main recods
                update newcontactlist;

}

Determing if Email is sent from Salesforce or not

There is an Email log that you could use. It’s available in the setup menu under Monitoring.It’s only for the past 30 days and you would have to manually check it.
From the email log page: “Email logs describe all emails sent through salesforce.com and can be used to help identify the status of an email delivery. Email logs are CSV files that provide information such as the email address of each email sender and its recipient, the date and time each email was sent, and any error code associated with each email. Logs are only available for the past 30 days.”
Go to Set UP> Logs > Email Logs
You can Request for logs and SFDC will provide an email notification once Log is available.

Debug log of Connection user in salesforce to salesforce Integration

When configuring Debug Logs, you cannot choose a Salesforce to Salesforce Connection User from the User Lookup, but there is a workaround to achieve this.
To Capture Debug Logs for a Connection User open the following URL in your browser:
https://[salesforceInstance].salesforce.com/p/setup/layout/AddApexDebugLogUser?retURL=%2Fsetup%2Fui%2FlistApexTraces.apexp&UserLookupInput_lkid=[connectingUserId]&UserLookupInput=[ConnectingUser Name]
Replace [salesforceInstance] with your salesforce instance, 
UserLookupInput_lkid is the ID of the Connection User and UserLookupInput is the User name. 
You can find the user ID of the connection user, by inspecting the CreatedById for a record created by this user.

Wednesday, April 15, 2015

Enable inline editing after overriding Edit button of Salesforce Object

When we override edit button of any object in sales force then inline editing of that object in other standard layouts are disabled for that specific object.

We can provide inline editing in visualforce page for which we have overridden the edit button using <apex:inlineEditSupport> tag, but if object uses different record types and based on record types different standard page layouts are assigned then inline editing is disabled in all that layouts.

To Enable inline editing in all other standard layouts, we have to do the following steps

Do not override the object with any visualforce page, instead do the page redirect from home page component.

Create a home page component with following javascript code, and add that home page component to the current home page layout.


<script>
    var objectCode = window.top.location.pathname.substring(1,4);
    var isedit = window.top.location.pathname.substring(16,18);
    var noOverride = window.top.location.search.search('nooverride=1');

if(objectCode == 'objCode' && (isedit == '/e') && noOverride == -1){
    var pid = window.top.location.pathname.substring(1,16);
    window.top.location = '/apex/VisualforcePage?id='+pid;
}
</script>

in that visualforce page perform proper redirection in action method of page, and redirect page to standard layout by adding nooverride=1 in the url

ex:
http://salesforceInstance/Recordid?nooverride=1


Hope this helps!!

Thanks

Implementing Escalations Rules on Custom Objects in Salesforce

Salesforce provides Escalation actions only in Cases Object.We can implement escalations actions on custom object by creating 2 time dependent workflow rules for respective object

Steps as follows

Create one Date custom field -- Next Escalation Date in salesforce.

1st Time Dependent Rule:

  1. Define conditions for workflow rule
  2. Add Time Dependent workflow Trigger based on days of escalations
  3. Create following Time dependent workflow actions
    • Send an Escalation email
    • Create Field update to set Next Escalation Date field to Today


2nd Time Dependent Rule:

  1. Use same conditions defined in 1st rule and add extra condition for Date Field to check for today
  2. Add Time Dependent workflow Trigger based on days of escalations 
  3. Create following Time dependent workflow actions
    • Send an Escalation email
    • Create Field update to set Next Escalation Date field to Today

2nd Workflow rule will trigger recursively, till the time condition is satisfied.