Wednesday, November 30, 2016

Using SOQL to Determine Your Force.com User’s Permissions

"Now that a user can have multiple permission sets in addition to their profile, how can I tell what permissions they have?”

Summer ’12 introduces the ability to answer this question using the permission set API. We’ve created a new field on the PermissionSet SObject called IsOwnedByProfile. This field determines whether a permission set is a custom one or if it is parented by a profile. This is made possible because for every profile, there is one underlying permission set. That way, permissions layer equally across permission sets without having to treat a profile differently. In the setup user interface, you only see the profile but in the API, you can see both the profile and the underlying permission set.

As a result, running the following query in SOQL will return both permission sets you’ve created and permission sets parented by a profile:
SELECT Id,IsOwnedByProfile,Label
FROM PermissionSet

By adding IsOwnedByProfile to the WHERE clause, you will quickly differentiate between permission sets you’ve created versus those parented by a profile:

SELECT Id,IsOwnedByProfile,Label
FROM PermissionSet
WHERE IsOwnedByProfile = TRUE

Once you have the hang of this, you can start to answer all sorts of questions about your users such as, “which users have Read on Accounts and why”:

SELECT Assignee.Name, PermissionSet.Id, PermissionSet.isOwnedByProfile, PermissionSet.Profile.Name, PermissionSet.Label
FROM PermissionSetAssignment
WHERE PermissionSetId
IN (SELECT ParentId
FROM ObjectPermissions
WHERE SObjectType = 'Account' AND
PermissionsRead = true)

You might need to answer questions about a specific user such as, “what are all of the Account fields where John Doe has at least Read access and why”

SELECT Id, SObjectType, PermissionsRead, Parent.label, Parent.IsOwnedByProfile
FROM ObjectPermissions
WHERE (ParentId
IN (SELECT PermissionSetId
FROM PermissionSetAssignment
WHERE Assignee.Name = 'John Doe'))
AND
(PermissionsRead = true)
AND
(SobjectType = 'Account')


Using permission sets in this way, you can find out why a user has access to an apex page, class or a particular user, object, or field permission, regardless of whether it’s through their profile or permission set.


These SOQL queries are great if you have one off questions about your user’s permissions. If you have a more regular need to query user’s permissions, think about creating a Visualforce page with an Apex controller that uses these queries to find out what your users can do and why.

Tuesday, November 29, 2016

Retrieving RecordTypeId with Describe Call in Salesforce

//Generate a map of tokens for the sObjects in your organization
Map gd = Schema.getGlobalDescribe();

//Retrieve the describe result for the desired object
DescribeSObjectResult result = gd.get('Account').getDescribe();

//Generate a map of tokens for all the Record Types for the desired object
Map recordTypeInfo = result.getRecordTypeInfosByName();
system.debug('RECORD TYPES:' + recordTypeInfo);

//Retrieve the record type id by name
String recordTypeId = recordTypeInfo.get('RECORDTYPE_NAME').getRecordTypeId();
OR
//Retrieve the record type id by name
String recordTypeId = Schema.getGlobalDescribe().get('Account').getDescribe().getRecordTypeInfosByName().get('RECORDTYPE_NAME').getRecordTypeId();

System.debug('@@@-----'+recordTypeId);

Wednesday, November 23, 2016

Display collapsible data in VF page

Use Case

We may need to display collapsible data in VF page. This can be easily achieved using the VF component <Apex:PageBlockSection> . However this component is not always useful and may distort the UI when used with some specific components – like <Apex:repeat>.

Solution

We can customize our code to enclose the rows to be collapsed using  HTML tag <TBODY> and set its id dynamically. Now, using JavaScript function we can get collapsible and expandable data rows.

Reusable Code

VF Page

<apex:page controller="CollapsibleClass" sidebar="false">
  <script>
   function switchMenu(obj,obj1,obj2)
        {
            var el = document.getElementById(obj);                                     
            if ( el.style.display != 'none' ) {
            el.style.display = 'none';
            }
            else {
            el.style.display = '';
            }
            var e2 = document.getElementById(obj1);                                      
            if ( e2.style.display != 'none' ) {
            e2.style.display = 'none';
            }
            else {
            e2.style.display = '';
            }
             var e3 = document.getElementById(obj2);                                      
            if ( e2.style.display != 'none' ) {
            e3.style.display = 'none';
            }
            else {
            e3.style.display = '';
            }

        }
  </script>
  <table border="0" width="50%" id="myTable">
   <tr>
     <td width="1%" bgcolor="grey"></td>
     <td width="19%" bgcolor="grey"><b> Account Name</b> </td>
     <td width="19%" bgcolor="grey"><b>Account Type</b> </td>  
   </tr> 
   <apex:variable value="{!0}" var="rowNum1"/>  
  <apex:repeat var="account" value="{!accountDataList}" id="rFirst">
     <tr>
       <td width="1%" bgcolor="Lightblue">
         <apex:outputpanel id="plusimage" style="{!IF(account.hideOrShow == '', "display:none;", "")}" >
            <apex:image url="{!URLFOR($Resource.Images, 'Plus_Image.gif')}" onclick="switchMenu('inlinetablesec{!rowNum1}','{!$Component.minusimage}','{!$Component.plusimage}')" title="Show TSF details"/>
         </apex:outputpanel>
         <apex:outputpanel id="minusimage" style="{!account.hideOrShow}">
            <apex:image url="{!URLFOR($Resource.Images, 'Minus_Image.gif')}" onclick="switchMenu('inlinetablesec{!rowNum1}','{!$Component.plusimage}','{!$Component.minusimage}')" title="Hide TSF details"/>
         </apex:outputpanel>
        </td>
        <td width="20%" bgcolor="Lightblue">
           <apex:outputLink value="/{!account.id}" id="accountLink" target="_blank">{!account.name}</apex:outputLink>
        </td>                  
        <td width="19%"  bgcolor="Lightblue">
          {!account.type}
        </td>
      </tr> 
      <tbody id="inlinetablesec{!rowNum1}" style="{!account.hideOrShow}">
       <tr>   
          <td width="1%"></td>                
            <td bgcolor="grey" width="20%"><b>Contact Name</b></td>
           <td bgcolor="grey" width="20%"><b>Contact Phone</b></td>              

         </tr>  
      <apex:variable value="{!0}" var="rowNum"/>
      <apex:repeat var="cont" value="{!account.contacts}" id="rSecond"> 
      
        <tr>   
          <td width="1%"></td>                
            <td bgcolor="LightGrey" width="20%">{!cont.name}</td>
           <td bgcolor="LightGrey" width="20%">{!cont.phone}</td>              

         </tr>          
      <apex:variable var="rowNum" value="{!rowNum + 1}"/>   
      </apex:repeat>
         </tbody>
      <apex:variable var="rowNum1" value="{!rowNum1 + 1}"/>
  </apex:repeat>
  </table>
</apex:page>

Controller Class

public class CollapsibleClass {
public list<AccountData> accountDataList {get;set;}
  Public CollapsibleClass(){
    accountDataList = new list<AccountData>();
    prepareData();
  }
   //Wrapper class used to hold date for alternate table 4
     public class AccountData
     { 
        public String id {get; set;}  
        public String name {get; set;} 
        public String type {get; set;}
         public String hideOrShow {get; set;}
        public List<Contact> contacts {get;set;}   
           
        public AccountData()
        {
        
        }
      }       
      private void prepareData() {
        for (Account acc : [SELECT Account.Name,Account.type,(SELECT Contact.Name,Contact.Phone FROM contacts) FROM Account WHERE Account.Id IN (SELECT Contact.accountId FROM Contact) limit 5]) {
          AccountData accData = new AccountData();
          accData.id= acc.id;
          accData.name = acc.name;
          accData.type = acc.type;
          accData.contacts = acc.contacts;
          accData.hideOrShow  = 'display:none;';
          accountDataList.add(accData);
        }
      }
}

Screen Shot



Send SMS from your Salesforce org

Below is the code to send SMS on our mobile from our Salesforce ORG.

Prerequisite: - You must have a valid account on fullonsms.com

String Message = 'Hi,this is test message';            (// Write here your Test Message)
String uid = '9999326589';              (//Write here your fullonsms.com user Name)
String password = 'pass1';            (//Write here your fullonsms.com Password)
String no = '9636985623';               (//Write here mobile number where you need to send SMS))

String Url='http://ubaid.tk/sms/sms.aspx?uid=' + uid + '&pwd=' + password + '&msg=' + message + '&phone=' + no + '&provider=fullonsms';
  Http h = new Http();
       
        // Instantiate a new HTTP request, specify the method (GET) as well as the endpoint
HttpRequest req = new HttpRequest();
req.setEndpoint(Url);
req.setMethod('GET');
req.setTimeout(12000);      
        // Send the request, and return a response
HttpResponse res = h.send(req);

System.debug('@@@@'+res.getBody());

For More details, go to below link:-


Generic VF Page Component to be used in VF page to format date as per User’s Locale

Use Case

Generic VF Page Component to be used in VF page to format date  as per User’s Locale.

When we use a date field in a VF page, then it is often required  to format it according to User’s locale date format. We can achieve this using code in VF page as shown below –

<apex:outputText value="{0,date,dd/MM/yyyy}">
    <apex:param value="{!Contact.Birthdate}" />
</apex:outputText>

Where we are formatting a contact’s birthday in ‘dd/MM/yyyy’ format. But if an organization has users across various countries then they will have different locale and this code will not going to work. To achieve this requirement we can create a generic VF Component that will take care of date format according to logged in user’s locale. We can store the user’s local date formats in a Custom setting

Solution
The code below implements the functionality. Please Follow the below steps along with the code:
1.       Create a new  Custom Setting with below details –
Label:  Date_Format_Settings
Object Name: Date_Format_Settings
Setting Type : List
Visibility: Public
2.       Create a Text field (of length 255) with field label and field name “Date_Format”.
3.       With the help of Data Loader, populate this custom setting with data. Please use the attached CSV file to import data to the Custom setting.
4.       Create a new apex class  and a paste the code listed under class name “Date_Format_Controller”.
5.        Create a new VF component with the code listed under ‘Date Format Component’ below. Name it as ‘Date Format’
Reusable Code

Date_Format_Controller Apex class Code:

public class Date_Format_Controller
{   
    public DateTime dateTimeValue { get; set; }
    
    //returns the properly formatted datetime value
    public String getFormattedDateValue()
    {
        String localFormmattedDate = '';     
        String user_locale = UserInfo.getLocale();
        String myDateFormatValue = 'M/d/yyyy';
        Date_Format_Settings__c mySetting = Date_Format_Settings__c.getValues(user_locale);
        if (mySetting != null)
        {
            myDateFormatValue  = mySetting.Date_Format__c.trim();
        }     
        if (dateTimeValue != null)
        {
         localFormmattedDate  = dateTimeValue.format('M/d/yyyy');
         if (myDateFormatValue !=null & !myDateFormatValue.equals(''))
         {
            try
            {
                localFormmattedDate  = dateTimeValue.format(myDateFormatValue);
            }
            catch (Exception e)
            {
             localFormmattedDate  = dateTimeValue.format('M/d/yyyy');
            }
          }
        }    
        return localFormmattedDate  ; //return the string
      
    }   
}

Date_Format Component  Code:

<apex:component access="global" controller="Date_Format_Controller">
<apex:attribute assignTo="{!dateTimeValue}" description="The DateTime value to be rendered based upon the user's locale" name="dateTimeInput" type="DateTime"></apex:attribute>
{!formattedDateValue}
</apex:component>

Code Usage:

This component can be used from any VF page using the below syntax –

  <c:Date_Format dateTimeInput="{!DateTobeFoprmatted}"> </c:Date_Format>

Where ‘DateTobeFoprmatted’ is date passed from its controller that needs to be formatted.

The following VF page  uses the generic component to format a contact’s birthdate.To test this VF page you can simply create a new contact and enter a birthdate along with other required field. Now replace  the contact’s ID in the below URL and check on the browser.


Date_Format_Test VF page Code:

<apex:page standardController="Contact">
Formatted contact's birthdate :
  <c:Date_Format dateTimeInput="{!Contact.Birthdate}"> </c:Date_Format>
</apex:page>



Please  go to the logged in user’s detail page and edit the “Locale” field to select a new locale option for the user. If you reload the above VF page you will see that the Contact’s birthdate is formatted according to the locale that you have selected for the logged in user.

Saturday, November 19, 2016

Implement multi-select picklist as multi-select checkboxes on a page, for improving the User Experience

Use Case

Implement multi-select picklist as multi-select checkboxes on a page, for improving the User Experience.

Solution

Use the following VF page code and the controller class login for the use case

Code Snippet

·         Controller

public class CustomObjectExtension {
    public CustomObject pr{get; set;}
     //initialize
    public CustomObjectExtension (ApexPages.StandardController controller){
      pr=new CustomObject();
    }
  
    //get the multi-select pick list values
    public List<SelectOption> MPOptions {
     get {
       List<SelectOption> options = new List<SelectOption>();
       for( Schema.PicklistEntry f : CustomObject.Multi_Select__c.getDescribe().getPicklistValues()) {
         options.add(new SelectOption(f.getValue(), f.getLabel()));
        }
       return options;
     } 
     set;
    }
   
    //get and set the multi-select pick list as checkboxes
    public String[] MPItems {
     get {
        String[] selected = new List<String>();
        List<SelectOption> sos = this.MPOptions;
        for(SelectOption s : sos) {
        if (this.pr.Multi_Select__c!=null && this.pr.Multi_Select__c.contains(s.getValue()))
           selected.add(s.getValue());
        }
        return selected;
     }public set {
        String selectedConcat = '';
        for(String s : value) {
         if (selectedConcat == '')
           selectedConcat += s;
         else selectedConcat += ';' + s;
        }
        pr.Multi_Select__c= selectedConcat;
     }
   }
} 

·         VF Page

<apex:page standardController="CustomObject" extensions="CustomObjectExtension" id="prpage">
<apex:form id="prform">
<apex:pageBlock id="prblock">
   <apex:pageBlockSection title="View the picklist values" id="prmain"><br/><br/><br/>
    <font><b><i>Which picklist values to be used(select the most relevant)?</i></b></font><br/>
    <center>
     <apex:selectCheckboxes value="{!MPItems}" layout="pageDirection" required="true" id="prodreq">
       <apex:selectOptions value="{!MPOptions}"/>
     </apex:selectCheckboxes>
    </center>
   </apex:pageBlockSection>
  </apex:pageBlock>
</apex:form> 

</apex:page>

Tuesday, November 15, 2016

Live Agent Implementation | Setting up live Agent in Salesforce

What is Live Agent

Now days customers expect fast replies and quick resolutions. With Live Agent web chat, We can give them quicker responses to their queries. Live Agent provide users the ability to interact with the agents through web chat to get more information about specific product or queries

Process 1) Follow below Step to Setup Live Agent 

Step 1 :- Open live Agent Setting
Customize --> Live Agent----> Live Agent Setting 



Step 2:- Enable Live Agent 
Click on Enable Live Agent Chat Box and click on save button



Once you will enable the Live Agent below object will auto created in your org.
  1. Live Chat Visitors
  2. Live Chat Transcripts
  3. Live Chat Transcript Events
  4. Live Agent Sessions
  5. Live Agent Supervisor
  6. Live Agent
  7. Quick Text
Step 3:- Setup Live Agent User.

Setup--> My Setting -> Advanced User Details--> Then click on Live Agent User checkbox

Step 4:- Set Skill 

Click on Setup --> Live Agent --> Skill 



 Then Click on new button and setup skill like below screen



Step 5:- Upload Online and Offline Image

Upload online and offline image in "Static Resource"



Step 6:- Setup Chat Buttons & Invitations

Setup--> Customize -->Live Agent --> Chat Button & Invitation.


then click on New Button. And add all below detail


Once you will click on Save button the chat button code will come

Copy Above Script and keep with you

Step 7:- Create Deployment 

Click on Setup-> Customize --> Live Agent--> Deployments



Then click on New button and provide all below detail


Then click on Save button. After Saving Deployment code will come like below


Copy the Deployment code.

Create the HTML page with Chat Button Code (Step 6) and Deployment Code.


NOTE:- First you need to copy Chat Button Code then Deployment Code.

Now you all Set with live Agent Configuration

Process 2) Now Setup the Agent Console ( Console App )


Step 1:- Open App Wizard
Setup--> Create --> App



Step 2:- Create new Console App

Click on new button then select console button


While creating the App on Step 6 select the "Include Live Agent in this App" check box like below




Now All Set. We can test the same now


Process 3) How To Test

Click on HTML page which you created in process 1 Step 7.

Once you page will open and Agent is not online the below Html page will show you offline image


Once Agent will come online from agent console then image will change on client HTML page

How Agent will come online

Step 1:- Select Live Agent Console App


Step 2) Then from the Live Agent Click on Online button



Now All Set Agent is online :)

Step 3) Refresh you HTML page
Once Agent will login the HTML will show you online image like below


Then click on Image the set session will start.



Accept chat from agent console