Wednesday 25 February 2015

Microsoft Dynamics CRM 2015 in General Pre-Sales Presentation

Hi All,
Since I am doing pre-sales activity as well, I created some presentation slides for pre-sales material that I want to share to you, just in case in the future you need this for your presentation or reference, or I lose this documentation so that I could recover this later.

This is all about Microsoft Dynamics CRM 2015 Pre-sales for general in various industries presentation.

I have uploaded to the Slideshare, please feel free to access, which you can also view my recent works there.





If you need the copy just email me, I would be happy to share the file to you.

If you need any assistance in creating pre-sales material in specific modules or industries, , e-book, training resources/materials, marketing material, product advice, catalog, productize your product/solution, product review to be posted in my blog (official Microsoft Dynamics community blog as well), or anything about Microsoft Dynamics CRM, please feel free to contact me.

Thank you and good night from Indonesia!

Thursday 5 February 2015

Control Ribbon Visibility (Show/Hide) based on Specific Form in CRM 2011/2013/2015 Multiple Entity Forms

CRM Supports Multiple Forms and we can put ribbon (button in CRM) or Command in the CRM Forms as well. What if we have requirement to show or hide the ribbon based on Form. In this post I will give example of the code to control ribbon visibility.

Scenario

I have scenario that I have 3 Forms of Account Form.

image

Now, I want to place a ribbon applicable for Account Form, but only for Partner Form. So when the users are in different form, other than Partner Form, this ribbon should not be available.

The Code


The code is in JavaScript code and it’s pretty simple.

function controlFormRibbon() {
   var formLabel;
   var currForm = Xrm.Page.ui.formSelector.getCurrentItem();
   formLabel = currForm.getLabel();

   //this code to show the ribbon if only the current opened form is Partner, 
   //otherwise remain disable/hidden
   if (formLabel == "Partner") //change this with your own specific form name
   {
      return true;
   }
   else
   {
      return false; 
   }
   //you can also apply the different/reverse rule here, for example you want to hide if form is Partner
}

Ribbon Workbench Favor

Here, I need a favor from my favorite tool.

I have solution with the ribbon image and script now I just want to place a ribbon and set the JavaScript there.

I create a Button in the Form section, give the Command, rename the Id, assign the Images to the Ribbon.

image

Then I rename the Label to ‘Partner Only’ that you can see in the final result showing this label Text.

Then Here is the Command.

image

I apply a Rule here to EnableRules.

This is my rule:

image

image

*You can change the Default to True/False to set the default visibility, but in my script I have set other than Partner, will hide this ribbon button, so I don’t bother to change to False.

The key here is just referring the correct FunctionName under the correct Library (your Web Resource where you kept the script) and set parameters if any.

Note: The display rules doesn’t support CustomRule, so just apply it to the EnableRule to show/hide.

Result

I can navigate using Form Selector

image

*My Partner Form

image

*My Account & Information Forms

image












As you can see the ribbon is there if I choose the form to Partner, otherwise it’s hidden.

Hope this can help you!

Thank you.

Wednesday 4 February 2015

SLA Fields: ‘First Response By’ and ‘Resolve By’ Behind The Scenes

Ever wondering where the ‘First Response By’ and ‘Resolve By’ fields value in the Applicable SLA came from?

image

In this post will explain about Applicable SLA fields in Case Form in Microsoft Dynamics CRM 2013/2015. I will use the Standard SLA and the Resolve By by CreatedOn as the example here.

I am not going to explain how to setup a SLA in your Organization (including initialization, SLA Detail, SLA Actions, etc.), I am focusing in the Resolve By field value because there are many articles already explained about SLA in general, but not about the fields value in particular topic.

To understand the SLA and how to setup, please see this Microsoft document.

http://www.microsoft.com/en-us/dynamics/crm-customer-center/define-service-level-agreements-slas.aspx

Basically the Resolve By field will be automatically filled by the system to the specific datetime that is the result from the combination of SLA Item Failure, Business Hours (Customer Service Calendar Schedule), and Holiday Schedule.

image

Now, let’s discuss it one by one.

SLA Item Failure

What is the effect of this SLA Item Failure setting?
To go to this item, you need to to Settings –> Service Management –> Service Terms –> Service Level Agreement.

Create New SLA and then Add the New SLA Detail and go to the ‘SLA Item Failure section’ here

image

Here I set 10 Days in the ‘Failure after’ setting.

I set the Applicable From by Created On field and I have no setting in the Business Hours.

image

Do not forget to Activate and Set it as Default.

So here is the result

image
If you did not set the Business Hours setting for your Customer Service Calendar then CRM will treat your support working day is full-day 24x7 hours without any break, so that you set 10 days, it does require exactly 10 days!
I set 10 Days in SLA Item Failure, I create the Case on today 4 February 2015, I must resolve the case by 24 February 2015 or exactly 10 days after the creation date of my Case. Wonderful right?!
Here is the formula.
Resolve By =  (failure tolerance days) + CreatedOn

Business Hours (Customer Service Schedule/Calendar)

Now the second thing that can affect the ‘resolve by’ calculation is the Business Hours (Customer Service Schedule).

You can set the Business Hour in your SLA to my company Customer Service Calendar, here is my example:

I don’t want to open 24x7 Service Center because my company is not a service-oriented company, for instance.
Sorry, Mr. Customer we are closed on Saturday and Sunday, so please call us or visit us only on weekdays at 8.00 AM to 5.00 PM, and remember our lunch break 1 hour!
So, I have this setting:

image

Now, my customer service has the schedule in the calendar setting, so no more 24x7 support setting here, I set the first one (the same each day) with only 5 days for working day, 2 days as holiday in weekend (Saturday and Sunday) to give my CS little bit relaxation and family time! Yeahh!…

Which having 9 hours for each day with 1 hour lunch break, so the total working day hours are 8 hours.

image

Note: You can also set various work days, for example: half day working hours in Saturday (if working) or 2 hours break in Friday for prayers, and so on.

So how much does this Customer Service Schedule affect your Cases?

Result:

image

You may wonder why it is 18 March 2015 5.00 PM?

The answer here is the calculation result of the combination: Failure setting + Business Hours
In the ‘Failure 'after’ setting, you set 10 days, need to understand that this 10 days does not mean exactly the 10 days of your real life calendar time, it does mean 10 working days.

Have you ever called maybe Bank Call Center then you make a request, data changes, for instance, or make new credit card, then the CS Agent will say, okay, Sir, it will be done in 3 days, then he will emphasize, 3 working days. So, if you requested on Friday, do not expect you will get it done on next Monday, because they are off in weekend (Sat-Sun).

The concept in CRM is similar to that analogy, but here, you are needed to be very careful on this way because the 10 days here in CRM SLA here it does not mean 10 days in real life, you need to divide by how many hours you are really working in the Business Hours Customer Service schedule.
I set 8 working hours on Monday until Friday, I set the Failure tolerance to 10 days, so it does mean 30 days.
Here is the formula.
Resolve By = (24 hours / working hours * failure tolerance days) + CreatedOn
So (24/8 * 10) = 30 days, I need to add to CreatedOn (4 February 2015 5.00 PM), excluding the weekend, so I will get 18 March 2015 5.00 PM

imageimage

You can count the yellow-highlighted date in the calendar (from 5 February 2015) and will get 30 days.

In reality we will give 30 days tolerance because it counts of every single minute you spend as the time unit, not by day.

Therefore, we need to be careful in making decision of this failure setting.

Note: This also works for non-exact number of hours, in this example I use exact number (8 hours), just in case you have 8.5 working hours, the formula will be still same 24/8.5 hours, so you will get the number of days + hours + minutes maybe to get your ‘resolve by’ date value.

Do not be confuse here, you set 10 days but you get 30 days.
If you want to have full day, just set 24 hours working day in 7 days…You will get the same result from the first example (SLA with Failure Setting only) because CRM will give 24x7 hours.
If you want to exclude the Weekend only like Bank Call Center analogy, do not set the 8 hours, instead, set 24 hours (because considering you are not caring pretty much about minutes), it will give 10 days in reality, excluding Weekend.
Or…instead set to 24 hours, reducing your Failure time to 3,33 days (10/(24/8))!!
Careful..Careful.. Be careful is the key.
For some companies, the resolution might not important in every single minute, but in some companies with high-level service-oriented type, every single hour, minute, even second, and millisecond are very important, so that they really define the failure tolerance in minute, in fact they cannot rely on to the Day as the lowest unit, so this setting is very important for them to get real ‘Resolved By’!

Holiday Schedule/Calendar

The third thing that will affect the value of ‘Resolve By’ field is the Holiday Schedule.
How much does it will affect the date?

Regarding to the previous example, now I will use that as the base reference here, I just want to add a small piece of setting, I plan to give 2 days as holiday between the tolerance days, that is between 4 February and 18 March.

I set Holiday Schedule two days on 19-20 February 2015

image

Then I modify the Customer Service Schedule to Observe this Holiday Schedule.

image

See the result here:

image

As we can see the result here is 20 March 2015, before we set the holiday we got 18 March 2015, then we set 2 days working-off, so it will delay the ‘resolve by’ postponing it to next after 2 days, that is 20 March 2015 (2 days after initial 18 March 2015).
I set 8 working hours on Monday until Friday, I set the Failure tolerance to 10 days, I have 2 days working day between ‘createdon’ and initial ‘resolve by’ date (18 March 2015), so it does mean 30 days + 2 days = 32 days.
Here is the formula.
Resolve By = (24 hours / working hours * failure tolerance days) + (Number of Holiday in between the two dates) + CreatedOn
Finally, do not be confused if you expect to finish 3 days then you set 3 days and 8 working hours, your field will not be filled by 3 days after the created on, it will give you 9 days (remember, 24/3 * 3 = 9) Smile

Hope this can be e-document for us, in case I also encounter this SLA issue or prospect/client asking about this at least I can understand and refer to this document back, in the future.

Because I found this is interesting topic that having less documentation + may cause confusion in setting it on) and because our memory is not forever. Also to my friend, Ricardo here who is becoming my friend in the community.

Note: This will also works for the ‘First Response By’ field, no worry here.
Just in case you cannot get those fields auto-filled, make sure you have activate it and set it as default.

image

Thank you.

Tuesday 3 February 2015

Capturing and Storing Case Resolution Fields in The Case Form

Recently I had this question from the Community fellows and I think there are many people also need this requirement since you know this is very difficult to display the fields from the Case Resolution. They are stored in the different entity and included as Activity entity which is considered as Child record to the Case so that you cannot show the fields value as the displayed column through View or Advanced Find.

Let’s get started..

Objective

Our objective here is to capture the information that User Inputted through this system form and store the values to the Case entity.

image

Create Fields in the Case Entity

Now, I create the fields that I need in the Case entity

- Resolution
- Total Time
- Billable Time
- Remarks

*Resolution Type is already defined in the Status Reason of the Case, in case you want to create new field, it is also possible to do!

What If I Want To Have Another Status Code?

You can go to Status Reason field of the Case entity and Add New Item

*Status Reason Field

image

I create a new item: ‘Enhancement Requested’

Then I put those fields in the Form and make them as read-only

image

Problem

The challenge here is this entity is a special Entity that seems to be ‘hidden’ in CRM and included as Activity in CRM, thus, considered as Child record of the Case, we should take note on that list to make the proper solution.

Solution

Of course as the Consultant we need to give the best solution and the best solution that comes up to the CRM professional is thinking the Out of the box first or the most effortless customization if inbuilt function is not there, Should I create Workflow or Plugin?

#1 Can I use Workflow for Case Resolution?

The answer is ‘No’ because the Case Resolution is one of the unsupported entity in Workflow.

#2 Can I use the Workflow and use The Case as The Entity?

Okay if you are using the OOB Workflow, the answer is ‘No’ as the solution here, it is not possible because as mentioned before Case Resolution is a child entity, as we know the OOB Workflow cannot get the related record from the 1:N Relationship so you cannot get the Case Resolution entity record through parent Case using Out of The Box CRM Workflow

#3 Can I use Plugin?

Yes, of course, but what kind of Plugin?

#4 What about Plugin on The Case Resolution Entity?

Surprisingly it works! I tried it.

I thought it would not work if I register to the Case Resolution entity on Post-Create Event because at the time Case Resolution Entity is created by the time the Case has been Resolved (status that makes the Case Read-Only).

After some research I see that in the Case the status is still 1 or In Progress

image

image

This is possible because CRM has another message Close for Case Entity.

#5 What is the difficulty?

The difficulty here is to retrieve the Total Time here because you need to sum up the times spent in each activity related to the Case.

image

Another difficulty here is to get the Status Code to become the Resolution Type because mentioned before CRM only gives status = 1 (In Progress) not yet Resolved, so that you might need another plugin in the Case entity to capture that, but I recommend you to use the Status Reason field in the Case entity. I you really need this field you can contact me for further development.

#6 So, What Is The Plugin Code?

Here is the Plugin Code

public class CaseResolution : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            #region must to have

            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

            IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));

            // Create service with context of current user
            IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

            //create tracing service
            ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            #endregion

            #region Variable

            Entity targetCase = new Entity("incident");
            string strResolution = string.Empty;
            int intTotalTime = -1;
            int intTotalBillableTime = -1;
            string strRemarks = string.Empty;

            #endregion

            if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
            {

                //create entity context
                Entity entity = (Entity)context.InputParameters["Target"];

                if (entity.LogicalName != "incidentresolution")
                    return;

                try
                {
                    if (entity.Contains("incidentid"))
                    {
                        //get the related Case
                        targetCase.Id = ((EntityReference)entity["incidentid"]).Id;
                        
                        //capture the Case Resolution Fields                      
                        strResolution = entity.Contains("subject") ? entity["subject"].ToString() : string.Empty;
                        intTotalBillableTime = entity.Contains("timespent") ? (Int32)entity["timespent"] : 0;   
                        strRemarks = entity.Contains("description") ? 
                            (entity["description"] != null ? entity["description"].ToString() : string.Empty) : 
                            string.Empty;

                        //get the total time from Activities
                        intTotalTime = GetTotalTime(service, targetCase.Id);
                        
                        //update Case with the fields
                        targetCase["new_resolution"] = strResolution;
                        targetCase["new_totalbillabletime"] = intTotalBillableTime;
                        targetCase["new_totaltime"] = intTotalTime;
                        targetCase["new_remark"] = strRemarks;
                        service.Update(targetCase);
                    }
                }
                catch (Exception ex)
                {
                    throw new InvalidPluginExecutionException(ex.Message);
                }

            }
        }

        private int GetTotalTime(IOrganizationService service, Guid guidRelatedCaseId)
        {
            //count the Activity Actual Duration Minutes for this Case
            //need to sum time spent of each activity (cannot directly using the actualtdurationminutes) 

            int intSumTotalTime = 0;

            //Retrieve all related Activities by Case
            QueryExpression query = new QueryExpression("activitypointer");
            query.ColumnSet.AddColumns("actualdurationminutes");

            query.Criteria = new FilterExpression();
            query.Criteria.AddCondition("regardingobjectid", ConditionOperator.Equal, guidRelatedCaseId);

            // Execute the Query 
            EntityCollection results = service.RetrieveMultiple(query);

            foreach (Entity entity in results.Entities)
            {
                int intActivityTime = 0;
                intActivityTime = entity.Contains("actualdurationminutes") ? (Int32)entity["actualdurationminutes"] : 0;
                intSumTotalTime = intSumTotalTime + intActivityTime;
            }

            return intSumTotalTime;
        }
    }

#5 How to Register The Plugin


Here is the Plugin Registration Tool Setting for this Step

image

Result


And Here is your Result

I resolve the Case with following information

image

And here is the captured Information in my Case entity form.

image

Summary

Here is the summary

1. You cannot capture using the Out of the box Workflow because the entity is not supported

2. You can achieve it by creating a plugin updating the Case fields and register the plugin on the Post-Create of the Incident Resolution entity

3. Just be careful, in CRM a case can be closed and can be-reactivated again so every time CRM close the case it will keep updating the field and keep the latest position/value and will create another activity-close case to the related Case

image

This is how CRM treats the Case Resolution as the Case Activities.

4. CRM stores the total billable time in the 'Time Spent' field, while the Total Time for all activities are not stored in any field, you need to manually count the SUM from each related Case Activities, then store it somewhere else if you want to display it.

5. Once you save those fields in the Case, you will able to see the fields in the Case entity, either through Form, View, or Report of Case entity, while if you are not, you can still show but you need to query agains the Activity entity with type = Case Resolution.

Hope this helps you!

Thank you.