fork download
  1. public class PaynetReportBatch implements Database.Batchable<sObject>, Database.AllowsCallouts,Database.Stateful {
  2. private Id opportunityId;
  3.  
  4. public PaynetReportBatch(Id opportunityId) {
  5. this.opportunityId = opportunityId;
  6. }
  7.  
  8. public Database.QueryLocator start(Database.BatchableContext bc) {
  9. return Database.getQueryLocator([SELECT Id, AccountId FROM Opportunity WHERE Id = :opportunityId]);
  10. }
  11.  
  12. public void execute(Database.BatchableContext bc, List<sObject> scope) {
  13. Id acctId;
  14. try {
  15. Opportunity opp = (Opportunity) scope[0];
  16. acctId = opp.AccountId;
  17.  
  18. forseva1__CreditPolicy__c creditPolicy = [SELECT Id FROM forseva1__CreditPolicy__c WHERE Name = 'WEF Paynet Automated' LIMIT 1];
  19.  
  20. Id creditPolicyId = creditPolicy.Id;
  21.  
  22. forseva1.CommercialReportService crs = new forseva1.CommercialReportService();
  23. forseva1__PaynetCreditHistoryReport__c efx = (forseva1__PaynetCreditHistoryReport__c) crs.performCreditRequest(acctId, creditPolicyId, 'Credit Review');
  24. } catch (Exception ex) {
  25. system.debug('An error occurred during batch execution: ' + ex.getMessage());
  26. forseva1__Decision__c[] decisionRecords = [SELECT Id, PayNet_Credit_History_Log__c
  27. FROM forseva1__Decision__c
  28. WHERE Opportunity__c = :opportunityId
  29. ORDER BY CreatedDate DESC
  30. LIMIT 1];
  31. if (!decisionRecords.isEmpty()) {
  32. forseva1__Decision__c decisionRecord = decisionRecords[0];
  33. decisionRecord.PayNet_Credit_History_Log__c = ex.getMessage();
  34. update decisionRecord;
  35. }
  36.  
  37. if (ex.getMessage().contains('Paynet')|| ex.getMessage().contains('Error in performCreditRequest()')) {
  38. forseva1__PaynetCreditHistoryReport__c newPaynet = new forseva1__PaynetCreditHistoryReport__c(
  39. forseva1__Account__c = acctId
  40. );
  41.  
  42. insert newPaynet;
  43. }
  44. }
  45. }
  46.  
  47. public void finish(Database.BatchableContext bc) {
  48. updateRelatedDecision(opportunityId);
  49. execDecScoreCard(true, opportunityId);
  50. handlePostScoreRules(opportunityId);
  51. timeInBusiness (opportunityId);
  52. calculateSecondaryDecision(opportunityId);
  53. }
  54.  
  55. public static void updateRelatedDecision(Id oppId) {
  56. try {
  57. Opportunity opp = [SELECT Id, AccountId FROM Opportunity WHERE Id = :oppId LIMIT 1];
  58.  
  59. forseva1__Decision__c decision = [SELECT Id, Opportunity__c, WEF_Decision_Status__c, Master_Score_Points__c, MasterScore__c
  60. FROM forseva1__Decision__c
  61. WHERE Opportunity__c = :oppId
  62. ORDER BY CreatedDate DESC
  63. LIMIT 1];
  64. System.debug('Decision record: ' + decision);
  65. forseva1__PaynetCreditHistoryReport__c paynetReport = [SELECT Id, forseva1__Account__c, Opportunity__c, Decision__c, forseva1__Master_Score__c, MasterScore_Points__c
  66. FROM forseva1__PaynetCreditHistoryReport__c
  67. WHERE forseva1__Account__c = :opp.AccountId
  68. ORDER BY CreatedDate DESC
  69. LIMIT 1];
  70.  
  71. paynetReport.Opportunity__c = oppId;
  72. paynetReport.Decision__c = decision.Id;
  73. update paynetReport;
  74.  
  75. decision.WEF_Decision_Status__c = 'Paynet Commercial Complete';
  76. decision.MasterScore__c = paynetReport.forseva1__Master_Score__c;
  77. decision.Master_Score_Points__c = paynetReport.MasterScore_Points__c;
  78. update decision;
  79. } catch (Exception e) {
  80. System.debug('An error occurred while updating related decision: ' + e.getMessage());
  81. System.debug('Stack trace: ' + e.getStackTraceString());
  82. }
  83. }
  84. public static void execDecScoreCard(Boolean main, Id oppId) {
  85. try {
  86. forseva1__Decision__c latestDecision = [SELECT Id, forseva1__Account__c, CIDS_Score_Points__c, Master_Score_Points__c,
  87. FICO_Score_Points__c, WEF_Score_Tier__c, Cut_Off_Segment__c, Primary_Decision__c
  88. FROM forseva1__Decision__c
  89. WHERE Opportunity__c = :oppId
  90. ORDER BY CreatedDate DESC
  91. LIMIT 1];
  92. List<forseva1__Decision__c> decReqList = new List<forseva1__Decision__c>();
  93. decReqList.add(latestDecision);
  94. forseva1.ScorecardService scService = new forseva1.ScorecardService();
  95. List<Id> secSCs = new List<Id>();
  96. if (main) {
  97. List<forseva1__Scorecard__c> fullScorecard = [SELECT Id, Name, forseva1__Active__c
  98. FROM forseva1__Scorecard__c
  99. WHERE Name = 'Decision'
  100. LIMIT 1];
  101. if (fullScorecard != null && !fullScorecard.isEmpty()) {
  102. secSCs.add(fullScorecard[0].Id);
  103. if (!Test.isRunningTest()) {
  104. scService.executeScorecards(decReqList, null, secSCs);
  105. }
  106. }
  107. }
  108. } catch (Exception e) {
  109. System.debug('An error occurred while executing the score card: ' + e.getMessage());
  110. System.debug('Stack trace: ' + e.getStackTraceString());
  111. }
  112. }
  113.  
  114. public static void timeInBusiness (Id oppId) {
  115. try {
  116. // Fetch the latest decision record for the opportunity
  117. Opportunity opp = [SELECT Id, AccountId, WEF_Years_In_Business__c FROM Opportunity WHERE Id = :oppId];
  118.  
  119. forseva1__Decision__c decision = [SELECT Id, forseva1__Account__c, Consumer_Bankruptcy__c, Commercial_Bankruptcy__c, Post_Score_Action__c, Time_In_Business__c
  120. FROM forseva1__Decision__c WHERE Opportunity__c = :oppId ORDER BY CreatedDate DESC LIMIT 1];
  121.  
  122. forseva1__PaynetCreditHistoryReport__c paynetReport = [SELECT Id, forseva1__Account__c, Opportunity__c, Decision__c, forseva1__Master_Score__c, MasterScore_Points__c, Years_In_Business__c
  123. FROM forseva1__PaynetCreditHistoryReport__c WHERE forseva1__Account__c = :opp.AccountId ORDER BY createdDate DESC LIMIT 1];
  124.  
  125. forseva1__EquifaxCommercialCredit__c commercialReport = [SELECT Id, forseva1__Account__c, Opportunity__c, Decision__c, Commercial_Bankruptcy__c, CIDS_Score__c, CIDS_Score_Points__c,
  126. Amount_Financed__c, Lien_Recent_Date__c, Total_Lien_Amount__c, No_of_Liens__c, Judgments__c, Judgment_Recent_Date__c,
  127. Total_Judgment_Amount__c, Commercial_Public_Filings__c, Industry_Requires_Manual_Review__c, forseva1__eqYearsInBusiness__c
  128. FROM forseva1__EquifaxCommercialCredit__c WHERE forseva1__Account__c = :opp.AccountId ORDER BY createdDate DESC LIMIT 1];
  129.  
  130. Integer numberOfPg = getNumberOfPGs(oppId);
  131.  
  132. Boolean timeInBusiness = false;
  133.  
  134. if (opp.WEF_Years_In_Business__c != null) {
  135.  
  136. if ( opp.WEF_Years_In_Business__c > 0 && opp.WEF_Years_In_Business__c < 2 && numberOfPg > 0) {
  137. timeInBusiness = true;
  138. System.debug('Condition 1 met: WEF Years In Business > 0 and < 2 and Number of PGs > 0');
  139. } else if ( opp.WEF_Years_In_Business__c > 0 && opp.WEF_Years_In_Business__c < 5 && numberOfPg == 0) {
  140. timeInBusiness = true;
  141. System.debug('Condition 2 met: WEF Years In Business > 0 and < 5 and Number of PGs == 0');
  142. }
  143. } else if (opp.WEF_Years_In_Business__c == null && commercialReport.forseva1__eqYearsInBusiness__c != null) {
  144. if (commercialReport.forseva1__eqYearsInBusiness__c > 0 && commercialReport.forseva1__eqYearsInBusiness__c < 2 && numberOfPg > 0) {
  145. timeInBusiness = true;
  146. System.debug('Condition 3 met: Equifax Years In Business > 0 and < 2 and Number of PGs > 0');
  147. } else if (commercialReport.forseva1__eqYearsInBusiness__c > 0 && commercialReport.forseva1__eqYearsInBusiness__c < 5 && numberOfPg == 0) {
  148. timeInBusiness = true;
  149. System.debug('Condition 4 met: Equifax Years In Business > 0 and < 5 and Number of PGs == 0');
  150. }
  151. } else if (opp.WEF_Years_In_Business__c == null && paynetReport.Years_In_Business__c != null) {
  152. if (paynetReport.Years_In_Business__c > 0 && paynetReport.Years_In_Business__c < 2 && numberOfPg > 0) {
  153. timeInBusiness = true;
  154. System.debug('Condition 5 met: Paynet Years In Business > 0 and < 2 and Number of PGs > 0');
  155. } else if (paynetReport.Years_In_Business__c > 0 && paynetReport.Years_In_Business__c < 5 && numberOfPg == 0) {
  156. timeInBusiness = true;
  157. System.debug('Condition 6 met: Paynet Years In Business > 0 and < 5 and Number of PGs == 0');
  158. }
  159. }
  160.  
  161. // Update the decision record if any of the conditions are met
  162. if (timeInBusiness) {
  163. decision.Time_In_Business__c = true;
  164. decision.Post_Score_Action__c = 'Manual Review';
  165. update decision;
  166. }
  167.  
  168. } catch (Exception e) {
  169. System.debug('An error occurred while handling decision rules: ' + e.getMessage());
  170. }
  171. }
  172.  
  173. public static Integer getNumberOfPGs(Id oppId) {
  174. List<Relationship__c> oppContactandPgs = [SELECT Id FROM Relationship__c WHERE Related_Opportunity__c = :oppId AND Relationship_Type__c = 'Personal Guarantee'];
  175. return oppContactandPgs.size();
  176. }
  177.  
  178. public static void handlePostScoreRules(Id oppId) {
  179. try {
  180. forseva1__Decision__c latestDecision = [SELECT Id, forseva1__Account__c, Consumer_Bankruptcy__c, Commercial_Bankruptcy__c, Prior_Decline__c, Previous_ChargeOff__c,
  181. Low_FICO_Score_Post_Scoring__c, Exceeds_App_Only_Limit__c, Time_In_Business__c, number_of_Inquiries__c, PG_Thin_File__c,
  182. Industry_Requires_Manual_Review__c, Low_CIDS__c, Low_MSV2__c, Commercial_Public_Filings__c, No_Commercial_Data__c,
  183. Currently_Delinquent_With_WEF__c, WEF_Risk_Rated__c, Post_Score_Action__c, WEF_Decision_Status__c
  184. FROM forseva1__Decision__c
  185. WHERE Opportunity__c = :oppId
  186. ORDER BY CreatedDate DESC
  187. LIMIT 1];
  188.  
  189. Boolean shouldDecline = latestDecision.Consumer_Bankruptcy__c || latestDecision.Commercial_Bankruptcy__c ||
  190. latestDecision.Prior_Decline__c || latestDecision.Previous_ChargeOff__c;
  191.  
  192. Boolean shouldManualReview = latestDecision.Low_FICO_Score_Post_Scoring__c || latestDecision.Exceeds_App_Only_Limit__c || latestDecision.Time_In_Business__c || latestDecision.number_of_Inquiries__c ||latestDecision.PG_Thin_File__c || latestDecision.Industry_Requires_Manual_Review__c ||
  193. latestDecision.Low_CIDS__c || latestDecision.Low_MSV2__c || latestDecision.Commercial_Public_Filings__c || latestDecision.No_Commercial_Data__c ||latestDecision.Currently_Delinquent_With_WEF__c || latestDecision.WEF_Risk_Rated__c;
  194.  
  195.  
  196. if (shouldDecline) {
  197. latestDecision.Post_Score_Action__c = 'Decline';
  198. } else if (shouldManualReview) {
  199. latestDecision.Post_Score_Action__c = 'Manual Review';
  200. } else {
  201. latestDecision.Post_Score_Action__c = 'Pass';
  202. }
  203.  
  204. latestDecision.WEF_Decision_Status__c = 'Post Scoring Complete';
  205. update latestDecision;
  206. } catch (Exception e) {
  207. System.debug('An error occurred while handling post score rules: ' + e.getMessage());
  208. System.debug('Stack trace: ' + e.getStackTraceString());
  209. }
  210. }
  211.  
  212.  
  213.  
  214. // Method to calculate Secondary Decision for a given Opportunity
  215. public static void calculateSecondaryDecision(Id oppId) {
  216. try {
  217. forseva1__Decision__c decision = [SELECT Id, Primary_Decision__c, Post_Score_Action__c, Pre_Score_Action__c, Final_Decision__c, WEF_Score_Tier__c, WEF_Score_Credit_Rating__c, WEF_Score_Risk_Rating__c
  218. FROM forseva1__Decision__c
  219. WHERE Opportunity__c = :oppId
  220. ORDER BY CreatedDate DESC LIMIT 1
  221. ];
  222.  
  223. if (decision != null) {
  224. // Calculate Secondary Decision based on Pre Score Action, Primary Decision and Post Score Action
  225. String primaryDecision = decision.Primary_Decision__c;
  226. String postScoreAction = decision.Post_Score_Action__c;
  227. String preScoreAction = decision.Pre_Score_Action__c;
  228. String finalDecision = decision.Final_Decision__c;
  229. Integer numberOfPGs = getNumberOfPGs(oppId);
  230. String secondaryDecision;
  231.  
  232. if (preScoreAction == 'No Rule Triggered' && primaryDecision == 'Approve' && postScoreAction == 'Manual Review') {
  233. secondaryDecision = 'Manual Review';
  234. } else if (preScoreAction == 'No Rule Triggered' && primaryDecision == 'Recommend Approve' && postScoreAction == 'Manual Review') {
  235. secondaryDecision = 'Manual Review';
  236. } else if (preScoreAction == 'No Rule Triggered' && primaryDecision == 'Recommend Approve' && postScoreAction == 'Decline') {
  237. secondaryDecision = 'Decline';
  238. } else if (preScoreAction == 'No Rule Triggered' && primaryDecision == 'Approve' && postScoreAction == 'Decline') {
  239. secondaryDecision = 'Decline';
  240. } else if (preScoreAction == 'No Rule Triggered' && primaryDecision == 'Approve' && postScoreAction == 'Pass') {
  241. secondaryDecision = 'Approve';
  242. } else if (preScoreAction == 'No Rule Triggered' && primaryDecision == 'Recommend Decline' && postScoreAction == 'Pass' /*String.isBlank(postScoreAction)*/) {
  243. secondaryDecision = 'Manual Review';
  244. } else if (preScoreAction == 'Decline' && primaryDecision == 'Not Scored' && postScoreAction == 'Pass') {
  245. secondaryDecision = 'Decline';
  246. } else if (preScoreAction == 'Manual Review' && primaryDecision == 'Not Scored' && postScoreAction == 'Pass') {
  247. secondaryDecision = 'Manual Review';
  248. } else if (preScoreAction == 'Decline' && primaryDecision == 'Approve' && postScoreAction == 'Manual Review') {
  249. secondaryDecision = 'Manual Review';
  250. } else if (preScoreAction == 'Decline' && primaryDecision == 'Recommend Approve' && postScoreAction == 'Manual Review') {
  251. secondaryDecision = 'Manual Review';
  252. } else if (preScoreAction == 'Decline' && primaryDecision == 'Recommend Approve' && postScoreAction == 'Decline') {
  253. secondaryDecision = 'Decline';
  254. } else if (preScoreAction == 'Decline' && primaryDecision == 'Approve' && postScoreAction == 'Decline') {
  255. secondaryDecision = 'Decline';
  256. } else if (preScoreAction == 'Decline' && primaryDecision == 'Approve' && postScoreAction == 'Pass') {
  257. secondaryDecision = 'Approve';
  258. } else if (preScoreAction == 'Decline' && primaryDecision == 'Recommend Decline' && postScoreAction == 'Pass') {
  259. secondaryDecision = 'Manual Review';
  260. } else if (preScoreAction == 'Manual Review' && primaryDecision == 'Approve' && postScoreAction == 'Manual Review') {
  261. secondaryDecision = 'Manual Review';
  262. } else if (preScoreAction == 'Manual Review' && primaryDecision == 'Recommend Approve' && postScoreAction == 'Manual Review') {
  263. secondaryDecision = 'Manual Review';
  264. } else if (preScoreAction == 'Manual Review' && primaryDecision == 'Recommend Approve' && postScoreAction == 'Decline') {
  265. secondaryDecision = 'Decline';
  266. } else if (preScoreAction == 'Manual Review' && primaryDecision == 'Approve' && postScoreAction == 'Decline') {
  267. secondaryDecision = 'Decline';
  268. } else if (preScoreAction == 'Manual Review' && primaryDecision == 'Approve' && postScoreAction == 'Pass') {
  269. secondaryDecision = 'Approve';
  270. } else if (preScoreAction == 'Manual Review' && primaryDecision == 'Recommend Decline' && postScoreAction == 'Pass') {
  271. secondaryDecision = 'Manual Review';
  272. } else if (preScoreAction == 'No Rule Triggered' && primaryDecision == 'Decline' && postScoreAction == 'Pass') {
  273. secondaryDecision = 'Decline';
  274.  
  275. } else if (preScoreAction == 'No Rule Triggered' && primaryDecision == 'Recommend Approve' && postScoreAction == 'Pass') {
  276. secondaryDecision = 'Manual Review';
  277. } else if (preScoreAction == 'No Rule Triggered' && primaryDecision == 'Recommend Decline' && postScoreAction == 'Manual Review') {
  278. secondaryDecision = 'Manual Review';
  279. } else if (preScoreAction == 'No Rule Triggered' && primaryDecision == 'Recommend Decline' && postScoreAction == 'Decline') {
  280. secondaryDecision = 'Decline';
  281. } else if (preScoreAction == 'Manual Review' && primaryDecision == 'Recommend Approve' && postScoreAction == 'Pass') {
  282. secondaryDecision = 'Manual Review';
  283. } else if (preScoreAction == 'Manual Review' && primaryDecision == 'Recommend Decline' && postScoreAction == 'Manual Review') {
  284. secondaryDecision = 'Manual Review';
  285. } else if (preScoreAction == 'Manual Review' && primaryDecision == 'Recommend Decline' && postScoreAction == 'Decline') {
  286. secondaryDecision = 'Decline';
  287. } else if (preScoreAction == 'Decline' && primaryDecision == 'Recommend Approve' && postScoreAction == 'Pass') {
  288. secondaryDecision = 'Manual Review';
  289. } else if (preScoreAction == 'Decline' && primaryDecision == 'Recommend Decline' && postScoreAction == 'Manual Review') {
  290. secondaryDecision = 'Manual Review';
  291. } else if (preScoreAction == 'Decline' && primaryDecision == 'Recommend Decline' && postScoreAction == 'Decline') {
  292. secondaryDecision = 'Decline';
  293. } else if (preScoreAction == 'Manual Review' && primaryDecision == 'Decline' && postScoreAction == 'Manual Review') {
  294. secondaryDecision = 'Decline';
  295. } else if (preScoreAction == 'Manual Review' && primaryDecision == 'Decline' && postScoreAction == 'Decline') {
  296. secondaryDecision = 'Decline';
  297. } else if (preScoreAction == 'Manual Review' && primaryDecision == 'Decline' && postScoreAction == 'Pass') {
  298. secondaryDecision = 'Decline';
  299. } else if (preScoreAction == 'Decline' && primaryDecision == 'Decline' && postScoreAction == 'Manual Review') {
  300. secondaryDecision = 'Decline';
  301. } else if (preScoreAction == 'Decline' && primaryDecision == 'Decline' && postScoreAction == 'Decline') {
  302. secondaryDecision = 'Decline';
  303. } else if (preScoreAction == 'Decline' && primaryDecision == 'Decline' && postScoreAction == 'Pass') {
  304. secondaryDecision = 'Decline';
  305. } else if (preScoreAction == 'No Rule Triggered' && primaryDecision == 'Decline' && postScoreAction == 'Manual Review') {
  306. secondaryDecision = 'Decline';
  307. } else if (preScoreAction == 'No Rule Triggered' && primaryDecision == 'Decline' && postScoreAction == 'Decline') {
  308. secondaryDecision = 'Decline';
  309. } else {
  310. // Handle cases not explicitly covered
  311. secondaryDecision = '';
  312. }
  313.  
  314. // Calculate Final Decision based on Secondary Decision
  315. if (secondaryDecision == 'Manual Review') {
  316. finalDecision = 'Made by Analyst';
  317. } else if (secondaryDecision == 'Decline') {
  318. finalDecision = 'Declined';
  319. } else if (secondaryDecision == 'Approve') {
  320. finalDecision = 'Approved';
  321. } else {
  322. // Handle cases not explicitly covered
  323. finalDecision = null;
  324. }
  325.  
  326. // Update the Decision record with the calculated Secondary Decision
  327. decision.Secondary_Decision__c = secondaryDecision;
  328. decision.Final_Decision__c = finalDecision;
  329. update decision;
  330.  
  331. // Update Opportunity record
  332. Opportunity opp = new Opportunity(Id = oppId);
  333. opp.Primary_Decision__c = primaryDecision;
  334. opp.Secondary_Decision__c = secondaryDecision;
  335. opp.Final_Decision__c = finalDecision;
  336. opp.WEF_Score_Tier__c = decision.WEF_Score_Tier__c;
  337. opp.WEF_Score_Credit_Rating__c = decision.WEF_Score_Credit_Rating__c;
  338. opp.WEF_Score_Risk_Rating__c = decision.WEF_Score_Risk_Rating__c;
  339. opp.Number_of_PGs__c = numberOfPGs; // update the Opportunity with the number of PGs
  340.  
  341. update opp;
  342.  
  343. }
  344. } catch (Exception e) {
  345. System.debug('An error occurred while calculating secondary decision: ' + e.getMessage());
  346. System.debug('Stack trace: ' + e.getStackTraceString());
  347. }
  348. }
  349. }
Success #stdin #stdout #stderr 0.02s 12324KB
stdin
Standard input is empty
stdout
Object: UndefinedObject error: did not understand #PaynetReportBatch
MessageNotUnderstood(Exception)>>signal (ExcHandling.st:254)
UndefinedObject class(Object)>>doesNotUnderstand: #PaynetReportBatch (SysExcept.st:1448)
UndefinedObject>>executeStatements (prog:1)
Object: nil error: did not understand #associationAt:ifAbsent:
MessageNotUnderstood(Exception)>>signal (ExcHandling.st:254)
UndefinedObject(Object)>>doesNotUnderstand: #associationAt:ifAbsent: (SysExcept.st:1448)
DeferredVariableBinding>>resolvePathFrom: (DeferBinding.st:115)
DeferredVariableBinding>>value (DeferBinding.st:69)
UndefinedObject>>executeStatements (prog:31)
Object: nil error: did not understand #associationAt:ifAbsent:
MessageNotUnderstood(Exception)>>signal (ExcHandling.st:254)
UndefinedObject(Object)>>doesNotUnderstand: #associationAt:ifAbsent: (SysExcept.st:1448)
DeferredVariableBinding>>resolvePathFrom: (DeferBinding.st:115)
DeferredVariableBinding>>value (DeferBinding.st:69)
UndefinedObject>>executeStatements (prog:101)
Object: nil error: did not understand #associationAt:ifAbsent:
MessageNotUnderstood(Exception)>>signal (ExcHandling.st:254)
UndefinedObject(Object)>>doesNotUnderstand: #associationAt:ifAbsent: (SysExcept.st:1448)
DeferredVariableBinding>>resolvePathFrom: (DeferBinding.st:115)
DeferredVariableBinding>>value (DeferBinding.st:69)
UndefinedObject>>executeStatements (prog:103)
stderr
./prog:1: expected expression
./prog:31: expected expression
./prog:101: expected expression
./prog:101: expected expression
./prog:103: expected expression
./prog:134: expected expression
./prog:143: expected expression
./prog:151: expected expression
./prog:223: expected expression