A blog dedicated to Salesforce Ohana

How to create Chatter Free and Chatter External Users

There are two ways by which we can create Chatter Free or Chatter External Users. They are -


  • Administrator can create a new user record and select Chatter Free or Chatter External from User License picklist like -





  • Administrator can enable Chatter settings -
    • Coworker Invitations - For users to invite coworkers as Chatter Free Users.
    • Customer Invitations - For inviting customers as Chatter External Users.











P.S. Users can accept an invitation to join chatter within 30 days.

Share:

Different Chatter Licenses in Salesforce

In Salesforce, we have two types of Chatter Licenses. Below are they and small description to help you in choosing Salesforce Chatter license appropriate for your requirement.

Chatter Free License: User with Chatter Free License can access people, profiles, groups and files. They can make posts, view comments, upload & view files, join groups. But they can't interact with Salesforce data such as accounts, contacts or opportunities.

So if you have a requirement of allowing people to only join groups, view/participate in conversation, please allow Chatter Free License to those people.

Chatter External License: Chatter External License allows people outside the organization, such as customer, into private groups in the Chatter community. Users with Chatter External License can -
  • see the groups they belong to, and profiles of members of those groups.
  • share files common to groups they belong.
Customers with Chatter External License can only be invited to a private Chatter group.
They can see-
  • Groups and profiles of the members of groups they belong to.
  • Files shared to groups they belong to
They cannot-
  • Post to profiles.
  • See records or other Salesforce information, even in search results.
  • Be followed. Additionally, customer can't follow people or files also.
So if you have a requirement of allowing people outside of your organization i.e. your customers to join specific groups, please allow Chatter External License to those people.


Share:

Standard Chatter Profiles in Salesforce

In Salesforce, we have Standard Chatter Profiles. These profiles are available to those users with Chatter Free or Chatter External User licenses. These profiles allow user to login to Chatter only.

Below are the Standard Chatter Profiles available -
  • Chatter Free User Profile:  User with Chatter Free User Profile can access all standard chatter people, profiles, groups and files. User can make posts, leave comments, upload files and join groups. They have limited administrative and general user permission and that is why they are not allowed to access any Salesforce's object details. This profile is available to users having Chatter Free User license.
  • Chatter Moderator User Profile: Access same data as Chatter Free Users. They can activate/deactivate other Chatter Free users/moderators. They can grant/revoke moderator privileges. They can delete posts and comments which they can see. This profile is available to users having Chatter Free User license.
  • Chatter External User Profile: User will this profile can access groups they have been invited to and interact with members of that groups. This profile normally assigns to external customers so that they can quickly make posts, leave comments or provide feedback. 
Please provide your feedback. Thanks in advance. 
Share:

Standard Profiles available in Salesforce

There are 6 standard profiles available in Salesforce (EE/UE and PE). They are -

  • Standard User – Can view, edit, and delete their own records
  • Solution Manager – Standard User permissions + Can manage published solutions + Can manage categories
  • Marketing User – Standard User permissions + Can import leads for the organization
  • Contract Manager – Standard User permissions + Can edit, approve, activate, and delete contracts
  • Read-Only – Can only view records
  • System Administrator – “Super User”, can customize and administer the application
For more details, please refer the below help topics -
Share:

Calculate Age from Date of Birth in Salesforce

Below formula can be used to calculate age from date of birth in Salesforce -

IF(
    NOT(ISNULL(BirthDate)), /* Condition to check to make sure BirthDate is not null */
    TEXT(FLOOR((TODAY()-BirthDate)/365.2425)) & " year(s) " & 
    TEXT(FLOOR(MOD((TODAY()-BirthDate),365.2425)/30)) & " month(s)", /* Value IF True */
    "" /* Value IF False */
)

Share:

Diwali 2014












Share:

JSON Parsing with Apex in Salesforce - Part III

Hello friends,

In this post, I am going to share the information how to parse multiple JSON request and display the same in Visual Force page in tabular format.

If you haven't visited my previous posts regarding JSON parsing, please go to below links -
JSON Parsing with Apex in Salesforce - Part I
JSON Parsing with Apex in Salesforce - Part II

So let's start.
First the Visual Force Page-
<apex:page controller="CountryController">
    <apex:form >
        <apex:pageBlock Title="JSON Parser Example - Multiple Data">
            <apex:commandButton value="Parse Multiple JSON Data" action="{!parseJSONData}"
                reRender="countryData" />
        </apex:pageBlock>
        <br />
        <apex:pageBlock id="countryData">
            <apex:pageBlockTable value="{!countries}" var="country">
                <apex:column headerValue="Country Name" value="{!country.countryName}"/> 
                <apex:column headerValue="Country Capital" value="{!country.countryCapital}"/> 
                <apex:column headerValue="Country Currency" value="{!country.countryCurrency}"/> 
        </apex:pageBlockTable> 
        </apex:pageBlock>
    </apex:form>
</apex:page>
Now the controller-
public class CountryController {
    private List<CountryDataWrapper> countryDataWrapper;
    
    public void parseJSONData(){
        countryDataWrapper = new ParseMultipleJsonData().parse();
    }
    
    public List<CountryDataWrapper> getCountries(){
        return countryDataWrapper;
    }
}
The wrapper class to hold Country information-
public class CountryDataWrapper {
    public String countryName{get;set;}
    public String countryCapital{get;set;}
    public String countryCurrency{get;set;}
}
And finally the parser class doing the parsing
public class ParseMultipleJsonData {
    public List<CountryDataWrapper> parse() {
        String jsonMessage = '[{'+
        '  \"countryName\": \"India\",'+
        '  \"countryCapital\": \"Delhi\",'+
        '  \"countryCurrency\": \"Indian rupee\"'+
        '},'+
        '{'+
        '  \"countryName\": \"Switzerland\",'+
        '  \"countryCapital\": \"Bern\",'+
        '  \"countryCurrency\": \"Swiss franc\"'+
        '},'+
        '{'+
        '  \"countryName\": \"United States of America\",'+
        '  \"countryCapital\": \"Washington, D.C.\",'+
        '  \"countryCurrency\": \"US Dollar\"'+
        '}]';
        
        return (List<CountryDataWrapper>) System.JSON.deserialize(jsonMessage, List<CountryDataWrapper>.class);
    }
}

That's all. Let's see how the Visual force page is behaving now-
Initially the page looks like -
Now when we clicked on the "Parse Multiple JSON Data" button, it parsed the JSON data and displayed in tabular format like below-

If you have any feedback, please share with me. Thanks in advance.
Share:

JSON2Apex - Convert JSON Into Apex Class


JSON2Apex is an online tool to convert JSON into Apex class. The URL is: JSON2Apex
This tool is hosted in Heroku.

This app allows a user to paste a JSON String, and then this app will generate strongly typed apex code that can deserialize it. This entire app is written in Java using Play framework.

A special thanks to superfell and metadaddy for providing this amazing tool.

Guys, please use this one while working with JSON and Apex code.
Share:

Dreamforce 2014 - Salesforce Developer's Keynote

Nice video. Please watch-


Share:

JSON Parsing with Apex in Salesforce - Part II

This post is in continuation of my previous post regarding JSON Parsing.

In this post, what I am going to share is-

  • How to parse a little more complex JSON containing array. 
  • Once the JSON data is parsed, how to display the same information in Visual Force Page.
Check the below link to understand what I am trying to achieve at the end of this post

So let's start with creating the Visual Force Page
<apex:page controller="StudentDetailController">
    <apex:form >
        <apex:pageBlock Title="JSON Parser Example">
            <apex:commandButton value="Parse JSON Data" action="{!parseJSONData}"
                reRender="studentData" />
        </apex:pageBlock>
        <br />
        <apex:pageBlock id="studentData">
            First Name: <apex:inputText value="{!firstName}" />
            Last Name: <apex:inputText value="{!lastName}" />
            <br/>
             
            <apex:pageBlockSection title="Language Known:" collapsible="false">
                <apex:selectList value="{!selectedLanguage}" multiselect="false"
                    size="1">
                    <apex:selectOptions value="{!languageOptions}"/>
                </apex:selectList>
            </apex:pageBlockSection>
        </apex:pageBlock>
    </apex:form>
</apex:page>
Now the controller-
public class StudentDetailController{  
    public String firstName{get;set;}
    public String lastName{get;set;}
    public String selectedLanguage{get;set;}
    private StudentDetailWrapper m;
    public List<SelectOption> languageOptions;
    
    public void parseJSONData(){
        m = new ParseStudentData().parseData();
        doAllInitialization();
    }
    
    public void parseJSONData(String jsonMessage){
        m = new ParseStudentData().parseData(jsonMessage);
        doAllInitialization();
    }
    
    public List<SelectOption> getLanguageOptions(){
        if(null == languageOptions){
            languageOptions = new List<SelectOption>();
        }
        return languageOptions;
    }
    
    private void doAllInitialization(){
        initializeStudentName();
        initializeLanguageOptions(m.language);
    }
    
    private void initializeStudentName(){
        this.firstName = m.firstName;
        this.lastName = m.lastName;
    }
    
    private void initializeLanguageOptions(List<String> language){
        languageOptions = new List<SelectOption>();
        for(String aLanguage : language){
            languageOptions.add(new SelectOption(aLanguage, aLanguage));
        }
    }
}
Now the class which will do the JSON Parsing-
public class ParseStudentData {
    private StudentDetailWrapper m;
    
    public StudentDetailWrapper parseData(String jsonMessage){
        return doParsing(jsonMessage);
    }
    
    public StudentDetailWrapper parseData(){
        String jsonMessage = '{"firstName" : "Sudipta", "lastName" : "Deb","language": ["Hindi", "German", "English", "Bengali"]}';
        return doParsing(jsonMessage);
    }
    
    private StudentDetailWrapper doParsing(String jsonMessage){
        CustomLogging.logMessage('StudentDetailController', 'parseJSONData', 'Starting of parseJSONData()', CustomLogging.INFO);
        try{
            m = (StudentDetailWrapper) System.JSON.deserialize(jsonMessage, StudentDetailWrapper.class);
        }catch(Exception ex){
            String message = 'Error: ' + ex.getMessage() + '; Stack Trace:' + ex.getStackTraceString();
            CustomLogging.logMessage('ParseStudentData', 'parseJSONData', message, CustomLogging.ERROR);
        }
        return m;
    }
}
Now StudentDetailWrapper Class which will hold the student data-
public class StudentDetailWrapper {
    
    public String firstName;
    public List<String> language;
    public String lastName;
}
And finally the test class - very important:
@isTest
private class TestStudentDetailController {
    
    private static void setEnableCustomLoggingFlag(Boolean value){
        insert(new Decision_Object__c(Name='EnableCustomLogging', Value__c=value));
    }
    
    static testMethod void testJsonParseData() {
        setEnableCustomLoggingFlag(false);
        String jsonMessage = '{"firstName" : "Paromita", "lastName" : "Banerjee","language": ["German", "English", "Bengali"]}';
    
        StudentDetailController studentDetailController = new StudentDetailController();
        studentDetailController.parseJSONData(jsonMessage);
        
        System.assertEquals('Paromita',studentDetailController.firstName);
        System.assertEquals('Banerjee',studentDetailController.lastName);
        System.assertEquals(3,studentDetailController.getLanguageOptions().size());
    }
}

Note: If you are thinking what is the reason for this method setEnableCustomLoggingFlag(),please refer to my earlier post regarding Custom Logging in Salesforce. Link: Custom Logging in Salesforce

Now when we will open the Visual Force Page, it will look like-
But once you click the "Parse JSON Data" it is going to parse the JSON Data in background and populate the same in Visual Force Page like below-

That's all. I am currently working on more complex examples. Will share very soon.
Any feedback is always welcome. Thanks
Share:

Learn & Practice Salesforce directly from Salesforce - TrailHead - What an initiative

In Dreamforce 2014, Salesforce announces a platform where developers can learn Salesforce by their own. WoW!!! It is TrailHead.

Though it is in a beta stage, but already this platform is having quite a good amount of tutorials. But what I like most is that TrailHead is having a very cool feature - Challenge yourself. Here what you can do is that you can challenge yourself to complete the exercises and earn points. The intention behind is to check your understanding.

I am already in love with this initiative. Guys, please go ahead and check this one.

Salesforce rocks. 
Share:

JSON Parsing with Apex in Salesforce - Part I

Here, I would like to share an example of very basic JSON parsing with Apex programming language in Salesforce.


MainWrapper Class:
public class MainWrapper {
    public Integer studentId;
    public String studentName;
    public String address;
    
    public MainWrapper(Integer studentId, String studentName, String address) {
        this.studentId = studentId;
        this.studentName = studentName;
        this.address = address;
    }
}
And now the test class to check whether JSON Parsing is working fine or not.
@isTest
private class TestMainWrapper {

    static testMethod void testJsonParser() {
        String jsonMessage = '{"studentId" : 1, "studentName" : "Sudipta Deb", "address" : "Kolkata, India"}';
        
        JSONParser parser = JSON.createParser(jsonMessage);
        MainWrapper m = (MainWrapper)parser.readValueAs(MainWrapper.class);
        
        System.assertEquals(1, m.studentId);
        System.assertEquals('Sudipta Deb', m.studentName);
        System.assertEquals('Kolkata, India', m.address);
    }
}

I will share more complex JSON Parsing very soon. Any feedback is always welcome.
Share:

Custom Logging Framework in Salesforce

In my current project, I have a requirement where I have to implement a custom logging framework. Salesforce put the debug/exception log with System.debug() statement, but going through that debug log to identify the issue is always a challenge. So the better approach is to store the exception as soon as it occurred somewhere so that later point we can always refer that to identify what happened.

In order to achieve that below is what I did-

First I have created an object(API Name: Custom_Log__c) to store the exception logs-
Below are the custom field inside the object-

  • Class__c(Text Area(255))   From which class the exception is coming
  • Method__c(Text Area(255))  From which method the exception is coming
  • Message__c(Long Text Area(32768))  Stack trace of the exception
  • Priority__c(Picklist) - Possible values are DEBUG, ERROR, FATAL, INFO, WARNING
Now I need to create the below custom settings -
EnableCustomLogging with possible values true/false. 
The reason behind is that with EnableCustomLogging = true, exceptions will be stored in the custom object i.e. Custom_Log__c and with EnableCustomLogging = false, exception will be stored in the debug log with System.debug() 

Now with this setup, I have created the visual page.
Source Code:
<apex:page controller="CustomLogController">
    <apex:form >
        <apex:commandButton value="Divide By Zero Exception!" action="{!divideByZeroException}" />
        <br/>
        <apex:commandButton value="Null Pointer Exception!" action="{!nullPointerException}" />
    </apex:form>
</apex:page>
Now the controller - CustomLogController:
public class CustomLogController {
    public void divideByZeroException(){
        Integer number1, number2;
        try{
            number1 = 10;
            number2 = 0;
            Integer number3 = number1/number2;    
        }catch(Exception ex){
            String message = 'Error: ' + ex.getMessage() + '; Stack Trace:' + ex.getStackTraceString();
            CustomLogging.logMessage('CustomLogController', 'divideByZeroException', message, CustomLogging.WARNING);
        }
    }
    
    public void nullPointerException(){
        Contact aContact = null;
        try{
            String email = aContact.Email;
        }catch(Exception ex){
            String message = 'Error: ' + ex.getMessage() + '; Stack Trace:' + ex.getStackTraceString();
            CustomLogging.logMessage('CustomLogController', 'nullPointerException', message, CustomLogging.ERROR);
        }
    }
}
Now the CustomLogging class-
public class CustomLogging {
    
    public static String INFO = 'INFO';
    public static String DEBUG = 'DEBUG';
    public static String WARNING = 'WARNING';
    public static String ERROR = 'ERROR';
    public static String FATAL = 'FATAL';
    
    private static Boolean isEnabled(){
        Decision_Object__c enableCustomLogging = Decision_Object__c.getInstance('EnableCustomLogging');
        System.debug('IsEnabled: ' + enableCustomLogging.Value__c);
        return enableCustomLogging.Value__c;
    }
    
    public static void logMessage(String className, String methodName, String message, String Priority){
        if(isEnabled()){
            Custom_Log__c newLogMessage = new Custom_Log__c(
                Class__c = className,
                Method__c = methodName,
                Message__c = message,
                Priority__c = Priority);
            try{
                Database.insert(newLogMessage);
            }catch(Exception ex){
                System.debug(
                    'Failed to INSERT the [Apex Debug Log] ADL record. ' +
                    'Error: ' + ex.getMessage()
                );
            }
        }else{
            String completeErrorMessage = 'Error occured at class: ' + className + ' method: ' + methodName + 
                ' and the error is: ' + message;
            System.debug(completeErrorMessage);
        }
        
    }
}
And finally the test class - This is very important
@isTest
private class UnitTestCustomLogController {
    
    private static void setEnableCustomLoggingFlag(Boolean value){
        insert(new Decision_Object__c(Name='EnableCustomLogging', Value__c=value));
    }
    
    static testMethod void testWhetherCustomLoggingIsGettingCreatedWhileDisabled() {
        setEnableCustomLoggingFlag(false);
        CustomLogController customLogController = new CustomLogController();
        customLogController.divideByZeroException();
        
        Integer numberOfCustomLogs= [Select count() From Custom_Log__c];
        System.assertEquals(0, numberOfCustomLogs);
    }
    
    static testMethod void testDivideByZeroException(){
        setEnableCustomLoggingFlag(true);
        CustomLogController customLogController = new CustomLogController();
        customLogController.divideByZeroException();
        
        Integer numberOfCustomLogs= [Select count() From Custom_Log__c];
        Custom_Log__c customLog= [Select Class__c, Priority__c, Method__c, Message__c From Custom_Log__c LIMIT 1];
        System.assertEquals('CustomLogController', customLog.Class__c);
        System.assertEquals('divideByZeroException', customLog.Method__c);
        System.assertEquals(CustomLogging.WARNING, customLog.Priority__c);
    }
    
    static testMethod void testNullPointerException(){
        setEnableCustomLoggingFlag(true);
        CustomLogController customLogController = new CustomLogController();
        customLogController.nullPointerException();
        
        Integer numberOfCustomLogs= [Select count() From Custom_Log__c];
        Custom_Log__c customLog= [Select Class__c, Priority__c, Method__c, Message__c From Custom_Log__c LIMIT 1];
        System.assertEquals('CustomLogController', customLog.Class__c);
        System.assertEquals('nullPointerException', customLog.Method__c);
        System.assertEquals(CustomLogging.ERROR, customLog.Priority__c);
    }
}
Done. That's all.
So now if I click on any of the buttons in VisualForce page and EnableCustomLogging = true, I can see one record is getting inserted into the Custom_Log__c object like below-
If you have any feedback, please share. Thanks.

Share:

How to test Email Deliverability in Salesforce

In my current project, suddenly I started facing a problem where no email was coming to my organisation's email address. So I need to check with my organisation's network team, whether there is a problem. Salesforce.com sends email from 52 IP addresses. So, I need to provide the all 52 IPs to my network team. The intention is to check whether any of the 52 IP addresses are blocked in my organisation.

I thought of sharing the information here so that if someone face similar issue, this is what you should do first.
Once you go to Salesforce, go to Setup -> Administer -> Email Administration -> Test Deliverability. You will find a screen like this-
If you click on the send button, 52 emails will be delivered to your email address. From there you can get all the 52 IP addresses and share with your network team.

Hope this will help to do initial analysis. Any feedback is always welcome.


Share:

Before Delete Trigger in Salesforce

Requirement:
Write a Trigger on Employee custom Object -> The requirement is that the trigger should prevent Delete operation on Employee custom Object if a particular field(i.e., canDelete__c) is not checked.
Solution:

trigger DeleteEmployeeTrigger on Employee__c (before delete) {
   if(Trigger.isDelete){
      for(Employee__c anEmployee : Trigger.old){
         if(!anEmployee.canDelete__c){
             anEmployee.addError(Cannot delete Employee:  + anEmployee.First_Name__c +   + anEmployee.Last_Name__c);
         }
      }
   }
}

Share:

Order of Execution of Salesforce's Trigger

When a record is saved with an insert, update, or upsert statement, the following events occur in order:
  1. The original record is loaded from the database or initialized for in case of an insert statement.
  2. The new record field values are loaded from the request and overwrite the old values.
  3. System validation occurs, such as verifying that all required fields have a non-null value, and running any user-defined validation rules.
  4. All before triggers execute.
  5. The record is saved to the database, but not yet committed.
  6. All after triggers execute.
  7. Assignment rules execute.
  8. Auto-response rules execute.
  9. Workflow rules execute.
  10. If there are workflow field updates, the record is updated again.
  11. If the record was updated with workflow field updates, before and after triggers fire one more time (and only one more time).
  12. Escalation rules execute.
  13. All DML operations are committed to the database.
  14. Post-commit logic executes, such as sending email.
Here is the diagram -

The Pdf version is here. Click Here
It is always important to keep the order of execution in mind. Please provide your feedback.
Share:

Follow Me

Enter your email address:

Delivered by FeedBurner

Popular Posts

Labels

Salesforce (105) Apex (44) admin (27) ADM (20) visualforce (20) dev 501 (19) integration (18) learn salesforce (18) 501 (16) SOAP (13) lightning (12) tutorial (11) Certification. (9) javascript (8) Trigger (7) test class (7) unit testing (7) Sharing and Visibility (6) design pattern (6) report (6) security (6) trailhead (6) Advanced Admin (5) Certification (5) Kitchener Developer Group (5) New Features (5) SOQL (5) css (5) dashboard (5) debug (5) developer (5) formula (5) mobile (5) salesforce release (5) service cloud (5) solution management (5) use case (5) JSON (4) Lightning Experience (4) Salesforce DX (4) WebSphere (4) best practice (4) cast iron (4) component (4) deployment (4) github (4) html (4) polymer (4) profiles (4) responsive (4) tdd (4) ui (4) Advanced Apex (3) Architect (3) Live Chat (3) Online Event (3) Performance (3) Products (3) Role (3) Sales Cloud (3) Scratch Org (3) Study Notes. (3) Summer15 (3) Tips (3) Web Technology (3) dynamic apex (3) event (3) license (3) map (3) mapbox (3) singleton (3) version controlling (3) Bulkify (2) Data Architecture and Management Certification (2) Devops (2) Distributed Version Controlling (2) ES6 (2) Eclipse (2) Einstein (2) Enterprise Territory Management (2) Financial Services Cloud (2) Force.com IDE (2) Governor Limit (2) Groups (2) IBM (2) Implicit Sharing (2) JourneyToCTA (2) Kitchener User Group (2) Lightning Design System (2) Live Agent (2) Metadata (2) Opportunity (2) Price Book (2) REST (2) SOSL (2) Sharing (2) Spring 15 (2) Summer17 (2) Territory (2) ant (2) automation tool (2) basic (2) chatter (2) coding (2) communication (2) console (2) controller (2) documentation (2) flow (2) git (2) jquery (2) logging (2) object (2) permission (2) process builder (2) release (2) salesforce1 (2) strategy (2) xml (2) Action Plan (1) Action Plan Template (1) Agent Productivity (1) Analytics (1) Apex Sharing (1) Arrow (1) Asynchronous callout (1) Aura Framework (1) Bots (1) Browser (1) Bulk data load (1) CTA (1) Calendar (1) Canon (1) Case Management (1) Cheat Sheet (1) Classic (1) Community (1) Constructor (1) Contact Center (1) Continuation (1) Continuous Integration (1) Convert (1) Cookie (1) Custom Metadata (1) Custom Object (1) Customer (1) Decorator Design Pattern (1) Dev Hub (1) Diwali (1) Email (1) FSC (1) Function (1) Goals (1) Guide (1) Household (1) Ideas (1) Improvement (1) KPIs (1) Large Data Volume (1) LastModifiedDate (1) Lightning Web Component (1) Manual Sharing (1) Metrics (1) New (1) OOPS (1) OWD (1) Omni-Channel (1) Partner (1) Person Account (1) Photo (1) Pipeline (1) Platform Developer I (1) Presentation (1) Product Schedule (1) Profile (1) Promise (1) Prototype (1) Public Site (1) Query Plan (1) QuickReference (1) Reports (1) Retrieve (1) Role Hierarchy (1) SFDX (1) Salesforce Optimizer (1) Session (1) Sharing Rule (1) Sharing Sets (1) Site (1) Skills (1) Snap-ins (1) Spring 17 (1) Summer14 (1) Summer16 (1) Switch (1) SystemModStamp (1) User License (1) Users (1) Webservice (1) Winter'15 (1) Winter'17 (1) access (1) agile (1) app (1) approval process (1) aura (1) awesome (1) backup (1) bitbucket (1) book (1) campaign (1) change set (1) code (1) code coverage (1) configuration (1) csv (1) custom button (1) custom settings (1) customization (1) data loader (1) database (1) delegate Admin (1) describe (1) dom (1) dreamforce (1) duplicate (1) dynamic (1) equals (1) error (1) field-level security (1) folder (1) ftp (1) generic (1) gift (1) global describe (1) hashcode (1) import wizard (1) jenkins (1) keynote (1) long running requests (1) monitoring (1) mysql (1) page layout (1) personal (1) power of one (1) record type (1) relationship (1) request (1) review (1) sub-tab (1) tab (1) username (1) visual workflow (1) workflow (1)

Total Subscribers

Total Pageviews