1

What exist

So I've custom Object called Credit Memo where I want to relate one Order and I want multiple OrderItem in the Relate List(Related Tab). I don't have Master-Detail relationship. Or by using lookup relationship I can only relate one record?

As it's easy to relate order as I only have to relate one so I can just search and select but I'm unable to figure out how to add Order Item using basic UI also because I don't have any option in a Related tab for adding the Order Item but the Related list still shows me Order Products Tab.

I want to achieve these using REST API too, I've tried composite tree but it fails(as I'm not doing it properly of course).

What I want

Is there any way of adding multiple child records to the custom object using REST API? Like Array of Id's to realte?

Sorry, Maybe I'm missing basics of how Salesforce work as I'm beginner.

UPDATE: I think my question is little confusing, so here's the simpler question I thought of - "How to link existing OrderItem to the custom object using REST API while creating the Record of that Custom object."

UPDATE

I was doing something horribly wrong, now I can relate OrderItems exactly the way I want by doing following.

  1. Create Credit Memo

  2. Go to OrderItem search and select Credit Memo Save

  3. Do above for another OrderItem

By doing this I've two OrderItems in Credit Memo. So If I'm not wrong I've to do same via REST.

  1. Insert Credit Memo via REST and save the response Id.

  2. Update the existing OrderItem and set saved Credit Memo id to Credit Memo Lookup field.

  3. Do above for another OrderItem.

But is there any way doing this opposite? Like while creating the Credit Memo how can I give both ID's and relate them? So it will minimize my update API calls

API Service I'm trying

Endpoint https:///services/data/v42.0/composite/tree/Credit_Memo__c/

Request Body (I know this is the dumbest way a one can think of)

{
  "records":[
    {"attributes":{"type":"Credit_Memo__c","referenceId":"ref1"},
     "Name":"Test",
     "Order_Product__c":{
       "records":[
         {"attributes":{"type":"OrderItem","referenceId":"ref2"},
         "Id":"80229000000zltwAAA"}
       ]
     }
    }
  ]
}

Error

[
    {
        "message": "Cannot deserialize instance of reference from START_OBJECT value { or request may be missing a required field at [line:4, column:19]",
        "errorCode": "JSON_PARSER_ERROR"
    }
]
  • Please include what you've done so far (with the composite API), and the exact error message you receive or the behavior that needs to be changed. – David Reed Jun 21 '18 at 13:48
  • @DavidReed I think the way I've defined the relationship is not working as I expected. I want multiple OrderItem but I can only select one. That is the main problem so I think it is absurd to send multiple ids to single lookup field. Am I right? – Indrajeet Latthe Jun 21 '18 at 13:53
  • @IndrajeetLatthe can you post your code ? – naruto-sfdc Jun 21 '18 at 14:11
  • 1
    The composite API using the sobject tree resource is the right approach here. We won't be able to provide much help unless you provide the request body that you're trying to use, and the content of the error response that you're getting. – Derek F Jun 21 '18 at 14:30
  • @DerekF is this enough? – Indrajeet Latthe Jun 21 '18 at 15:02
0

I was waiting for some downtime to dive head-first into this, but that didn't really materialize.

I've just finished answering a similar question though, so this topic is fresh in my mind.

Like I said in my comment, I believe the "tree" resource to be the correct one to use. The documentation on the SObject Tree resource isn't exactly the clearest, but it does mention that you can nest up to 5 levels of child records in a single request.

One thing to note is that when you are using the SObject Tree resource to create records (or just try to create records in general), you do not specify an id for any of the records. The referenceId here is used by Salesforce to automatically set the appropriate relationship field (this will be important in a bit).

It's not entirely clear from your question what your object hierarchy is, but let's take a look at the example request from the create nested records documentation

{
"records" :[{
    "attributes" : {"type" : "Account", "referenceId" : "ref1"},
    "name" : "SampleAccount1",
    "phone" : "1234567890",
    "website" : "www.salesforce.com",
    "numberOfEmployees" : "100",
    "industry" : "Banking",
    "Contacts" : {
      "records" : [{
         "attributes" : {"type" : "Contact", "referenceId" : "ref2"},
         "lastname" : "Smith",
         "Title" : "President",
         "email" : "sample@salesforce.com"
         },{
         "attributes" : {"type" : "Contact", "referenceId" : "ref3"},
         "lastname" : "Evans",
         "title" : "Vice President",
         "email" : "sample@salesforce.com"
         }]
      }
    }
    // rest of request truncated
  ]
}

This is for creating an Account and immediately creating a Contact related to the Account.

The big difference between what you have and what this example shows is the label that contains the child records. It's a subtle difference unless you're familiar with parent-child subqueries in SOQL. Your attempt tries to use the name of the child SObject, whereas the documentation uses the child relationship name (Contacts instead of Contact).

The short explanation for why we use the child relationship name is because creating a master-detail or lookup relationship on a child object also causes a special "field" to be created on the parent object. This special "field" holds a List<SObject> (specifically a List of the child sobject's type), and its API name is the same as the child relationship name that you set when you create the relationship field on the child object.

It's hard to know what your child relationship name is between Credit_Memo__c and Order_Product__c, but it's likely Order_Products__r (the plural, and changing __c to __r). You can check this for yourself by looking at the detail page for your lookup relationship on the Order_Product__c object.

So, that all said, a well-formed request to accomplish what you're looking to do should look like this (make sure to remove my comments, as JSON doesn't support them)

{
  "records":[
    {"attributes":{"type":"Credit_Memo__c","referenceId":"ref1"},
     "Name":"Test",
     // You need to use the relationship name, and __r since it's a custom relationship
     "Order_Products__r":{
       "records":[
         // type name in the attributes here should match the API name of your object
         {"attributes":{"type":"Order_Product__c","referenceId":"ref2"},
          // Do not specify Ids, but be sure to include any other required fields
         },
         {"attributes":{"type":"Order_Product__c","referenceId":"ref3"},
           // If you want to populate data from your credit memo record, you may
           //   be able to use @{ref1.<field api name here>}, assuming that it's
           //   either the Id of your parent object, or one of the fields that
           //   you set (like "Name" in this example => @{ref1.Name})
           // I have, however, not tested this myself
         }
       ]
     }
    }
  ]
}
  • thanks for taking so much time for this, and by considering your example, you can assume that Credit_Memo is my parent which can have multiple order product/OrderItem. So the Order is already there with OrderItem so I already have OrderItem id's I just want to relate them to Credit Memo. – Indrajeet Latthe Jul 9 '18 at 15:55
  • I don't know if I got this correctly but do you mean I've to give the Name field in Order_Products__r records? Like say if there is one OrderItem with Name TestOrderItem I will give that? Or I'm completely wrong about this? – Indrajeet Latthe Jul 9 '18 at 15:56
  • @IndrajeetLatthe Oh, my answer is completely off the mark then. Also, if Name is something other than an autonumber field, then I think you would need to include that in the JSON for each Order_Product__c. However, that's only an issue if you're creating Order_Product__c records via the API. – Derek F Jul 9 '18 at 16:33
  • @IndrajeetLatthe Since your records already exist, the sobject tree resource isn't the thing to use. You might be able to use the "Composite" resource to first create your Credit_Memo__c and then use the reference to update Order_Product__c records, but you'd need to hard-code Order_Product__c Ids into the request. At this point, you're probably better off creating a Lightning Component or Visualforce Page to help users choose which Order_Product__c records to relate to a new Credit_Memo__c. – Derek F Jul 9 '18 at 16:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.