SALESFORCE USEFUL VALIDATION RULES

Improve the quality of your data using validation rules. Validation rules verify that the data a user enters in a record meets the standards you specify before the user can save the record. A validation rule can contain a formula or expression that evaluates the data in one or more fields and returns a value of “True” or “False”. Validation rules also include an error message to display to the user when the rule returns a value of “True” due to an invalid value.

After you have defined validation rules:

  1. The user chooses to create a new record or edit an existing record.
  2. The user clicks Save.
  3. All validation rules are verified.
  • If all data is valid, the record is saved.
  • If any data is invalid, the associated error message displays without saving the record. 
    4.The user makes the necessary changes and clicks Save again.

There are many operators and functions which we can use in salesforce validation.
The most important and tipical is use to REGEX function in validation.

A regular expression (regex or regexp for short) is a special text string for describing a search pattern. You can think of regular expressions as wildcards. You are probably familiar with wildcard notations such as *.txt to find all text files in a file manager.

REGEX: Compares a text field to a regular expression and returns TRUE if there is a match. Otherwise, it returns FALSE. A regular expression is a string used to describe a format of a string according to certain syntax rules.

How to use regex:
REGEX(text_field, regex_text) replace regex_text with the regular expression you want to match.

Validation Rule Example:
1. This example ensures that a custom field called SSN matches a regular expression representing a valid social security number format of the form 999-99-9999.

Regex to validate user input in SSN field: "[0-9]{3}-[0-9]{2}-[0-9]{4}"
[0-9] => 0 through 9.
{3}   => 3 times.
So [0-9]{3} => 0 through 9 3 times.

Function:
NOT(
    OR(
LEN (SSN__c) = 0,
REGEX(SSN__c, "[0-9]{3}-[0-9]{2}-[0-9]{4}")
    )
)

2. Validates that the account Billing Zip/Postal Code is in the correct format if Billing Country is Canada. Canadian postal code must be in A9A 9A9 format.

Regex to validate user input in account Billing Zip/Postal Code field: "((?i)[ABCEGHJKLMNPRSTVXY]\\d[A-Z]?\\s?\\d[A-Z]\\d)?"

?i =>   Case-insensitive matching enabled
[ABCEGHJKLMNPRSTVXY] => A, B... or Y
\ => Nothing, but quotes the following character
\d =>   A digit: [0-9]
\s => A whitespace character
[A-Z] =>  A through Z
X? => X, once or not at all

Function:
AND(
OR(
BillingCountry = "CAN",
BillingCountry = "CA",
BillingCountry = "Canada"
),
NOT(
REGEX(
BillingPostalCode,
"((?i)[ABCEGHJKLMNPRSTVXY]\\d[A-Z]?\\s?\\d[A-Z]\\d)?"
)
)
)


Salesforce + OAuth 1.0


Salesforce integration

The below code is OAuth 1.0 from salesforce.
Here i just give Yelp api intregration example, you can change the code as per your requirement.

public class YelpApiCallout {
    public String consumerKey = 'xxxxxxxxxxxxxxxxx';
    public String token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
    public String timestamp = '';
    public String nonce = '';
    public String consumerSecret = 'xxxxxxxxxxxxxx';
    public String tokenSecret = 'xxxxxxxxxxxxxxxxxxx';
    public String signature = '';
    public Map<String, String> parameters = new Map<String, String>();
 
    public String location  {get; set;}
    public String jasonData ;
    public YelpDataWrapper apiRecords   {get; set;}
    public String term   {get; set;}
 
    public void accessToken(){
        term = ApexPages.CurrentPage().getParameters().get('term');
        String locationWOspace = location.replace(' ', '%20');
        String termWOspace;
        if(term != null){
            termWOspace = term.replace(' ', '%20');
        }
        HttpRequest req = new HttpRequest();
        String endpointurl ='http://api.yelp.com/v2/search?                            location='+locationWOspace+'&limit=20&term='+termWOspace;   
        req.setEndpoint(endpointurl);
        req.setMethod('GET');
        sign(req);
        Http httpOath = new Http();
        HTTPResponse res = httpOath.send(req);
     
        jasonData = res.getBody();
     
        //Step 3:parse the received JSON
        JSONParser parser = JSON.createParser(jasonData);
        while (parser.nextToken() != null) {
            if (parser.getCurrentToken() == JSONToken.START_OBJECT) {
                 apiRecords = ( YelpDataWrapper)parser.readValueAs(YelpDataWrapper.class);
            }
        }
    }
 
    private void refreshParameters() {
        parameters.clear();
        parameters.put('oauth_consumer_key',consumerKey);
        if(token!=null) {
            parameters.put('oauth_token',token);
        }
        parameters.put('oauth_signature_method','HMAC-SHA1');
        parameters.put('oauth_timestamp',timestamp);
        parameters.put('oauth_nonce',nonce);
    }
 
    private Map<String,String> getUrlParams(String value) {
        Map<String,String> res = new Map<String,String>();
        if(value==null || value=='') {
            return res;
        }
        for(String s : value.split('&')) {
            System.debug('getUrlParams: '+s);
            List<String> kv = s.split('=');
            if(kv.size()>1) {
              String encName = EncodingUtil.urlEncode(EncodingUtil.urlDecode(kv[0], 'UTF-8'), 'UTF-8').replace('+','%20');
              String encValue = EncodingUtil.urlEncode(EncodingUtil.urlDecode(kv[1], 'UTF-8'), 'UTF-8').replace('+','%20');
              System.debug('getUrlParams:  -> '+encName+','+encValue);
              res.put(encName,encValue);
            }
        }
        return res;
    }
 
    private String createBaseString(Map<String,String> oauthParams, HttpRequest req) {
        Map<String,String> p = oauthParams.clone();
        if(req.getMethod().equalsIgnoreCase('post') && req.getBody()!=null &&
           req.getHeader('Content-Type')=='application/x-www-form-urlencoded') {
            p.putAll(getUrlParams(req.getBody()));
        }
        String host = req.getEndpoint();
        Integer n = host.indexOf('?');
        if(n>-1) {
            p.putAll(getUrlParams(host.substring(n+1)));
            host = host.substring(0,n);
        }
        List<String> keys = new List<String>();
        keys.addAll(p.keySet());
        keys.sort();
        String s = keys.get(0)+'='+p.get(keys.get(0));
        for(Integer i=1;i<keys.size();i++) {
            s = s + '&' + keys.get(i)+'='+p.get(keys.get(i));
        }
 
        return req.getMethod().toUpperCase()+ '&' +
            EncodingUtil.urlEncode(host, 'UTF-8') + '&' +
            EncodingUtil.urlEncode(s, 'UTF-8');
    }
 
    public void sign(HttpRequest req) {
        nonce = String.valueOf(Crypto.getRandomLong());
        timestamp = String.valueOf(DateTime.now().getTime()/1000);
 
        refreshParameters();
 
        String s = createBaseString(parameters, req);
 
        System.debug('Signature base string: '+s);
 
        Blob sig = Crypto.generateMac('HmacSHA1', Blob.valueOf(s),
                       Blob.valueOf(consumerSecret+'&'+
                                    (tokenSecret!=null ? tokenSecret : '')));
        signature = EncodingUtil.urlEncode(EncodingUtil.base64encode(sig), 'UTF-8');
        System.debug('Signature: '+signature);
 
        String header = 'OAuth ';
        for (String key : parameters.keySet()) {
            header = header + key + '="'+parameters.get(key)+'", ';
        }
        header = header + 'oauth_signature="'+signature+'"';
        System.debug('Authorization: '+header);
        req.setHeader('Authorization',header);
    }
 
    public class YelpDataWrapper
    {
       public List<businesses> businesses  {get; set;}
    }
 
    public class businesses
    {
        public String rating               {get; set;}
        public String image_url            {get; set;}
        public String review_count         {get; set;}
        public String name                 {get; set;}
        public String snippet_image_url    {get; set;}
        public String url                  {get; set;}
        public String rating_img_url_large {get; set;}
        public String id                   {get; set;}
        public String snippet_text         {get; set;}
    }
 
}

AngularJS + OAuth 1.0


OAuth callout is very simple and easy with AngularJS.
Here i just used a simple Yelp Api integration example . You can change this as per your requirment.

We need to construct a signature "base string", which consists of a concatenation of three request elements:
1. The HTTP request method.
2. The base URL the request is being sent to.
3. A normalized string of the parameters in the request.

and generate an oauth_signature using HMAC-SHA1 method.


Js code:
var app = angular.module('MyApp', []);

app.controller('MainCtrl', ['$scope', 'MyYelpAPI', function($scope, MyYelpAPI) {
$scope.businesses = [];
MyYelpAPI.retrieveYelp('', function(data) {
$scope.businesses = data.businesses;
    });

}]).factory("MyYelpAPI", function($http) {
return {
"retrieveYelp": function(name, callback) {
var method = 'GET';
var url = 'http://api.yelp.com/v2/search';
var params = {
callback: 'angular.callbacks._0',
location: 'San+Francisco',
oauth_consumer_key: 'xxxxxxxxxxxxxxxx', //Consumer Key
oauth_token: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', //Token
oauth_signature_method: "HMAC-SHA1",
oauth_timestamp: new Date().getTime(),
oauth_nonce: randomString(32, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'),
term: 'Restaurants'
};
var consumerSecret = '_wkOfBWAlsQK6kUPcDw_MXC8sMM'; //Consumer Secret
var tokenSecret = 'uEqyN4F3GLKEOTAEgNAlyugh1iI'; //Token Secret
var signature = oauthSignature.generate(method, url, params, consumerSecret, tokenSecret, { encodeSignature: false});
params['oauth_signature'] = signature;
$http.jsonp(url, {params: params}).success(callback);
}
}
});

function randomString(length, chars) {
     var result = '';
     for (var i = length; i > 0; --i) result += chars[Math.round(Math.random() * (chars.length - 1))];
                return result;
}



Html code:
<html>
    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.js"></script>
        <script type="text/javascript"  src="oauth-signature.min.js"></script>
    </head>
    <body ng-app="plunker">
        <div  ng-controller="MainCtrl">
            <ul>
                <li data-ng-repeat="business in businesses">
                    {{business.name}}
                </li>
            </ul>
        </div>
    </body>
</html>

Salesforce Lightning Connect

Lightning Connect is a framework that enables you to access and use external data stored outside Salesforce, such as data in an enterprise resource planning (ERP) system. Copying the external data into your organization can be redundant and inefficient, especially if the data is constantly changing. You can instead connect to the external data source and access just the data you need when you need it, via Web service callouts.

Note: "You can currently use Lightning Connect to read external data, but not to create or update it."

External Objects vs. Custom Objects:

External objects share much of the same functionality as custom objects. For example, you can:

  • Access external objects via list views, detail pages, record feeds, custom tabs, and page layouts.
  • Define relationships between external objects and standard or custom objects to integrate data from different sources.
  • Enable Chatter feeds on external object pages for collaboration. 
Here is a quick comparison of the features supported in external objects and custom objects:

FeatureCustom ObjectsExternal Objects
Data stored in SalesforceYesNo
ReadYesYes
WriteYesNot Yet
Tabs, LayoutsYesYes
VisualforceYesYes
Field-level SecurityYesYes
SharingYesNo
REST and SOAP APIYesYes
SOQLYesYes (limited)
Search and SOSLYesYes (pass-through)
Formula FieldsYesNot Yet
Workflow, TriggersYesNot Yet
Reports and AnalyticsYesNot Yet
ChatterYesYes (no field tracking)
Types of External Connections:

To connect to an external data source and create external objects for it, Lightning Connect uses a specially designed adapter. There are currently three types of adapters.
  • OData 2.0 adapter—This lets you create external objects for data exposed by any OData 2.0 producer on the Internet. OData (Open Data Protocol) is a modern, REST-based protocol for integrating data. Vendors such as SAP and Microsoft have already implemented OData support, so products such as NetWeaver and SharePoint are directly accessible. Integration products from Salesforce partners extend the reach of Lightning Connect to a much wider range of back-office systems.
  • Salesforce adapter (pilot only)—This lets you create external objects for data from other Salesforce organizations. It uses the standard Salesforce APIs and directly connects to the remote organization without the need of any intermediary Web service, as is the case with OData.
  • Apex adapter (pilot only)—This is an SDK you can use to write your own adapters. It provides additional flexibility in case the OData or Salesforce adapters aren’t suitable for your needs.


Custom labels in javascript

We can use '{!$Label.Label_Name}' in JS function if this funtion is written on Visual force to access labels.

But Its tricky, If we need to access labels in JS file which is saved in static resource:
There are two way to do the same requiremnt:

1. Pass label as a parameter or pass-through attributes to JS function.

2. JavaScript bridging component:

2.a) loads before your script, like so:
<script>
    window.$Label = window.$Label || {};
    $Label.MyError = '{!JSENCODE($Label.MyError)}';
    $Label.MyPrompt = '{!JSENCODE($Label.MyPrompt)}';
    $Label.MyMessage = '{!JSENCODE($Label.MyMessage)}';
</script>
2.b) Now in your javascript (in a static resource) use the variables just as 
if they were VF without {!}
function errorHandler() {
    console.log($Label.MyError);
    alert($Label.MyMessage);
}

Conditional IF statements in an salesforce email template

Hi all SF guys,
Yes this is possible to have conditional IF statements in an email template.

Today I faced some issues when I was using IF statements in "HTML Email Template".

So, I found that some time its not works when you are using "HTML Email Template"  because of metadata issue.

Issue:
If you are using IF statements in HTML email template, some time its metadat in backend add some formating html and css inside of IF statements, Thats why its not working.

Solution:
Edit the email template matadata and remove all html and css which is inside your IF statement:

Note: Please use eclipse IDE or sublime text to edit email template.

Ex:
IF statements in an email template not works when email template metadata like as:
<div style="color: rgb(0, 0, 0); font-family: arial; font-size: 12pt;">
{!IF(Lead.vpUID__c&nbsp;=&nbsp;""<span style="font-size: 12pt;">,&nbsp;</span>"<span style="font-size: 12pt;">No"</span><span style="font-size: 12pt;">,&nbsp;</span></div><div style="color: rgb(0, 0, 0); font-family: arial; font-size: 12pt;"><span style="font-size: 12pt;">"Yes</span><span style="font-size: 12pt;">"</span><span style="font-size: 12pt;">)}</span></div>

To make it worable please remove all strange html inside from IF statement like as:
<div style="color: rgb(0, 0, 0); font-family: arial; font-size: 12pt;">
{!IF(Lead.vpUID__c = "", "No", "Yes)}
</div>

After removing all these strange and useless html, Save it.
Now this will work for you :)