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

Sunday, 18 June 2017

Failed: Not approved for access in salesforce



After entering credentials and attempting to login to Salesforce, the API user is denied access to the application and is typically accompanied by a Login History Status of "Failed: Not approved for access".




Solution:-

Update  OAuth policies and set Permitted Users to "All users may self-authorize".

Step 1) Open the connected App the click on Manage button.




Step 2) Then click on Edit policies button




Step 3)  then update "OAuth policies"





     Please check below post to resolve this issue
    1) https://help.salesforce.com/articleView?id=000212208&language=en_US&type=1


Thanks
Amit Chaudhary