You need to sign in to do that
Don't have an account?
dlCamelot
Easy Trigger (but not for me)
Trying to write a trigger that fires when a contact is created/updated. The trigger would update a lookup field on the account (Account.Primary_Contact__c). The correct ID comes from a contact record that has Contact.Primary_Contact__c = true.
Why won't this work?
trigger fillPrimaryonAcct on Contact (before insert, before update) {
//Collect IDs to update
List<Id> cIdList = new list<Id>();
List<Id> aIdList = new list<Id>();
//Loop
for(contact c: trigger.new) {
aIdList.add(c.Id);
}
//List that grabs the Id of the primary contact
List<Contact> pContact = [SELECT Id FROM Contact WHERE Primary_Contact__c = true, Id = :id];
}
Any better ways to do this would be appreciated!
Why won't this work?
trigger fillPrimaryonAcct on Contact (before insert, before update) {
//Collect IDs to update
List<Id> cIdList = new list<Id>();
List<Id> aIdList = new list<Id>();
//Loop
for(contact c: trigger.new) {
aIdList.add(c.Id);
}
//List that grabs the Id of the primary contact
List<Contact> pContact = [SELECT Id FROM Contact WHERE Primary_Contact__c = true, Id = :id];
}
Any better ways to do this would be appreciated!
trigger fillPrimaryonAcct on Contact (after insert, after update) {
//map of Account Id vs the primary Contact record
Map<Id, Contact> accountVsContacts = new Map<Id, Contact>();
//list to hold Accounts that would be affected
List<Account> accounts = new List<Account>();
//collect all Contacts that are primary along with their parent Account's Id
for(Contact c : Trigger.New)
{
if(c.Primary_Contact__c)
{
accountVsContacts.put(c.AccountId, c);
}
}
//query all Accounts for which a primary contact exists in the batch
accounts = [SELECT Id, Primary_Contact__c FROM Account WHERE Id IN :accountVsContacts.keySet()];
//iterate over all Account records and set the primary Contact
for(Account a : accounts)
{
a.Primary_Contact__c = accountVsContacts.get(a.Id).Id;
}
//commit changes to database
update accounts;
}
All Answers
2. In SOQL, filters need to be separated by an AND or OR. Comma won't work.
trigger fillPrimaryonAcct on Contact (after insert, after update) {
//map of Account Id vs the primary Contact record
Map<Id, Contact> accountVsContacts = new Map<Id, Contact>();
//list to hold Accounts that would be affected
List<Account> accounts = new List<Account>();
//collect all Contacts that are primary along with their parent Account's Id
for(Contact c : Trigger.New)
{
if(c.Primary_Contact__c)
{
accountVsContacts.put(c.AccountId, c);
}
}
//query all Accounts for which a primary contact exists in the batch
accounts = [SELECT Id, Primary_Contact__c FROM Account WHERE Id IN :accountVsContacts.keySet()];
//iterate over all Account records and set the primary Contact
for(Account a : accounts)
{
a.Primary_Contact__c = accountVsContacts.get(a.Id).Id;
}
//commit changes to database
update accounts;
}
If none of the answers helped you significantly, please post the solution. You may also mark your solution as the best answer.
Above code was just to give you an idea about how to approach your Usecase.
May be you should give it a try first and then if you are stuck, you can always get help. Some hints to make your task easier -
1. It would simplify the solution, if you can utilize a relationship query like -
[SELECT Id, Primary_Contact__c, (Select Id, Primary_Contact__c FROM Contacts) FROM Account WHERE Id IN :accountVsContacts.keySet()]. Also, you can have any valid clause/filter inside the inner query.
2. You may want some of your code to just execute during Update and not during Insert. Can be done using Trigger context variables like isInsert and isUpdate.
3. You may want to figure out if a Contact was earlier set as Primary and has been removed (as Primary) during the Update or vice-versa. Best way is to use something like -
for(Contact c : Trigger.New)
{
if(c.Primary_Contact__c != Trigger.oldMap.get(c.Id).Primary_Contact__c)
{
//your code to handle this
}
}
Happy Coding !!!