Tuesday, May 21, 2013

Delete Custom Button in List Views

Salesforce.com does not provide the functionality to delete records in batch / bulk size in List Views. Like in Salesforce.com we have standard / out-of-the box buttons "Change Owner", "Accept" and "Change Status". Unfortunately we do not have "Delete Lead" button in List Views but you can add it in List Views by just writing a small code snippet in JavaScript.

Sample Code:



{!REQUIRESCRIPT("/soap/ajax/27.0/connection.js")}
{!REQUIRESCRIPT("/soap/ajax/27.0/apex.js")}

//To show the alert pop up on the page
function log(message) {
alert(message);
}

//string for the URL of the current page
var url = parent.location.href;
//grabs the Lead records that the user is requesting to delete
var records = {!GETRECORDIDS($ObjectType.Lead)};
//if the button was clicked but there was no record selected
if (records[0] == null) {
//alert the user that they didn't make a selection
alert("Please select at least one record to update.");
} else {
//otherwise, there was a record selection
var delResult = sforce.connection.deleteIds(records);
if (delResult[0].getBoolean("success")) {
log(records.length+" record(s) have been deleted.");
}
else{
log("Failed to delete records.");
}
//refresh the page
parent.location.href = url;
}

Perform DML Using External ID

Perform DML Using External ID

If you want to create a Contact associate with an Account without using AccountId field then you must have an External Id on Account object in order to create a Contact record.

It is not Efficient Code:

The following code is creating a Contact record by querying an Account record. However, because it uses a SOQL query, it is not as efficient. If this code was called multiple times, it could reach the execution limit for the maximum number of SOQL queries.
Sample Code:
Account refAcct = [SELECT Id FROM Account WHERE externalId__c='12345' LIMIT 1];
Contact c = new Contact(Account = refAcct.Id);
insert c;

Efficient Code:
The following code is equivalent to the code above. However, because it does not use a SOQL query, it is efficient.
Sample Code:
Account refAcct = new Account(externalId__c = '12345');
Contact c = new Contact(Account = refAcct, LastName = 'Kay');
insert c;
Note: This inserts a new contact with the AccountId equal to the account with the external_id equal to ‘12345’. If there is no such account, the insert fails.

Sunday, May 5, 2013

Salesforce Mobile SDK

Visualforce Page Sample Code


<!--
        Salesforce Developer Meetup Karachi April 21-27, 2013.
        Salesforce Mobile Developer Week.
        Worldwide Developer Gathering.
        April 21-27, 2013
     
        Salesforce Mobile Web(HTML5) Apps
-->
<apex:page docType="html-5.0" sidebar="false" showHeader="false" standardStylesheets="false" cache="false" controller="SalesforceDevMeetupKarachiCtrl">
<html>
    <apex:stylesheet value="{!URLFOR($Resource.MobileSample_Resources_jQueryMobile, 'jquery.mobile-1.3.0.min.css')}"/>
    <apex:includeScript value="{!URLFOR($Resource.MobileSample_Resources_jQueryMobile, 'jquery-1.9.1.min.js')}"/>
    <apex:includeScript value="{!URLFOR($Resource.MobileSample_Resources_jQueryMobile, 'jquery.mobile-1.3.0.min.js')}"/>
    <apex:includeScript value="{!URLFOR($Resource.MobileSample_Resources_jQueryMobile, 'ForceTk.js')}"/>
<head>
    <title>Salesforce Developer Meetup Karachi April 21-27, 2013</title>
 
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />  
 
    <script type="text/javascript">
        var $j = jQuery.noConflict();
        var leadRecs = new Array();
     
        var restAPIClient = new forcetk.Client();
        restAPIClient.setSessionToken('{!$Api.Session_ID}');
     
        $j(document).ready(function(){
            getAllLeads();
        });
         
        //Query and get list of Leads to show        
        function getAllLeads(){
            $j.mobile.showPageLoadingMsg();
            var q = "select id, firstName, lastName, phone, email, company, LeadSource, Status from Lead where isconverted = false order by FirstName";
            restAPIClient.query(q ,
            function(response){
                showLeads(response.records);
            });                              
        }

        //Show list of Leads to convert it into Account, Contact and Opportunity                  
        function showLeads(records){  
            $j('#leadListView').empty();
            leadRecs.length = 0;                            
            for(var i = 0; i < records.length; i++) { leadRecs[records[i].Id] = records[i]; }
            var x = 0;
            $j.each(records,
            function() {
                var newLi = $j('<li></li>');                              
                var newLink = $j('<a id="' +this.Id+ '" data-transition="flip">' +this.FirstName+ ' '+this.LastName+ '</a>');
                newLink.click(function(e){
                    e.preventDefault();
                    $j.mobile.showPageLoadingMsg();
                    $j('#fNameHeader').val(leadRecs[this.id].FirstName);
                    $j('#lNameHeader').val(leadRecs[this.id].LastName);
                    $j('#fName').val(leadRecs[this.id].FirstName);
                    $j('#lName').val(leadRecs[this.id].LastName);
                    $j('#phone').val(leadRecs[this.id].Phone);
                    $j('#email').val(leadRecs[this.id].Email);
                    $j('#company').val(leadRecs[this.id].Company);
                    $j('#leadSource').val(leadRecs[this.id].LeadSource);
                    $j('#status').val(leadRecs[this.id].Status);
                    $j('#leadId').val(leadRecs[this.id].Id);
                    $j('#error').html('');                  
                    $j.mobile.changePage('#leaddetailpage', {changeHash: true});
                });
                newLi.append(newLink);          
                newLi.appendTo('#leadListView');
                x++;
            });                                
            $j.mobile.hidePageLoadingMsg();
            $j('#leadListView').listview('refresh');
        }
     
        //Convert Lead into Account, Contact and Opportunity
        function convertLead(){
            var leadToConvert =  $j('#leadId').val();
            //Invoke JavaScript Remoting function convertLead in Apex controller to convert Lead into Account, Contact and Opportunity
            SalesforceDevMeetupKarachiCtrl.convertLead(leadToConvert,
            //Show the details of new Account created by convet Lead process
            function(result, e){
                $j.mobile.showPageLoadingMsg("b", "Converting Lead ...", true);
                $j('#acctName').val(result.Name);
                $j('#acctType').val(result.Type);
                $j('#acctId').val(result.Id);
                $j.mobile.hidePageLoadingMsg();            
                $j.mobile.changePage('#newconvertedaccountcontactopportunity', {changeHash: true});
                getUser(result);
                getContact(result);
                getOpportunity(result);
            });                                                                                                  
        }
     
        //Get and show the User Name associated with the Account Owner Id
        function getUser(result){
            var acctOwnerId = result.OwnerId;
            //Invoke JavaScript Remoting function getUser in Apex controller to get the User Name associated with the Account Owner Id
            SalesforceDevMeetupKarachiCtrl.getUser(acctOwnerId,
            //Show the User Name associated with the Account Owner Id
            function(result, e){
                $j.mobile.showPageLoadingMsg("b", "Converting Lead ...", true);
                $j('#acctOwner').val(result.Name);
                $j.mobile.hidePageLoadingMsg();            
                $j.mobile.changePage('#newconvertedaccountcontactopportunity', {changeHash: true});
            });                                      
        }
     
        //Get and show the details of new Contact created by convet Lead process
        function getContact(result){
            var newacctId = result.Id;
            //Invoke JavaScript Remoting function getContact in Apex controller to get the details of new Contact created by convet Lead process
            SalesforceDevMeetupKarachiCtrl.getContact(newacctId,
            //Show the details of new Contact created by convet Lead process
            function(result, e){
                $j.mobile.showPageLoadingMsg("b", "Converting Lead ...", true);
                $j('#contFirstName').val(result.FirstName);
                $j('#contLastName').val(result.LastName);
                $j('#contTitle').val(result.Title);
                $j('#contPhone').val(result.Phone);
                $j('#contEmail').val(result.Email);
                $j('#contId').val(result.Id);
                $j.mobile.hidePageLoadingMsg();            
                $j.mobile.changePage('#newconvertedaccountcontactopportunity', {changeHash: true});
            });                                      
        }
     
        //Get and show the details of new Opportunity created by convet Lead process          
        function getOpportunity(result){
            var newacctId = result.Id;
            //Invoke JavaScript Remoting function getOpportunity in Apex controller to get the details of new Opportunity created by convet Lead process
            SalesforceDevMeetupKarachiCtrl.getOpportunity(newacctId,
            //Show the details of new Opportunity created by convet Lead process
            function(result, e){
                $j.mobile.showPageLoadingMsg("b", "Converting Lead ...", true);
                $j('#opptyName').val(result.Name);
                $j('#opptyStageName').val(result.StageName);
                $j('#opptyCloseDate').val(result.Close_Date__c);
                $j('#opptyAmount').val(result.Amount);
                $j('#opptyId').val(result.Id);
                $j.mobile.hidePageLoadingMsg();            
                $j.mobile.changePage('#newconvertedaccountcontactopportunity', {changeHash: true});
            });                                      
        }
     
        function refreshThePage(){
            $.mobile.loadPage("/apex/VFSalesforceDevMeetupKarachi");
        }

        function displayError(e){
            var error = JSON.parse(e.responseText);
            $j('#error').html(error[0].message);
        }                              
    </script>  

    <style type="text/css" media="screen">
    th {
        text-align: right;
    }
    td {
        text-align: left;
        padding: 5px; 10px; 5px; 5px;
        color: #6099c6;
        font-weight: bold;
     }
    </style>
     
</head>

<body>
    <div data-role="page" data-theme="b" id="listpage">              
        <div data-role="header" data-theme="b" data-position="fixed">
            <h2>Salesforce Mobile Developer Week</h2>
            <h4>Worldwide Developer Gathering</h4>
            <h4>April 21-27, 2013</h4>                          
        </div>
     
        <!-- Show list of Leads -->
        <div data-role="content" id="leadList">
            <h2>Search Salesforce Leads</h2>          
            <ul id="leadListView" data-filter="true" data-inset="true" data-role="listview"
            data-theme="c" data-dividertheme="b" data-autodividers="true" data-filter-placeholder="Search Salesforce Leads">
            </ul>
        </div>                      
    </div>  
 
    <!-- Show Lead Detail -->      
    <div data-role="page" data-theme="b" id="leaddetailpage">
        <div data-role="header" data-position="fixed" data-theme="b">
            <h1><output name="fNameHeader" id="fNameHeader"></output> <output name="lNameHeader" id="lNameHeader"></output>'s Detail</h1>
            <a href='#listpage' id="back2Home" data-role="button" class='ui-btn-left' data-icon="home" data-transition="slide" onClick="refreshThePage();">Back to Home</a>  
        </div>          

        <div data-role="content">
            <a href="#" data-role="button" data-icon="star" data-iconpos="left" style="background: #E29221; color: white;">Lead</a>
            <table>                            
            <tr>
            <th>First Name</th>
            <td><output name="fName" id="fName"></output></td>
            </tr>              
            <tr>
            <th>Last Name</th>
            <td><output name="lName" id="lName"></output></td>
            </tr>              
            <tr>
            <th>Company</th>
            <td><output name="company" id="company"></output></td>
            </tr>                            
            <tr>
            <th>Lead Source</th>
            <td><output name="leadSource" id="leadSource"></output></td>
            </tr>                            
            <tr>
            <th>Lead Status</th>
            <td><output name="status" id="status"></output></td>
            </tr>
            <tr>
            <th>Phone</th>                  
            <td><a href="tel:"><output name="phone" id="phone"></output></a></td>
            </tr>              
            <tr>
            <th>Email</th>
            <td><a href="mailto:"><output name="email" id="email"></output></a></td>
            </tr>                            
            <tr>
            <th></th>
            <td>
            <h2 style="color:red" id="error"></h2><br/>
            <input type="hidden" id="leadId" />
            </td>
            </tr>
            </table>
            <hr size="2"/>
            <center>
            <a href="#newconvertedaccountcontactopportunity" id="convertLead" data-theme="b" data-role="button" data-icon="star" data-direction="reverse" data-transition="flip" class='ui-btn-left' onClick="convertLead();" >Convert Lead</a>
            </center>
        </div>                        
    </div>
         
    <!-- Show detail of new Account, Contact and Opportunity created by convert Lead process -->
    <div data-role="page" data-theme="b" id="newconvertedaccountcontactopportunity">  
        <div data-role="header" data-position="fixed" data-theme="b">
            <h1>Converted Lead Detail</h1>
            <a href='#listpage' id="back2Home" data-role="button" class='ui-btn-left' data-icon="home" data-transition="slide" onClick="refreshThePage();">Back to Home</a>
        </div>
     
        <!-- Show detal of new Account created by convert Lead process -->
        <div data-role="content">
            <a href="#" data-role="button" data-icon="star" data-iconpos="left" style="background: #236EBC; color: white;">Account</a>
            <div data-role="fieldcontain">
                <table>
                <tr>
                <th>Account Owner</th>
                <td><output name="acctOwner" id="acctOwner"></output></td>
                </tr>
                <tr>
                <th>Account Name</th>
                <td><output name="acctName" id="acctName"></output></td>
                </tr>
                <tr>
                <th>Account Type</th>
                <td><output name="acctType" id="acctType"></output></td>
                </tr>
                </table>
            </div>
            <h2 style="color:red" id="error"></h2><br/>
            <input type="hidden" id="acctId" />
        </div>  
        <hr size="2"/>

        <!-- Show detal of new Contact created by convert Lead process -->        
        <div data-role="content">
            <a href="#" data-role="button" data-icon="star" data-iconpos="left" style="background: #55448B; color: white;">Contact</a>
            <div data-role="fieldcontain">
                <table>
                <tr>
                <th>First Name</th>
                <td><output name="contFirstName" id="contFirstName"></output></td>
                </tr>
                <tr>
                <th>Last Name</th>
                <td><output name="contLastName" id="contLastName"></output></td>
                </tr>
                <tr>
                <th>Title</th>
                <td><output name="contTitle" id="contTitle"></output></td>
                </tr>
                <tr>
                <th>Phone</th>
                <td><output name="contPhone" id="contPhone"></output></td>
                </tr>
                <tr>
                <th>Email</th>
                <td><output name="contEmail" id="contEmail"></output></td>
                </tr>
                </table>
            </div>
            <h2 style="color:red" id="error"></h2><br/>
            <input type="hidden" id="contId" />
        </div>  
        <hr size="2"/>
     
        <!-- Show detal of new Opportunity created by convert Lead process -->  
        <div data-role="content">
            <a href="#" data-role="button" data-icon="star" data-iconpos="left" style="background: #E3BF30; color: white;">Opportunity</a>
            <div data-role="fieldcontain">
                <table>
                <tr>
                <th>Opportunity Name</th>
                <td><output name="opptyName" id="opptyName"></output></td>
                </tr>
                <tr>
                <th>Opportunity Stage</th>
                <td><output name="opptyStageName" id="opptyStageName"></output></td>
                </tr>
                <tr>
                <th>Opportunity Close Date</th>
                <td><output name="opptyCloseDate" id="opptyCloseDate"></output></td>
                </tr>
                <tr>
                <th>Opportunity Amount</th>
                <td><output name="opptyAmount" id="opptyAmount"></output></td>
                </tr>
                </table>
            </div>
            <h2 style="color:red" id="error"></h2><br/>
            <input type="hidden" id="opptyId" />
        </div>          
        <center>
        <a href='#listpage' id="back2Home" data-role="button" class='ui-btn-left' data-icon="home" data-transition="slide" onClick="refreshThePage();">Back to Home</a>
        </center>
    </div>  
</body>
</html>  
</apex:page>




Visualforce Controller Sample Code
/*
* @Created Date : 4/26/2013
* @Modified Date : 4/26/2013
* @Modified By : Salesforce Developer Meetup Karachi User
* @Purpose: 
* (a) To show Salesforce Leads.
* (b) To show details of Leads.
* (c) To convert Lead into Account, Contact and Opportunity.
* (d) To show newly created Account, Contact and Opportunity created by Convert Lead process.
*/
public with sharing class SalesforceDevMeetupKarachiCtrl{

    //Controller constructor
    public SalesforceDevMeetupKarachiCtrl(){
    }
    
    //Remote Function to convert Lead into Account, Contact and Opportunity
    @RemoteAction
    public static Account convertLead(String leadId){
        //Query Lead record to convert Lead into Account, Contact and Opportunity
        Lead lead = [SELECT Id FROM Lead WHERE Id =:leadId LIMIT 1];

        
        //Query Lead status to convert Lead into Account, Contact and Opportunity
        LeadStatus convertStatus = [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true LIMIT 1];

        //Convert Lead into Account, Contact and Opportunity
        Database.LeadConvert lc = new database.LeadConvert();
        lc.setLeadId(lead.id);        
        lc.setConvertedStatus(convertStatus.MasterLabel);        
        Database.LeadConvertResult lcr = Database.convertLead(lc);
        System.assert(lcr.isSuccess());

        //Query new Account record created by created by convert Lead process        
        Account newConvertedAccount = [SELECT Id, Name, Type, Owner.Name, OwnerId FROM Account WHERE Id =:lcr.getAccountId() LIMIT 1];                 
        return newConvertedAccount;
    }
    
    //Remote Function to get the User Name associated with the Account Owner Id
    @RemoteAction
    public static User getUser(String userId){
        //Query User record for Account Owner       
        User user = [SELECT Id, Name FROM User WHERE Id =:userId LIMIT 1];
        return user;
    }

    //Remote Function to get the details of new Contact created by convert Lead process
    @RemoteAction
    public static Contact getContact(String accountId){
        //Query new Contact record created by created by convert Lead process        
        Contact cont = [SELECT Id, FirstName, LastName, Title, Email, Phone FROM Contact WHERE AccountId =:accountId LIMIT 1];
        return cont;
    }

    //Remote Function to get the details of new Opportunity created by convert Lead process
    @RemoteAction
    public static Opportunity getOpportunity(String accountId){
        //Query new Opportunity record created by created by convert Lead process        
        Opportunity oppty = [SELECT Id, Name, StageName, Close_Date__c, Amount FROM Opportunity WHERE AccountId =:accountId LIMIT 1];
        oppty.Amount = 100.00;
        update oppty;
        return oppty;
    }
}

AccountShare Object


Recipe: Definition of AccountShare Object

Discussion:
At times, users may need to manage their record Sharing tables via the API.
For example, if an administrator wishes to remove all manually-assigned Territories from Accounts or Opportunities, it may be inconvenient to manage this change via the GUI.  Instead, the admin may prefer to delete these references in mass.  This would be done by accessing the Share tables through the API (for example, via the DataLoader).  The administrator would look for all records with a ROWCAUSE of TerritoryManual and delete these records.

Explanations of Fields of AccountShare object:
When accessing "Share" tables via the API, there are a number of columns that may not be immediately familiar.  Below are descriptions of each column and the possible values (the following refer to the AccountShare table, but the structure is very similar for other Share tables, such as OpportunityShare):

1. ID
This is the unique record ID for the AccountShare record.

2. ACCOUNTID
This column stores the IDs for the Account records being shared.  There may be multiple rows with the same AccountID value, as each Account record might be shared with more than one User or Group.

3. USERORGROUPID
This column stores the IDs for the User or Group to whom the Account record is shared.

4. ACCOUNTACCESSLEVEL
This column determines the access level granted for the Account record to the specified User or Group.
Values are:
A. All (Full access).
B. Edit (Read/Write).
C. Read (ReadOnly).

5. OPPORTUNITYACCESSLEVEL
This column determines the access level granted - for the Opportunities associated with this Account record - to the specified User or Group.
Values are:
A. Edit (Read/Write).
B. Read (ReadOnly).
C. None (No sharing granted).

6. CASEACCESSLEVEL
This column determines the access level granted - for the Cases associated with this Account record - to the specified User or Group.
Values are:
A. Edit (Read/Write).
B. Read (ReadOnly).
C. None (No sharing granted).

7. CONTACTACCESSLEVEL
This column determines the access level granted - for the Contacts associated with this Account record - to the specified User or Group.
Values are:
A. Edit (Read/Write)
B. Read (ReadOnly).
C. None (No sharing granted).

8. ROWCAUSE
This column explains *why* the Account record is shared to the specified User or Group.
Values are:
A. Owner (the specified User is the record owner).
B. ImplicitParent (a child record related to this Account is owned by the specified User).
C. Team (the specified User is an Account Team member).
D. Manual (sharing was manually granted to the specified User).
E. TerritoryManual (the Account record was manually assigned to a Territory).
F. Territory (a Territory assignment rule granted access for this Account record to the specified Group.  Note: records marked as Territory cannot be edited/deleted via DataLoader/API).

Reference Help Link for Account Share Object:
How do I interpret 'Share' tables?
http://help.salesforce.com/apex/HTViewSolution?id=000004856&language=en_US

Saturday, May 4, 2013

Territory Management in Apex


Recipe: Territory Management
Territory management is 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.
If you want to use territory management in Apex then you should read this document for limitations and territory functionality in Apex.

Relationships among Territory, Account, Opportunity and User objects:
a) A territory can have unlimited number of users, and a user can be assigned to an unlimited number of Territories.
b) A territory can have unlimited number of accounts, and an account can be assigned to an unlimited number of territories.
c) An Opportunity can only be assigned to a Territory.

Territories in Opportunity object:

Problem:
If you want to access the territory field of Opportunity in Apex you can access it easily. Because the field Territory on Opportunity object is exactly present in Opportunity object.

Solution with Example Code:
/*
Author: @Abrar Haq
Purpose:
    (a)To populate Parent Territory Name and Territory User Name of assigned Territory of Opportunity.
*/
trigger OpportunityTrg on Opportunity (before insert) {
    if(Trigger.isBefore){
        /* Declaration of collection data types */
        Set<Id> setOfTerritoryIds = new Set<Id>();

        for(Opportunity oppty : Trigger.New){
            if(Trigger.isInsert){
                if(oppty.TerritoryId != null){
                    setOfTerritoryIds.add(oppty.TerritoryId);
                }
            }
        }

        /*
            (b)To populate Parent Territory Name of assigned Territory of Opportunity.
        */    
        if(setOfTerritoryIds.size() > 0){
            Map<Id, Territory> mapOfTerritory = new Map<Id, Territory>([Select t.RestrictOpportunityTransfer, t.ParentTerritoryId, t.OpportunityAccessLevel, t.Name, t.MayForecastManagerShare, t.Id, t.ForecastUserId, t.Description, t.ContactAccessLevel, t.CaseAccessLevel, t.AccountAccessLevel From Territory t Where Id IN :setOfTerritoryIds]);
        }
    }
}


Territories in Account object:

Problem:
If you want to access to the Territories field on Account then you need to do extra work. Because Territories field on Account is not present in Account object. You have to query in different objects to get the assigned territory of Account.

Algorithm (Pseudo Code):
1) Query AccountShare object where AccountId = Trigger.New (Account Ids)
where RowCause = 'Territory' (Note: If Account has assigned via Territory Assignment Rules).
where RowCause = 'TerritoryManual' (Note: If Account has assigned via “Manually Assigned Accounts” related list on Territory detail page or AccountShare record has created in Apex Code).
2) Query Group object where Id = AccountShare.UserOrGroupId
3) Query Territory object where Id = Group.RelatedId
4) Query UserTerritory object where Id = Territory.UserId


Solution with Example Code:
/*
Author: @Abrar Haq
Purpose:
    (a)To populate Parent Territory Name and Territory User Name of assigned Territory of Account.
*/
trigger AccountTrg on Account (before update){
    if(Trigger.isBefore){
        /* Declaration of collection data types */
        Set<Id> setOfAccountIds = new Set<Id>();

        for(Account acct : Trigger.New){
            if(Trigger.isUpdate){
                if(acct.Id != null){
                    setOfAccountIds.add(acct.Id);
                }
            }
        }

        /*
            (b) To populate Parent Territory Name of assigned Territory of Opportunity.
        */    
        if(setOfAccountIds.size() > 0){

        /* Declaration of collection data types */
Map<Id, Id> mapOfAccountShare = new Map<Id, Id>();
       Map<Id, Id> mapOfGroup = new Map<Id, Id>();
       Map<Id, Territory> mapOfUserTerritory = new Map<Id, Territory>();


(1)

//Query in Account Share object
    /*
    Those Accounts which are assigned via Territory Assignment Rules.
You can query those Accounts by filtering RowCause = 'Territory' in AccountShare object query.
    */
    List<AccountShare> listOfAccountShare =
    [Select Id, UserOrGroupId, AccountId from AccountShare where RowCause = 'Territory' and AccountId IN :setOfAccountIds];

    //Query in Account Share object
    /*
    Those Accounts which are assigned via Manually Assigned Accounts related list on Territory detail page or create an AccountShare record in Apex code.
    You can query those Accounts by filtering RowCause = 'TerritoryManual' in AccountShare object query.
    */
    List<AccountShare> listOfAccountShare =
    [Select Id, UserOrGroupId, AccountId from AccountShare where RowCause = 'TerritoryManual' and AccountId IN :setOfAccountIds];

//Map of Account Share
    for(AccountShare acctShare : listOfAccountShare){
    mapOfAccountShare.put(acctShare.AccountId, acctShare.UserOrGroupId);        
    }      

(2)

    //Query in Group object            
    List<Group> listOfGroup = [Select Id, RelatedId from Group where Type='Territory' and Id IN :mapOfAccountShare.Values()];

//Map of Group object
    for(Group groupRecord : listOfGroup){
    mapOfGroup.put(groupRecord.Id, groupRecord.RelatedId);        
    }

(3)

    //Query in Territory object
    //Map<Id, Territory> mapOfTerritories =
    new Map<Id, Territory>([select id, name, ParentTerritoryId from Territory where Id IN:mapOfGroup.Values() ]);      

(4)

    //Query in User Territory object
    List<UserTerritory> listOfUserTerritory = [Select u.UserId, u.TerritoryId, u.IsActive, u.Id From UserTerritory u WHERE IsActive = true AND TerritoryId IN :mapOfTerritories.KeySet()];

//Map of User Territory object
    for(UserTerritory userTerritory : listOfUserTerritory){
    mapOfUserTerritory.put(userTerritory.TerritoryId, userTerritory);              
    }

}

}
}


Limitation(s):
1) You cannot edit / delete AccountShare record where ROWCAUSE = ‘Territory’ via Data Loader and API. If you do then you will get the following error.
“System.DmlException: Delete failed. First exception on row 0 with id 00rZ000001G3hDoIAJ; first error: INVALID_CROSS_REFERENCE_KEY, id does not exist: []”.