POSTMAN – Create URL using Consumer key, Consumer secret , Username and Password+Security Token to generate Access Token
Click on Send button and you will get Access Token as below, We will use this Access Token into REST API URL
Below screen you can see that we have created Rest API request URL and Authorization(Bearer + Access Token) and Content Type
And Below is Rest API Request Body
Create Employee(Employee__c) Object and Add fields as mention in below screen.
Create EmployeeAPI (EmployeeAPI__c) object as shown in below screen. This object will be used as parent id in Attachment object to save Response as attachment.
We have almost completed configuration part, Now its time to jump on Coding. Create Apex Class (EmployeeSync and EmployeeICSResponse). Apex Class (EmployeeICSResponse) will be use to send response to third party application and Apex class (EmployeeSync) is to expose Apex as Rest API. This Rest API will be consume by third party application.(like Postman, Mobile App etc..). I have added comments on each block of code which will explain meaning and significance on that code block.
Public class EmployeeICSResponse {
public String Id{get;set;}
public String Status{get;set;}
Public String Message{get;set;}
public String SeqNum{get;set;}
}
@RestResource(urlMapping='/Employee/*')
global with sharing class EmployeeSync {
@HttpPost
global static void doPost() {
RestRequest req = RestContext.request;// We will get Request Here
EmployeeAPI__c objReqRes=new EmployeeAPI__c();//This object will be used to save Request and Response
objReqRes.RequestType__c='Employee'; // This is just Type of Request
String BatchNumber='';
//This is Response List which we will used to send response to Requester App(In Our Case requester APP is POSTMAN)
List<EmployeeICSResponse> responseList=new List<EmployeeICSResponse>();
try{
//Checking here if The Request is not blank
if(!String.isBlank(req.requestBody.toString()) && req.requestBody.toString() !='""'){
//We have created one map Map<String,Object> employeeDataMap here to get Data from RequestBody.
Map<String,Object> employeeDataMap=(Map<String,Object>)JSON.deserializeUntyped(req.requestBody.toString());
//Extract All list/Array of Data from Request on the Basis of Parent Node Name.
//Here In our Case Parent Node Name is 'Employee__c' as per Json request format.
List<object> empLst =(List<object>) employeeDataMap.get('Employee__c');
//This List is created for To Add each Employee Record from list/Array into list.
List<Employee__c> lstEmp=new List<Employee__c>();
//We are iterating over the List of Employee which we get from Json Request body.
for(integer i=0; i< empLst.size();i++)
{
//Getting Json List Data into map.
map<String,Object> m = (map<String,Object>) empLst[i];
try{
//Created Employee Object to collect each employee record and add into lstEmp
Employee__c EmpObj=new Employee__c();
EmpObj.Name__c = (String)m.get('Employee_Name__c');//Extracting Employee Name from Map and assign to Employee object Name__c field
EmpObj.Employee_Number__c=(String)m.get('Employee_Number__c');
EmpObj.Person_ID__c=(String)m.get('Person_ID__c');////Extracting Employee Name from Map and assign to Employee object Person_ID__c field
EmpObj.EMP_EFF_START_DATE__c=ConvertStringToDate((String)m.get('EMP_EFF_START_DATE__c'));
EmpObj.NPW__c=(String)m.get('NPW__c');
EmpObj.FIRST_NAME__c=(String)m.get('FIRST_NAME__c');
EmpObj.LAST_NAME__c=(String)m.get('LAST_NAME__c');
EmpObj.OFFICIAL_EMAIL_ADDRESS__c=((String)m.get('OFFICIAL_EMAIL_ADDRESS__c')).replace(';','');
EmpObj.EMPLOYEE_TYPE__c=(String)m.get('EMPLOYEE_TYPE__c');
EmpObj.CURRENT_EMPLOYEE_FLAG__c=((String)m.get('CURRENT_EMPLOYEE_FLAG__c')=='Y' && (String)m.get('CURRENT_EMPLOYEE_FLAG__c') != '') ? 'Yes':'No';
EmpObj.TOTAL_EXP__c=decimal.valueOf((String)m.get('TOTAL_EXP__c') == '' ? '0' : (String)m.get('TOTAL_EXP__c'));
EmpObj.Attribute1__c=(String)m.get('Attribute1__c');//unique field
EmpObj.Seq_Number__c=(String)m.get('Seq_Number__c');//Seq Number
BatchNumber=(String)m.get('Batch_Number__c');
//Here We are checking if Epmloyee Type is not null and start with ex.
//then Employee isActive=False else isActive=true
if (EmpObj.EMPLOYEE_TYPE__c != null && EmpObj.EMPLOYEE_TYPE__c.toLowerCase().startsWith('ex'))
{
EmpObj.isActive__c = false;
}
else{
EmpObj.isActive__c = true;
}
//Here we are checking if Employee Name is blank. One kind of Validation we have added here.
//If its Blank then adding response message ='Employee Name Required'
//Else it will be added into lstEmp list.
if( String.isBlank(EmpObj.Name__c))
{
EmployeeICSResponse objRes=new EmployeeICSResponse();
objRes.Id=(String)m.get('Person_ID__c');
objRes.Status='Fail';
objRes.Message= 'Employee Name Required';
objRes.SeqNum=(String)m.get('Seq_Number__c');
responseList.add(objRes);
}
else{
lstEmp.add(EmpObj);
}
}
//If any exception occur during data extraction from Json Request
//then below exception block will be execute and we will send Exception into response
catch(exception ex){
EmployeeICSResponse objRes=new EmployeeICSResponse();
objRes.Id=(String)m.get('Person_ID__c');
objRes.Status='Fail';
objRes.Message=ex.getMessage();
objRes.SeqNum=(String)m.get('Seq_Number__c');
responseList.add(objRes);
}
}
// Created one set of PersonIds from Valid Employee Data of Json request.
Set<String> personIdS=new Set<String>();
for(Employee__c p : lstEmp)
{
personIdS.add(p.Person_ID__c);
}
// Created Map before Upsert Employee
Map<String,Employee__c> empBeforeUpsertMAP=new Map<String,Employee__c>();
// We will fetch Person , ID and EMP Effective Start Date of those Record from the
// salesforce database whose person id is already exists in system
// and add into Map<String,Employee__c> empBeforeUpsertMAP
for(Employee__c empMstBeforeUpsert : [Select Id,Person_ID__c, EMP_EFF_START_DATE__c from Employee__c where
Person_ID__c in: personIdS])
{
empBeforeUpsertMAP.put(empMstBeforeUpsert.Person_ID__c, empMstBeforeUpsert);
}
// This list is for employee need to Upsert on the basis of Person Id
List<Employee__c> empforUpsert=new List<Employee__c>();
// This list is for employee not need to Upsert
List<Employee__c> empNoNeedToUpsert=new List<Employee__c>();
// We are iterating here on Employee list lstEmp which we have generated from Json Request.
for(Employee__c lem: lstEmp)
{
//Getting existing Employee from system
Employee__c gpempmst=empBeforeUpsertMAP.get(lem.Person_ID__c);
//and check if its not null
if(gpempmst != null)
{
// Check If Request Employee Eff Start Date is Greater than of equal to
// Existing Employee Eff Start Date or Existing Employee Eff Start Date = null
// Then that employee is considered for Upsert else No need to upsert that Employee because latest Record already exist
// as per Eff start date
if(lem.EMP_EFF_START_DATE__c >= gpempmst.EMP_EFF_START_DATE__c || gpempmst.EMP_EFF_START_DATE__c == null )
{
empforUpsert.add(lem);
}
else
{
empNoNeedToUpsert.add(lem);
}
}
//and check if its null then Employee Record is considered for Upsert.
else
{
system.debug('===lem==='+lem.Person_ID__c);
empforUpsert.add(lem);
}
}
lstEmp=empforUpsert;//Assign all Employee who are elogible for upsert into lstEmp list
//Here We are checking if No Need To Upsert employee size is greator than 0
//If this this list has more than 0 record then We will send response message as
//'Latest employee record already exists.'
if(empNoNeedToUpsert.size()>0)
{
for(Integer index = 0, size = empNoNeedToUpsert.size(); index < size; index++) {
EmployeeICSResponse resp=new EmployeeICSResponse();
resp.Id=empNoNeedToUpsert[index].Person_ID__c;
resp.Status='Fail';
resp.SeqNum=empNoNeedToUpsert[index].Seq_Number__c;
resp.Message='Latest employee record already exists.';
if(resp.Status!=null)
responseList.add(resp);
}
}
system.debug('===responseList 1==='+responseList.size());
//End : check to handle employee on the basis of Eff Start date
// If lstEmp has more employee then we will upsert employee on the basis of Person_ID__C
// We have taken Person_ID__c as external ID into employee object.
if(lstEmp.size()>0){
system.debug('===lstEmp==='+lstEmp.size());
Schema.SObjectField f = Employee__c.Fields.Person_ID__c;
Database.UpsertResult [] srList = Database.upsert(lstEmp, f, false);
//This list will hold all duplicate employee on the basis of Person Id
List<Employee__c> duplicateList= new List<Employee__c>();
system.debug('===srList.size()==='+srList.size());
for(Integer index = 0, size = srList.size(); index < size; index++) {
EmployeeICSResponse resp=new EmployeeICSResponse();
// if Employee is upsert successfully then We are sending Id=Person Id, SeqNum and Status=Success as response.
if(srList[index].isSuccess()) {
resp.Id=lstEmp[index].Person_ID__c;
resp.SeqNum=lstEmp[index].Seq_Number__c;
resp.Status='Success';
}
// if Employee is not upsert
else if (!srList.get(index).isSuccess()){
//We are taking Error into Database.Error error
Database.Error error = srList.get(index).getErrors().get(0);
//get error message into failedDML
String failedDML = error.getMessage();
system.debug('===failedDML==='+failedDML);
// if failedDML contain 'Duplicate external id specified' then that Employee record add into duplicateList
if(failedDML.contains('Duplicate external id specified'))
{
duplicateList.add(lstEmp[index]);
}
//Else set response with failedDML exception and send response to Requester APP
else{
system.debug('===lstEmp[index].Person_ID__c==='+lstEmp[index].Person_ID__c);
resp.Id=lstEmp[index].Person_ID__c;
resp.Status='Fail';
resp.SeqNum=lstEmp[index].Seq_Number__c;
resp.Message=failedDML;
}
}
if(resp.Status!=null)
responseList.add(resp);
}
// Now we rae checking for Duplicate Employee list which we get at the time of Upsert Employee activity.
// We have to decided that which employee record is valid amongs all duplicate record
// Will decide Valid Employee Record on the basis of EFF Start Date
// Valid Employee who has EFF START Date is greatest than Other Employee with same Person ID.
if(duplicateList.size()>0){
//Getting Person ID from Duplicate Employee List
Set<String> personId=new Set<String>();
for(Employee__c emp : duplicateList)
{
personId.add(emp.Person_ID__c);
}
system.debug('===Getting Person ID from Duplicate Employee List==='+personId);
//Map of unique Person Id and Employee object
Map<String,List<Employee__c>> mapUniquePersonId=new Map<String,List<Employee__c>>();
//Iteration over Person Id get from Duplicate Employee List
for(String st: personId)
{
List<Employee__c> segregateEmployeeDup=new List<Employee__c>();
//Iterating Over Duplicate Employee List
for(Employee__c empMst:duplicateList)
{
//Here We are checking if Set Person Id and duplicate employee person id are same
//then we are taking it into segregateEmployeeDup
//Ultimately we are creating group of Duplicate employee whose Person Id are same
if(st==empMst.Person_ID__c){
segregateEmployeeDup.add(empMst);}
}
// and Putting key=PersonId( i.e. ST) and Value = segregateEmployeeDup into mapUniquePersonId
mapUniquePersonId.put(st,segregateEmployeeDup);
}
//system.debug('===mapUniquePersonId==='+mapUniquePersonId.keySet());
//Below list is taken for to collect Actual Employee from Duplicate Employee on the basis of EFF START DATE
List<Employee__c> ActualEmployeeFrmDup=new List<Employee__c>();
//Iterating Over Unique Person Id , group of Employee for same person Id.
for(String key:mapUniquePersonId.KeySet())
{
//Below List is taking to collect group of employee on the basis of Person ID
List<Employee__c> lstEmpDataByKey=new List<Employee__c>();
lstEmpDataByKey=mapUniquePersonId.get(key);
Employee__c actEmp=new Employee__c();
//system.debug('===lstEmpDataByKey==='+lstEmpDataByKey.size());
//Lets Consider lstEmpDataByKey has 5 Employee with same person ID
//below line we are taking first Employee lstEmpDataByKey[0] as actEmp
actEmp=lstEmpDataByKey[0];
//iterating over lstEmpDataByKey
for(Integer i=0; i < lstEmpDataByKey.size()-1;i++)
{
//checking if actEmp Person Id == lstEmpDataByKey[i+1].Person_ID__c
//actEmp=lstEmpDataByKey[0] already has first record
if(actEmp.Person_ID__c == lstEmpDataByKey[i+1].Person_ID__c )
{
//comparing if actEmp EFF START DATE greater than lstEmpDataByKey
//if yes then actEmp = actEmp; Whosever EFF START DATE is greater
// that will be our actual employee
if(actEmp.EMP_EFF_START_DATE__c > lstEmpDataByKey[i+1].EMP_EFF_START_DATE__c)
{
actEmp = actEmp;
}
//else actEmp = lstEmpDataByKey[i+1];;
else{
actEmp = lstEmpDataByKey[i+1];
}
}
}
// gathered all actual employee on the basis of EFF START DATE greater
ActualEmployeeFrmDup.add(actEmp);
}
if(ActualEmployeeFrmDup.size()>0)
{
// Upsert on the basis of Person ID
Database.UpsertResult [] srActList = Database.upsert(ActualEmployeeFrmDup, f, false);
for(Integer index = 0, size = srActList.size(); index < size; index++) {
EmployeeICSResponse respN=new EmployeeICSResponse();
// IF success then send response ID=Person Id, seqNum=Seq num, Status=Success
if(srActList[index].isSuccess()) {
respN.Id=ActualEmployeeFrmDup[index].Person_ID__c;
respN.SeqNum=ActualEmployeeFrmDup[index].Seq_Number__c;
respN.Status='Success';
}
//else if error occur
////the send response Id=Person Id, Status=Fail, SeqNum=SeqNum, Message= error.Message
else if (!srActList.get(index).isSuccess()){
// DML operation failed
Database.Error errorN = srActList.get(index).getErrors().get(0);
String failedDML = errorN.getMessage();
respN.Id=ActualEmployeeFrmDup[index].Person_ID__c;
respN.Status='Fail';
respN.SeqNum=ActualEmployeeFrmDup[index].Seq_Number__c;
respN.Message=errorN.getMessage();
}
responseList.add(respN);
}
}
system.debug('===responseList 3==='+responseList.size());
//for duplicate external id sending error response
//now we have to send FakeEmployee from Duplicate
List<Employee__c> FakeEmployeeFrmDup=new List<Employee__c>();
//iteration over Actual Employee From Duplicate list
for(Employee__c empMas: ActualEmployeeFrmDup)
{
//Iteration Over Duplicate Employee list
for(Employee__c dpEmp: duplicateList)
{
//Compare ActualEmp Person ID == duplicate Person Id
if(empMas.Person_ID__c == dpEmp.Person_ID__c )
{
//check if Actual Employee EFF START DATE != Duplicate Emp EFF START DATE
//and Actual Employee SEQ NUM != Duplicate Employee Seq num
// Resulted Employee list will be added to Fake Employee list
if((empMas.EMP_EFF_START_DATE__c != dpEmp.EMP_EFF_START_DATE__c) ||
(empMas.Seq_Number__c != dpEmp.Seq_Number__c))
{
FakeEmployeeFrmDup.add(dpEmp);
}
}
}
}
//Check If Fake Employee list has some records
//Send respose as Id= fake Employee Person Id, Status = Fail, Message=Latest employee record already exists.
for(Integer index = 0, size = FakeEmployeeFrmDup.size(); index < size; index++) {
EmployeeICSResponse respNM=new EmployeeICSResponse();
respNM.Id=FakeEmployeeFrmDup[index].Person_ID__c;
respNM.Status='Fail';
respNM.SeqNum=FakeEmployeeFrmDup[index].Seq_Number__c;
respNM.Message='Latest employee record already exists.';
responseList.add(respNM);
}
system.debug('===responseList 4==='+responseList.size());
//End here - for duplicate external id sending error response
}
}
String strJSON = '{ "Employee__Response":';
strJSON += JSON.serialize(responseList);
strJSON +='}';
objReqRes.Request_Data__c=String.valueOf(empLst.size());
upsert objReqRes;
// Attached request and response to the Notes and attachment and Parent ID id EmployeeAPIs
AddAttachment('Employee__Request',objReqRes.Id,req.requestBody.toString(),BatchNumber);
AddAttachment('Employee__Response',objReqRes.Id,strJSON,BatchNumber);
RestContext.response.addHeader('Content-Type', 'application/json');
RestContext.response.responseBody = Blob.valueOf(strJSON);
}
else
{
//If Request is blank then we are sending response as below. Id='',Status='Fail', Message='Blank Request' and SeqNum=''
EmployeeICSResponse objRes=new EmployeeICSResponse();
objRes.Id='';
objRes.Status='Fail';
objRes.Message='Blank Request';
objRes.SeqNum='';
responseList.add(objRes);
String strJSON = '{ "Employee__Response":';
strJSON += JSON.serialize(responseList);
strJSON +='}';
objReqRes.Request_Data__c='Blank Request';
//objReqRes.response__c= strJSON;
upsert objReqRes;
AddAttachment('Employee__Request',objReqRes.Id,req.requestBody.toString(),BatchNumber);
AddAttachment('Employee__Response',objReqRes.Id,strJSON,BatchNumber);
system.debug('===responseList 5==='+responseList.size());
RestContext.response.addHeader('Content-Type', 'application/json');
RestContext.response.responseBody = Blob.valueOf(strJSON);
}
}
catch(exception ex)
{
//If any exception Occur then we will also send it as response with Exception Message
EmployeeICSResponse objRes=new EmployeeICSResponse();
objRes.Id='';
objRes.Status='Fail';
objRes.Message=ex.getMessage();
objRes.SeqNum='';
responseList.add(objRes);
String strJSON = '{ "Employee__Response":';
strJSON += JSON.serialize(responseList);
strJSON +='}';
objReqRes.Request_Data__c=ex.getMessage();
//objReqRes.response__c= strJSON;
upsert objReqRes;
AddAttachment('Employee__Request',objReqRes.Id,req.requestBody.toString(),BatchNumber);
AddAttachment('Employee__Response',objReqRes.Id,strJSON,BatchNumber);
system.debug('===responseList 6==='+responseList.size());
RestContext.response.addHeader('Content-Type', 'application/json');
RestContext.response.responseBody = Blob.valueOf(strJSON);
}
}
//Below Method will be used to save attachment against any Parent Object(Parent Id. In our case Parent Id is EmployeeAPIs)
global static void AddAttachment(String Name, String ParentId, String body,String BatchNumber)
{
Attachment attach = new Attachment();
attach.contentType = 'text/plain';
attach.name = Name+'_'+system.now()+'_'+BatchNumber;
attach.parentId = ParentId;
attach.body = Blob.valueOf(body);
insert attach;
}
global static Date ConvertStringToDate(String MapDate)
{
if(!String.isBlank(MapDate))
{
MapDate = MapDate.replace('4712','4000');//check for infinity value
}
return String.isBlank(MapDate) ? null :Date.valueOf(MapDate);
}
}
Below is Complete Request Body send by Third party Apps. In Request 3 Employee data is there. Two record are for Saurabh Jain and one for Avinash Narnaware. As per our code implementation only the latest employee whose EMP_EFF_START_DATE__c is greatest that will be insert into Salesforce Employee object Else it will return ‘Latest employee record already exists.’ into response.
{
"Employee__c" : [
{
"Employee_Name__c":"Saurabh Jain",
"Person_ID__c" : "2628584",
"Employee_Number__c" : "21212212",
"EMP_EFF_START_DATE__c" : "2020-01-08",
"NPW__c" : "850015155",
"FIRST_NAME__c" : "Saurabh",
"LAST_NAME__c" : "Jain",
"OFFICIAL_EMAIL_ADDRESS__c" : "[email protected]",
"EMPLOYEE_TYPE__c" : "Seconded Employee",
"CURRENT_NPW_FLAG__c" : "Y",
"TOTAL_EXP__c" : "0",
"Attribute1__c" : "2628584|02-JAN-20",
"Seq_Number__c" : "392" ,
"Batch_Number__c" : "139672084"
} ,
{
"Employee_Name__c":"Saurabh Jain",
"Person_ID__c" : "2628584",
"Employee_Number__c" : "21212212",
"EMP_EFF_START_DATE__c" : "2020-01-07",
"NPW__c" : "850015155",
"FIRST_NAME__c" : "Saurabh",
"LAST_NAME__c" : "Jain",
"OFFICIAL_EMAIL_ADDRESS__c" : "[email protected]",
"EMPLOYEE_TYPE__c" : "Seconded Employee",
"CURRENT_NPW_FLAG__c" : "Y",
"TOTAL_EXP__c" : "0",
"Attribute1__c" : "2628584|02-JAN-20",
"Seq_Number__c" : "392" ,
"Batch_Number__c" : "139672084"
} ,
{
"Employee_Name__c":"Avinash Narnaware",
"Person_ID__c" : "26285845",
"Employee_Number__c" : "212122125",
"EMP_EFF_START_DATE__c" : "2020-01-08",
"NPW__c" : "8500151555",
"FIRST_NAME__c" : "Avinash",
"LAST_NAME__c" : "Narnaware",
"OFFICIAL_EMAIL_ADDRESS__c" : "[email protected]",
"EMPLOYEE_TYPE__c" : "Seconded Employee",
"CURRENT_NPW_FLAG__c" : "Y",
"TOTAL_EXP__c" : "0",
"Attribute1__c" : "26285845|02-JAN-20",
"Seq_Number__c" : "396" ,
"Batch_Number__c" : "139672085"
}
]
}
Below is Response for above request:
{
"Employee__Response": [
{
"Status": "Fail",
"SeqNum": "392",
"Message": "Latest employee record already exists.",
"Id": "2628584"
},
{
"Status": "Success",
"SeqNum": "392",
"Message": null,
"Id": "2628584"
},
{
"Status": "Success",
"SeqNum": "396",
"Message": null,
"Id": "26285845"
}
]
}
Final Output as Shown in POSTMAN as Below
Employee Records are inserted into Salesforce as shown in below
Request and Response as attachment in salesforce as below screen
Excellent post. Keep writing such kind of information on your site. Jordana Jamesy Durrace
Absolutely written articles, Really enjoyed studying. Ellynn Morgan Avi
Thanks All
This website was… how do you say it? Relevant!! Finally I’ve found something which helped me.
Thanks!
I have not checked in here for some time as I thought it was getting boring, but the last few posts are good quality so I guess I’ll add you back to my daily bloglist. You deserve it my friend 🙂
I have been checking out many of your articles and i can state nice stuff. I will surely bookmark your site. Jared Sturges
This will prevent recurring repairs and maintenance. Lyndon Stenman
Thanks for this post, I am a big big fan of this website would like to go along updated.
wohh just what I was searching for, thanks for posting.