+ Start a Discussion
DebjaniDebjani 

How to open up sharing for old/exising records in system using apex code?

I have a list of old records open and closed on which there is no sharing (these records are old requests that I want to share with groups) . How can I achieve this using apex code?
Best Answer chosen by Debjani
Nagendra Prasad ChNagendra Prasad Ch
Hi Lilly,

For caseShare it is CaseId, not ParentId.

obj.CaseId =c.Id;​

Try the below code. It will work. 
 
List<Case> CaseListToShare=new List<Case>();
CaseListToShare=[SELECT Id,CaseNumber FROM Case WHERE Id='5002800000AEIwm'];
List<CaseShare> sharesToCreate = New List<CaseShare>();

for(Case c : CaseListToShare)
        {
            CaseShare obj = new CaseShare();
            obj.CaseAccessLevel = 'Edit';
            obj.CaseId =c.Id;
            obj.UserOrGroupId ='0G28000001dupr';
            sharesToCreate.add(obj);
        }
       
if (!sharesToCreate.isEmpty()){
            insert sharesToCreate;
            system.debug('$$ sharesToCreate inserted '+sharesToCreate);
        }

Let me know if it will work.

All Answers

Rajiv Penagonda 12Rajiv Penagonda 12
Lilly, most objects in salesforce will have a related object postfixed with key "Share". For example Account object has AccountShare. We can make an entry in this object to share it with the group/user of preference using apex.

You can refer the documentation here (https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_objects_accountshare.htm)

The documentation has an example in the end, do refer that for coding tips.
Nagendra Prasad ChNagendra Prasad Ch
Here is the code for Apex sharing. Here I take Opportunity as the example.
All share objects for custom objects are named as MyCustomObject__Share, where MyCustomObject__c is the name of the related custom object.
 
List<OpportunityShare> sharesToCreate = New List<OpportunityShare>();

for(Opportunity Opp : OpportunityListToShare)// Opportunities list to share
        {                
            OpportunityShare objOpty = new OpportunityShare();
            objOpty.OpportunityAccessLevel = 'Read'; //Level access 'Read' or 'Edit'
            objOpty.OpportunityId = Opp.Id; // Id of Record which you want to share
            objOpty.UserOrGroupId =  fixedGroupId;  // Id of group/user u want to share
            sharesToCreate.add(objOpty);            
        }
       
if (!sharesToCreate.isEmpty()){
            insert sharesToCreate;
            system.debug('$$ sharesToCreate inserted '+sharesToCreate);
        }


Go through this resource for more details on Apex sharing.
https://developer.salesforce.com/page/Using_Apex_Managed_Sharing_to_Create_Custom_Record_Sharing_Logic
Yury BondarauYury Bondarau
Lilly,

I believe creating a custom code is NOT necessary. The easiest way is to create a sharing rule https://help.salesforce.com/apex/HTViewHelpDoc?id=security_sharing_cbs_about.htm&language=en_US.
Ater sharing rule is created it will recalculate sharings for existing records
Please see more details about recalculation here:
https://help.salesforce.com/apex/HTViewHelpDoc?id=security_sharing_recalculating.htm&language=en
 
DebjaniDebjani
Since this is Bulk case we will have to achieve through coding.
I am trying to use this, but it throwing error at ParentId(which is the Case Id)
List<Case> CaseListToShare=new List<Case>();
CaseListToShare=[SELECT Id,CaseNumber FROM Case WHERE Id='5002800000AEIwm'];
List<CaseShare> sharesToCreate = New List<CaseShare>();

for(Case c : CaseListToShare)
        {
            CaseShare obj = new CaseShare();
            obj.CaseAccessLevel = 'Read';
            obj.ParentId =c.Id;
            obj.UserOrGroupId ='0G28000001dupr';
            sharesToCreate.add(obj);
        }
       
if (!sharesToCreate.isEmpty()){
            insert sharesToCreate;
            system.debug('$$ sharesToCreate inserted '+sharesToCreate);
        }

 
Nagendra Prasad ChNagendra Prasad Ch
Hi Lilly,

For caseShare it is CaseId, not ParentId.

obj.CaseId =c.Id;​

Try the below code. It will work. 
 
List<Case> CaseListToShare=new List<Case>();
CaseListToShare=[SELECT Id,CaseNumber FROM Case WHERE Id='5002800000AEIwm'];
List<CaseShare> sharesToCreate = New List<CaseShare>();

for(Case c : CaseListToShare)
        {
            CaseShare obj = new CaseShare();
            obj.CaseAccessLevel = 'Edit';
            obj.CaseId =c.Id;
            obj.UserOrGroupId ='0G28000001dupr';
            sharesToCreate.add(obj);
        }
       
if (!sharesToCreate.isEmpty()){
            insert sharesToCreate;
            system.debug('$$ sharesToCreate inserted '+sharesToCreate);
        }

Let me know if it will work.
This was selected as the best answer
JSingh9JSingh9
You can do that using a sharing rule, it will als take care of the old records as well, no need to write Apex code
DebjaniDebjani
@Ch Nagendra Prasad

Thanks, it is working now. I am calling multiple cases and provide sharing to specific public groups based on name of group.
Should i use map to write something like this: call liost of case with id's and assign them to group if group name equal or contains name as "abc group" ?
Nagendra Prasad ChNagendra Prasad Ch
Yes. You can use map or list for this.