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
CheesemonautCheesemonaut 

Apex Managed Sharing using Roles

Hi,

 

I'm trying to use Roles with Apex Managed Sharing, but I'm running in to a problem.  The documentation and example for Apex Sharing Rules implies that we can use Roles to populate the UserOrGroupId field on a sharing object, but I'm getting an error when I use an Id I derive from the UserRole object:

 

FIELD_INTEGRITY_EXCEPTION, User/Group ID: id value of incorrect type

 

In a nutshell, I've created an Apex class that is used to manage sharing on a custom object we have (Object B).  Object B is related to an Account.  I'm grabbing the account id and then using that to find any Customer Portal Roles (UserRoles object, these are created automatically when you create a portal user) associated to that account.  I then take the Id from the UserRole object and use it to populate the UserOrGroupId field on my ObjectB__Shares record.

 

Can I not use Roles with Apex Managed Sharing or am I doing something wrong?  Here's the relevant code (slightly modified to protect the innocent):

 

 

//Now that you have all the account ids, get the corresponding portal user roles
            Set<ID> allPortalRoleIDs = new Set<ID>();
            for(UserRole ur: [Select Id, Name From UserRole Where PortalAccountId in: allRelatedAcctIDs])
            {
                allPortalRoleIDs.add(ur.Id);
            }
            
            //Now that you have all the relevant Portal User Roles, populate the shares
            if(allPortalRoleIDs != null && allPortalRoleIDs.size() > 0)
            {
                for(ObjectB__c b: ForClientOnly)
                {
                    for(ID roleId : allPortalRoleIDs)
                    {
                        
                        ObjectB__Share bs = new ObjectB__Share();
                        bs.ParentID = b.id;
                        bs.UserOrGroupID = roleId;
                        bs.AccessLevel = 'read';
                        bs.RowCause = Schema.ObjectB__Share.RowCause.portal_access__c;
                        
                        allShares.add(bs);
                    }
                }
            }

            //Once you have all the Shares, insert them
            insert allShares;

 

Any thoughts?
Thanks in advance!

 

 

MohandaasMohandaas

Cheesemonaut,

 

I do not know how you can assign a 'roleId' to a 'UserOrGroupID' field in ObjectB__Share object. I am not sure how to implement apex managed sharing using roles, If at all you can do so.

DevNVDevNV

You are missing one step:  Accounts are linked to UserRoles through the portalAccountid field (with PortalRole of Executive, Manager or Group), but then UserRoles are linked to Groups.  Take your userrole and lookup the Group record where relatedid = UserRole.id and Type = role or rolesandsubordinates.  Once you have the Group Id then you can use that in the sharing object for userorGroupId.

 

I used a bit of a map to map structure to get my Account to Group Id.  First I created a map of Account Id to UserRole Id.  Then I created a map of UserRole Ids to Group Ids.  Finally I cycled throught he Account to UserRole map, found the Group Id for that UserRole Id and added it to a new map of Account to Group Ids.  A bit roundabout but it gave me what I needed.

 

Hope that helps

Niki Vankerk

www.vankerksolutions.com

SamHowleSamHowle
@DevNV Thank you! I had been trying to solve that same exact problem all day. Works like a charm now.

For anybody else reading this now- you have to switch to Classic to create Apex Sharing Reasons (RowCause field on Share record). That also took me awhile to figure out.