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

Navigating Across multiple Lists and Maps and entering Map Values as String

I'm trying to populate a text field on Account with the Territory names (original territories, not Enterprise Territories or Territories2).  In order to do this you have to map through Account to Account Share to Group to Territory and then back.  I've got the mapping done I think but the navigating back is proving quite difficult, especially since my map for Account Share involves a list inside a map.  I also need the Territories that have been both mapped and Listed to show up in my field as just a string (IE Territory 1, Territory 2, Territory 3, etc).  How can I do this?  Currently line 75 is giving me an error of Incompatible key type List<AccountShare> for Map<Id,Id> at line 75 column 43.  I did the Account Shares map with a List because just having the Account ID, Group ID on the accountShare was deduplicating by the account ID and leaving me with just 1 record everytime instead of multiples.  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<String> to String at line 75 column 12 so there's an issue there of having it list them out no matter if I get back to the correct account or not.
Thank you for your help

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

        for(Account acct : Trigger.New){
                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))
        MapOfAccountShare.get(acctShare.AccountID). add(acctShare);
        MapOfAccountShare.put(acctShare.AccountID, new  List <AccountShare> { acctShare });
    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 : {
    String territory = MapofTerritories.get(mapofGroup.get(mapofAccountShare.get( )));
    updatedAccount.territories__c = territory;

Best Answer chosen by SFDCDevQA
Finally figured out how to get it mapped properly. Here's what I have at the end to map back to the beginning and put in the Territory names.

for (Account updatedAccount : {
            List<AccountShare> accountSharesList = mapofAccountShare.get(;
            // 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;