Пример #1
0
        private void ProcessTicket(TicketSlaInfo ticket)
        {
            UpdateHealth();

            bool isPaused     = false;
            bool isPending    = false;
            int? slaTriggerId = null;

            Logs.WriteEvent("Getting SlaTicket record");
            SlaTicket slaTicket = SlaTickets.GetSlaTicket(LoginUser, ticket.TicketId);

            if (slaTicket != null)
            {
                isPaused     = ticket.IsSlaPaused(slaTicket.SlaTriggerId, ticket.OrganizationId);
                isPending    = slaTicket.IsPending;
                slaTriggerId = slaTicket.SlaTriggerId;
            }

            Logs.WriteEventFormat("IsPaused: {0}; IsPending: {1}", isPaused.ToString(), isPending.ToString());

            if (!isPaused && !isPending)
            {
                SlaTriggersView triggers = new SlaTriggersView(LoginUser);
                triggers.LoadByTicketId(ticket.TicketId);
                bool warnGroup = false;
                bool warnUser  = false;
                bool vioGroup  = false;
                bool vioUser   = false;

                foreach (SlaTriggersViewItem item in triggers)
                {
                    warnGroup = item.NotifyGroupOnWarning || warnGroup;
                    warnUser  = item.NotifyUserOnWarning || warnUser;
                    vioGroup  = item.NotifyGroupOnViolation || vioGroup;
                    vioUser   = item.NotifyUserOnViolation || vioUser;
                }

                SlaNotification notification = SlaNotifications.GetSlaNotification(LoginUser, ticket.TicketId);
                if (notification == null)
                {
                    notification          = (new SlaNotifications(LoginUser)).AddNewSlaNotification();
                    notification.TicketID = ticket.TicketId;
                }

                DateTime notifyTime;

                if (ticket.SlaViolationInitialResponse != null && ticket.SlaViolationInitialResponse <= DateTime.UtcNow)
                {
                    notifyTime = (DateTime)ticket.SlaViolationInitialResponse;
                    if (!IsTooOld(notifyTime))
                    {
                        if (notification.InitialResponseViolationDate == null || Math.Abs(((DateTime)notification.InitialResponseViolationDateUtc - notifyTime).TotalMinutes) > 5)
                        {
                            NotifyViolation(ticket.TicketId, vioUser, vioGroup, false, SlaViolationType.InitialResponse, notification, slaTriggerId);
                            notification.InitialResponseViolationDate = notifyTime;
                        }
                    }
                }
                else if (ticket.SlaWarningInitialResponse != null && ticket.SlaWarningInitialResponse <= DateTime.UtcNow)
                {
                    notifyTime = (DateTime)ticket.SlaWarningInitialResponse;

                    if (!IsTooOld(notifyTime))
                    {
                        if (notification.InitialResponseWarningDate == null || Math.Abs(((DateTime)notification.InitialResponseWarningDateUtc - notifyTime).TotalMinutes) > 5)
                        {
                            NotifyViolation(ticket.TicketId, warnUser, warnGroup, true, SlaViolationType.InitialResponse, notification, slaTriggerId);
                            notification.InitialResponseWarningDate = notifyTime;
                        }
                    }
                }


                if (ticket.SlaViolationLastAction != null && ticket.SlaViolationLastAction <= DateTime.UtcNow)
                {
                    notifyTime = (DateTime)ticket.SlaViolationLastAction;

                    if (!IsTooOld(notifyTime))
                    {
                        if (notification.LastActionViolationDate == null || Math.Abs(((DateTime)notification.LastActionViolationDateUtc - notifyTime).TotalMinutes) > 5)
                        {
                            NotifyViolation(ticket.TicketId, vioUser, vioGroup, false, SlaViolationType.LastAction, notification, slaTriggerId);
                            notification.LastActionViolationDate = notifyTime;
                        }
                    }
                }
                else if (ticket.SlaWarningLastAction != null && ticket.SlaWarningLastAction <= DateTime.UtcNow)
                {
                    notifyTime = (DateTime)ticket.SlaWarningLastAction;

                    if (!IsTooOld(notifyTime))
                    {
                        if (notification.LastActionWarningDate == null || Math.Abs(((DateTime)notification.LastActionWarningDateUtc - notifyTime).TotalMinutes) > 5)
                        {
                            NotifyViolation(ticket.TicketId, warnUser, warnGroup, true, SlaViolationType.LastAction, notification, slaTriggerId);
                            notification.LastActionWarningDate = notifyTime;
                        }
                    }
                }


                if (ticket.SlaViolationTimeClosed != null && ticket.SlaViolationTimeClosed <= DateTime.UtcNow)
                {
                    notifyTime = (DateTime)ticket.SlaViolationTimeClosed;

                    if (!IsTooOld(notifyTime))
                    {
                        if (notification.TimeClosedViolationDate == null || Math.Abs(((DateTime)notification.TimeClosedViolationDateUtc - notifyTime).TotalMinutes) > 5)
                        {
                            NotifyViolation(ticket.TicketId, vioUser, vioGroup, false, SlaViolationType.TimeClosed, notification, slaTriggerId);
                            notification.TimeClosedViolationDate = notifyTime;
                        }
                    }
                }
                else if (ticket.SlaWarningTimeClosed != null && ticket.SlaWarningTimeClosed <= DateTime.UtcNow)
                {
                    notifyTime = (DateTime)ticket.SlaWarningTimeClosed;

                    if (!IsTooOld(notifyTime))
                    {
                        if (notification.TimeClosedWarningDate == null || Math.Abs(((DateTime)notification.TimeClosedWarningDateUtc - notifyTime).TotalMinutes) > 5)
                        {
                            NotifyViolation(ticket.TicketId, warnUser, warnGroup, true, SlaViolationType.TimeClosed, notification, slaTriggerId);
                            notification.TimeClosedWarningDate = notifyTime;
                        }
                    }
                }

                notification.Collection.Save();
            }
        }
Пример #2
0
    protected void Page_Load(object sender, EventArgs e)
    {
        if (Request["TicketID"] == null)
        {
            EndResponse("Invalid Ticket");
        }
        LoginUser loginUser = TSAuthentication.GetLoginUser();
        int       ticketID  = int.Parse(Request["TicketID"]);
        Ticket    ticket    = Tickets.GetTicket(loginUser, ticketID);

        if (ticket == null)
        {
            EndResponse("Invalid Ticket");
        }

        tipNumber.InnerText = "Ticket #" + ticket.TicketNumber.ToString();
        tipNumber.Attributes.Add("onclick", "top.Ts.MainPage.openTicket(" + ticket.TicketNumber + "); return false;");
        tipName.InnerHtml = ticket.Name;

        bool      isStatusPaused = false;
        SlaTicket slaTicket      = SlaTickets.GetSlaTicket(loginUser, ticket.TicketID);

        if (slaTicket != null)
        {
            SlaTrigger slaTrigger = SlaTriggers.GetSlaTrigger(loginUser, slaTicket.SlaTriggerId);

            if (slaTrigger != null)
            {
                isStatusPaused = ticket.IsSlaStatusPaused();
                string slaName = new SlaLevels(TSAuthentication.GetLoginUser()).GetSlaveLevelName(slaTicket.SlaTriggerId);
                wslaName.InnerText = slaName;
            }
            else
            {
                ticket.SlaViolationInitialResponse = null;
                ticket.SlaViolationTimeClosed      = null;
                ticket.SlaViolationLastAction      = null;
                ticket.SlaWarningInitialResponse   = null;
                ticket.SlaWarningTimeClosed        = null;
                ticket.SlaWarningLastAction        = null;
                ticket.Collection.Save();
            }
        }

        if (isStatusPaused)
        {
            wClose.InnerText = "Paused";
            vClose.InnerText = "Paused";
            wLast.InnerText  = "Paused";
            vLast.InnerText  = "Paused";
            wInit.InnerText  = "Paused";
            vInit.InnerText  = "Paused";
            wNext.InnerText  = "Paused";
            vNext.InnerText  = "Paused";
        }
        else
        {
            DateTime?nextViolation = GetUtcDate(ticket, "SlaViolationInitialResponse");
            nextViolation = GetMinDate(loginUser, nextViolation, GetUtcDate(ticket, "SlaViolationLastAction"));
            nextViolation = GetMinDate(loginUser, nextViolation, GetUtcDate(ticket, "SlaViolationTimeClosed"));

            DateTime?nextWarning = GetUtcDate(ticket, "SlaWarningInitialResponse");
            nextWarning = GetMinDate(loginUser, nextWarning, GetUtcDate(ticket, "SlaWarningLastAction"));
            nextWarning = GetMinDate(loginUser, nextWarning, GetUtcDate(ticket, "SlaWarningTimeClosed"));

            if (nextViolation != null && nextViolation < DateTime.UtcNow)
            {
                tipSla.Attributes.Add("class", "ts-icon ts-icon-sla-bad");
            }
            else if (nextWarning != null && nextWarning < DateTime.UtcNow)
            {
                tipSla.Attributes.Add("class", "ts-icon ts-icon-sla-warning");
            }
            else
            {
                tipSla.Attributes.Add("class", "ts-icon ts-icon-sla-good");
            }

            wClose.InnerText = GetDateString(loginUser, GetUtcDate(ticket, "SlaWarningTimeClosed"));
            vClose.InnerText = GetDateString(loginUser, GetUtcDate(ticket, "SlaViolationTimeClosed"));
            wLast.InnerText  = GetDateString(loginUser, GetUtcDate(ticket, "SlaWarningLastAction"));
            vLast.InnerText  = GetDateString(loginUser, GetUtcDate(ticket, "SlaViolationLastAction"));
            wInit.InnerText  = GetDateString(loginUser, GetUtcDate(ticket, "SlaWarningInitialResponse"));
            vInit.InnerText  = GetDateString(loginUser, GetUtcDate(ticket, "SlaViolationInitialResponse"));
            wNext.InnerText  = GetDateString(loginUser, nextWarning);
            vNext.InnerText  = GetDateString(loginUser, nextViolation);
        }
    }
Пример #3
0
        public override void Run()
        {
            try
            {
                SlaTickets slaTickets = new SlaTickets(LoginUser);
                slaTickets.LoadPending();

                if (slaTickets != null && slaTickets.Count > 0)
                {
                    Logs.WriteEvent(string.Format("{0} pending tickets to calculate the SLA values for.", slaTickets.Count));
                }

                foreach (SlaTicket slaTicket in slaTickets)
                {
                    if (IsStopped)
                    {
                        break;
                    }
                    UpdateHealth();

                    try
                    {
                        Ticket ticket = Tickets.GetTicket(LoginUser, slaTicket.TicketId);

                        if (ticket != null)
                        {
                            bool     isStatusPaused                 = ticket.IsSlaStatusPaused();
                            bool     isClosed                       = ticket.DateClosed != null;
                            DateTime?newSlaViolationTimeClosed      = null;
                            DateTime?newSlaWarningTimeClosed        = null;
                            DateTime?newSlaViolationLastAction      = null;
                            DateTime?newSlaWarningLastAction        = null;
                            DateTime?newSlaViolationInitialResponse = null;
                            DateTime?newSlaWarningInitialResponse   = null;

                            if (!isClosed && !isStatusPaused)
                            {
                                DateTime?lastActionDateCreated = Actions.GetLastActionDateCreated(LoginUser, ticket.TicketID);
                                int      totalActions          = Actions.TotalActionsForSla(LoginUser, ticket.TicketID, ticket.OrganizationID);

                                Organization organization = Organizations.GetOrganization(LoginUser, ticket.OrganizationID);
                                SlaTrigger   slaTrigger   = SlaTriggers.GetSlaTrigger(LoginUser, slaTicket.SlaTriggerId);

                                if (slaTrigger == null)
                                {
                                    Logs.WriteEventFormat("Trigger {0} not found.", slaTicket.SlaTriggerId);
                                }

                                SlaTickets.BusinessHours businessHours = new SlaTickets.BusinessHours()
                                {
                                    DayStartUtc  = organization.BusinessDayStartUtc,
                                    DayEndUtc    = organization.BusinessDayEndUtc,
                                    BusinessDays = organization.BusinessDays
                                };

                                //Check if we should use SLA's business hours instead of Account's
                                if (!slaTrigger.UseBusinessHours &&
                                    !slaTrigger.NoBusinessHours &&
                                    slaTrigger.DayStartUtc.HasValue &&
                                    slaTrigger.DayEndUtc.HasValue)
                                {
                                    businessHours.DayStartUtc  = slaTrigger.DayStartUtc.Value;
                                    businessHours.DayEndUtc    = slaTrigger.DayEndUtc.Value;
                                    businessHours.BusinessDays = slaTrigger.Weekdays;
                                }
                                else if (!slaTrigger.UseBusinessHours && !slaTrigger.NoBusinessHours)
                                {
                                    Logs.WriteEventFormat("Using Account's business hours {0} to {1} because while the trigger is set to use sla's business hours one of them has no value. Sla DayStartUtc {2}, Sla DayEndUtc {3}",
                                                          organization.BusinessDayStartUtc.ToShortTimeString(),
                                                          organization.BusinessDayEndUtc.ToShortTimeString(),
                                                          slaTrigger.DayStartUtc.HasValue ? slaTrigger.DayStartUtc.Value.ToShortTimeString() : "NULL",
                                                          slaTrigger.DayEndUtc.HasValue ? slaTrigger.DayEndUtc.Value.ToShortTimeString() : "NULL");
                                }

                                Logs.WriteEvent(string.Format("Ticket #{0} id {1}. LastAction: {2}, TotalActions: {3}, Org({4}) {5}, SlaTriggerId {6}.", ticket.TicketNumber,
                                                              ticket.TicketID,
                                                              lastActionDateCreated == null ? "none" : lastActionDateCreated.Value.ToString(),
                                                              totalActions,
                                                              organization.OrganizationID,
                                                              organization.Name,
                                                              slaTrigger.SlaTriggerID));
                                List <DateTime> daysToPause    = SlaTriggers.GetSpecificDaysToPause(slaTrigger.SlaTriggerID);
                                bool            pauseOnHoliday = slaTrigger.PauseOnHoliday;
                                CalendarEvents  holidays       = new CalendarEvents(LoginUser);

                                if (pauseOnHoliday)
                                {
                                    holidays.LoadHolidays(organization.OrganizationID);
                                }

                                Dictionary <int, double> businessPausedTimes = new Dictionary <int, double>();

                                //We need to have two calculations for the paused time, one for the Time To Close and Initial Response which should count the paused time since the Ticket creation
                                //and another one for Last Action where it should only count starting from the last action added
                                TimeSpan totalPausedTimeSpan = SlaTickets.CalculatePausedTime(ticket.TicketID, organization, businessHours, slaTrigger, daysToPause, holidays, LoginUser, businessPausedTimes, Logs);
                                Logs.WriteEventFormat("Total Paused Time: {0}", totalPausedTimeSpan.ToString());

                                UpdateBusinessPausedTimes(LoginUser, businessPausedTimes);

                                newSlaViolationTimeClosed = SlaTickets.CalculateSLA(ticket.DateCreatedUtc, businessHours, slaTrigger, slaTrigger.TimeToClose, totalPausedTimeSpan, daysToPause, holidays);

                                if (newSlaViolationTimeClosed != null)
                                {
                                    newSlaWarningTimeClosed = SlaTickets.CalculateSLAWarning(newSlaViolationTimeClosed.Value,
                                                                                             businessHours,
                                                                                             slaTrigger.NoBusinessHours,
                                                                                             slaTrigger.TimeToClose,
                                                                                             slaTrigger.WarningTime,
                                                                                             daysToPause,
                                                                                             holidays);
                                }

                                TimeSpan pausedTimeSpanSinceLastAction = SlaTickets.CalculatePausedTime(ticket.TicketID,
                                                                                                        organization, businessHours,
                                                                                                        slaTrigger,
                                                                                                        daysToPause,
                                                                                                        holidays,
                                                                                                        LoginUser,
                                                                                                        businessPausedTimes,
                                                                                                        Logs,
                                                                                                        false,
                                                                                                        lastActionDateCreated.HasValue ? lastActionDateCreated.Value : (DateTime?)null);
                                Logs.WriteEventFormat("Total Paused Time: {0}", pausedTimeSpanSinceLastAction.ToString());

                                if (lastActionDateCreated == null)
                                {
                                    newSlaViolationLastAction = null;
                                    newSlaWarningLastAction   = null;
                                }
                                else
                                {
                                    newSlaViolationLastAction = SlaTickets.CalculateSLA(lastActionDateCreated.Value,
                                                                                        businessHours,
                                                                                        slaTrigger,
                                                                                        slaTrigger.TimeLastAction,
                                                                                        pausedTimeSpanSinceLastAction,
                                                                                        daysToPause,
                                                                                        holidays);

                                    if (newSlaViolationLastAction != null)
                                    {
                                        newSlaWarningLastAction = SlaTickets.CalculateSLAWarning((DateTime)newSlaViolationLastAction.Value,
                                                                                                 businessHours,
                                                                                                 slaTrigger.NoBusinessHours,
                                                                                                 slaTrigger.TimeLastAction,
                                                                                                 slaTrigger.WarningTime,
                                                                                                 daysToPause,
                                                                                                 holidays);
                                    }
                                }

                                if (slaTrigger.TimeInitialResponse < 1 || totalActions > 0)
                                {
                                    newSlaViolationInitialResponse = null;
                                    newSlaWarningInitialResponse   = null;
                                }
                                else
                                {
                                    newSlaViolationInitialResponse = SlaTickets.CalculateSLA(ticket.DateCreatedUtc,
                                                                                             businessHours,
                                                                                             slaTrigger,
                                                                                             slaTrigger.TimeInitialResponse,
                                                                                             totalPausedTimeSpan,
                                                                                             daysToPause,
                                                                                             holidays);

                                    if (newSlaViolationInitialResponse != null)
                                    {
                                        newSlaWarningInitialResponse = SlaTickets.CalculateSLAWarning((DateTime)newSlaViolationInitialResponse.Value,
                                                                                                      businessHours,
                                                                                                      slaTrigger.NoBusinessHours,
                                                                                                      slaTrigger.TimeInitialResponse,
                                                                                                      slaTrigger.WarningTime,
                                                                                                      daysToPause,
                                                                                                      holidays);
                                    }
                                }
                            }
                            else
                            {
                                Logs.WriteEventFormat("Ticket is {0}, clearing its SLA values.", isClosed ? "Closed" : "Status Paused");
                            }

                            if (HasAnySlaChanges(ticket,
                                                 newSlaViolationTimeClosed,
                                                 newSlaWarningTimeClosed,
                                                 newSlaViolationLastAction,
                                                 newSlaWarningLastAction,
                                                 newSlaViolationInitialResponse,
                                                 newSlaWarningInitialResponse))
                            {
                                ticket.SlaViolationTimeClosed      = newSlaViolationTimeClosed;
                                ticket.SlaWarningTimeClosed        = newSlaWarningTimeClosed;
                                ticket.SlaViolationLastAction      = newSlaViolationLastAction;
                                ticket.SlaWarningLastAction        = newSlaWarningLastAction;
                                ticket.SlaViolationInitialResponse = newSlaViolationInitialResponse;
                                ticket.SlaWarningInitialResponse   = newSlaWarningInitialResponse;
                                Tickets.UpdateTicketSla(LoginUser,
                                                        ticket.TicketID,
                                                        newSlaViolationInitialResponse,
                                                        newSlaViolationLastAction,
                                                        newSlaViolationTimeClosed,
                                                        newSlaWarningInitialResponse,
                                                        newSlaWarningLastAction,
                                                        newSlaWarningTimeClosed);
                                Logs.WriteEvent("Ticket SLA calculation completed.");

                                string signalRUrl = Settings.ReadString("SignalRUrl");

                                if (!string.IsNullOrEmpty(signalRUrl))
                                {
                                    //Dictionary<string, string> queryStringData = new Dictionary<string, string>();
                                    //queryStringData.Add("userID", "-1");
                                    //queryStringData.Add("organizationID", ticket.OrganizationID.ToString());
                                    //HubConnection connection = new HubConnection(signalRUrl, queryStringData);
                                    //IHubProxy signalRConnection = connection.CreateHubProxy("TicketSocket");

                                    //try
                                    //{
                                    //    connection.Start().Wait();
                                    //    signalRConnection.Invoke("RefreshSLA", ticket.TicketNumber);
                                    //}
                                    //catch (Exception ex)
                                    //{
                                    //    Logs.WriteEvent("Could not send signalR to refresh the SLA. Message: " + ex.Message);
                                    //}
                                }
                            }
                            else
                            {
                                Logs.WriteEvent("Ticket SLA calculation completed. SLA values did not change, ticket was not updated.");
                            }

                            slaTicket.IsPending = false;
                            slaTicket.Collection.Save();
                        }
                        else
                        {
                            SlaPausedTimes slaPausedTimes = new SlaPausedTimes(LoginUser);
                            slaPausedTimes.LoadByTicketId(slaTicket.TicketId);
                            slaPausedTimes.DeleteAll();
                            slaPausedTimes.Save();

                            slaTicket.Delete();
                            slaTicket.Collection.Save();
                            Logs.WriteEventFormat("Ticket id {0} does not exist anymore, deleted from SlaTickets.", slaTicket.TicketId);
                        }

                        System.Threading.Thread.Sleep(100);
                    }
                    catch (System.Data.SqlClient.SqlException sqlEx)
                    {
                        //Handle the deadlock exception, any other bubble up.
                        if (sqlEx.Number == 1205 || sqlEx.Message.Contains("deadlocked"))
                        {
                            ExceptionLogs.LogException(LoginUser, sqlEx, "SLA Calculator", "Sync");
                            Logs.WriteEventFormat("Exception. Message {0}{1}StackTrace {2}", sqlEx.Message, Environment.NewLine, sqlEx.StackTrace);
                            slaTicket.IsPending = true;
                            slaTicket.Collection.Save();
                            Logs.WriteEventFormat("SlaTicket: TicketId {0} TriggerId {1} still pending.", slaTicket.TicketId, slaTicket.SlaTriggerId);
                        }
                        else
                        {
                            throw;
                        }
                    }
                    catch (Exception ex)
                    {
                        ExceptionLogs.LogException(LoginUser, ex, "SLA Calculator", "Sync");
                        Logs.WriteEventFormat("Exception. Message {0}{1}StackTrace {2}", ex.Message, Environment.NewLine, ex.StackTrace);

                        slaTicket.IsPending = false;
                        slaTicket.Collection.Save();
                        Logs.WriteEventFormat("SlaTicket: TicketId {0} TriggerId {1} set to not pending.", slaTicket.TicketId, slaTicket.SlaTriggerId);
                    }
                }

                if (slaTickets != null && slaTickets.Count > 0)
                {
                    Logs.WriteEvent(string.Format("Completed processing the {0} pending tickets to calculate the SLA values for.", slaTickets.Count));
                }
            }
            catch (Exception ex)
            {
                ExceptionLogs.LogException(LoginUser, ex, "SLA Calculator", "Sync");
                Logs.WriteEvent(string.Format("Exception. Message {0}{1}StackTrace {2}", ex.Message, Environment.NewLine, ex.StackTrace));
            }
        }