1public class RedAccountPredictor {
2
3 private static final Integer MAX_CASES_EXPECTED = 2;
4
5 public RedAccountPredictor() { }
6
7 // First method to be called for performing account status prediction.
8 // Get the account IDs related to the passed-in case IDs
9 // and call a predictor method.
10 // Return a map of account ID to account status Boolean.
11 public Map<String, boolean> predictForCases(List<String> caseId) {
12 List<Case> casesMatchingIds =
13 [SELECT Id, Account.Id FROM Case WHERE Id IN :caseId];
14 if (null != casesMatchingIds && casesMatchingIds.size() > 0) {
15 List<String> accountIds = new List<String>();
16 for (Case c : casesMatchingIds) {
17 accountIds.add(c.Account.Id);
18 }
19 return predictForAccounts(accountIds);
20 } else {
21 return new Map<String, boolean>();
22 }
23 }
24
25 // Perform slow, resource intensive calcuation to determine.
26 // If Account is in RED status (think Einsein predictions, etc.)
27 public Map<String, boolean> predictForAccounts(List<String> acctIds) {
28 List<Case> casesForAccounts =
29 [SELECT Id, Account.Id, Status, CaseNumber, Priority,
30 IsEscalated, SLAViolation__c
31 FROM Case
32 WHERE AccountId IN :acctIds AND Status !='Closed'];
33 Map<String, List<Case>> accountsToCases = new Map<String, List<Case>>();
34 for (Case c : casesForAccounts) {
35 if (null == c.Account.Id) continue;
36 if (!accountsToCases.containsKey(c.Account.Id)) {
37 accountsToCases.put(c.Account.Id, new List<Case>());
38 }
39 accountsToCases.get(c.Account.Id).add(c);
40 }
41 Map<String, boolean> results = new Map<String, boolean>();
42 for (String acctId : accountsToCases.keySet()) {
43 results.put(acctId, predict(accountsToCases.get(acctId)));
44 }
45 return results;
46 }
47
48 // Perform the account status prediction.
49 // Return true if account is red; otherwise, return false.
50 private boolean predict(List<Case> casesForAccount) {
51 boolean isEscalated = false;
52 boolean hasSlaViolation = false;
53 boolean hasHighPiority = false;
54 boolean allStatusesResolved = true;
55
56 for (Case openCase : casesForAccount) {
57 isEscalated |= openCase.IsEscalated;
58 hasSlaViolation |= (openCase.SLAViolation__c == 'Yes');
59 hasHighPiority |= openCase.Priority == 'High';
60 allStatusesResolved &= (openCase.Status == 'Closed'
61 || openCase.Status == 'Part Received');
62 }
63 if (allStatusesResolved) {
64 return false;
65 }
66 if (casesForAccount.size() > MAX_CASES_EXPECTED) {
67 return true;
68 } else if (isEscalated || hasSlaViolation) {
69 return true;
70 } else if (hasHighPiority) {
71 return true;
72 }
73 return false;
74 }
75}