function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student 

Help with simple Account Name Update Trigger-Yet to find solution-

Hi guys and girls,

So I have posted this a few times and am yet to come up with a solution. The trigger's aim is to update the Account name dependent on the contacts associated with the account. The goal is to have the trigger update the account name in the way that should an account have two contacts, Ben Peters and Jane Peters, then the account name would equal = Peters, Ben and Peters, jane

At the moment, the trigger works except that it updates the name to be in the form, account name = and Peters, Ben and peters, Jane. 

I understand why it is doing this, but I am not sure how to phrase the code to avoid it. Originally I had a workflow rule which would automatically set the company Name in a lead record to be in the Lastname, FirstName format which would make the account name right upon lead conversion, however this method loses its effectiveness after you add another contact to the account.

This is my trigger:

trigger ContactTrigger on Contact (after insert,after update, after delete, after undelete) {
    Set<ID> setAccountIDs = new Set<ID>();
    for(Contact c : Trigger.new){
        setAccountIDs.add(c.AccountId);
    }
 
    List<Account> accounts = [Select ID, Name,(Select FirstName, LastName From Contacts)  From Account WHERE ID IN :setAccountIDs];
    for(Account a : accounts){
        String accName = '';
        for(Contact c : a.Contacts){
        accName +=' and '+c.LastName+', '+c.FirstName;                     
        }
        a.Name=accName;
    }
    update accounts;
 
}

The goal is to change the code so that should the account have one contact, the name will be just in the format 'Lastname, Firstname' then should another contact be added to the account the account name will be 1Lastname, 1Firstname and 2Lastname, 2Firstname

Thank you for your help in advance
Best Answer chosen by Developer.mikie.Apex.Student
ShaTShaT
Hey Mikie,

You need to put a condition over there .
if you are doing a insert than you need to check 
if(trigger.isInsert)
 and write your insert code .

if it is update than you check if(tigger.isupdate)

Please refer below link.

http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_triggers_context_variables.htm

Thanks
Shailu

All Answers

Phillip SouthernPhillip Southern
Hi there, so from my first look...really you just need some kind of boolean to say its the first pass through and you don't need the ' and ' string.  So for your loops you could do this:

for(Account a : accounts){
        String accName = '';
        Boolean hit = false;
        for(Contact c : a.Contacts){
             if(hit)
             {
                    accName+=' and ';
              }
           
             accName += c.LastName+', '+c.FirstName;  
             hit = true;                  
        }
        a.Name=accName;
    }


This way the first time through hit will be false...' and ' won't be appended...but each consecutive time through hit will be true, and then the ' and ' string will be added.
Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student
Hey Phillip,

Your code works perfectly when it comes to building the account name. First contact add changes to LastName, Firstname and then every contact add after that continue the LastName, Firstname and Lastname, Firstname process. So thank you so much, however when I attempted to delete a contact I received this error:

There were custom validation error(s) encountered while saving the affected record(s). The first validation error encountered was "Apex trigger ContactTrigger caused an unexpected exception, contact your administrator: ContactTrigger: execution of AfterDelete caused by: System.NullPointerException: Attempt to de-reference a null object: Trigger.ContactTrigger: line 3, column 1".

Click here to return to the previous page.

What could be causing this error?
 

ShaTShaT
Hey Mikie,

You need to put a condition over there .
if you are doing a insert than you need to check 
if(trigger.isInsert)
 and write your insert code .

if it is update than you check if(tigger.isupdate)

Please refer below link.

http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_triggers_context_variables.htm

Thanks
Shailu

This was selected as the best answer
Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student
Hi shailu, would you possibly be able to help me out by showing me how I would add the code to reference the deletion of a contact and as such the shortening of the account name?

Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student
Thank you shailu, I just need to figure out what the delete code would look like though. I assume the code I have at the moment is for after insert. I guess I could have to do the opposite, but how do you reference a contact that you are deleting so that you can remove it from the account name...
ShaTShaT
Hi Mikie,

If you want your trigger should not execute on delete,
Than just remove the delete from trigger

trigger ContactTrigger on Contact (after insert,after update)

you just use those dml operation which you want to excute. Such as insert Or update.

if you want that your trigger should excute on all operations

Than you need to check like
if (Trigger.isBefore) {
    if (Trigger.isDelete) {

Write your delete code

}

if it is insert than use

if (Trigger.isInsert) {

Write your insert code
}

}

when you will add these condtions they will bew only excuted when the respective dml is performed like insert or delete.

If you want to check the length of account name.

list<Contact>deleteContact= new list<Contact>();
for(Account a : accounts){
        String accName = '';
        for(Contact c : a.Contacts){
        accName +=' and '+c.LastName+', '+c.FirstName;                    
        }
        a.Name=accName;
    }
integer acclength =accName.length();
if(acclength<50){
deleteContact.add(a.Contacts);


}

delete deleteContact;

It will delete all the contacts for that account

Thanks
Shailu
Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student
Hey Shailu and phillip,

I figured it out, you were right Shailu as I did not need it. As soon as I edit one of the contacts the account name corrects itself if I have deleted acontact. Thank you both so mcuh for your help.
Phillip SouthernPhillip Southern
Hey Mikie, the issue is trigger.new is not available for delete operations...thats why you get a null pointer exception.  New represents the new version of the records....which in a delete operation does not exist.  Processing it through a delete operation seems like a valid scenario for your use case...so you can process like this when setting up your Set:  (use the old version of the records to get the accountid)

Set<ID> setAccountIDs = new Set<ID>();

    if(trigger.isdelete)
{
    for(Contact c : Trigger.old)
   {
        setAccountIds.add(c.Accountid);
    }
 }else
 {

    for(Contact c : Trigger.new){
        setAccountIDs.add(c.AccountId);
    }
}
Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student
Thank you for your help Phillip  you are a genius, is there anyway you could give me a quick hand in fixing my test code up? I am getting the error: Variable does not exist: setAccountIDs.

This is what I have so far:

@isTest
private class HelloWorldTestClass {
    static testMethod void validateHelloWorld() {
//create teast data
       Contact C = new Contact(FirstName='test1',lastName='test2');
       Account a = new Account(Name='test');
  
       insert c;
       insert a;
  
       // Retrieve data
       a = [Select ID, Name,(Select FirstName, LastName From Contacts)  From Account WHERE ID IN :setAccountIDs];
       System.debug('Value after trigger fired: ' + a.name);

       // Test that the trigger correctly updated the name
       System.assertEquals('test',a.name);
    }
}
Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student
@isTest
private class TestAccountNameTrigger {
    static testMethod void validateAccountNameTrigger() {
//create test data

Set<ID> setAccountIDs = new Set<ID>();
       Contact C = new Contact(FirstName='test1',lastName='test2');
       Account a = new Account(Name='test');

       insert c;
       insert a;

       // Retrieve data
       a = [Select ID, Name,(Select FirstName, LastName From Contacts)  From Account WHERE ID IN :setAccountIDs];
       System.debug('Value after trigger fired: ' + a.name);

       // Test that the trigger correctly updated the name
       System.assertEquals('test',a.name);
    }
}


I added the bit in bold and it allowed me to save..however it only passed 41%
Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student
System.QueryException: List has no rows for assignment to SObject

stack trace line 14
Phillip SouthernPhillip Southern
So in a test class...you are wanting to mimic a use case situation....you dont need to query back in to find something.  So all you need to do is create the account, insert it....create the contact (set accountID to the account you just created) and insert that....then you should be good.  you would need to query the account back to get any updated values and then test base on that...so you could do this:



@isTest
private class TestAccountNameTrigger {
    static testMethod void validateAccountNameTrigger() {
//create test data

       
       Account a = new Account(Name='test');
       insert a;
       Contact C = new Contact(FirstName='test1',lastName='test2', accountid = a.Id);
       insert c;

       // Retrieve data
       a = [Select ID, Name  From Account WHERE ID = a.Id];
       System.debug('Value after trigger fired: ' + a.name);

       // Test that the trigger correctly updated the name
       System.assertEquals('test2, test1',a.name);
    }
}
Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student
Hey philip, I tried the code except i am getting an error on line 13 collumn 53, about unexpected token: a.id. Why could this be happening, I thought we introduced a as a variable when we inserted the contact?