...
In the AdminPortal load the Setup tab
Click on Custom Code
Click Add
Enter a Name and then paste in the code below[cce lang="C#"]
//Reference: Castle.MonoRail.Framework
//Reference: Newtonsoft.Json
//Reference: Logisense.Utility
//Reference: System.Data
using Castle.MonoRail.Framework;
using Logisense.Boss.Logic;
using Logisense.Boss.Logic.DomainModel;
using Logisense.Boss.Utility;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using Newtonsoft.Json.Linq;Code Block //Reference: Castle.MonoRail.Framework //Reference: Newtonsoft.Json //Reference: Logisense.Utility //Reference: System.Data using Castle.MonoRail.Framework; using Logisense.Boss.Logic; using Logisense.Boss.Logic.DomainModel; using Logisense.Boss.Utility; using System; using System.Collections.Generic; using System.Data; using System.Linq; using Newtonsoft.Json.Linq; namespace LogisenseKB.EventHandlers { public class CreatePackageQuestionAction : BaseTicketType, IAction { public string Name { get { return "CreatePackageQuestionAction"; } } public string Description { get { return "Triggered by a new package being added to a system, which will add 2 package profile questions"; } } public string EventCode { get { return "Package.Create"; } } public int OwnerID { get; set; } public void Run(ScriptContext context) { if (!ProfileQuestion.SearchByQuestion(TicketTypeForCreateUserPackage).Any()) { Logisense.Boss.Logic.Core.PackageProfileQuestion.GetNewQuestion(TicketTypeForCreateUserPackage, Logisense.Boss.Logic.Core.DataType.TEXT_NAME, OwnerID); } if (!ProfileQuestion.SearchByQuestion(TicketTypeForCancelUserPackage).Any()) { Logisense.Boss.Logic.Core.PackageProfileQuestion.GetNewQuestion(TicketTypeForCancelUserPackage, Logisense.Boss.Logic.Core.DataType.TEXT_NAME, OwnerID); } } } public class InitializeTicketWhenCreateAction : BaseTicketType, IAction { public string Name { get { return "InitializeTicketWhenCreateAction"; } } public string Description { get { return "Triggered by a new user package being added to a system"; } } public string EventCode { get { return "UserPackage.Create"; } } public int OwnerID { get; set; } public void Run(ScriptContext context) { var userPackage = UserPackage.GetByID(Convert.ToInt32(context["UserPackageID"])); var user = userPackage.GetUser(); var owner = user.GetActingOwner(); var ticketType = GetTicketType(TicketTypeForCreateUserPackage, GetPackageAttributeProfileAnswers(userPackage), owner); if (ticketType != default(TicketType)) { var ticketName = string.Format("Auto Generated Ticket for User Package: '{0}'", userPackage.Name); InitializeTicket(userPackage, user, owner, ticketName, ticketType); } } } public class InitializeTicketWhenCancelAction : BaseTicketType, IAction { public string Name { get { return "InitializeTicketWhenCancelAction"; } } public string Description { get { return "Triggered by a user package was cancelled"; } } public string EventCode { get { return "UserPackage.Update"; } } public int OwnerID { get; set; } public void Run(ScriptContext context) { var userPackage = UserPackage.GetByID(Convert.ToInt32(context["UserPackageID"])); var oldUserPackage = UserPackage.Deserialize((string)context["OldRow"]); var user = userPackage.GetUser(); var owner = user.GetActingOwner(); var newStatusType = userPackage.GetStatusType().Name; if (newStatusType == Logisense.Boss.Logic.Core.StatusType.CanceledName && oldUserPackage.GetStatusType().Name != newStatusType) { var packageAttributeProfileAnswers = GetPackageAttributeProfileAnswers(userPackage); var ticketTypeForCancelUserPackage = GetTicketType(TicketTypeForCancelUserPackage, packageAttributeProfileAnswers, owner); if (ticketTypeForCancelUserPackage != default(TicketType)) { var ticketTypeForCreateUserPackage = GetTicketType(TicketTypeForCreateUserPackage, packageAttributeProfileAnswers, owner); var ticketName = string.Format("Auto Generated Ticket for Cancelling the User Package: '{0}'", userPackage.Name); if (ticketTypeForCreateUserPackage != default(TicketType)) { var ticketQuery = new TicketQuery() { UserPackageID = userPackage.ID, TicketTypeID = ticketTypeForCreateUserPackage.ID, }; var existingTicket = Ticket.GetCollection(ref ticketQuery).FirstOrDefault(); if (existingTicket != default(Ticket)) { //if the user package has existing tickets with the ticketTypeForCreateUserPackage if (existingTicket.GetTicketStatus().GetTicketStatusType().Name == Logisense.Boss.Logic.Core.TicketStatusType.OpenName) { //if there is an existing open ticket, update ticket type to it EditExistingTicket((Logisense.Boss.Logic.Core.Ticket)existingTicket, ticketTypeForCancelUserPackage, owner); } else { //else the ticket has been closed, create a new one InitializeTicket(userPackage, user, owner, ticketName, ticketTypeForCancelUserPackage); } } } else { //else initialize a new ticket InitializeTicket(userPackage, user, owner, ticketName, ticketTypeForCancelUserPackage); } } } } private static void EditExistingTicket(Logisense.Boss.Logic.Core.Ticket ticket, TicketType ticketType, Owner owner) { ticket.TicketTypeID = ticketType.ID; if (!ticket.ValidateTicketTypeAndTransitions()) { Logisense.Boss.Logic.Core.Alert.Create(Logisense.Boss.Logic.Core.TicketTypeTransition.invalidTicketTypeMsg, owner.ID); } else { ticket.RawUpdate(); } } } public class BaseTicketType { protected static string TicketType { get { return "TicketType"; } } public static string TicketTypeForCreateUserPackage { get { return "Ticket Type for Creating a User Package"; } } public static string TicketTypeForCancelUserPackage { get { return "Ticket Type for Cancelling a User Package"; } } protected static void InitializeTicket(UserPackage userPackage, User user, Owner owner, string ticketName, TicketType ticketType) { var ticketCategory = owner.GetTicketCategoryCollection().FirstOrDefault(); var ticketGroup = owner.GetTicketGroupCollection().FirstOrDefault(); var ticketPriority = owner.GetTicketPriorityCollection().FirstOrDefault(); var ticketStatus = owner.GetTicketStatusCollection().FirstOrDefault(); var ticketCategoryId = ticketCategory != null ? ticketCategory.ID : int.MinValue; var ticketGroupId = ticketGroup != null ? ticketGroup.ID : int.MinValue; var ticketPriorityId = ticketPriority != null ? ticketPriority.ID : int.MinValue; var ticketStatusId = ticketStatus != null ? ticketStatus.ID : int.MinValue; var ticket = Ticket.GetNew(); ticket.Name = ticketName; ticket.Title = ticketName; ticket.TicketTypeID = ticketType.ID; ticket.OpenedBy_UserID = user.ID; ticket.RelatedTo_UserID = ticket.OpenedBy_UserID; ticket.TicketCategoryID = ticketCategoryId; ticket.TicketGroupID = ticketGroupId; ticket.TicketPriorityID = ticketPriorityId; ticket.TicketStatusID = ticketStatusId; ticket.UserID = user.ID; ticket.CreatedDate = DateTime.Now; ticket.UserPackageID = userPackage.ID; var coreTicket = (Logisense.Boss.Logic.Core.Ticket)ticket; if (coreTicket.ValidateTicketTypeAndTransitions()) { coreTicket.Create(ticketName, string.Empty, null, false); } else { Logisense.Boss.Logic.Core.Alert.Create(Logisense.Boss.Logic.Core.TicketTypeTransition.invalidTicketTypeMsg, owner.ID); } } protected static PackageAttributeProfileAnswer[] GetPackageAttributeProfileAnswers(UserPackage userPackage) { var packageAttributeProfileAnswers = userPackage.GetPackage().GetPackageAttributeProfileAnswerCollection(); return packageAttributeProfileAnswers; } protected static TicketType GetTicketType(string profileQuestion, IEnumerable<PackageAttributeProfileAnswer> packageAttributeProfileAnswers, Owner owner) { var answer = packageAttributeProfileAnswers.FirstOrDefault(x => x.GetPackageProfileQuestion().GetProfileQuestion().Name == profileQuestion); return answer != null ? owner.GetTicketTypeCollection().FirstOrDefault(x => x.Name == answer.GetProfileAnswer().Value) : default(TicketType); } } public class TicketTypeTransitionInstaller : Logisense.Boss.Logic.Core.ICustomCodeInstaller { public void Install(int ownerId) { var owner = (Logisense.Boss.Logic.Core.Owner)Owner.GetByID(ownerId); SetupReversedTicketTypeTransitions(); SetupPageExtensions(owner); } public static void SetupReversedTicketTypeTransitions() { //This SQL query will only create reversed TicketTypeTransitions that do not already exist (based on Current_TicketStatusID and Allowed_TicketStatusID //appearing in alternate order in a second row for each TicketTypeID). //NOTE: This CustomCode relies on reversed transitions being named [TransitionName] + "_Reversed", reversed transitions missing //"_Reversed" from their names will not be handled correctly and incorrect behaviour of TicketStatuses will be observed. var createdTransitions = SQLHelper.ExecuteDataTable(@" INSERT INTO TicketTypeTransition (Name, Current_TicketStatusID, Allowed_TicketStatusID, TicketGroupID, AssignedTo_UserID, TicketTypeID) OUTPUT INSERTED.ID AS TransitionID, INSERTED.Name AS TransitionName SELECT ttt1.Name + '_Reversed', ttt1.Allowed_TicketStatusID, ttt1.Current_TicketStatusID, ttt3.TicketGroupID, ttt3.AssignedTo_UserID, ttt1.TicketTypeID FROM TicketTypeTransition AS ttt1 LEFT JOIN TicketTypeTransition AS ttt2 ON --Searching for missing reversed transitions ttt2.Allowed_TicketStatusID = ttt1.Current_TicketStatusID AND ttt2.Current_TicketStatusID = ttt1.Allowed_TicketStatusID AND ttt2.TicketTypeID = ttt1.TicketTypeID LEFT JOIN TicketTypeTransition AS ttt3 ON --Searching for transitions previous to the current one, the reversed transitions will use their TicketGroupID/AssignTo_UserID ttt3.Allowed_TicketStatusID = ttt1.Current_TicketStatusID AND ttt3.TicketTypeID = ttt1.TicketTypeID WHERE ttt2.ID IS NULL GROUP BY ttt1.Name, ttt1.Allowed_TicketStatusID, ttt1.Current_TicketStatusID, ttt3.TicketGroupID, ttt3.AssignedTo_UserID, ttt1.TicketTypeID;"); foreach (DataRow transition in createdTransitions.Rows) { Log.Information("Created TicketTypeTransition '{0}' (ID: {1})", transition["TransitionName"], transition["TransitionID"]); } } private static void SetupPageExtensions(Owner owner) { var script = string.Format(@" var ticketId = document.getElementById('Ticket.id').value; setLoadSession(); ByPassIfTicketTypeHasNoTransition(); // Description: if the ticket has ticket type with transition configured, update input values and the logic behind the select button function ByPassIfTicketTypeHasNoTransition(){{ var query = 'AJAXBypassIfTicketTypeHasNoTransition.rails?ticketId=' + ticketId; new Ajax.Request(query, {{ asynchronous: false, evalScripts: true, onSuccess: function (response) {{ if(response.responseJSON.None == false){{ //action starts as Load when the page loads and changes to Previous or Next based on what button was clicked var action = '{2}'; if (sessionStorage.previousTicketTypeTransition == 'true') {{ action = '{0}'; }} else if (sessionStorage.nextTicketTypeTransition == 'true') {{ action = '{1}'; }} //TS-1697 Editing the ticket without clicking the next or previous button shouldn't populate inputs var ajaxUpdateInput = action != '{2}'; updateTicketField(action, 'TicketStatus', ajaxUpdateInput); updateTicketField(action, 'User', ajaxUpdateInput); updateTicketField(action, 'TicketGroup', ajaxUpdateInput); UpdateButton(ajaxUpdateInput); new Form.Element.Observer('Ticket.TicketStatus', 0.100, function (element, value) {{ //These need a separate action since they're changed by the TicketStatus dropdown updateTicketField('{3}', 'User', true); updateTicketField('{3}', 'TicketGroup', true); UpdateButton(false); }}); }} }} }}) }} function updateTicketField(action, field, updateInput) {{ var ticketField = field != 'TicketGroup' ? 'Ticket.' + field : 'TicketGroup.TicketGroup'; if (updateInput === true){{ ajaxUpdateInput(action, ticketField, ticketField); }} if (ticketField == 'Ticket.TicketStatus'){{ jQuery('#TicketStatus_select').attr('href', ""javascript: ajaxLaunchCustomTicketStatusSelectWindow();""); }} }} function UpdateButton(multipleTransitionsDisableButtons) {{ var ticketStatusName = document.getElementById('Ticket.TicketStatus').value; var query = 'AJAXUpdateButton.rails?ticketId=' + ticketId + '&ticketStatusName=' + ticketStatusName; new Ajax.Request(query, {{ asynchronous: false, evalScripts: true, onSuccess: function (response) {{ if ($('nextTicketTypeTransition') != null){{ $('nextTicketTypeTransition').remove(); }} if ($('previousTicketTypeTransition') != null){{ $('previousTicketTypeTransition').remove(); }} if (response){{ clearSession(); if (response.responseJSON.Previous || response.responseJSON.MultiplePrevious && !multipleTransitionsDisableButtons){{ jQuery(""#SaveButton"").before(""<input name='previousTicketTypeTransition' id='previousTicketTypeTransition' type='submit' value='{0}' onclick='setPreviousSession(); return thisCheckvalidation(); '> ""); }} if (response.responseJSON.Next || response.responseJSON.MultipleNext && !multipleTransitionsDisableButtons){{ jQuery(""#SaveButton"").before(""<input name='nextTicketTypeTransition' id='nextTicketTypeTransition' type='submit' value='{1}' onclick='setNextSession(); return thisCheckvalidation(); '> ""); }} }} }} }}); }} function showInvalidError(){{ if ($('errorMsgDiv') != null){{ $('errorMsgDiv').remove(); }} jQuery(""#EditForm"").before(""<div class='error' id='errorMsgDiv'>Multiple valid transitions were found, please choose one status from the drop down list.</div> ""); }} function thisCheckvalidation(){{ return checkvalidation(document.getElementById('EditForm'), 0); }} function setPreviousSession(){{ sessionStorage.previousTicketTypeTransition = true; sessionStorage.removeItem(""nextTicketTypeTransition""); sessionStorage.removeItem(""load""); }} function setNextSession(){{ sessionStorage.nextTicketTypeTransition = true; sessionStorage.removeItem(""previousTicketTypeTransition""); sessionStorage.removeItem(""load""); }} function setLoadSession(){{ if (sessionStorage.previousTicketTypeTransition != 'true' && sessionStorage.nextTicketTypeTransition != 'true') {{ sessionStorage.load = true; }} }} function clearSession(){{ sessionStorage.removeItem(""nextTicketTypeTransition""); sessionStorage.removeItem(""previousTicketTypeTransition""); sessionStorage.removeItem(""load""); }} function ajaxUpdateInput(action, target, selector) {{ var ticketStatusName = document.getElementById('Ticket.TicketStatus').value; var ticketStatusId = document.getElementById('Ticket.TicketStatusID').value; var query = 'AJAXUpdateInput.rails?ticketId=' + ticketId + '¤tTicketStatusId=' + ticketStatusId + '&newTicketStatusName=' + ticketStatusName + '&action=' + action + '&target=' + target; new Ajax.Request(query, {{ asynchronous: true, evalScripts: true, onSuccess: function (response) {{ if (response){{ if (response.responseJSON.Message == '{4}') {{ //if restictive document.getElementById(selector).value = response.responseJSON.Value; }} else if (response.responseJSON.Message == '{5}') {{ //if invalid document.getElementById(selector).value = ''; showInvalidError(); }} }} }} }}); }} // Description: restrict selection lists function ajaxLaunchCustomTicketStatusSelectWindow() {{ //We only create a custom select list for TicketStatus, everything else should use the standard select list var field = 'TicketStatus'; var target = 'Ticket.' + field; var d = document.getElementById(target + 'selectdiv'); var element = document.getElementById(target); d.innerHTML = 'Loading' + '...'; d.style.marginLeft = jQuery('#Ticket\\.TicketStatus').css('margin-left'); d.style.width = element.offsetWidth + 'px'; d.style.display = 'block'; window.currentlyVisiblePopup = d; window.currentlyVisiblePopup.style.visibility = 'visible'; var query = 'AJAXCustomSelect.rails?ticketId=' + ticketId + '&target=' + target; new Ajax.Request(query, {{ asynchronous: true, evalScripts: true, onSuccess: function (response) {{ if (response.responseText == 'no match') {{ // empty the selection d.innerHTML = ''; }} else if (response.responseText == '') {{ // non restricted selection LaunchSelectWindow(field, 'Name', target, '', 0); }} else {{ // restricted selection d.innerHTML = response.responseText; }} }} }}); }}", TransitionAction.Previous, TransitionAction.Next, TransitionAction.Load, TransitionAction.ManualChange, GetFieldMessage.Restrictive, GetFieldMessage.Invalid); const string PAGE_EXTENSION_NAME = "TicketTypeTransitionPageExtension"; try { var pageExtensionQuery = new PageExtensionQuery { OwnerID = owner.ID, Name = PAGE_EXTENSION_NAME }; if (!PageExtension.GetCollection(ref pageExtensionQuery).Any()) { var pageExtension = new Logisense.Boss.Logic.Core.PageExtension() { OwnerID = owner.ID, Name = PAGE_EXTENSION_NAME, Page = "ticket/edit", Script = script }; pageExtension.Create(); } } catch (Exception ex) { throw new ApplicationException(string.Format("Error while creating/updating page extension: '{0}'", PAGE_EXTENSION_NAME), ex); } } } public enum TransitionAction { Previous, Next, Load, ManualChange } public enum GetFieldMessage { NonRestrictive, Restrictive, Invalid } public class AJAXUpdateButton : IDynamicAction { public void Execute(Controller controller) { var ticketId = controller.Params["ticketId"]; var ticketStatusName = controller.Params["ticketStatusName"]; var next = false; var multipleNext = false; var previous = false; var multiplePrevious = false; if (!string.IsNullOrWhiteSpace(ticketId) && ticketId != int.MinValue.ToString()) { var ticket = (Logisense.Boss.Logic.Core.Ticket)Ticket.GetByID(Convert.ToInt32(ticketId)); var ticketTypeTransitions = ticket.GetTicketType().GetTicketTypeTransitionCollection(); var countNextTransitions = ticketTypeTransitions.Count(x => x.GetCurrent_TicketStatus().Name == ticketStatusName && !x.Name.Contains("_Reversed")); var countPreviousTransitions = ticketTypeTransitions.Count(x => x.GetCurrent_TicketStatus().Name == ticketStatusName && x.Name.Contains("_Reversed")); if (countNextTransitions == 1) { next = true; } else if (countNextTransitions > 1) { multipleNext = true; } if (countPreviousTransitions == 1) { previous = true; } else if (countPreviousTransitions > 1) { multiplePrevious = true; } } var json = new JObject { {"Next", next}, {"MultipleNext", multipleNext}, {"Previous", previous}, {"MultiplePrevious", multiplePrevious}, {"None", true} }; controller.Response.ContentType = "application/json"; controller.RenderText(json.ToString()); } } public class AJAXCustomSelect : BaseTicketType, IDynamicAction { public void Execute(Controller controller) { var ticketId = controller.Params["ticketId"]; var noRestriction = false; var results = GetFieldSelection(ticketId, ref noRestriction); if (!results.Any()) { // render "no match": empty the ticket status' selection if no previous or next status has been found // render empty string: load the non restricted selections var noMatch = !noRestriction ? "no match" : string.Empty; controller.RenderText(noMatch); } else { //Target will always be Ticket.TicketStatus var target = controller.Params["target"]; var listResults = new ListResults { objects = results.Values.ToArray(), RowCount = results.Count }; controller.PropertyBag["results"] = listResults; controller.PropertyBag["target"] = target; //Select.vm requires that $table be set, it should be last portion of the target controller.PropertyBag["table"] = target.Split('.').Last(); controller.RenderSharedView("select"); } } public class ListResults { private object[] _objects; public object[] objects { get { return _objects; } set { _objects = value; } } private int _RowCount; public int RowCount { get { return _RowCount; } set { _RowCount = value; } } } /// <summary> /// Get a dictionary of restricted value for ticket field /// </summary> /// <param name="ticketId">string: ID of the ticket to act on</param> /// <param name="noRestriction">ref bool: output true means the ticket type doesn't restrict ticket status</param> /// <returns></returns> private static Dictionary<string, object> GetFieldSelection(string ticketId, ref bool noRestriction) { var ticket = (Logisense.Boss.Logic.Core.Ticket)Ticket.GetByID(Convert.ToInt32(ticketId)); var results = new Dictionary<string, object>(); if (ticket.TicketTypeID != int.MinValue) { var ticketType = ticket.GetTicketType(); var transitionCollection = ticketType.GetTicketTypeTransitionCollection(); if (!transitionCollection.Any()) { noRestriction = true; } else { //Get all transitions that start on the current status to populate the TicketStatus dropdown var possibleTransitions = transitionCollection.Where(x => x.Current_TicketStatusID == ticket.TicketStatusID).ToList(); foreach (var transition in possibleTransitions) { if (transition.Allowed_TicketStatusID != int.MinValue) { var item = transition.GetAllowed_TicketStatus(); AddToDictionary(ref results, item, item.Name); } if (transition.Current_TicketStatusID != int.MinValue) { var item = transition.GetCurrent_TicketStatus(); AddToDictionary(ref results, item, item.Name); } } } } return results; } private static void AddToDictionary(ref Dictionary<string, object> dictionary, object item, string name) { if (item != null & !dictionary.ContainsKey(name)) { dictionary.Add(name, item); } } } public class AJAXUpdateInput : BaseTicketType, IDynamicAction { public void Execute(Controller controller) { var ticketId = controller.Params["ticketId"]; var newTicketStatusName = controller.Params["newTicketStatusName"]; var currentTicketStatusId = controller.Params["currentTicketStatusId"]; var action = controller.Params["action"]; var target = controller.Params["target"]; var fieldValue = GetFieldValue(action, target, ticketId, GetCorrectTicketStatusId(target, currentTicketStatusId, newTicketStatusName)); controller.Response.ContentType = "application/json"; controller.RenderText(fieldValue); } /// <summary> /// Get the value of a ticket field which is restricted by the ticket type transition /// </summary> /// <param name="action">string: "previous" or "next"</param> /// <param name="target">string: the id of the ticket field that needs to be restricted</param> /// <param name="ticketId">string: ID of the ticket to act on</param> /// <param name="ticketStatusId">string: ticketStatusId from the form</param> /// <returns>string: the value of restricted ticket field</returns> private static string GetFieldValue(string action, string target, string ticketId, int ticketStatusId) { var ticket = (Logisense.Boss.Logic.Core.Ticket)Ticket.GetByID(Convert.ToInt32(ticketId)); var returnString = string.Empty; // if returnString is empty, no restriction on this field var jsonMessage = GetFieldMessage.NonRestrictive; if (ticket.TicketTypeID != int.MinValue) { var ticketType = ticket.GetTicketType(); var transitionCollection = ticketType.GetTicketTypeTransitionCollection(); if (transitionCollection.Any()) { var allowedTransitions = ticket.GetNextTicketTypeTransitions(ticket.TicketStatusID, transitionCollection); //ticket.GetNextTicketTypeTransitions() will return both a forward and return transition for the Allowed_TicketStatusID, differentiate using "_Reversed" if (action == TransitionAction.Next.ToString()) { allowedTransitions = allowedTransitions.Where(x => !x.Name.Contains("_Reversed")).ToList(); } else if (action == TransitionAction.Previous.ToString()) { allowedTransitions = allowedTransitions.Where(x => x.Name.Contains("_Reversed")).ToList(); } else if (action == TransitionAction.ManualChange.ToString()) { //This will only happen when the form observer on TicketStatus triggers an update for User and TicketGroup allowedTransitions = allowedTransitions.Where(x => x.Allowed_TicketStatusID == ticketStatusId).ToList(); if (ticketStatusId == ticket.TicketStatusID) { //TicketStatus was moved back to the original value, since TicketGroup and User are //associated to the allowed TicketStatus just grab the first transition that matches allowedTransitions = transitionCollection.Where(x => x.Allowed_TicketStatusID == ticketStatusId).Take(1).ToList(); } } var firstPageLoad = action == TransitionAction.Load.ToString(); if (allowedTransitions.Count == 1 || firstPageLoad) { //If the page is being loaded for the first time we don't care what transitions exist just yet, we're going to load in ticket details instead var ticketTransition = !firstPageLoad ? allowedTransitions.Single() : default(TicketTypeTransition); // get field value switch (target) { case "Ticket.User": if (firstPageLoad) { returnString = ticket.GetUser().Name; } else if (ticketTransition != null && ticketTransition.AssignedTo_UserID != int.MinValue) { returnString = ticketTransition.GetAssignedTo_User().Name; } break; case "Ticket.TicketStatus": if (firstPageLoad) { returnString = ticket.GetTicketStatus().Name; } else if (ticketTransition != null) { //If the TicketStatusID from the form doesn't match the ticket it means the form has already transitioned forward, //don't update the TicketStatus returnString = ticket.TicketStatusID != ticketStatusId ? ticketTransition.GetCurrent_TicketStatus().Name : ticketTransition.GetAllowed_TicketStatus().Name; } break; case "TicketGroup.TicketGroup": if (firstPageLoad) { returnString = ViewTicketGroupWithOwner.GetByID(ticket.TicketGroupID).Name; } else if (ticketTransition != null && ticketTransition.TicketGroupID != int.MinValue) { returnString = ViewTicketGroupWithOwner.GetByID(ticketTransition.TicketGroupID).Name; } break; default: returnString = string.Empty; break; } if (returnString != string.Empty) { jsonMessage = GetFieldMessage.Restrictive; } } else if (allowedTransitions.Count > 1) { jsonMessage = GetFieldMessage.Invalid; } } } var json = new JObject { { "Message", jsonMessage.ToString() }, { "Value", returnString } }; return json.ToString(); } private static int GetCorrectTicketStatusId(string target, string currentTicketStatusId, string newTicketStatusName) { var ticketStatusId = Convert.ToInt32(currentTicketStatusId); if (ticketStatusId > 0 && target != "Ticket.TicketStatus") { //TicketStatus requires currentTicketStatusId (related to ticket), but TicketGroup and User require newTicketStatusName (current value in form) TicketStatus ticketStatus; try { ticketStatus = TicketStatus.GetByID(ticketStatusId); } catch (RecordNotFoundException) { //Couldn't find a TicketStatus for the passed in ID, all we can really do is pass back the original ID return ticketStatusId; } var ticketStatusQuery = new TicketStatusQuery { OwnerID = ticketStatus.OwnerID, Name = newTicketStatusName }; ticketStatus = TicketStatus.GetCollection(ref ticketStatusQuery).SingleOrDefault(); if (ticketStatus != null) { ticketStatusId = ticketStatus.ID; } } return ticketStatusId; } } public class AJAXBypassIfTicketTypeHasNoTransition : IDynamicAction { public void Execute(Controller controller) { var ticketId = controller.Params["ticketId"]; var none = true; if (!string.IsNullOrWhiteSpace(ticketId) && ticketId != int.MinValue.ToString()) { var ticket = Ticket.GetByID(Convert.ToInt32(ticketId)); if (ticket.TicketTypeID != int.MinValue) { var ticketTypeTransitions = ticket.GetTicketType().GetTicketTypeTransitionCollection(); if (ticketTypeTransitions.Any()) { none = false; } } } var json = new JObject { { "None", none } }; controller.Response.ContentType = "application/json"; controller.RenderText(json.ToString()); } } }
Click Save
...