You need to sign in to do that
Don't have an account?
Admin: Looking for help with using Custom Meta Data to build request body
Hello
I have this class that is making the request body for an integration with netsuite.
public class netsuite_CustomerMap implements INetsuiteMap{ public map<string, object> getNSMap(SObject sobj) { Account acc = (Account)sobj; string objectName = acc.getSObjectType().getDescribe().getName(); netsuite_Service nsService = new netsuite_Service(); map<string,map<string, Netsuite_Mapping__mdt>> ns_Map = nsService.getNSDefaultMap(); map<string, object> objMap = new map<string, object>(); objMap.put('companyname',acc.Name); objMap.put('externalid', acc.Id); objMap.put('recordtype', ns_Map.get('recordtype').get(objectName).Netsuite_Value__c); objMap.put('altPhone',acc.Phone); objMap.put('currency', ns_Map.get('currency').get(acc.CurrencyIsoCode).Netsuite_Value__c); objMap.put('customForm', ns_Map.get('customForm').get(objectName).Netsuite_Value__c); objMap.put('phone', acc.phone); objMap.put('isPerson', ns_Map.get('isPerson').get(objectName).Netsuite_Value__c); objMap.put('entityStatus',ns_Map.get('entityStatus').get(objectName).Netsuite_Value__c);*/ return objMap; } }
It works nicely but then I started thinking about what would happen if that request body needed to be changed. Perhaps a new field becsomes required by Netsuite, for example. This would require me to make edits to the class and deploying. So, I thought maybe I could put these map definitions into custom metadata, which would allow me to make any required changes by editing custom metdata inside production. I wound up with the following class:
public class netsuite_CustomerMap implements INetsuiteMap{ public map<string, object> getNSMap(SObject sobj) { Account acc = (Account)sobj; string objectName = acc.getSObjectType().getDescribe().getName(); netsuite_Service nsService = new netsuite_Service(); map<string,map<string, Netsuite_Mapping__mdt>> ns_Map = nsService.getNSDefaultMap(); map<string, object> objMap = new map<string, object>(); for(Netsuite_Master_Map_Definition__mdt mapSource : [select Id, MasterLabel, Netsuite_Master_Map__c, Netsuite_Master_Map__r.MasterLabel, Netsuite_Field__c, Salesforce_Value__c from Netsuite_Master_Map_Definition__mdt where Netsuite_Master_Map__r.Apex_Class_Name__c = 'netsuite_CustomerMap']) { objMap.put(mapSource.Netsuite_Field__c, mapSource.Salesforce_Value__c); } return objMap; } }
And here is an example of what the 2 custom fields in Netsuite_Master_Map_Definition__mdt called Netsuite_Field__c and Salesforce_Value__c are storing:
Netsuite_Field__c = 'companyname'
Salesforce_Value__c = acc.Name
As an admin, what I didn't think through is that this would not work because these are text fields and therefore simply populates the objMap with literal text values like so "'companyname'" => "acc.Name".
So, at this point I'm not sure what to do and will probably just reconcile myself to the reality of updating the class anytime a change to request body is needed.....Unless someone out there has any good ideas.
Thanks!
Hi Andy,
You can fetch the fields from the Sobject dynamically. I would suggest adding some sort of check, a boolean or a picklist field to determine if the value is string literal or a reference.
For e.g. Let's add Salesforce_Value_type__c on Netsuite_Master_Map_Definition__mdt which can have two typesof values - 'Literal' or 'Dynamic'. Now in your code, you can check if the Salesforce_Value_type__c is 'Literal', add the value directly. If not, fetch it from the sObj/acc.
The code sample looks like:
Please note that you should keep only the fieldName in the Salesforce_Value__c. For instance, the Salesforce_Value__c should be 'Name' and not 'acc.Name' for the above code to work.
Thanks,
Princy
All Answers
Hi Andy,
You can fetch the fields from the Sobject dynamically. I would suggest adding some sort of check, a boolean or a picklist field to determine if the value is string literal or a reference.
For e.g. Let's add Salesforce_Value_type__c on Netsuite_Master_Map_Definition__mdt which can have two typesof values - 'Literal' or 'Dynamic'. Now in your code, you can check if the Salesforce_Value_type__c is 'Literal', add the value directly. If not, fetch it from the sObj/acc.
The code sample looks like:
Please note that you should keep only the fieldName in the Salesforce_Value__c. For instance, the Salesforce_Value__c should be 'Name' and not 'acc.Name' for the above code to work.
Thanks,
Princy
Hope you had a chance to look at the above reply. Please mark it as solved if the above helps.
Thanks,
Princy