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
t_developert_developer 

Add user to Account Team and set Access Levels

I have custom object named 'Top Account' that is related to the standard Account object.

When creating new 'Top Accounts', it requires a user to be specified and a role. When saved, I want that user to be added to the Account Team, and give specific Access Levels (i.e. edit access to contacts, and read access to opportunities).

Adding the user to the Account Team is straightforward, but setting the Access Levels has proven to be pretty complex.

Below is the AccountShare attempt. Again the first part works in that it correctly creates the AccountTeamMember, but all the access levels are set to private.

Thanks!

public static void updateAccountTeamFromTopAcct(List<Target_Account__c> ttAcctList) {

List<Target_Account__c> ttUpdateList = new List<Target_Account__c>(); // trigger list

List<String> assignedUserIdsList = new List<String>(); // Ids from Assigned Top Account users

List<String> accountList = new List<String>(); // accounts IDs affected by Top Account

Map<String,String> roleMap = new Map<String,String>();

for(Target_Account__c ttAcc : ttAcctList){

    assignedUserIdsList.add(ttAcc.Assigned_User__c);
    accountList.add(ttAcc.Account__c);
    roleMap.put(ttAcc.Assigned_User__c, ttAcc.User_Role__c);
    }

    List<Account> affectedAccounts = [select Id from Account where Id in : accountList]; // list of all accounts affected by top account
    List<AccountTeamMember> accountTeamList = new List<AccountTeamMember>(); // list of AccountTeamMembers to insert    

    for(Account acct : affectedAccounts){
        AccountTeamMember acctTM = new AccountTeamMember();
        acctTM.AccountId = acct.Id;

        for(String usrId: assignedUserIdsList){
            acctTM.userId = usrId;
            if(roleMap.get(usrId).equals('SpecialRole')){
                acctTM.TeamMemberRole = 'Sales Rep';
                accountTeamList.add(acctTM);
            }
        }
    }

    insert accountTeamList;

    List<AccountShare> affectedAcctShare = [select Id from AccountShare where AccountId in :affectedAccounts and UserOrGroupId in :assignedUserIdsList];

    for (AccountShare share : affectedAcctShare ) {

        // Give view access to opportunities and edit access to contacts
        share.ContactAccessLevel = 'Edit';
        share.OpportunityAccessLevel = 'Read';
    }

    update affectedAcctShare;


Best Answer chosen by t_developer
Ramu_SFDCRamu_SFDC
I have come across this situation earlier where even after giving the access level in Account share  the access is not assigned correctly. This happens due to the fact that when a team member is inserted the system will first check if there is an associated account ID and user combination in Account Share object. If yes, it grants the access level to Accounts, Contacts and Opportunities accordingly. If not, it will set with default access levels.

In the current code, as you are inserting the team members initially ( where the accont share object related data will not be there at that moment) it is saving the account team member record with default access level. Even though you are updating the records later it will not have any impact.

To correct this, I suggest that you first update the account Share data or insert the account share data if not already present and then Insert Account team members.

Please mark this as best answer if it resolved your issue so that others who are looking out for similar solution will be benefited.

All Answers

Ramu_SFDCRamu_SFDC
I have come across this situation earlier where even after giving the access level in Account share  the access is not assigned correctly. This happens due to the fact that when a team member is inserted the system will first check if there is an associated account ID and user combination in Account Share object. If yes, it grants the access level to Accounts, Contacts and Opportunities accordingly. If not, it will set with default access levels.

In the current code, as you are inserting the team members initially ( where the accont share object related data will not be there at that moment) it is saving the account team member record with default access level. Even though you are updating the records later it will not have any impact.

To correct this, I suggest that you first update the account Share data or insert the account share data if not already present and then Insert Account team members.

Please mark this as best answer if it resolved your issue so that others who are looking out for similar solution will be benefited.
This was selected as the best answer
t_developert_developer
Thank you! Inserting the AccountShare records before the other records worked. Below is the updated code that worked. Thanks again.

for(Account acct : affectedAccounts){
			AccountTeamMember acctTM = new AccountTeamMember();
			AccountShare acctShare = new AccountShare(); 

			acctTM.AccountId = acct.Id;

			for(String usrId: assignedUserIdsList){
				acctTM.userId = usrId;
				if(roleMap.get(usrId).equals('SpecialRole')){
					acctTM.TeamMemberRole = 'Sales Rep';
					accountTeamList.add(acctTM);

				acctShare.AccountId = acct.Id;
				acctShare.UserOrGroupId = usrId;
				acctShare.ContactAccessLevel = 'Edit';
				acctShare.OpportunityAccessLevel = 'Read';
				acctShare.AccountAccessLevel = 'Read';
				acctShareList.add(acctShare);
				}
			}
		}
		
		insert acctShareList;
		insert accountTeamList;


Blake Kercovich 2Blake Kercovich 2
We are having the same problem.
We are using Informatica to migrate our data into Salesforce.
I was excited when I saw this answer, because I thought it would finally fix the problem.
Unfortunately, it did no work.
We had no records in either AccountTeamMember or AccountShare.
So, I tried the method above, of inserting the records for AccountShare, and then AccountTeamMember.
All the inserts were successful, but when you go to look at the records in the interface, they still show the wrong values, just like when the AccountTeamMember records are imported first.
I used DataLoader to select out the AccountShare data, to verify it wasn't changed, and it is stored correctly.
The data in AccountShare is "Edit" for all the Access fields.
But, when you look at it in the interface, the Account Acess and Opportunity Access fields both show "Read Only".
The Case Access field shows "Read/Write", which is what I would expect all 3 to show, since "Edit" is the value stored in the database.
The good news is that functionality works correctly, meaning that the user can edit the Accoutn and the Opportunity.
So, it's just a matter of the Edit Member screen showing the wrong data.
Since the functionality works, it's really just an annoyance thing from a Sys Admin perspective at this point, but it still would be nice if this were to display the correct data that is actually stored.
Sofiya SaneSofiya Sane
We are also facing same issue when we are inserting record into Account Team member using dataloader. Its showing default access levels and not from Account Share. Is this the known issue or we are missing something?

@Blake- Are you able to solve the above? Please share.
PappuPappu
Hi t_developer,

How you are calling the updateAccountTeamFromTopAcct class?
Through process builder?