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

Assigning Territories through APEX (without Assignment Rules)

I realize that the DMO Options do not apply to Accounts or Territories, however I am still looking for a good way to assign a Territory to an Account in APEX.


Currently we have an assignment rule which assigns the Territory to the Account where the Territory Name matches a Picklist value in the Account. I figured that if I set the Picklist value in APEX and update the Account, the assignment rule should catch it - apparently not - although updating the account again (changing no values) directly in SF does call the assignment rule and attaches the Territory as expected. I'm guessing that running the update Account command twice in APEX won't work either.


Since Workflows are evaluated after the Assignment Rules, I don't think a workflow based on the picklist value will work.


So, would creating an AccountShare record connecting the Account to the Group that is related to the Territory do the trick??  This is based on the likely mistaken premise that a Territory attached to an Account represents the AccountShare rule that was created - create the AccountShare, and the Territory is connected and should show up in the Account. Seems like flawed thinking to me, but I'm not sure why.


I know I'm not the first to encounter this, so I'm hoping someone out there might have the best solution for this.






I just tried this solution and it didn't work for me.  It shared the Account with the territory, but the GUI didn't reflect that the account was part of the territory.


Did you find any solution to this?


The "you don't need to run these rules that frequently" is fine and all, but when you've got over 500 territory rules that you've got to run to reflect territory changes the hunt and peck approach to "goto the Territory screen, click run rules" isn't a place that should be settled for.  Especially with (our) quarterly updates to our accounts.


Here's a link for future readers of this topic:


And the content if that page ever goes down:

The Territory field on an Account record is only available via the GUI.  

When trying to access an Account's Territories via the API/Data Loader, there is no Territory field on the Account table; instead, the relationship looks like this: 

Account Table | Account Share Table | Group Table | Territory Table 

In essence, a query will need to have multiple parts to read the Territory information from an Account record.

When an Account is assigned to a Territory, the Territory is linked to a Group and that Group is given sharing permissions on the Account.  This is a process similar to manually granting sharing permissions on an Account.  When using the API, it is important to query each of the above-mentioned tables.


Our solution was to completely bypass the Auto-Assignment Rules altogether and create our own process using the manual Assignment in Apex.


Basically any Territory that is auto-Assigned has to be unassigned by the same auto-process, which can't be accessed in APEX, where you need it. So dump it!


We exported our Account Territory assignments, then ran a prcess that erased all the auto-assigned terrtories, then used the new triggers and classes to reassign the Territories as a manual assignment, that was still 'auto-assigned' by APEX. Same result, way less headaches, and using Custom Settings were considerably easier to maintain.


I think you described exactly what we were trying to accomplish on our own, so is there anyway you could post some example code of how you went about assigning an account to a territory using APEX?


The key is understanding the relationship between an Territory and an Account which look like this:


Account -> Sharing Rule <-> Group <- Territory


Basically an Account is being Shared with a Group whose 'RelatedID' is the TerritoryID of the Territory you want associated with the Account.So you're looking to

1) identify the Territory you want to associate with the Account,

2) get its Territory ID,[Select id from Territory WHERE Name = TerritoryName];

3) find the Group whose 'RelatedID == TerritoryID, [Select id, RelatedID from Group Where RelatedID = :TerritoryID];

4) then create a new Account Sharing Rule for that Group.

   AccountSharingRule ASR = new AccountSharingRule(AccountID = A.ID, UserOrgroupID = G.Id); insert ASR;


That's the short description of what you're trying to do - removing a Territory essentially is just deleting the sharing rule. You'll want to batchify the process to allow for multiple updates, which means several levels of 'for' loops checking ids to ensure the right TerritoryID and thus the right groupID is being shared with the right Account.

To make it easier we had a hidden field on the Account that stored the Territory name, once it was determined, to ensure we queried only the territories we wanted, although now I would probably just do that in a Class with methods for both determining the right territory/Group and creating the sharing rule.

Anyway, once you've done all this successfully, you'll see the Territory listed in the Territory field in the Account. It is manually editable though so you'll want to add your validation rules or whatever to make sure no one changes it inadvertently.





Hey !

AccountSharingRule is invalid object in salesforce .

How Territory field would be listed by apex script.


 I got it ,

This not AccountSharingRule its AccountShare !

How to change the territory of an account in apex?