public class PaynetReportBatch implements Database.Batchable<sObject>, Database.AllowsCallouts,Database.Stateful {
private Id opportunityId;
public PaynetReportBatch(Id opportunityId) {
this.opportunityId = opportunityId;
}
public Database.QueryLocator start(Database.BatchableContext bc) {
return Database.getQueryLocator([SELECT Id, AccountId FROM Opportunity WHERE Id = :opportunityId]);
}
public void execute(Database.BatchableContext bc, List<sObject> scope) {
Id acctId;
try {
Opportunity opp = (Opportunity) scope[0];
acctId = opp.AccountId;
forseva1__CreditPolicy__c creditPolicy = [SELECT Id FROM forseva1__CreditPolicy__c WHERE Name = 'WEF Paynet Automated' LIMIT 1];
Id creditPolicyId = creditPolicy.Id;
forseva1.CommercialReportService crs = new forseva1.CommercialReportService();
forseva1__PaynetCreditHistoryReport__c efx = (forseva1__PaynetCreditHistoryReport__c) crs.performCreditRequest(acctId, creditPolicyId, 'Credit Review');
} catch (Exception ex) {
system.debug('An error occurred during batch execution: ' + ex.getMessage());
forseva1__Decision__c[] decisionRecords = [SELECT Id, PayNet_Credit_History_Log__c
FROM forseva1__Decision__c
WHERE Opportunity__c = :opportunityId
ORDER BY CreatedDate DESC
LIMIT 1];
if (!decisionRecords.isEmpty()) {
forseva1__Decision__c decisionRecord = decisionRecords[0];
decisionRecord.PayNet_Credit_History_Log__c = ex.getMessage();
update decisionRecord;
}
if (ex.getMessage().contains('Paynet')|| ex.getMessage().contains('Error in performCreditRequest()')) {
forseva1__PaynetCreditHistoryReport__c newPaynet = new forseva1__PaynetCreditHistoryReport__c(
forseva1__Account__c = acctId
);
insert newPaynet;
}
}
}
public void finish(Database.BatchableContext bc) {
updateRelatedDecision(opportunityId);
execDecScoreCard(true, opportunityId);
handlePostScoreRules(opportunityId);
timeInBusiness (opportunityId);
calculateSecondaryDecision(opportunityId);
}
public static void updateRelatedDecision(Id oppId) {
try {
Opportunity opp = [SELECT Id, AccountId FROM Opportunity WHERE Id = :oppId LIMIT 1];
forseva1__Decision__c decision = [SELECT Id, Opportunity__c, WEF_Decision_Status__c, Master_Score_Points__c, MasterScore__c
FROM forseva1__Decision__c
WHERE Opportunity__c = :oppId
ORDER BY CreatedDate DESC
LIMIT 1];
System.debug('Decision record: ' + decision);
forseva1__PaynetCreditHistoryReport__c paynetReport = [SELECT Id, forseva1__Account__c, Opportunity__c, Decision__c, forseva1__Master_Score__c, MasterScore_Points__c
FROM forseva1__PaynetCreditHistoryReport__c
WHERE forseva1__Account__c = :opp.AccountId
ORDER BY CreatedDate DESC
LIMIT 1];
paynetReport.Opportunity__c = oppId;
paynetReport.Decision__c = decision.Id;
update paynetReport;
decision.WEF_Decision_Status__c = 'Paynet Commercial Complete';
decision.MasterScore__c = paynetReport.forseva1__Master_Score__c;
decision.Master_Score_Points__c = paynetReport.MasterScore_Points__c;
update decision;
} catch (Exception e) {
System.debug('An error occurred while updating related decision: ' + e.getMessage());
System.debug('Stack trace: ' + e.getStackTraceString());
}
}
public static void execDecScoreCard(Boolean main, Id oppId) {
try {
forseva1__Decision__c latestDecision = [SELECT Id, forseva1__Account__c, CIDS_Score_Points__c, Master_Score_Points__c,
FICO_Score_Points__c, WEF_Score_Tier__c, Cut_Off_Segment__c, Primary_Decision__c
FROM forseva1__Decision__c
WHERE Opportunity__c = :oppId
ORDER BY CreatedDate DESC
LIMIT 1];
List<forseva1__Decision__c> decReqList = new List<forseva1__Decision__c>();
decReqList.add(latestDecision);
forseva1.ScorecardService scService = new forseva1.ScorecardService();
List<Id> secSCs = new List<Id>();
if (main) {
List<forseva1__Scorecard__c> fullScorecard = [SELECT Id, Name, forseva1__Active__c
FROM forseva1__Scorecard__c
WHERE Name = 'Decision'
LIMIT 1];
if (fullScorecard != null && !fullScorecard.isEmpty()) {
secSCs.add(fullScorecard[0].Id);
if (!Test.isRunningTest()) {
scService.executeScorecards(decReqList, null, secSCs);
}
}
}
} catch (Exception e) {
System.debug('An error occurred while executing the score card: ' + e.getMessage());
System.debug('Stack trace: ' + e.getStackTraceString());
}
}
public static void timeInBusiness (Id oppId) {
try {
// Fetch the latest decision record for the opportunity
Opportunity opp = [SELECT Id, AccountId, WEF_Years_In_Business__c FROM Opportunity WHERE Id = :oppId];
forseva1__Decision__c decision = [SELECT Id, forseva1__Account__c, Consumer_Bankruptcy__c, Commercial_Bankruptcy__c, Post_Score_Action__c, Time_In_Business__c
FROM forseva1__Decision__c WHERE Opportunity__c = :oppId ORDER BY CreatedDate DESC LIMIT 1];
forseva1__PaynetCreditHistoryReport__c paynetReport = [SELECT Id, forseva1__Account__c, Opportunity__c, Decision__c, forseva1__Master_Score__c, MasterScore_Points__c, Years_In_Business__c
FROM forseva1__PaynetCreditHistoryReport__c WHERE forseva1__Account__c = :opp.AccountId ORDER BY createdDate DESC LIMIT 1];
forseva1__EquifaxCommercialCredit__c commercialReport = [SELECT Id, forseva1__Account__c, Opportunity__c, Decision__c, Commercial_Bankruptcy__c, CIDS_Score__c, CIDS_Score_Points__c,
Amount_Financed__c, Lien_Recent_Date__c, Total_Lien_Amount__c, No_of_Liens__c, Judgments__c, Judgment_Recent_Date__c,
Total_Judgment_Amount__c, Commercial_Public_Filings__c, Industry_Requires_Manual_Review__c, forseva1__eqYearsInBusiness__c
FROM forseva1__EquifaxCommercialCredit__c WHERE forseva1__Account__c = :opp.AccountId ORDER BY createdDate DESC LIMIT 1];
Integer numberOfPg = getNumberOfPGs(oppId);
Boolean timeInBusiness = false;
if (opp.WEF_Years_In_Business__c != null) {
if ( opp.WEF_Years_In_Business__c > 0 && opp.WEF_Years_In_Business__c < 2 && numberOfPg > 0) {
timeInBusiness = true;
System.debug('Condition 1 met: WEF Years In Business > 0 and < 2 and Number of PGs > 0');
} else if ( opp.WEF_Years_In_Business__c > 0 && opp.WEF_Years_In_Business__c < 5 && numberOfPg == 0) {
timeInBusiness = true;
System.debug('Condition 2 met: WEF Years In Business > 0 and < 5 and Number of PGs == 0');
}
} else if (opp.WEF_Years_In_Business__c == null && commercialReport.forseva1__eqYearsInBusiness__c != null) {
if (commercialReport.forseva1__eqYearsInBusiness__c > 0 && commercialReport.forseva1__eqYearsInBusiness__c < 2 && numberOfPg > 0) {
timeInBusiness = true;
System.debug('Condition 3 met: Equifax Years In Business > 0 and < 2 and Number of PGs > 0');
} else if (commercialReport.forseva1__eqYearsInBusiness__c > 0 && commercialReport.forseva1__eqYearsInBusiness__c < 5 && numberOfPg == 0) {
timeInBusiness = true;
System.debug('Condition 4 met: Equifax Years In Business > 0 and < 5 and Number of PGs == 0');
}
} else if (opp.WEF_Years_In_Business__c == null && paynetReport.Years_In_Business__c != null) {
if (paynetReport.Years_In_Business__c > 0 && paynetReport.Years_In_Business__c < 2 && numberOfPg > 0) {
timeInBusiness = true;
System.debug('Condition 5 met: Paynet Years In Business > 0 and < 2 and Number of PGs > 0');
} else if (paynetReport.Years_In_Business__c > 0 && paynetReport.Years_In_Business__c < 5 && numberOfPg == 0) {
timeInBusiness = true;
System.debug('Condition 6 met: Paynet Years In Business > 0 and < 5 and Number of PGs == 0');
}
}
// Update the decision record if any of the conditions are met
if (timeInBusiness) {
decision.Time_In_Business__c = true;
decision.Post_Score_Action__c = 'Manual Review';
update decision;
}
} catch (Exception e) {
System.debug('An error occurred while handling decision rules: ' + e.getMessage());
}
}
public static Integer getNumberOfPGs(Id oppId) {
List<Relationship__c> oppContactandPgs = [SELECT Id FROM Relationship__c WHERE Related_Opportunity__c = :oppId AND Relationship_Type__c = 'Personal Guarantee'];
return oppContactandPgs.size();
}
public static void handlePostScoreRules(Id oppId) {
try {
forseva1__Decision__c latestDecision = [SELECT Id, forseva1__Account__c, Consumer_Bankruptcy__c, Commercial_Bankruptcy__c, Prior_Decline__c, Previous_ChargeOff__c,
Low_FICO_Score_Post_Scoring__c, Exceeds_App_Only_Limit__c, Time_In_Business__c, number_of_Inquiries__c, PG_Thin_File__c,
Industry_Requires_Manual_Review__c, Low_CIDS__c, Low_MSV2__c, Commercial_Public_Filings__c, No_Commercial_Data__c,
Currently_Delinquent_With_WEF__c, WEF_Risk_Rated__c, Post_Score_Action__c, WEF_Decision_Status__c
FROM forseva1__Decision__c
WHERE Opportunity__c = :oppId
ORDER BY CreatedDate DESC
LIMIT 1];
Boolean shouldDecline = latestDecision.Consumer_Bankruptcy__c || latestDecision.Commercial_Bankruptcy__c ||
latestDecision.Prior_Decline__c || latestDecision.Previous_ChargeOff__c;
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 ||
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;
if (shouldDecline) {
latestDecision.Post_Score_Action__c = 'Decline';
} else if (shouldManualReview) {
latestDecision.Post_Score_Action__c = 'Manual Review';
} else {
latestDecision.Post_Score_Action__c = 'Pass';
}
latestDecision.WEF_Decision_Status__c = 'Post Scoring Complete';
update latestDecision;
} catch (Exception e) {
System.debug('An error occurred while handling post score rules: ' + e.getMessage());
System.debug('Stack trace: ' + e.getStackTraceString());
}
}
// Method to calculate Secondary Decision for a given Opportunity
public static void calculateSecondaryDecision(Id oppId) {
try {
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
FROM forseva1__Decision__c
WHERE Opportunity__c = :oppId
ORDER BY CreatedDate DESC LIMIT 1
];
if (decision != null) {
// Calculate Secondary Decision based on Pre Score Action, Primary Decision and Post Score Action
String primaryDecision = decision.Primary_Decision__c;
String postScoreAction = decision.Post_Score_Action__c;
String preScoreAction = decision.Pre_Score_Action__c;
String finalDecision = decision.Final_Decision__c;
Integer numberOfPGs = getNumberOfPGs(oppId);
String secondaryDecision;
if (preScoreAction == 'No Rule Triggered' && primaryDecision == 'Approve' && postScoreAction == 'Manual Review') {
secondaryDecision = 'Manual Review';
} else if (preScoreAction == 'No Rule Triggered' && primaryDecision == 'Recommend Approve' && postScoreAction == 'Manual Review') {
secondaryDecision = 'Manual Review';
} else if (preScoreAction == 'No Rule Triggered' && primaryDecision == 'Recommend Approve' && postScoreAction == 'Decline') {
secondaryDecision = 'Decline';
} else if (preScoreAction == 'No Rule Triggered' && primaryDecision == 'Approve' && postScoreAction == 'Decline') {
secondaryDecision = 'Decline';
} else if (preScoreAction == 'No Rule Triggered' && primaryDecision == 'Approve' && postScoreAction == 'Pass') {
secondaryDecision = 'Approve';
} else if (preScoreAction == 'No Rule Triggered' && primaryDecision == 'Recommend Decline' && postScoreAction == 'Pass' /*String.isBlank(postScoreAction)*/) {
secondaryDecision = 'Manual Review';
} else if (preScoreAction == 'Decline' && primaryDecision == 'Not Scored' && postScoreAction == 'Pass') {
secondaryDecision = 'Decline';
} else if (preScoreAction == 'Manual Review' && primaryDecision == 'Not Scored' && postScoreAction == 'Pass') {
secondaryDecision = 'Manual Review';
} else if (preScoreAction == 'Decline' && primaryDecision == 'Approve' && postScoreAction == 'Manual Review') {
secondaryDecision = 'Manual Review';
} else if (preScoreAction == 'Decline' && primaryDecision == 'Recommend Approve' && postScoreAction == 'Manual Review') {
secondaryDecision = 'Manual Review';
} else if (preScoreAction == 'Decline' && primaryDecision == 'Recommend Approve' && postScoreAction == 'Decline') {
secondaryDecision = 'Decline';
} else if (preScoreAction == 'Decline' && primaryDecision == 'Approve' && postScoreAction == 'Decline') {
secondaryDecision = 'Decline';
} else if (preScoreAction == 'Decline' && primaryDecision == 'Approve' && postScoreAction == 'Pass') {
secondaryDecision = 'Approve';
} else if (preScoreAction == 'Decline' && primaryDecision == 'Recommend Decline' && postScoreAction == 'Pass') {
secondaryDecision = 'Manual Review';
} else if (preScoreAction == 'Manual Review' && primaryDecision == 'Approve' && postScoreAction == 'Manual Review') {
secondaryDecision = 'Manual Review';
} else if (preScoreAction == 'Manual Review' && primaryDecision == 'Recommend Approve' && postScoreAction == 'Manual Review') {
secondaryDecision = 'Manual Review';
} else if (preScoreAction == 'Manual Review' && primaryDecision == 'Recommend Approve' && postScoreAction == 'Decline') {
secondaryDecision = 'Decline';
} else if (preScoreAction == 'Manual Review' && primaryDecision == 'Approve' && postScoreAction == 'Decline') {
secondaryDecision = 'Decline';
} else if (preScoreAction == 'Manual Review' && primaryDecision == 'Approve' && postScoreAction == 'Pass') {
secondaryDecision = 'Approve';
} else if (preScoreAction == 'Manual Review' && primaryDecision == 'Recommend Decline' && postScoreAction == 'Pass') {
secondaryDecision = 'Manual Review';
} else if (preScoreAction == 'No Rule Triggered' && primaryDecision == 'Decline' && postScoreAction == 'Pass') {
secondaryDecision = 'Decline';
} else if (preScoreAction == 'No Rule Triggered' && primaryDecision == 'Recommend Approve' && postScoreAction == 'Pass') {
secondaryDecision = 'Manual Review';
} else if (preScoreAction == 'No Rule Triggered' && primaryDecision == 'Recommend Decline' && postScoreAction == 'Manual Review') {
secondaryDecision = 'Manual Review';
} else if (preScoreAction == 'No Rule Triggered' && primaryDecision == 'Recommend Decline' && postScoreAction == 'Decline') {
secondaryDecision = 'Decline';
} else if (preScoreAction == 'Manual Review' && primaryDecision == 'Recommend Approve' && postScoreAction == 'Pass') {
secondaryDecision = 'Manual Review';
} else if (preScoreAction == 'Manual Review' && primaryDecision == 'Recommend Decline' && postScoreAction == 'Manual Review') {
secondaryDecision = 'Manual Review';
} else if (preScoreAction == 'Manual Review' && primaryDecision == 'Recommend Decline' && postScoreAction == 'Decline') {
secondaryDecision = 'Decline';
} else if (preScoreAction == 'Decline' && primaryDecision == 'Recommend Approve' && postScoreAction == 'Pass') {
secondaryDecision = 'Manual Review';
} else if (preScoreAction == 'Decline' && primaryDecision == 'Recommend Decline' && postScoreAction == 'Manual Review') {
secondaryDecision = 'Manual Review';
} else if (preScoreAction == 'Decline' && primaryDecision == 'Recommend Decline' && postScoreAction == 'Decline') {
secondaryDecision = 'Decline';
} else if (preScoreAction == 'Manual Review' && primaryDecision == 'Decline' && postScoreAction == 'Manual Review') {
secondaryDecision = 'Decline';
} else if (preScoreAction == 'Manual Review' && primaryDecision == 'Decline' && postScoreAction == 'Decline') {
secondaryDecision = 'Decline';
} else if (preScoreAction == 'Manual Review' && primaryDecision == 'Decline' && postScoreAction == 'Pass') {
secondaryDecision = 'Decline';
} else if (preScoreAction == 'Decline' && primaryDecision == 'Decline' && postScoreAction == 'Manual Review') {
secondaryDecision = 'Decline';
} else if (preScoreAction == 'Decline' && primaryDecision == 'Decline' && postScoreAction == 'Decline') {
secondaryDecision = 'Decline';
} else if (preScoreAction == 'Decline' && primaryDecision == 'Decline' && postScoreAction == 'Pass') {
secondaryDecision = 'Decline';
} else if (preScoreAction == 'No Rule Triggered' && primaryDecision == 'Decline' && postScoreAction == 'Manual Review') {
secondaryDecision = 'Decline';
} else if (preScoreAction == 'No Rule Triggered' && primaryDecision == 'Decline' && postScoreAction == 'Decline') {
secondaryDecision = 'Decline';
} else {
// Handle cases not explicitly covered
secondaryDecision = '';
}
// Calculate Final Decision based on Secondary Decision
if (secondaryDecision == 'Manual Review') {
finalDecision = 'Made by Analyst';
} else if (secondaryDecision == 'Decline') {
finalDecision = 'Declined';
} else if (secondaryDecision == 'Approve') {
finalDecision = 'Approved';
} else {
// Handle cases not explicitly covered
finalDecision = null;
}
// Update the Decision record with the calculated Secondary Decision
decision.Secondary_Decision__c = secondaryDecision;
decision.Final_Decision__c = finalDecision;
update decision;
// Update Opportunity record
Opportunity opp = new Opportunity(Id = oppId);
opp.Primary_Decision__c = primaryDecision;
opp.Secondary_Decision__c = secondaryDecision;
opp.Final_Decision__c = finalDecision;
opp.WEF_Score_Tier__c = decision.WEF_Score_Tier__c;
opp.WEF_Score_Credit_Rating__c = decision.WEF_Score_Credit_Rating__c;
opp.WEF_Score_Risk_Rating__c = decision.WEF_Score_Risk_Rating__c;
opp.Number_of_PGs__c = numberOfPGs; // update the Opportunity with the number of PGs
update opp;
}
} catch (Exception e) {
System.debug('An error occurred while calculating secondary decision: ' + e.getMessage());
System.debug('Stack trace: ' + e.getStackTraceString());
}
}
}