Saturday, December 26, 2015

Salesforce: Change Record Owner

In general, to transfer a record from a user to you or to someone else in Salesforce, you need to have following access or permission:
  • you are record owner, or
  • record owned by a user under you in the role hierarchy (Grant Access Using Hierarchies must be enabled for that object), or
  • you have Modify All permission for the given object, regardless of who owns the record, or
  • you have Transfer Record permission and Edit permission on the object type
  • you have Modify All Data permission, regardless of who owns the record.
Special case to transfer Campaign, users must also have the "Marketing User" checkbox selected on their user record.

If you see above criteria's, having edit access on a record doesn't mean you will be able to transfer a record you can edit. If you click Sharing button on the record, it will show the explanation of Access Levels:
  • Full Access - User can view, edit, delete, and transfer the record. User can also extend sharing access to other users.
  • Read/Write - User can view and edit the record, and add associated records, notes, and attachments to it.
While, using sharing rule in OWD, we cannot share object access to Full Access.

Note: user with "Transfer Record" permission will allowed user to transfer ALL records for the object, as long as user have Edit access to the object. Read again here "edit on object", NOT "edit on record", so this mean, user will be able to transfer record owner even user do not have Edit access to that record.

Use Case: allow user to change owner as long as user have edit access to the record, edit access maybe given from OWD sharing rules or manual sharing.

Solution: based on above criterias, this use case doesn't fit any criteria. In short, we need to customize with write trigger to query to object UserRecordAccess, example: SELECT RecordId, HasEditAccess FROM UserRecordAccess WHERE UserId='00590000000OoB0AAK' and RecordId='00690000005vUbw' and "Transfer Record" permission must be given to that users.

Other Solution: this maybe not ideal solution, but if you do not have developer to write trigger, you can use validation rules based on conditions from user object, example: users located in West area only allowed to transfer record owned by users in the same West area, sample validation rule:
TEXT($User.Area__c) <> PRIORVALUE(Owner.Area__c) || 
TEXT($User.Area__c) <> Owner.Area__c 

** this validation rule will stop user to edit record if the record owner is not in the same Area with the user, or the prior record owner is not in the same with user's Area.