Guest User

Untitled

a guest
Sep 24th, 2018
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.21 KB | None | 0 0
  1. global class CiphrBatchJob implements Database.Batchable<sObject>, Database.AllowsCallouts{
  2. String query;
  3. //final ID UKLog = Schema.getGlobalDescribe().get('Integration_Log__c').getDescribe().getRecordTypeInfosByName().get('UK Log').getRecordTypeId();
  4. String Endpoint = 'https://****/***/absence?EmployeeNumber=[in]';
  5. String DetailEndpoint;
  6. private String API_Key;
  7. private date cutOffDate= Date.newInstance(2010,01,01); //Change date to current year
  8.  
  9. global Database.QueryLocator start(Database.BatchableContext bc){
  10. query = 'Select KC_Employee_Reference__c from KimbleOne__Resource__c where KC_Employee_Reference__c <> null';
  11. return Database.getQueryLocator(query);
  12. }
  13.  
  14. global void execute(Database.BatchableContext BC, List<KimbleOne__Resource__c> scope){
  15. for(Integer i=0;i<scope.size();i++){
  16. if(i==scope.size()-1){
  17. Endpoint += scope[i].KC_Employee_Reference__c;
  18. }else{
  19. Endpoint += scope[i].KC_Employee_Reference__c+',';
  20. }
  21. }
  22.  
  23. Http http = new Http();
  24. HttpRequest request = new HttpRequest();
  25. API_Key = getApiKey();
  26.  
  27. request.setEndpoint(Endpoint);
  28. request.setMethod('GET');
  29. request.setHeader('Accept', 'application/json');
  30. request.setHeader('Authorization', 'apikey '+API_key);
  31. request.setTimeout(60000);
  32.  
  33. CiphrWrapper result;
  34. /*List<Integration_log__c> LogList = new List<Integration_Log__c>();
  35. Integration_log__c log = new Integration_log__c();
  36. log.recordTypeID = UKLog;
  37. log.Job_Name__c = 'Ciphr Get Absence Request';
  38. log.Request_Body__c = 'Get '+Endpoint;*/
  39.  
  40. try{
  41. HttpResponse response = http.send(request);
  42. result = CiphrWrapper.parse(response.getBody());
  43. /*if(response.getBody().length() >= 131001){
  44. log.Response_Body__c = String.valueOf(response.getBody()).subString(0,131000);
  45. }else{
  46. log.Response_Body__c = response.getBody();
  47. }
  48. log.Status__c = response.getStatus();
  49. log.Status_Code__c = response.getStatusCode();*/
  50. }catch(Exception e){
  51. System.debug('Exception during call--> '+e.getMessage());
  52. //log.Exception__c = e.getMessage();
  53. sendEmail('Call to Ciphr failed','Exception Occurred',e.getMessage(),true,Endpoint);
  54. }
  55. //LogList.add(log);
  56.  
  57. Map<String,Ciphr.Resource> CRMap = new Map<String,Ciphr.Resource>();
  58. Map<String,Ciphr.AbsenceDetail> CADMap = new Map<String,Ciphr.AbsenceDetail>();
  59. Map<Integer,Ciphr.Absence> CAMap = new Map<Integer,Ciphr.Absence>();
  60. DateTime dt; Date d;
  61.  
  62. if(result <> null){
  63. //Populate Resources
  64. for(CiphrWrapper.Absence ab: result.Absence){
  65. dt = DateTime.ValueOf(ab.Start.replace('T',' '));
  66. d = Date.newinstance(dT.year(), dT.month(), dT.day());
  67. if(d >= /*System.today()*/ cutOffDate){ //<---- Change Date here
  68. Ciphr.Resource CR = new Ciphr.Resource();
  69. CR.employeeNumber = ab.EmployeeNumber;
  70. CR.absences = new List<Ciphr.Absence>();
  71. CRMap.put(CR.employeeNumber, CR);
  72. }
  73. }
  74.  
  75. //Populate Absences in Resources
  76. for(CiphrWrapper.Absence ab: result.Absence){
  77. dt = DateTime.ValueOf(ab.Start.replace('T',' '));
  78. d = Date.newinstance(dT.year(), dT.month(), dT.day());
  79. if(CRMap.containsKey(ab.employeeNumber) && d >= /*System.today()*/ cutOffDate){ //<-- Change date here
  80. Ciphr.Absence CA = new Ciphr.Absence();
  81. CA.AbsenceID = Integer.valueOf(ab.ID);
  82. CA.employeeNumber = ab.EmployeeNumber;
  83. CA.absenceDetails = new List<Ciphr.AbsenceDetail>();
  84. CAMap.put(CA.AbsenceID, CA);
  85. CRMap.get(CA.employeeNumber).absences.add(CA);
  86. }
  87. }
  88. System.debug('CRMap: '+CRMap);
  89.  
  90. //Calling Absences
  91. for(Ciphr.Resource cr: CRMap.values()){
  92. DetailEndpoint = 'https://****.***/***/absenceDetail?AbsenceID=[in]';
  93. Integer i = 0;
  94. for(Ciphr.Absence ca: cr.absences){
  95. if(i==cr.absences.size()-1){
  96. DetailEndpoint += String.valueOf(ca.AbsenceID);
  97. }else{
  98. DetailEndpoint += String.valueOf(ca.AbsenceID)+',';
  99. }
  100. i++;
  101. }
  102. System.debug('Details Endpoint for emp: '+cr.employeeNumber+' is:'+DetailEndpoint);
  103. HttpRequest requestAbsenceDetail = new HttpRequest();
  104.  
  105. requestAbsenceDetail.setEndpoint(DetailEndpoint);
  106. requestAbsenceDetail.setMethod('GET');
  107. requestAbsenceDetail.setHeader('Accept', 'application/json');
  108. requestAbsenceDetail.setHeader('Authorization', 'apikey '+API_Key);
  109.  
  110. CiphrAbsenceDetail resultAbsenceDetails;
  111. /*Integration_Log__c DetailLog = new Integration_log__c();
  112. DetailLog.RecordTypeId = UKLog;
  113. DetailLog.Job_Name__c = 'Ciphr Get Absence Detail Request';
  114. DetailLog.Request_Body__c = 'Get '+DetailEndpoint;*/
  115.  
  116. try{
  117. HttpResponse responseDetails = http.send(requestAbsenceDetail);
  118. resultAbsenceDetails = CiphrAbsenceDetail.parse(responseDetails.getBody());
  119. /*DetailLog.Response_Body__c = responseDetails.getBody();
  120. DetailLog.Status__c = responseDetails.getStatus();
  121. DetailLog.Status_Code__c = responseDetails.getStatusCode();*/
  122. }catch(Exception e){
  123. System.debug('Exception during Absence detail call for EmployeeNumber --> '+cr.employeeNumber+' '+e.getMessage());
  124. //DetailLog.Exception__c = e.getMessage();
  125. sendEmail('SF Ciphr Detail Call failed','Exception Occurred in Detail Call',e.getMessage(),true,DetailEndpoint);
  126. }//LogList.add(DetailLog);
  127. if(resultAbsenceDetails<> null){
  128. for(Ciphr.Absence ca: cr.absences){
  129. for(CiphrAbsenceDetail.AbsenceDetail cad: resultAbsenceDetails.AbsenceDetail){
  130. if(ca.AbsenceID == cad.AbsenceID){
  131. Ciphr.AbsenceDetail cad1 = new Ciphr.AbsenceDetail();
  132. cad1.employeeNumber = ca.employeeNumber;
  133. cad1.AbsenceID = cad.AbsenceID;
  134. cad1.End_Z = cad.End_Z;
  135. cad1.Start = cad.Start;
  136. cad1.ID = Integer.valueOf(cad.AbsenceID)+'_'+Integer.valueOf(cad.ID);
  137. cad1.Hours = cad.Hours;
  138. CADMap.put(cad1.ID, cad1);
  139. CAMap.get(ca.AbsenceID).absenceDetails.add(cad1);
  140. ca.AbsenceDetails.add(cad1);
  141. }
  142. }
  143.  
  144. }
  145. }
  146. System.debug('CAMap: '+CAMap);
  147. }
  148. System.debug('CRMap: '+CRMap);
  149. }
  150. //Insert Logs //Insert LogList;
  151. //Retrieve current absences greater than the cutoffdate from Kimble
  152. List<KimbleOne__TimeEntryImportLine__c> kimbleCurrentAbsences = [SELECT KimbleOne__ExternalId__c, KimbleOne__Resource__r.KC_Employee_Reference__c, KimbleOne__EntryUnits__c, KimbleOne__EntryDate__c FROM KimbleOne__TimeEntryImportLine__c where KimbleOne__EntryDate__c >=: cutOffDate And KimbleOne__Resource__r.KC_Employee_Reference__c in:CRMap.keyset()];
  153. Map<String, KimbleOne__TimeEntryImportLine__c> KimbleCurrentAbsencesMap = new Map<String, KimbleOne__TimeEntryImportLine__c>();
  154. List<Map<String,Object>> PayLoad = new List<Map<String,Object>>();
  155.  
  156. if(KimbleCurrentAbsences.size()>0){
  157. for(KimbleOne__TimeEntryImportLine__c kab: kimbleCurrentAbsences){
  158. KimbleCurrentAbsencesMap.put(kab.KimbleOne__ExternalId__c, kab);
  159. }
  160. }
  161.  
  162. //Check and remove absence details if they exist in Kimble with same absence detail Id and same no. of hours
  163. for(Ciphr.AbsenceDetail cad: CADMap.Values()){
  164. if(KimbleCurrentAbsencesMap.containsKey(cad.id)){
  165. if(cad.hours == KimbleCurrentAbsencesMap.get(cad.id).KimbleOne__EntryUnits__c)
  166. {
  167. CADMap.remove(cad.id);
  168. KimbleCurrentAbsencesMap.remove(cad.id);
  169. }
  170. }
  171. }
  172.  
  173. //Check if there are any absence details in Kimble but are not Ciphr i.e. absence details that were deleted in Ciphr so add a 0 against the absence deleted in Ciphr
  174. for(KimbleOne__TimeEntryImportLine__c kab: KimbleCurrentAbsencesMap.values()){
  175. if(!CadMap.containsKey(kab.KimbleOne__ExternalId__c)){
  176. Ciphr.AbsenceDetail cad = new Ciphr.AbsenceDetail();
  177. cad.employeeNumber = KimbleCurrentAbsencesMap.get(kab.KimbleOne__ExternalId__c).KimbleOne__Resource__r.KC_Employee_Reference__c;
  178. cad.Start = KimbleCurrentAbsencesMap.get(kab.KimbleOne__ExternalId__c).KimbleOne__EntryDate__c.format();
  179. cad.ID = kab.KimbleOne__ExternalId__c;
  180. cad.Hours = 0;
  181. CADMap.put(kab.KimbleOne__ExternalId__c,cad);
  182. }
  183. }
  184.  
  185.  
  186. //Prepare the payload
  187. for(Ciphr.AbsenceDetail cad: CADMap.Values()){
  188. Map<String,Object> MaptoSerialize = new Map<String,Object>{'resource' => cad.employeeNumber,'activity' => 'a5z1w0000004CH5AAM', 'date' => Date.valueOf(cad.start), 'hours' => cad.Hours, 'CIPHR_Id' => cad.ID};
  189. PayLoad.add(MaptoSerialize);
  190. }
  191.  
  192. String responseOfPayloadPush = SendPayload(PayLoad);
  193.  
  194. System.debug('*******************Payload******************n'+json.serializePretty(PayLoad));
  195. System.debug('Response of the payload push: '+responseOfPayloadPush); //Uncomment for testing
  196.  
  197. //Below only for testing
  198. Attachment att = new Attachment();
  199. att.parentID = '001w000001W37mWAAR'; //Attaches to account "jon_singer_test_UK_SOHO"
  200. att.ContentType = 'text/plain';
  201. att.name = 'Payload '+Date.today()+'.txt';
  202. if(String.valueOf(json.serializePretty(PayLoad)).length()>131000){
  203. att.body = Blob.valueOf(String.valueOf(json.serializePretty(PayLoad)).substring(0,131000));
  204. }else{
  205. att.body = Blob.valueOf(String.valueOf(json.serializePretty(PayLoad)));
  206. }
  207. insert att;
  208.  
  209. Attachment att1 = new Attachment();
  210. att1.parentID = '001w000001W37mWAAR'; //Attaches to account "jon_singer_test_UK_SOHO"
  211. att1.ContentType = 'text/plain';
  212. att1.name = 'Payload Push Response'+Date.today()+'.txt';
  213. att1.body = Blob.valueOf(responseOfPayloadPush);
  214. insert att1;
  215. //Above for Testing only
  216. }
  217.  
  218. global void finish(Database.BatchableContext BC){
  219. sendEmail('SF Ciphr Records Processed','SF Ciphr Batch Process Completed','SF Ciphr Batch Process Completed.',false,'');
  220. }
  221.  
  222. private String getApiKey(){
  223. Ciphr_Kimble__c ck = Ciphr_Kimble__c.getInstance();
  224. String key = ck.EncryptionKey__c;
  225. String APIKey = ck.EncryptedCiphrKey__c;
  226. Blob decrypted = Crypto.decryptWithManagedIV('AES128', EncodingUtil.base64Decode(key), EncodingUtil.base64Decode(APIKey));
  227. APIKey = decrypted.toString();
  228. //System.debug('API Key getApiKey '+APIKey);
  229. return APIKey;
  230. }
  231.  
  232. private void sendEmail(string displayName, string subject, String messageBody, boolean exceptionOccurred, String endpoint){
  233. Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
  234. mail.setToAddresses(new String[] {'****@***.***'});
  235. //mail.setToAddresses(new String[] {'*****@****.***'});
  236. mail.setReplyTo('batch@acme.com');
  237. mail.setSenderDisplayName(displayName);
  238. mail.setSubject(subject);
  239. if(exceptionOccurred){
  240. mail.setPlainTextBody('Exception: '+messageBody+'nnFor URL: '+endpoint);
  241. }else{
  242. mail.setPlainTextBody(messageBody);
  243. }
  244. Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
  245. }
  246.  
  247. private String SendPayload(List<Map<String,Object>> payload){
  248. String sfdcURL = URL.getSalesforceBaseUrl().toExternalForm();
  249. String restAPIURL = sfdcURL + '/services/apexrest/***/**/****/***';
  250.  
  251. HttpRequest httpRequest = new HttpRequest();
  252. httpRequest.setEndpoint(restAPIURL);
  253. httpRequest.setMethod('POST');
  254. httprequest.setHeader('Content-Type', 'application/json');
  255. httprequest.setHeader('Accept','application/json');
  256. httpRequest.setHeader('Authorization', 'OAuth ' + UserInfo.getSessionId());
  257. httpRequest.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionID());
  258. httpRequest.setBody(json.serializePretty(PayLoad));
  259. String response = '';
  260. try {
  261. Http http = new Http();
  262. HttpResponse httpResponse = http.send(httpRequest);
  263. System.debug('>> Response of payload >> '+httpResponse.getStatusCode());
  264. response = 'Status Code: '+httpResponse.getStatusCode()+' Response: '+httpResponse.getBody();
  265. } catch(Exception e) {
  266. System.debug('ERROR: '+ e.getMessage());
  267. response = e.getMessage();
  268. sendEmail('Payload Sending to Kimble failed','Exception Occurred Payload Push',e.getMessage(),true,restAPIURL);
  269. }
  270. System.debug(' ** response ** : ' + response );
  271. return response;
  272. }}
  273.  
  274. @isTest(SeeAllData = True) //In progress
  275. public class CiphrBatchJobTest {
  276. static testmethod void doTest(){
  277. Test.startTest();
  278. CiphrBatchJob c = new CiphrBatchJob();
  279. Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator_Ciphr());
  280. ID BatchProcessID = Database.executeBatch(c,50);
  281. Test.stopTest();
  282. }
  283. }
  284.  
  285. @isTest
  286. global class MockHttpResponseGenerator_Ciphr {
  287. // Implement this interface method
  288. global HTTPResponse respond(HTTPRequest req) {
  289. // Create a fake response
  290. if(req.getBody().contains('EmployeeNumber')){
  291. HttpResponse res = new HttpResponse();
  292. res.setHeader('Content-Type', 'application/json');
  293. res.setBody('{"Absence": [{"ID": "1463","Start": "1995-08-08T00:00:00","End": "1995-08-20T00:00:00","EmployeeNumber": "10187","Forenames": "Jonathan","Surname": "Christopher"}]}');
  294. res.setStatusCode(200);
  295. return res;
  296. }else if(req.getBody().contains('AbsenceID')){
  297. HttpResponse res = new HttpResponse();
  298. res.setHeader('Content-Type', 'application/json');
  299. res.setBody('{"AbsenceDetail": [{"AbsenceID": "1463","Start": "1995-08-08T00:00:00","End": "1995-08-20T00:00:00","ID": 8763 ,"Hours": 7.40}]}');
  300. res.setStatusCode(200);
  301. return res;
  302. }else{
  303. return null;
  304. }
  305.  
  306. }
  307. }
Add Comment
Please, Sign In to add comment