sharingmodel1

The past two previous discussions were primarily based on the Sharing model and managed programmatic sharing on the Salesforce platform. This post will be focused on recalculating apex managed sharing. What does it mean to recalculate sharing?

Sharing Recalculation

Salesforce automatically recalculates sharing for all records on an object when its organization-wide sharing default access level changes. The recalculation adds managed sharing when appropriate. Also, all types of sharing are removed if the access they grant is considered redundant. For example, manual sharing, which grants Read-Only access to a user, is deleted when the object’s sharing model changes from Private to Public Read Only. >To recalculate Apex managed sharing, you must write an Apex class that implements a Salesforce-provided interface to do the recalculation. You must then associate the class with the custom object, on the custom object’s detail page, in the Apex Sharing Recalculation related list. The above can be accomplished using batchable apex to mass update shared records. Also please bare, in mind Apex sharing reasons and Apex managed sharing recalculation are only available for custom objects.

Every time a custom object’s organization-wide sharing default access level is updated, any Apex recalculation classes defined for the associated custom objects are also executed.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// assume a sharing reason called Manager__c and Position__c was created for Essence__Share
global class EssenceSharingCalculation implements Database.Batchable<Sobject>{

    global EssenceSharingCalculation(){

    }
    global Database.QueryLocator start(Database.BatchableContext bc){
        return Database.getQueryLocator([SELECT Id,userId FROM  Essence__c WHERE Name = :'Awesome']);
    }
    global execute(Database.BatchableContext bc, List<Essence__c>  records){
        List<Essence__Share> newShareRecords = List<Essence__Share>();
        for(Essence__c record: records){
            Essence__Share share = new Essence__Share();
            share.UserorGroupId = record.userId;
            share.AccessLevel = 'Read';
            share.ParentID = record.Id;
            share.RowCause = Schema.Essence_Share.RowCause.Position__c;
            newShareRecords.add(share);
        }
        if(!newShareRecords.isEmpty()){
            // Delete the existing sharing records.
            // This allows new sharing records to be written from scratch.
            delete [SELECT Id FROM Essence_Share WHERE RowCause = :Schema.Essence_Share.RowCause.Position__c AND
            ParentID IN :records];

            //Insert the new sharing records
            insert newShareRecords;
        }

    }
    global void finish(Database.BatchableContext bc){
        System.debug('Finished');
    }
}

Associating an Apex Class Used for Recalculation

An Apex class used for recalculation must be associated with a custom object. - Switch salesforce classic, navigate to the Essence object page details - Go to Apex Sharing Recalculations section - Choose the Apex class that recalculates the Apex sharing for this object. The class you choose must implement the Database.Batchable interface. You cannot associate the same Apex class multiple times with the same custom object. - Click Save.