Thursday, 2 June 2016

How to read Organisation Business Closure in MS CRM Using C#

How to read Organisation Business Closure in MS CRM Using C#


Some time in CRM one needs to read Organisation Business Closure in code  to know whether any organisation level holiday is defined there or not.


For Ex: In scheduler services which needs to only run on  the days business is ON.











Below is the C# code snippet that can be utilise to achieve such functionality:


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  public static Boolean ISTodayOrgHolidayInOrgBusinessClosure(DateTime datetime, IOrganizationService service)
        {

            Guid orgId = ((WhoAmIResponse)service.Execute(new WhoAmIRequest())).OrganizationId;
            Entity org = service.Retrieve("organization", orgId, new Microsoft.Xrm.Sdk.Query.ColumnSet("businessclosurecalendarid"));
            QueryExpression query = new QueryExpression("calendar");
            query.ColumnSet = new ColumnSet(true);
            query.Criteria = new FilterExpression();
            query.Criteria.AddCondition(new ConditionExpression("calendarid", ConditionOperator.Equal, org["businessclosurecalendarid"].ToString()));
            EntityCollection OrgBusinessClosureCalendarCollection = service.RetrieveMultiple(query);
            if (OrgBusinessClosureCalendarCollection.Entities.Count> 0)
            {
                Entity BusinessClosureCalendar = OrgBusinessClosureCalendarCollection.Entities[0];
                if (BusinessClosureCalendar != null)
                {
                  foreach (Entity closure in BusinessClosureCalendar.GetAttributeValue<EntityCollection>("calendarrules").Entities)
                    {
                        DateTime intervalStart = closure.GetAttributeValue<DateTime>("effectiveintervalstart");
                        DateTime intervalEnd = closure.GetAttributeValue<DateTime>("effectiveintervalend");
                        if ((DateTime.Now >= intervalStart) && (datetime <= intervalEnd))
                        {
                            return true;   //return is holiday
                        }
                    }
                }
            }
            return false;
        }

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

Hope it would be helpful.

Comments are highly appreciated..!!!

Happy CRMing 


Wednesday, 1 June 2016

How to read Resource Calendar in MS CRM using C#

How to read Resource (System User/ Facility-Equipment ) Calendar in MS CRM using C#

How to check Resource availability in MS CRM using C#


Many times one needs to schedule some tasks/functionalities according to the resource work hours in calendar. 

For Ex: Send some Notification Emails to Resources only in working hours or assigning some activities to resource (User/Facility-Equipment) with-in working hours .In such case we needs to read user's calendar to get the user availability at that time.

Below is the code snippet to get the CRM Resource availability in calendar at current time.


Function Parameters   : System User/ Facility-Equipment Entity
Return Type                 :  Boolean (True if available at current time otherwise false)

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    public static Boolean IsUser_ResourceAvailable(Entity User_Resource)
        {
            Guid currentUserId =null;
            if (User_Resource.LogicalName == "equipment")
            currentUserId = User_Resource.GetAttributeValue<Guid>("equipmentid");  
            else if (User_Resource.LogicalName == "systemuser")
            currentUserId = user.GetAttributeValue<Guid>("systemuserid");  

            QueryScheduleRequest scheduleRequest = new QueryScheduleRequest();
            scheduleRequest.ResourceId = currentUserId;
            scheduleRequest.Start = Convert.ToDateTime(DateTime.Now);
            scheduleRequest.End = Convert.ToDateTime(DateTime.Now);
            scheduleRequest.TimeCodes = new TimeCode[] { TimeCode.Available };
            QueryScheduleResponse scheduleResponse = (QueryScheduleResponse)service.Execute(scheduleRequest);
            if (scheduleResponse.TimeInfos.Length > 0)  // AVAILABLE RESOURCE
            {
                return true; //Return true if available
            }
            return false;
        }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
You can modify the code according to the requirement if you wants to check the availability of Resource at some future time in Calendar.

Hope this would be helpful.

Comments are highly appreciated.

Happy CRMing,,,!

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