[SalesForce] How to insert 3rd level nested records using rest class

I am trying to insert Account/Contact/Customer records into SFDC using Rest API. i have written the following class. I am able to create the Accounts and Contacts, but I'm having issues creating Customer records. In my setup, Customer is a child of Contacts, and Contacts a child of Accounts. How should I rewrite my class and JSON to insert Customer records along with Contacts and Accounts in a single call?
Here's my apex class:

@RestResource(urlMapping='/test/*')
global with sharing class OrderWebServices{

@HttpPost
   global static void createSomething(Wrapper1 test){

         Account obj = new Account();
         obj.Name = test.name;
         obj.AccountNumber = test.accountnumber;
         obj.External_Id__c = test.externalid;
         insert obj;
         List<Contact> conList = new List<Contact>();

         for(Wrapper2 con : test.Wrapper2){
                  Contact obj2 = new Contact();
                  obj2.LastName = con.lastname;
                  obj2.Email = con.email;
                  obj2.AccountId = obj.Id;
                  conList.add(obj2);
         }
         insert conList;
        //Below doesn't insert related Customer
        List<Customer__c> csList = new List<Customer__c>();
        for(Wrapper3 cs : test.Wrapper2){
                  Customer__c obj3 = new Customer__c();
                  obj3.LastName__c = cs.lastname;
                  obj3.Email__c = cs.email;
                  obj3.AccoountId = obj.Id;
                  csList.add(obj2);
         }
         insert csList;      
    }
    global with sharing class Wrapper1{
      public String name{get;set;}
      public String accountnumber{get;set;}
      public List<Wrapper2> Wrapper2{get;set;}
    }
    global with sharing class Wrapper2{
     public String lastname{get;set;}
     public String email{get;set;}
    public List<Wrapper3> Wrapper3{get;set;}//Add this for Customer object?
    }
    global with sharing class Wrapper3{
     public String lastname{get;set;}
     public String email{get;set;}
    }
}

Here's my JSON:

{
"test": {
    "name": "Test Acc",
    "accountnumber": "12345",
    "externalid": "12345",
    "Wrapper2": [{
        "lastnmame": "last",
        "email": "test123@test.com",            
        "Wrapper3": [{
            "lastname": "customer",
            "email": "customer123@test.com"
        }]          
    },
    {
        "lastnmame": "last2",
        "email": "test456@test.com",            
        "Wrapper3": [{
            "lastname": "customer2",
            "email": "customer123@test.com"
        }]          
    }]
}

The Account record and Contact records are inserted, but the associated Customer__c records are not inserted. I have an external id field 'External_Id__c' which ties all three records, even though Contact is a child of Accounts, and Customer__c is a child of Contacts.

How can I revise the class to be able to insert multiple contacts and multiple Customer__c records?

Best Answer

You can create ContactWrapper class which contains standard Contact as a field and list of customers.

apex:

@RestResource(urlMapping='/Order/*')
global with sharing class OrderWebServicesV2 {

    private class OrderWrapper {
        Account account;
        list<ContactWrapper> contacts;
    }

    private class ContactWrapper {
        Contact contact;
        list<Customer__c> customers;
    }

    @HttpPost
    global static String doPost() {

        OrderWrapper container = (OrderWrapper)System.JSON.deserialize(
            RestContext.request.requestBody.tostring(), 
            OrderWrapper.class);

        Account acc = container.account;
        insert acc;

        list<Contact> contactsToInsert = new list <Contact>();
        for (ContactWrapper wcon :container.contacts) {
            wcon.contact.accountId = acc.id;
            contactsToInsert.add(wcon.contact);
        }
        insert contactsToInsert;

        //now wrapper list contains contact ids
        list<Customer__c> customersToInsert = new list <Customer__c>();
        for (ContactWrapper wcon :container.contacts) {
            for (Customer__c customer :wcon.customers) {
                customer.Contact__c = wcon.contact.id;
                customersToInsert.add(customer);
            }
        }
        insert customersToInsert;
        return acc.id;
    }
}

JSON:

{
    "account": {
        "name": "Wonderland"
    },
    "contacts": [{
        "contact": {
            "LastName": "Alice",
            "Email": "Alice@test.com"
        },
        "customers": [{
            "lastname__c": "Mad Hatter",
            "email__c": "Hatter@test.com"
        }, {
            "lastname__c": "Cheshire Cat",
            "email__c": "Cheshire@test.com"
        }]
    }, {
        "contact": {
            "LastName": "Queen",
            "Email": "Queen@test.com"
        },
        "customers": [{
            "lastname__c": "King",
            "email__c": "King@test.com"
        }]
    }]
}
Related Topic