public TicketCreateViewModel(ISecurityService security, SettingsService settings, Ticket ticket)
 {
     ListUtility = MefHttpApplication.ApplicationContainer.GetExportedValue<SelectListUtility>();
     Security = security;
     Settings = settings;
     Ticket = ticket;
 }
 public virtual ActionResult Create()
 {
     Ticket ticket = new Ticket();
     var model = new TicketCreateViewModel(Security, Settings, ticket);
     return View(model);
 }
Beispiel #3
0
        private void AddAttachmentsToNewTicket(Ticket ticket, string creatorUserName)
        {
            //files
            if (ticket.TicketAttachments != null && ticket.TicketAttachments.Count > 0)
            {
                var attaches = ticket.TicketAttachments.ToArray();
                ticket.TicketAttachments.Clear();
                foreach (var f in attaches)
                {
                    var ta = Repository.GetPendingAttachment(f.FileId);
                    ta.FileName = f.FileName;

                    ta.FileDescription = f.FileDescription;
                    ta.IsPending = false;
                    ticket.TicketAttachments.Add(ta);

                    //TODO: What to do when pending attachment isn't found?
                    ticket.TicketAttachments.Add(ta);
                }
            }
        }
        private Document CreateIndexDocuementForTicket(Ticket ticket)
        {
            var doc = new Document();
            
            var commentTexts = (from c in ticket.TicketComments
                                select c.Comment);
            StringBuilder sb = new StringBuilder();
            foreach (var c in commentTexts)
            {
                sb.AppendLine(c);
            }
            var commentText = sb.ToString();

            Lucene.Net.Documents.Field idField = new Lucene.Net.Documents.Field
                                                   (
                                                       "ticketid",
                                                       ticket.TicketId.ToString(),
                                                       Lucene.Net.Documents.Field.Store.YES,
                                                       Lucene.Net.Documents.Field.Index.NO,
                                                       Lucene.Net.Documents.Field.TermVector.NO
                                                   );

            Lucene.Net.Documents.Field titleField = new Lucene.Net.Documents.Field
                                                    (
                                                        "title",
                                                        ticket.Title ?? string.Empty,
                                                        Lucene.Net.Documents.Field.Store.YES,
                                                        Lucene.Net.Documents.Field.Index.ANALYZED,
                                                        Lucene.Net.Documents.Field.TermVector.YES
                                                    );
            titleField.SetBoost(1.5F);

            Lucene.Net.Documents.Field detailsField = new Lucene.Net.Documents.Field
                                                    (
                                                        "details",
                                                        ticket.Details ?? string.Empty,
                                                        Lucene.Net.Documents.Field.Store.NO,
                                                        Lucene.Net.Documents.Field.Index.ANALYZED,
                                                        Lucene.Net.Documents.Field.TermVector.YES
                                                    );
            detailsField.SetBoost(1F);



            Lucene.Net.Documents.Field tagsField = new Lucene.Net.Documents.Field
                                                    (
                                                        "tags",
                                                        ticket.TagList ?? string.Empty,
                                                        Lucene.Net.Documents.Field.Store.NO,
                                                        Lucene.Net.Documents.Field.Index.ANALYZED,
                                                        Lucene.Net.Documents.Field.TermVector.NO
                                                    );
            tagsField.SetBoost(2F);

            Lucene.Net.Documents.Field commentsField = new Lucene.Net.Documents.Field
                                                    (
                                                        "comments",
                                                        commentText ?? string.Empty,
                                                        Lucene.Net.Documents.Field.Store.NO,
                                                        Lucene.Net.Documents.Field.Index.ANALYZED,
                                                        Lucene.Net.Documents.Field.TermVector.YES
                                                    );
            commentsField.SetBoost(.8F);


            doc.Add(idField);
            doc.Add(titleField);
            doc.Add(detailsField);
            doc.Add(tagsField);
            doc.Add(commentsField);
            if (ticket.CurrentStatus != "Closed")
            {
                doc.SetBoost(10F);
            }
            return doc;
        }
        /// <summary>
        /// Clears the tags of a ticket.
        /// </summary>
        /// <param name="ticket">The ticket.</param>
        /// <param name="commit">if set to <c>true</c> deletes the tags from the DB.</param>
        /// <returns></returns>
        public bool ClearTags(Ticket ticket, bool commit)
        {
            var tagsToKill = new List<TicketTag>();
            foreach (var tag in ticket.TicketTags)
            {
                tagsToKill.Add(tag);

            }
            foreach (var tag in tagsToKill)
            {
                ctx.TicketTags.DeleteObject(tag);
            }

            if (commit)
            {
                ctx.SaveChanges();
                SavingTicketChanges(ticket);
            }
            return true;
        }
 /// <summary>
 /// Updates the ticket.
 /// </summary>
 /// <remarks>
 /// In the EF implementation we don't need the ticket entity passed as a parameter, but we pass it anyway as other repositories may not work the same way
 /// </remarks>
 /// <param name="ticket">The ticket to update.</param>
 /// <returns></returns>
 public bool UpdateTicket(Ticket ticket)
 {
     ctx.SaveChanges();
     SavingTicketChanges(ticket);
     return true;
 }
 /// <summary>
 /// Create a new Ticket object.
 /// </summary>
 /// <param name="ticketId">Initial value of the TicketId property.</param>
 /// <param name="type">Initial value of the Type property.</param>
 /// <param name="category">Initial value of the Category property.</param>
 /// <param name="title">Initial value of the Title property.</param>
 /// <param name="details">Initial value of the Details property.</param>
 /// <param name="isHtml">Initial value of the IsHtml property.</param>
 /// <param name="createdBy">Initial value of the CreatedBy property.</param>
 /// <param name="createdDate">Initial value of the CreatedDate property.</param>
 /// <param name="owner">Initial value of the Owner property.</param>
 /// <param name="currentStatus">Initial value of the CurrentStatus property.</param>
 /// <param name="currentStatusDate">Initial value of the CurrentStatusDate property.</param>
 /// <param name="currentStatusSetBy">Initial value of the CurrentStatusSetBy property.</param>
 /// <param name="lastUpdateBy">Initial value of the LastUpdateBy property.</param>
 /// <param name="lastUpdateDate">Initial value of the LastUpdateDate property.</param>
 /// <param name="affectsCustomer">Initial value of the AffectsCustomer property.</param>
 /// <param name="publishedToKb">Initial value of the PublishedToKb property.</param>
 /// <param name="version">Initial value of the Version property.</param>
 public static Ticket CreateTicket(global::System.Int32 ticketId, global::System.String type, global::System.String category, global::System.String title, global::System.String details, global::System.Boolean isHtml, global::System.String createdBy, global::System.DateTime createdDate, global::System.String owner, global::System.String currentStatus, global::System.DateTime currentStatusDate, global::System.String currentStatusSetBy, global::System.String lastUpdateBy, global::System.DateTime lastUpdateDate, global::System.Boolean affectsCustomer, global::System.Boolean publishedToKb, global::System.Byte[] version)
 {
     Ticket ticket = new Ticket();
     ticket.TicketId = ticketId;
     ticket.Type = type;
     ticket.Category = category;
     ticket.Title = title;
     ticket.Details = details;
     ticket.IsHtml = isHtml;
     ticket.CreatedBy = createdBy;
     ticket.CreatedDate = createdDate;
     ticket.Owner = owner;
     ticket.CurrentStatus = currentStatus;
     ticket.CurrentStatusDate = currentStatusDate;
     ticket.CurrentStatusSetBy = currentStatusSetBy;
     ticket.LastUpdateBy = lastUpdateBy;
     ticket.LastUpdateDate = lastUpdateDate;
     ticket.AffectsCustomer = affectsCustomer;
     ticket.PublishedToKb = publishedToKb;
     ticket.Version = version;
     return ticket;
 }
        private bool DoTicketActivity(string activityName, Ticket ticket, string comments, params object[] args)
        {
            //TODO: The methods called on the ticket service are supplying the user name, but the ticket service has a reference to security service and can infer that
            bool result = false;
            switch (activityName)
            {
                case "AddComment":
                    result = Tickets.AddCommentToTicket(ticket, comments);
                    break;
                case "SupplyMoreInfo":
                    bool markActive = (bool)args[0];
                    result = Tickets.SupplyMoreInfoForTicket(ticket, comments, markActive);
                    break;
                case "RequestMoreInfo":
                    result = Tickets.RequestMoreInfoForTicket(ticket, comments);
                    break;
                case "CancelMoreInfo":
                    result = Tickets.CancelMoreInfoForTicket(ticket, comments);
                    break;
                case "TakeOver":
                    string tpriority = (args != null && args.Length == 1) ? args[0] as string : null;
                    result = Tickets.TakeOverTicket(ticket, comments, tpriority);
                    break;
                case "Assign":
                    string assignTo = (args != null && args.Length > 0) ? args[0] as string : null;
                    string apriority = (args != null && args.Length > 1) ? args[1] as string : null;
                    result = Tickets.AssignTicket(ticket, comments, assignTo, apriority);
                    break;
                case "Resolve":
                    result = Tickets.ResolveTicket(ticket, comments);
                    break;
                case "Close":
                    result = Tickets.CloseTicket(ticket, comments, false);
                    break;
                case "ForceClose":
                    result = Tickets.CloseTicket(ticket, comments, true);
                    break;
                case "GiveUp":
                    result = Tickets.GiveUpTicket(ticket, comments);
                    break;
                case "ReOpen":
                    bool? assignToMe = (args != null && args.Length > 0) ? args[0] as bool? : false;
                    bool? ownedByMe = (args != null && args.Length > 1) ? args[1] as bool? : false;
                    if (!assignToMe.HasValue)
                    {
                        assignToMe = false;
                    }
                    if (!ownedByMe.HasValue)
                    {
                        ownedByMe = false;
                    }

                    if (!Security.IsTdStaff())
                    {
                        if (ticket.Owner != Security.CurrentUserName)
                        {
                            ownedByMe = true;
                        }
                    }

                    result = Tickets.ReOpenTicket(ticket, comments, assignToMe.Value, ownedByMe.Value);
                    break;
                case "ModifyAttachments":

                    var attachments = args[0] as List<TicketAttachment>;
                    result = Tickets.ModifyAttachmentsForTicket(ticket, comments, attachments);
                    //TODO: on successful result we need to remove the pending files. The model has no notion of "pending files" though so this needs to be done seperately
                    break;
                case "EditTicketInfo":
                    result = Tickets.EditTicketDetails(ticket, comments);
                    break;
            }
            return result;

        }
Beispiel #9
0
        /// <summary>
        /// Gives up a ticket and marks it unassigned again.
        /// </summary>
        /// <param name="ticket">The ticket.</param>
        /// <param name="userName">Name of the user giving up the ticket.</param>
        /// <param name="comments">The comments.</param>
        /// <returns></returns>
        public bool GiveUpTicket(Ticket ticket, string comment)
        {
            if (!CheckSecurityForTicketActivity(ticket, TicketActivity.GiveUp))
            {
                throw new RuleException("noAuth", "User is not authorized to modify ticket information");
            }
            if (string.IsNullOrEmpty(comment))
            {
                throw new RuleException("comment", "A comment is required");
            }

            ticket.TicketComments.Add(GetActivityComment(TicketActivity.GiveUp, comment, ticket.AssignedTo, ticket.GetNotificationSubscribers()));

            ticket.AssignedTo = null;
            ticket.LastUpdateBy = Security.CurrentUserName;
            ticket.LastUpdateDate = DateTime.Now;

            return Repository.UpdateTicket(ticket);
        }
Beispiel #10
0
        /// <summary>
        /// Closes the ticket.
        /// </summary>
        /// <param name="ticket">The ticket.</param>
        /// <param name="userName">Name of the user closing the ticket.</param>
        /// <param name="comment"></param>
        /// <returns></returns>
        public bool CloseTicket(Ticket ticket, string comment, bool force)
        {
            var rnv = new NameValueCollection();
            bool secCheck = false;
            if (force)
            {
                secCheck = CheckSecurityForTicketActivity(ticket, TicketActivity.ForceClose);
            }
            else
            {
                secCheck = CheckSecurityForTicketActivity(ticket, TicketActivity.Close);
            }

            if (!secCheck)
            {
                rnv.Add("noAuth", "User is not authorized to close ticket");
            }

            if (force && string.IsNullOrEmpty(comment))
            {
                rnv.Add("comment", "A comment is required");
            }
            if (rnv.Count > 0)
            {
                throw new RuleException(rnv);
            }

            TicketComment c = (force) ?
                GetActivityComment(TicketActivity.ForceClose, comment, ticket.AssignedTo, ticket.GetNotificationSubscribers()) :
                GetActivityComment(TicketActivity.Close, comment, ticket.AssignedTo, ticket.GetNotificationSubscribers());

            ticket.TicketComments.Add(c);

            ticket.CurrentStatus = "Closed";
            ticket.CurrentStatusSetBy = Security.CurrentUserName;
            ticket.CurrentStatusDate = DateTime.Now;
            ticket.LastUpdateBy = Security.CurrentUserName;
            ticket.LastUpdateDate = ticket.CurrentStatusDate;

            return Repository.UpdateTicket(ticket);
        }
Beispiel #11
0
        /// <summary>
        /// Resolves the ticket.
        /// </summary>
        /// <param name="ticket">The ticket.</param>
        /// <param name="userName">Name of the user resolving the ticket.</param>
        /// <param name="comment">The comment.</param>
        /// <returns></returns>
        public bool ResolveTicket(Ticket ticket, string comment)
        {
            var rnv = new NameValueCollection();

            if (!CheckSecurityForTicketActivity(ticket, TicketActivity.Resolve))
            {
                rnv.Add("noAuth", "User is not authorized to resolve ticket");
            }

            if (string.IsNullOrEmpty(comment))
            {
                rnv.Add("comment", "A comment is required");
            }

            if (rnv.Count > 0)
            {
                throw new RuleException(rnv);
            }

            ticket.TicketComments.Add(GetActivityComment(TicketActivity.Resolve, comment, ticket.AssignedTo, ticket.GetNotificationSubscribers()));

            ticket.CurrentStatus = "Resolved";
            ticket.CurrentStatusSetBy = Security.CurrentUserName;
            ticket.CurrentStatusDate = DateTime.Now;
            ticket.LastUpdateBy = Security.CurrentUserName;
            ticket.LastUpdateDate = ticket.CurrentStatusDate;
            return Repository.UpdateTicket(ticket);
        }
Beispiel #12
0
        public bool AssignTicket(Ticket ticket, string comment, string assignTo, string priority)
        {
            bool hasPriority = (!string.IsNullOrEmpty(priority));

            TicketActivity activityEn;

            if (string.IsNullOrEmpty(ticket.AssignedTo))
            {
                activityEn = (hasPriority) ? TicketActivity.AssignWithPriority : TicketActivity.Assign;
            }
            else if (ticket.AssignedTo.Equals(Security.CurrentUserName, StringComparison.InvariantCultureIgnoreCase))
            {
                activityEn = (hasPriority) ? TicketActivity.PassWithPriority : TicketActivity.Pass;
            }
            else
            {
                activityEn = (hasPriority) ? TicketActivity.ReAssignWithPriority : TicketActivity.ReAssign;
            }

            var rnv = new NameValueCollection();

            if (!CheckSecurityForTicketActivity(ticket, activityEn))
            {
                rnv.Add("noAuth", "User is not authorized to assign a ticket");
            }
            if (string.IsNullOrEmpty(assignTo))
            {
                rnv.Add("assignTo", "You must select a user to which you wish to assign the ticket");
            }
            if (rnv.Count > 0)
            {
                throw new RuleException(rnv);
            }
            ticket.TicketComments.Add(GetActivityComment(activityEn, comment, ticket.AssignedTo, ticket.GetNotificationSubscribers(), Security.GetUserDisplayName(ticket.AssignedTo), Security.GetUserDisplayName(assignTo), priority));

            ticket.AssignedTo = assignTo;
            ticket.LastUpdateBy = Security.CurrentUserName;
            ticket.LastUpdateDate = DateTime.Now;

            if (!string.IsNullOrEmpty(priority))
            {
                ticket.Priority = priority;
            }

            return Repository.UpdateTicket(ticket);
        }
Beispiel #13
0
        /// <summary>
        /// Takes the over ticket.
        /// </summary>
        /// <param name="ticket">The ticket.</param>
        /// <param name="userName">Name of the user taking over.</param>
        /// <param name="comment">optional comment contents.</param>
        /// <param name="priority">a priority or null if no change to priority.</param>
        /// <returns></returns>
        public bool TakeOverTicket(Ticket ticket, string comment, string priority)
        {
            if (!CheckSecurityForTicketActivity(ticket, TicketActivity.TakeOver))//no need to check TakeOverWithPriority seperately
            {
                throw new RuleException("noAuth", "User is not authorized to take over a ticket");
            }

            if (!string.IsNullOrEmpty(priority))
            {
                ticket.Priority = priority;
            }

            var fromUser = (string.IsNullOrEmpty(ticket.AssignedTo)) ? string.Empty : " from " + Security.GetUserDisplayName(ticket.AssignedTo);

            TicketComment c = (string.IsNullOrEmpty(priority)) ?
                GetActivityComment(TicketActivity.TakeOver, comment, ticket.AssignedTo, ticket.GetNotificationSubscribers(), fromUser) :
                GetActivityComment(TicketActivity.TakeOverWithPriority, comment, ticket.AssignedTo, ticket.GetNotificationSubscribers(), fromUser, priority);

            ticket.TicketComments.Add(c);
            ticket.AssignedTo = Security.CurrentUserName;
            ticket.LastUpdateBy = Security.CurrentUserName;
            ticket.LastUpdateDate = DateTime.Now;

            return Repository.UpdateTicket(ticket);
        }
Beispiel #14
0
        /// <summary>
        /// Cancels the request for more information for ticket.
        /// </summary>
        /// <param name="ticket">The ticket.</param>
        /// <param name="userName">Name of the user cancelling the request for more information.</param>
        /// <param name="comments">The comments.</param>
        /// <returns></returns>
        public bool CancelMoreInfoForTicket(Ticket ticket, string comment)
        {
            var rnv = new NameValueCollection();

            if (!CheckSecurityForTicketActivity(ticket, TicketActivity.CancelMoreInfo))
            {
                rnv.Add("noAuth", "User is not authorized to cancel the request for more information for the ticket");
            }

            if (rnv.Count > 0)
            {
                throw new RuleException(rnv);
            }

            ticket.TicketComments.Add(GetActivityComment(TicketActivity.CancelMoreInfo, comment, ticket.AssignedTo, ticket.GetNotificationSubscribers()));

            var now = DateTime.Now;
            ticket.CurrentStatus = "Active";
            ticket.CurrentStatusDate = now;
            ticket.CurrentStatusSetBy = Security.CurrentUserName;
            ticket.LastUpdateBy = Security.CurrentUserName;
            ticket.LastUpdateDate = now;

            return Repository.UpdateTicket(ticket);
        }
Beispiel #15
0
        /// <summary>
        /// Supplies more information for the ticket.
        /// </summary>
        /// <param name="ticket">The ticket.</param>
        /// <param name="userName">Name of the user supplying more information.</param>
        /// <param name="comment">The comment.</param>
        /// <param name="markActive">if set to <c>true</c> marks ticket active again.</param>
        /// <returns></returns>
        public bool SupplyMoreInfoForTicket(Ticket ticket, string comment, bool markActive)
        {
            var rnv = new NameValueCollection();

            if (!CheckSecurityForTicketActivity(ticket, TicketActivity.SupplyMoreInfo))
            {
                rnv.Add("noAuth", "User is not authorized to supply more information for the ticket");
            }
            if (string.IsNullOrEmpty(comment))
            {
                rnv.Add("comment", "A comment is required");
            }
            if (rnv.Count > 0)
            {
                throw new RuleException(rnv);
            }

            var markActiveText = (markActive) ? "and reactivated the ticket." : "without reactivating the ticket";
            ticket.TicketComments.Add(GetActivityComment(TicketActivity.SupplyMoreInfo, TicketCommentFlag.CommentNotApplicable, comment, ticket.AssignedTo, ticket.GetNotificationSubscribers(), markActiveText));

            var now = DateTime.Now;
            if (markActive)
            {
                ticket.CurrentStatus = "Active";
                ticket.CurrentStatusDate = now;
                ticket.CurrentStatusSetBy = Security.CurrentUserName;

            }

            ticket.LastUpdateBy = Security.CurrentUserName;
            ticket.LastUpdateDate = now;

            return Repository.UpdateTicket(ticket);
        }
        private void SetupActivityViewData(string activity, Ticket ticket)
        {

            ViewData.Add("activity", activity);
            //TODO: Need a more elaborate way to map activity name to display name text
            var activityDisplayName = (activity == "ActivityButtons") ? "Choose Activity" : activity.ConvertPascalCaseToFriendlyString();
            ViewData.Add("activityDisplayName", activityDisplayName);


        }
        private ActionResult PerformActivity(Ticket model, string activityName, string commentContent, params object[] args)
        {
            if (ModelState.IsValid)//if the modelstate is already invalid, don't perform the activity, just move on to re-rendering the view
            {
                try
                {
                    bool result = DoTicketActivity(activityName, model, commentContent, args);
                    if (!result)
                    {
                        throw new ApplicationException("Ticket Activity Failed");
                    }
                }
                catch (RuleException rx)
                {
                    if (rx.Errors.AllKeys.Contains("noAuth"))
                    {
                        //TODO: Authorization to perform the action failed, need to show the
                        //          error activity panel and cancel copy to model state

                    }
                    rx.CopyToModelState(ModelState, string.Empty);
                }
                catch
                {
                    ModelState.AddModelError("unknownSaveError", "Unknown error, please try again");
                }
            }
            if (ModelState.IsValid)
            {
                TempData["IsRedirectFromAjax"] = IsItReallyRedirectFromAjax();
                return RedirectToAction(MVC.TicketEditor.Display(model.TicketId, string.Empty));
            }
            else
            {
                if (IsItReallyRedirectFromAjax())
                {
                    SetupActivityViewData(activityName, model);
                    return PartialView(string.Format("~/Views/TicketEditor/Controls/{0}.ascx", activityName), model);
                }
                else
                {
                    return RedirectToAction(MVC.TicketEditor.Display(model.TicketId, string.Empty));
                }
            }
        }
Beispiel #18
0
        /// <summary>
        /// Reopen ticket.
        /// </summary>
        /// <param name="ticket">The ticket.</param>
        /// <param name="userName">Name of the user re-opening the ticket.</param>
        /// <param name="comment">The comment.</param>
        /// <param name="reopenAssignedToUser">if set to <c>true</c> reopen and assign to the reopening user.</param>
        /// <param name="reopenOwnedByUser">if set to <c>true</c> reopen and set owner to the reopening user.</param>
        /// <returns></returns>
        public bool ReOpenTicket(Ticket ticket, string comment, bool reopenAssignedToUser, bool reopenOwnedByUser)
        {
            var rnv = new NameValueCollection();
            if (!CheckSecurityForTicketActivity(ticket, TicketActivity.ReOpen))
            {
                rnv.Add("noAuth", "User is not authorized to re-open ticket");
            }
            if (string.IsNullOrEmpty(comment))
            {
                rnv.Add("comment", "A comment is required");
            }

            if (rnv.Count > 0)
            {
                throw new RuleException(rnv);
            }

            //If user is already owner, prevent "as the owner" part of event text
            if (Security.CurrentUserName.Equals(ticket.Owner, StringComparison.InvariantCultureIgnoreCase))
            {
                reopenOwnedByUser = false;
            }

            var reopenAssignedToUserText = (reopenAssignedToUser) ? " and assigned it to themself" : string.Empty;
            var reopenOwnedByUserText = (reopenOwnedByUser) ? " as the owner" : string.Empty;


            //TODO: if reopened by a user that is not help desk, and re-opener is not 
            //          the previous owner reopen with this user as the owner

            ticket.TicketComments.Add(GetActivityComment(TicketActivity.ReOpen, comment, ticket.AssignedTo, ticket.GetNotificationSubscribers(), reopenOwnedByUserText, reopenAssignedToUserText));

            ticket.AssignedTo = (reopenAssignedToUser) ? Security.CurrentUserName : null;
            if (reopenOwnedByUser)
            {
                ticket.Owner = Security.CurrentUserName;
            }

            ticket.CurrentStatus = "Active";
            ticket.CurrentStatusSetBy = Security.CurrentUserName;
            ticket.CurrentStatusDate = DateTime.Now;
            ticket.LastUpdateBy = Security.CurrentUserName;
            ticket.LastUpdateDate = ticket.CurrentStatusDate;

            return Repository.UpdateTicket(ticket);
        }
 /// <summary>
 /// Deprecated Method for adding a new object to the Tickets EntitySet. Consider using the .Add method of the associated ObjectSet&lt;T&gt; property instead.
 /// </summary>
 public void AddToTickets(Ticket ticket)
 {
     base.AddObject("Tickets", ticket);
 }
Beispiel #20
0
        /// <summary>
        /// Modifies the attachments for a ticket.
        /// </summary>
        /// <param name="ticket">The ticket.</param>
        /// <param name="userName">Name of the user modifying attachments.</param>
        /// <param name="comment">The comment.</param>
        /// <param name="attachments">The list attachment files with the desired state of the attachments</param>
        /// <returns></returns>
        public bool ModifyAttachmentsForTicket(Ticket ticket, string comment, List<TicketAttachment> attachments)
        {
            List<string> changeComments = new List<string>();

            var rnv = new NameValueCollection();
            if (!CheckSecurityForTicketActivity(ticket, TicketActivity.ModifyAttachments))
            {
                rnv.Add("noAuth", "User is not authorized to modify the ticket's attachments");
            }



            var attachmentsToRemove = new List<TicketAttachment>();

            bool attachmentsChanged = false;
            foreach (var ticketAttachment in ticket.TicketAttachments.Where(ta => !ta.IsPending || ta.IsPending && ta.UploadedBy == Security.CurrentUserName))
            {
                var attMod = attachments.SingleOrDefault(a => a.FileId == ticketAttachment.FileId);
                if (attMod == null)// an attachment on the ticket is not in the list of attachments supplied, assume it is to be removed
                {
                    attachmentsToRemove.Add(ticketAttachment);
                }
                else//attachment in modified collection, assume it is to be modified
                {
                    //TODO: the commenting here needs to be moved into the text utilities so it can deal with formatting (html vs. markdown) according to rules defined elsewhere, this is not the right place for the system to make formatting decisions. 
                    if (ticketAttachment.FileName != attMod.FileName)
                    {
                        attachmentsChanged = true;
                        if (!ticketAttachment.IsPending)//add comment about changed attachment only of !IsPending
                        {
                            
                            changeComments.Add(string.Format("changed file name from {0} to {1}", ticketAttachment.FileName, attMod.FileName));
                        }
                        ticketAttachment.FileName = attMod.FileName;
                    }
                    if (ticketAttachment.FileDescription != attMod.FileDescription)
                    {
                        attachmentsChanged = true;
                        if (!ticketAttachment.IsPending)//add comment about changed attachment only of !IsPending
                        {
                            changeComments.Add(string.Format("changed file description for file: {0}", attMod.FileName));
                        }
                        ticketAttachment.FileDescription = attMod.FileDescription;
                    }

                    if (ticketAttachment.IsPending)
                    {
                        attachmentsChanged = true;
                        changeComments.Add(string.Format("added file: {0}", attMod.FileName));
                        ticketAttachment.IsPending = false;
                    }
                }
            }
            foreach (var killAtt in attachmentsToRemove)
            {
                attachmentsChanged = true;
                changeComments.Add(string.Format("removed file: {0}", killAtt.FileName));
                Repository.RemoveAttachment(killAtt, false);
                ticket.TicketAttachments.Remove(killAtt);
            }

            if (!attachmentsChanged)
            {
                rnv.Add("attachments", "No changes to ticket's attachments were found.");
            }
            if (rnv.Count > 0)
            {
                throw new RuleException(rnv);
            }

            var ticketComment = GetActivityComment(TicketActivity.ModifyAttachments, comment, ticket.AssignedTo, ticket.GetNotificationSubscribers());
            StringBuilder sb = new StringBuilder();
            foreach (string s in changeComments)
            {
                //TODO: the replace here is a bit of a hack, need to refactor this for a more robust formatting system.
                sb.Append(string.Format("- {0}\n", s.Replace("_", @"\_")));//replace to deal with underscores in filenames & markdown formatting
            }
            if (ticketComment.Comment.Length > 0)
            {
                sb.Append("\n******\n");
                sb.Append(ticketComment.Comment);
            }
            ticketComment.Comment = sb.ToString();

            //TODO: add comment content for each change made
            ticket.TicketComments.Add(ticketComment);

            ticket.LastUpdateBy = Security.CurrentUserName;
            ticket.LastUpdateDate = DateTime.Now;

            return Repository.UpdateTicket(ticket);
        }
        /// <summary>
        /// Creates a new ticket.
        /// </summary>
        /// <param name="newTicket">The new ticket.</param>
        /// <param name="commit">if set to <c>true</c> save new ticket to DB.</param>
        /// <returns>
        /// 	<c>true</c> if the ticket is created successfully.
        /// </returns>
        public bool CreateTicket(Ticket newTicket, bool commit)
        {
            ctx.Tickets.AddObject(newTicket);
            if (commit)
            {
                ctx.SaveChanges();
                SavingTicketChanges(newTicket);

            }
            return true;
        }
Beispiel #22
0
        /// <summary>
        /// Edits the ticket.
        /// </summary>
        /// <param name="ticket">The ticket being edited with updated values.</param>
        /// <param name="comment">The comment.</param>
        /// <returns></returns>
        public bool EditTicketDetails(Ticket ticket, string comment)
        {

            var changes = Repository.GetTicketChanges(ticket);

            var rnv = new NameValueCollection();
            if (!CheckSecurityForTicketActivity(ticket, TicketActivity.EditTicketInfo))
            {
                rnv.Add("noAuth", "User is not authorized to edit ticket details");
            }

            //There are only certain fields we allow to be changed, check rules
            List<string> allowedFieldChanges = new List<string> { "Title", "Details", "Priority", "Type", "Category", "Owner", "TagList" };
            foreach (var field in changes)
            {
                if (!allowedFieldChanges.Contains(field.Key))
                {
                    rnv.Add("ticketInfo", string.Format("Changes to field {0} are not allowed", field.Key));
                }
            }

            //handle taglist changed by removing all existing tags and rebuilding them
            //NOTE: We could examine the tags and just make removals and insertions as needed, but the
            //          actual performance suffers very little and is not worth the extra effort and complexity.
            if (changes.ContainsKey("TagList"))
            {
                Repository.ClearTags(ticket, false);

                string[] tagsArr = TagUtility.GetTagsFromString(ticket.TagList);
                foreach (string tag in tagsArr)
                {
                    TicketTag tTag = new TicketTag();
                    tTag.TagName = tag;
                    ticket.TicketTags.Add(tTag);
                }
                ticket.TagList = string.Join(",", tagsArr);//in case the tags array trimmed spaces and such
            }

            rnv.Add(ValidateTicketDetailFields(ticket));//check the field rules 

            if (changes.Count < 1)
            {
                rnv.Add("ticketInfo", "No changes to ticket's details were found.");
            }

            if (rnv.Count > 0)
            {
                throw new RuleException(rnv);
            }

            var ticketComment = GetActivityComment(TicketActivity.EditTicketInfo, comment, ticket.AssignedTo, ticket.GetNotificationSubscribers());

            StringBuilder sb = new StringBuilder();
            foreach (var c in changes)
            {
                string v = null;
                PropertyInfo pi = ticket.GetType().GetProperty(c.Key);
                if (pi != null)
                {
                    v = pi.GetValue(ticket, null) as string;
                }
                if (c.Key != "Details" && c.Key != "Title" && c.Key != "TagList" && c.Key != "Owner")
                {
                    sb.Append(string.Format("- Changed {0} from \"{1}\" to \"{2}\"\n", c.Key.ConvertPascalCaseToFriendlyString(), c.Value, v));
                }
                else if (c.Key == "Owner")
                {
                    sb.Append(string.Format("- Changed {0} from \"{1}\" to \"{2}\"\n", c.Key.ConvertPascalCaseToFriendlyString(), Security.GetUserDisplayName(c.Value as string), Security.GetUserDisplayName(v)));
                }
                else //details, title, and tags are long strings so we don't include the full text of the old and new values
                {
                    sb.Append(string.Format("- Changed {0}\n", c.Key.ConvertPascalCaseToFriendlyString()));
                }
            }
            if (ticketComment.Comment.Length > 0)
            {
                sb.Append("\n******\n");
                sb.Append(ticketComment.Comment);
            }
            ticketComment.Comment = sb.ToString();

            ticket.TicketComments.Add(ticketComment);

            ticket.LastUpdateBy = Security.CurrentUserName;
            ticket.LastUpdateDate = DateTime.Now;

            return Repository.UpdateTicket(ticket);
        }
        /// <summary>
        /// Gets the list of changes for a ticket.
        /// </summary>
        /// <param name="modifiedTicket">The modified ticket.</param>
        /// <returns>
        /// A dictionary containing the fields and their original values for field that have been changed.
        /// </returns>
        public Dictionary<string, object> GetTicketChanges(Ticket modifiedTicket)
        {
            Dictionary<string, object> changes = new Dictionary<string, object>();

            var ose = ctx.ObjectStateManager.GetObjectStateEntry(modifiedTicket);

            var modProperties = ose.GetModifiedProperties();

            foreach (var p in modProperties)
            {
                if (!ose.OriginalValues[p].Equals(ose.CurrentValues[p]))
                {
                    changes.Add(p, ose.OriginalValues[p]);
                }
            }

            // THIS IS THE LINQ to SQL version - keeping for reference

            //var originalTicket = ctx.Tickets.GetOriginalEntityState(modifiedTicket);
            //ModifiedMemberInfo[] minfo = ctx.Tickets.GetModifiedMembers(modifiedTicket);
            //foreach (var info in minfo)
            //{
            //    if (info.CurrentValue != info.OriginalValue)
            //    {
            //        changes.Add(info.Member.Name, info.OriginalValue);
            //    }
            //}
            return changes;
        }
Beispiel #24
0
 /// <summary>
 /// Checks the security for ticket activity for the current user.
 /// </summary>
 /// <param name="ticket">The ticket.</param>
 /// <param name="activity">The activity.</param>
 /// <returns></returns>
 public bool CheckSecurityForTicketActivity(Ticket ticket, TicketActivity activity)
 {
     return CheckSecurityForTicketActivity(ticket, activity, Security.CurrentUserName);
 }
 private void SavingTicketChanges(Ticket ticket)
 {
     if (Saving != null)
     {
         Saving(this, new TicketEventArgs() { Ticket = ticket });
     }
 }
Beispiel #26
0
        /// <summary>
        /// Checks the security for ticket activity for the specified user.
        /// </summary>
        /// <param name="ticket">The ticket, or null if checking an operation that isn't reliant on any specific ticket's state (such as NoChange, GetTicketInfo, etc).</param>
        /// <param name="activity">The activity.</param>
        /// <param name="userName">Name of the user to check.</param>
        /// <returns></returns>
        public bool CheckSecurityForTicketActivity(Ticket ticket, TicketActivity activity, string userName)
        {
            bool isAllowed = false;

            if (Security.IsInValidTdUserRole())//short-cut whole thing if not a valid TD user role
            {
                if (ticket == null)//some ops might supply no ticket, so we can create a dummy ticket instead
                {
                    ticket = new Ticket();
                }
                bool isAssigned = (!string.IsNullOrEmpty(ticket.AssignedTo));
                bool isOpen = (ticket.CurrentStatus != "Resolved" && ticket.CurrentStatus != "Closed");
                bool isAssignedToMe = (!string.IsNullOrEmpty(ticket.AssignedTo) && ticket.AssignedTo == userName);
                bool isOwnedByMe = (ticket.Owner == userName);
                bool isMoreInfo = (ticket.CurrentStatus == "More Info");
                bool isResolved = (ticket.CurrentStatus == "Resolved");

                switch (activity)
                {
                    case TicketActivity.NoChange:
                        isAllowed = true;
                        break;
                    case TicketActivity.GetTicketInfo:
                        isAllowed = true;
                        break;
                    case TicketActivity.Create:
                        isAllowed = true;
                        break;
                    case TicketActivity.CreateOnBehalfOf:
                        isAllowed = true;
                        break;
                    case TicketActivity.ModifyAttachments:
                        isAllowed = isOpen;
                        break;
                    case TicketActivity.EditTicketInfo:
                        isAllowed = isOpen && (Security.IsTdStaff() || isOwnedByMe);
                        break;
                    case TicketActivity.AddComment:
                        isAllowed = isOpen && !isMoreInfo;
                        break;
                    case TicketActivity.SupplyMoreInfo:
                        isAllowed = isMoreInfo;
                        break;
                    case TicketActivity.Resolve:
                        isAllowed = isOpen && !isMoreInfo && isAssignedToMe;
                        break;
                    case TicketActivity.RequestMoreInfo:
                        isAllowed = isOpen && !isMoreInfo && isAssignedToMe;
                        break;
                    case TicketActivity.CancelMoreInfo:
                        isAllowed = isMoreInfo && isAssignedToMe;
                        break;
                    case TicketActivity.Close:
                        isAllowed = isResolved && isOwnedByMe;
                        break;
                    case TicketActivity.ReOpen:
                        isAllowed = !isOpen;
                        break;
                    case TicketActivity.TakeOver:
                        isAllowed = (isOpen || isResolved) && !isAssignedToMe && Security.IsTdStaff();
                        break;
                    case TicketActivity.TakeOverWithPriority:
                        isAllowed = (isOpen || isResolved) && !isAssignedToMe && Security.IsTdStaff();
                        break;
                    case TicketActivity.Assign:
                        isAllowed = (isOpen || isResolved) && Security.IsTdStaff() && !isAssigned;
                        break;
                    case TicketActivity.AssignWithPriority:
                        isAllowed = (isOpen || isResolved) && Security.IsTdStaff() && !isAssigned;
                        break;
                    case TicketActivity.ReAssign:
                        isAllowed = (isOpen || isResolved) && Security.IsTdStaff() && isAssigned && !isAssignedToMe; ;
                        break;
                    case TicketActivity.ReAssignWithPriority:
                        isAllowed = (isOpen || isResolved) && Security.IsTdStaff() && isAssigned && !isAssignedToMe; ;
                        break;
                    case TicketActivity.Pass:
                        isAllowed = (isOpen || isResolved) && Security.IsTdStaff() && isAssignedToMe;
                        break;
                    case TicketActivity.PassWithPriority:
                        isAllowed = (isOpen || isResolved) && Security.IsTdStaff() && isAssignedToMe;
                        break;
                    case TicketActivity.GiveUp:
                        isAllowed = (isOpen || isResolved) && isAssignedToMe;
                        break;
                    case TicketActivity.ForceClose:
                        isAllowed = (isOpen || isResolved) && (isAssignedToMe || isOwnedByMe) && !(isResolved && isOwnedByMe);
                        break;
                }
            }
            return isAllowed;
        }
Beispiel #27
0
        public NameValueCollection ValidateTicketDetailFields(Ticket ticket)
        {
            var rnv = new NameValueCollection();

            List<RuleException> brokenRules = new List<RuleException>();
            if (string.IsNullOrEmpty(ticket.Title))
            {
                rnv.Add("title", "A title is required");
            }
            if (string.IsNullOrEmpty(ticket.Category))
            {
                rnv.Add("category", "A category is required");
            }
            if (string.IsNullOrEmpty(ticket.Type))
            {
                rnv.Add("type", "A ticket type is required");
            }
            if (string.IsNullOrEmpty(ticket.Details))
            {
                rnv.Add("details", "Details are required");
            }
            if (string.IsNullOrEmpty(ticket.Owner))
            {
                rnv.Add("owner", "Owner is required.");
            }
            return rnv;
        }
Beispiel #28
0
        /// <summary>
        /// Creates the new ticket.
        /// </summary>
        /// <param name="newTicket">The new ticket.</param>
        /// <param name="filesToAttach">The files to attach.</param>
        /// <param name="creatorUserName">User name of the creator.</param>
        /// <param name="creatorDisplayName">Display name of the creator.</param>
        /// <param name="ownerDisplayName">Display name of the owner.</param>
        /// <returns></returns>
        public int? CreateNewTicket(Ticket newTicket)
        {
            var rnv = new NameValueCollection();

            if (!CheckSecurityForTicketActivity(null, TicketActivity.Create))// don't need to check CreateOnBehalfOf separately
            {
                rnv.Add("noAuth", "User is not authorized to create a ticket");
            }

            var now = DateTime.Now;
            newTicket.CreatedBy = Security.CurrentUserName;
            newTicket.CreatedDate = now;
            newTicket.CurrentStatus = "Active";
            newTicket.CurrentStatusDate = now;
            newTicket.CurrentStatusSetBy = Security.CurrentUserName;
            newTicket.LastUpdateBy = Security.CurrentUserName;
            newTicket.LastUpdateDate = now;

            string[] tagsArr = TagUtility.GetTagsFromString(newTicket.TagList);

            foreach (string tag in tagsArr)
            {
                TicketTag tTag = new TicketTag();
                tTag.TagName = tag;
                newTicket.TicketTags.Add(tTag);
            }

            rnv.Add(ValidateTicketDetailFields(newTicket));// enforce field rules

            if (rnv.Count > 0)
            {
                throw new RuleException(rnv);
            }

            //comment
            TicketComment openingComment = (!newTicket.Owner.Equals(Security.CurrentUserName, StringComparison.InvariantCultureIgnoreCase)) ?
                GetActivityComment(TicketActivity.CreateOnBehalfOf, TicketCommentFlag.CommentNotApplicable, null, newTicket.AssignedTo, newTicket.GetNotificationSubscribers(), Security.GetUserDisplayName(newTicket.Owner)) :
                GetActivityComment(TicketActivity.Create, TicketCommentFlag.CommentNotApplicable, null, newTicket.AssignedTo, newTicket.GetNotificationSubscribers());

            newTicket.TicketComments.Add(openingComment);

            AddAttachmentsToNewTicket(newTicket, Security.CurrentUserName);

            int? newTicketId = null;
            if (Repository.CreateTicket(newTicket, true))
            {
                newTicketId = newTicket.TicketId;
            }
            return newTicketId;
        }