You need to sign in to do that
Don't have an account?
L.Delano
Account Sharing Trigger
We have some strict requirements on account sharing amongst sales teams members in our org. I have created a custom object which holds the rules of who can see which account based on the Owner on the account. I wrote a trigger which makes use of AccountTeamMember object. Everything is working fine. However I would like to bulkify my trigger but have not been able too after a few attempts.
Below is part of my trigger I would like to bulkify: (the rest of it has code unrelated to account sharing).
Could someone suggest a solution?
Thank you
Below is part of my trigger I would like to bulkify: (the rest of it has code unrelated to account sharing).
Could someone suggest a solution?
Thank you
List<AccountTeamMember> atmToAdd = new List<AccountTeamMember>(); for (Account a : trigger.new) { //Custom object holding sharing rules SharingRuleMap__c[] sMap = [SELECT SharingWith_ID__c, TeamMemberRole__c, AccountAccessLevel__c, ContactAccessLevel__c, CaseAccessLevel__c, OpportunityAccessLevel__c FROM SharingRuleMap__c WHERE Dealing_Rep__c = :a.OwnerId]; if (sMap.size() > 0) { For (Integer i=0; i<sMap.size();i++) { AccountTeamMember atm = new AccountTeamMember(); atm.AccountId = a.Id; atm.UserId = sMap.get(i).SharingWith_ID__c; atm.TeamMemberRole = sMap.get(i).TeamMemberRole__c; atm.AccountAccessLevel = sMap.get(i).AccountAccessLevel__c; atm.ContactAccessLevel = sMap.get(i).ContactAccessLevel__c; atm.CaseAccessLevel = sMap.get(i).CaseAccessLevel__c; atm.OpportunityAccessLevel = sMap.get(i).OpportunityAccessLevel__c; atmToAdd.add(atm); } } } insert atmToAdd;
In that case all you do is, check if the Key exists in the map and if it does, get the list of values related to the key, and add the new value to the list.
You just need to do a minor modification to the code. I have done it for you.
Feel free to ask questions if you have.
All Answers
First of all, you should NEVER put a query inside a for loop!
Then you should, inside a for loop for trigger, first gather all owner ids into a list. Like
Then after first for loop select your rules, and parse them into an actual Map by owner And finally run a second loop for triggered accounts where you'll do the rest
You have to create an extra list to store the ownerId and a map to store the owner id and SharingRuleMap__c
so you can store all the ownerid in the list and use the same list to query the SharingRuleMap__c records. Then you loop over to the data returned by the query and save the ownerid and SharingRuleMap__c record in the map.
then just call the get method of map inside the for(Account a : trigger.new) loop to get SharingRuleMap__c records based on the a.ownerId.
I hope this is the correct approach. Guys Please correct me if I am wrong.
List<id> listownerID = new list<id>();
map<id,SharingRuleMap__c> mapofownerIdandsharingrule = new map<id,SharingRuleMap__c>();
for (Account a : trigger.new)
{
listownerID.add(a.OwnerId);
}
SharingRuleMap__c[] sMap1 = [SELECT SharingWith_ID__c,
TeamMemberRole__c,
AccountAccessLevel__c,
ContactAccessLevel__c,
CaseAccessLevel__c,
OpportunityAccessLevel__c
FROM SharingRuleMap__c
WHERE Dealing_Rep__c IN : listownerID];
for(SharingRuleMap__c ss :sMap1 )
{
mapofownerIdandsharingrule.put(ss.Dealing_Rep__c,ss);
}
for (Account a : trigger.new)
{
//Custom object holding sharing rules
/*SharingRuleMap__c[] sMap = [SELECT SharingWith_ID__c,
TeamMemberRole__c,
AccountAccessLevel__c,
ContactAccessLevel__c,
CaseAccessLevel__c,
OpportunityAccessLevel__c
FROM SharingRuleMap__c
WHERE Dealing_Rep__c = :a.OwnerId]; */
list<SharingRuleMap__c> sMap = mapofownerIdandsharingrule.get(a.OwnerId);
if (sMap.size() > 0)
{
For (Integer i=0; i<sMap.size();i++)
{
AccountTeamMember atm = new AccountTeamMember();
atm.AccountId = a.Id;
atm.UserId = sMap.get(i).SharingWith_ID__c;
atm.TeamMemberRole = sMap.get(i).TeamMemberRole__c;
atm.AccountAccessLevel = sMap.get(i).AccountAccessLevel__c;
atm.ContactAccessLevel = sMap.get(i).ContactAccessLevel__c;
atm.CaseAccessLevel = sMap.get(i).CaseAccessLevel__c;
atm.OpportunityAccessLevel = sMap.get(i).OpportunityAccessLevel__c;
atmToAdd.add(atm);
}
}
}
insert atmToAdd;
The SharingRuleMap__c custom object contains multiple records for the same OwnerId, one record per user with whom the Owners are sharing their accounts with.
The map cannot use the OwnerId as the key since keys cannot be duplicated. In my attempts I got close to you suggested, but I don’t know how to get around the map problem.
Unfortunately this has the same problem. When iterating through "lstSharingRuleMap" and using the OwnerId (Dealing_Rep__c) as the key, the map will end up with unique records only.
What lstSharingRuleMap contains is something like this:
OwnerId 1 sharing with User 1
OwnerId 1 sharing with User 2
OwnerId 1 sharing with User 3
... and so on for other account owners. If you put this into a map where the Key is the OwnerId the only key/value pair would be the last one.
Have you tried using "Map<Id,List<SharingRuleMap__c>>". Below is the link for how to use it:
https://salesforce.stackexchange.com/questions/87951/better-way-to-use-map-of-list
In that case all you do is, check if the Key exists in the map and if it does, get the list of values related to the key, and add the new value to the list.
You just need to do a minor modification to the code. I have done it for you.
Feel free to ask questions if you have.
Thank you all fro your suggestions.