You need to sign in to do that
Don't have an account?
Holly Havelka 10
Help with Apex Sharing Trigger
Hi All,
I have the below trigger, and what I want to do is pull in the name of the group based on a field on the contact record where the after insert/after update is taking place. The field is an account lookup field on contact and is named: Acct__c. I want this to happen dynamically vs. having to hard code the name of the group.
I have the below trigger, and what I want to do is pull in the name of the group based on a field on the contact record where the after insert/after update is taking place. The field is an account lookup field on contact and is named: Acct__c. I want this to happen dynamically vs. having to hard code the name of the group.
trigger ContactMakePublicTrigger on Contact (after insert, after update) { ID groupId = [select id, Name from Group where Name = 'Cincinati User'].id; // inserting new records if (Trigger.isInsert) { List<ContactShare> sharesToCreate = new List<ContactShare>(); for (Contact contact : Trigger.new) { if (contact.Make_Public__c == true) { // create the new share for group ContactShare cs = new ContactShare(); cs.ContactAccessLevel = 'Edit'; cs.ContactId = contact.Id; cs.UserOrGroupId = groupId; sharesToCreate.add(cs); } } // do the DML to create shares if (!sharesToCreate.isEmpty()) insert sharesToCreate; // updating existing records } else if (Trigger.isUpdate) { List<ContactShare> sharesToCreate = new List<ContactShare>(); List<ID> shareIdsToDelete = new List<ID>(); for (Contact contact : Trigger.new) { // if the record was public but is now private -- delete the existing share if (Trigger.oldMap.get(contact.id).Make_Public__c == true && contact.Make_Public__c == false) { shareIdsToDelete.add(contact.id); // if the record was private but now is public -- create the new share for the group } else if (Trigger.oldMap.get(contact.id).Make_Public__c == false && contact.Make_Public__c == true) { // create the new share with read/write access ContactShare cs = new ContactShare(); cs.ContactAccessLevel = 'Edit'; cs.ContactId = contact.Id; cs.UserOrGroupId = groupId; sharesToCreate.add(cs); } } // do the DML to delete shares if (!shareIdsToDelete.isEmpty()) delete [select id from ContactShare where ContactId IN :shareIdsToDelete and RowCause = 'Manual']; // do the DML to create shares if (!sharesToCreate.isEmpty()) insert sharesToCreate; } }Any thoughts on how to rework the trigger to get the name of the lookup field dynamically?
I got this trigger to work correctly, here is my updated code:
All Answers
Get the list of all the groups in a List Group Object and then apply a for loop on that List based Group Object and then write the after logic inside the for Loop starting from //inserting records as in the code shared by you.
Regards,
Pankul
Your code shoulde be like below:
Try the below changes:
trigger ContactMakePublicTrigger on Contact (after insert, after update) {
//ID groupId = [select id, Name from Group where Name = 'Cincinati User'].id;
// Get the Group Details
List<Group> groups = [SELECT Email,Id,Name FROM Group];
system.debug('@@@ groups'+groups.size());
//Contact con = [select id, Name,Acct__r.Name from contact where id =: '0032800000UUC9U'];
//system.debug('@@@ Account ' + con.Acct__r.Name );
Map<String,Id> GroupMap = new MAp<String,Id>();
for( Group grp:groups)
{
if(grp.Name != null && grp.Name != '')
{
GroupMap.put(grp.Name,grp.Id);
}
}
// inserting new records
if (Trigger.isInsert) {
List<ContactShare> sharesToCreate = new List<ContactShare>();
for (Contact contact : Trigger.new) {
if (contact.Make_Public__c == true) {
// create the new share for group
ContactShare cs = new ContactShare();
cs.ContactAccessLevel = 'Edit';
cs.ContactId = contact.Id;
//cs.UserOrGroupId = groupId;
if(GroupMap.containsKey(cs.Acct__r.Name))
{
cs.UserOrGroupId = GroupMap.get(cs.Acct__r.Name); // Check here if you can able to access the Account name of lookup field as like this otherwisw we have query this Account from DB then get the Name with the help of Map,Soql mostly the above will work
}
sharesToCreate.add(cs);
}
}
// do the DML to create shares
if (!sharesToCreate.isEmpty())
insert sharesToCreate;
// updating existing records
} else if (Trigger.isUpdate) {
List<ContactShare> sharesToCreate = new List<ContactShare>();
List<ID> shareIdsToDelete = new List<ID>();
for (Contact contact : Trigger.new) {
// if the record was public but is now private -- delete the existing share
if (Trigger.oldMap.get(contact.id).Make_Public__c == true && contact.Make_Public__c == false) {
shareIdsToDelete.add(contact.id);
// if the record was private but now is public -- create the new share for the group
} else if (Trigger.oldMap.get(contact.id).Make_Public__c == false && contact.Make_Public__c == true) {
// create the new share with read/write access
ContactShare cs = new ContactShare();
cs.ContactAccessLevel = 'Edit';
cs.ContactId = contact.Id;
if(GroupMap.containsKey(cs.Acct__r.Name))
{
cs.UserOrGroupId = GroupMap.get(cs.Acct__r.Name);
}
//cs.UserOrGroupId = groupId;
sharesToCreate.add(cs);
}
}
// do the DML to delete shares
if (!shareIdsToDelete.isEmpty())
delete [select id from ContactShare where ContactId IN :shareIdsToDelete and RowCause = 'Manual'];
// do the DML to create shares
if (!sharesToCreate.isEmpty())
insert sharesToCreate;
}
}
Can you please Let me know if it helps or not!!!
If it helps don't forget to mark this as a best answer!!!
Thanks,
Raj
Sorry its my mistake:
trigger ContactMakePublicTrigger on Contact (after insert, after update) {
//ID groupId = [select id, Name from Group where Name = 'Cincinati User'].id;
// Get the Group Details
List<Group> groups = [SELECT Email,Id,Name FROM Group];
system.debug('@@@ groups'+groups.size());
//Contact con = [select id, Name,Acct__r.Name from contact where id =: '0032800000UUC9U'];
//system.debug('@@@ Account ' + con.Acct__r.Name );
Map<String,Id> GroupMap = new MAp<String,Id>();
for( Group grp:groups)
{
if(grp.Name != null && grp.Name != '')
{
GroupMap.put(grp.Name,grp.Id);
}
}
// inserting new records
if (Trigger.isInsert) {
List<ContactShare> sharesToCreate = new List<ContactShare>();
for (Contact contact : Trigger.new) {
if (contact.Make_Public__c == true) {
// create the new share for group
ContactShare cs = new ContactShare();
cs.ContactAccessLevel = 'Edit';
cs.ContactId = contact.Id;
//cs.UserOrGroupId = groupId;
if(GroupMap.containsKey(contact.Acct__r.Name))
{
cs.UserOrGroupId = GroupMap.get(contact.Acct__r.Name); // Check here if you can able to access the Account name of lookup field as like this otherwisw we have query this Account from DB then get the Name with the help of Map,Soql mostly the above will work
}
sharesToCreate.add(cs);
}
}
// do the DML to create shares
if (!sharesToCreate.isEmpty())
insert sharesToCreate;
// updating existing records
} else if (Trigger.isUpdate) {
List<ContactShare> sharesToCreate = new List<ContactShare>();
List<ID> shareIdsToDelete = new List<ID>();
for (Contact contact : Trigger.new) {
// if the record was public but is now private -- delete the existing share
if (Trigger.oldMap.get(contact.id).Make_Public__c == true && contact.Make_Public__c == false) {
shareIdsToDelete.add(contact.id);
// if the record was private but now is public -- create the new share for the group
} else if (Trigger.oldMap.get(contact.id).Make_Public__c == false && contact.Make_Public__c == true) {
// create the new share with read/write access
ContactShare cs = new ContactShare();
cs.ContactAccessLevel = 'Edit';
cs.ContactId = contact.Id;
if(GroupMap.containsKey(contact.Acct__r.Name))
{
cs.UserOrGroupId = GroupMap.get(contact.Acct__r.Name);
}
//cs.UserOrGroupId = groupId;
sharesToCreate.add(cs);
}
}
// do the DML to delete shares
if (!shareIdsToDelete.isEmpty())
delete [select id from ContactShare where ContactId IN :shareIdsToDelete and RowCause = 'Manual'];
// do the DML to create shares
if (!sharesToCreate.isEmpty())
insert sharesToCreate;
}
}
Can you please Let me know if it helps or not!!!
If it helps don't forget to mark this as a best answer!!!
Thanks,
Raj
Small update to avoid the null exception due to cross object reference field acct__r.name:
trigger ContactMakePublicTrigger on Contact (after insert, after update) {
//ID groupId = [select id, Name from Group where Name = 'Cincinati User'].id;
// Get the Account Name Details
Set<Id> AcctId = new Set<Id>();
List<Account> AccountLists = new List<Account>();
Map<Id,String> AccountNameMap = new Map<Id,String>();
for(Contact con : trigger.new)
{
if(con.Acct__c != null)
{
system.debug('@@@ Acct__c '+con.Acct__c);
system.debug('@@@ Acct__c Name '+ con.Acct__r.Name);
AcctId.add(con.Acct__c);
}
}
if(AcctId.size() > 0)
{
AccountLists = [select Id,name from Account where Id IN: AcctId];
}
for(Account acc :AccountLists )
{
AccountNameMap.put(acc.id,acc.Name);
}
system.debug('@@@ AccountNameMap values'+AccountNameMap.values());
// Get the Group Details
List<Group> groups = [SELECT Email,Id,Name FROM Group];
system.debug('@@@ groups'+groups.size());
//Contact con = [select id, Name,Acct__r.Name from contact where id =: '0032800000UUC9U'];
//system.debug('@@@ Account ' + con.Acct__r.Name );
Map<String,Id> GroupMap = new MAp<String,Id>();
for( Group grp:groups)
{
if(grp.Name != null && grp.Name != '')
{
GroupMap.put(grp.Name,grp.Id);
}
}
// inserting new records
if (Trigger.isInsert) {
List<ContactShare> sharesToCreate = new List<ContactShare>();
for (Contact contact : Trigger.new) {
if (contact.Make_Public__c == true) {
// create the new share for group
ContactShare cs = new ContactShare();
cs.ContactAccessLevel = 'Edit';
cs.ContactId = contact.Id;
//cs.UserOrGroupId = groupId;
if(AccountNameMap.containsKey(contact.Acct__c))
{
if(GroupMap.containsKey(AccountNameMap.get(contact.Acct__c))
{
cs.UserOrGroupId = GroupMap.get(AccountNameMap.get(contact.Acct__c));
}
}
sharesToCreate.add(cs);
}
}
// do the DML to create shares
if (!sharesToCreate.isEmpty())
insert sharesToCreate;
// updating existing records
} else if (Trigger.isUpdate) {
List<ContactShare> sharesToCreate = new List<ContactShare>();
List<ID> shareIdsToDelete = new List<ID>();
for (Contact contact : Trigger.new) {
// if the record was public but is now private -- delete the existing share
if (Trigger.oldMap.get(contact.id).Make_Public__c == true && contact.Make_Public__c == false) {
shareIdsToDelete.add(contact.id);
// if the record was private but now is public -- create the new share for the group
} else if (Trigger.oldMap.get(contact.id).Make_Public__c == false && contact.Make_Public__c == true) {
// create the new share with read/write access
ContactShare cs = new ContactShare();
cs.ContactAccessLevel = 'Edit';
cs.ContactId = contact.Id;
if(AccountNameMap.containsKey(contact.Acct__c))
{
if(GroupMap.containsKey(AccountNameMap.get(contact.Acct__c))
{
cs.UserOrGroupId = GroupMap.get(AccountNameMap.get(contact.Acct__c));
}
}
//cs.UserOrGroupId = groupId;
sharesToCreate.add(cs);
}
}
// do the DML to delete shares
if (!shareIdsToDelete.isEmpty())
delete [select id from ContactShare where ContactId IN :shareIdsToDelete and RowCause = 'Manual'];
// do the DML to create shares
if (!sharesToCreate.isEmpty())
insert sharesToCreate;
}
}
Can you please Let me know if it helps or not!!!
If it helps don't forget to mark this as a best answer!!!
Thanks,
Raj
I have the one question here:
How are you compare the group and acct__c field. is that acct__c and group name is same?
How you want to get the group id? based on which field.
Thanks,
Raj
The acct__c.name should equal the group name. The group ID would be once you find the group.name which is equal to acct__c.name, then the group.id would come from the identified group name.
I got this trigger to work correctly, here is my updated code: