function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Joel RichardsJoel Richards 

OppTerrAssignDefaultLogicFilter class

Hi, I'm trying to Enable Filter-Based Opportunity Territory Assignment for Enterprise Territory Management.Part of the setup is:
'If your organization is using the Apex code Salesforce provides, first create the class and then return to this Settings page and enter the class name: OppTerrAssignDefaultLogicFilter. If you opt to use your own code for the Apex class, you’ll come back and enter the name of the class that you create.

However I can't find any other information related to the 'OppTerrAssignDefaultLogicFilter' class anywhere. Has anyone come across this apex class and if so can they share it?
Best Answer chosen by Joel Richards
ShashankShashank (Salesforce Developers) 
You can find it here: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_interface_TerritoryMgmt_OpportunityTerritory2AssignmentFilter.htm

All Answers

ShashankShashank (Salesforce Developers) 
You can find it here: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_interface_TerritoryMgmt_OpportunityTerritory2AssignmentFilter.htm
This was selected as the best answer
William BoyceWilliam Boyce
Hi Joel,

Did you get the OppTerrAssignDefaultLogicFilter to work in your org?
Jennifer Alden SanchezJennifer Alden Sanchez
Hi there,
Was this issue ever resolved?  The OppTerrAssignDefaultLogicFilter apex class in not working in my dev org, keep getting an unexpected token 'else' error and I am using the code Salesforce provided. Any update would be appreciated!  Thank you!!
 
Wenda McMahanWenda McMahan

@Jennifer Alden Sanchez, that Apex class needs to be edited. There are several comments that wrap to two different lines, without the comment delimiter in front of the second line. The first error is that "else" on line 45. Let me know if you want some help with it. Here is another post on the same topic. 
https://developer.salesforce.com/forums/?id=906F0000000BJSZIA4
Curt Griffin 4Curt Griffin 4
When I try to create the Apex Class for this filter using this post, I get the following error when I try to save the Class:

Compile Error: unexpected token: 'global class OppTerrAssignDefaultLogicFilter implements' at line 11 column 0

I used the Apex Code example found at this link:
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_interface_TerritoryMgmt_OpportunityTerritory2AssignmentFilter.htm

I editted the above Apex Class to fix the issue with the comments wrapping to another line...I think I got them all.  but I still get the above error.  See the Apex Class code below.

In case it is not obvious, I am not a devloper, so any suggestions would be appreciated.

Thank you

Curt
 
1	/*** Apex version of the default logic.
2	* If opportunity's assigned account is assigned to
3	*  Case 1: 0 territories in active model
4	*            then set territory2Id =   null
5	*  Case 2: 1 territory in active model
6	*            then set territory2Id =   account's territory2Id
7	*  Case 3: 2 or more territories in active model
8	*            then set territory2Id =   account's territory2Id that is of highest priority.
9	*            But if multiple   territories have same highest priority, then set territory2Id = null
10	*/
11	global class OppTerrAssignDefaultLogicFilter implements
12	TerritoryMgmt.OpportunityTerritory2AssignmentFilter {
13	     /**
14	     * No-arg constructor.
15	     */
16	     global   OppTerrAssignDefaultLogicFilter() {}
17	
18	     /**
19	      * Get mapping of   opportunity to territory2Id. The incoming list of opportunityIds contains only those with IsExcludedFromTerritory2Filter=false.
20	      * If territory2Id =   null in result map, clear the opportunity.territory2Id if set.
21	      * If opportunity is not present in result map, its territory2Id remains intact.
22	      */
23	    global Map<Id,Id> getOpportunityTerritory2Assignments(List<Id> opportunityIds) {
24	        Map<Id,   Id> OppIdTerritoryIdResult = new Map<Id, Id>();
25	
26	        //Get the active territory model Id
27	        Id   activeModelId = getActiveModelId();
28	
29	        if(activeModelId   != null){
30	            List<Opportunity>   opportunities =
31	              [Select Id, AccountId, Territory2Id from Opportunity where Id   IN
32	              :opportunityIds];
33	            Set<Id>   accountIds = new Set<Id>();
34	            //Create   set of parent accountIds
35	            for(Opportunity opp:opportunities){
36	                if(opp.AccountId   != null){
37	                    accountIds.add(opp.AccountId);
38	                    }
39	                }
40	
41	                Map<Id,Territory2Priority> accountMaxPriorityTerritory =
42	getAccountMaxPriorityTerritory(activeModelId, accountIds);
43	
44	            //for each opportunity, assign the highest priority territory if there is no conflict,
45	else assign null
46	            for(Opportunity opp: opportunities){
47	               Territory2Priority tp = accountMaxPriorityTerritory.get(opp.AccountId);
48	               //assign highest priority territory if there is only 1
49	              if((tp   != null) && (tp.moreTerritoriesAtPriority == false) &&
50	(tp.territory2Id != opp.Territory2Id)){
51	                   OppIdTerritoryIdResult.put(opp.Id, tp.territory2Id);
52	               }else{
53	                   OppIdTerritoryIdResult.put(opp.Id,   null);
54	               }
55	            }
56	        }
57	        return   OppIdTerritoryIdResult;
58	    }
59	     
60	    /**
61	      * Query assigned territoryIds in active model for given accountIds
62	      * Create a map of accountId to max priority territory
63	      */
64	     private Map<Id,Territory2Priority> getAccountMaxPriorityTerritory(Id
65	activeModelId, Set<Id> accountIds){
66	        Map<Id,Territory2Priority> accountMaxPriorityTerritory = new
67	Map<Id,Territory2Priority>();
68	        for(ObjectTerritory2Association ota:[Select ObjectId, Territory2Id,
69	Territory2.Territory2Type.Priority from ObjectTerritory2Association where objectId IN
70	:accountIds and Territory2.Territory2ModelId = :activeModelId]){
71	            Territory2Priority tp = accountMaxPriorityTerritory.get(ota.ObjectId);
72	
73	            if((tp   == null) || (ota.Territory2.Territory2Type.Priority >
74	tp.priority)){
75	                //If this is the first territory examined for account or it has greater priority than current highest priority territory, then set this as new highest priority territory.
76	                tp = new
77	Territory2Priority(ota.Territory2Id,ota.Territory2.Territory2Type.priority,false);
78	            }else if(ota.Territory2.Territory2Type.priority == tp.priority){
79	                //The priority of current highest territory is same as this, so set  moreTerritoriesAtPriority to indicate multiple highest priority territories seen so far.
80	                tp.moreTerritoriesAtPriority = true;
81	            }
82	             
83	            accountMaxPriorityTerritory.put(ota.ObjectId,   tp);
84	        }
85	        return accountMaxPriorityTerritory;
86	    }
87	
88	              
89	    /**
90	     * Get the Id of the Active Territory Model.
91	     * If none exists, return   null;
92	     */
93	   private Id getActiveModelId() {
94	       List<Territory2Model>   models = [Select Id from Territory2Model where State ='Active'];
95	       Id activeModelId = null;
96	       if(models.size()   == 1){
97	           activeModelId = models.get(0).Id;
98	       }
99	        
100	       return activeModelId;
101	   }
102	    
103	   /**
104	    * Helper class to help   capture territory2Id, its priority, and whether there are more territories with same priority assigned to the account
105	    */
106	   private class Territory2Priority {
107	       public Id territory2Id { get; set; }
108	       public Integer priority { get; set; }
109	       public   Boolean moreTerritoriesAtPriority { get; set; }
110	        
111	              Territory2Priority(Id territory2Id, Integer priority, Boolean moreTerritoriesAtPriority){
112	           this.territory2Id = territory2Id;
113	           this.priority = priority;
114	           this.moreTerritoriesAtPriority = moreTerritoriesAtPriority;
115	       }
116	   }
117	}}


 
Benjamin ChismBenjamin Chism
I was able to write the custom apex class with the help of one of my developers. Now we are trying to write the test class. Any suggestions. See class below.
global class OppTerrAssignDefaultLogicFilter implements TerritoryMgmt.OpportunityTerritory2AssignmentFilter { 

    global OppTerrAssignDefaultLogicFilter() {}

    global Map<Id,Id> getOpportunityTerritory2Assignments(List<Id> opportunityIds) { 
        Map<Id, Id> OppIdTerritoryIdResult = new Map<Id, Id>();
        
        // Get the active territory model Id
        Id activeModelId = getActiveModelId();
        
        if(activeModelId != null){

            List<Opportunity> opportunities =
                [Select Id, OwnerId, Territory2Id from Opportunity where Id IN :opportunityIds];

            Set<Id> ownerIds = new Set<Id>();
            // Create set of parent ownerIds
            for(Opportunity opp:opportunities){
                if(opp.OwnerId != null){
                    ownerIds.add(opp.OwnerId);
                }
            }
           
            Map<Id,Territory2Priority> ownerMaxPriorityTerritory = getownerMaxPriorityTerritory(activeModelId, ownerIds);
            
            // For each opportunity, assign the territory of the opportunity to the value of the highest priority territory of the owner
            for(Opportunity opp: opportunities){
                Territory2Priority tp = ownerMaxPriorityTerritory.get(opp.OwnerId);
                // Assign highest priority territory if there is only 1.
                if((tp != null) && (tp.moreTerritoriesAtPriority == false) && (tp.territory2Id != opp.Territory2Id)){
                    OppIdTerritoryIdResult.put(opp.Id, tp.territory2Id);
                    System.debug('Territory ID ' + tp.territory2Id + 'assigned to opportunity ' + opp.Id);
                }else{
                    OppIdTerritoryIdResult.put(opp.Id, null);
                }
            }
        }
        return OppIdTerritoryIdResult;
    }
    
    private Map<Id,Territory2Priority> getOwnerMaxPriorityTerritory(Id activeModelId, Set<Id> ownerIds){

        Map<Id,Territory2Priority> ownerMaxPriorityTerritory = new Map<Id,Territory2Priority>();
        for(UserTerritory2Association ota:[Select UserId, Territory2Id, Territory2.Territory2Type.Priority from UserTerritory2Association where userId IN :ownerIds and Territory2.Territory2ModelId = :activeModelId]){
            System.debug('User: ' + ota.UserId + ' Territory: ' + ota.Territory2Id);
            Territory2Priority tp = ownerMaxPriorityTerritory.get(ota.UserId);
            
            if((tp == null) || (ota.Territory2.Territory2Type.Priority > tp.priority)){
                // If this is the first territory examined for the owner or it has greater priority than current highest priority territory, then set this as new highest priority territory.
                tp = new Territory2Priority(ota.Territory2Id,ota.Territory2.Territory2Type.priority,false);
            }else if(ota.Territory2.Territory2Type.priority == tp.priority){
                tp.moreTerritoriesAtPriority = true;
            }

            ownerMaxPriorityTerritory.put(ota.UserId, tp);
        }
        return ownerMaxPriorityTerritory;
    }

    private Id getActiveModelId() {
        List<Territory2Model> models = [Select Id from Territory2Model where State = 'Active'];
        Id activeModelId = null;
        if(models.size() == 1){
        activeModelId = models.get(0).Id;
        }
        return activeModelId;
    }

    private class Territory2Priority {
        public Id territory2Id { get; set; }
        public Integer priority { get; set; }
        public Boolean moreTerritoriesAtPriority { get; set; }
        
        Territory2Priority(Id territory2Id, Integer priority, Boolean moreTerritoriesAtPriority){
            this.territory2Id = territory2Id;
            this.priority = priority;
            this.moreTerritoriesAtPriority = moreTerritoriesAtPriority;
        }
    }
}