Tuesday, 31 May 2016

How to customise the SLA in MS CRM

How to customise the SLA in MS CRM

How to Read Orgnisation Business Closure



Today we are going to learn how to customise your SLA.


Although MS has provided  Enhanced SLA which can full-fill most of the business requirements but when requirements are so complicate that can't be handled using system Enhanced SLA, developing a custom SLA functionality is the only solution.


In this post we'll not discuss anything regarding CRM System SLA because there are many posts out there on the internet for the same and if you are here reading this post, means you want your SLA to work beyond CRM System SLA.

Here i have created a hypothetical scenario on the basis of which your customer might want the SLA to run.


1.

a) As a training scenario, i have considered that for  your customer wants different SLA hours    for cases assigned to different teams which are working in different shifts (here we'll cal,l it SLA window). 


b) Lets suppose there are 20 different teams in an organisation for which different SLA needs to be set up, then such custom SLA solution are suitable.

b) We will take  care of Organisation Business Closure as well in calculating SLA.


2.  I have created a Custom entity named SLA Configurator in my organisation with following fields:

Field Name Data Type Validation  Purpose
Name Text NA A name for SLA record
SLA window Start whole number Range 0-24 Defines SLA start time
 or shift Start time
SLA window End whole number Range 0-24 Defines SLA end time
or shift end time
Team Lookup NA Team for which this SLA
 needs to be implemented
Resolution SLA in hrs whole number Range as required Total No of SLA hrs
for this scenario
Refer to image below:



3. 
a) Now what we need to do is that on creation  of case, needs to get the team for which the case has been created, and fetch the proper SLA configuration records according to the team.

b) We'll write this whole logic in a plugin which will fire on create of Case. I assume that you will be able to do that.

c) Below is the function to which we'll pass SLA Configuration Record and organisation service object as parameters. It'll return you the date to which your Resolve by needs to be set.


Calculation are as follows:
  • A Case is created for Team1
  • SLA Configuration Master have following data for Team1 


Let's say case created on 31 May,2016 01:00PM
Case assigned to Team1 
SLA hrs for Team1 : 24
SLA start window: 10 AM
SLA End Window: 07 PM
Business Closure have holiday on 1st June,2016
Then Resolve by:

31st May,2016         :    06 hrs     (1 PM- 7 PM)
1st June                     :    Holiday in Business Closure
2nd June                   :    09 hrs      (10 AM-07 PM)
3rd June                    :   09 hrs      (10 AM-07 PM)
Total Working hrs :    24 hrs

Resolve By                :   03 June,2016 07:00PM


Below is the code snippet:

 
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


 public static DateTime CalculateSla(Entity SLAConfigurator, IOrganizationService service)
        {

            int workstarttime = 0;
            int workendtime = 24;
            if (SLAConfigurator.Contains("new_slastartwindow") && SLAConfigurator.Contains("new_slaendwindow"))
            {
                int start = SLAConfigurator.GetAttributeValue<int>("new_slastartwindow");
                int end = SLAConfigurator.GetAttributeValue<int>("new_slaendwindow");
                if (end > start)
                {
                    workstarttime = start;
                    workendtime = end;
                }
            
            }

            int SLAInMin = 600;  //Default Value
            if(SLAConfigurator.Contains("new_resolvesla"))
            SLAInMin = SLAConfigurator.GetAttributeValue<int>("new_resolvesla") * 60;

            DateTime tempdate = DateTime.UtcNow.ToLocalTime();
            
            while (SLAInMin > 0)
            {
                if (tempdate.Hour >= workstarttime && tempdate.Hour < workendtime && lookinbusinessclosure(tempdate, service))
                {
                    tempdate = tempdate.AddMinutes(1);
                    SLAInMin--;
                }
                else
                {
                    while (!(tempdate.Hour >= workstarttime && tempdate.Hour < workendtime && lookinbusinessclosure(tempdate, service)))
                    {
                        tempdate = tempdate.AddMinutes(1);
                    }
                }
            }
            
            return tempdate;

        }
#region businessclosure
        private static IEnumerable<Entity> GetBusinessClosureCalendarRules(IOrganizationService service)
        {
            // Get Organization Business Closure Calendar Id
            Guid orgId = ((WhoAmIResponse)service.Execute(new WhoAmIRequest())).OrganizationId;
            var organization = service.Retrieve("organization", orgId, new ColumnSet("businessclosurecalendarid"));

            var query = new QueryExpression("calendar")
            {
                ColumnSet = new ColumnSet(true),
                Criteria = new FilterExpression()
            };

            // Add condition to get Get Calander where CalanderId is equal to Organization's businessclosurecalendarid
            query.Criteria.AddCondition(new ConditionExpression("calendarid", ConditionOperator.Equal, organization["businessclosurecalendarid"].ToString()));

            // Get Calendar
            var businessClosureCalendar = service.RetrieveMultiple(query).Entities[0];

            // Return the Calendar rules
            return businessClosureCalendar != null ? businessClosureCalendar.GetAttributeValue<EntityCollection>("calendarrules").Entities : null;
        }
        public static bool lookinbusinessclosure(DateTime tempdate, IOrganizationService service)
        {
IEnumerable<Entity> businessClosures = null; //Define it static globally 
            if (businessClosures == null)
            { businessClosures = GetBusinessClosureCalendarRules(service); }
            foreach (var closure in businessClosures)
            {
                var startDate = (DateTime)closure["effectiveintervalstart"];
                var endDate = (DateTime)closure["effectiveintervalend"];
                if (tempdate >= startDate && tempdate <= endDate)
                    return false;
            }
            return true;  //true if not a holdiday
        }
        #endregion
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////




4. Here we have taken care of Business closure as well. So this is how you can set up your custom SLA. 

Your requirements might be different and based on that you can customise it as you want.

Comments are highly appreciated..!!!

Happy CRMing 











Thursday, 26 May 2016

Get CRM form Type in MS CRM using javascript

getFormType(): Method is used to get the form context for the record. The following table lists the form types that correspond to the return value.
////////////////////////////////////////////////////////////////////////
Xrm.Page.ui.getFormType();
////////////////////////////////////////////////////////////////////////

Form Type
Value
Undefined
0
Create
1
Update
2
Read Only
3
Disabled
4
Quick Create
5
Bulk Edit
6
Read Optimized
11

Tuesday, 24 May 2016

How to implement enable rule on a ribbon button using ribbon Workbench in MS CRM

Hello Folks,
In this post we are going to learn how to implement enable rule on a system/custom button on ribbon of MS CRM form using ribbon workbench solution.


Here i have created a step by step procedure of implementing enable rule in MS CRM.
The test scenario i have created is as follwos:

1. Entity  : Task
2. Button : Convert to Case
3. Event  : On the value of option set field Priority


The test scenario is such that Covert to case button should be only visible on Task entity when Priority field is set to High otherwise Convert to Case button should be hidden.



I have included following javascript function in a library to check the value of Priority field:


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function enbleconverttocase()
{
var value =Xrm.Page.getAttribute("prioritycode").getValue();
if(value!=null)
{
if(value ==2) //Value 2 = Priority High
return true;
else
return false;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Step 1 :
a) Open the desired solution which contain your entity on which you want to implement enable rule and the library having javascript function similar to the one above.

Note: For fast load and upload/publish of solution, keep solution small i.e. don't add unnecessary components.

In my case solution name is test enable  rule:

b) Select the desired solution and click OK

Step 2: Right click on the desired button and click Customise command.

In my case it's "To Case".

Step 3: 
a) You'll see command as shown in image below.

b) No need to do anything here.

Step 4: Right Click on enable rule and select add new.


Step 5: 
a) A new enable rule will be created below Enable rule.
b) Right click on the new rule created and click add new.


Step 6: Select Custom javascript rule and click add.

Step 7: Now right click on the created enable rule and select Edit enable rule.


Step 8:  

a)Now edit your custom rule as shown below:

  • Default                 :      True
  • Function Name :      enbleconverttocase (write yours)
  • Invert Results    :      False
  • Library                 :      Select library containing your function
  • Parameters         :      NA(leave blank) 
b) Click OK




Step 9: 

a) Now you need to right click on the desired command and select edit enable rule and  select the created rule and move it to the box in the right side.



b) Here we have moved it to the box in the right side.


c) Click OK

Step 10: Now publish your solution. It's done.


Note: In case you  want this show hide of button according to different conditions, you just need to manipulate the js function according to your requirements. Rest steps will be same.

In case of any query, leave a comment.












Monday, 23 May 2016

Entity StateCode and StatusCode in MS CRM

Hello,
Here we have the Statecodes and statuscodes list  of the commonly used entities in MS CRM.


Entity
Status (statecode)
Associated Status Reason (statuscode)
Account (account)
0 Active
1 Active
1 Inactive
2 Inactive
Activity (activitypointer)
0 Open
1 Open
1 Completed
2 Completed
2 Canceled
3 Canceled
3 Scheduled
4 Scheduled
Appointment (appointment)
0 Open
1 Free
2 Tentative
1 Completed
3 Completed
2 Canceled
4 Canceled
3 Scheduled
5 Busy
6 Out of Office
Article (kbarticle)
1 Draft
1 Draft
2 Unapproved
2 Unapproved
3 Published
3 Published
Campaign (campaign)
0 Active
0 Proposed
1 Ready To Launch
2 Launched
3 Completed
4 Canceled
5 Suspended
Campaign Activity (campaignactivity)
0 Open
0 In Progress
1 Proposed
4 Pending
5 System Aborted
6 Completed
1 Closed
2 Closed
2 Canceled
3 Canceled
Campaign Response (campaignresponse)
0 Open
1 Open
1 Closed
2 Closed
2 Canceled
3 Canceled
Case (incident)
0 Active
1 In Progress
2 On Hold
3 Waiting for Details
4 Researching
1 Resolved
5 Problem Solved
2 Canceled
6 Canceled
Case Resolution (incidentresolution, notcustomizable)
0 Open
1 Open
1 Completed
2 Closed
2 Canceled
3 Canceled
Contact (contact)
0 Active
1 Active
1 Inactive
2 Inactive
Contract (contract)
0 Draft
1 Draft
1 Invoiced
2 Invoiced
2 Active
3 Active
3 On Hold
4 On Hold
4 Canceled
5 Canceled
5 Expired
6 Expired
Contract Line (contractdetail)
0 Existing
1 New
1 Renewed
2 Renewed
2 Canceled
3 Canceled
3 Expired
4 Expired
Currency (transactioncurrency)
0 Active
0 Active
1 Inactive
1 Inactive
Discount (discounttype)
0 Active
100001 Active
1 Inactive
100002 Inactive
E-mail (email)
0 Open
1 Draft
8 Failed
1 Completed
2 Completed
3 Sent
4 Received
6 Pending Send
7 Sending
2 Canceled
5 Canceled
Fax (fax)
0 Open
1 Open
1 Completed
2 Completed
3 Sent
4 Received
2 Canceled
5 Canceled
Invoice (invoice)
0 Active
1 New
2 Partially Shipped
4 Billed
5 Booked (applies to services)
6 Installed (applies to services)
1 Closed (deprecated)
3 Canceled (deprecated)
7 Paid in Full (deprecated
2 Paid
100001 Complete
100002 Parial
3 Canceled
100003 Canceled
Lead (lead)
0 Open
1 New
2 Contacted
1 Qualified
3 Qualified
2 Disqualified
4 Lost
5 Cannot Contact
6 No Longer Interested
7 Canceled
Letter (letter)
0 Open
1 Open
2 Draft
1 Completed
3 Received
4 Sent
2 Canceled
5 Canceled
Marketing List (list)
0 Active
0 Active
1 Inactive
1 Inactive
Opportunity (opportunity)
0 Open
1 In Progress
2 On Hold
1 Won
3 Won
2 Lost
4 Canceled
5 Out-Sold
Order (salesorder)
0 Active
1 New
2 Pending
1 Submitted
3 In Progress
2 Canceled
4 No Money
3 Fulfilled
100001 Complete
100002 Partial
4 Invoiced
100003 Invoiced
Phone Call (phonecall)
0 Open
1 Open
1 Completed
2 Made
4 Received
2 Canceled
3 Canceled
Price List (pricelevel)
0 Active
100001 Active
1 Inactive
10002 Inactive
Product (product)
0 Active
1 Active
1 Inactive
2 Inactive
Quote (quote)
0 Draft
1 In Progress
1 Active
2 In Progress
3 Open
2 Won
4 Won
5 Out-Sold
3 Closed
5 Lost
6 Canceled
7 Revised
Service Activity (serviceappointment)
0 Open
1 Requested
2 Tentative
1 Closed
8 Completed
2 Canceled
9 Canceled
10 No Show
3 Scheduled
3 Pending
4 Reserved
6 In Progress
7 Arrived
Task (task)
0 Open
2 Not Started
3 In Progress
4 Waiting on someone else
7 Deferred
1 Completed
5 Completed
2 Canceled
6 Canceled