You need to sign in to do that
Don't have an account?
Torm Hustvet
Activity Trigger Causing Errors - SFDC for Outlook
Hello,
My org has a profile requiring confidentiality of opportunities and tasks. Opportunities was addressed via record types and sharing rules; however, it appears there was a custom object and trigger set up for the ability to make the tasks private to a specific profile (Profile A).
Our firm has recently rolled out SFDC for outlook and users in Profile A are unable to add e-mails to records due to the trigger. I believe the trigger creates the custom object and relates the task to it, but I'm a true novice at Apex.
Can someone help me determine what the trigger is doing, and what solution(s) are available to resolve the error? I am aware of the knowledge article on how to disable a trigger in produciton, but I would much rather modify the existing trigger to maintain the task record confidentiality current state.
Thanks,
Torm
Trigger:
trigger BT_Capital_Task on Task (before insert) {
/**
* If the user has the BT Capital profile or role OR the Create Opps Activities Both Teams permission set and the activity is record type BT Capital
* and the Activity is related to an Account or Contact, a BT_Capital_Activity__c object is created with a Master-Detail relationship to the Account if the Account does not already have one.
* The Activity is then updated to relate to the BT_Capital_Activity__c instead of the Account or Contact.
* BT_Capital_Activity__c objects are only visible to BT Capital users therefore any Activities owned by BT Capital users are hidden from non-BT Capital users.
**/
// get Profile and Role for BT Capital
Id bTCProfileId = [SELECT Id FROM Profile WHERE Name = 'Standard - BT Capital'].Id;
Id bTCRoleId = [SELECT Id FROM UserRole WHERE DeveloperName = 'BT_Capital'].Id;
// get Owners with Profile or Role as BT Capital
Set<Id> owners = new Set<Id>();
for(Task t : Trigger.New){
owners.add(t.OwnerId);
}
Set<Id> bTCUserSet = new Set<Id>();
for(User u : [SELECT Id FROM User WHERE Id IN: owners AND (ProfileId =: bTCProfileId OR UserRoleId =: bTCRoleId)]){
bTCUserSet.add(u.Id);
}
// check for Create Activities Both Teams permission set or System Admin profile
Boolean hasPermissionSet = false;
String userId = UserInfo.getUserId();
String userProfId = UserInfo.getProfileId();
Id sysAdminProfileId = [SELECT Id FROM Profile WHERE Name = 'System Administrator'].Id;
if(userProfId == sysAdminProfileId){
hasPermissionSet = true;
} else {
for(PermissionSetAssignment assignee : [SELECT AssigneeId FROM PermissionSetAssignment WHERE PermissionSetId IN (SELECT Id FROM PermissionSet WHERE Name = 'Create_Opps_Activities_Both_Teams') AND AssigneeId =: userId]){
if(userId == assignee.AssigneeId){
hasPermissionSet = true;
}
}
}
// get Event (BT Capital) record type ID
RecordType taskRecordTypeId = [SELECT Id FROM RecordType WHERE DeveloperName = 'Task_BT_Capital' AND SObjectType = 'Task'];
// get Account Ids where task relates to account
List<Id> taskAccountsIds = new List<Id>();
List<Id> taskContactsIds = new List<Id>();
for(Task t : Trigger.New){
// if task owner is BT Capital
if((bTCUserSet.contains(t.OwnerId) && t.RecordTypeId == taskRecordTypeId.Id) || (hasPermissionSet = true && t.RecordTypeId == taskRecordTypeId.Id)){
// if task relates to Account
if(t.WhatId != null){
Id what = t.WhatId;
if(what.getSObjectType() == Schema.Account.SObjectType){
// add account to taskAccountsIds list
taskAccountsIds.add(t.WhatId);
}
} else {
Id who = t.WhoId;
// if Contact get WhoId to find associated Account
if(who.getSobjectType() == Schema.Contact.SObjectType){
taskContactsIds.add(who);
}
}
}
}
// get Accounts
List<Account> taskAccounts = [SELECT Id, BT_Capital_Activity__c FROM Account WHERE Id IN: taskAccountsIds];
// get contact Accounts
List<Contact> contactsAccounts = [SELECT Id, AccountId FROM Contact WHERE Id IN: taskContactsIds];
Map<Id, Id> contactsAccountsMap = new Map<Id, Id>();
for(Contact c : contactsAccounts){
contactsAccountsMap.put(c.Id, c.AccountId);
}
// add contact Accounts to taskAccounts list
List<Account> accountsToAdd = [SELECT Id, BT_Capital_Activity__c FROM Account WHERE Id IN: contactsAccountsMap.values()];
taskAccounts.addAll(accountsToAdd);
// lists to upsert
Set<Account> taskAccountsToUpdate = new Set<Account>();
List<Task> tasksToUpdate = new List<Task>();
List<BT_Capital_Activity__c> bTCapitalActs = new List<BT_Capital_Activity__c>();
for(Task t : Trigger.New){
for(Account a : taskAccounts){
if(t.WhatId == a.Id || contactsAccountsMap.get(t.WhoId) == a.Id){
if(a.BT_Capital_Activity__c == null){
if(!taskAccountsToUpdate.contains(a)){
BT_Capital_Activity__c act = new BT_Capital_Activity__c(Account__c = a.Id);
bTCapitalActs.add(act);
taskAccountsToUpdate.add(a);
}
tasksToUpdate.add(t);
} else {
t.WhatId = a.BT_Capital_Activity__c;
}
}
}
}
// insert BT_Capital_Activity__c list, put into map with Account__c as key, Id as value
insert bTCapitalActs;
Map<Id, Id> actsMap = new Map<Id, Id>();
for(BT_Capital_Activity__c act : bTCapitalActs){
actsMap.put(act.Account__c, act.Id);
}
// update task.WhatId and account.BT_Capital_Activity__c or campaign.BT_Capital_Activity__c with BT_Capital_Activity__c.Id
for(Task t : tasksToUpdate){
for(Account a : taskAccountsToUpdate){
if(t.WhatId == a.Id || contactsAccountsMap.get(t.WhoId) == a.Id){
a.BT_Capital_Activity__c = actsMap.get(a.Id);
t.WhatId = actsMap.get(a.Id);
}
}
}
// put accounts in list and upsert
List<Account> taskAccountsToUpdateList = new List<Account>(taskAccountsToUpdate);
upsert taskAccountsToUpdateList;
// trigger end, tasks will now be inserted.
}
My org has a profile requiring confidentiality of opportunities and tasks. Opportunities was addressed via record types and sharing rules; however, it appears there was a custom object and trigger set up for the ability to make the tasks private to a specific profile (Profile A).
Our firm has recently rolled out SFDC for outlook and users in Profile A are unable to add e-mails to records due to the trigger. I believe the trigger creates the custom object and relates the task to it, but I'm a true novice at Apex.
Can someone help me determine what the trigger is doing, and what solution(s) are available to resolve the error? I am aware of the knowledge article on how to disable a trigger in produciton, but I would much rather modify the existing trigger to maintain the task record confidentiality current state.
Thanks,
Torm
Trigger:
trigger BT_Capital_Task on Task (before insert) {
/**
* If the user has the BT Capital profile or role OR the Create Opps Activities Both Teams permission set and the activity is record type BT Capital
* and the Activity is related to an Account or Contact, a BT_Capital_Activity__c object is created with a Master-Detail relationship to the Account if the Account does not already have one.
* The Activity is then updated to relate to the BT_Capital_Activity__c instead of the Account or Contact.
* BT_Capital_Activity__c objects are only visible to BT Capital users therefore any Activities owned by BT Capital users are hidden from non-BT Capital users.
**/
// get Profile and Role for BT Capital
Id bTCProfileId = [SELECT Id FROM Profile WHERE Name = 'Standard - BT Capital'].Id;
Id bTCRoleId = [SELECT Id FROM UserRole WHERE DeveloperName = 'BT_Capital'].Id;
// get Owners with Profile or Role as BT Capital
Set<Id> owners = new Set<Id>();
for(Task t : Trigger.New){
owners.add(t.OwnerId);
}
Set<Id> bTCUserSet = new Set<Id>();
for(User u : [SELECT Id FROM User WHERE Id IN: owners AND (ProfileId =: bTCProfileId OR UserRoleId =: bTCRoleId)]){
bTCUserSet.add(u.Id);
}
// check for Create Activities Both Teams permission set or System Admin profile
Boolean hasPermissionSet = false;
String userId = UserInfo.getUserId();
String userProfId = UserInfo.getProfileId();
Id sysAdminProfileId = [SELECT Id FROM Profile WHERE Name = 'System Administrator'].Id;
if(userProfId == sysAdminProfileId){
hasPermissionSet = true;
} else {
for(PermissionSetAssignment assignee : [SELECT AssigneeId FROM PermissionSetAssignment WHERE PermissionSetId IN (SELECT Id FROM PermissionSet WHERE Name = 'Create_Opps_Activities_Both_Teams') AND AssigneeId =: userId]){
if(userId == assignee.AssigneeId){
hasPermissionSet = true;
}
}
}
// get Event (BT Capital) record type ID
RecordType taskRecordTypeId = [SELECT Id FROM RecordType WHERE DeveloperName = 'Task_BT_Capital' AND SObjectType = 'Task'];
// get Account Ids where task relates to account
List<Id> taskAccountsIds = new List<Id>();
List<Id> taskContactsIds = new List<Id>();
for(Task t : Trigger.New){
// if task owner is BT Capital
if((bTCUserSet.contains(t.OwnerId) && t.RecordTypeId == taskRecordTypeId.Id) || (hasPermissionSet = true && t.RecordTypeId == taskRecordTypeId.Id)){
// if task relates to Account
if(t.WhatId != null){
Id what = t.WhatId;
if(what.getSObjectType() == Schema.Account.SObjectType){
// add account to taskAccountsIds list
taskAccountsIds.add(t.WhatId);
}
} else {
Id who = t.WhoId;
// if Contact get WhoId to find associated Account
if(who.getSobjectType() == Schema.Contact.SObjectType){
taskContactsIds.add(who);
}
}
}
}
// get Accounts
List<Account> taskAccounts = [SELECT Id, BT_Capital_Activity__c FROM Account WHERE Id IN: taskAccountsIds];
// get contact Accounts
List<Contact> contactsAccounts = [SELECT Id, AccountId FROM Contact WHERE Id IN: taskContactsIds];
Map<Id, Id> contactsAccountsMap = new Map<Id, Id>();
for(Contact c : contactsAccounts){
contactsAccountsMap.put(c.Id, c.AccountId);
}
// add contact Accounts to taskAccounts list
List<Account> accountsToAdd = [SELECT Id, BT_Capital_Activity__c FROM Account WHERE Id IN: contactsAccountsMap.values()];
taskAccounts.addAll(accountsToAdd);
// lists to upsert
Set<Account> taskAccountsToUpdate = new Set<Account>();
List<Task> tasksToUpdate = new List<Task>();
List<BT_Capital_Activity__c> bTCapitalActs = new List<BT_Capital_Activity__c>();
for(Task t : Trigger.New){
for(Account a : taskAccounts){
if(t.WhatId == a.Id || contactsAccountsMap.get(t.WhoId) == a.Id){
if(a.BT_Capital_Activity__c == null){
if(!taskAccountsToUpdate.contains(a)){
BT_Capital_Activity__c act = new BT_Capital_Activity__c(Account__c = a.Id);
bTCapitalActs.add(act);
taskAccountsToUpdate.add(a);
}
tasksToUpdate.add(t);
} else {
t.WhatId = a.BT_Capital_Activity__c;
}
}
}
}
// insert BT_Capital_Activity__c list, put into map with Account__c as key, Id as value
insert bTCapitalActs;
Map<Id, Id> actsMap = new Map<Id, Id>();
for(BT_Capital_Activity__c act : bTCapitalActs){
actsMap.put(act.Account__c, act.Id);
}
// update task.WhatId and account.BT_Capital_Activity__c or campaign.BT_Capital_Activity__c with BT_Capital_Activity__c.Id
for(Task t : tasksToUpdate){
for(Account a : taskAccountsToUpdate){
if(t.WhatId == a.Id || contactsAccountsMap.get(t.WhoId) == a.Id){
a.BT_Capital_Activity__c = actsMap.get(a.Id);
t.WhatId = actsMap.get(a.Id);
}
}
}
// put accounts in list and upsert
List<Account> taskAccountsToUpdateList = new List<Account>(taskAccountsToUpdate);
upsert taskAccountsToUpdateList;
// trigger end, tasks will now be inserted.
}