Wednesday, 6 September 2017

Salesforce to Salesforce | S2S | How to Setup Salesforce to Salesforce



STEP 1) Enabling Salesforce to Salesforce

Enable the Salesforce to Salesforce in both the org. Follow below step to do that
Setup--> Salesforce to Salesforce --> Salesforce to Salesforce Setting.


 Then click on Edit button checked the Enable checkbox.


NOTE:- you should have "Manage Connections" access on profile level.

Step 2) Connection Setup

To setup connection you need to open "Connection" Tab. Then Click on New Tab.

Then Select Account and Contact then click on "Save & Send Invite". You also need to set Owner. Owner will get notification if any error will come.


When you will click on "Save & Send Invite" button Contact (Amit Chaudhary) will get a email like below

Then copy above URL and login by other org user.


Then other org user need to accept the invitation.

Now Connection is established but no object is shared.

Step 3) Publishing Objects

Now we need to publish or subscribe the standard or custom object. To publish the object you need to go to first Org and click on "Publish/Unpublish" button.

Then select the object and click on save.



You can select the field from Publish Object related list. Select the object and click on Object name.


Step 4) Subscribing Objects

Now got back to receiving org and click on "Subscribed Objects" related list.


 Then map the object.


Now we need to map the field. Go to "Subscribed Object" related list and select object and map field.



Now connection is setup.




Step 5) Using the Shared Connection

To share the record we have two way one is Manual and 2nd is by programming. 
  •     Manual Sharing Records
 To share record manually click go to object List View and click on "Forward To Connection"


Then select the connection and click on Save button.

Records will be automatically created in the target environment if auto-accept for the object is enabled

  •  Programmatic sharing records via Apex
    Some time we need to send record to other org automatically. Then we can create some trigger like below and do the same.

Sample Code.
trigger ShareAccountS2S on Account (After update) {
    Set <Id> setAcc = new Set<Id>();
    for(account acc : Trigger.New){
        if(acc.Active__c == 'Yes'){
            setAcc.add(acc.id);
        }
    }
 
    if(setAcc.size() >0) {
        Id NetworkId ;
        String connName ='ForBlog'; // Plz add connection Name 
        list<PartnerNetworkConnection> conns = [select id from PartnerNetworkConnection where ConnectionName = :connName ];
        if(conns.size()>0) {
            NetworkId = conns[0].id;
        }

        if( NetworkId != NULL ){
            string relatedRecords = 'Contact' ;
            list<PartnerNetworkRecordConnection> recordShares = new list<PartnerNetworkRecordConnection>();
            for(id accId : setAcc )
            {
                recordShares.add(new PartnerNetworkRecordConnection(
                    ConnectionId = networkId,
                    LocalRecordId = accId,
                    RelatedRecords = relatedRecords
                ));
            }
            insert recordShares;  
        }    
    }
}

Related Post
1) Salesforce to Salesforce Overview
2) https://developer.salesforce.com/page/Best_Practices_for_Salesforce_to_Salesforce

Thanks
Amit Chaudhary
@amit_sfdc

Monday, 14 August 2017

Language Translation in VisualForce Page | Translation Workbench


Salesforce offer functionality through that we'll be able to create single VF page which can be translated in several languages based on language/locale preference of current logged in user. We just need to upload the translation of all custom fields that you're going to use in VF page . To render the VF page in particular language, use Language attribute on <apex:page> tag.

Please follow below step to achieve the same. 
Step 1) Enable Translation Workbench and all Translation   Please follow below post to enable Translation Workbench
URL :-Translation Workbench - Salesforce ( Multilingual picklist values )

Step 2) You Can use the "Language" attribute of the VF page.

Step 3) Try to use Salesforce standard way to is to use apex:inputField tag with assigned sobject field. In this case a field will be generated automatically with respect to the current user language. 
Apex Class:-

public with sharing class TranslationWorkbenchController {
    public string selectedLang{get;set;}
    public List<selectoption> listOfLang {get;set;}
    public TranslationWorkbenchController(ApexPages.StandardController controller) {
        selectedLang='en';

        listOfLang = new List<selectOption>();
        listOfLang.add(new selectOption('en','English'));
        listOfLang.add(new selectOption('it','Italian'));
        listOfLang.add(new selectOption('es','Spanish'));
        listOfLang.add(new selectOption('de','German'));
        listOfLang.add(new selectOption('fr','French'));
    }
}


VF Page :-


<apex:page standardcontroller="Account" extensions="TranslationWorkbenchController" language="{!selectedLang}" >
<apex:form >

        <apex:selectList value="{!selectedLang}" size="1">
            <apex:selectoptions value="{!listOfLang}"/>
            <apex:actionsupport event="onchange"/>
        </apex:selectlist>
   
        <apex:pageblock >
            <apex:pageblocksection >
                <apex:inputfield value="{!Account.Name}"/>
                <apex:inputfield value="{!Account.Type}"/>
                <apex:inputfield value="{!Account.Industry}"/>
                <apex:inputfield value="{!Account.BillingCountry}"/>
            </apex:pageblocksection>
        </apex:pageblock>
   
</apex:form>
</apex:page>


Screen shot :-

English :-


Spanish:-




Thanks
Amit Chaudhary

Sunday, 6 August 2017

Webservice callout from Scheduled Apex | Report in Batch Job | System.CalloutException: Callout from scheduled Apex not supported


We used to get "System.CalloutException: Callout from scheduled Apex not supported" Error when we are making a webservice callout from a class which is implementing Database.Schedulable interface because Salesforce does not allow us to make callouts from Schedulable classes.

Issue

Sample Scheduler Class


global class SampleScheduler implements Schedulable{
    
    global void execute(SchedulableContext sc) 
    {        
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        request.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals');
        request.setMethod('GET');
        HttpResponse response = http.send(request);

        if (response.getStatusCode() == 200) {
            Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
            List<Object> animals = (List<Object>) results.get('animals');
            System.debug('Received the following animals:');
            for (Object animal: animals) {
                System.debug(animal);
            }
        }
    }    
}

Execute Above Scheduler Class


String sch = '0 00 * * * ?';
system.schedule('Test Schedule', sch, new SampleScheduler());


Error Screen Shot 

Scheduler: failed to execute scheduled job: jobId: 7076A00000EmLPu, class: common.apex.async.AsyncApexJobObject, reason: Callout from scheduled Apex not supported




Solution :- We can solved this issue with below solution.
  1. @future method
Scheduler Class

global class SampleScheduler implements Schedulable{
    
    global void execute(SchedulableContext sc) 
    {        
 
  BatchUtilClass.futureMethodSample();
    }    
}

Future Class Method

public class BatchUtilClass {
    @future(callout=true)
    public static void futureMethodSample() {
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        request.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals');
        request.setMethod('GET');
        HttpResponse response = http.send(request);

        if (response.getStatusCode() == 200) {
            Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
            List<Object> animals = (List<Object>) results.get('animals');
            System.debug('Received the following animals:');
            for (Object animal: animals) {
                System.debug(animal);
            }
        }
    }
}


Thanks
Amit Chaudhary

Tuesday, 25 July 2017

Success Story of :- Gaurav Kheterpal

Welcome to my 11th Salesforce Success Story series. This series is focused on success story and to inspire/encourage new user/Developer. And why we should join our local Salesforce Developer/User group.



1) Your Job Title

Vice President - Mobility & Technology Evangelism at Metacube 

2) Your success Story

I'm a BITS Pilani alumni and I've been in the industry for about 17 years. I used to work on telecom applications and protocol stacks before I accidentally stared my Salesforce journey in 2007. I was initially involved in building mobile applications on the Force.com platform which helped me gain a holistic understanding of Salesforce over the years. I'm a naturally inquisitive person so I tend to dig deeper into how things work and this helped me learn Salesforce. In 2012, my team built an app called ‘Noteprise’ – a connector  between Salesforce and Evernote, basically notes for enterprise powered by the Force.com platform. The app was a runner-up in a global mobile development challenge held by Salesforce and was selected for the mobile dev gallery – a collection of some of the best reference applications. I was then developed a few more interesting applications like one called Socialforce, which is a mashup of Salesforce, Facebook, Twitter and Linkedin & again won an award from Salesforce. I keep experimenting, and in 2014, I wrote another app using the Titanium framework for Force.com which won the Appcelerator enterprise app challenge

Although I started off in 2007, I believe 2012 was the definitive year for me - my app won an award from Salesforce, I presented at Dreamforce for the first time and since then I've not looked back. I've presented sessions at Dreamforce every year since then and I'm eagerly looking forward to the results of Call for papers for Dreamforce 2017 that's due soon.

I'm the co-leader for the Jaipur Developer User Group and we try to do events with high-quality content on a regular basis. I feel honoured that Salesforce recognised me as a developer success story on their blog in year 2015. I was inducted as a Salesforce MVP last year and I believe it's an important milestone in my journey.



3) Why we Should Join a Salesforce User/Developer Group 
There's no better way to learn than learning in a group. Jaipur Developer User Group is a great example of collaborative learning. You get to learn from the others as well as share your knowledge among others. It helps you connect to people and also opens up opportunities to grow your network.
4) Advice for new Salesforce Developer 
Spend time focusing on the concepts. Trailhead is a great starting point. Once you feel confident, appear for the relevant certification to you. Give yourself time - don't look for shortcuts. Salesforce isn't a magic wand for your career but if you work hard, it can help you create the magic.
5) Trailhead badges
I'm at about 90 badges right now and I'm eager to find time to join the elusive Ranger club of 100+ badges. When Trailhead started off, I was among the leaders for the first few weeks but then I just couldn't devote enough time as expected. Hopefully, I'll cross that bridge some day.



Follow Gaurav Kheterpal on:
 Twitter or his blog blog



If you want to share your Salesforce Success Story, Please feel free to drop me an email :- amit.salesforce21@gmail.com 


<<PREVIOUS       NEXT>>


Thanks
Amit Chaudhary
@amit_sfdc


Tuesday, 18 July 2017

How to write test class for Scheduler /Schedulable class in Salesforce



Sample Batch job

global class AccountUpdateBatchJob implements Database.Batchable<sObject> 
{    
    global Database.QueryLocator start(Database.BatchableContext BC)     {
        String query = 'SELECT Id,Name FROM Account';                
        return Database.getQueryLocator(query);     
    }    
    global void execute(Database.BatchableContext BC, List<Account> scope)     {        
        for(Account a : scope)        
        {            
            a.Name = a.Name + 'Updated by Batch job';        
        }        
        update scope;       
    }    
    global void finish(Database.BatchableContext BC) {    }
}



Scheduler Class For Batch Apex


global class AccountUpdateBatchJobscheduled implements Schedulable 
{
    global void execute(SchedulableContext sc) 
    {
        AccountUpdateBatchJob b = new AccountUpdateBatchJob(); 
        database.executebatch(b);
    }
}




Test Class for Scheduler Class


@isTest
private class AccountUpdateBatchJobscheduledTest
{

    static testmethod void schedulerTest() 
    {
        String CRON_EXP = '0 0 0 15 3 ? *';
        
        // Create your test data
        Account acc = new Account();
        acc.name= 'test';
        insert acc;
        
        Test.startTest();

            String jobId = System.schedule('ScheduleApexClassTest',  CRON_EXP, new AccountUpdateBatchJobscheduled());
            CronTrigger ct = [SELECT Id, CronExpression, TimesTriggered, NextFireTime FROM CronTrigger WHERE id = :jobId];
            System.assertEquals(CRON_EXP, ct.CronExpression);
            System.assertEquals(0, ct.TimesTriggered);

        Test.stopTest();
        // Add assert here to validate result
    }
}



Please check below post for Batch job
1) http://amitsalesforce.blogspot.com/2016/02/batch-apex-in-salesforce-test-class-for.html



Please check below post for more detail
1) https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_scheduler.htm


Thanks,
Amit Chaudhary




Wednesday, 21 June 2017

Test Salesforce API by Postman Rest Client | Postman and Salesforce | Calling APEX Rest service using Postman| OAuth 2.0


Force.com platform support powerful web services API for interaction with external app and salesforce.com . For secured interaction with third party app, Salesforce enforces authentication process.


Above image is picked from here.


Step 1) Connected App for OAuth

To perform OAuth in salesforce, you must create Connected App in salesforce

Follow below step to create connected App.

1) Click on Setup->Create->App


2) Then from above screen click on Connect Apps then New button. Then add all required information like below



 3) Now After creating connected App we have consumer key and consumer secret



Step 2) Create a REST API in salesforce.

Please check below post for REST API
1) Learn Rest API in salesforce | How to learn Rest API | Rest API in salesforce
2) Rest API in Salesforce | Execute Rest API on workbench | Test class for Rest API

Sample code to Start


@RestResource(urlMapping='/api/Account/*')
global with sharing class MyFirstRestAPIClass
{
@HttpGet
global static Account doGet()
{
RestRequest req = RestContext.request;
RestResponse res = RestContext.response;
String AccNumber = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);
Account result = [SELECT Id, Name, Phone, Website FROM Account WHERE AccountNumber = :AccNumber ];
return result;
}

@HttpDelete
global static void doDelete()
{
RestRequest req = RestContext.request;
RestResponse res = RestContext.response;
String AccNumber = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);
Account result = [SELECT Id, Name, Phone, Website FROM Account WHERE AccountNumber = :AccNumber ];
delete result;
}

@HttpPost
global static String doPost(String name,String phone,String AccountNumber )
{
Account acc = new Account();
acc.name= name;
acc.phone=phone;
acc.AccountNumber =AccountNumber ;
insert acc;

return acc.id;
}

}

Step 3) Get Access Token by POSTMAN

  3.1) Install the postman from here.

  Download URL :- https://www.getpostman.com/

  3.2) Generate URL

  OAuth Endpoints in Salesforce
  Authorization
: https://login.salesforce.com/services/oauth2/authorize
  Token Request: https://login.salesforce.com/services/oauth2/token




  There are two way to get Access token
  1) By Post Callout (Direct URL)
  2) By OAuth Setting in POSTMAN (Wizard one)

  3.2.1:- By Post Callout (Direct URL)

  Use below link to Generate the Token for accessing SFDC

https://na50.salesforce.com/services/oauth2/token?grant_type=password&client_id=***Consumer Key_Here***&client_secret=***Consumer Secret_Here***&username=*********&password=*****password+securityToken******






NOTE:-   May be After try to login you will get below error "Failed: Not approved for access"



     Please check below post to resolve this issue
    1) https://help.salesforce.com/articleView?id=000212208&language=en_US&type=1
    2) http://amitsalesforce.blogspot.com/2017/06/failed-not-approved-for-access-in.html
  

  Finally We have Access Token

  3.2.2:- By OAuth Setting in POSTMAN (Wizard one)

  •   Select Type OAuth 2.0

  • Then click on  "Get Access Token". Then provide all below detail.

  • Then click on Request Token button. Then it will ask you to enter userName and password.


  • Here we have Access Token
  


Step 4) Test APEX REST API. 

Now Copy the Access Token from above Screen. Add below detail to make get call



a.       End point URL: https://na50.salesforce.com/services/apexrest/api/Account/12345
b.      Select method as ‘GET
c.       Put the details in header as below:
Authorization: OAuth + Access Token



Or you can try like below as well.


Now Copy the Access Token from above Screen. Add below detail to make get call


a.       Click Add Token to "Header"
b.      Then select "Use Token"
c.       Then select Get Method and add below URL
https://na50.salesforce.com/services/apexrest/api/Account/12345





Related Post
1) Apex REST Basic Code Sample
2) Rest API
3) Understanding the Web Server OAuth Authentication Flow

Please let us know if this will help you

Thanks
Amit Chaudhary