I'm trying to populate a text field on Account with the Territory names of the account on insert or update (original territories, not Enterprise Territories or Territories2).

I've mapped through Account to Account Share to Group to Territory and have the correct territories but I can't seem to connect it back to the Account again.

Due to the AccountShare list inside the first map I am getting Incompatible key type List for Map at line 75 where I try to populate AccountTerritories__c (the text field on Account) with the correct territories. I tried vastly simplifying line 75 to just MapofTerritories.values(); (which I don't think would bulk at all) and got the error of Illegal assignment from List to String at line 75.

How can I get the correct territories linked with the correct Account ID and entered into the Text field?

Thank you for your help

trigger AccountTerritories on Account(before update) {
    if (Trigger.isBefore) {
        Set < Id > setOfAccountIds = new Set < Id > ();

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

        if (setOfAccountIds.size() > 0) {

            /* Declaration of collection data types */
            Map < id, List < AccountShare >> MapOfAccountShare = new Map < id, List < AccountShare >> ();
            Map < Id, Id > mapOfGroup = new Map < Id, Id > ();
            Map < Id, String > mapOfTerritories = new Map < Id, String > ();

            //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, RowCause from AccountShare where AccountId IN: setOfAccountIds];
            System.debug('=== contents of listOfAccountShare: ' + listOfAccountShare);
            System.debug('=== size of listOfAccountShare: ' + listOfAccountShare.size());
            List < Id > Groupids = new List < Id > ();
            for (AccountShare a: listofAccountShare) {

            //Map of Account Share

            for (AccountShare acctShare: listOfAccountShare) {
                if (MapOfAccountShare.containsKey(acctShare.AccountID)) {
                } else {
                    MapOfAccountShare.put(acctShare.AccountID, new List < AccountShare > {
            System.debug('=== all AccountShare keys in the map: ' + mapOfAccountShare.keySet());
            System.debug('=== all AccountShare values in the map (as a List): ' + mapOfAccountShare.values());
            System.debug('=== size of mapOfAccountShare: ' + mapOfAccountShare.size());

            //Query in Group object            
            List < Group > listOfGroup = [Select Id, RelatedId from Group where Type = 'Territory'
                and Id IN: GroupIDs
            System.debug('=== contents of listOfGroup: ' + listOfGroup);
            System.debug('=== size of listOfGroup: ' + listOfGroup.size());
            //Map of Group object
            for (Group groupRecord: listOfGroup) {
                mapOfGroup.put(groupRecord.Id, groupRecord.RelatedId);
            System.debug('=== all Group keys in the map: ' + mapOfGroup.keySet());
            System.debug('=== all Group values in the map (as a List): ' + mapOfGroup.values());
            System.debug('=== size of MapOfGroup: ' + mapOfGroup.size());

            //Query in Territory object
            List < Territory > listOfTerritory = [Select Id, Name from Territory where Id IN: mapOfGroup.Values()];
            System.debug('=== contents of listOfTerritories: ' + listOfTerritory);
            System.debug('=== size of listOfTerritories: ' + listOfTerritory.size());
            //Map of Territory object

            for (Territory Territories: listOfTerritory) {
                mapOfTerritories.put(Territories.Id, Territories.Name);
                System.debug('=== all Territories keys in the map: ' + mapOfTerritories.keySet());
                System.debug('=== all Territories values in the map (as a List): ' + mapOfTerritories.values());
                System.debug('=== size of MapOfTerritories: ' + mapOfTerritories.size());

            for (Account updatedAccount: Trigger.new) {
                String territory = MapofTerritories.values().get(mapofGroup.get(mapofAccountShare.get(updatedaccount.id)));
                updatedAccount.territories = territory;


  • What are you hoping to have in the territory String? In other words, how are you hoping to represent a List as a String? For example, do you want it to have a value of Germany,France,Italy?
    – Rob
    Commented Aug 25, 2015 at 14:18
  • 1
    I think you need to go back to the drawing board with you objects and maps. The piece you are missing is how to relate the account back to the territories based on the account shares. Right now you have all of the info but there is nothing linking the data to the territories. All you have is a map of territories found as a result of the data but no way to relate it back to the data. Value() in your territories will be ALL territory names for ALL groups for ALL Accounts in the trigger currently
    – Eric
    Commented Aug 25, 2015 at 14:24
  • I'd like it in a string like it shows up in the debug logs which looks like USER_DEBUG|[71]|DEBUG|=== all Territories values in the map (as a List): (Higher Education, HS Team, HS1) So Territories = Higher Education, HS Team, HS1
    – user2769
    Commented Aug 25, 2015 at 14:35
  • So yes, I'm hoping to represent the List as a String with just the Territory Name Values.
    – user2769
    Commented Aug 25, 2015 at 14:48

2 Answers 2


You have the below line inside of a for loop:

mapOfTerritories.put(Territories.Id, Territories.Name);

If you want a list of the Territory Names, you can just use


and assign that to a list.

You could also have created the list inside the original for loop where you created the map by simply doing something like this:

        list<string>terrlst = new list<string();

        for (Territory Territories: listOfTerritory) {
            mapOfTerritories.put(Territories.Id, Territories.Name);
            System.debug('=== all Territories keys in the map: ' + mapOfTerritories.keySet());
            System.debug('=== all Territories values in the map (as a List): ' + mapOfTerritories.values());
            System.debug('=== size of MapOfTerritories: ' + mapOfTerritories.size());

Finally figured out how to get it mapped properly. Here's what I ended up with at the end to map back to the beginning and put in the Territory names.

for (Account updatedAccount : Trigger.new) {
        List<AccountShare> accountSharesList = mapofAccountShare.get(updatedaccount.id);

        // Start with empty string of territories
        String territories = '';
        for (AccountShare accountshare : accountshareslist){ //loop through accountShares
          // Get the group from the share
          id groupid = accountshare.userorgroupid;
          // Get the territory from the group map
          id territoryid  = mapofGroup.get(groupid);
          // Get the Territory Name from the territory Map
          string TerritoryName = MapofTerritories.get(territoryid);
          if(territoryname != null){
               // Add next territory name to string of territories
               territories = territories + territoryName +', ';// this is how i add the new territory to my string of territories
        // remove last two chars here, but only if territories is not empty string
            String TerritoryNames = Territories.Substring(0,Territories.length()-2);
            updatedAccount.territories__c = TerritoryNames;

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .