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
Sonia GenesseSonia Genesse 

Auto update a lookup field with a Trigger on a Customer Object for Detail Object

I realize after looking at the 2 additional Triggers needed, that they are a bit different. In these I would need to access the Detail object, not sure how to approach this.
 
Is this something you can help me with?
 
#1
I need to have the trigger update the Parts_Order_Line__c  (lookup) on the SVMXC__RMA_Shipment_Order__c object, the detail object is SVMXC__RMA_Shipment_Line__c the Line Number field = NAME.
 
Once populated both the Product__c and the Parts_Order_Line_Serial_Number__c (both formula text fields) would need to be populated.
 
The Order Number on the SVMXC__RMA_Shipment_Order__c object = NAME and on the detail object SVMXC__RMA_Shipment_Line__c = SVMXC__RMA_Shipment_Order__c

User-added image

#2
Need to have the trigger update the Work_Detail__c (lookup) on the  SVMXC__Service_Order__c object, the detail object is SVMXC__Service_Order_Line__c the Work Detail Line Number field = NAME, update where SVMXC__Line_Type__c (picklist)  = ‘Parts’
 
 
Once updated the Work_Detail_Part__c  (formula text field) would need to be populated.
 
The Work Order number (Service Order Number) on the SVMXC__Service_Order__c object  = NAME, the Work Order number on the detail object SVMXC__Service_Order_Line__c = SVMXC__Service_Order__c
 
User-added image

User-added image

Thanks for any assistance you can provide!
 
Sonia

 
Best Answer chosen by Sonia Genesse
pconpcon
This should do it for you
 
trigger PopulateWorkDetail on SVMX__Service_Order_Line__c (after insert) {
    List<SVMXC__Service_Order__c> workOrderToUpdate = new List<SVMXC__Service_Order__c>();

    for (SVMX__Service_Order_Line__c workDetail : Trigger.new) {
        if (
            workDetail.SVMXC__Line_Type__c == 'Parts' &&
            workDetail.SVMXC__Service_Order__c != null
        ) {
            workOrderToUpdate.add(new SVMXC__Service_Order__c(
                Id = workDetail.SVMXC__Service_Order__c,
                Work_Detail__c = workDetail.Id
            ));
        }
    }

    if (!workOrderToUpdate.isEmpty()) {
        update workOrderToUpdate;
    }
}

All Answers

pconpcon
Let's start with #1 and then we'll move on to #2.

I'm a little confused as to what you are trying todo and most of that is because I don't completely understand your object model.  You mention that formula fields would need to be updated.  Formula fields by definition are not updated, they are automatically "updated" whenever the data is viewed based on the current data.

So you are trying to set the Product field on X number of SVMXC__RMA_Shipment_Line__c objects that are children of your SVMXC__RMA_Shipment_Order__c.  The product field on your SVMXC__RMA_Shipment_Order__c is a text field that corresponds to the Name field on your SVMXC__Installed_Product__c object.
Sonia GenesseSonia Genesse
Here’s an example that might help: Without manually populated the Parts_Order_Line__c (lookup), I have no data in the formula fields when I leave this field blank, shown below. Once I fill in this lookup I’m able to see the two fields I wish to view. I used this for testing purposes, so I could create two new fields in place of these formulas. Does this help? [cid:image001.jpg@01D10CDB.DEC66490] [cid:image002.jpg@01D10CDB.DEC66490]
pconpcon
The images didn'g come through :/
Sonia GenesseSonia Genesse
User-added image

User-added image
pconpcon
That does clarify some things.  What data ties the SVMXC__RMA_Shipment_Order__c to a SVMXC__RMA_Shipment_Line__c.  On the previous post there was the Serial_Number__c field that was the Name of the product.  What is that on the SVMXC__RMA_Shipment_Order__c object?
Sonia GenesseSonia Genesse
The Order Number on the SVMXC__RMA_Shipment_Order__c object = NAME and on the detail object SVMXC__RMA_Shipment_Line__c = SVMXC__RMA_Shipment_Order__c

The  SVMXC__RMA_Shipment_Order__c object  is what is shown in the images posted above. And the SVMXC__RMA_Shipment_Line__c looks like this:

User-added image
pconpcon
I feel as dense as mud today.  If I were a human looking at the RMA Shipment Order page, how would I know what Parts Order Line to add to the Shipment?
Sonia GenesseSonia Genesse
Pls don't feel that way !! :)

Ok so the Parts Order Line is a Related List on the RMA Shipment Order page: 




User-added image
pconpcon
So if someone inserts a new Part Order Line then it should "roll up" to the Shipment page?  What happens if there are more than one order line.
Sonia GenesseSonia Genesse
Yes. that is correct.There should and can only be one record per Parts Order Line. Per our logic, only one Product can exist and print on an RMA form. If there are mutiple, a new Shipment would be entered.  
pconpcon
This turns out to be a pretty simple trigger.  You will need to update line 5 and 7 with the correct field name on the Shipment Line object that points to your Shipment Order.  And you'll need to update line 8 with the right field name on the Shipment Order object that points to the Shipment Line object.
 
trigger PopulateProduct on SVMXC__RMA_Shipment_Line__c (after insert) {
    List<SVMXC__RMA_Shipment_Order__c> orderList = new List<SVMXC__RMA_Shipment_Order__c>()

    for (SVMXC__RMA_Shipment_Line__c shipmentLine : Trigger.new) {
        if (shipmentLine.Product__c != null) { //TODO: Update this to be the right lookup field
            orderList.add(new SVMXC__RMA_Shipment_Order__c(
                Id = shipmentLine.Product__c, //TODO: Update this to be the right lookup field
                SVMXC__RMA_Shipment_Line__c = shipmentLine.Id //TODO: Update this to the the right target field
            ));
        }
    }

    if (!orderList.isEmpty()) {
        update orderList;
    }
}

And the second issue, you need to populate the Part field with the product's Id if the line type is equal to part?  This is going to be very close to the trigger from the other issue.  This trigger will probably need more love since I wasn't sure what the field names were.
 
trigger PopulateProduct on Work_Detail__c(before insert) {
    Set<String> productNumbers = new Set<String>();
    Map<String, SVMXC__Installed_Product__c> numberToProductMap = new Map<String, SVMXC__Installed_Product__c>();

    for (Work_Detail__c workDetail : Trigger.new) {
        if (workDetail.SVMXC__Line_Type__c == 'Parts') {
            productNumbers.add(workDetail.Product_Number__c);
        }
    }

    productNumbers.remove(null);

    if (!productNumbers.isEmpty()) {
        for (SVMXC__Installed_Product__c product : [
            select Name
            from SVMXC__Installed_Product__c
            where Name in :partNumbers
        ]) {
            numberToProductMap.put(product.Name, product);
        }   

        for (Work_Detail__c workDetail : Trigger.new) {
            if (
                workDetail.SVMXC__Line_Type__c == 'Parts' &&
                numberToProductMap.containsKey(workDetail.Product_Number__c)
            ) {
                workDetail.Part__c = numberToProductMap.get(workDetail.Product_Number__c).Id;
            }
        }
    }   
}
Sonia GenesseSonia Genesse
Did you want me to create new fields and remove the Formula fields I currently have in place?? 

As for #2 Part field name  = Work_Detail_Part__c where  SVMXC__Service_Order_Line__c.Name  = SVMXC__Service_Order__c.Work_Detail__c , need the Product Name (SVMXC__Installed_Product__c) not the Product ID 

I won't be able to test these right away since I need to deploy changes via change sets to Sandbox in order to test these triggers :/ 
So if I need to add fields as noted above, I'll need to do that first as well. Since we are not yet Live in our Prod Org, this will become our Sandbox post go-live.
pconpcon
No, you shouldn't need to create any new fields.  It all comes down to me not knowing the datastructure
Sonia GenesseSonia Genesse
Ok, I'll let you know how it goes once the Change Sets are up-to-date, I'll post an update.

Thanks again for helping me with this!!!
Sonia GenesseSonia Genesse
Hi PCON

I completed the Change Sets for #1, here is what I have in the Trigger (Note changes per your ToDo's, but I have one error:



User-added image
pconpcon
That line should read
 
SVMXC__RMA_Shipment_Line__c = shipmentLine.Parts_Order_Line__c

If Parts_Order_Line__c is the right right field on the SVMXC__RMA_Shipment_Line__c object.
Sonia GenesseSonia Genesse
Actually I think what we're looking for is the Line Number on the SVMXC__RMA_Shipment_Line__c object to polulate the Parts_Order_Line__c on SVMXC__RMA_Shipment_Order__c. If so, than that should be the NAME field, shown below.   

Though that's giving me an error as well....?

 
User-added image

User-added image
 
pconpcon
Right, my comment is to update the field name on your object from SVMXC__RMA_Shipment_Line__c to whatever the field name for "Parts Order Line" is on the SVMXC__RMA_Shipment_Order__c.  You'll want to make sure that you still has shipmentLine.Id there since that's how the lookup is done on the object.  It's not base on Name.
Sonia GenesseSonia Genesse
The field name on my object from SVMXC__RMA_Shipment_Line__c for the  Line Number is NAME, shown below.

That is the field we want to update the "Parts Order Line" on the  the SVMXC__RMA_Shipment_Order__c.  object.

However, this isn't working and throws an error........   "Invalid field SVMXC__RMA_Shipment_Line__c for SObject SVMXC__RMA_Shipment_Order__c at line 8 column 47"

OR am I being dense as mud today :)

User-added image
pconpcon
That is correct that the Name is what is being displayed.  However, that is not what pairs the two objects together.  If you could look at your SVMXC__RMA_Shipment_Order__c object and click on the field that is a Lookup(SVMXC__RMA_Shipment_Line__c) and find it's API name.  Then you'll take it and put it in the code below.   So assuming the Lookup on SVMXC__RMA_Shipment_Order__c has an API name of Bob__c then line 8 would be
 
Bob__c = shipmentLine.Id

This is because the Lookup field is populated with the Id of the object that it is pointing to.  The name is displayed because it's easier to understand than using the random id :)
Sonia GenesseSonia Genesse
Oh I see ok, I think I was focusing on updating the field to the right of the = sign ...   :)

Here is the compile error I am getting now, since this field update is occuring on the SVMXC__RMA_Shipment_Order__c obejct shouldn't line 1 be for this object or not?

User-added image

Thanks!
Sonia

 
pconpcon
This error happens when you change the name of your trigger.  You can do one of two things
  • Update the PopulateProduct name to be that of your Trigger name
  • Copy the text of this trigger, create a new trigger named PopulateProduct on the SVMXC__RMA_Shipment_Line__c object, delete the old trigger
Sonia GenesseSonia Genesse

Ok, not a very intuitive error, but I guess since the first Trigger we previously worked on had that name, I guess I can see why.

I now was able to place the Trigger (with a new name) on the SVMXC__RMA_Shipment_Line__c object and ran a quick test for creating a new Parts Order with a Parts Order Line.

The Parts Order Line had this error: 

User-added image

I did a quick search online and found it states the following, which was in regards to Account in this case:

You can't set the id of the account(or any object on insert), it gets set on its own. (this is why you see the error) 

Any ideas?
 


User-added image

Sonia GenesseSonia Genesse
Nevermind.... I think that  comment was for hardcoded Id's.... So I'm not sure what the issue is and/or what the error means.
Sonia GenesseSonia Genesse
I thought perhaps this could be due to a Look-up Filter criteria I have set on the SVMXC__RMA_Shipment_Order__c  object  for the Parts_Order_Line__c field, but I made it inactive and I still receive the same error   :/

Filter Criteria:   Parts Order Line: Parts Order ID EQUALS Parts Order: Record ID
 
pconpcon
No that error is because the Parts_Order_Line__c field isn't a Lookup to a SVMXC__RMA_Shipment_Line__c object.  Can you do me a favor and just take a screenshot or something of the custom fields on SVMXC__RMA_Shipment_Order__c ?
Sonia GenesseSonia Genesse
I will work on getting that to you. In the meantime here is that Parts-Order_Line__c, it is a Lookup relationship  :)

User-added image
pconpcon
Well, that's the problem.  That is a Lookup(Parts Order Line) and we are putting the id in for a SVMXC__RMA_Shipment_Line__c  That's why you're getting that error.
Sonia GenesseSonia Genesse
I'm a bit confused, I thought in your previuos post you said if the Parts_Order_Line__c field isn't a Lookup to SVMXC__RMA_Shipment_Line__c object, that was the reason for the error..?

So bcuz it is a lookup, we should not assign an Id to that field, what do we need to do to update/replace the use of the Id?
pconpcon
We really are just spinning our wheels here.  The only way I'll really be able to help moving forward is to take a look at all of the objects involved and see all of their fields.  If you do not feel comfortable with posting those here then I can provide you my contact information and you can email them to me.  Otherwise you'll either have to take the code I've provided and work out where it's gone wrong, or hire someone to do the development for you where they have access to your data structure.
Sonia GenesseSonia Genesse
I can share the Objects with you offline not a problem, just let me know how to get those to you.

Since we are working on Issue #1,  I will send you all Fields for Object SVMXC__RMA_Shipment_Order__c and SVMXC__RMA_Shipment_Line__c, pls let me know if you require anything else other than these two Objects listed.

Thanks!

 
 
pconpcon
You can email them to me at pcon@forcebuds.com
pconpcon
So this is because we did have the wrong field name, but it wasn't on line 8, it was on line 7.
 
trigger PopulateProduct on SVMXC__RMA_Shipment_Line__c (after insert) {
    List<SVMXC__RMA_Shipment_Order__c> orderList = new List<SVMXC__RMA_Shipment_Order__c>()

    for (SVMXC__RMA_Shipment_Line__c shipmentLine : Trigger.new) {
        if (shipmentLine.SVMX__RMA_Shipment_Order__c != null) {
            orderList.add(new SVMXC__RMA_Shipment_Order__c(
                Id = shipmentLine.SVMXC__RMA_Shipment_Order__c,
                Parts_Order_Line__c = shipmentLine.Id
            ));
        }
    }

    if (!orderList.isEmpty()) {
        update orderList;
    }
}

That should be what you need
Sonia GenesseSonia Genesse
Works perfectly!!!!!! Thank you so much :)

I'll work on getting the change sets over to Sandbox for #3, should I send you the Object details of that one as well to make the process go smoother? We should be very close
pconpcon
Awesome.  Yes, please go ahead and email me the object details.
pconpcon
Ok, so let me verify the flow of #2 real quick.
  1. Insert Work Order
  2. Insert Work Detail
    • If Line Type equals 'Parts'
      • Copy the Work Detail's value to it's parent Work Order
Sonia GenesseSonia Genesse
Yes, correct and it will update the Work Detail Part field on the Work Oorder.

One thing though, we are not using the Parent Work Order field, we us the auto numbering scheme to assign the Work Order number as the Record Id

User-added image

User-added image
 
pconpcon
This should do it for you
 
trigger PopulateWorkDetail on SVMX__Service_Order_Line__c (after insert) {
    List<SVMXC__Service_Order__c> workOrderToUpdate = new List<SVMXC__Service_Order__c>();

    for (SVMX__Service_Order_Line__c workDetail : Trigger.new) {
        if (
            workDetail.SVMXC__Line_Type__c == 'Parts' &&
            workDetail.SVMXC__Service_Order__c != null
        ) {
            workOrderToUpdate.add(new SVMXC__Service_Order__c(
                Id = workDetail.SVMXC__Service_Order__c,
                Work_Detail__c = workDetail.Id
            ));
        }
    }

    if (!workOrderToUpdate.isEmpty()) {
        update workOrderToUpdate;
    }
}
This was selected as the best answer
Sonia GenesseSonia Genesse
Ok thanks, I'll test it as soon as my Change Sets have been setup and deployed. I'll get back to you soon!
Sonia GenesseSonia Genesse
Everythigs looks good with my testing, so I think all is good.

Thanks so much for your time,I appreaciate everything. You've been a real life saver!!!