Dynamics 365





Sunday, November 17, 2019

Dynamics 365 make invoice active and Paid using C#.net code or plugin




Dynamics 365 make invoice active and Paid using C#.net code or plugin


                foreach (var item in ERPInvoices.Entities)
                {
// Set active
                    SetStateRequest setStateRequest = new SetStateRequest()
                    {
                        EntityMoniker = new EntityReference
                        {
                            Id = new Guid(item["invoiceid"].ToString()),
                            LogicalName = "invoice",
                        },
                        State = new OptionSetValue(0),

                        Status = new OptionSetValue(1)

                    };
                    _CrmService.Execute(setStateRequest);

                  // Update the field

                    Entity invoiceToUpdate = new Entity("invoice");
                    invoiceToUpdate.Id = item.Id;
                    if (issendfullyerp)
                    {
                        invoiceToUpdate.Attributes["has_issendfullyerp"] = true;
                    }
                    if (issendpartiallyerp)
                    {
                        invoiceToUpdate.Attributes["has_issendpartiallyerp"] = true;
                    }
                    _CrmService.Update(invoiceToUpdate);
//set abck paid - to old status
                    SetStateRequest request = new SetStateRequest()
                    {
                        EntityMoniker = new EntityReference
                        {
                            Id = new Guid(item["invoiceid"].ToString()),
                            LogicalName = "invoice",
                        },
                        State = new OptionSetValue(2),
                        Status = new OptionSetValue(100001),
                    };

                    _CrmService.Execute(request);

}

Tuesday, October 1, 2019

Field Service WoodFord Resco Mobile App On save validation - Make mandatory

Field Service WoodFord Resco Mobile App On save validation - Make mandatory

Dnamics 365 field services WoordFord design - Make a field mandatory on save event.

make ATE Number mandatory on save event eventhough user not changed any data.

Normally if you open existing record on mobile app where one field should be madatory before proceed with save where same field is not mandatory or business required on CRM.

in this case we can follow below steps to make any field mandatory on save..

OnLoad Event
Open On Load event of form and keep condition you required - then update any field (modified on) so on save event will make sure field mandatory.



OnSave Event

to check the condition we should use Entity.FieldName  

Use error message insted of form.field name.error message




Monday, May 28, 2018

MS CRM get break duration time from business calendar


innerCalendar entitycollection  will have 2 entities
1 is business hours 
2nd one is break 

//with entity[1].attributes["duration"] will get break duration.


//temp code
                Entity BCalendar = GetCalendar(calendarGuid);

                EntityCollection calendarRules = BCalendar.GetAttributeValue<EntityCollection>(CalendarColumnNames.CalendarRules);
                var firstRulePattern = calendarRules[0].GetAttributeValue<string>(CalendarColumnNames.Pattern);

                Guid innerCalendarId = calendarRules[0].GetAttributeValue<EntityReference>(CalendarColumnNames.InnerCalendarId).Id;
                Entity innerCalendar = service.Retrieve(CalendarColumnNames.EntityName, innerCalendarId, new ColumnSet(true));
                EntityCollection innnerCalendarRule = innerCalendar.GetAttributeValue<EntityCollection>(CalendarColumnNames.CalendarRules);
                var duration = 0;
                var offset = 0;
                var BreakDuration = 0;
                BreakDuration = innerCalendar.GetAttributeValue<EntityCollection>(CalendarColumnNames.CalendarRules).Entities[1].GetAttributeValue<int>(CalendarColumnNames.Duration);
                duration = innerCalendar.GetAttributeValue<EntityCollection>(CalendarColumnNames.CalendarRules).Entities[0].GetAttributeValue<int>(CalendarColumnNames.Duration);
                offset = innerCalendar.GetAttributeValue<EntityCollection>(CalendarColumnNames.CalendarRules).Entities[0].GetAttributeValue<int>(CalendarColumnNames.Offset);
                // temp code

Calculate business hours using Business calendar - complex methods


using System;
using Microsoft.Xrm.Sdk;
using Vrp.Crm.Base.Handler;
using Vrp.Crm.Base.Tracing;
using Vrp.Crm.Base.Logging;
using dyn.Common.Handler;
using dyn.CaseManagement.Common;
using dyn.Base.Scheduling;
using dyn.CaseManagement.Business.Objects;
using PluginStage = dyn.Base.Handler.PluginStage;
using Microsoft.Crm.Sdk.Messages;
using System.Collections.Generic;
using Microsoft.Xrm.Sdk.Query;

namespace dyn.CaseManagement
{
    public class IncidentResolutionsProcessorPluginExecutor : PluginExecutor
    {
        public IncidentResolutionsProcessorPluginExecutor(IServiceProvider serviceProvider, IPluginExecutionContext pluginExecutionContext, ITracingService crmTracing, string userId, IOrganizationService service, Tracer tracer)
            : base(serviceProvider, pluginExecutionContext, crmTracing, userId, service, tracer)
        {
        }

        public override void Execute()
        {
            try
            {
                var context = pluginExecutionContext;
                tracer.AddInfo(string.Format("{0} - {1}", CaseManagementConstants.Module, context.MessageName));

                Entity targetEntity = PluginHelper.GetEntityFromContext(context);

                if (context.Stage == PluginStage.PreOperation)
                {
                    if (targetEntity == null)
                    {
                        return;
                    }

                    CaseHandler caseHandler = new CaseHandler(service, userId, CaseManagementConstants.Module);

                    Guid incidentId = Guid.Empty;

                    if (targetEntity.Attributes.Contains(IncidentResolutionEntityAttributeNames.RegardingIncidentIdFieldName))
                    {
                        EntityReference entityReference = targetEntity.Attributes[IncidentResolutionEntityAttributeNames.RegardingIncidentIdFieldName] as EntityReference;
                        if (entityReference != null && entityReference.LogicalName == IncidentEntityAttributeNames.EntityName)
                        {
                            incidentId = entityReference.Id;
                        }
                    }

                    if (incidentId != Guid.Empty)
                    {
                        Entity caseEntity = new Entity
                        {
                            Id = incidentId,
                            LogicalName = IncidentEntityAttributeNames.EntityName
                        };

                        if (caseEntity != null)
                        {
                            //get Case Configuration Case resolution Duration 24x7 or business hours

                            bool isDurationTypeBusinessHours =  GetCaseProcessConfigResolutionDuration(caseHandler, caseEntity.Id.ToString());
                         
                         
                            //Validate
                            if (ValidateCaseResolution(caseHandler, incidentId.ToString()))
                            {
                                string subject = String.Empty;
                                string description = String.Empty;

                                //Get resolution Subject
                                if (
                                    targetEntity.Attributes.Contains(
                                        IncidentResolutionEntityAttributeNames.SubjectFieldName))
                                {
                                    subject =
                                        targetEntity.Attributes[IncidentResolutionEntityAttributeNames.SubjectFieldName]
                                            .ToString();
                                }

                                //Get resolution Description
                                if (targetEntity.Attributes.Contains(
                                    IncidentResolutionEntityAttributeNames.DescriptionFieldName)
                                    &&
                                    targetEntity.Attributes[IncidentResolutionEntityAttributeNames.DescriptionFieldName] !=
                                    null)
                                {
                                    description =
                                        targetEntity.Attributes[
                                            IncidentResolutionEntityAttributeNames.DescriptionFieldName].ToString();
                                }

                                //Set Resolution Subject on Case Entity
                                if (
                                    caseEntity.Attributes.Contains(
                                        IncidentEntityAttributeNames.ResolutionSubjectFieldName))
                                {
                                    caseEntity.Attributes.Remove(IncidentEntityAttributeNames.ResolutionSubjectFieldName);
                                }

                                //Subject is mandatory field so no need to check for empty or null
                                caseEntity.Attributes.Add(IncidentEntityAttributeNames.ResolutionSubjectFieldName,
                                    subject);

                                //Set Resolution description on Case Entity
                                if (
                                    caseEntity.Attributes.Contains(
                                        IncidentEntityAttributeNames.ResolutionDescriptionFieldName))
                                {
                                    caseEntity.Attributes.Remove(
                                        IncidentEntityAttributeNames.ResolutionDescriptionFieldName);
                                }

                                caseEntity.Attributes.Add(IncidentEntityAttributeNames.ResolutionDescriptionFieldName,
                                    description);

                                if (
                                    caseEntity.Attributes.Contains(
                                        IncidentEntityAttributeNames.ActualResolutionTimeFieldName))
                                {
                                    caseEntity.Attributes.Remove(
                                        IncidentEntityAttributeNames.ActualResolutionTimeFieldName);
                                }

                                caseEntity.Attributes.Add(IncidentEntityAttributeNames.ActualResolutionTimeFieldName,
                                    DateTime.Now);
                                //var resolutionDuration =CrmTypesHelper.GetIntValue(targetEntity, IncidentResolutionEntityAttributeNames.TimeSpentFieldName);
                                //caseEntity.Attributes.Add(IncidentEntityAttributeNames.ResolutionDurationFieldName, resolutionDuration + " Minutes");
                                TimeSpan ts;
                                if (isDurationTypeBusinessHours)
                                {
                                    ts = CalculateCaseresolutionDuration(caseHandler, incidentId.ToString());

                                }
                                else
                                {
                                    ts = DateTime.UtcNow - GetCaseCreatedOnDateTime(caseHandler, incidentId.ToString());
                                }
                                var resolutionDuration = string.Format("{0:%d} days, {0:%h} hours, {0:%m} minutes, {0:%s} seconds", ts);

                                caseEntity.Attributes.Add(IncidentEntityAttributeNames.ResolutionDurationFieldName, resolutionDuration);

                                caseHandler.Update(caseEntity);
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                ExceptionHelper.LogException(e, userId, CaseManagementConstants.Module, "Error occured", service);
                tracer.AddError("Error occured in Case Management, Change Category Task Generator Plugin" + e.Message);
                throw;
            }
        }

        public DateTime GetCaseCreatedOnDateTime(CaseHandler caseHandler, string incidentId)
        {
            var caseEntity = caseHandler.GetCaseById(incidentId, new[]
            {
                IncidentEntityAttributeNames.CreatedOnFieldName
            });

            var result = CrmTypesHelper.GetDateTimeValue(caseEntity, IncidentEntityAttributeNames.CreatedOnFieldName);

            return result;
        }
        public bool GetCaseProcessConfigResolutionDuration(CaseHandler caseHandler, string incidentId)
        {
            TimeManager TimeManager = new TimeManager(service, tracer, userId, CaseManagementConstants.Module);
            bool result = false;
            try
            {
                var caseEntity = caseHandler.GetCaseById(incidentId, new[]
                {
                IncidentEntityAttributeNames.ProcessConfigurationIdFieldName,IncidentEntityAttributeNames.OwnerIdFieldName,IncidentEntityAttributeNames.Entitlement
            });

                var ConfigID = CrmTypesHelper.GetEntityReferenceId(caseEntity, IncidentEntityAttributeNames.ProcessConfigurationIdFieldName);
               
               
                ProcessTaskConfigurationHandler caseProcessHandler = new ProcessTaskConfigurationHandler(service, userId, CaseManagementConstants.Module);

                Entity caseProcessConfig = caseProcessHandler.GetCaseProcessConfigurationById(ConfigID);
                if (caseProcessConfig.Attributes.Contains(CaseProcessConfigurationEntityAttributeNames.CaseResolutionDuration))
                {
                    if (((OptionSetValue)caseProcessConfig[CaseProcessConfigurationEntityAttributeNames.CaseResolutionDuration]).Value == 2)
                    {
                        result = true; // Business Hours
                    }
                }
               
            }
            catch (Exception e)
            {
                ExceptionHelper.LogException(e, userId, CaseManagementConstants.Module, "Error occured", service);
                tracer.AddError("Error occured in Case Management, GetCaseProcessConfigResolutionDuration:" + e.Message);
                throw;
            }
            return result;
        }
        public TimeSpan CalculateCaseresolutionDuration(CaseHandler caseHandler, string incidentId)
        {
            TimeSpan BusinessHoursDuration;
            var workingDays = new List<DayOfWeek>();
            try
            {
                TimeManager TimeManager = new TimeManager(service, tracer, userId, CaseManagementConstants.Module);
                var caseEntity = caseHandler.GetCaseById(incidentId, new[]
                {
                IncidentEntityAttributeNames.ProcessConfigurationIdFieldName,IncidentEntityAttributeNames.OwnerIdFieldName,IncidentEntityAttributeNames.Entitlement
            });

                var ConfigID = CrmTypesHelper.GetEntityReferenceId(caseEntity, IncidentEntityAttributeNames.ProcessConfigurationIdFieldName);
                var OwnerID = CrmTypesHelper.GetEntityReferenceId(caseEntity, IncidentEntityAttributeNames.OwnerIdFieldName);
                Guid OwnerGuid = new Guid(OwnerID);
                Guid ConfigGUID = new Guid(ConfigID);

                SLAConfigObject slaConfig = new SLAConfigObject(service, userId, CaseManagementConstants.Module, tracer);

                SLAObject sla = slaConfig.GetCaseProcessConfigurationSLAbyConfigId(ConfigGUID, Guid.Empty, OwnerGuid);

                var entitlementGuid = CrmTypesHelper.GetEntityReferenceId(caseEntity,
                       IncidentEntityAttributeNames.Entitlement);

                Guid calendarGuid = TimeManager.GetCalendarFromSLA(sla.SLAId);

                Entity BCalendar = GetCalendar(calendarGuid);

                EntityCollection calendarRules = BCalendar.GetAttributeValue<EntityCollection>(CalendarColumnNames.CalendarRules);
                var firstRulePattern = calendarRules[0].GetAttributeValue<string>(CalendarColumnNames.Pattern);

                Guid innerCalendarId = calendarRules[0].GetAttributeValue<EntityReference>(CalendarColumnNames.InnerCalendarId).Id;
                Entity innerCalendar = service.Retrieve(CalendarColumnNames.EntityName, innerCalendarId, new ColumnSet(true));
                EntityCollection innnerCalendarRule = innerCalendar.GetAttributeValue<EntityCollection>(CalendarColumnNames.CalendarRules);
                var duration = 0;
                var offset = 0;

                duration = innerCalendar.GetAttributeValue<EntityCollection>(CalendarColumnNames.CalendarRules).Entities[0].GetAttributeValue<int>(CalendarColumnNames.Duration);
                offset = innerCalendar.GetAttributeValue<EntityCollection>(CalendarColumnNames.CalendarRules).Entities[0].GetAttributeValue<int>(CalendarColumnNames.Offset);

                DateTime CaseCreateTime = GetCaseCreatedOnDateTime(caseHandler, incidentId.ToString());
                var ResolutionDate = DateTime.UtcNow;
                List<TimeSlot> timeSlots = TimeManager.GetAvailableTimeSlotsForCalendar(calendarGuid, CaseCreateTime, DateTime.UtcNow);
                double totalSpanSeconds = 0;
                foreach (var slot in timeSlots)
                {
                    double slotSpan = 0;
                    if (CaseCreateTime > slot.End)
                        slotSpan = 0;
                    else if (CaseCreateTime > slot.Start && ResolutionDate < slot.End)
                        slotSpan = (ResolutionDate - CaseCreateTime).TotalSeconds;
                    else if (CaseCreateTime > slot.Start && CaseCreateTime < slot.End && ResolutionDate > slot.End)
                        slotSpan = (slot.End - CaseCreateTime).TotalSeconds;
                    else if (ResolutionDate > slot.Start && ResolutionDate < slot.End)
                        slotSpan = (ResolutionDate - slot.Start).TotalSeconds;
                    else
                        slotSpan = (slot.End - slot.Start).TotalSeconds;

                    totalSpanSeconds += slotSpan;
                }

                TimeSpan TotalDuration = DateTime.UtcNow - CaseCreateTime;

                workingDays = GetPatternDays(firstRulePattern);

                List<Day> workingHours = BuildWorkingHoursFromPattern(workingDays, offset, offset + duration);

                var timeBetween = new Duration(CaseCreateTime, DateTime.UtcNow);
                timeBetween.RemoveNonWorkingMinutes(workingHours);
                double responseTime = Math.Round(TimeSpan.FromMinutes(timeBetween.GetTotalMinutes()).TotalHours, 2);

                BusinessHoursDuration = new TimeSpan(0, 0, Convert.ToInt32(totalSpanSeconds));
                var resolutionDuration = string.Format("{0:%d} days, {0:%h} hours, {0:%m} minutes, {0:%s} seconds", BusinessHoursDuration);
               
            }

            catch (Exception e)
            {
                ExceptionHelper.LogException(e, userId, CaseManagementConstants.Module, "Error occured", service);
                tracer.AddError("Error occured in Case Management, CalculateCaseresolutionDuration:" + e.Message);
                throw;
            }
            return BusinessHoursDuration;
        }
        private Entity GetCalendar(Guid calendarId)
        {
            ColumnSet cols = new ColumnSet(true);

            return service.Retrieve(CalendarColumnNames.EntityName, calendarId, cols);
        }
        internal static List<DayOfWeek> GetPatternDays(string pattern)
        {
            var days = new List<DayOfWeek>();

            string split = Array.Find(pattern.Split(';'), s => s.Contains("BYDAY"));
            int index = split.IndexOf("BYDAY=");
            string[] daysStr = split.ToString().Remove(index, 6).Split(',');
           
            if (daysStr.Length > 0)
            {
                var dayMappings = BuildDayMapping();

                foreach (var day in daysStr)
                {
                    if (dayMappings.ContainsKey(day))
                        days.Add(dayMappings[day]);
                }
            }

            return days.Count > 0 ? days : null;
        }
        static Dictionary<string, DayOfWeek> BuildDayMapping()
        {
            Dictionary<string, DayOfWeek> dayMapping = new Dictionary<string, DayOfWeek>(7);
            dayMapping.Add("MO", DayOfWeek.Monday);
            dayMapping.Add("TU", DayOfWeek.Tuesday);
            dayMapping.Add("WE", DayOfWeek.Wednesday);
            dayMapping.Add("TH", DayOfWeek.Thursday);
            dayMapping.Add("FR", DayOfWeek.Friday);
            dayMapping.Add("SA", DayOfWeek.Saturday);
            dayMapping.Add("SU", DayOfWeek.Sunday);

            return dayMapping;
        }
        internal static List<Day> BuildWorkingHoursFromPattern(List<DayOfWeek> days, int start, int end)
        {
            var workingDays = new List<Day>(7);
            var weekDays = BuildWeekDays();

            foreach (var day in days)
                workingDays.Add(new Day(day, start, end));

            foreach (var weekDay in weekDays)
                if (!days.Contains(weekDay))
                    // Add an empty Day with no minutes.
                    workingDays.Add(new Day(weekDay));

            return workingDays;
        }
        static List<DayOfWeek> BuildWeekDays()
        {
            return new List<DayOfWeek>() {
            DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday,
            DayOfWeek.Thursday, DayOfWeek.Friday, DayOfWeek.Saturday, DayOfWeek.Sunday };
        }
        public bool ValidateCaseResolution(CaseHandler caseHandler, string incidentId)
        {
            bool result = false;

            if (caseHandler != null)
            {
                var caseEntityCheck = caseHandler.GetCaseById(incidentId, new[]
                {
                    IncidentEntityAttributeNames.SubCaseTypeCodeFieldName,
                    IncidentEntityAttributeNames.CustomerSatisfactionFieldName,
                    IncidentEntityAttributeNames.RootCauseFieldName,
                    IncidentEntityAttributeNames.RootCauseDescriptionFieldName,
                    IncidentEntityAttributeNames.InFavorOfFieldName,
                    IncidentEntityAttributeNames.ResolutionSubjectFieldName
                   
                });

                var caseSubType = CrmTypesHelper.GetOptionSetValue(caseEntityCheck,
                    IncidentEntityAttributeNames.SubCaseTypeCodeFieldName);
           
                if (caseSubType != 1) // Not equal to Customer Information Update
                {
                    var resolutionSubject = CrmTypesHelper.GetStringValue(caseEntityCheck,
                        IncidentEntityAttributeNames.ResolutionSubjectFieldName);
                    if (resolutionSubject == CaseManagementConstants.SubjectAutoResolved)
                        return true;

                    var errMsg = "";
                    var satisfaction = CrmTypesHelper.GetOptionSetValue(caseEntityCheck,
                        IncidentEntityAttributeNames.CustomerSatisfactionFieldName);
                    if (satisfaction == 0)
                        errMsg = errMsg + @"Please select customer Satisfaction. \n";

                    var rootCause = CrmTypesHelper.GetEntityReferenceName(caseEntityCheck,
                        IncidentEntityAttributeNames.RootCauseFieldName);
                    if (string.IsNullOrWhiteSpace(rootCause))
                        errMsg = errMsg + @"Please select Root Cause. \n";

                    var rootCauseDesc = CrmTypesHelper.GetStringValue(caseEntityCheck,
                        IncidentEntityAttributeNames.RootCauseDescriptionFieldName);
                    if (string.IsNullOrWhiteSpace(rootCauseDesc))
                        errMsg = errMsg + @"Please select Root Cause Description. \n";

                    var inFavorOf = CrmTypesHelper.GetOptionSetValue(caseEntityCheck,
                        IncidentEntityAttributeNames.InFavorOfFieldName);
                    if (inFavorOf == 0)
                        errMsg = errMsg + @"Please select In Favor Of. \n";

                    if (!string.IsNullOrWhiteSpace(errMsg))
                        throw new InvalidPluginExecutionException(errMsg);
                    else
                    {
                        result = true;
                    }
                }
            }

            return result;
        }
    }
    //Murthy BEGIN - CALCULATE DUration
    sealed class CalendarColumnNames
    {
        public const string EntityName = "calendar";
        public const string HolidayScheduleCalendar = "holidayschedulecalendarid";
        public const string CalendarRules = "calendarrules";
        public const string CalendarId = "calendarid";
        public const string InnerCalendarId = "innercalendarid";
        public const string Pattern = "pattern";
        public const string Duration = "duration";
        public const string Offset = "offset";
        //
     
    }
    public sealed class Minute
    {
        public int Index;

        /// <summary>
        /// Default constructor for <see cref="Minute"/>.
        /// </summary>
        /// <param name="index">The minute's offset from midnight in minutes
        /// e.g. a <see cref="Index"/> of 60 would represent the minute at 01:00am for a <see cref="Day"/>.</param>
        public Minute(int index)
        {
            Index = index;
        }
    }
    public sealed class Day
    {
        public DayOfWeek DayOfWeek;
        public int DayOfMonth;
        public int Month;
        public int Year;
        public List<Minute> Minutes;
        public TimeSpan WorkingHours;

        public Day(DayOfWeek dayOfWeek)
        {
            DayOfWeek = dayOfWeek;
            Minutes = new List<Minute>();
        }
        public Day(DayOfWeek dayOfWeek, int start = 0, int end = 1440)
        {
            DayOfWeek = dayOfWeek;
            SetMinutes(start, end);
        }
        public Day(DateTime dateTime, int start = 0, int end = 1440)
        {
            DayOfWeek = dateTime.DayOfWeek;
            DayOfMonth = dateTime.Day;
            Month = dateTime.Month;
            Year = dateTime.Year;

            SetMinutes(start, end);
        }
        public Day(DayOfWeek dayOfWeek, int day, int month, int year)
        {
            DayOfWeek = dayOfWeek;
            DayOfMonth = day;
            Month = month;
            Year = year;
            SetMinutes();
        }

        /// <summary>
        /// Initialises the minutes in a day, either using an offset for start and end
        /// or setting all 1440 minutes (default).
        /// </summary>
        /// <param name="start">Offset from midnight in minutes.</param>
        /// <param name="end">Offset from midnight in minutes.</param>
        void SetMinutes(int start = 0, int end = 1440)
        {
            var minutes = new List<Minute>(1440);
            for (int i = start; i < end; i++)
                minutes.Add(new Minute(i));
            Minutes = minutes;
        }
        public bool IsSameDate(DateTime dt)
        {
            bool isSameDate = false;
            DateTime thisDay = new DateTime(this.Year, this.Month, this.DayOfMonth);

            if (dt != null)
                isSameDate = dt.Date == thisDay.Date;

            return isSameDate;
        }
    }
    public sealed class Duration
    {
        public List<Day> Days;
        public DateTime Start;
        public DateTime End;

        public Duration(List<Day> days)
        {
            Days = days;
        }
        public Duration(DateTime start, DateTime end)
        {
            Start = start;
            End = end;
            SetDays();
        }

        /// <summary>
        /// Get sum total of all minutes of all days within the <see cref="Duration"/>.
        /// </summary>
        /// <returns></returns>
        public int GetTotalMinutes()
        {
            int count = 0;

            foreach (var day in Days)
                count += day.Minutes.Count;

            return count;
        }

        /// <summary>
        /// Initialises <see cref="Days"/>.
        /// Begins with <see cref="Start"/>, ends with <see cref="End"/> and initialises all days between the two.
        /// </summary>
        void SetDays()
        {
            var daysInBetween = (End - Start).Days;
            Days = new List<Day>(daysInBetween);

            var dayOfWeek = Convert.ToInt16(Start.DayOfWeek);
            Days.Add(new Day(Start, Convert.ToInt16(Start.TimeOfDay.TotalMinutes)));

            for (int i = 0; i < daysInBetween; i++)
            {
                var nextDate = Start.AddDays(i + 1);

                if (nextDate.Date != End.Date)
                    Days.Add(new Day(nextDate.DayOfWeek, nextDate.Day, nextDate.Month, nextDate.Year));
            }

            Days.Add(new Day(End, 0, Convert.ToInt16(End.TimeOfDay.TotalMinutes)));
        }

        /// <summary>
        /// Sets <see cref="Start"/> equal to the smaller value of <see cref="Start"/> and <see cref="End"/>.
        /// </summary>
        /// <param name="inverted">Outputs true if <see cref="Start"/> and <see cref="End"/> has to be swapped, otherwise false.</param>
        //void SetStartDate(out bool inverted)
        //{
        //    inverted = false;

        //    if (Start > End)
        //    {
        //        Helpers.Common.Swap(ref Start, ref End);
        //        inverted = true;
        //    }
        //}

        /// <summary>
        /// Removes all minutes from the <see cref="Duration"/> which are not included in <paramref name="businessHours"/> parameter
        /// i.e. are not considered 'working' minutes.
        /// </summary>
        /// <param name="businessHours">Representation of minutes in days which are working minutes e.g. 09:00 - 17:00.</param>
        public void RemoveNonWorkingMinutes(List<Day> businessHours)
        {
            var startMinutes = Start.TimeOfDay.TotalMinutes;
            var endMinutes = End.TimeOfDay.TotalMinutes;

            if (Start.Date == End.Date && Days.Count == 2)
                Days.RemoveAt(1);

            foreach (var day in Days)
            {
               
                   var businessDay = businessHours.Find(x => x.DayOfWeek == day.DayOfWeek);
                var minutesToRemove = new List<Minute>();

                foreach (var minute in day.Minutes)
                {
                    if (businessDay.Minutes.FindAll(m => m.Index == minute.Index).Count <= 0)
                        minutesToRemove.Add(minute);

                    if (day.IsSameDate(Start))
                        if (minute.Index < startMinutes)
                            minutesToRemove.Add(minute);


                        else if (day.IsSameDate(End))
                            if (minute.Index >= endMinutes)
                                minutesToRemove.Add(minute);
                }

                foreach (var minuteToRemove in minutesToRemove)
                    try
                    {
                        day.Minutes.Remove(minuteToRemove);
                    }
                    catch { continue; } // Lazy. Expecting IndexOutOfBounds..
            }
        }
    }
    //Murthy END - CALCULATE DUration
}

Calculate Duration between two times using business calendar in MS CRM Dynamics

Calculate Duration between two times using business calendar in MS CRM Dynamics

Guid calendarGuid = TimeManager.GetCalendarFromSLA(sla.SLAId);

                var ResolutionDate = DateTime.UtcNow;
                List<TimeSlot> timeSlots = TimeManager.GetAvailableTimeSlotsForCalendar(calendarGuid, CaseCreateTime, DateTime.UtcNow);
                double TotalSpanSeconds = 0;
                double Totalhours = 0;
                double TotalBusinesshours = 0;
                double Totaldays = 0;
                double TotalMinutes = 0;
                int TotalDaysTillDay = timeSlots.Count / 2;
                foreach (var slot in timeSlots)
                {
                    double slotSpan = 0;
                    double hours = 0;
                    if (CaseCreateTime > slot.End)
                        slotSpan = 0;
                    else if (CaseCreateTime > slot.Start && ResolutionDate < slot.End)
                    {
                        slotSpan = (ResolutionDate - CaseCreateTime).TotalSeconds;
                        hours = (ResolutionDate - CaseCreateTime).TotalHours;
                    }
                    else if (CaseCreateTime > slot.Start && CaseCreateTime < slot.End && ResolutionDate > slot.End)
                    {
                        slotSpan = (slot.End - CaseCreateTime).TotalSeconds;
                        hours = (slot.End - CaseCreateTime).TotalHours;
                    }
                    else if (ResolutionDate > slot.Start && ResolutionDate < slot.End)
                    {
                        slotSpan = (ResolutionDate - slot.Start).TotalSeconds;
                        hours = (ResolutionDate - slot.Start).TotalHours;
                    }
                    else
                    {
                        slotSpan = (slot.End - slot.Start).TotalSeconds;
                        hours = (slot.End - slot.Start).TotalHours;
                    }

                    TotalSpanSeconds += slotSpan;
                    Totalhours += hours;

                }
                TotalBusinesshours = Totalhours;

                double reminingHours = Totalhours % 8;
                Totaldays = Totalhours / 8;             
                TotalMinutes = reminingHours * 60;

                BusinessHoursDuration = new TimeSpan(Convert.ToInt32(Totaldays), Convert.ToInt32(reminingHours), Convert.ToInt32(TotalMinutes), 0);


                var resolutionDuration = string.Format("{0:%d} days, {0:%h} hours, {0:%m} minutes, {0:%s} seconds", BusinessHoursDuration);




//GetAvailableTimeSlotsForCalendar


public List<TimeSlot> GetAvailableTimeSlotsForCalendar(Guid calendarId, DateTime startTime, DateTime endTime)
        {
            try
            {
                //Convert time to UTC because calendar info returned by the system is in UTC
                if (startTime.Kind == DateTimeKind.Local)
                    startTime = startTime.ToUniversalTime();
                if (endTime.Kind == DateTimeKind.Local)
                    endTime = endTime.ToUniversalTime();

             
                TimeInfo[] timeInfos = GetTimeInfoForCalendar(calendarId, startTime, endTime);
           
                List<TimeSlot> timeSlots = GetAvailableTimeSlots(timeInfos);
                return timeSlots;

            }
            catch (Exception ex)
            {
               
                throw;
            }
        }


// to get time slot

internal Entity GetCalendarFromSLA(Guid slaId)
        {
            try
            {
                return Retrieve(SLAColumnNames.EntityName, slaId, new string[] { SLAColumnNames.SLAId, SLAColumnNames.BusinessHours });
            }
            catch (Exception ex)
            {
                ExceptionHelper.LogException(ex, user, BaseConstants.BaseModuleName, "Error getting calendar for SLA:" + slaId.ToString(), service);
                throw;
            }
        }

Calculate Case Resolution time based on business calendar SLA


Calculate Case Resolution time based on business calendar SLA

//CaseHandler caseHandler  // this caseHandler to retrieve the case related fields like case create time
// you can replace it by CaseEntity

public TimeSpan CalculateCaseresolutionDuration(CaseHandler caseHandler, string incidentId, DateTime CaseCreateTime)
        {
            TimeSpan BusinessHoursDuration;
         
            try
            {
                TimeManager TimeManager = new TimeManager(service, tracer, userId, CaseManagementConstants.Module);
                var caseEntity = caseHandler.GetCaseById(incidentId, new[]
                {
//pass case attributes which are reqired               
IncidentEntityAttributeNames.ProcessConfigurationIdFieldName,IncidentEntityAttributeNames.OwnerIdFieldName,IncidentEntityAttributeNames.Entitlement
            });

                var ConfigID = CrmTypesHelper.GetEntityReferenceId(caseEntity, IncidentEntityAttributeNames.ProcessConfigurationIdFieldName);
                var OwnerID = CrmTypesHelper.GetEntityReferenceId(caseEntity, IncidentEntityAttributeNames.OwnerIdFieldName);
                Guid OwnerGuid = new Guid(OwnerID);
                Guid ConfigGUID = new Guid(ConfigID);

                SLAConfigObject slaConfig = new SLAConfigObject(service, userId, CaseManagementConstants.Module, tracer);

                SLAObject sla = slaConfig.GetCaseProcessConfigurationSLAbyConfigId(ConfigGUID, Guid.Empty, OwnerGuid);
                           

                Guid calendarGuid = TimeManager.GetCalendarFromSLA(sla.SLAId);

                var ResolutionDate = DateTime.UtcNow;
                List<TimeSlot> timeSlots = TimeManager.GetAvailableTimeSlotsForCalendar(calendarGuid, CaseCreateTime, DateTime.UtcNow);
                double TotalSpanSeconds = 0;
                double Totalhours = 0;
                double TotalBusinesshours = 0;
                double Totaldays = 0;
                double TotalMinutes = 0;
                int TotalDaysTillDay = timeSlots.Count / 2;
                foreach (var slot in timeSlots)
                {
                    double slotSpan = 0;
                    double hours = 0;
                    if (CaseCreateTime > slot.End)
                        slotSpan = 0;
                    else if (CaseCreateTime > slot.Start && ResolutionDate < slot.End)
                    {
                        slotSpan = (ResolutionDate - CaseCreateTime).TotalSeconds;
                        hours = (ResolutionDate - CaseCreateTime).TotalHours;
                    }
                    else if (CaseCreateTime > slot.Start && CaseCreateTime < slot.End && ResolutionDate > slot.End)
                    {
                        slotSpan = (slot.End - CaseCreateTime).TotalSeconds;
                        hours = (slot.End - CaseCreateTime).TotalHours;
                    }
                    else if (ResolutionDate > slot.Start && ResolutionDate < slot.End)
                    {
                        slotSpan = (ResolutionDate - slot.Start).TotalSeconds;
                        hours = (ResolutionDate - slot.Start).TotalHours;
                    }
                    else
                    {
                        slotSpan = (slot.End - slot.Start).TotalSeconds;
                        hours = (slot.End - slot.Start).TotalHours;
                    }

                    TotalSpanSeconds += slotSpan;
                    Totalhours += hours;

                }
                TotalBusinesshours = Totalhours;

                double reminingHours = Totalhours % 8;
                Totaldays = Totalhours / 8;             
                TotalMinutes = reminingHours * 60;

                BusinessHoursDuration = new TimeSpan(Convert.ToInt32(Totaldays), Convert.ToInt32(reminingHours), Convert.ToInt32(TotalMinutes), 0);


                var resolutionDuration = string.Format("{0:%d} days, {0:%h} hours, {0:%m} minutes, {0:%s} seconds", BusinessHoursDuration);
            }

            catch (Exception e)
            {
                ExceptionHelper.LogException(e, userId, CaseManagementConstants.Module, "Error occured", service);
                tracer.AddError("Error occured in Case Management, CalculateCaseresolutionDuration:" + e.Message);
                throw;
            }
            return BusinessHoursDuration;
        }

Monday, November 27, 2017

Loading IFrame on form - MS CRM Dynamics javascript

This is helpful to set the URL to IFRAME using javascript in MicroSoft Dynamics CRM.

use below script as reference to your javascript webresource.

you need to call the SetTransactionFrame() from onload even and save event of crm form.

// script to webpage to Iframe .. load web page on MS CRM form IFRAME.



var transactionsURL = "http:blogger.com";

function SetTransactionFrame()
{

 var subjectValue = Xrm.Page.getAttribute("subjectid").getValue();

 if ((subjectValue != null)) {
 
var subjectName = subjectValue[0].name;


var formType = Xrm.Page.ui.getFormType();
    if (formType !== 1 && subjectName=="yoursubject" )
        {
SetIFrameURL();
}
else
{
//"Details" - tab name
Xrm.Page.ui.tabs.get("Details").sections.get("Details_section_2").setVisible(false);
}

   }
}

function SetIFrameURL() {

    var CaseId = Xrm.Page.data.entity.getId();
    var UserId = Xrm.Page.context.getUserId();
   var FormType ="case";

    var transactionsURL = TransactionDetailsURL + '?id=' + CaseId +'&userid=' +UserId +'&typename='+FormType;


Xrm.Page.getControl('IFRAME_Transactions').setSrc(transactionsURL);
}