Пример #1
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);
        }
Пример #2
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);
        }
Пример #3
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);
        }
Пример #4
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);
        }
Пример #5
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);
        }
Пример #6
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);
        }
Пример #7
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);
        }
Пример #8
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);
        }
Пример #9
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);
        }
Пример #10
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);
        }
Пример #11
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;
        }