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
kiaya.caraway1.3900736803203115E12kiaya.caraway1.3900736803203115E12 

Trigger to update a contact look up field based on another lookup field on that record

I am helping a non-profit organization and I am very new to salesforce development (i'm an admin). What I am trying to accomplish is we have a contact (Nominee) and on their record a look-up field to another contact (referree). I need to write a trigger that will populate the account that contact (referree) is associated with on the contact (nominee) field referred_by_org__c  at that point in time.

This is my way around historical data - if the referree moves accouts I want to know what account they were associated with at the time they nominated contact (Nominee)

Any help would be very appreciated!
Kiaya
Best Answer chosen by kiaya.caraway1.3900736803203115E12
GlynAGlynA
<pre>
trigger RecordOriginalReferreeAccount on Contact ( before insert, before update )
{
    Set<Id> set_ReferreeIDs = new Set<Id>();
    for ( Contact theContact : trigger.new )
    {
        //  if there's no referree, then this contact is not a nominee
        //  if there's already a Referred By Org, skip this nominee
        if ( theContact.Referree__c == null || theContact.Referred_By_Org__c != null ) continue;
        set_ReferreeIDs.add( theContact.Referree__c );
    }

    Map<Id,Contact> map_Referrees = new Map<Id,Contact>
    (   [   SELECT  Id, AccountId
            FROM    Contact
            WHERE   Id IN :set_ReferreeIDs
        ]
    );

    for ( Contact theContact : trigger.new )
    {
        //  if there's no referree, then this contact is not a nominee
        //  if there's already a Referred By Org, skip this nominee
        if ( theContact.Referree__c == null || theContact.Referred_By_Org__c != null ) continue;
        theContact.Referred_By_Org__c = map_Referrees.get( theContact.Referree__c ).AccountId;
    }
}

//  run this in the Anonymous Execute window as many times as necessary to update all nominees
update
    [   SELECT  Id
        FROM    Contact
        WHERE   Referree__c != null AND Referred_By_Org__c == null
        LIMIT   10000
    ];
</pre>

All Answers

GlynAGlynA
The following post contains a possible trigger implementation for you.  It assumes that any Contact that has a lookup to a referree (which I called, "Referree__c" - you can change it to the actual field name) is a nominee.  Any contact without a referree is not a nominee.  If this is not the right way to identify a nominee Contact, you will have to change the code.

I wrote it as a "before" trigger because it modifies a field on the records in the trigger.  By doing the work "before" the records are written to the database, you don't have to update the records.

I've also included a line of code that you can run in the Anonymous Execute window (from Developer Console) to update existing nominee records.  It finds nominees that don't have a Referred By Org value, and updates them so that the trigger runs and updates the field.

Let me know if you have any questions.  I apologize in advance if there are any typos.

Glyn Anderson
Sr Developer | System Analyst | ClosedWon | closedwon.com
Certified Developer | Certified Advanced Administrator
Blog: GlynATheApexGuy.blogspot.com
Twitter: @GlynAtClosedWon

GlynAGlynA
<pre>
trigger RecordOriginalReferreeAccount on Contact ( before insert, before update )
{
    Set<Id> set_ReferreeIDs = new Set<Id>();
    for ( Contact theContact : trigger.new )
    {
        //  if there's no referree, then this contact is not a nominee
        if ( theContact.Referree__c == null ) continue;
        set_ReferreeIDs.add( theContact.Referree__c );
    }

    Map<Id,Contact> map_Referrees = new Map<Id,Contact>
    (   [   SELECT  Id, AccountId
            FROM    Contact
            WHERE   Id IN :set_ReferreeIDs
        ]
    );

    for ( Contact theContact : trigger.new )
    {
        //  if there's no referree, then this contact is not a nominee
        if ( theContact.Referree__c == null ) continue;
        theContact.Referred_By_Org__c = map_Referrees.get( theContact.Referree__c ).AccountId;
    }
}

//  run this in the Anonymous Execute window as many times as necessary to update all nominees
update
    [   SELECT  Id
        FROM    Contact
        WHERE   Referree__c != null AND Referred_By_Org__c == null
        LIMIT   10000
    ];
</pre>
GlynAGlynA
I was thinking about my solution, and realized that it will change the Referred By Org anytime the nominee is updated; but it should only set it the first time and never change it after that.  So the following post has an update to the code that fixes the problem.

-Glyn

GlynAGlynA
<pre>
trigger RecordOriginalReferreeAccount on Contact ( before insert, before update )
{
    Set<Id> set_ReferreeIDs = new Set<Id>();
    for ( Contact theContact : trigger.new )
    {
        //  if there's no referree, then this contact is not a nominee
        //  if there's already a Referred By Org, skip this nominee
        if ( theContact.Referree__c == null || theContact.Referred_By_Org__c != null ) continue;
        set_ReferreeIDs.add( theContact.Referree__c );
    }

    Map<Id,Contact> map_Referrees = new Map<Id,Contact>
    (   [   SELECT  Id, AccountId
            FROM    Contact
            WHERE   Id IN :set_ReferreeIDs
        ]
    );

    for ( Contact theContact : trigger.new )
    {
        //  if there's no referree, then this contact is not a nominee
        //  if there's already a Referred By Org, skip this nominee
        if ( theContact.Referree__c == null || theContact.Referred_By_Org__c != null ) continue;
        theContact.Referred_By_Org__c = map_Referrees.get( theContact.Referree__c ).AccountId;
    }
}

//  run this in the Anonymous Execute window as many times as necessary to update all nominees
update
    [   SELECT  Id
        FROM    Contact
        WHERE   Referree__c != null AND Referred_By_Org__c == null
        LIMIT   10000
    ];
</pre>
This was selected as the best answer
kiaya.caraway1.3900736803203115E12kiaya.caraway1.3900736803203115E12
Thank you thank you!