Salesforce Custom button with Javascript & jQuery model dialogue window for sending email to customers

jQuery Code Snippet :

{!REQUIRESCRIPT('//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js')}
{!REQUIRESCRIPT('//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js')}
{!REQUIRESCRIPT('/soap/ajax/15.0/connection.js')}
{!REQUIRESCRIPT('/soap/ajax/15.0/apex.js')}
var emailFinalText;
var descriptionFinalText;
try{
  jQuery(function(){
    /*Append the jQuery CSS CDN Link to the Head tag.*/
    jQuery('head').append('<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/themes/start/jquery-ui.css" type="text/css" />');  
    /*Create the HTML(DIV Tag) for the Dialog.*/
    var html = '<form id="dialog" title="Send Email">'
+'<table style="width:100%">'
+'<tr><th>Email</th></tr><tr><td><input style="width: -webkit-fill-available !important;" id="email" type="email" name="email"></td></tr>'
+'<tr><th>Message</th></tr><tr><td><textarea style="width: -webkit-fill-available;" id="messageDescription" name="comment" rows="13" cols="45"></textarea></td></tr>'
+'</table>'
+'</form>';  
    /*Check if the Dialog(DIV Tag) already exists if not then Append the same to the Body tag.*/
    if(!jQuery('[id=dialog]').size()){
      jQuery('body').append(html);
    }
    /*Open the jQuery Dialog.*/
    jQuery( "#dialog" ).dialog({
   bgiframe: true,
autoOpen: true,
resizable: false,
maxWidth:500,
maxHeight:400,
width: 500,
height: 400,
modal: true,
      show:{
        duration: 1000
      },
      hide:{
        duration: 1000
      },
      /*Adding value to display*/
      open: function( event, ui ){
      var emailId = "{!Lead.Email}";
      var leadDesc ="{!Lead.FirstName}";
      emailFinalText = document.getElementById("email").value = emailId;
      descriptionFinalText = document.getElementById("messageDescription").value = "Hello "+leadDesc+"\n\nPlease confirm if you are interested in buying the product ?\n\nRegards,\n{!$User.FirstName}";
      },
      buttons:{
        "Send": function(){        
           /*alert("call Apex method.");*/
                var contextUser = sforce.apex.execute("sendEmailToUser_Cls", "sendEmail", {emailFinalTextApex:$('#email').val(),descriptionFinalTextApex:$('#messageDescription').val()});
                alert(contextUser);
                jQuery( this ).dialog( "close" );
        },
        Cancel: function(){
          jQuery( this ).dialog( "close" );
        }
      }
    });
  });
}catch(e){
    alert('An Error has Occured. Error: ' + e);
}

Apex Soap code snippet:

global class sendEmailToUser_Cls{
   webService static String sendEmail(String emailFinalTextApex,string descriptionFinalTextApex) {
       List<Messaging.SingleEmailMessage> mails =  new List<Messaging.SingleEmailMessage>();
       if(String.isNotBlank(emailFinalTextApex) && String.isNotBlank(descriptionFinalTextApex)){
           Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
           List<String> sendTo = new List<String>();
           sendTo.add(emailFinalTextApex);
           mail.setToAddresses(sendTo);
           mail.setSenderDisplayName('Official Bank of Nigeria');
           mail.setReplyTo('fgangana@cisco.com');
           mail.setHtmlBody(descriptionFinalTextApex);
           mails.add(mail);
           Messaging.sendEmail(mails);
           return 'Success: Mail has been sent';
       }else{
           return 'Error:Please fillout Email and Description fields';
       }
   }
}

Sample Screenshot:




Matching rules with apex salesforce

De-Dupe - 
                 Before going to implement dedupe logic using batch apex or regular apex, make sure we need to create matching rules with certain criteria and duplicate rules for same.

Example Here you go -

               Now implemet the actual logic from trigger or apex class based on your requirement. I am going to test the same stuf using developer console on lead object.

Apex Code & Trigger Snippet -

trigger Dedupe_Trg on Lead (after insert) {
   
    public static List<lead> leadIds = new List<lead>();
    public static String query;  
    if(Trigger.isAfter && Trigger.isInsert){
        for(Lead l : trigger.newMap.Values()){
            if(l.status=='Pre-Prospect' && l.dedupe__c=='dedupe'){
                leadIds.add(l);
        }
    }          
    if(!leadIds.isEmpty()){
       String ids = getLeadIdsString(leadIds);
       if(String.isNotBlank(ids)){
           query = 'select id';
           for(Schema.FieldSetMember fld :SObjectType.Lead.FieldSets.DedupeFiedSet.getFields()) {
                query+= ', ' + fld.getFieldPath();
            }
            query+= ' from lead WHERE ID in ('+ ids +')';
       }
    }  
    if(String.isNotBlank(query)){
        Database.executeBatch(new Lead_Deduper(query));
    }
   }
   public static String getLeadIdsString(List<Lead> input){
        String result = '';      
        for (Lead l: input){          
            result = result + '\'' + l.Id + '\',';
            system.debug('result first------'+result);
        }
        result = result.substring(0, result.length()-1);
        system.debug('result Second------'+result);
        return result;
    }    
}
----------------------------------------

global class Lead_Deduper implements Database.Batchable < sObject > {
    //@Class level variable declaration here
    global String query;
    global List<sObject> tempMatchRecordId;
   
    //@Method: Constructor for getting query string from trigger
    global Lead_Deduper(String query){
        this.query = query;
    }
    //@Method: Start method for fetching records from query
    global Database.QueryLocator start(Database.BatchableContext info) {
        return Database.getQueryLocator(query);
    }
    //@Method: Execute will do actual operations
    global void execute(Database.BatchableContext info, List <Lead> scope) {
        for(Lead l : scope){
            If(l.status=='Pre-Prospect'){
                l.status='New Prospect';
                l.Dedupe__c= Null;
                l.Dedupe_Processing__c = True;
            }
        }
       
        scopeIdentifier(scope);
    }
    //@Method: This is responsible for gettting both existing and latest lead ids
    global static Lead getLatestExistingLead(Datacloud.MatchRecord[] matchRecords){
        Lead existingLeadId;
        for (Datacloud.MatchRecord matchRecord : matchRecords) {
            existingLeadId = (Lead)matchRecord.getRecord();
        }
        system.debug('exsting lead id ----->>>'+existingLeadId);
        return existingLeadId;
    }
    //@Method: Finish logic for sending emails
    global void finish(Database.BatchableContext info){
        system.debug('Finally i am success...');
    }
    //@Method: This method will identify the duplicate records based on new record using datacloud namespace classes and matching rules defined in the system
    global static void scopeIdentifier(List<Lead> scope){
        // Optionally, set DML options here, use “DML” instead of “false”
        //   in the insert()
        // Database.DMLOptions dml = new Database.DMLOptions();
        // dml.DuplicateRuleHeader.allowSave = true;
        // dml.DuplicateRuleHeader.runAsCurrentUser = true;
        Database.SaveResult[] saveResult  = Database.Update(scope,false);
        Map <Id,Id> duplicateLeadIds = new Map <ID,ID> ();
        Integer i=0;
        for (Database.SaveResult sr: saveResult){
        if (sr.isSuccess()){
            scope.remove(i);
        }else{
            for (Database.Error error: sr.getErrors()){
                // If there are duplicates, an error occurs
                // Process only duplicates and not other errors
                // (e.g., validation errors)
                if (error instanceof Database.DuplicateError){
                    // Handle the duplicate error by first casting it as a
                    // DuplicateError class
                    // This lets you use methods of that class
                    // (e.g., getDuplicateResult())
                    Database.DuplicateError duplicateError = (Database.DuplicateError) error;
                    Datacloud.DuplicateResult duplicateResult = duplicateError.getDuplicateResult();
                    // Return only match results of matching rules that
                    // find duplicate records
                    Datacloud.MatchResult[] matchResults = duplicateResult.getMatchResults();
                    // Just grab first match result (which contains the
                    // duplicate record found and other match info)
                    Datacloud.MatchResult matchResult = matchResults[0];
                    Datacloud.MatchRecord[] matchRecords = matchResult.getMatchRecords();
                    Lead existingLead = getLatestExistingLead(matchRecords);
                    duplicateLeadIds.put(scope.get(i).Id,existingLead.Id);
                }else {
                }
            }
            i++;
            }
        }
        List<Suppressed_Lead__c > suppressList = new List<Suppressed_Lead__c>();
        // Add matched record to the duplicate records variable
        for(Lead led : scope){
            led.status = 'Inactive';
            led.Dedupe_Processing__c = false;
            led.Active_Lead_Id_Reason__c = 'https://mysalesproductforce-dev-ed.my.salesforce.com/'+duplicateLeadIds.get(led.id);
            led.Supperession_Reason__c = 'Duplicate lead has been found with same email or customer name';
            Suppressed_Lead__c sup = new Suppressed_Lead__c(Active_Lead__c=led.id,Suppressed_Lead__c=duplicateLeadIds.get(led.id),Description__c=led.description);          
            suppressList.add(sup);
        }
        Database.update(scope,false);
        Map<string,string> queueDetailsUpdate = getQueueDetails(scope);
        for(lead l : scope){
            l.ownerId = queueDetailsUpdate.get(l.country__c);
        }
        Database.update(scope,false);
        if(!suppressList.isEmpty()){
            Database.insert(suppressList,false);
        }
        //List<Lead> leads = [select id,firstname,leadsource,Active_Lead_Id_Reason__c,annualrevenue ,Supperession_Reason__c,lastname,email,description,company,Dedupe__c,Dedupe_Processing__c,status from lead WHERE ID IN : scope];
        String queryString = 'select id';
        //Getting fields from fieldset from lead object
        for(Schema.FieldSetMember fld :SObjectType.Lead.FieldSets.DedupeFiedSet.getFields()) {
            queryString+= ', ' + fld.getFieldPath();
        }
        queryString+= ' from lead WHERE  ID IN : scope ';
       
        //@Response : Creating new response record based on lead information        
        List<Response__c> resp = createResponse(Database.query(queryString));
        system.debug(resp);
        if(resp!=Null && !resp.isEmpty()){
            insert resp;
            system.debug(resp[0].id);
        }      
    }
    //@Method: Create one dummy response using lead details and tagged under the same lead id
    global static List<Response__c> createResponse(List<Lead> scope){
        List<Response__c> response = new List<Response__c>();
        for(Lead l : scope){
            Response__c r = new Response__c();
                r.name = system.now()+'-'+l.firstname+' '+l.lastname;
                r.Is_Suppressed__c = true;
                r.Lead__c = l.id;
                r.Revenue__c = l.annualrevenue;
                r.Description__c = l.Description;
                r.Source__c = l.leadsource;
            response.add(r);
            system.debug(response);
        }
        return response;
    }
    //@Method: This method is reposible for getting Queue name based on country name from lead record
    global static Map<String,string> getQueueDetails(List<Lead> scope){
        Set<String> queueName = new Set<String>();
        Map<String,string> queueMap = new Map<String,string>();
        for(Lead sc : scope){
            if(sc.country__c != Null){
                queueName.add(sc.Country__c);
            }          
        }
        for(QueueSobject q : [Select Id, QueueId, Queue.Name, SobjectType from QueueSobject where queue.name=:queueName]){
            queueMap.put(q.queue.name,q.queueid);
        }
        return queueMap;
    }  
}

xml package for all the components in salesforce

XML package:
------------------

<?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>AppMenu</name>
    </types>
    <types>
        <members>*</members>
        <name>ApprovalProcess</name>
    </types>
    <types>
        <members>Case.Standard</members>
        <members>Lead.Standard</members>
        <name>AssignmentRule</name>
    </types>
    <types>
        <members>*</members>
        <name>AuthProvider</name>
    </types>
    <types>
        <members>*</members>
        <name>CallCenter</name>
    </types>
    <types>
        <members>*</members>
        <name>Community</name>
    </types>
    <types>
        <members>*</members>
        <name>ConnectedApp</name>
    </types>
    <types>
        <members>*</members>
        <name>CustomApplication</name>
    </types>
    <types>
        <members>*</members>
        <name>CustomApplicationComponent</name>
    </types>
    <types>
        <members>*</members>
        <name>CustomLabels</name>
    </types>
    <types>
        <members>*</members>
        <name>CustomMetadata</name>
    </types>
    <types>
        <members>*</members>
        <members>Account</members>
        <members>AccountCleanInfo</members>
        <members>AccountContactRole</members>
        <members>Activity</members>
        <members>Asset</members>
        <members>AssetRelationship</members>
        <members>AssistantProgress</members>
        <members>Campaign</members>
        <members>CampaignMember</members>
        <members>Case</members>
        <members>CaseContactRole</members>
        <members>Contact</members>
        <members>ContactCleanInfo</members>
        <members>ContentVersion</members>
        <members>Contract</members>
        <members>ContractContactRole</members>
        <members>DandBCompany</members>
        <members>DuplicateRecordItem</members>
        <members>DuplicateRecordSet</members>
        <members>EmailMessage</members>
        <members>Event</members>
        <members>ExchangeUserMapping</members>
        <members>FeedItem</members>
        <members>ForecastingCategoryMapping</members>
        <members>Idea</members>
        <members>Lead</members>
        <members>LeadCleanInfo</members>
        <members>Macro</members>
        <members>MacroAction</members>
        <members>MacroInstruction</members>
        <members>Opportunity</members>
        <members>OpportunityCompetitor</members>
        <members>OpportunityContactRole</members>
        <members>OpportunityLineItem</members>
        <members>Order</members>
        <members>OrderItem</members>
        <members>PartnerRole</members>
        <members>Pricebook2</members>
        <members>PricebookEntry</members>
        <members>Product2</members>
        <members>Site</members>
        <members>SocialPersona</members>
        <members>Solution</members>
        <members>StreamingChannel</members>
        <members>Task</members>
        <members>User</members>
        <members>UserProvisioningRequest</members>
        <name>CustomObject</name>
    </types>
    <types>
        <members>*</members>
        <name>CustomObjectTranslation</name>
    </types>
    <types>
        <members>*</members>
        <name>CustomPageWebLink</name>
    </types>
    <types>
        <members>*</members>
        <name>CustomPermission</name>
    </types>
    <types>
        <members>*</members>
        <name>CustomSite</name>
    </types>
    <types>
        <members>*</members>
        <name>CustomTab</name>
    </types>
    <types>
        <members>*</members>
        <name>DataCategoryGroup</name>
    </types>
    <types>
        <members>unfiled$public</members>
        <members>unfiled$public/MarketingProductInquiryResponse</members>
        <members>unfiled$public/SUPPORTSelfServiceNewCommentNotificationSAMPLE</members>
        <members>unfiled$public/SUPPORTSelfServiceNewUserLoginInformationSAMPLE</members>
        <members>unfiled$public/SUPPORTSelfServiceResetPasswordSAMPLE</members>
        <members>unfiled$public/SalesNewCustomerEmail</members>
        <members>unfiled$public/SupportCaseAssignmentNotification</members>
        <members>unfiled$public/SupportCaseCreatedPhoneInquiries</members>
        <members>unfiled$public/SupportCaseCreatedWebInquiries</members>
        <members>unfiled$public/SupportCaseResponse</members>
        <members>unfiled$public/SupportEscalatedCaseNotification</members>
        <members>unfiled$public/SupportEscalatedCaseReassignment</members>
        <members>unfiled$public/SupportSelfServiceNewLoginandPassword</members>
        <members>unfiled$public/SupportSelfServiceResetPassword</members>
        <name>EmailTemplate</name>
    </types>
    <types>
        <members>Case.Standard</members>
        <name>EscalationRule</name>
    </types>
    <types>
        <members>*</members>
        <name>FlexiPage</name>
    </types>
    <types>
        <members>*</members>
        <name>Flow</name>
    </types>
    <types>
        <members>*</members>
        <name>Group</name>
    </types>
    <types>
        <members>*</members>
        <name>HomePageComponent</name>
    </types>
    <types>
        <members>*</members>
        <name>HomePageLayout</name>
    </types>
    <types>
        <members>*</members>
        <name>Layout</name>
    </types>
    <types>
        <members>*</members>
        <name>Letterhead</name>
    </types>
    <types>
        <members>*</members>
        <name>PermissionSet</name>
    </types>
    <types>
        <members>*</members>
        <name>PostTemplate</name>
    </types>
    <types>
        <members>*</members>
        <name>Profile</name>
    </types>
    <types>
        <members>*</members>
        <name>Queue</name>
    </types>
    <types>
        <members>*</members>
        <name>QuickAction</name>
    </types>
    <types>
        <members>ApexDevNet</members>
        <name>RemoteSiteSetting</name>
    </types>
    <types>
        <members>unfiled$public</members>
        <name>Report</name>
    </types>
    <types>
        <members>*</members>
        <name>ReportType</name>
    </types>
    <types>
        <members>*</members>
        <name>Role</name>
    </types>
    <types>
        <members>*</members>
        <name>SamlSsoConfig</name>
    </types>
    <types>
        <members>*</members>
        <name>Scontrol</name>
    </types>
    <types>
        <members>*</members>
        <name>SharingSet</name>
    </types>
    <types>
        <members>*</members>
        <name>SiteDotCom</name>
    </types>
    <types>
        <members>*</members>
        <name>StaticResource</name>
    </types>
    <types>
        <members>*</members>
        <name>Workflow</name>
    </types>
    <types>
        <members>*</members>
        <name>Settings</name>
    </types>
    <version>36.0</version>
</Package>

Saleforce Difficult scenarios

difficult scenarios salesforce :

1) Faced one scenario like i have one trigger on campaign object that will help to update campaign fieds first and then based on campaign fields update it will also update leads fields.
   Because there is a look up relation between campaign and leads. But for every campaign there are more than 1 lack leads assigned which is hit two governer limits.
                a) 10000 DML rows exception.
                b) Apex CPU time limit exception.
                As a work around have implemented one batch apex logic from trigger that will update 50 Million lead records whenever campaign fields update/insert.
                This implementation would avoid both 10000 DML & CPU time limit exceed exceptions.

2) Face one more scenario like all mangers would get email notification every day whenever the approval records didn't approved by manger and submitted date more than 10 days in pending status.
   As a work around have implemented apex logic that would get query all the criteria met records from process Instance object and store all the records in temporary table.
   Created one workflow email alert on same custom object that would get fire email to Mangers.

3) I have done purging activities which would purge Billions/Millions records based on created date and take a .csv back up on daily basis without manual work.
   As a work around I have implemented new batch apex that would get delete all the criteria meets and same records we are storing in document object as a .csv file.
   Storing all the fields speared by comma.

4) Faced one scenario like--I have many Question & Answer records created in Question_Answer__c Custom Object and all Q&A's same for four theaters(AMER,EMEAR,APJ,GC).
   I have created one dynamic page which will help to display all the records in single visual force page as a input components based on theater.

5) Approval process scenario-  Parent & Child relationship between Lead, Notes&Attachement object whenever lead having at least one valid attachment then only it would eligible for approval.
   As a work around created one trigger on notes&attachement object which will update/insert/increase parent temp field and we have too many approval queues based on criteria it will go for correct approval queue.

6) We have one scenario where if any user leave the company the same user would get inactive and we have some assignment rules been defined for each and every user that needs to be deleted.
   I have implemented one trigger scenario where it will do as soon as user inacitve from user object trigger witll fire and it will get deleted assignment rules objects reords but i am getting "Mixed DML" operation here.
   Becuase i am doing operation between setup objects and non setup objects. After that i decided to ran the code snippet using @future method and issue been resolved.

7) I have created one visulforce page where it will display all the lead history records and lead records in single visualforce page. There were many records and too many query filters i used and displaying the same result in visualforce page.
   But i started getting "max view state (135KB) reached".
   As a work around i removed some filds which all are not using in visualforce page and put transient keyword for all getters and setters.
   removed large getters and converted into normal list format and used try catch finally exception blcoks at final block i clearead the list of results.


   

Custom Rollup summaries using trigger salesforce


Trigger Code :
--------------
trigger RollupSummaries_Trg on Contact (after insert,after update,after delete,after undelete) {
    //RollupSummaries_Helper.cmdRollupCalculation(trigger.newMap.Values(),trigger.isInsert,trigger.isUpdate,trigger.isAfter);
    RollupSummaries_Helper.cmdRollupCalculation(trigger.new,trigger.isInsert,trigger.isUpdate,trigger.isAfter,trigger.isDelete,trigger.isUndelete,trigger.old);
}

Helper Class :
--------------
public class RollupSummaries_Helper {
    public static Map<Id,contact> uniqueMap = new Map<Id,contact>();
    public static List<Account> finalAcc = new List<Account>();
    public static Set<Contact> conSet = new Set<Contact>();
    public static Decimal sumCount;
    public static Decimal sumMax;
    public static Decimal sumMin;
    public static Decimal sumAvg;
    public static decimal sumCountList;
    public RollupSummaries_Helper(){
    }
    public static void cmdRollupHelper(List<Contact> triggerNew){
            for(contact con : triggerNew){
              uniqueMap.put(con.AccountId,con);
          }
            for(account a : [select id,(select id from contacts) from account where id IN : uniqueMap.keySet()]){
                conSet.addAll(a.contacts);
          }
        
            List<AggregateResult> groupedResults = [select count(id) totalCount,sum(Amount__c) totalSum,Max(amount__c) totalMax,min(amount__c) totalMin,avg(amount__c) totalAvg from contact where ID IN :conSet];
            for(AggregateResult ar : groupedResults ){
                sumCount = (Decimal)ar.get('totalSum');
                sumMax = (Decimal)ar.get('totalMax');
                sumMin = (Decimal)ar.get('totalMin');
                sumAvg =  (Decimal)ar.get('totalAvg');
                sumCountList = (Decimal)ar.get('totalCount');
            }
             for(account a : [select id,Sum_Of_Contacs__c from account where id IN : uniqueMap.keySet()]){
                 a.Rollup_Sum__c = sumCount;
                 a.Sum_Of_Contacs__c =sumCount;
                 a.Rollup_Max__c = sumMax;
                 a.Rollup_Min__c = sumMin;
                 a.Rollup_Avg__c = sumAvg;
                 a.Rollup_Count__c = sumCountList;
                 
                 finalAcc.add(a);
             }
        if(!finalAcc.isEmpty()){            
            database.update(finalAcc,false);
        }
    }
    public static Set<Id> acctIds = new Set<Id>();
    public static void cmdRollupCount(List<Contact> triggerNew,List<Contact> triggerOld){
        for(Contact c : triggerNew){
      acctIds.add(c.AccountId);            
        }
        Map<Id,Account> acctMapIds = new Map<Id,Account>([select id,Rollup_Count__c,(select id from contacts) from account where id IN :acctIds]);
        for(Account a : acctMapIds.values()){
            a.Rollup_Count__c = a.contacts.size();
        }
        if(!acctMapIds.isEmpty()){
            Database.update(acctMapIds.values(),false);
        }
    }
    public static void cmdRollupCountDelete(List<Contact> triggerNew,List<Contact> triggerOld){
        for(Contact c : triggerOld){
      acctIds.add(c.AccountId);            
        }
        Map<Id,Account> acctMapIds = new Map<Id,Account>([select id,Rollup_Count__c,(select id from contacts) from account where id IN :acctIds]);
        for(Account a : acctMapIds.values()){
            a.Rollup_Count__c = a.contacts.size();
        }
        if(!acctMapIds.isEmpty()){
            Database.update(acctMapIds.values(),false);
        }
    }
    public static void cmdRollupCalculation(List<Contact> triggerNew,boolean isInsert,boolean isUpdate,boolean isAfter,boolean isDelete,boolean isUndelete,List<Contact> triggerOld){        
        if(isAfter){
            if(isInsert){
                cmdRollupHelper(triggerNew);
                //cmdRollupCount(triggerNew,triggerOld);
            }else if(isUpdate){
                cmdRollupHelper(triggerNew);
            }else if(isUndelete){
                cmdRollupHelper(triggerNew);
            }else if(isDelete){
                cmdRollupCountDelete(triggerNew,triggerOld);
            }
        }
    }
}

Salesforce Rest Api getting access token and CRUD operation in java

Connected App :
Create connected app in SFDC side and put call back url as : https://localhost:8443/_callback

CliendId and Secret :
Client_Id and Client_Secret would be generated by system automatically

Get Access Token :
Get the access token from salesforce.

Jar Files :
commons-codec-1.7.jar
commons-httpclient-3.1.jar
java-json.jar
org-apache-commons-logging.jar
org.json.jar
gson-2.2.2.jar
jackson-mapper-asl-1.2.0.jar
jackson-all-1.9.0.jar
httpcore-4.2.3.jar

Complete Java Class :

import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import javax.swing.text.html.HTMLDocument.Iterator;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.DeleteMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;

public class AccountQuery{
    private static final String clientId = "3MVG9Y6d_Btp4xp5fHfBCvTWgHlfBKxrEf0lFIt9p71zfTmei0q9P8QxoaRowTIefchOoNdY8syyWOriUKYlV";
    private static final String clientSecret = "7975635620731036814";
    // THis is meaningless in our context
    private static final String redirectUri = "https://localhost:8443/_callback";
    private static final String environment = "https://ap1.salesforce.com";  
    private static String tokenUrl = null;
   
    public static final String username = "Your userName";
public static final String password = "Your Password";

    private static String accessToken = null;
    private static String instanceUrl = null;
    public void accessTokenSFDC(){
    System.out.println("------------------------Getting a token--------------------------");      
        tokenUrl = environment + "/services/oauth2/token";
        HttpClient httpclient = new HttpClient();
        PostMethod post = new PostMethod(tokenUrl);    
        post.addParameter("grant_type", "password");
        post.addParameter("client_id", clientId);
        post.addParameter("client_secret", clientSecret);
        post.addParameter("redirect_uri", redirectUri);
        post.addParameter("username", username);
        post.addParameter("password", password);
        try {
            httpclient.executeMethod(post);
            try {
                JSONObject authResponse = new JSONObject(new JSONTokener(new InputStreamReader(post.getResponseBodyAsStream())));
                System.out.println("Auth response: " + authResponse.toString(2));
                accessToken = authResponse.getString("access_token");
                instanceUrl = authResponse.getString("instance_url");
                System.out.println("Got access token: " + accessToken);
                System.out.println("-------------------Request has been done--------------------------\n\n");
               
            } catch (JSONException e) {
                e.printStackTrace();              
            }
        } catch (HttpException e1) {
            e1.printStackTrace();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
    }
   
    public static void main( String[] args ) throws Exception{  
    new AccountQuery().accessTokenSFDC();//getting access token from this method
        //new AccountQuery().CreateAccount(instanceUrl,accessToken);//responsible for create account and contact records.      
        //new AccountQuery().queryAccountObject(instanceUrl, accessToken);//responsible for query account records.
        //new AccountQuery().patch(instanceUrl, accessToken);//responsible for updating records
    //new AccountQuery().showAccountId(instanceUrl, accessToken);//responsible for query account records.
    //new AccountQuery().deleteRecords(instanceUrl, accessToken);//responsible for query account records.    
    new AccountQuery().patchRecord(instanceUrl, accessToken);
    }
    public String CreateAccount(String instanceUrl, String accessToken) throws Exception{
    System.out.println("---------------------Creating Account Record in SFDC------------------------");
    HttpClient httpclient = new HttpClient();
    JSONObject account = new JSONObject();    
        Scanner scanner = new Scanner(System.in);
        System.out.print("Enter Account  name: ");
        String name = scanner.next();
        System.out.print("Enter AccountNumber  Number : ");
        String accountNumber = scanner.next();
        System.out.print("Enter AnnualRevenue  : ");
        String annualRevenue = scanner.next();
        System.out.print("Enter Description  : ");
        String description = scanner.next();
        System.out.print("Enter Industry  : ");
        String industry = scanner.next();
        System.out.print("Enter Phone : ");
        String phone = scanner.next();
        System.out.print("Enter Active (Yes/No) : ");
        String isActive = scanner.next();
        System.out.print("Enter Customer Priority : ");
        String customerPriority = scanner.next();
        System.out.print("Enter Number of Locations : ");
        String numberofLocations = scanner.next();
        System.out.print("Enter SLA (GOLD/Silver) : ");
        String slaValue = scanner.next();
       
    try{
    account.put("Name",name);
    account.put("AccountNumber",accountNumber);
    account.put("AnnualRevenue",annualRevenue);
    account.put("Description",description);
    account.put("Industry",industry);
    account.put("Phone",phone);
    account.put("Active__c",isActive);
    account.put("CustomerPriority__c",customerPriority);
    account.put("NumberofLocations__c",numberofLocations);
    account.put("SLA__c",slaValue);
   
    PostMethod post = new PostMethod(instanceUrl+"/services/data/v20.0/sobjects/Account");
    post.setRequestHeader("Authorization", "OAuth " + accessToken);
    post.setRequestEntity(new StringRequestEntity(account.toString(),"application/json","UTF-8"));    
    httpclient.executeMethod(post);
    System.out.println("Get HTTP status :"+post.getStatusCode());
    if(post.getStatusCode()==201){
    try{
    JSONObject response = new JSONObject(new JSONTokener(new InputStreamReader(post.getResponseBodyAsStream())));
    System.out.println("Create Response : "+response.toString(2));
    if(response.getBoolean("success")){
    String accountid= response.getString("id");
    System.out.println("New Record has been created withe ID : "+accountid);    
    createContactRecords(accountid,instanceUrl,accessToken);
    }
    }catch (Exception e1) {
               e1.printStackTrace();
           }
    }
    }catch (Exception e1) {
            e1.printStackTrace();
        }
    System.out.println("-----------------------Records has been create successfully-------------------------\n\n");
return null;
    }
    public String  createContactRecords(String accountid,String instanceUrl, String accessToken) throws Exception{
    HttpClient httpclientContact = new HttpClient();
   
JSONObject contact = new JSONObject();
contact.put("LastName", "SFDC-Fazu");
contact.put("AccountId",accountid);

PostMethod postContact = new PostMethod(instanceUrl+"/services/data/v20.0/sobjects/Contact");
postContact.setRequestHeader("Authorization", "OAuth " + accessToken);
postContact.setRequestEntity(new StringRequestEntity(contact.toString(),"application/json","UTF-8"));
try{
httpclientContact.executeMethod(postContact);
System.out.println("Get HTTP status :"+postContact.getStatusCode());
JSONObject responseContact = new JSONObject(new JSONTokener(new InputStreamReader(postContact.getResponseBodyAsStream())));
System.out.println("Create Response : "+responseContact.toString(2));
}catch (Exception e1) {
           e1.printStackTrace();
       }
    return null;
    }
    public void queryAccountObject(String instanceUrl, String accessToken)throws Exception{
    HttpClient  httpClient= new HttpClient();
    GetMethod get = new GetMethod(instanceUrl+"/services/data/v20.0/query");
    get.setRequestHeader("Authorization", "OAuth " + accessToken);
    NameValuePair[] params = new NameValuePair[1];
    params[0]=new NameValuePair("q","select id,name from account");
    get.setQueryString(params);
    try{
    httpClient.executeMethod(get);
    if(get.getStatusCode()==HttpStatus.SC_OK){
    try{
    JSONObject response = new JSONObject(new JSONTokener(new InputStreamReader(get.getResponseBodyAsStream())));
    System.out.println("Query Response :"+response.toString(2) );
    System.out.println(response.get("totalSize")+"record(s) returned \n\n");
    JSONArray results = response.getJSONArray("records");
    for(int i = 0;i < results.length();i++){
    System.out.println(results.getJSONObject(i).getString("Id")+"-----"+results.getJSONObject(i).getString("Name")+"\n" );
    }
    System.out.println("\n");
   
    }catch (Exception e1) {
               e1.printStackTrace();
           }
    }
    }catch (Exception e1) {
            e1.printStackTrace();
        }
    }
    public void showAccountId(String instanceUrl, String accessToken)throws Exception{
    HttpClient  httpClient= new HttpClient();
    GetMethod get = new GetMethod(instanceUrl+"/services/data/v20.0/sobjects/Account/0019000001qmYdAAAU");
    get.setRequestHeader("Authorization", "OAuth " + accessToken);
    try{
    httpClient.executeMethod(get);
    if(get.getStatusCode()==HttpStatus.SC_OK){
    try{
    JSONObject response = new JSONObject(new JSONTokener(new InputStreamReader(get.getResponseBodyAsStream())));
    System.out.println("Query Response :"+response.toString(2) );
    java.util.Iterator iterator = response.keys();
    while(iterator.hasNext() ){
    String key = (String)iterator.next();
    String value = (String)iterator.next();
    System.out.println(key + ":"+(value !=null ? value : "")+"\n");
    }
    }catch (Exception e1) {
               e1.printStackTrace();
           }
    }
    }catch (Exception e1) {
            e1.printStackTrace();
        }
    }
    public void deleteRecords(String instanceUrl, String accessToken)throws Exception{
    Scanner scanner = new Scanner(System.in);
        System.out.print("Enter Account  ID : ");
        String accountId = scanner.next();
    HttpClient  httpClient= new HttpClient();
    DeleteMethod deleteMethod = new DeleteMethod(instanceUrl+"/services/data/v20.0/sobjects/Account/"+accountId);
    deleteMethod.setRequestHeader("Authorization", "OAuth " + accessToken);
    try{
    httpClient.executeMethod(deleteMethod);
    System.out.println("Http Status"+deleteMethod.getStatusCode()+"Deleting account \n\n");
   
    }catch (Exception e1) {
            e1.printStackTrace();
        }
    }
    public static void patchRecord(String instanceUrl, String accessToken) throws Exception{
    Scanner scanner = new Scanner(System.in);
        System.out.print("Enter Account  ID : ");
        String accountId = scanner.next();
    HttpClient httpClient = new HttpClient();
    JSONObject update = new JSONObject();
    try{
    update.put("name", "SFDC-Fazu patch test");
    }catch (Exception e1) {
            e1.printStackTrace();
        }
    PostMethod post = new PostMethod(instanceUrl+"/services/data/v20.0/sobjects/Account/"+accountId) {
    @Override public String getName() { return "PATCH"; }
    };
    post.setRequestHeader("Authorization", "OAuth " + accessToken);
    post.setRequestEntity(new StringRequestEntity(update.toString(),"application/json","UTF-8"));
    try{
    httpClient.executeMethod(post);
    System.out.println("Http Status"+post.getStatusCode()+"  updated successfully \n\n");

    }catch (Exception e1) {
            e1.printStackTrace();
        }
    }
}



ANT Migration Tool Salesforce Step by Step Procedure

  • Extract the downloaded zip file somewhere like C:\Users\fgangana\Desktop\apache-ant-1.10.1
  • Set the path in system variables -
  • ANT_HOME - C:\Users\fgangana\Desktop\apache-ant-1.10.1\bin
  • If PATH system variable already exists then add %ANT_HOME% to your path variable, else add new PATH variable and keep this value.
  • Path-%ANT_HOME%\bin;%JAVA_HOME%\bin;C:\app\fgangana\product\11.1.0\client_1\bin;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\;%systemroot%\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\QuickTime\QTSystem\;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Program Files (x86)\Sennheiser\SoftphoneSDK\
  • Also create a JAVA_HOME environment variable and set the value to the location of your JDK.
  • JAVA_HOME-C:\Program Files\Java\jdk1.7.0\bin
  • Go to command prompt and type ant -version. If it shows that ‘Apache Ant Version compiled’ then that means we are good to go.
  • still we need to dowload one more salesforce jar file-
  • extact and save it to somewhere like C:\Users\fgangana\Downloads\salesforce_ant_37.0\sample
  • open command prompt and navigate to salesforce ant file like- C:\salesforce_ant_37.0\sample> ant commands
  • Go to build.properties in salesforce_ant_37.0 and open in note pad ++ and enter salesforce credentials(password=password+securitytoken).After that dont change anything
  • Open "build.xml" and you could see many commands like -deployUnpackaged,deployCode,retrieveCode,undeployCode,deployCodeCheckOnly,quickDeploy,cancelDeploy etc.
  • For ex: if you want to retrieve components from source system run the below query ---
  • C:\salesforce_ant_37.0\sample> ant retrieveCode and hit "enter".
  • Uder "codepkg" folder need add or updatecomponents in  Package.xml.


For reference : https://www.youtube.com/watch?v=IrJ9gPQ1bbk

Package.xml could be -

<?xml version="1.0" encoding="UTF-8"?>
<Package x
        <members>*</members>
        <name>ApexClass</name>
    </types>
    <types>
        <members>*</members>
        <name>ApexPage</name>
    </types>
    <types>
        <members>*</members>
        <name>CustomObject</name>
    </types>
    <types>
        <members>*</members>
        <name>EmailTemplate</name>
    </types>
    <types>
        <members>*</members>
        <name>LiveChatAgentConfig</name>
    </types>
    <version>31.0</version>
</Package>


Featured

What is Cryptography in salesforce and what are all the algorithms provided by them ?

A). It is a security protocal between two systems. Lets say we are integration two systems without any encrytion mechanism then hackers wil...

Popular