Wednesday, January 25, 2017

Take Ownership of Case from Case Details & ListView

Use case

As we know that in Case Management, when a Case is assigned to queue, the queue member will login to the system and try to assign the Case to himself/herself before working on the Case.

Scenario 1

Taking ownership can be done if the user reaches the Case Details page and try to change the owner like this.
case-details-owner
Clicking on Change link, it will open this "Change Case Owner" screen:
case-details-change-owner
And user has to choose his/her name and saves the changes.
We can easily automate this upon introducing a "Take Ownership" button on the Case details page.
case-details-take-ownership
Clicking on the button, system will check if the user part of the queue and if so, assign the case to that user. Otherwise, it will show an alert "You cannot take this case because you are not part of the queue".
If user already had a ownership then system will show the alert "You are already the Case Owner".
Idea behind this automation
From an user point of view, there will be just a single click instead of 3-4 clicks.
From developer point of view, following tested code with save effort of 1-2 hours depending of experience.
Implementation Details
Create a Custom Button, with following characteristics
  • Display Type = "Detail Page Button"
  • Behavior = "Execute Javascript"
  • Content Source = "OnClick Javascript"
  • Use the following source code in the code section
  • Be sure to add the button the page layout.
Source Code
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
{!REQUIRESCRIPT("/soap/ajax/31.0/connection.js")} 
var caseObj = new sforce.SObject("Case"); 
var previousOwner = "{!Case.OwnerId}"; 
var currentOwner = "{!$User.Id}"; 
caseObj.Id = "{!Case.Id}"; 
caseObj.OwnerId = "{!$User.Id}"; 
caseObj.Status = 'Working';

//if previousOwner is queue 
var ownerRec = sforce.connection.query("SELECT owner.type, ownerid, Id from Case WHERE owner.type= 'Queue' AND OwnerId='"+ previousOwner + "' AND Id='" + caseObj.Id + "'"); 
var records1 = ownerRec.getArray('records');
if(records1 !=null && records1.length>0)
{ 
  //currentOwner is part of queue
  var currentOwnerRec = sforce.connection.query("SELECT g.UserOrGroupId From GroupMember g WHERE groupId ='" + previousOwner + "' AND g.UserOrGroupId ='" + currentOwner + "'");
  var records2 = currentOwnerRec.getArray('records');
 
  if(records2 !=null && records2.length>0)
  {
   var result = sforce.connection.update([caseObj]); 
   location.reload();  
  }
  else
  {
   alert("You cannot take this case because you are not part of the queue");
  }
}
else
{
 if(previousOwner == currentOwner) 
 { 
  alert("You are already the Case Owner "); 
 }
 else
 { 
   var result = sforce.connection.update([caseObj]);     
   location.reload();
 }
}


Scenario 2

User want to change the ownership of multiple cases from ListView. In that scenario, out of box "Change Owner" button will behave same as changing the ownership from Case Details (as shown in those pictures).
Idea behind this automation
From an user point of view, there will be just a single click from changing owner instead of 3-4 clicks.
From developer point of view, following tested code with save effort of 2-3 hours depending of experience.
The logic is still be same. User can choose multiple records and click on Take Ownership button in List View. If user is not part of any queues of the chosen records then system will show the alert "You cannot take this case because you are not part of the queue". Otherwise, system will allow user to take ownership at one go.
Implementation Details
Create a Custom Button, with following characteristics
  • Display Type = "List Button"
  • Behavior = "Execute Javascript"
  • Content Source = "OnClick Javascript"
  • Use the following source code in the code section
  • Be sure to add the button in Case Search Layout --> Cases List View.
Source Code
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
{!REQUIRESCRIPT("/soap/ajax/31.0/connection.js")} 
try {
 var caseObj = new sforce.SObject("Case");
 var selectedCases = {!GETRECORDIDS($ObjectType.Case)}; //chosen records from list view checkboxes
 var caseIds = '';
 var previousOwners = '';
 var currentOwner = "{!$User.Id}"; 
 var caseObjsForUpdate = [];
 
 //check at-least one record is selected
 if (selectedCases[0] == null) {
  alert("You must select at least one record");
 } else 
 {
  //collect all the selected caseids in proper format
  for (var i = 0; i < selectedCases.length; i++) {
   caseIds = caseIds + ",'" + selectedCases[i] + "'";
  }
  caseIds = caseIds.substring(1, caseIds.length);
  
  //if previousOwner is queue 
  var ownerRec = sforce.connection.query("SELECT owner.type, OwnerId, Id, Status from Case WHERE owner.type= 'Queue' AND Id IN (" + caseIds + ")"); 
  var caseOwnerRecords = ownerRec.getArray('records');
  if(caseOwnerRecords !=null && caseOwnerRecords.length>0)
  {
   var count =0;
   //collect all the previous queues
   for (var i = 0; i < caseOwnerRecords.length; i++) {
    if(!previousOwners.includes(caseOwnerRecords[i].OwnerId))
    {
     count = count + 1;
     previousOwners = previousOwners + ",'" + caseOwnerRecords[i].OwnerId + "'";     
    }
    
   }
   previousOwners = previousOwners.substring(1, previousOwners.length);
   
   //currentOwner is part of all those queues
   var currentOwnerRec = sforce.connection.query("SELECT g.UserOrGroupId From GroupMember g WHERE groupId IN(" + previousOwners + ") AND g.UserOrGroupId ='" + currentOwner + "'");
   var records2 = currentOwnerRec.getArray('records');
   
   //finally update all the records if count of queues selected and returning rows from query are same
   if(records2 !=null && records2.length == count)
   {
    for (var i = 0; i < caseOwnerRecords.length; i++) {
     caseObj = new sforce.SObject("case");
     caseObj.Id = caseOwnerRecords[i].Id;
     caseObj.OwnerId = "{!$User.Id}"; 
     caseObj.Status = 'In Progress';
     caseObjsForUpdate.push(caseObj);
    }
    
    var result = sforce.connection.update(caseObjsForUpdate);
    
    if ( result[0].getBoolean( "success" ) ) {
     location.reload( true ); // refresh page
      } else {
     var errors = result[0].errors;
     var errorMessages = "";
     for ( var i = 0; i < errors.length; i++ ) {
       errorMessages += errors[i].message + '\n';
     }
     // display all validation errors
     alert( errorMessages ); 
      }    
   }
   else
   {
    alert("You cannot take this case because you are not part of the queue");
   }
  } 
 }
} catch ( ex ) {
  alert( ex ); // display any javascript exception message
}

2 comments:

  1. If the case is a new case and getting created due to email-2-case, we have Omni Channel. Omni Channel will present the case to only those users who are part of the queue. User can then accept the case and owner will change accordingly. May be you can check Omni Channel capabilities.

    ReplyDelete
  2. Yes, Omni Channel is good for dynamic routing. For this Service Cloud license to be purchased. I have just provided simple functionality to accept the case on single click. Thanks for your input.

    ReplyDelete