[SalesForce] Updating a related record in a trigger

I'm absolutly new to apex, started learning a few days ago and currently trying to set up a trigger, that updates a Lead, that is related via a look-up with my custom object. However, I'm failing at almost everything right now (even the tests …)

I really hope you can hint me to what I'm doing wrong. I don't ask for you to code for me.

So here's my situation:
MyCustomObject__c has a Lookup-Relationship AttachedLeadId__c with the Standard-Lead-Object.
The Lead has a custom Checkbox "HasCustomObject__c".

My Trigger is on "after update" of MyCustomObject__c and should tick the checkbox to true, if a Lead is in the lookup (and vice versa, tick it to false, if the relationship is deleted). As far as I am concerned (and please, correct me if I am wrong), this isn't possible via workflowrules or the process designer, because a Lead can have multiple CustomObjects in his related list, and the Trigger should only untick the Checkbox, if the lead has exactly zero related CustomObjects.

I already figured out, that AttachedLeadId__r isn't available in my Trigger, so here's my code:

trigger UpdateRelatedCORecords on MyCustomObject__c (after update) {

    Map<Id, Lead> newLeads = new Map<Id, Lead>();
    Map<Id, Lead> oldLeads = new Map<Id, Lead>();

    for ( MyCustomObject__c po : Trigger.new ) {        

        if ( po.AttachedLeadId__c != Trigger.oldMap.get(po.Id).AttachedLeadId__c ) {

            // add ids of new leads to update-list
            if ( po.AttachedLeadId__c != NULL ) {
                newLeads.put(po.AttachedLeadId__c, NULL);           
            }

            // add ids of old leads to update-list
            if ( Trigger.oldMap.get(po.Id).AttachedLeadId__c != NULL) {                 
                oldLeads.put(po.AttachedLeadId__c, NULL);          
            }

        }
    }

    // update new Leads in bulk    
    newLeads.remove(null);
    newLeads.putAll([SELECT ID, hasCustomObject__c FROM Lead WHERE Id IN :newLeads.keySet()]);
    for ( Lead l : newLeads.values() ) {
        l.hasCustomObject__c = true;
    }
    update newLeads.values();

    // update new Leads in bulk
    oldLeads.remove(null);
    oldLeads.putAll([SELECT ID, hasCustomObject__c FROM Lead WHERE Id IN :oldLeads.keySet()]);
    for ( Lead l : oldLeads.values() ) {
        l.hasCustomObject__c = false;
    }
    update oldLeads.values();  
}

So, what's most devastating: When I manually relate a Lead with my CustomObject, the flag is set correctly. However, if I run the code anonymously (or in my tests), the checkbox-update doesn't work.

Can anyone spot the issue here? Please?

EDIT—

Anonymous code, that fails:

MyCustomObject__c testOrga = new MyCustomObject__c (Name='test@test.de', id__c='95', organization__c='Testaccount'); 
Lead testLeadOne = new Lead(LastName='sLastName1', Company = 'Testcompany'); 
insert testOrga; 
insert testLeadOne; 

testOrga.AttachedLeadId__c = testLeadOne.Id; 
update testOrga; 

System.debug(testOrga.AttachedLeadId__c);
System.debug(testLeadOne.hasCustomObject__c);

Best Answer

Even if the suggested solution provided by @sfdcfox of querying the lead again may solve your problem, I see another logic flaw in your trigger.

if ( Trigger.oldMap.get(po.Id).AttachedLeadId__c != NULL) { oldLeads.put(po.AttachedLeadId__c, NULL); }

This code populates the oldLeads map with the new lead id po.AttachedLeadId__c. So when you change the lead from lead A to lead B, your trigger will first update lead B's hasCustomObject__c field to true as its available in newLeads map. Then oldLeads map also have lead B only and updates its hasCustomObject__c to false.

So lead A will be having true and lead B will still have false.

So change that part to

if ( Trigger.oldMap.get(po.Id).AttachedLeadId__c != NULL) { oldLeads.put( Trigger.oldMap.get(po.Id).AttachedLeadId__c , NULL); }

Hope I make some sense.

Related Topic