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
Phuc Nguyen 18Phuc Nguyen 18 

Update records from lookup record

Hello Alll,

I am trying to create a trigger handler class to update records based on the field values from another object record.  But there is no direct relationship between the 2  objects.  Do I have have to create a relationship between them?
  • Object 1 lookup to obejct 3
  • Object 2 lookup to object 1
  • Object 3

I am trying to take the fields from object 3(only 1 record) and match them to the name of the records of object 2.
So field on obect 3 records are called
  • 'big dog - old' 
  • 'big cat - young'
  • small pig - old'
Name of records for obejct 2 are
  • record name is 'big dog' 
  • record name is 'big cat'
  • record name is 'small pig'
How do I do this when there is no direct relationship between the 2 objects.  Object 3 is a lookup on Object 1 and object 2 are children records of object 1? 

Thank you,
P
Best Answer chosen by Phuc Nguyen 18
David Zhu 🔥David Zhu 🔥
You may try this, I added a method to handle get merch field name using "big dog" to "big dog - Old"
 
public static void UpdateObject2Method(Map<Id,object1> parentObjects)    //pass trigger.newMap (Ojbect1) to parentObjects
    {
        List<Id> object1Ids = new List<Id>();
        Merch__c merch = [select id,field1__c,field2__c,field3__c,.... from Merch__c  limit 1];


        List<Finance__c> financeList= [Select Id,object1__c,price__c,totalamt__c,financerecordName__c from Finance__c  where project__c in : parentObjects.KeySet()];
        //assume we need to get qty from object3 and use to calculate totalamt on object2 records

        Map<String, Schema.SObjectField> merchMap = Schema.SObjectType.Merch__c .fields.getMap();

        for (Finance__c finance : financeList)
        {
            
            string  financeRecordName = finance.financeRecordName__c;   //get the finance record name. i.e. big dog

            string merchFieldName = getFieldName(merchMap,financeRecordName);

            string qty = string.valueof(merch.get(merchFieldName));

            finance.totalamt__c = obj2.price__c * decimal.valueof(qty);   //assume totalamt and price are decimal fields.
        }

        update object2List;

    }

    private static string getFieldName(Map<String, Schema.SObjectField> merchMap,string financeRecordName)
    {
        //the purpose of this method is from finance record name ("big dog") to get the corresponding merch__c field ("big dog - old")
        string result = '';

        for (string s : merchMap.KeySet())
        {
            if (s.startsWith(financeRecordName))
            {
                result = s;
                break;
            }
        }
        return result;
    }

 

All Answers

Agustin BAgustin B
HI P, from your definition:
Object 1 lookup to obejct 3
Object 2 lookup to object 1
Object 3

You could do something like this in your trigger for object 3:
1)Map<Id, Object1 > object1Map = new Map<Id, Object1 >([select Id,Name from Object1 where object3 IN : trigger.new]);
2)Map<Id, Object2 > object2Map = new Map<Id, Object2 >([select Id,Name from Object2 where object1 IN : object1Map.keyset()]);

From that you can iterate the trigger.new to validate the name of the object 2 record name.

If it help please like and mark as correct so it can be of use to others having the same question
Phuc Nguyen 18Phuc Nguyen 18
Thank you for the reply Agustin,
How can I do it from Object 1?  I was thinking the triggerhandler would trigger when a user adds the lookup value to Object 1.
Thanks,
P
Phuc Nguyen 18Phuc Nguyen 18
Could I do something like this
global void beforeupdate(sobject so)
List<object1> o1  = [ select Id, ( Select object1__c,qty__c From Object2__r) 
from Object1 where Id IN : so.id];

 List<Object2> obj2s = new List<Object2>();

for( Object2 ob2 : object2s ) {

 if (ob2.name = o1.Object3.fieldname 
{
match record with field name?       
}
 }

 
David Zhu 🔥David Zhu 🔥
I am very confused about what the object relationships and what you want to accomplish. 

1. The relationships have already been added to three objects, is it correct?
    Object 1 lookup to obejct 3 
    Object 2 lookup to object 1

2. If not, it seems you want to use field on object 3 and object 2 to do the match, which object are you going to update after the match?
  
3. On which object you want to create the trigger?

 
Phuc Nguyen 18Phuc Nguyen 18
I will try to explain this better.
We can call Object1 a parent record (Project)
Object2(invoices) are child records on Object1
Object3(Merch) is a look field on Object1
So when a user selects a lookup value and saves the record(object1) I want to match the fields from the lookup(Object3) record to the any existing child records(Object2)

On object3 there are fields with api names like
'big dog - old' 
'big cat - young'
small pig - old'

Object2 records
record name is 'big dog' 
record name is 'big cat'
record name is 'small pig'

I am trying to match the field names from the lookup record(Object3) to the record names on Object2 
So field 'big dog - old' has a value of 5. I want to copy this value to the qty field on record  'big dog'
Field 'big cat - young' has a value 9. I want to copy this value to the qty field on record  'big cat'
So I want to have the triggerhandler on Object1 

Hopefully I did not make this more confusing.
P
David Zhu 🔥David Zhu 🔥
1. The trigger will be on Object 1. It should be an AFTER INSERT and AFTER UPDATE trigger.

2. You may refer to the following code for trigger handler class.

   public static void UpdateObject2Method(Map<Id,object1> parentObjects)    //pass trigger.newMap (Ojbect1) to parentObjects
   {
        List<Id> object1Ids = new List<Id>();
        List<Id> object3Ids = new List<Id>();
        for (Id oId : parentObjects.KeySet())
        {
            object3Ids.add(parentObjects.get(oId).object3__c);
            object1Ids.add(oId);
        }

        Map<Id,Object3> object3Map = new Map<Id,object3>([Select Id,qty__c from object3 where id in : object3Ids]);

        List<object2> object2List= [Select Id,object1__c,price__c,totalamt__c from object2 where object1 in : object1Ids];
        //assume we need to get qty from object3 and use to calculate totalamt on object2 records

        for (object2 obj2 : object2List)
        {
            Object1 obj1 = parentObjects.get(obj2.object1__c);
            object3 obj3 = object3Map.get(obj1.object3__c);

            integer qty = obj3.qty__c;

            obj2.totalamt__c = obj2.price__c * decimal.valueof(qty;   //assume totalamt and price are decimal fields.
        }

        update object2List;

   }
Phuc Nguyen 18Phuc Nguyen 18
Hey David,
Do we not have to compare the Field Name on Object3(lookup) to the Record Name of Object2(child)? There are multiple fields on Object3 that needs to be matched to Record Names of Object2. 
Thanks,
P
David Zhu 🔥David Zhu 🔥
Just want to clarify:
1. The values of picklist of object1 are the field api names for object3.  it is not lookup relationship.
2. In Object 2, use the api name selected in Object1 record, pull the value from corresponding field of object 3 and do calculation. 
3. Object3 has no relationship to object 1 or 2.
Is my understanding correct?
 
David Zhu 🔥David Zhu 🔥
You may use the following code for trigger handler.
 
public static void UpdateObject2Method(Map<Id,object1> parentObjects)    //pass trigger.newMap (Ojbect1) to parentObjects
    {
        List<Id> object1Ids = new List<Id>();
        Object3 obj3 = [select id,field1__c,field2__c,field3__c,.... from object3__c limit 1];


        List<object2__c> object2List= [Select Id,object1__c,price__c,totalamt__c from object2__c where object1__c in : parentObjects.KeySet()];
        //assume we need to get qty from object3 and use to calculate totalamt on object2 records

        for (object2__c obj2 : object2List)
        {
            Object1 obj1 = parentObjects.get(obj2.object1__c);  
            string  obj3FieldName = obj1.object3__c;   //result could be field1__c,field2__c or any field name of object3

            object qty = obj3.get(obj3FieldName);

            obj2.totalamt__c = obj2.price__c * decimal.valueof(qty);   //assume totalamt and price are decimal fields.
        }

        update object2List;

    }

 
Phuc Nguyen 18Phuc Nguyen 18
Apologies for the confusion
I probably should have just used the obejct names:
Object1 - Project - Parent
Object2 - Finance__c - Child 
Object3 - Merch__c - Lookup on Project 

On Merch__c there are fields with api names like
'big dog - old' 
'big cat - young'
small pig - old'
The Finance__c records will have names like this
Finance__c  record name is 'big dog' 
Finance__c record name is 'big cat'
Finance__c record name is 'small pig'
When a user add a Merch lookup value on the Project record.
I need to comapre the field values of the Merch__c record to the all of the existing Finance record Names.
So field 'big dog - old' on the Merch__c record has a  value of 5.  I need to query the Finance record to see if there is a Fiance record associetd to the Project that has a name of 'big dog'.  If the Finance_c record exist.  Update the qty filed to 5.
The biggest issue I see is how do you match the Field Name from the look record to Record names of the Finance Object becasue they are not an exact match.
They do follow a pattern though.  The Fiance record Name will always be the the text value to the left of the '-'  when you look at the Merch__c field value.
Merch__c field API name = small pig - old
Fiance Record Name = small pig

Please let me know if I need to supply more detail.
Thank you,
P
Phuc Nguyen 18Phuc Nguyen 18
Hey David,
I am having an issue with valueof(Object) from the type Decimal on line 17 of your example. 
Is obj3FieldName variable.  There are no calculations but I have 2 feilds that are being copied over from 1one object to the other
Can I  have
object qty = LS.get(lsfieldname);
object est = LS.get(lsfieldname2);

Still trying to figure out the field record name matching since they are not exact matches.
Thansk for all your help and time,
P
 
Phuc Nguyen 18Phuc Nguyen 18
Hello David,
Let me know if you have any thoughts on how to match the Merch record field Names to the Finance record Names.
Thank you,
P
David Zhu 🔥David Zhu 🔥
You may try this, I added a method to handle get merch field name using "big dog" to "big dog - Old"
 
public static void UpdateObject2Method(Map<Id,object1> parentObjects)    //pass trigger.newMap (Ojbect1) to parentObjects
    {
        List<Id> object1Ids = new List<Id>();
        Merch__c merch = [select id,field1__c,field2__c,field3__c,.... from Merch__c  limit 1];


        List<Finance__c> financeList= [Select Id,object1__c,price__c,totalamt__c,financerecordName__c from Finance__c  where project__c in : parentObjects.KeySet()];
        //assume we need to get qty from object3 and use to calculate totalamt on object2 records

        Map<String, Schema.SObjectField> merchMap = Schema.SObjectType.Merch__c .fields.getMap();

        for (Finance__c finance : financeList)
        {
            
            string  financeRecordName = finance.financeRecordName__c;   //get the finance record name. i.e. big dog

            string merchFieldName = getFieldName(merchMap,financeRecordName);

            string qty = string.valueof(merch.get(merchFieldName));

            finance.totalamt__c = obj2.price__c * decimal.valueof(qty);   //assume totalamt and price are decimal fields.
        }

        update object2List;

    }

    private static string getFieldName(Map<String, Schema.SObjectField> merchMap,string financeRecordName)
    {
        //the purpose of this method is from finance record name ("big dog") to get the corresponding merch__c field ("big dog - old")
        string result = '';

        for (string s : merchMap.KeySet())
        {
            if (s.startsWith(financeRecordName))
            {
                result = s;
                break;
            }
        }
        return result;
    }

 
This was selected as the best answer