Salesforce
This topic is related to the sharing in communities. I need to setup the sharing on partner communities and there is no point and click option for sharing any object for partner communities object. First you should setup the communities in the ORG than go to the setupàcommunity settings and add a new sharing sets, see the below image 1
In above red highlighted box, you would not able to see the partner community profiles, so this is really a main point for which I used manual sharing by apex code. We can add a sharing rule for customer community user license. So if we are making customer community than this would be pretty mush simple to configure. Now moving forward, my task was to share a newly created case in the community only for same account, Means let’s say if I have created a Case1 and adding this case against any contact, obviously Account is there for that contact, so this Case1 should be share among all those community user which have that same Account Id and if another account user login to the community than that Case1 should not be seen for that User. So this is the user case which I need to follow here. So I have made a trigger on case and on that trigger, newly created case should be share with all those user which are of same account. Please keep this in mind if let’s say we update that case and link that case with another Account than we must un-share the case with previous users and that case would be share with new community user. So, I have just written a sample here which is perfect for the created case if we change the Account on updating than few more lines needs to be added here, please see the below trigger code here.
trigger trShareCase on Case (after insert, after update) { map<Id,Id> mCase_Account = new map<Id,Id>(); map<Id,Id> mUser_Account = new map<Id,Id>(); map<Id,List<Id>> mCase1 = new map<Id,List<Id>>(); Map<Id,List<User>> mUser = new Map<Id,List<User>>(); for(Case cs:trigger.new) { if (cs.accountid != null) { mCase_Account.put(cs.Id,cs.accountid); } } for (user u : [select Id,AccountId from user where IsActive= true And AccountId in :mCase_Account.values()]) { mUser_Account.put(u.Id,u.AccountId); } List<Id> liUser ; for(Id caseId: mCase_Account.keyset()) { for(Id userId: mUser_Account.keyset()) { if(mCase_Account.get(caseId) == mUser_Account.get(userId)) { if (!mCase1.containsKey(caseId)) { liUser = new List<Id>(); liUser.add(userId); mCase1.put(caseId,liUser); } else { liUser = new List<Id>(); liUser = mCase1.get(caseId); liUser.add(userId); mCase1.put(caseId,liUser); } } } } List<CaseShare> csShareList = new List<CaseShare>(); Id TestId ; for(Case cs:trigger.new) { for (Id caseId: mCase1.keyset()) { if (cs.Id == caseId) { liUser = mCase1.get(caseId); for (Id UserId: liUser) { CaseShare csShare = new CaseShare(); // Give Read write access to that user for this particular case record. csShare.CaseAccessLevel = 'Read'; // Assign case Id of case record. csShare.CaseId = cs.id; // Assign user id to grant read write access to this particular case record. TestId = UserId; csShare.UserOrGroupId = TestId; //csShare.RowCause = Schema.Project__Share.RowCause.Manual; csShareList.add( csShare ); } } } } insert csShareList; } |
The Community plus license also needs the same way of manual sharing but if you want to play the same game against customer community user license than go to setpàcommunity settings and define the sharing set and add the same rule means Case1 should be share against all those user which are under the umbrella of same Account, see below image for your help
So this is the case of adding any new case, let’s say if we are making any new partner community user than what should we do? Because we have earlier worked on Case object. So, for this we need to add a trigger on User as well but the important punch over here is that if we add a trigger on user and on that trigger if we are manually share the object like Case, so if User is added and then hit that trigger, it would give an exception of MIXED_DML_OPEARATION, reason being we are getting the exception because the same time we are using the System object that is user for DML operation and on the other way we are using non-system object which is CaseSharing object, so it would create an issue. So to handle this we should need some time difference between these 2 operation, so I have made a custom formula date time field in user and set the time 55 minutes before the created date. See below image
Why I added this field because I want to add a time base workflow and in time base workflow, it need minimum an hours to execute. I have also added a custom field in user object, a checkbox “Show in Community” , so if the workflow executes after 5 min than it would update this checkbox field and on update the user record than the trigger would execute on user. So the purpose of this so to give some time elapse between user object creation and case sharing object. See the below time dependent workflow snapshot.
The rule criteria is mentioned in red box which show that if
the custom field is not checked than it would enter into the workflow.
Secondly, the red box showing 1 hour after the custom date time formula field,
we do not have any option to execute the workflow under an hour. Third one the
field update, it would mark check on the custom checkbox field. Immediately if
it mark the checkbox than it would hit the trigger and trigger will share the
object with the newly created user. I am not writing the User trigger here as
this trigger would be prettly kuch similar to the above trigger, only the difference
would be that in this trigger, we should maintain the final map with User Id
and list of case, the opposite logic to the above trigger, so happy coding guys
J