0

I am working on a web service callout in Apex which returns some child data for the Asset object. I can represent a class to depict the structure of the data that I am receiving.

[{
    "Id": "02i0000000000000C",
    "options": [{
            "name": "Conference Event",
            "startDate": "2019-01-01T00:00:00.000Z",
            "EndDate": "2023-01-01T00:00:00.000Z"
        },
        {
            "name": "Drama",
            "startDate": "2023-01-01T00:00:00.000Z",
            "EndDate": "2024-01-01T00:00:00.000Z"
        },
        {
            "name": "Magic Show",
            "startDate": "2020-01-01T00:00:00.000Z",
            "EndDate": "2022-01-01T00:00:00.000Z"
        }
    ]
}]

The options is a child object of Asset with the name Asset_Options__c. I need to query to Asset_Options__c for a given asset and compare the data with the above response and update Asset_Options__c records and I am not sure what is the best way to proceed. There is no need to consider the time portions of the date while comparing. However, whatever is coming from the web service response should overwrite what is available in the Asset_Options__c object in Salesforce. In short, below are the three scenarios:

Update Scenario

For ex, if the Asset_Option__c record for "Magic Show" has the start date of "2018-01-01T11:11:11.000Z" in Salesforce, it should be over written with the value coming from webservice response (2020-01-01T00:00:00.000Z).

Insert Scenario

Also, if an option that is coming from webservice is not found in Asset_Options__c record, it should be inserted as a new record.

Delete Scenario

Also, if the web service response comes with "Conference Event" and "Drama" where as Asset_Options__c has all three options, the "Magic Show" record should be deleted from the Asset_Options__c object.

Can someone help?

1
  • why don't you delete all Asset_Options__c records and insert them again with the latest response from web service? that would cover new/updated/deleted scenarios. I don't know, might be a quick solution, but I don't know all the automations you might have in place.
    – McCubo
    Commented May 24, 2022 at 9:55

1 Answer 1

1

Considering the web service callout response will be stringified JSON:

//serialized response from webservice callout
String jsonInput = '[{"Id":"02i0000000000000C","options":[{"name":"Conference Event","startDate":"2019-01-01T00:00:00.000Z","EndDate":"2023-01-01T00:00:00.000Z"},{"name":"Drama","startDate":"2023-01-01T00:00:00.000Z","EndDate":"2024-01-01T00:00:00.000Z"},{"name":"Magic Show","startDate":"2020-01-01T00:00:00.000Z","EndDate":"2022-01-01T00:00:00.000Z"}]}]';

//parse the response
List<Object> responseArray = (List<Object>)JSON.deserializeUntyped(jsonInput);
Map<String, Object> responseObject = (Map<String, Object>)(responseArray[0]);

//map of options - Map<name , object (name, enddate, startdate)>
Map<String, Map<String, Object>> optionsMap = new Map<String, Map<String, Object>>();
for(Object obj : (List<Object>)responseObject.get('options')){
    Map<String, Object> optionsObj = (Map<String, Object>)obj;
    optionsMap.put((String)optionsObj.get('name') , optionsObj);
}

//set of option names
//will be used to check which are new asset options to insert
Set<String> assetOptionsInsertKeys = optionsMap.keyset();

Get the Id of the Asset:

//If Id is null return 
if(responseObject.get('Id') == null){
    return;
}
Id assetId = responseObject.get('Id');

Get exisitng related Asset_Options__c records:

List<Asset_Options__c> assetOptionsList = [SELECT Id, Name, StartDate__c, EndDate__c FROM Asset_Options__c WHERE Asset__c =: assetId];

Prepare Upsert and Delete List:

List<Asset_Options__c> upsertList = new List<Asset_Options__c>();
List<Asset_Options__c> deleteList = new List<Asset_Options__c>();

for(Asset_Options__c assetObj : assetOptionsList){
    //If Asset option name not in response delete
    if(optionsMap.get(assetObj.Name) == null){
        deleteList.add(assetObj);
        continue;
    }
    
    //If Assset option name exists in response update the start date and end date
    if(optionsMap.get(assetObj.Name) != null){
        assetObj.StartDate__c = (optionsMap.get(assetObj.Name).get('startDate') != null) ? Date.valueOf((String)optionsMap.get(assetObj.Name).get('startDate')) : assetObj.StartDate__c;
        assetObj.EndDate__c = (optionsMap.get(assetObj.Name).get('EndDate') != null) ? Date.valueOf((String)optionsMap.get(assetObj.Name).get('EndDate')) : assetObj.EndDate__c;
        upsertList.add(assetObj);
    }
    
    //If Asset option name exists remove it from assetOptionsInsertKeys
    if(assetOptionsInsertKeys.contains(assetObj.Name)){
        assetOptionsInsertKeys.remove(assetObj.Name);
    }
}

//assetOptionsInsertKeys has only new options to be created
for(String assetKey : assetOptionsInsertKeys){
    Asset_Options__c assetObj = new Asset_Options__c();
    assetObj.Name = assetKey;
    assetObj.StartDate__c = (optionsMap.get(assetKey).get('startDate');
    assetObj.EndDate__c = (optionsMap.get(assetKey).get('EndDate');
    upsertList.add(assetObj);
}

Perform DML:

if(!deleteList.isEmpty()){
    delete deleteList;
}

if(!upsertList.isEmpty()){
    upsert upsertList;
}
2
  • Thanks for your response. I will try this out. I am not sure if we can do an upsert without an external id field on Asset_Options__c. Commented May 24, 2022 at 11:03
  • @BalajiPooruli You can always upsert against Id (null=create new record). You can also upsert against Name if the values are unique and it is not an auto-number field.
    – sfdcfox
    Commented May 24, 2022 at 12:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .