Concepts or coding lessons of Salesforce that you can implement easily

Territory Management In Salesforce Can Increase Your Profit !!!

Territory management is important and critical to businesses of any size i.e. Large businesses, Medium and Small.
Territories align to sales team, defined on the basis of geography, sales potential, history, product-based, or a combination of factors.
With the help of Territory management, companies can make the most of sales team resources at minimum cost.

Territory management is an account sharing system that grants access to accounts based on the characteristics of the accounts. It enables your company to structure your Salesforce data and users the same way you structure your sales territories.

Mostly your salesforce organization has a private sharing model, and you want to grant access to accounts based on criteria then Territory management is a solution.

Key points of Territory Management:

1. An Opportunity can assigned to only one Territory.
2. One territory can have unlimited number of Users and Users can assign to any number of territories.
3. One territory can have unlimited number of Accounts and Accounts can assign to any number of territories.

Territory management in Opportunity object:


Requirement: Access TerritoryId of Opportunity in Apex class.
Solution: Easily you can access TerritoryId of Opportunity using Apex class. Once you enables Territory Management into salesforce organization then Territory lookup is created in Opportunity Object which is Standard Field.

Apex Code:

trigger OpportunityTerritoryManagement on Opportunity (before insert, before update) {
    if(Trigger.isBefore){
// Create Set which store opportunity`s territoryId
        Set<Id> setOpptyTerritoryIds = new Set<Id>();
        for(Opportunity objOppty : Trigger.New){
            if(Trigger.isInsert || Trigger.isUpdate){
              if(objOppty.TerritoryId != null){
                setOpptyTerritoryIds.add(objOppty.TerritoryId);
      }
            }
        }
        // Populate Territory details of assigned Territory of Opportunity.
        if(setOpptyTerritoryIds.size() > 0){
            Map<Id, Territory> mapOpptyTerritory = new Map<Id, Territory>([SELECT Id, Name, ParentTerritoryId, ForecastUserId, Description FROM Territory WHERE Id IN :setOpptyTerritoryIds]);
        }
    }
}


Territory management in Account object:


Requirement: Access TerritoryId of Account in Apex class.
Solution: This is not easy as Opportunity. You need to write extra code to access TerritoryId of Account using Apex class. If Territory Management is enable then Territory lookup create on Opportunity object not on Account object. You need extra queries on different object to access TerritoryId of Account.

Steps to Access TerritoryId of Account in Apex class:
1. Query in Account Share object.
2. Query in Group object from where access RelatedId.
3. Query in Territory object to Populate Territory details of assigned Territory of Account.

Apex Code:

trigger AccountTerritoryManagement on Account (before update) {
  if(Trigger.isBefore){
    // Create Set which store Account Territory Id
    Set<Id> setAccTerritoryIds = new Set<Id>();
    Map<Id, Id> mapAccountShare = new Map<Id, Id>();
    Map<Id, Id> mapGroup = new Map<Id, Id>();
    Map<Id, Territory> mapUserTerritory = new Map<Id, Territory>();
    
    //Query in Account Share object
    List<AccountShare> listOfAccountShare = [SELECT Id, UserOrGroupId, AccountId FROM AccountShare WHERE RowCause = 'Territory' AND AccountId IN :Trigger.newMap.keyset()];
    
    for(AccountShare objAcctShare : listOfAccountShare){
      mapAccountShare.put(objAcctShare.AccountId, objAcctShare.UserOrGroupId);         
    }   
    
    //Query in Group object from where access RelatedId
    List<Group> listOfGroup = [SELECT Id, RelatedId FROM Group WHERE Type = 'Territory' AND Id IN :mapAccountShare.Values()];
    
    //Map of Group object
    for(Group objGroupRecord : listOfGroup){
      mapGroup.put(objGroupRecord.Id, objGroupRecord.RelatedId);         
    }
    
    // Populate Territory details of assigned Territory of Account.
    if(!mapGroup.isEmpty()){
      //Query in Territory object
      Map<Id, Territory> mapTerritories = new Map<Id, Territory>([SELECT Id, Name, ParentTerritoryId, ForecastUserId, Description FROM Territory WHERE Id IN:mapGroup.Values()]);
    }
  }
}

If you want more details on Territory Management the check Salesforce Documentation.

Enjoy! If you have any questions, comments etc. please feel free to let me know. As always, please feel free to get in touch me as I would be more than happy to assist you with any of your Salesforce development needs.

Next Post: Import CSV file In Salesforce using Apex in 3 Easiest Steps

Import CSV file In Salesforce using Apex in 3 Easiest Steps

Salesforce does not read the excel file into apex. To overcome for this either we can covert excel file to CSV and import csv file using below code.

We can import data using data loader But sometime there is requirement when end users do not want to use Apex Data loader. 

Client want custom page to load data in salesforce.

Here I am explaining Import CSV file In Salesforce using Apex. Below is the code snippet which import CSV file from apex. In this blog, I have one visual force page and one controller associated with it. 

Visual force page have Import Accounts into Salesforce button. 
Once user click on the button, I am sending email using apex code. 

Step 1: Go to setup and Create one Apex Controller

public class importDataFromCSVController {

  public Blob csvFileBody{get;set;}
  public String csvAsString{get;set;}
  public String[] csvFileLines{get;set;}
  public List<account> accountlist{get;set;}
  public importDataFromCSVController(){
    csvFileLines = new String[]{};
    accountlist= New List<Account>(); 
  }
  
  public void importCSVFile(){
       try{
             // Read CSV file body and store it in variable
              csvAsString = csvFileBody.toString();
  
            // Split CSV String to lines
             csvFileLines = csvAsString.split('\n'); 
           
            // Iterate CSV file lines and retrieve one column at a time.
             for(Integer i=1; i < csvFileLines.size(); i++){
               Account accObj = new Account() ;
               String[] csvRecordData = csvFileLines[i].split(',');
               accObj.name = csvRecordData[0] ;             
               accObj.accountnumber = csvRecordData[1];
               accObj.Type = csvRecordData[2];
               accObj.AccountSource = csvRecordData[3];   
               accObj.Industry = csvRecordData[4];                                                                             
               accountlist.add(accObj);   
             }
            // if all correct then insert Account into Org
             if(accountlist.size()>0)
             insert accountlist;
        }
        catch (Exception e)
        {
            ApexPages.Message errorMessage = new ApexPages.Message(ApexPages.severity.ERROR,'An error has occured while importing data into Salesforce. Please make sure input csv file is correct');
            ApexPages.addMessage(errorMessage);
        }  
  }
}

Step 2: Create Visual force Page

<apex:page controller="importDataFromCSVController" sidebar="false" showHeader="false">
    <apex:form >
        <apex:pagemessages />
        <apex:pageBlock >
            <apex:pageBlockSection columns="4"> 
                  <apex:inputFile value="{!csvFileBody}"  filename="{!csvAsString}"/>
                  <apex:commandButton value="Import Accounts into Salesforce" action="{!importCSVFile}"/>
            </apex:pageBlockSection>
        </apex:pageBlock>
        <apex:pageBlock >
           <apex:pageblocktable value="{!accountlist}" var="acc">
              <apex:column value="{!acc.name}" />
              <apex:column value="{!acc.AccountNumber}" />
              <apex:column value="{!acc.Type}" />
              <apex:column value="{!acc.Phone}" />
              <apex:column value="{!acc.Fax}" />
        </apex:pageblocktable>
     </apex:pageBlock>
   </apex:form>
</apex:page>

Step 3: Download csv file into local machine. Click here to download CSV file. 

CSV will be like:
















Visualforce page have Preview button, you can click on that Preview button. 
OR 
Go to an URL and type or you can paste below URL (Change the salesforceinstancename with your salesforce org URL).

Go to : https://salesforceinstancename/apex/Import_Data_From_CSV .
Load the downloaded CSV file and Click on Import Accounts into Salesforce button

Output:










Note: If the CSV file size are large then you will hit a apex governor limit such as the the 6M byte heap space or the 10 seconds of CPU or the 10,000 rows of DML or the "Regex too complicated" error when importing a large amount of data from a CSV file.

There are other ways to import data into Salesforce.
Check out my other blog: 5 Quick Steps To Install Apex Data Loader.


Enjoy! If you have any questions, comments etc. please feel free to let me know. As always, please feel free to get in touch me as I would be more than happy to assist you with any of your Salesforce development needs.

Next post: Check out Salesforce Daily Limit Only in 5 Simplest Steps

Check out Salesforce Daily Limit Only in 5 Simplest Steps

While writing any code in Salesforce, every developer need to play in the Box, in Salesforce language we can say it as Daily Limits.

Here is the simplest way to check your Salesforce org`s daily limit.


Follow below steps:


1. Log in into your Salesforce Environment.
2. Go to Workbench link: https://workbench.developerforce.com/login.php
3. Select Salesforce Environment, API version and Accept the Terms and conditions. 
4. Go to utilities Tab and select REST ExplorerThen Click on Execute button .



5. Select limits: /services/data/v37.0/limits
Output :



Salesforce Governor Limits:

As you aware that, Salesforce is multitenant platform. Multitenant is a software architecture in which a single instance of software runs on a server and serves multiple user groups. Group of users who share a common access with specific privileges to the software instance.
Governor execution limits ensure the efficient use of resources on the Force.com multitenant platform. Because Apex runs in a multitenant environment, the Apex runtime engine strictly enforces limits to ensure that runaway Apex code or processes don’t monopolize shared resources. If some Apex code ever exceeds a limit, the associated governor issues a runtime exception that cannot be handled.

The Apex limits, or governors, track and enforce the statistics outlined in the following tables and sections.
  • Per-Transaction Apex Limits
  • Per-Transaction Certified Managed Package Limits
  • Force.com Platform Apex Limits
  • Static Apex Limits
  • Size-Specific Apex Limits
  • Miscellaneous Apex Limits
In this blog, I have added few of the Governer Limits mentioned below:

1. Total number of SOQL queries issued: 
  •    Synchronous Limit = 100
  •    Asynchronous Limit = 200
2. Total number of records retrieved by SOQL queries : 50,000
3. Total number of records retrieved by Database.getQueryLocator : 10,000
4. Total number of SOSL queries issued : 20
5. Total number of records retrieved by a single SOSL query : 2,000
6. Total number of DML statements issued : 150
7. Total number of callouts : 100 (include Web Service and HTTP Request calls in a transaction)
8. Maximum timeout for all callouts : 120 seconds or 2 minutes (include Web Service and HTTP Request calls in a transaction)
9. Maximum number of @future annotation methods allowed : 50
10. Maximum number of Apex jobs added to the queue with System.enqueueJob : 50
11. Total number of sendEmail methods allowed : 10
12. Total heap size : 6 MB or 12 MB
13. Maximum execution time for each Apex transaction : 600 seconds or 10 minutes
14. Maximum number of push notification method calls allowed per Apex transaction : 10
15. Maximum number of push notifications that can be sent in each push notification method call : 2,000
16. Email services heap size is 36 MB.
17. The maximum number of asynchronous Apex method executions per a 24-hour period : 250,000 or the number of user licenses in your organization multiplied by 200, whichever is greater.
18. Maximum number of Apex classes scheduled concurrently : 100
19. Maximum number of batch Apex jobs in the Apex flex queue that are in Holding status : 100
20. Maximum number of batch Apex jobs queued or active concurrently : 5
21. Event Reports : The maximum number of records that an event report returns for a user who is not a system administrator is 20,000; for system administrators, 100,000.
22. Inbound Email Services: Maximum Number of Email Messages Processed : Number of user licenses multiplied by 1,000; maximum 1,000,000
23. Inbound Email Services: Maximum Size of Email Message : 10 MB

There are some Size-Specific Apex Limits. Check below:

1. Maximum number of characters for a class : 1 million
2. Maximum number of characters for a trigger : 1 million
3. Maximum amount of code used by all Apex code in an organization : 3 MB
4. Method size limit : 65,535 bytecode instructions in compiled form

Enjoy! If you have any questions, comments, please feel free to let me know.
As always, please feel free to get in touch me as I would be more than happy to assist you with any of your Salesforce development needs.

Next post: Learning Pagination In Salesforce Is Not Difficult At All ! You Just Need 3 Easy Steps


More Salesforce Blogs:

Check out Salesforce Daily Limit Only in 5 Simplest Steps
Learning Pagination In Salesforce Is Not Difficult At All ! You Just Need 3 Easy Steps
How To Learn Get Field Values From Visualforce Page To Apex Class Controller Without Losing Your Mind
Main Difference Between ISBLANK And ISNULL in Salesforce
How To Get Total Amount Of Records Processed In Batch Job In 10 Minutes And Still Look Your Best 
Export VisualForce Data into Excel Sheet in 3 Easiest Steps
7 Easy Steps to Generate Apex Class From WSDL In Salesforce
Simplest Way To Find Number of Days Between Two Dates in Salesforce
3 Easy Steps To Send Emails With Attachment From Your Apex Class In Salesforce
How Insert Comma In Formula Fields Can Help You Improve Your Productivity
Simple Guidance For You In Access Of Subquery Field Value Using Apex - Upwards Traversal.
Access Subquery Field Value Using Apex in 2 Easy Steps- Downwards Traversal

How Learning Enable Inline Editing In Visual Force Pages Could Save Your Money And Time



Enjoy! If you have any questions, comments etc. please feel free to let me know. As always, please feel free to get in touch me as I would be more than happy to assist you with any of your Salesforce development needs.