Future vs Immediate
Future method is for when large or multiple records are created. The code will run in the "Future" and it queues the request. This is used when you have more than one update occurring, such as when you have a header record with child records. eg. Sales Order with Sales Order Transaction Items. The first example below shows the @future callout, and does not have a response section of invokable fields.
Immediate, allows only single record creation. However it also allows passing of return values such as the NetSuite API Response. The second example below shows the @future method commented out, and the addition of Response invokable fields. You'll also notice the response is "wrapped" so it properly passes between objects. Note the inclusion of "List <Results>" instead of "void" and the methods both have return statements. The Response invokable values then become avaiable in the "Advanced" section of the apex action in flow, and you can set variables with the values passed back from apex.
Code Example: Future Method
// Start Apex Class
public with sharing class createNSContactUsingFuture {
public createNSContactUsingFuture() {
}
@InvocableMethod(label='Create NetSuite Contact' description='Create NetSuite Contact' category='Breadwinner')
public static void createNetSuiteContactUsingFuture(List<Requests> requestList){
createNetSuiteContact(JSON.serialize(requestList));
}
@future(callout = true)
public static void createNetSuiteContact(String requestListJSON){
List<Requests> requestList = (List<Requests>)JSON.deserialize(requestListJSON, List<Requests>.class);
List<Object> netSuiteContactList = new List<Object>();
for(Requests req : requestList){
netSuiteContactList.add(generateNetSuiteContactMap(req));
}
// Sending request to NetSuite via exposed Global API
Map<String, Object> reqJSONMap = new Map<String, Object>();
reqJSONMap.put('contacts' , netSuiteContactList);
String reqJSON = JSON.serialize(reqJSONMap);
Map<String, Object> finalReqMap = new Map<String, Object>();
finalReqMap.put('version' , '1.0');
finalReqMap.put('action' , 'createContact');
finalReqMap.put('RequestJSON' , reqJSON);
System.debug('Request ::: ' + finalReqMap);
Map<String, Object> respMap = breadwinner_ns.BreadwinnerNetSuiteAPI.call(finalReqMap);
System.debug('Response ::: ' + respMap);
}
public class Requests{
@InvocableVariable(label='Alternate Email' description='Alternate Email')
public String altEmail;
@InvocableVariable(label='Assistant' description='Assistant')
public String assistant;
@InvocableVariable(label='Comments' description='Comments')
public String comments;
@InvocableVariable(label='Billing Street' description='Billing Street')
public String BillingStreet;
@InvocableVariable(label='Shipping Street' description='Shipping Street')
public String ShippingStreet;
@InvocableVariable(label='Billing Country' description='Billing Country')
public String BillingCountry;
@InvocableVariable(label='Billing Postal Code' description='Billing Postal Code')
public String BillingPostalCode;
@InvocableVariable(label='Billing City' description='Billing City')
public String BillingCity;
@InvocableVariable(label='Billing State' description='Billing State')
public String BillingState;
@InvocableVariable(label='Shipping Country' description='Shipping Country')
public String ShippingCountry;
@InvocableVariable(label='Shipping Postal Code' description='Shipping Postal Code')
public String ShippingPostalCode;
@InvocableVariable(label='Shipping City' description='Shipping City')
public String ShippingCity;
@InvocableVariable(label='Shipping State' description='Shipping State')
public String ShippingState;
@InvocableVariable(label='Company' description='Company')
public String company;
@InvocableVariable(label='Custom Form' description='Custom Form')
public String customForm;
@InvocableVariable(label='Email' description='Email')
public String email;
@InvocableVariable(label='External Id' description='External Id')
public String externalId;
@InvocableVariable(label='Fax' description='Fax')
public String fax;
@InvocableVariable(label='First Name' description='First Name')
public String firstName;
@InvocableVariable(label='Home Phone' description='Home Phone')
public String homePhone;
@InvocableVariable(label='internalId' description='internalId')
public String internalId;
@InvocableVariable(label='is Inactive' description='Is Inactive')
public Boolean isInactive;
@InvocableVariable(label='Is Private' description='Is Private')
public Boolean isPrivate;
@InvocableVariable(label='Last Name' description='Last Name')
public String lastName;
@InvocableVariable(label='Middle Name' description='Middle Name')
public String middleName;
@InvocableVariable(label='Mobile Phone' description='Mobile Phone')
public String mobilePhone;
@InvocableVariable(label='Office Phone' description='Office Phone')
public String officePhone;
@InvocableVariable(label='Phone' description='Phone')
public String phone;
@InvocableVariable(label='salutation' description='salutation')
public String salutation;
@InvocableVariable(label='Subsidiary' description='Subsidiary')
public String subsidiary;
@InvocableVariable(label='Title' description='Title')
public String title;
}
public static Map<String, Object> generateNetSuiteContactMap(Requests req){
Map<String, Object> netSuiteContactMap = new Map<String, Object>();
// Assign values from the Request to NetSuite Contact
List<Object> addressBookList = new List<Object>();
Map<String, Object> billingAddressBook = new Map<String, Object>();
Map<String, Object> billingAddressbookAddress = new Map<String, Object>();
If(req.BillingCity != NULL && String.isNotBlank(req.BillingCity))
billingAddressbookAddress.put('city' , req.BillingCity);
If(req.BillingState != NULL && String.isNotBlank(req.BillingState))
billingAddressbookAddress.put('state' , req.BillingState);
If(req.BillingCountry != NULL && String.isNotBlank(req.BillingCountry))
billingAddressbookAddress.put('country' ,req.BillingCountry);
If(req.BillingPostalCode != NULL && String.isNotBlank(req.BillingPostalCode))
billingAddressbookAddress.put('zip' , req.BillingPostalCode);
billingAddressBook.put('defaultBilling' , true);
billingAddressBook.put('isResidential' , true);
If(req.BillingStreet != NULL && String.isNotBlank(req.BillingStreet)){
String billingAddr = String.isNotBlank(req.BillingStreet) ? req.BillingStreet : '';
String billingAddr1 = '';
String billingAddr2 = '';
String billingAddr3 = '';
if(billingAddr.length() >= 0 && billingAddr.length() <= 150){
billingAddr1 = billingAddr.substring(0,billingAddr.length());
}else if(billingAddr.length() > 150 && billingAddr.length() <= 300){
billingAddr1 = billingAddr.substring(0,150);
billingAddr2 = billingAddr.substring(150,billingAddr.length());
}else if(billingAddr.length() > 300 && billingAddr.length() <= 450){
billingAddr1 = billingAddr.substring(0,150);
billingAddr2 = billingAddr.substring(150,300);
billingAddr3 = billingAddr.substring(300,billingAddr.length());
}else if(billingAddr.length() > 450){
billingAddr1 = billingAddr.substring(0,150);
billingAddr2 = billingAddr.substring(150,300);
billingAddr3 = billingAddr.substring(300,450);
}
billingAddressbookAddress.put('addr1' , billingAddr1);
billingAddressbookAddress.put('addr2' , billingAddr2);
billingAddressbookAddress.put('addr3' , billingAddr3);
}
billingAddressBook.put('addressbookAddress', billingAddressbookAddress);
addressBookList.add(billingAddressBook);
Map<String, Object> shippingAddressBookAddress = new Map<String, Object>();
If(req.ShippingCity != NULL && String.isNotBlank(req.ShippingCity))
shippingAddressBookAddress.put('city' , req.ShippingCity);
If(req.ShippingState != NULL && String.isNotBlank(req.ShippingState))
shippingAddressBookAddress.put('state' , req.ShippingState);
If(req.ShippingCountry != NULL && String.isNotBlank(req.ShippingCountry))
shippingAddressBookAddress.put('country' ,req.ShippingCountry);
If(req.ShippingPostalCode != NULL && String.isNotBlank(req.ShippingPostalCode))
shippingAddressBookAddress.put('zip' , req.ShippingPostalCode);
Map<String, Object> ShippingAddressBook = new Map<String, Object>();
ShippingAddressBook.put('defaultShipping' , true);
ShippingAddressBook.put('isResidential' , true);
If(req.ShippingStreet != NULL && String.isNotBlank(req.ShippingStreet)){
String shippingAddr = String.isNotBlank(req.ShippingStreet) ? req.ShippingStreet : '';
String shippingAddr1 = '';
String shippingAddr2 = '';
String shippingAddr3 = '';
if(shippingAddr.length() >= 0 && shippingAddr.length() <= 150){
shippingAddr1 = shippingAddr.substring(0,shippingAddr.length());
}else if(shippingAddr.length() > 150 && shippingAddr.length() <= 300){
shippingAddr1 = shippingAddr.substring(0,150);
shippingAddr2 = shippingAddr.substring(150,shippingAddr.length());
}else if(shippingAddr.length() > 300 && shippingAddr.length() <= 450){
shippingAddr1 = shippingAddr.substring(0,150);
shippingAddr2 = shippingAddr.substring(150,300);
shippingAddr3 = shippingAddr.substring(300,shippingAddr.length());
}else if(shippingAddr.length() > 450){
shippingAddr1 = shippingAddr.substring(0,150);
shippingAddr2 = shippingAddr.substring(150,300);
shippingAddr3 = shippingAddr.substring(300,450);
}
shippingAddressBookAddress.put('addr1' , shippingAddr1);
shippingAddressBookAddress.put('addr2' , shippingAddr2);
shippingAddressBookAddress.put('addr3' , shippingAddr3);
}
ShippingAddressBook.put('addressbookAddress', shippingAddressBookAddress);
addressBookList.add(ShippingAddressBook);
// Adding Shipping and Billing Address List to Map
netSuiteContactMap.put('addressbookList',new Map<String,Object>{'addressbook'=>addressBookList});
If(req.altEmail != NULL)
netSuiteContactMap.put('altEmail',req.altEmail);
If(req.assistant != NULL)
netSuiteContactMap.put('assistant',req.assistant);
If(req.comments != NULL)
netSuiteContactMap.put('comments',req.comments);
If(req.company != NULL)
netSuiteContactMap.put('company', new Map<String, Object>{'internalId'=>req.company});
If(req.customForm != NULL)
netSuiteContactMap.put('customForm' ,new Map<String, Object>{'internalId' => req.customForm});
If(req.email != NULL)
netSuiteContactMap.put('email',req.email);
If(req.externalID != NULL)
netSuiteContactMap.put('externalID',req.externalID);
If(req.fax != NULL)
netSuiteContactMap.put('fax',req.fax);
If(req.firstName != NULL)
netSuiteContactMap.put('firstName',req.firstName);
If(req.homePhone != NULL)
netSuiteContactMap.put('homePhone',req.homePhone);
If(req.isInactive != NULL)
netSuiteContactMap.put('isInactive',req.isInactive);
If(req.isPrivate != NULL)
netSuiteContactMap.put('isPrivate',req.isPrivate);
If(req.lastName != NULL)
netSuiteContactMap.put('lastName',req.lastName);
If(req.middleName != NULL)
netSuiteContactMap.put('middleName',req.middleName);
If(req.mobilePhone != NULL)
netSuiteContactMap.put('mobilePhone',req.mobilePhone);
If(req.officePhone != NULL)
netSuiteContactMap.put('officePhone',req.officePhone);
If(req.phone != NULL)
netSuiteContactMap.put('phone',req.phone);
If(req.salutation != NULL)
netSuiteContactMap.put('salutation',req.salutation);
If(req.subsidiary != NULL)
netSuiteContactMap.put('subsidiary', new Map<String, Object>{'internalId'=>req.subsidiary});
If(req.title != NULL)
netSuiteContactMap.put('title',req.title);
return netSuiteContactMap;
}
}Code Example: Immediate with Debug Values
// Start Apex Class
public with sharing class createNSContactWithDebug {
public createNSContactWithDebug() {
}
@InvocableMethod(label='Create NetSuite Contact with API Debug' description='Create NetSuite Contact with API Debug' category='Breadwinner')
public static List <Results> createNSContactWithDebug(List<Requests> requestList){
return createNetSuiteContact(JSON.serialize(requestList));
}
//Not Desired when API reponse requested @future(callout = true)
public static List <Results> createNetSuiteContact(String requestListJSON){
List<Requests> requestList = (List<Requests>)JSON.deserialize(requestListJSON, List<Requests>.class);
List<Object> netSuiteContactList = new List<Object>();
//Create a Results object to hold the return values
Results response = new Results();
for(Requests req : requestList){
netSuiteContactList.add(generateNetSuiteContactMap(req));
}
// Sending request to NetSuite via exposed Global API
Map<String, Object> reqJSONMap = new Map<String, Object>();
reqJSONMap.put('contacts' , netSuiteContactList);
String reqJSON = JSON.serialize(reqJSONMap);
Map<String, Object> finalReqMap = new Map<String, Object>();
finalReqMap.put('version' , '1.0');
finalReqMap.put('action' , 'createContact');
finalReqMap.put('RequestJSON' , reqJSON);
System.debug('Request ::: ' + finalReqMap);
Map<String, Object> respMap = breadwinner_ns.BreadwinnerNetSuiteAPI.call(finalReqMap);
System.debug('Response ::: ' + respMap);
//Take the NetSuite response map and convert to single string
String nsResponseString = '';
for(String key : respMap.keySet()){
if(nsResponseString.length() !=0){
nsResponseString += '::';
}
nsResponseString += key + '=' + respMap.get(key);
}
response.netSuiteResponse = nsResponseString;
//Wrap the Results object in a List container
//(an extra step added to allow this interface to also support bulkification)
List<Results> responseWrapper= new List<Results>();
responseWrapper.add(response);
return responseWrapper;
}
public class Requests{
@InvocableVariable(label='Alternate Email' description='Alternate Email')
public String altEmail;
@InvocableVariable(label='Assistant' description='Assistant')
public String assistant;
@InvocableVariable(label='Comments' description='Comments')
public String comments;
@InvocableVariable(label='Billing Street' description='Billing Street')
public String BillingStreet;
@InvocableVariable(label='Shipping Street' description='Shipping Street')
public String ShippingStreet;
@InvocableVariable(label='Billing Country' description='Billing Country')
public String BillingCountry;
@InvocableVariable(label='Billing Postal Code' description='Billing Postal Code')
public String BillingPostalCode;
@InvocableVariable(label='Billing City' description='Billing City')
public String BillingCity;
@InvocableVariable(label='Billing State' description='Billing State')
public String BillingState;
@InvocableVariable(label='Shipping Country' description='Shipping Country')
public String ShippingCountry;
@InvocableVariable(label='Shipping Postal Code' description='Shipping Postal Code')
public String ShippingPostalCode;
@InvocableVariable(label='Shipping City' description='Shipping City')
public String ShippingCity;
@InvocableVariable(label='Shipping State' description='Shipping State')
public String ShippingState;
@InvocableVariable(label='Company' description='Company')
public String company;
@InvocableVariable(label='Custom Form' description='Custom Form')
public String customForm;
@InvocableVariable(label='Email' description='Email')
public String email;
@InvocableVariable(label='External Id' description='External Id')
public String externalId;
@InvocableVariable(label='Fax' description='Fax')
public String fax;
@InvocableVariable(label='First Name' description='First Name')
public String firstName;
@InvocableVariable(label='Home Phone' description='Home Phone')
public String homePhone;
@InvocableVariable(label='internalId' description='internalId')
public String internalId;
@InvocableVariable(label='is Inactive' description='Is Inactive')
public Boolean isInactive;
@InvocableVariable(label='Is Private' description='Is Private')
public Boolean isPrivate;
@InvocableVariable(label='Last Name' description='Last Name')
public String lastName;
@InvocableVariable(label='Middle Name' description='Middle Name')
public String middleName;
@InvocableVariable(label='Mobile Phone' description='Mobile Phone')
public String mobilePhone;
@InvocableVariable(label='Office Phone' description='Office Phone')
public String officePhone;
@InvocableVariable(label='Phone' description='Phone')
public String phone;
@InvocableVariable(label='salutation' description='salutation')
public String salutation;
@InvocableVariable(label='Subsidiary' description='Subsidiary')
public String subsidiary;
@InvocableVariable(label='Title' description='Title')
public String title;
}
public class Results {
@InvocableVariable(label='netSuiteResponse' description='Results from NetSuite API Call')
public string netSuiteResponse;
}
public static Map<String, Object> generateNetSuiteContactMap(Requests req){
Map<String, Object> netSuiteContactMap = new Map<String, Object>();
// Assign values from the Request to NetSuite Contact
List<Object> addressBookList = new List<Object>();
Map<String, Object> billingAddressBook = new Map<String, Object>();
Map<String, Object> billingAddressbookAddress = new Map<String, Object>();
If(req.BillingCity != NULL && String.isNotBlank(req.BillingCity))
billingAddressbookAddress.put('city' , req.BillingCity);
If(req.BillingState != NULL && String.isNotBlank(req.BillingState))
billingAddressbookAddress.put('state' , req.BillingState);
If(req.BillingCountry != NULL && String.isNotBlank(req.BillingCountry))
billingAddressbookAddress.put('country' ,req.BillingCountry);
If(req.BillingPostalCode != NULL && String.isNotBlank(req.BillingPostalCode))
billingAddressbookAddress.put('zip' , req.BillingPostalCode);
billingAddressBook.put('defaultBilling' , true);
billingAddressBook.put('isResidential' , true);
If(req.BillingStreet != NULL && String.isNotBlank(req.BillingStreet)){
String billingAddr = String.isNotBlank(req.BillingStreet) ? req.BillingStreet : '';
String billingAddr1 = '';
String billingAddr2 = '';
String billingAddr3 = '';
if(billingAddr.length() >= 0 && billingAddr.length() <= 150){
billingAddr1 = billingAddr.substring(0,billingAddr.length());
}else if(billingAddr.length() > 150 && billingAddr.length() <= 300){
billingAddr1 = billingAddr.substring(0,150);
billingAddr2 = billingAddr.substring(150,billingAddr.length());
}else if(billingAddr.length() > 300 && billingAddr.length() <= 450){
billingAddr1 = billingAddr.substring(0,150);
billingAddr2 = billingAddr.substring(150,300);
billingAddr3 = billingAddr.substring(300,billingAddr.length());
}else if(billingAddr.length() > 450){
billingAddr1 = billingAddr.substring(0,150);
billingAddr2 = billingAddr.substring(150,300);
billingAddr3 = billingAddr.substring(300,450);
}
billingAddressbookAddress.put('addr1' , billingAddr1);
billingAddressbookAddress.put('addr2' , billingAddr2);
billingAddressbookAddress.put('addr3' , billingAddr3);
}
billingAddressBook.put('addressbookAddress', billingAddressbookAddress);
addressBookList.add(billingAddressBook);
Map<String, Object> shippingAddressBookAddress = new Map<String, Object>();
If(req.ShippingCity != NULL && String.isNotBlank(req.ShippingCity))
shippingAddressBookAddress.put('city' , req.ShippingCity);
If(req.ShippingState != NULL && String.isNotBlank(req.ShippingState))
shippingAddressBookAddress.put('state' , req.ShippingState);
If(req.ShippingCountry != NULL && String.isNotBlank(req.ShippingCountry))
shippingAddressBookAddress.put('country' ,req.ShippingCountry);
If(req.ShippingPostalCode != NULL && String.isNotBlank(req.ShippingPostalCode))
shippingAddressBookAddress.put('zip' , req.ShippingPostalCode);
Map<String, Object> ShippingAddressBook = new Map<String, Object>();
ShippingAddressBook.put('defaultShipping' , true);
ShippingAddressBook.put('isResidential' , true);
If(req.ShippingStreet != NULL && String.isNotBlank(req.ShippingStreet)){
String shippingAddr = String.isNotBlank(req.ShippingStreet) ? req.ShippingStreet : '';
String shippingAddr1 = '';
String shippingAddr2 = '';
String shippingAddr3 = '';
if(shippingAddr.length() >= 0 && shippingAddr.length() <= 150){
shippingAddr1 = shippingAddr.substring(0,shippingAddr.length());
}else if(shippingAddr.length() > 150 && shippingAddr.length() <= 300){
shippingAddr1 = shippingAddr.substring(0,150);
shippingAddr2 = shippingAddr.substring(150,shippingAddr.length());
}else if(shippingAddr.length() > 300 && shippingAddr.length() <= 450){
shippingAddr1 = shippingAddr.substring(0,150);
shippingAddr2 = shippingAddr.substring(150,300);
shippingAddr3 = shippingAddr.substring(300,shippingAddr.length());
}else if(shippingAddr.length() > 450){
shippingAddr1 = shippingAddr.substring(0,150);
shippingAddr2 = shippingAddr.substring(150,300);
shippingAddr3 = shippingAddr.substring(300,450);
}
shippingAddressBookAddress.put('addr1' , shippingAddr1);
shippingAddressBookAddress.put('addr2' , shippingAddr2);
shippingAddressBookAddress.put('addr3' , shippingAddr3);
}
ShippingAddressBook.put('addressbookAddress', shippingAddressBookAddress);
addressBookList.add(ShippingAddressBook);
// Adding Shipping and Billing Address List to Map
netSuiteContactMap.put('addressbookList',new Map<String,Object>{'addressbook'=>addressBookList});
If(req.altEmail != NULL)
netSuiteContactMap.put('altEmail',req.altEmail);
If(req.assistant != NULL)
netSuiteContactMap.put('assistant',req.assistant);
If(req.comments != NULL)
netSuiteContactMap.put('comments',req.comments);
If(req.company != NULL)
netSuiteContactMap.put('company', new Map<String, Object>{'internalId'=>req.company});
If(req.customForm != NULL)
netSuiteContactMap.put('customForm' ,new Map<String, Object>{'internalId' => req.customForm});
If(req.email != NULL)
netSuiteContactMap.put('email',req.email);
If(req.externalID != NULL)
netSuiteContactMap.put('externalID',req.externalID);
If(req.fax != NULL)
netSuiteContactMap.put('fax',req.fax);
If(req.firstName != NULL)
netSuiteContactMap.put('firstName',req.firstName);
If(req.homePhone != NULL)
netSuiteContactMap.put('homePhone',req.homePhone);
If(req.isInactive != NULL)
netSuiteContactMap.put('isInactive',req.isInactive);
If(req.isPrivate != NULL)
netSuiteContactMap.put('isPrivate',req.isPrivate);
If(req.lastName != NULL)
netSuiteContactMap.put('lastName',req.lastName);
If(req.middleName != NULL)
netSuiteContactMap.put('middleName',req.middleName);
If(req.mobilePhone != NULL)
netSuiteContactMap.put('mobilePhone',req.mobilePhone);
If(req.officePhone != NULL)
netSuiteContactMap.put('officePhone',req.officePhone);
If(req.phone != NULL)
netSuiteContactMap.put('phone',req.phone);
If(req.salutation != NULL)
netSuiteContactMap.put('salutation',req.salutation);
If(req.subsidiary != NULL)
netSuiteContactMap.put('subsidiary', new Map<String, Object>{'internalId'=>req.subsidiary});
If(req.title != NULL)
netSuiteContactMap.put('title',req.title);
return netSuiteContactMap;
}
}