Hello
I have this class that is making the request body for an integration with netsuite.
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>();
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;
}
}
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,Princypublic 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 ,
Salesforce_Value_type__c
from Netsuite_Master_Map_Definition__mdt
where Netsuite_Master_Map__r.Apex_Class_Name__c = 'netsuite_CustomerMap']) {
if('Literal' == mapSource.Salesforce_Value_type__c)
objMap.put(mapSource.Netsuite_Field__c, mapSource.Salesforce_Value__c);
else
objMap.put(mapSource.Netsuite_Field__c, sobj.get(mapSource.Salesforce_Value__c));
}
return objMap;
}
}