2692 lines
114 KiB
C#
2692 lines
114 KiB
C#
using C4IT.FASD.Base;
|
|
using C4IT.FASD.Cockpit.Communication;
|
|
using C4IT.MultiLanguage;
|
|
using F4SD_AdaptableIcon.Enums;
|
|
using FasdDesktopUi.Basics.Helper;
|
|
using FasdDesktopUi.Basics.Models;
|
|
using FasdDesktopUi.Basics.Services.ProtocollService;
|
|
using FasdDesktopUi.Pages.TicketCompletion;
|
|
using MaterialIcons;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.ComponentModel;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Data;
|
|
using System.Windows.Input;
|
|
using System.Windows.Media;
|
|
using static C4IT.Logging.cLogManager;
|
|
|
|
namespace FasdDesktopUi.Basics.UserControls
|
|
{
|
|
public partial class CloseCaseDialogWithTicket : UserControl
|
|
{
|
|
#region Fields & Properties
|
|
private readonly Dictionary<string, string> _errors = new Dictionary<string, string>();
|
|
|
|
private readonly IValueConverter _languageConverter = new Converter.LanguageDefinitionsConverter();
|
|
|
|
private readonly List<Window> _openedWindows = new List<Window>();
|
|
|
|
private readonly cF4sdApiSearchResultRelation _newTicketRelation = new cF4sdApiSearchResultRelation()
|
|
{
|
|
id = Guid.NewGuid(),
|
|
DisplayName = cMultiLanguageSupport.GetItem("Header.Create.Ticket"),
|
|
Type = enumF4sdSearchResultClass.Ticket,
|
|
Identities = null,
|
|
Infos = new Dictionary<string, string> { [TicketInfoKeys.Special] = TicketSpecialValues.TicketCreation }
|
|
};
|
|
|
|
private readonly cF4sdApiSearchResultRelation _selectTicketRelation = new cF4sdApiSearchResultRelation()
|
|
{
|
|
id = Guid.NewGuid(),
|
|
DisplayName = cMultiLanguageSupport.GetItem("Header.Select.Ticket"),
|
|
Type = enumF4sdSearchResultClass.Ticket,
|
|
Identities = null,
|
|
Infos = new Dictionary<string, string> { [TicketInfoKeys.Special] = TicketSpecialValues.TicketSelect }
|
|
};
|
|
|
|
private readonly cF4sdApiSearchResultRelation _noTicketRelation = new cF4sdApiSearchResultRelation()
|
|
{
|
|
DisplayName = cMultiLanguageSupport.GetItem("Header.Skip.Ticket"),
|
|
Type = enumF4sdSearchResultClass.Ticket,
|
|
Identities = null,
|
|
Infos = new Dictionary<string, string> { [TicketInfoKeys.Special] = TicketSpecialValues.NoTicket }
|
|
};
|
|
|
|
private readonly cF4sdApiSearchResultRelation _removeAffectedAssetEntry = new cF4sdApiSearchResultRelation()
|
|
{
|
|
DisplayName = cMultiLanguageSupport.GetItem("Dialog.CloseCase.RemoveAffectedAssetEntry"),
|
|
Type = enumF4sdSearchResultClass.Computer,
|
|
Identities = null,
|
|
Infos = new Dictionary<string, string> { [TicketInfoKeys.Special] = TicketSpecialValues.RemoveAffectedAssetEntry }
|
|
};
|
|
|
|
private const string CategoryTableNamePrimary = "M42Wpm-Ticket-Categories";
|
|
private const string CategoryTableNameLegacy = "M42Wpm-Ticket-CloseCase-Categories";
|
|
private string activeCategoryTableName = CategoryTableNamePrimary;
|
|
|
|
private static readonly Brush SharedValidationBorderBrush = CreateValidationBrush();
|
|
private static readonly Brush DefaultTextBoxBorderBrush = CreateDefaultTextBoxBorderBrush();
|
|
private static Brush CreateValidationBrush()
|
|
{
|
|
var brush = new SolidColorBrush(Color.FromRgb(0xF5, 0x7C, 0x73));
|
|
if (brush.CanFreeze)
|
|
brush.Freeze();
|
|
return brush;
|
|
}
|
|
private static Brush CreateDefaultTextBoxBorderBrush()
|
|
{
|
|
var brush = new SolidColorBrush(Color.FromRgb(0xDE, 0xE2, 0xE6));
|
|
if (brush.CanFreeze)
|
|
brush.Freeze();
|
|
return brush;
|
|
}
|
|
|
|
private ObservableCollection<HierarchicalSelectionItem> categoryHierarchy = new ObservableCollection<HierarchicalSelectionItem>();
|
|
private readonly Dictionary<string, HierarchicalSelectionItem> categoryLookup = new Dictionary<string, HierarchicalSelectionItem>(StringComparer.OrdinalIgnoreCase);
|
|
private bool isCategoryLoading;
|
|
private Brush defaultCategoryBorderBrush;
|
|
private Brush defaultQuickTicketBorderBrush;
|
|
private readonly Brush validationErrorBrush = SharedValidationBorderBrush;
|
|
private Brush defaultTicketStatusBorderBrush;
|
|
private Thickness? defaultCategoryBorderThickness;
|
|
private Thickness? defaultQuickTicketBorderThickness;
|
|
private Thickness? defaultTicketStatusBorderThickness;
|
|
|
|
public bool AreCaseNotesMandatory =>
|
|
cFasdCockpitConfig.Instance?.Global?.TicketConfiguration?.NotesMandatory ?? false;
|
|
|
|
private static class TicketInfoKeys
|
|
{
|
|
public const string ActivityType = "ActivityType";
|
|
public const string Asset = "Asset";
|
|
public const string ServiceId = "ServiceId";
|
|
public const string ServiceName = "ServiceName";
|
|
public const string StatusId = "StatusId";
|
|
public const string Category = "Category";
|
|
public const string Summary = "Summary";
|
|
public const string Special = "Special";
|
|
}
|
|
|
|
private static class TicketInfoValues
|
|
{
|
|
public const string ActivityTypeTicket = "SPSActivityTypeTicket";
|
|
}
|
|
|
|
private static class TicketSpecialValues
|
|
{
|
|
public const string TicketCreation = "TicketCreation";
|
|
public const string TicketSelect = "TicketSelect";
|
|
public const string NoTicket = "NoTicket";
|
|
public const string RemoveAffectedAssetEntry = "RemoveAffectedAssetEntry";
|
|
public const string RemoveAffectedServiceEntry = "RemoveAffectedServiceEntry";
|
|
}
|
|
|
|
private static class ValidationPropertyNames
|
|
{
|
|
public const string SelectedTicket = nameof(SelectedTicket);
|
|
public const string SelectedCategory = nameof(SelectedCategory);
|
|
public const string QuickTicketSelection = nameof(QuickTicketSelection);
|
|
public const string TicketSummaryTextBox = nameof(TicketSummaryTextBox);
|
|
public const string TicketStatusCombobox = nameof(TicketStatusCombobox);
|
|
public const string CaseNotesPreview = nameof(CaseNotesPreview);
|
|
public const string SolutionTextbox = "SolutionTextbox";
|
|
public const string ErrorTypeValue = "ErrorTypeValue";
|
|
public const string ReminderDate = "ReminderDate";
|
|
public const string HoldComment = "HoldComment";
|
|
public const string SelectedRoleAndPerson = "SelectedRoleAndPerson";
|
|
public const string ForwardComment = "ForwardComment";
|
|
}
|
|
|
|
private bool TryGetSelectedTicketInfo(string key, out string value)
|
|
{
|
|
value = null;
|
|
return SelectedTicket?.Infos != null && SelectedTicket.Infos.TryGetValue(key, out value);
|
|
}
|
|
|
|
private string GetSelectedTicketInfoOrDefault(string key) =>
|
|
TryGetSelectedTicketInfo(key, out var value) ? value : null;
|
|
|
|
private static bool TryGetSpecialValue(cF4sdApiSearchResultRelation relation, out string specialValue)
|
|
{
|
|
specialValue = null;
|
|
return relation?.Infos != null && relation.Infos.TryGetValue(TicketInfoKeys.Special, out specialValue);
|
|
}
|
|
|
|
private static bool RelationHasSpecialInfo(cF4sdApiSearchResultRelation relation, string expectedSpecialValue) =>
|
|
TryGetSpecialValue(relation, out var specialValue) &&
|
|
string.Equals(specialValue, expectedSpecialValue, StringComparison.OrdinalIgnoreCase);
|
|
|
|
public bool IsTicket
|
|
{
|
|
get
|
|
{
|
|
return TryGetSelectedTicketInfo(TicketInfoKeys.ActivityType, out var activityType)
|
|
&& string.Equals(activityType, TicketInfoValues.ActivityTypeTicket, StringComparison.OrdinalIgnoreCase);
|
|
}
|
|
}
|
|
|
|
private bool _isTicketIntegrationActive;
|
|
public bool IsTicketIntegrationActive
|
|
{
|
|
get => _isTicketIntegrationActive;
|
|
private set => _isTicketIntegrationActive = value;
|
|
}
|
|
|
|
public bool EnableHoldTicketAction
|
|
{
|
|
get { return (bool)GetValue(EnableHoldTicketActionProperty); }
|
|
set { SetValue(EnableHoldTicketActionProperty, value); }
|
|
}
|
|
|
|
public static readonly DependencyProperty EnableHoldTicketActionProperty =
|
|
DependencyProperty.Register("EnableHoldTicketAction", typeof(bool), typeof(CloseCaseDialogWithTicket), new PropertyMetadata(true));
|
|
|
|
public bool EnableCloseTicketAction
|
|
{
|
|
get { return (bool)GetValue(EnableCloseTicketActionProperty); }
|
|
set { SetValue(EnableCloseTicketActionProperty, value); }
|
|
}
|
|
|
|
public static readonly DependencyProperty EnableCloseTicketActionProperty =
|
|
DependencyProperty.Register("EnableCloseTicketAction", typeof(bool), typeof(CloseCaseDialogWithTicket), new PropertyMetadata(true));
|
|
|
|
public bool EnableSaveTicketAction
|
|
{
|
|
get { return (bool)GetValue(EnableSaveTicketActionProperty); }
|
|
set { SetValue(EnableSaveTicketActionProperty, value); }
|
|
}
|
|
|
|
public static readonly DependencyProperty EnableSaveTicketActionProperty =
|
|
DependencyProperty.Register("EnableSaveTicketAction", typeof(bool), typeof(CloseCaseDialogWithTicket), new PropertyMetadata(true));
|
|
|
|
public bool EnableForwardTicketAction
|
|
{
|
|
get { return (bool)GetValue(EnableForwardTicketActionProperty); }
|
|
set { SetValue(EnableForwardTicketActionProperty, value); }
|
|
}
|
|
|
|
public static readonly DependencyProperty EnableForwardTicketActionProperty =
|
|
DependencyProperty.Register("EnableForwardTicketAction", typeof(bool), typeof(CloseCaseDialogWithTicket), new PropertyMetadata(true));
|
|
|
|
private cF4sdApiSearchResultRelation _selectedTicket;
|
|
|
|
public cF4sdApiSearchResultRelation SelectedTicket
|
|
{
|
|
get => _selectedTicket;
|
|
set
|
|
{
|
|
_selectedTicket = value;
|
|
//SelectedComputer = null;
|
|
|
|
UpdateSelectedTicketControl();
|
|
CheckAffectedAssetIsCurrentAsset();
|
|
CheckAffectedServiceIsCurrentService();
|
|
UpdateAffectedAssetLabel();
|
|
UpdateAffectedServiceLabel();
|
|
UpdateAffectedAssetComboBox();
|
|
ShowAssetWarningTicketAction = IsTicket;
|
|
ValidateProperty(ValidationPropertyNames.SelectedTicket);
|
|
EnableHoldTicketAction = _selectedTicket == null || SelectedTicket == _selectTicketRelation || selectedTicketIsNewTicket;
|
|
if (TryGetSelectedTicketInfo(TicketInfoKeys.StatusId, out var statusIdString) &&
|
|
Enum.TryParse(statusIdString, true, out enumTicketStatus statusId))
|
|
{
|
|
EnableHoldTicketAction = statusId != enumTicketStatus.OnHold;
|
|
}
|
|
TrySelectTicketCategoryFromTicketInfos();
|
|
}
|
|
}
|
|
|
|
private bool selectedTicketIsNewTicket
|
|
{
|
|
get => SelectedTicket == _newTicketRelation;
|
|
}
|
|
|
|
#region SelectedComputer DependencyProperty
|
|
public static readonly DependencyProperty SelectedComputerProperty =
|
|
DependencyProperty.Register("SelectedComputer", typeof(cF4sdApiSearchResultRelation), typeof(CloseCaseDialogWithTicket), new PropertyMetadata(null));
|
|
|
|
public cF4sdApiSearchResultRelation SelectedComputer
|
|
{
|
|
get { return (cF4sdApiSearchResultRelation)GetValue(SelectedComputerProperty); }
|
|
set
|
|
{
|
|
SetValue(SelectedComputerProperty, value);
|
|
CheckAffectedAssetIsCurrentAsset();
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
public bool ShowAssetWarningTicketAction
|
|
{
|
|
get { return (bool)GetValue(ShowAssetWarningTicketActionProperty); }
|
|
set { SetValue(ShowAssetWarningTicketActionProperty, value); }
|
|
}
|
|
|
|
public static readonly DependencyProperty ShowAssetWarningTicketActionProperty =
|
|
DependencyProperty.Register("ShowAssetWarningTicketAction", typeof(bool), typeof(CloseCaseDialogWithTicket), new PropertyMetadata(false));
|
|
|
|
#region SelectedService DependencyProperty
|
|
|
|
public static readonly DependencyProperty SelectedServiceProperty = DependencyProperty.Register(
|
|
"SelectedService",
|
|
typeof(KeyValuePair<string, object>),
|
|
typeof(CloseCaseDialogWithTicket),
|
|
new PropertyMetadata(default(KeyValuePair<string, object>), OnSelectedServiceChanged));
|
|
|
|
public KeyValuePair<string, object> SelectedService
|
|
{
|
|
get { return (KeyValuePair<string, object>)GetValue(SelectedServiceProperty); }
|
|
set
|
|
{
|
|
SetValue(SelectedServiceProperty, value);
|
|
CheckAffectedServiceIsCurrentService();
|
|
}
|
|
}
|
|
private static void OnSelectedServiceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
{
|
|
var control = (CloseCaseDialogWithTicket)d;
|
|
var newValue = (KeyValuePair<string, object>)e.NewValue;
|
|
control.CheckAffectedServiceIsCurrentService();
|
|
}
|
|
#endregion
|
|
|
|
#region SelectedCategory DependencyProperty
|
|
|
|
public static readonly DependencyProperty SelectedCategoryProperty = DependencyProperty.Register(
|
|
"SelectedCategory",
|
|
typeof(HierarchicalSelectionItem),
|
|
typeof(CloseCaseDialogWithTicket),
|
|
new PropertyMetadata(null, OnSelectedCategoryChanged));
|
|
|
|
public HierarchicalSelectionItem SelectedCategory
|
|
{
|
|
get { return (HierarchicalSelectionItem)GetValue(SelectedCategoryProperty); }
|
|
set { SetValue(SelectedCategoryProperty, value); }
|
|
}
|
|
|
|
private static void OnSelectedCategoryChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
{
|
|
if (d is CloseCaseDialogWithTicket instance)
|
|
{
|
|
instance.LogSelectedCategoryChanged(e.NewValue as HierarchicalSelectionItem);
|
|
instance.ValidateProperty(ValidationPropertyNames.SelectedCategory);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
private void LogSelectedCategoryChanged(HierarchicalSelectionItem category)
|
|
{
|
|
try
|
|
{
|
|
var fullPath = category == null
|
|
? "<null>"
|
|
: string.IsNullOrWhiteSpace(category.FullPath) ? category.DisplayName : category.FullPath;
|
|
var id = category == null || string.IsNullOrWhiteSpace(category.Id) ? "<null>" : category.Id;
|
|
LogEntry($"[CloseCaseDialog] SelectedCategory updated -> {fullPath} (Id={id})");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogException(ex);
|
|
}
|
|
}
|
|
|
|
public bool ShowServiceHasBeenChangedWarning
|
|
{
|
|
get { return ServiceHasBeenChanged && SetOrUpdateServiceInTicket; }
|
|
}
|
|
public bool ShowAssetHasBeenChangedWarning
|
|
{
|
|
get { return AssetHasBeenChanged && SetOrUpdateComputerInTicket; }
|
|
}
|
|
|
|
#region AssetHasBeenChanged DependencyProperty
|
|
|
|
public static readonly DependencyProperty AssetHasBeenChangedProperty =
|
|
DependencyProperty.Register("AssetHasBeenChanged", typeof(bool), typeof(CloseCaseDialogWithTicket), new PropertyMetadata(false));
|
|
|
|
public bool AssetHasBeenChanged
|
|
{
|
|
get { return (bool)GetValue(AssetHasBeenChangedProperty); }
|
|
set { SetValue(AssetHasBeenChangedProperty, value); }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region SetOrUpdateComputerInTicket DependencyProperty
|
|
|
|
public static readonly DependencyProperty SetOrUpdateComputerInTicketProperty =
|
|
DependencyProperty.Register("SetOrUpdateComputerInTicket", typeof(bool), typeof(CloseCaseDialogWithTicket), new PropertyMetadata(true, OnSetOrUpdateComputerInTicketChanged));
|
|
|
|
private static void OnSetOrUpdateComputerInTicketChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
{
|
|
if (d is CloseCaseDialogWithTicket instance)
|
|
instance.CheckAffectedAssetIsCurrentAsset();
|
|
}
|
|
|
|
public bool SetOrUpdateComputerInTicket
|
|
{
|
|
get { return (bool)GetValue(SetOrUpdateComputerInTicketProperty); }
|
|
set { SetValue(SetOrUpdateComputerInTicketProperty, value); }
|
|
}
|
|
|
|
#endregion
|
|
|
|
private bool _skipTicketPillSelected;
|
|
|
|
public bool SkipTicketPillSelected
|
|
{
|
|
get { return _skipTicketPillSelected; }
|
|
set { _skipTicketPillSelected = value; }
|
|
}
|
|
|
|
private bool _newTicketPillSelected;
|
|
|
|
public bool NewTicketPillSelected
|
|
{
|
|
get { return _newTicketPillSelected; }
|
|
set
|
|
{
|
|
_newTicketPillSelected = value;
|
|
ValidateProperty(ValidationPropertyNames.SelectedTicket);
|
|
|
|
}
|
|
}
|
|
|
|
#region SetOrUpdateServiceInTicket DependencyProperty
|
|
|
|
public static readonly DependencyProperty SetOrUpdateServiceInTicketProperty =
|
|
DependencyProperty.Register("SetOrUpdateServiceInTicket", typeof(bool), typeof(CloseCaseDialogWithTicket), new PropertyMetadata(false, OnSetOrUpdateServiceInTicketChanged));
|
|
|
|
private static void OnSetOrUpdateServiceInTicketChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
{
|
|
if (d is CloseCaseDialogWithTicket instance)
|
|
instance.CheckAffectedServiceIsCurrentService();
|
|
}
|
|
|
|
public bool SetOrUpdateServiceInTicket
|
|
{
|
|
get { return (bool)GetValue(SetOrUpdateServiceInTicketProperty); }
|
|
set { SetValue(SetOrUpdateServiceInTicketProperty, value); }
|
|
}
|
|
#endregion
|
|
|
|
#region ServiceHasBeenChanged DependencyProperty
|
|
|
|
public static readonly DependencyProperty ServiceHasBeenChangedProperty =
|
|
DependencyProperty.Register("ServiceHasBeenChanged", typeof(bool), typeof(CloseCaseDialogWithTicket), new PropertyMetadata(false));
|
|
|
|
public bool ServiceHasBeenChanged
|
|
{
|
|
get { return (bool)GetValue(ServiceHasBeenChangedProperty); }
|
|
set { SetValue(ServiceHasBeenChangedProperty, value); }
|
|
}
|
|
|
|
#endregion
|
|
|
|
public static readonly DependencyProperty ComputerRelationsProperty =
|
|
DependencyProperty.Register("ComputerRelations", typeof(List<cF4sdApiSearchResultRelation>), typeof(CloseCaseDialogWithTicket), new PropertyMetadata(new List<cF4sdApiSearchResultRelation>(), OnComputerRelationsChanged));
|
|
|
|
private static void OnComputerRelationsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
{
|
|
if (d is CloseCaseDialogWithTicket instance)
|
|
{
|
|
//instance.CheckAffectedAssetIsCurrentAsset();
|
|
}
|
|
}
|
|
|
|
public List<cF4sdApiSearchResultRelation> ComputerRelations
|
|
{
|
|
get { return (List<cF4sdApiSearchResultRelation>)GetValue(ComputerRelationsProperty); }
|
|
set { SetValue(ComputerRelationsProperty, value); }
|
|
}
|
|
|
|
public bool SupportNotepad { get; private set; } = false;
|
|
|
|
public static EventHandler<bool> TicketNotepadChanged { get; set; }
|
|
|
|
#region DataProvider
|
|
|
|
public cSupportCaseDataProvider DataProvider
|
|
{
|
|
get { return (cSupportCaseDataProvider)GetValue(DataProviderProperty); }
|
|
set { SetValue(DataProviderProperty, value); }
|
|
}
|
|
|
|
public static readonly DependencyProperty DataProviderProperty =
|
|
DependencyProperty.Register("DataProvider", typeof(cSupportCaseDataProvider), typeof(CloseCaseDialogWithTicket), new PropertyMetadata(null, DataProviderChanged));
|
|
|
|
private static async void DataProviderChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
if (!(d is CloseCaseDialogWithTicket me))
|
|
return;
|
|
|
|
|
|
me.SelectedTicket = me.SelectedTicket ?? me._selectTicketRelation;
|
|
|
|
me.UpdateSelectedTicketControl();
|
|
me.UpdateTicketSelection();
|
|
|
|
me.AddCopyTemplates();
|
|
me.UpdateAffectedAssetLabel();
|
|
me.UpdateAffectedServiceLabel();
|
|
me.UpdateAffectedAssetComboBox();
|
|
|
|
me.ServiceSelectionControl.SearchDataChanged = me.HandleServiceSearchDataChanged;
|
|
me.ServiceSelectionControl.ParentElement = me.MainStack;
|
|
me.ServiceSelectionControl.ParentIndex = me.MainStack.Children.IndexOf(me.ServiceSelectionControl);
|
|
|
|
me.AddNewOrExistingOrNoneTicketSelection();
|
|
me.UpdateCaseNotesPreview();
|
|
me.UpdateTicketComponentVisibility();
|
|
await me.InitializeCategorySelectionAsync();
|
|
await me.UpdateQuickCallsComboBoxAsync();
|
|
me.ValidateProperty(ValidationPropertyNames.SelectedCategory);
|
|
me.ValidateProperty(ValidationPropertyNames.QuickTicketSelection);
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
string lastServiceSearch = string.Empty;
|
|
|
|
private TicketCompletion parentWindow;
|
|
|
|
public CloseCaseDialogWithTicket()
|
|
{
|
|
InitializeComponent();
|
|
this.Unloaded += CloseCaseDialogWithTicket_Unloaded;
|
|
this.Loaded += CloseCaseDialogWithTicket_Loaded;
|
|
defaultCategoryBorderBrush = CategoryValidationBorder?.BorderBrush?.CloneCurrentValue();
|
|
defaultQuickTicketBorderBrush = QuickTicketValidationBorder?.BorderBrush?.CloneCurrentValue();
|
|
defaultTicketStatusBorderBrush = TicketStatusValidationBorder?.BorderBrush?.CloneCurrentValue();
|
|
if (validationErrorBrush is Freezable freezableBrush && freezableBrush.CanFreeze)
|
|
freezableBrush.Freeze();
|
|
|
|
DependencyPropertyDescriptor dpd =
|
|
DependencyPropertyDescriptor.FromProperty(TextBlock.TextProperty, typeof(TextBlock));
|
|
|
|
dpd?.AddValueChanged(CaseNotesPreview, TicketCaseNotesTextBlock_TextChanged);
|
|
|
|
SupportNotepad = true;
|
|
}
|
|
|
|
private void CloseCaseDialogWithTicket_Loaded(object sender, RoutedEventArgs e)
|
|
{
|
|
Window _parentWindow = Window.GetWindow(this);
|
|
|
|
if (!(_parentWindow is TicketCompletion _msgBox))
|
|
return;
|
|
|
|
_parentWindow.Closing += ParentWindow_Closing;
|
|
parentWindow = _msgBox;
|
|
parentWindow.SetButtonStateYes(false, "Initial gesperrt.");
|
|
parentWindow.SetButtonStateNo(true, cMultiLanguageSupport.GetItem("Dialog.CloseCase.Cancel"));
|
|
|
|
ValidateProperty(ValidationPropertyNames.TicketSummaryTextBox);
|
|
ValidateProperty(ValidationPropertyNames.TicketStatusCombobox);
|
|
ValidateProperty(ValidationPropertyNames.CaseNotesPreview);
|
|
ValidateProperty(ValidationPropertyNames.SelectedCategory);
|
|
ValidateProperty(ValidationPropertyNames.QuickTicketSelection);
|
|
}
|
|
private void CloseCaseDialogWithTicket_Unloaded(object sender, RoutedEventArgs e)
|
|
{
|
|
Window parentWindow = Window.GetWindow(this);
|
|
if (parentWindow != null)
|
|
{
|
|
parentWindow.Closing -= ParentWindow_Closing;
|
|
}
|
|
}
|
|
private void ParentWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
|
|
{
|
|
foreach (SelectionPill pill in NewOrExistingOrNoneTicketWrap.Children.OfType<SelectionPill>())
|
|
{
|
|
SelectionPill.RemovePill(pill);
|
|
}
|
|
foreach (SelectionPill pill in CopyTemplateWrap.Children.OfType<SelectionPill>())
|
|
{
|
|
SelectionPill.RemovePill(pill);
|
|
}
|
|
}
|
|
protected override void OnInitialized(EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
base.OnInitialized(e);
|
|
IsTicketIntegrationActive = cFasdCockpitCommunicationBase.CockpitUserInfo?.Roles?.Any(role => string.Equals(role, "Cockpit.TicketAgent", StringComparison.OrdinalIgnoreCase)) ?? false;
|
|
cSupportCaseDataProvider.CaseNotesChanged += (sender, args) => UpdateCaseNotesPreview();
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private void UpdateAffectedAssetLabel()
|
|
{
|
|
var computerName = GetSelectedTicketInfoOrDefault(TicketInfoKeys.Asset);
|
|
|
|
var binding = new Binding
|
|
{
|
|
Converter = _languageConverter,
|
|
ConverterParameter = NewTicketPillSelected || string.IsNullOrEmpty(computerName) ? "Dialog.CloseCase.SetAffectedAssetLabel" : "Dialog.CloseCase.UpdateAffectedAssetLabel"
|
|
};
|
|
|
|
SetOrUpdateComputerInTicketLabel.SetBinding(TextBlock.TextProperty, binding);
|
|
}
|
|
private void UpdateAffectedServiceLabel()
|
|
{
|
|
var serviceId = GetSelectedTicketInfoOrDefault(TicketInfoKeys.ServiceId);
|
|
|
|
var binding = new Binding
|
|
{
|
|
Converter = _languageConverter,
|
|
ConverterParameter = NewTicketPillSelected || string.IsNullOrEmpty(serviceId) || serviceId == Guid.Empty.ToString() ? "Dialog.CloseCase.SetAffectedServiceLabel" : "Dialog.CloseCase.UpdateAffectedServiceLabel"
|
|
};
|
|
|
|
SetOrUpdateServiceInTicketLabel.SetBinding(TextBlock.TextProperty, binding);
|
|
}
|
|
|
|
private bool checkTicketActive()
|
|
{
|
|
var _retVal = IsTicketIntegrationActive;
|
|
if (cFasdCockpitCommunicationBase.Instance.IsDemo())
|
|
_retVal = DataProvider.HealthCardDataHelper?.HealthCardRawData?.Tables?.ContainsKey("M42Wpm-User-NewTicket") ?? false;
|
|
return _retVal;
|
|
}
|
|
|
|
private void UpdateTicketComponentVisibility()
|
|
{
|
|
try
|
|
{
|
|
if (DataProvider is null)
|
|
return;
|
|
|
|
var _isVisible = checkTicketActive() && !_skipTicketPillSelected;
|
|
|
|
TicketSelectionCategory.Visibility = _isVisible ? Visibility.Visible : Visibility.Collapsed;
|
|
StatusSelectionBorder.Visibility = _isVisible ? Visibility.Visible : Visibility.Collapsed;
|
|
CopyDisclaimerTextBox.Visibility = _isVisible ? Visibility.Collapsed : Visibility.Visible;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
}
|
|
|
|
private UIElement GetTicketUiElement(cF4sdApiSearchResultRelation ticketRelation)
|
|
{
|
|
try
|
|
{
|
|
Border outputBorder = new Border();
|
|
outputBorder.MouseLeftButtonUp += TicketRelation_MouseLeftButtonUp;
|
|
outputBorder.TouchDown += TicketRelation_TouchDown;
|
|
|
|
outputBorder.SetResourceReference(StyleProperty, "Menu.SubCategory");
|
|
outputBorder.Tag = ticketRelation;
|
|
|
|
Grid contentGrid = new Grid();
|
|
outputBorder.Child = contentGrid;
|
|
contentGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Auto) });
|
|
contentGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) });
|
|
|
|
AdaptableIcon.AdaptableIcon ticketIcon = new AdaptableIcon.AdaptableIcon() { SelectedInternIcon = enumInternIcons.f4sd_outline };
|
|
|
|
if (RelationHasSpecialInfo(ticketRelation, TicketSpecialValues.TicketCreation))
|
|
{
|
|
ticketIcon.SelectedInternIcon = enumInternIcons.misc_plus;
|
|
}
|
|
else if (RelationHasSpecialInfo(ticketRelation, TicketSpecialValues.NoTicket))
|
|
{
|
|
ticketIcon.SelectedMaterialIcon = MaterialIconType.ic_block;
|
|
}
|
|
else if (ticketRelation.Infos.TryGetValue(TicketInfoKeys.StatusId, out string ticketStatusId))
|
|
{
|
|
Enum.TryParse(ticketStatusId, true, out enumTicketStatus ticketStatus);
|
|
|
|
switch (ticketStatus)
|
|
{
|
|
case enumTicketStatus.New:
|
|
case enumTicketStatus.InProgress:
|
|
case enumTicketStatus.OnHold:
|
|
ticketIcon.SelectedMaterialIcon = MaterialIconType.ic_drafts;
|
|
break;
|
|
case enumTicketStatus.Closed:
|
|
ticketIcon.SelectedMaterialIcon = MaterialIconType.ic_mail;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ticketIcon.SelectedMaterialIcon = MaterialIconType.ic_mail;
|
|
}
|
|
|
|
contentGrid.Children.Add(ticketIcon);
|
|
StackPanel ticketTextStack = new StackPanel() { Margin = new Thickness(15, 0, 15, 0), VerticalAlignment = VerticalAlignment.Center, IsHitTestVisible = false };
|
|
Grid.SetColumn(ticketTextStack, 1);
|
|
contentGrid.Children.Add(ticketTextStack);
|
|
|
|
Border ticketNameBorder = new Border() { ClipToBounds = true };
|
|
ticketTextStack.Children.Add(ticketNameBorder);
|
|
|
|
TextBlock ticketNameTextBlock = new TextBlock() { Text = ticketRelation.DisplayName, TextTrimming = TextTrimming.CharacterEllipsis };
|
|
ticketNameBorder.Child = ticketNameTextBlock;
|
|
|
|
Border ticketDescriptionBorder = new Border() { ClipToBounds = true };
|
|
ticketTextStack.Children.Add(ticketDescriptionBorder);
|
|
|
|
TextBlock ticketDescriptionTextBlock = null;
|
|
if (ticketRelation.Infos.TryGetValue(TicketInfoKeys.Summary, out string ticketSummary))
|
|
{
|
|
ticketDescriptionTextBlock = new TextBlock() { Text = ticketSummary, TextTrimming = TextTrimming.CharacterEllipsis, FontWeight = FontWeights.UltraLight };
|
|
ticketDescriptionBorder.Child = ticketDescriptionTextBlock;
|
|
}
|
|
|
|
outputBorder.MouseEnter += (sender, e) =>
|
|
{
|
|
try
|
|
{
|
|
cUtility.SetTickerTextAnimation(ticketNameTextBlock, ticketNameBorder);
|
|
|
|
if (ticketDescriptionTextBlock != null)
|
|
cUtility.SetTickerTextAnimation(ticketDescriptionTextBlock, ticketDescriptionBorder);
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
};
|
|
outputBorder.MouseLeave += (sender, e) =>
|
|
{
|
|
try
|
|
{
|
|
ticketNameTextBlock.TextTrimming = TextTrimming.CharacterEllipsis;
|
|
ticketNameTextBlock.BeginAnimation(MarginProperty, null);
|
|
|
|
ticketNameBorder.ClearValue(WidthProperty);
|
|
ticketNameTextBlock.ClearValue(WidthProperty);
|
|
|
|
if (ticketDescriptionTextBlock != null)
|
|
{
|
|
ticketDescriptionTextBlock.TextTrimming = TextTrimming.CharacterEllipsis;
|
|
ticketDescriptionTextBlock.BeginAnimation(MarginProperty, null);
|
|
}
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
};
|
|
|
|
|
|
return outputBorder;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private void UpdateSelectedTicketControl()
|
|
{
|
|
try
|
|
{
|
|
if (SelectedTicket is null)
|
|
return;
|
|
|
|
TicketIcon.SelectedInternIcon = null;
|
|
TicketIcon.SelectedMaterialIcon = null;
|
|
TicketTextBlock.Text = SelectedTicket.DisplayName;
|
|
|
|
if (SelectedTicket.Infos.TryGetValue(TicketInfoKeys.Summary, out var ticketSummary))
|
|
TicketSummaryTextBox.Text = ticketSummary;
|
|
else
|
|
TicketSummaryTextBox.Text = string.Empty;
|
|
|
|
if (RelationHasSpecialInfo(SelectedTicket, TicketSpecialValues.TicketCreation))
|
|
{
|
|
TicketIcon.SelectedInternIcon = enumInternIcons.misc_plus;
|
|
}
|
|
else if (RelationHasSpecialInfo(SelectedTicket, TicketSpecialValues.NoTicket))
|
|
{
|
|
TicketIcon.SelectedMaterialIcon = MaterialIconType.ic_block;
|
|
}
|
|
else if (SelectedTicket.Infos.TryGetValue(TicketInfoKeys.StatusId, out string ticketStatusId))
|
|
{
|
|
Enum.TryParse(ticketStatusId, true, out enumTicketStatus ticketStatus);
|
|
|
|
switch (ticketStatus)
|
|
{
|
|
case enumTicketStatus.New:
|
|
case enumTicketStatus.InProgress:
|
|
case enumTicketStatus.OnHold:
|
|
TicketIcon.SelectedMaterialIcon = MaterialIconType.ic_drafts;
|
|
break;
|
|
case enumTicketStatus.Closed:
|
|
TicketIcon.SelectedMaterialIcon = MaterialIconType.ic_mail;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TicketIcon.SelectedMaterialIcon = MaterialIconType.ic_mail;
|
|
}
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
}
|
|
|
|
private void CheckAffectedAssetIsCurrentAsset()
|
|
{
|
|
|
|
try
|
|
{
|
|
WarningAssetHasBeenChanged.DataContext = this;
|
|
Binding visibilityBinding = new Binding(nameof(ShowAssetHasBeenChangedWarning))
|
|
{
|
|
Converter = new BooleanToVisibilityConverter(),
|
|
};
|
|
if (DataProvider == null) return;
|
|
|
|
var computerName = GetSelectedTicketInfoOrDefault(TicketInfoKeys.Asset);
|
|
if (string.IsNullOrEmpty(computerName) || SelectedComputer == null)
|
|
{
|
|
AssetHasBeenChanged = false;
|
|
}
|
|
else
|
|
{
|
|
AssetHasBeenChanged = !SelectedComputer.DisplayName.Equals(computerName, StringComparison.OrdinalIgnoreCase);
|
|
}
|
|
WarningAssetHasBeenChanged.SetBinding(VisibilityProperty, visibilityBinding);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
LogException(e);
|
|
}
|
|
}
|
|
|
|
private void CheckAffectedServiceIsCurrentService()
|
|
{
|
|
|
|
try
|
|
{
|
|
WarningServiceHasBeenChanged.DataContext = this;
|
|
Binding visibilityBinding = new Binding(nameof(ShowServiceHasBeenChangedWarning))
|
|
{
|
|
Converter = new BooleanToVisibilityConverter(),
|
|
};
|
|
if (DataProvider == null) return;
|
|
|
|
var service = GetSelectedTicketInfoOrDefault(TicketInfoKeys.ServiceId);
|
|
if (string.IsNullOrEmpty(service) || service == Guid.Empty.ToString() || SelectedService.Value == null)
|
|
{
|
|
ServiceHasBeenChanged = false;
|
|
}
|
|
else
|
|
{
|
|
ServiceHasBeenChanged = !SelectedService.Value.ToString().Equals(service, StringComparison.OrdinalIgnoreCase);
|
|
}
|
|
WarningServiceHasBeenChanged.SetBinding(VisibilityProperty, visibilityBinding);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
LogException(e);
|
|
}
|
|
}
|
|
|
|
private void UpdateAffectedAssetComboBox()
|
|
{
|
|
try
|
|
{
|
|
if (DataProvider?.CaseRelations.TryGetValue(enumFasdInformationClass.Computer, out var computerRelationsTemp) != true)
|
|
return;
|
|
ComputerRelations = new List<cF4sdApiSearchResultRelation>(computerRelationsTemp);
|
|
var currentlySelectedId = DataProvider.Identities.FirstOrDefault(identity => identity.Class == enumFasdInformationClass.Computer)?.Id;
|
|
var computerName = GetSelectedTicketInfoOrDefault(TicketInfoKeys.Asset);
|
|
|
|
|
|
// Direktes Hinzufügen von Standardoptionen
|
|
var defaultOptions = new List<cF4sdApiSearchResultRelation>();
|
|
|
|
// Hinzufügen basierend auf der Verfügbarkeit eines ausgewählten Elements
|
|
if (SelectedTicket != _newTicketRelation && !string.IsNullOrEmpty(computerName))
|
|
{
|
|
var stringTemplate = cMultiLanguageSupport.GetItem("Dialog.CloseCase.RemoveAffectedAssetEntry");
|
|
_removeAffectedAssetEntry.DisplayName = string.Format(stringTemplate, computerName);
|
|
defaultOptions.AddRange(new[] { _removeAffectedAssetEntry });
|
|
}
|
|
else
|
|
{
|
|
ComputerRelations.Remove(_removeAffectedAssetEntry);
|
|
}
|
|
var matchingRelation = ComputerRelations.FirstOrDefault(relation => relation.DisplayName == computerName);
|
|
|
|
if (matchingRelation != null && !selectedTicketIsNewTicket)
|
|
{
|
|
ComputerRelations.Remove(matchingRelation);
|
|
}
|
|
ComputerRelations = ComputerRelations.Concat(defaultOptions).ToList();
|
|
|
|
var currentlySelectedComputer = DataProvider.Identities.FirstOrDefault(identity => identity.Class == enumFasdInformationClass.Computer);
|
|
if (currentlySelectedComputer != null)
|
|
SelectedComputer = ComputerRelations.FirstOrDefault(c => c.id == currentlySelectedComputer.Id);
|
|
else if (ComputerSelection.Items.Count > 0)
|
|
ComputerSelection.SelectedIndex = 0;
|
|
|
|
if (currentlySelectedComputer == null || ComputerRelations.Any(x => RelationHasSpecialInfo(x, TicketSpecialValues.RemoveAffectedAssetEntry)))
|
|
SetOrUpdateComputerInTicket = false;
|
|
if (NewTicketPillSelected)
|
|
SetOrUpdateComputerInTicket = true;
|
|
|
|
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
LogException(e);
|
|
}
|
|
}
|
|
|
|
|
|
private async void HandleServiceSearchDataChanged(object sender, cF4sdHealthSelectionDataRequest e) => await UpdateServiceSelectionControlAsync(e);
|
|
|
|
private async Task UpdateServiceSelectionControlAsync(cF4sdHealthSelectionDataRequest requestData)
|
|
{
|
|
|
|
try
|
|
{
|
|
string adDnUser = string.Empty;
|
|
|
|
if (!cFasdCockpitCommunicationBase.Instance.IsDemo())
|
|
{
|
|
if (DataProvider.NamedParameterEntries.TryGetValue("ad-dn-User", out var adDnUserParameter) &&
|
|
!string.IsNullOrEmpty(adDnUserParameter.GetValue()))
|
|
{
|
|
adDnUser = adDnUserParameter.GetValue();
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
requestData.Identities = DataProvider.Identities;
|
|
requestData.Table = "M42Wpm-Ticket-CloseCase-Services";
|
|
requestData.FilterParams = new List<string> { adDnUser };
|
|
requestData.ResetFilter = ServiceSelectionControl.ResetFilter;
|
|
|
|
if (string.IsNullOrEmpty(lastServiceSearch) || !lastServiceSearch.Equals(requestData.Search, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
var resServiceCount = await cFasdCockpitCommunicationBase.Instance.GetPagedDataCount(requestData);
|
|
ServiceSelectionControl.TotalItemCount = resServiceCount;
|
|
lastServiceSearch = requestData.Search;
|
|
}
|
|
|
|
var serviceData = await cFasdCockpitCommunicationBase.Instance.GetPagedData(requestData);
|
|
var servicesList = GetServiceSelectionData(serviceData);
|
|
|
|
var service = GetSelectedTicketInfoOrDefault(TicketInfoKeys.ServiceId);
|
|
var serviceName = GetSelectedTicketInfoOrDefault(TicketInfoKeys.ServiceName);
|
|
if (!string.IsNullOrEmpty(service) && Guid.Empty.ToString() != service)
|
|
{
|
|
|
|
servicesList.Add(new KeyValuePair<string, object>(string.Format(cMultiLanguageSupport.GetItem("Dialog.CloseCase.RemoveAffectedServiceEntry"), serviceName), TicketSpecialValues.RemoveAffectedServiceEntry));
|
|
var itemToRemove = servicesList.FirstOrDefault(item => item.Value is string && (string)item.Value == service);
|
|
if (!itemToRemove.Equals(default(KeyValuePair<string, object>)))
|
|
{
|
|
servicesList.Remove(itemToRemove);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var itemToRemove = servicesList.FirstOrDefault(x => string.Equals(x.Value.ToString(), TicketSpecialValues.RemoveAffectedServiceEntry, StringComparison.OrdinalIgnoreCase));
|
|
if (itemToRemove.Key != null)
|
|
{
|
|
servicesList.Remove(itemToRemove);
|
|
}
|
|
}
|
|
ServiceSelectionControl.ItemData = servicesList;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
}
|
|
|
|
private ObservableCollection<KeyValuePair<string, object>> GetServiceSelectionData(cF4SDHealthCardRawData.cHealthCardTable dataTable)
|
|
{
|
|
try
|
|
{
|
|
if (dataTable is null || dataTable.Name != "M42Wpm-Ticket-CloseCase-Services")
|
|
return null;
|
|
|
|
if (!dataTable.Columns.TryGetValue("id", out var idColumn))
|
|
return null;
|
|
|
|
dataTable.Columns.TryGetValue("Name", out var nameColumn);
|
|
|
|
var zippedKeyValuePairs = idColumn.Values.Zip(nameColumn.Values, (id, display) => new KeyValuePair<string, object>(display.ToString(), id));
|
|
|
|
return new ObservableCollection<KeyValuePair<string, object>>(zippedKeyValuePairs);
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private async Task InitializeCategorySelectionAsync()
|
|
{
|
|
if (isCategoryLoading)
|
|
return;
|
|
|
|
try
|
|
{
|
|
if (DataProvider == null || CategorySelectionControl == null)
|
|
return;
|
|
|
|
isCategoryLoading = true;
|
|
|
|
var tableCandidates = new[] { CategoryTableNamePrimary, CategoryTableNameLegacy };
|
|
bool initialized = false;
|
|
|
|
foreach (var tableName in tableCandidates)
|
|
{
|
|
if (await TryPopulateCategoryHierarchyAsync(tableName))
|
|
{
|
|
activeCategoryTableName = tableName;
|
|
initialized = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (initialized)
|
|
{
|
|
CategorySelectionControl.ItemsSource = categoryHierarchy;
|
|
TrySelectTicketCategoryFromTicketInfos();
|
|
}
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
isCategoryLoading = false;
|
|
ValidateProperty(ValidationPropertyNames.SelectedCategory);
|
|
}
|
|
}
|
|
|
|
private async Task<bool> TryPopulateCategoryHierarchyAsync(string tableName)
|
|
{
|
|
try
|
|
{
|
|
const int defaultPageSize = 250;
|
|
|
|
var requestData = new cF4sdHealthSelectionDataRequest
|
|
{
|
|
Identities = DataProvider.Identities,
|
|
Table = tableName,
|
|
Page = 0,
|
|
PageSize = defaultPageSize,
|
|
Search = string.Empty
|
|
};
|
|
|
|
var totalCount = await cFasdCockpitCommunicationBase.Instance.GetPagedDataCount(requestData);
|
|
var effectivePageSize = requestData.PageSize > 0 ? requestData.PageSize : defaultPageSize;
|
|
var pageCount = Math.Max(1, (int)Math.Ceiling((double)totalCount / Math.Max(1, effectivePageSize)));
|
|
|
|
var flatItems = new Dictionary<string, HierarchicalSelectionItem>(StringComparer.OrdinalIgnoreCase);
|
|
|
|
for (int pageIndex = 0; pageIndex < pageCount; pageIndex++)
|
|
{
|
|
requestData.Page = pageIndex;
|
|
requestData.PageSize = effectivePageSize;
|
|
|
|
var categoryTable = await cFasdCockpitCommunicationBase.Instance.GetPagedData(requestData);
|
|
bool rowAdded = false;
|
|
|
|
foreach (var item in ConvertCategoryTable(categoryTable))
|
|
{
|
|
if (string.IsNullOrWhiteSpace(item.Id))
|
|
continue;
|
|
|
|
flatItems[item.Id] = item;
|
|
rowAdded = true;
|
|
}
|
|
|
|
if (!rowAdded && categoryTable == null)
|
|
return false;
|
|
}
|
|
|
|
var hierarchy = HierarchicalSelectionItem.BuildTree(flatItems.Values);
|
|
if (hierarchy == null || hierarchy.Count == 0)
|
|
return false;
|
|
|
|
categoryHierarchy = hierarchy;
|
|
UpdateCategoryLookup();
|
|
return true;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private IEnumerable<HierarchicalSelectionItem> ConvertCategoryTable(cF4SDHealthCardRawData.cHealthCardTable dataTable)
|
|
{
|
|
if (dataTable == null || dataTable.Columns == null)
|
|
yield break;
|
|
|
|
if (!dataTable.Columns.TryGetValue("id", out var idColumn))
|
|
yield break;
|
|
|
|
if (!dataTable.Columns.TryGetValue("Name", out var nameColumn))
|
|
yield break;
|
|
|
|
cF4SDHealthCardRawData.cHealthCardTableColumn parentIdColumn = null;
|
|
cF4SDHealthCardRawData.cHealthCardTableColumn parentNameColumn = null;
|
|
if (!dataTable.Columns.TryGetValue("parentValue", out parentIdColumn))
|
|
dataTable.Columns.TryGetValue("Parent_Value", out parentIdColumn);
|
|
if (!dataTable.Columns.TryGetValue("parent", out parentNameColumn))
|
|
dataTable.Columns.TryGetValue("Parent", out parentNameColumn);
|
|
|
|
for (int index = 0; index < idColumn.Values.Count; index++)
|
|
{
|
|
var id = idColumn.Values[index]?.ToString();
|
|
if (string.IsNullOrWhiteSpace(id))
|
|
continue;
|
|
|
|
var displayName = index < nameColumn.Values.Count ? nameColumn.Values[index]?.ToString() : string.Empty;
|
|
|
|
string parentId = null;
|
|
if (parentIdColumn != null && index < parentIdColumn.Values.Count)
|
|
parentId = parentIdColumn.Values[index]?.ToString();
|
|
|
|
if (Guid.TryParse(parentId, out var parsedParentId) && parsedParentId == Guid.Empty)
|
|
parentId = null;
|
|
|
|
var parentDisplayName = parentNameColumn != null && index < parentNameColumn.Values.Count
|
|
? parentNameColumn.Values[index]?.ToString()
|
|
: null;
|
|
|
|
yield return new HierarchicalSelectionItem
|
|
{
|
|
Id = id,
|
|
DisplayName = string.IsNullOrWhiteSpace(displayName) ? parentDisplayName ?? id : displayName,
|
|
ParentId = parentId,
|
|
ParentDisplayName = parentDisplayName
|
|
};
|
|
}
|
|
}
|
|
|
|
private void UpdateCategoryLookup()
|
|
{
|
|
categoryLookup.Clear();
|
|
|
|
if (categoryHierarchy == null)
|
|
return;
|
|
|
|
foreach (var node in categoryHierarchy.SelectMany(item => item.SelfAndDescendants()))
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(node.Id))
|
|
categoryLookup[node.Id] = node;
|
|
}
|
|
}
|
|
|
|
private void TrySelectTicketCategoryFromTicketInfos()
|
|
{
|
|
try
|
|
{
|
|
if (SelectedTicket?.Infos == null)
|
|
{
|
|
SelectedCategory = null;
|
|
return;
|
|
}
|
|
|
|
if (!SelectedTicket.Infos.TryGetValue(TicketInfoKeys.Category, out var categoryId) || string.IsNullOrWhiteSpace(categoryId))
|
|
{
|
|
SelectedCategory = null;
|
|
return;
|
|
}
|
|
|
|
if (categoryLookup.TryGetValue(categoryId, out var categoryNode))
|
|
SelectedCategory = categoryNode;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
}
|
|
|
|
private Guid? GetSelectedCategoryGuid()
|
|
{
|
|
if (SelectedCategory == null || string.IsNullOrWhiteSpace(SelectedCategory.Id))
|
|
return null;
|
|
|
|
if (Guid.TryParse(SelectedCategory.Id, out var categoryGuid))
|
|
return categoryGuid;
|
|
|
|
return null;
|
|
}
|
|
|
|
private async Task UpdateQuickCallsComboBoxAsync()
|
|
{
|
|
try
|
|
{
|
|
cF4sdHealthSelectionDataRequest requestData = new cF4sdHealthSelectionDataRequest
|
|
{
|
|
Identities = DataProvider.Identities,
|
|
Table = "M42Wpm-Ticket-QuickCalls"
|
|
};
|
|
|
|
var resultCount = await cFasdCockpitCommunicationBase.Instance.GetPagedDataCount(requestData);
|
|
var quickCallsTable = await cFasdCockpitCommunicationBase.Instance.GetPagedData(requestData);
|
|
|
|
if (quickCallsTable == null) return;
|
|
|
|
if (!quickCallsTable.Columns.TryGetValue("Name", out var namesColumn) ||
|
|
!quickCallsTable.Columns.TryGetValue("id", out var idsColumn))
|
|
{
|
|
return;
|
|
}
|
|
|
|
var quickCallListe = new List<QuickCallEntry>();
|
|
|
|
for (int i = 0; i < idsColumn.Values.Count; i++)
|
|
{
|
|
var id = idsColumn.Values[i].ToString();
|
|
var name = namesColumn.Values[i].ToString();
|
|
|
|
quickCallListe.Add(new QuickCallEntry
|
|
{
|
|
ID = id,
|
|
DisplayName = name
|
|
});
|
|
}
|
|
|
|
QuickTicketSelection.ItemsSource = quickCallListe;
|
|
|
|
QuickTicketSelection.SelectedItem = quickCallListe
|
|
.FirstOrDefault(x => x.ID == "7bbe64e2-94d0-ee11-4285-00155d010a04");
|
|
ValidateProperty(ValidationPropertyNames.QuickTicketSelection);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
LogException(e);
|
|
}
|
|
}
|
|
|
|
public class QuickCallEntry
|
|
{
|
|
public string ID { get; set; }
|
|
public string DisplayName { get; set; }
|
|
public override string ToString()
|
|
{
|
|
return DisplayName.ToString();
|
|
}
|
|
}
|
|
|
|
|
|
private void UpdateTicketSelection()
|
|
{
|
|
|
|
try
|
|
{
|
|
TicketSelectionContainer.Children.Clear();
|
|
|
|
if (DataProvider is null)
|
|
return;
|
|
|
|
if (!DataProvider.CaseRelations.TryGetValue(enumFasdInformationClass.Ticket, out var tempTicketRelations))
|
|
return;
|
|
|
|
var ticketRelations = new List<cF4sdApiSearchResultRelation>(tempTicketRelations);
|
|
//ticketRelations.Insert(0, newTicketRelation);
|
|
//ticketRelations.Add(noTicketRelation);
|
|
|
|
foreach (var ticketRelation in ticketRelations)
|
|
{
|
|
var tempTicketElement = GetTicketUiElement(ticketRelation);
|
|
|
|
if (tempTicketElement is Border ticketBorder)
|
|
{
|
|
if (ticketRelations.FirstOrDefault() == ticketRelation)
|
|
ticketBorder.CornerRadius = new CornerRadius(7.5, 7.5, 0, 0);
|
|
else if (ticketRelations.LastOrDefault() == ticketRelation)
|
|
ticketBorder.CornerRadius = new CornerRadius(0, 0, 7.5, 7.5);
|
|
}
|
|
|
|
if (tempTicketElement is null)
|
|
continue;
|
|
|
|
TicketSelectionContainer.Children.Add(tempTicketElement);
|
|
}
|
|
|
|
var currentlySelectedTicket = DataProvider.Identities.FirstOrDefault(identity => identity.Class == enumFasdInformationClass.Ticket);
|
|
if (currentlySelectedTicket != null && !NewTicketPillSelected)
|
|
SelectedTicket = ticketRelations.FirstOrDefault(ticket => ticket.id == currentlySelectedTicket.Id);
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
}
|
|
|
|
private void UpdateCaseNotesPreview()
|
|
{
|
|
try
|
|
{
|
|
if (DataProvider is null)
|
|
return;
|
|
|
|
var caseNotesFlowDocument = DataProvider.CaseNotes;
|
|
StringBuilder caseNotes = new StringBuilder();
|
|
cRichTextBoxHelper.TraverseBlockAsUnicode(caseNotesFlowDocument.Blocks, caseNotes);
|
|
CaseNotesPreview.Text = caseNotes.ToString();
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
|
|
}
|
|
private void AddNewOrExistingOrNoneTicketSelection()
|
|
{
|
|
try
|
|
{
|
|
bool createTicket = _selectedTicket == null || SelectedTicket == _selectTicketRelation || selectedTicketIsNewTicket;
|
|
if (TryGetSelectedTicketInfo(TicketInfoKeys.StatusId, out var statusIdString) &&
|
|
Enum.TryParse(statusIdString, true, out enumTicketStatus statusId))
|
|
{
|
|
createTicket = statusId == enumTicketStatus.Closed;
|
|
SelectedTicket = SelectedTicket ?? _selectTicketRelation;
|
|
}
|
|
|
|
TicketSelectionBorder.IsEnabled = !createTicket;
|
|
|
|
var pillInfos = new (string, string, string, bool, bool)[]
|
|
{
|
|
("Header.Create.Ticket", "CreateTicket", "misc_plus", false, createTicket),
|
|
("Header.Select.Ticket", "SelectTicket", "ic_drafts", true, !createTicket),
|
|
("Header.Skip.Ticket", "SkipTicket", "ic_block", true, false)
|
|
};
|
|
NewTicketPillSelected = createTicket;
|
|
|
|
foreach (var (textKey, tag, icon, isMaterialIcon, isSelected) in pillInfos)
|
|
{
|
|
var pillText = cMultiLanguageSupport.GetItem(textKey);
|
|
var selectionPill = new SelectionPill
|
|
{
|
|
PillText = pillText,
|
|
Tag = tag,
|
|
SelectOne = true,
|
|
GroupName = "NewUpdateNoTicketSelection",
|
|
IsSelected = isSelected
|
|
};
|
|
|
|
if (isMaterialIcon)
|
|
{
|
|
selectionPill.SelectedMaterialIcon = (MaterialIconType)Enum.Parse(typeof(MaterialIconType), icon);
|
|
}
|
|
else
|
|
{
|
|
selectionPill.SelectedInternIcon = (enumInternIcons)Enum.Parse(typeof(enumInternIcons), icon);
|
|
}
|
|
if (checkTicketActive())
|
|
{
|
|
if (string.Equals(tag, "SelectTicket", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
selectionPill.IsSelectedChanged += (s, e) =>
|
|
{
|
|
TicketSelectionBorder.IsEnabled = selectionPill.IsSelected;
|
|
|
|
|
|
if (!DataProvider.CaseRelations.TryGetValue(enumFasdInformationClass.Ticket, out var tempTicketRelations))
|
|
return;
|
|
|
|
var ticketRelations = new List<cF4sdApiSearchResultRelation>(tempTicketRelations);
|
|
var currentlySelectedTicket = DataProvider.Identities.FirstOrDefault(identity => identity.Class == enumFasdInformationClass.Ticket);
|
|
SelectedTicket = SelectedTicket ?? ticketRelations.FirstOrDefault(ticket => ticket.id == currentlySelectedTicket.Id);
|
|
ValidateProperty(ValidationPropertyNames.SelectedTicket);
|
|
ValidateProperty(ValidationPropertyNames.TicketSummaryTextBox);
|
|
ValidateProperty(ValidationPropertyNames.TicketStatusCombobox);
|
|
};
|
|
}
|
|
else if (string.Equals(tag, "CreateTicket", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
selectionPill.IsSelectedChanged += (s, e) =>
|
|
{
|
|
NewTicketPillSelected = selectionPill.IsSelected;
|
|
SelectedTicket = selectionPill.IsSelected ? SelectedTicket : _selectTicketRelation;
|
|
if (selectionPill.IsSelected)
|
|
{
|
|
SelectedTicket = _selectTicketRelation;
|
|
}
|
|
ValidateProperty(ValidationPropertyNames.SelectedTicket);
|
|
ValidateProperty(ValidationPropertyNames.TicketSummaryTextBox);
|
|
ValidateProperty(ValidationPropertyNames.TicketStatusCombobox);
|
|
};
|
|
}
|
|
else if (string.Equals(tag, "SkipTicket", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
selectionPill.IsSelectedChanged += (s, e) =>
|
|
{
|
|
_skipTicketPillSelected = selectionPill.IsSelected;
|
|
_errors.Clear();
|
|
UpdateTicketComponentVisibility();
|
|
ValidateProperty(ValidationPropertyNames.SelectedTicket);
|
|
ValidateProperty(ValidationPropertyNames.TicketSummaryTextBox);
|
|
ValidateProperty(ValidationPropertyNames.TicketStatusCombobox);
|
|
if (selectionPill.IsSelected)
|
|
{
|
|
TicketStatusCombobox.SelectedIndex = 0;
|
|
}
|
|
};
|
|
}
|
|
NewOrExistingOrNoneTicketWrap.Children.Add(selectionPill);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
}
|
|
private void AddCopyTemplates()
|
|
{
|
|
try
|
|
{
|
|
foreach (var copyTemplate in cF4SDCockpitXmlConfig.Instance.CopyTemplateConfig.CopyTemplates.CopyTemplates)
|
|
{
|
|
if (copyTemplate.Value.HiddenInTicketDialog)
|
|
continue;
|
|
|
|
var selectionPill = new SelectionPill() { PillText = copyTemplate.Value.Names.GetValue(), Tag = copyTemplate.Value };
|
|
|
|
if (!string.IsNullOrWhiteSpace(copyTemplate.Value.Descriptions.GetValue()))
|
|
selectionPill.ToolTip = copyTemplate.Value.Descriptions.GetValue();
|
|
|
|
switch (copyTemplate.Value.Icon.IconType)
|
|
{
|
|
case enumIconType.intern:
|
|
if (Enum.TryParse(copyTemplate.Value.Icon.Name, out enumInternIcons internIcon))
|
|
selectionPill.SelectedInternIcon = internIcon;
|
|
break;
|
|
case enumIconType.material:
|
|
if (Enum.TryParse(copyTemplate.Value.Icon.Name, out MaterialIcons.MaterialIconType materialIcon))
|
|
selectionPill.SelectedMaterialIcon = materialIcon;
|
|
break;
|
|
case enumIconType.gif:
|
|
if (Enum.TryParse(copyTemplate.Value.Icon.Name, out enumInternGif internGif))
|
|
selectionPill.SelectedGif = internGif;
|
|
break;
|
|
}
|
|
|
|
CopyTemplateWrap.Children.Add(selectionPill);
|
|
}
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
}
|
|
|
|
private string GetCopyText(enumCopyContentFormat format)
|
|
{
|
|
string output = string.Empty;
|
|
|
|
try
|
|
{
|
|
if (CopyTemplateWrap.Children?.Count <= 0)
|
|
return string.Empty;
|
|
|
|
foreach (var child in CopyTemplateWrap.Children)
|
|
{
|
|
if (!(child is SelectionPill selectionPill))
|
|
continue;
|
|
|
|
if (selectionPill.IsSelected == false)
|
|
continue;
|
|
|
|
if (!(selectionPill.Tag is cCopyTemplate selectedCopyTemplate))
|
|
continue;
|
|
|
|
if (!selectedCopyTemplate.CopyContentList.TryGetValue(format, out cCopyContent copyContent))
|
|
if (!selectedCopyTemplate.CopyContentList.TryGetValue(enumCopyContentFormat.UNICODE, out copyContent))
|
|
continue;
|
|
|
|
if (copyContent is null)
|
|
continue;
|
|
|
|
if (!string.IsNullOrEmpty(output))
|
|
output += format == enumCopyContentFormat.HTML ? "</br></br>" : "\n\n";
|
|
|
|
string copyText = copyContent.Content;
|
|
copyText = DataProvider.HealthCardDataHelper.ReplaceNamedParameters(copyText, format == enumCopyContentFormat.HTML);
|
|
|
|
if (format == enumCopyContentFormat.HTML)
|
|
output += "<div>" + copyText + "</div>";
|
|
else
|
|
output += copyText;
|
|
}
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
#region CloseCaseWithTicket
|
|
|
|
private bool CloseCaseWithCopy()
|
|
{
|
|
try
|
|
{
|
|
StringBuilder asciiStringBuilder = new StringBuilder();
|
|
StringBuilder htmlStringBuilder = new StringBuilder();
|
|
|
|
if (TransferCaseNotesCheck.IsChecked ?? false)
|
|
{
|
|
|
|
var caseNotes = DataProvider.CaseNotes;
|
|
|
|
var unicodeCaseNotes = new StringBuilder();
|
|
cRichTextBoxHelper.TraverseBlockAsUnicode(DataProvider.CaseNotes.Blocks, unicodeCaseNotes);
|
|
if (!string.IsNullOrWhiteSpace(unicodeCaseNotes.ToString()))
|
|
{
|
|
asciiStringBuilder.AppendLine(cMultiLanguageSupport.GetItem("Dialog.CloseCase.Summary") + ": \n");
|
|
htmlStringBuilder.AppendLine("<u>" + cMultiLanguageSupport.GetItem("Dialog.CloseCase.Summary") + ":</u></br>");
|
|
asciiStringBuilder.Append(unicodeCaseNotes);
|
|
}
|
|
|
|
var htmlCaseNotes = new StringBuilder();
|
|
cRichTextBoxHelper.TraverseBlockAsHtml(DataProvider.CaseNotes.Blocks, htmlCaseNotes);
|
|
if (!string.IsNullOrWhiteSpace(htmlCaseNotes.ToString()))
|
|
htmlStringBuilder.Append(htmlCaseNotes);
|
|
else
|
|
htmlStringBuilder.Append(unicodeCaseNotes);
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(asciiStringBuilder.ToString()) is false)
|
|
asciiStringBuilder.AppendLine();
|
|
|
|
if (string.IsNullOrEmpty(htmlStringBuilder.ToString()) is false)
|
|
htmlStringBuilder.AppendLine("<hr/></br>");
|
|
|
|
|
|
var copyText = GetCopyText(enumCopyContentFormat.UNICODE);
|
|
if (!string.IsNullOrEmpty(copyText))
|
|
{
|
|
asciiStringBuilder.AppendLine(cMultiLanguageSupport.GetItem("Dialog.CloseCase.Heading.CopyTemplates") + ": \n");
|
|
htmlStringBuilder.AppendLine("<u>" + cMultiLanguageSupport.GetItem("Dialog.CloseCase.Heading.CopyTemplates") + ":</u></br>");
|
|
|
|
asciiStringBuilder.AppendLine(copyText);
|
|
htmlStringBuilder.AppendLine(GetCopyText(enumCopyContentFormat.HTML));
|
|
}
|
|
|
|
if (TransferQuickActionHistoryCheck.IsChecked ?? false)
|
|
{
|
|
var quickActionProtocoll = F4SDProtocoll.Instance.GetAllAsDataObject(true);
|
|
var actionText = quickActionProtocoll.GetText();
|
|
|
|
if (!string.IsNullOrEmpty(actionText))
|
|
{
|
|
|
|
if (string.IsNullOrEmpty(asciiStringBuilder.ToString()) is false)
|
|
asciiStringBuilder.AppendLine();
|
|
|
|
if (string.IsNullOrEmpty(htmlStringBuilder.ToString()) is false)
|
|
htmlStringBuilder.AppendLine("<hr/></br>");
|
|
|
|
asciiStringBuilder.AppendLine(cMultiLanguageSupport.GetItem("Dialog.CloseCase.Heading.QuickActions") + ": \n");
|
|
htmlStringBuilder.AppendLine("<u>" + cMultiLanguageSupport.GetItem("Dialog.CloseCase.Heading.QuickActions") + ":</u></br></br>");
|
|
|
|
asciiStringBuilder.AppendLine(quickActionProtocoll.GetText());
|
|
htmlStringBuilder.AppendLine("<br/>" + quickActionProtocoll.GetText(TextDataFormat.Html));
|
|
}
|
|
}
|
|
|
|
|
|
DataObject tempDataObj = new DataObject();
|
|
tempDataObj.SetText(asciiStringBuilder.ToString());
|
|
tempDataObj.SetText(cUtility.GetHtmlFrame(htmlStringBuilder.ToString()), TextDataFormat.Html);
|
|
|
|
System.Windows.Forms.Clipboard.SetDataObject(tempDataObj, true);
|
|
|
|
return true;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
|
|
|
|
return false;
|
|
}
|
|
|
|
private async Task<bool> CloseCaseWithTicketAsync(Guid? userId = null)
|
|
{
|
|
var cm = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(cm);
|
|
|
|
try
|
|
{
|
|
if (SelectedTicket.Equals(_noTicketRelation))
|
|
return false;
|
|
// Update Ticket Tables
|
|
const string ticketTable = "M42Wpm-Tickets";
|
|
Dictionary<string, object> ticketValues = new Dictionary<string, object>()
|
|
{
|
|
["UserId"] = userId,
|
|
|
|
["id"] = SelectedTicket.id,
|
|
[TicketInfoKeys.Summary] = TicketSummaryTextBox.Text,
|
|
["CreationSource"] = 3,
|
|
["Status"] = enumTicketStatus.Unknown,
|
|
["time"] = DateTime.UtcNow,
|
|
["Priority"] = 2,
|
|
};
|
|
Guid quickcallId = Guid.Empty;
|
|
if (QuickTicketSelection.SelectedItem is QuickCallEntry selectedQuickTicketItem)
|
|
{
|
|
//ticketValues.Add("Category", selectedQuickTicketItem.DisplayName);
|
|
ticketValues.Add("QuickCallId", selectedQuickTicketItem.ID);
|
|
Guid.TryParse(selectedQuickTicketItem.ID?.ToString(), out quickcallId);
|
|
}
|
|
var selectedCategoryId = GetSelectedCategoryGuid();
|
|
if (selectedCategoryId.HasValue)
|
|
ticketValues[TicketInfoKeys.Category] = selectedCategoryId.Value;
|
|
enumCloseCaseTicketStatus? closeCaseTicketStatus = null;
|
|
int errorType = -1;
|
|
var comment = string.Empty;
|
|
DateTime? reminderDate = null;
|
|
Guid? selectedRole = null;
|
|
Guid? selectedPerson = null;
|
|
if (TicketStatusCombobox.SelectedItem is ComboBoxItem selectedItem
|
|
&& Enum.TryParse(selectedItem.Tag?.ToString(), out enumCloseCaseTicketStatus result))
|
|
{
|
|
closeCaseTicketStatus = result;
|
|
switch (closeCaseTicketStatus)
|
|
{
|
|
case enumCloseCaseTicketStatus.Close:
|
|
ticketValues.Add("ClosingDate", DateTime.UtcNow);
|
|
ticketValues["Status"] = enumTicketStatus.Closed;
|
|
|
|
if (DynamicStatusAdditionBorder.Child is CloseTicketDialog closeTicket)
|
|
{
|
|
ticketValues.Add("Solution", closeTicket.Solution);
|
|
if (closeTicket.ErrorTypeComboBox.SelectedItem is ComboBoxItem closeTicketComboBox)
|
|
{
|
|
int.TryParse(closeTicketComboBox.Tag?.ToString(), out errorType);
|
|
ticketValues.Add("ErrorType", closeTicketComboBox.Tag);
|
|
}
|
|
}
|
|
break;
|
|
case enumCloseCaseTicketStatus.OnHold:
|
|
{
|
|
if (DynamicStatusAdditionBorder.Child is HoldTicketDialog holdTicket)
|
|
{
|
|
comment = holdTicket.Comment;
|
|
}
|
|
}
|
|
ticketValues["Status"] = enumTicketStatus.OnHold;
|
|
break;
|
|
case enumCloseCaseTicketStatus.Forward:
|
|
if (DynamicStatusAdditionBorder.Child is ForwardTicketDialog forwardTicket)
|
|
{
|
|
var roleSelection = forwardTicket.RoleSelectionControl.GetSelectedValue();
|
|
if (roleSelection.HasValue)
|
|
{
|
|
var roleSelectionval = roleSelection.Value.Value.ToString();
|
|
if (Guid.TryParse(roleSelectionval, out var roleResult))
|
|
{
|
|
selectedRole = roleResult;
|
|
}
|
|
}
|
|
var personSelection = forwardTicket.PersonSelectionControl.GetSelectedValue();
|
|
if (personSelection.HasValue)
|
|
{
|
|
var personSelectionval = personSelection.Value.Value.ToString();
|
|
if (Guid.TryParse(personSelectionval, out var personResult))
|
|
{
|
|
selectedPerson = personResult;
|
|
}
|
|
}
|
|
comment = forwardTicket.Comment;
|
|
}
|
|
ticketValues["Status"] = enumTicketStatus.InProgress;
|
|
break;
|
|
default:
|
|
ticketValues["Status"] = enumTicketStatus.New;
|
|
break;
|
|
}
|
|
}
|
|
|
|
string user = string.Empty;
|
|
if (DataProvider.NamedParameterEntries.TryGetValue("UserFullName", out var userNameParameter))
|
|
user = userNameParameter.GetValue();
|
|
ticketValues.Add("AffectedUser", user);
|
|
string asset = string.Empty;
|
|
if (SelectedComputer == _removeAffectedAssetEntry)
|
|
{
|
|
asset = TicketSpecialValues.RemoveAffectedAssetEntry;
|
|
}
|
|
else if (SetOrUpdateComputerInTicket)
|
|
{
|
|
asset = SelectedComputer?.DisplayName;
|
|
}
|
|
|
|
ticketValues.Add("Asset", asset);
|
|
|
|
Guid? service = null;
|
|
if (SetOrUpdateServiceInTicket && SelectedService.Value != null)
|
|
{
|
|
if (string.Equals(SelectedService.Value.ToString(), TicketSpecialValues.RemoveAffectedServiceEntry, StringComparison.OrdinalIgnoreCase))
|
|
service = Guid.Empty;
|
|
else if (Guid.TryParse(SelectedService.Value.ToString(), out Guid parsedGuid))
|
|
{
|
|
service = parsedGuid;
|
|
}
|
|
}
|
|
|
|
|
|
string adDnComputer = string.Empty;
|
|
string userFullName = string.Empty;
|
|
string userAccount = string.Empty;
|
|
string adDnUser = string.Empty;
|
|
string userMail = string.Empty;
|
|
|
|
// Abrufen der Variablenwerte aus den NamedParameterEntries
|
|
if (DataProvider.NamedParameterEntries.TryGetValue("ad-dn-computer", out var adDnComputerParameter))
|
|
{
|
|
adDnComputer = adDnComputerParameter.GetValue();
|
|
}
|
|
|
|
if (DataProvider.NamedParameterEntries.TryGetValue("UserFullName", out var userFullNameParameter))
|
|
{
|
|
userFullName = userFullNameParameter.GetValue();
|
|
}
|
|
|
|
if (DataProvider.NamedParameterEntries.TryGetValue("UserAccount", out var userAccountParameter))
|
|
{
|
|
userAccount = userAccountParameter.GetValue();
|
|
}
|
|
|
|
if (DataProvider.NamedParameterEntries.TryGetValue("ad-dn-User", out var adDnUserParameter))
|
|
{
|
|
adDnUser = adDnUserParameter.GetValue();
|
|
}
|
|
|
|
if (DataProvider.NamedParameterEntries.TryGetValue("UserMail", out var userMailParameter))
|
|
{
|
|
userMail = userMailParameter.GetValue();
|
|
}
|
|
|
|
var htmlCaseNotes = new StringBuilder();
|
|
if (TransferCaseNotesCheck.IsChecked ?? false)
|
|
{
|
|
var caseNotes = DataProvider.CaseNotes;
|
|
|
|
var unicodeCaseNotes = new StringBuilder();
|
|
cRichTextBoxHelper.TraverseBlockAsUnicode(DataProvider.CaseNotes.Blocks, unicodeCaseNotes);
|
|
if (!string.IsNullOrWhiteSpace(unicodeCaseNotes.ToString()))
|
|
ticketValues.Add("Description", unicodeCaseNotes.ToString());
|
|
|
|
cRichTextBoxHelper.TraverseBlockAsHtml(DataProvider.CaseNotes.Blocks, htmlCaseNotes);
|
|
if (!string.IsNullOrWhiteSpace(htmlCaseNotes.ToString()))
|
|
ticketValues.Add("DescriptionHtml", htmlCaseNotes.ToString());
|
|
}
|
|
|
|
const string journalTable = "M42Wpm-Tickets-History";
|
|
|
|
//Update QuickAction History
|
|
string solutionHtmlString = string.Empty;
|
|
Dictionary<string, object> quickActionValues = null;
|
|
|
|
if (ticketValues.TryGetValue("Solution", out var solutionValue))
|
|
{
|
|
if (solutionValue is string solutionString)
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(solutionString))
|
|
{
|
|
solutionString += "\n\n\n";
|
|
solutionHtmlString = solutionString + "</br></br></br>";
|
|
}
|
|
else
|
|
{
|
|
solutionHtmlString = "</br></br></br>";
|
|
}
|
|
|
|
ticketValues["Solution"] = solutionString;
|
|
ticketValues["SolutionHtml"] = solutionHtmlString;
|
|
}
|
|
}
|
|
|
|
if (TransferQuickActionHistoryCheck.IsChecked ?? false)
|
|
{
|
|
var quickActionProtocoll = F4SDProtocoll.Instance.GetAllAsDataObject(true);
|
|
|
|
if (ticketValues.TryGetValue("Solution", out solutionValue))
|
|
{
|
|
if (solutionValue is string solutionString)
|
|
{
|
|
solutionString += quickActionProtocoll.GetText();
|
|
solutionHtmlString += quickActionProtocoll.GetText(TextDataFormat.Html);
|
|
|
|
ticketValues["Solution"] = solutionString;
|
|
ticketValues["SolutionHtml"] = solutionHtmlString;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var tempQuickActionValues = new Dictionary<string, object>()
|
|
{
|
|
["UserId"] = userId,
|
|
["id"] = SelectedTicket.id,
|
|
["Header"] = "Commented by F4SD",
|
|
["IsVisibleForUser"] = false,
|
|
["time"] = DateTime.UtcNow,
|
|
["Description"] = quickActionProtocoll.GetText(),
|
|
["DescriptionHtml"] = string.IsNullOrWhiteSpace(quickActionProtocoll.GetText(TextDataFormat.Html))
|
|
? quickActionProtocoll.GetText()
|
|
: quickActionProtocoll.GetText(TextDataFormat.Html)
|
|
};
|
|
|
|
if (!string.IsNullOrWhiteSpace(quickActionProtocoll.GetText()))
|
|
quickActionValues = tempQuickActionValues;
|
|
}
|
|
}
|
|
|
|
await cFasdCockpitCommunicationBase.Instance.UpdateHealthcardTableData(new cF4SDWriteParameters() { id = SelectedTicket.id, TableName = ticketTable, Values = ticketValues });
|
|
|
|
if (quickActionValues != null)
|
|
await cFasdCockpitCommunicationBase.Instance.UpdateHealthcardTableData(new cF4SDWriteParameters() { id = SelectedTicket.id, TableName = journalTable, Values = quickActionValues });
|
|
|
|
string copyString = GetCopyText(enumCopyContentFormat.UNICODE);
|
|
string copyStringHtml = GetCopyText(enumCopyContentFormat.HTML);
|
|
if (!string.IsNullOrWhiteSpace(copyString))
|
|
{
|
|
Dictionary<string, object> copyValues = new Dictionary<string, object>()
|
|
{
|
|
["UserId"] = userId,
|
|
|
|
["id"] = SelectedTicket.id,
|
|
["Header"] = "Commented by F4SD",
|
|
["IsVisibleForUser"] = false,
|
|
["time"] = DateTime.UtcNow,
|
|
["Description"] = copyString,
|
|
["DescriptionHtml"] = string.IsNullOrWhiteSpace(copyStringHtml) ? copyString : copyStringHtml
|
|
};
|
|
await cFasdCockpitCommunicationBase.Instance.UpdateHealthcardTableData(new cF4SDWriteParameters() { id = SelectedTicket.id, TableName = journalTable, Values = copyValues });
|
|
}
|
|
|
|
string statusIdValue = null;
|
|
if (TryGetSelectedTicketInfo(TicketInfoKeys.StatusId, out var value))
|
|
{
|
|
statusIdValue = value;
|
|
}
|
|
|
|
|
|
var workingTimes = TimerView.GetWorkTimes();
|
|
workingTimes.Add("Description", cMultiLanguageSupport.GetItem("Dialog.CloseCase.WorkingTimeEntryDescription"));
|
|
var doNotEscalate = false;
|
|
var holdTicketReason = 0;
|
|
if (this.DynamicStatusAdditionBorder.Child is HoldTicketDialog holdTicketDialog)
|
|
{
|
|
reminderDate = new DateTime(
|
|
holdTicketDialog.SelectedDate.Year,
|
|
holdTicketDialog.SelectedDate.Month,
|
|
holdTicketDialog.SelectedDate.Day,
|
|
holdTicketDialog.SelectedHour,
|
|
holdTicketDialog.SelectedMinute,
|
|
0);
|
|
doNotEscalate = (bool)holdTicketDialog.DoNotEscalate.IsChecked;
|
|
if (holdTicketDialog.ReasonSelection.SelectedItem is ComboBoxItem sel)
|
|
{
|
|
if (int.TryParse(sel.Tag.ToString(), out int tmpReasonTag))
|
|
{
|
|
holdTicketReason = tmpReasonTag;
|
|
}
|
|
}
|
|
}
|
|
cApiM42Ticket ticketData = new cApiM42Ticket()
|
|
{
|
|
Ticket = _selectedTicket.Identities == null ? Guid.Empty : SelectedTicket.id,
|
|
Action = closeCaseTicketStatus.HasValue ? closeCaseTicketStatus : null,
|
|
User = adDnUser,
|
|
AffectedAsset = asset,
|
|
AffectedService = service,
|
|
Category = selectedCategoryId,
|
|
Summary = TicketSummaryTextBox.Text,
|
|
DescriptionHtml = htmlCaseNotes.ToString(),
|
|
Quickcall = quickcallId,
|
|
CopyTemplates = string.IsNullOrWhiteSpace(copyStringHtml) ? copyString : copyStringHtml,
|
|
SolutionHtml = solutionHtmlString,
|
|
ErrorType = errorType,
|
|
ReminderDate = reminderDate,
|
|
DoNotEscalateWhilePaused = doNotEscalate,
|
|
Reason = holdTicketReason,
|
|
ResponsibleRole = selectedRole,
|
|
ResponsiblePerson = selectedPerson,
|
|
Comment = comment,
|
|
QuickActionHistory = TransferQuickActionHistoryCheck.IsChecked ?? false ? F4SDProtocoll.Instance.GetOfType<QuickActionProtocollEntry>().Select(e => e.GetResult()).ToList() : null,
|
|
workTimes = workingTimes,
|
|
StatusIdValue = statusIdValue,
|
|
CaseId = DataProvider.CaseId
|
|
};
|
|
ticketData.AdditionalValues.Add("IsTicket", IsTicket);
|
|
ticketData.AdditionalValues.Add(TicketInfoKeys.ActivityType, GetSelectedTicketInfoOrDefault(TicketInfoKeys.ActivityType));
|
|
ticketData.AdditionalValues.Add("Dialog.CloseCase.AssetNotFoundInMatrix42", cMultiLanguageSupport.GetItem("Dialog.CloseCase.AssetNotFoundInMatrix42"));
|
|
ticketData.AdditionalValues.Add("Dialog.CloseCase.ReopenReasonText", cMultiLanguageSupport.GetItem("Dialog.CloseCase.ReopenReasonText"));
|
|
ticketData.AdditionalValues.Add("Dialog.CloseCase.ReopenReasonTextHtml", cMultiLanguageSupport.GetItem("Dialog.CloseCase.ReopenReasonTextHtml"));
|
|
var _res = await cFasdCockpitCommunicationBase.Instance.Matrix42TicketFinalization(ticketData);
|
|
return true;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
LogException(e);
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(cm);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public async Task<bool> CloseCaseAsync(Guid? userId = null)
|
|
{
|
|
try
|
|
{
|
|
|
|
if (checkTicketActive() && !_skipTicketPillSelected)
|
|
return await CloseCaseWithTicketAsync(userId);
|
|
else
|
|
return CloseCaseWithCopy();
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
public List<string> GetErrors(string propertyName)
|
|
{
|
|
switch (propertyName)
|
|
{
|
|
case ValidationPropertyNames.SelectedTicket:
|
|
if (SelectedTicket == _selectTicketRelation && !NewTicketPillSelected && !SkipTicketPillSelected)
|
|
{
|
|
if (!_errors.ContainsKey(propertyName))
|
|
_errors.Add(propertyName, cMultiLanguageSupport.GetItem("Header.Select.Ticket"));
|
|
}
|
|
else
|
|
{
|
|
if (_errors.ContainsKey(propertyName))
|
|
_errors.Remove(propertyName);
|
|
}
|
|
break;
|
|
case ValidationPropertyNames.TicketSummaryTextBox:
|
|
validateTextboxNotEmpty(TicketSummaryTextBox);
|
|
if (!string.IsNullOrEmpty(TicketSummaryTextBox.Text) || !TicketSummaryTextBox.IsVisible)
|
|
{
|
|
if (_errors.ContainsKey(propertyName))
|
|
_errors.Remove(propertyName);
|
|
}
|
|
else
|
|
{
|
|
if (!_errors.ContainsKey(propertyName))
|
|
_errors.Add(propertyName, cMultiLanguageSupport.GetItem("Dialog.CloseCase.ValidationErrorSummaryEmpty"));
|
|
}
|
|
break;
|
|
case ValidationPropertyNames.CaseNotesPreview:
|
|
var errorNotEmpty = CheckTextBlockNotEmpty(CaseNotesPreview, cFasdCockpitConfig.Instance.Global.TicketConfiguration.NotesMandatory);
|
|
if (errorNotEmpty && CaseNotesPreview.IsVisible)
|
|
{
|
|
if (!_errors.ContainsKey(propertyName))
|
|
_errors.Add(propertyName, cMultiLanguageSupport.GetItem("Dialog.CloseCase.ValidationErrorCaseNoteEmpty"));
|
|
}
|
|
else
|
|
{
|
|
if (_errors.ContainsKey(propertyName))
|
|
_errors.Remove(propertyName);
|
|
}
|
|
break;
|
|
case ValidationPropertyNames.SolutionTextbox:
|
|
if (DynamicStatusAdditionBorder.Child is CloseTicketDialog closeTicketDialog)
|
|
{
|
|
if (string.IsNullOrEmpty(closeTicketDialog.Solution))
|
|
{
|
|
setTextboxErrorState(closeTicketDialog.SolutionTextbox, true);
|
|
if (!_errors.ContainsKey(propertyName))
|
|
_errors.Add(propertyName, cMultiLanguageSupport.GetItem("Dialog.CloseCase.ValidationErrorSolutionEmpty"));
|
|
}
|
|
else
|
|
{
|
|
setTextboxErrorState(closeTicketDialog.SolutionTextbox, false);
|
|
if (_errors.ContainsKey(propertyName))
|
|
_errors.Remove(propertyName);
|
|
}
|
|
}
|
|
break;
|
|
case ValidationPropertyNames.ReminderDate:
|
|
if (DynamicStatusAdditionBorder.Child is HoldTicketDialog holdTicketDialog)
|
|
{
|
|
if (holdTicketDialog.SelectedReminderDate <= DateTime.UtcNow.AddMinutes(-2))
|
|
{
|
|
if (!_errors.ContainsKey(propertyName))
|
|
_errors.Add(propertyName, cMultiLanguageSupport.GetItem("Dialog.CloseCase.ValidationErrorReminderDate"));
|
|
}
|
|
else
|
|
{
|
|
if (_errors.ContainsKey(propertyName))
|
|
_errors.Remove(propertyName);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ValidationPropertyNames.ErrorTypeValue:
|
|
if (DynamicStatusAdditionBorder.Child is CloseTicketDialog closeTicketDialog2)
|
|
{
|
|
if (closeTicketDialog2.SelectedErrorType == null || closeTicketDialog2.SelectedErrorType is ComboBoxItem b && b.Tag == null)
|
|
{
|
|
closeTicketDialog2.UpdateErrorTypeValidationState(true);
|
|
if (!_errors.ContainsKey(propertyName))
|
|
_errors.Add(propertyName, cMultiLanguageSupport.GetItem("Dialog.CloseCase.ValidationErrorTypeEmpty"));
|
|
}
|
|
else
|
|
{
|
|
closeTicketDialog2.UpdateErrorTypeValidationState(false);
|
|
if (_errors.ContainsKey(propertyName))
|
|
_errors.Remove(propertyName);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ValidationPropertyNames.SelectedRoleAndPerson:
|
|
if (DynamicStatusAdditionBorder.Child is ForwardTicketDialog forwardTicketDialog)
|
|
{
|
|
bool hasError = (forwardTicketDialog.SelectedPerson.Key == null || forwardTicketDialog.SelectedPerson.Value == null) &&
|
|
(forwardTicketDialog.SelectedRole.Key == null || forwardTicketDialog.SelectedRole.Value == null);
|
|
|
|
forwardTicketDialog.UpdateResponsibleSelectionValidationState(hasError);
|
|
|
|
if (hasError)
|
|
{
|
|
if (!_errors.ContainsKey(propertyName))
|
|
_errors.Add(propertyName, cMultiLanguageSupport.GetItem("Dialog.CloseCase.ValidationErrorRoleAndPersonEmpty"));
|
|
}
|
|
else
|
|
{
|
|
if (_errors.ContainsKey(propertyName))
|
|
_errors.Remove(propertyName);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ValidationPropertyNames.ForwardComment:
|
|
if (DynamicStatusAdditionBorder.Child is ForwardTicketDialog forwardTicketDialog2)
|
|
{
|
|
if (string.IsNullOrEmpty(forwardTicketDialog2.Comment))
|
|
{
|
|
setTextboxErrorState(forwardTicketDialog2.CommentTextbox, true);
|
|
if (!_errors.ContainsKey(propertyName))
|
|
_errors.Add(propertyName, cMultiLanguageSupport.GetItem("Dialog.CloseCase.ForwardTicket.ValidationErrorCommentEmpty"));
|
|
}
|
|
else
|
|
{
|
|
setTextboxErrorState(forwardTicketDialog2.CommentTextbox, false);
|
|
if (_errors.ContainsKey(propertyName))
|
|
_errors.Remove(propertyName);
|
|
}
|
|
}
|
|
break;
|
|
case ValidationPropertyNames.HoldComment:
|
|
if (DynamicStatusAdditionBorder.Child is HoldTicketDialog holdTicketDialog1)
|
|
{
|
|
if (string.IsNullOrEmpty(holdTicketDialog1.Comment))
|
|
{
|
|
setTextboxErrorState(holdTicketDialog1.CommentTextBox, true);
|
|
if (!_errors.ContainsKey(propertyName))
|
|
_errors.Add(propertyName, cMultiLanguageSupport.GetItem("Dialog.CloseCase.HoldTicket.ValidationErrorCommentEmpty"));
|
|
}
|
|
else
|
|
{
|
|
setTextboxErrorState(holdTicketDialog1.CommentTextBox, false);
|
|
if (_errors.ContainsKey(propertyName))
|
|
_errors.Remove(propertyName);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ValidationPropertyNames.TicketStatusCombobox:
|
|
validateComboboxNotEmpty(TicketStatusCombobox);
|
|
if (!(TicketStatusCombobox.SelectedItem is ComboBoxItem a))
|
|
break;
|
|
|
|
enumTicketStatus currentTicketStatus = enumTicketStatus.Unknown;
|
|
if (TryGetSelectedTicketInfo(TicketInfoKeys.StatusId, out var statusIdString) &&
|
|
Enum.TryParse(statusIdString, true, out enumTicketStatus parsedStatus))
|
|
{
|
|
currentTicketStatus = parsedStatus;
|
|
}
|
|
|
|
bool ticketActionHasError = TicketStatusCombobox.IsVisible && a.Tag == null;
|
|
if (!ticketActionHasError)
|
|
{
|
|
if (_errors.ContainsKey(propertyName))
|
|
_errors.Remove(propertyName);
|
|
}
|
|
else if (!_errors.ContainsKey(propertyName))
|
|
{
|
|
_errors.Add(propertyName, cMultiLanguageSupport.GetItem("Dialog.CloseCase.ValidationErrorTicketActionEmpty"));
|
|
}
|
|
UpdateTicketStatusValidationVisualState(ticketActionHasError);
|
|
|
|
if (a.Tag == null)
|
|
{
|
|
ShowAssetWarningTicketAction = false;
|
|
break;
|
|
}
|
|
|
|
enumCloseCaseTicketStatus? selectedStatus = null;
|
|
if (Enum.TryParse(a.Tag.ToString(), true, out enumCloseCaseTicketStatus parsedStatusAction))
|
|
{
|
|
selectedStatus = parsedStatusAction;
|
|
}
|
|
|
|
bool hasTicketActivity = TryGetSelectedTicketInfo(TicketInfoKeys.ActivityType, out var currentTicketActivityType) &&
|
|
string.Equals(currentTicketActivityType, TicketInfoValues.ActivityTypeTicket, StringComparison.OrdinalIgnoreCase);
|
|
|
|
if (selectedStatus.HasValue && selectedStatus != enumCloseCaseTicketStatus.Forward && selectedStatus != enumCloseCaseTicketStatus.Save && hasTicketActivity)
|
|
{
|
|
ShowAssetWarningTicketAction = true;
|
|
var binding = new Binding
|
|
{
|
|
Converter = _languageConverter,
|
|
ConverterParameter = "Dialog.CloseCase.ValidationErrorTicketToIncident"
|
|
};
|
|
|
|
WarningTicketAction.SetBinding(ToolTipProperty, binding);
|
|
}
|
|
else if (currentTicketStatus == enumTicketStatus.Closed)
|
|
{
|
|
ShowAssetWarningTicketAction = true;
|
|
var binding = new Binding
|
|
{
|
|
Converter = _languageConverter,
|
|
ConverterParameter = "Dialog.CloseCase.ValidationErrorTicketWillBeReopened"
|
|
};
|
|
|
|
WarningTicketAction.SetBinding(ToolTipProperty, binding);
|
|
}
|
|
else
|
|
{
|
|
ShowAssetWarningTicketAction = false;
|
|
}
|
|
|
|
break;
|
|
case ValidationPropertyNames.SelectedCategory:
|
|
bool categoryIsVisible = CategorySelectionControl?.IsVisible ?? false;
|
|
bool categoryHasError = categoryIsVisible && SelectedCategory == null;
|
|
UpdateCategoryValidationVisualState(categoryHasError);
|
|
|
|
if (categoryHasError)
|
|
{
|
|
if (!_errors.ContainsKey(propertyName))
|
|
_errors.Add(propertyName, cMultiLanguageSupport.GetItem("Dialog.CloseCase.ValidationErrorCategoryEmpty"));
|
|
}
|
|
else
|
|
{
|
|
if (_errors.ContainsKey(propertyName))
|
|
_errors.Remove(propertyName);
|
|
}
|
|
|
|
break;
|
|
case ValidationPropertyNames.QuickTicketSelection:
|
|
bool quickCallIsVisible = QuickTicketSelection?.IsVisible ?? false;
|
|
bool quickCallSelected = QuickTicketSelection?.SelectedItem is QuickCallEntry selectedQuickCall && !string.IsNullOrWhiteSpace(selectedQuickCall.ID);
|
|
bool quickCallHasError = quickCallIsVisible && !quickCallSelected;
|
|
UpdateQuickTicketValidationVisualState(quickCallHasError);
|
|
|
|
if (quickCallHasError)
|
|
{
|
|
if (!_errors.ContainsKey(propertyName))
|
|
_errors.Add(propertyName, cMultiLanguageSupport.GetItem("Dialog.CloseCase.ValidationErrorQuickCallEmpty"));
|
|
}
|
|
else
|
|
{
|
|
if (_errors.ContainsKey(propertyName))
|
|
_errors.Remove(propertyName);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
return new List<string>(_errors.Values);
|
|
}
|
|
|
|
|
|
private void ValidateProperty(string propertyName)
|
|
{
|
|
var errors = GetErrors(propertyName);
|
|
if (errors != null && errors.Count > 0)
|
|
{
|
|
// Speichern-Button deaktivieren
|
|
if (Window.GetWindow(this) is TicketCompletion msgBox)
|
|
{
|
|
this.parentWindow = msgBox;
|
|
this.parentWindow.SetButtonStateYes(false, cMultiLanguageSupport.GetItem("Dialog.CloseCase.ValidationErrorsList") + "\r\n• " + string.Join("\r\n• ", errors));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Speichern-Button aktivieren
|
|
Window parentWindow = Window.GetWindow(this);
|
|
|
|
if (parentWindow is TicketCompletion _msgBox)
|
|
{
|
|
this.parentWindow = _msgBox;
|
|
this.parentWindow.SetButtonStateYes(true, "");
|
|
}
|
|
}
|
|
}
|
|
|
|
#region TicketRelation_Click
|
|
|
|
private void TicketRelation_Click(object sender)
|
|
{
|
|
try
|
|
{
|
|
if (!(sender is FrameworkElement senderElement))
|
|
return;
|
|
|
|
if (!(senderElement.Tag is cF4sdApiSearchResultRelation selectedSearchResult))
|
|
return;
|
|
|
|
SelectedTicket = selectedSearchResult;
|
|
UpdateSelectedTicketControl();
|
|
TicketSelectionPopUp.IsOpen = false;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
}
|
|
|
|
private void TicketRelation_TouchDown(object sender, TouchEventArgs e)
|
|
{
|
|
TicketRelation_Click(sender);
|
|
}
|
|
|
|
private void TicketRelation_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
|
|
{
|
|
TicketRelation_Click(sender);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region EditCaseNotesButton_Click
|
|
|
|
private void EditCaseNotesButton_Click()
|
|
{
|
|
try
|
|
{
|
|
if (SupportNotepad == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
TicketNotepadChanged?.Invoke(this, true);
|
|
|
|
//TODO
|
|
//var notepad = new Notepad(true, DataProvider.caseNotes) { DataProvider = DataProvider };
|
|
//openedWindows.Add(Window.GetWindow(notepad));
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
|
|
}
|
|
|
|
private void EditCaseNotesButton_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
|
|
{
|
|
EditCaseNotesButton_Click();
|
|
|
|
if (!string.IsNullOrWhiteSpace(CaseNotesPreview.Text))
|
|
{
|
|
CaseNotesPreviewBorder.BorderBrush = (SolidColorBrush)new BrushConverter().ConvertFromString("#DEE2E6");
|
|
ValidateProperty(ValidationPropertyNames.CaseNotesPreview);
|
|
}
|
|
else
|
|
{
|
|
CaseNotesPreviewBorder.BorderBrush = SharedValidationBorderBrush;
|
|
}
|
|
}
|
|
|
|
private void EditCaseNotesButton_TouchDown(object sender, TouchEventArgs e)
|
|
{
|
|
EditCaseNotesButton_Click();
|
|
}
|
|
|
|
#endregion
|
|
|
|
private void TicketStatusCombobox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
{
|
|
|
|
if (DynamicStatusAdditionBorder is null)
|
|
return;
|
|
|
|
if (!(sender is ComboBox comboBox))
|
|
return;
|
|
|
|
// Die Werte aus 'errors' entfernen
|
|
Array.ForEach(
|
|
new[]
|
|
{
|
|
ValidationPropertyNames.SolutionTextbox,
|
|
ValidationPropertyNames.ErrorTypeValue,
|
|
ValidationPropertyNames.ReminderDate,
|
|
ValidationPropertyNames.SelectedRoleAndPerson,
|
|
ValidationPropertyNames.ForwardComment,
|
|
ValidationPropertyNames.HoldComment
|
|
},
|
|
key => _errors.Remove(key));
|
|
ValidateProperty(ValidationPropertyNames.TicketStatusCombobox);
|
|
|
|
if (!(comboBox.SelectedItem is ComboBoxItem selectedItem))
|
|
return;
|
|
if (!(Enum.TryParse(selectedItem.Tag?.ToString(), out enumCloseCaseTicketStatus closeCaseTicketStatus)))
|
|
{
|
|
DynamicStatusAdditionBorder.Visibility = Visibility.Collapsed;
|
|
return;
|
|
}
|
|
|
|
FrameworkElement dynamicStatusChild = null;
|
|
switch (closeCaseTicketStatus)
|
|
{
|
|
case enumCloseCaseTicketStatus.Close:
|
|
var dialog = new CloseTicketDialog() { DataProvider = DataProvider };
|
|
dialog.ErrorTypeValueChanged += Dialog_ErrorTypeValueChanged;
|
|
dialog.SolutionValueChanged += SolutionTextboxValueChanged;
|
|
var _h = Dispatcher.BeginInvoke((Action)(() =>
|
|
{
|
|
if (dialog.IsLoaded)
|
|
{
|
|
ValidateProperty(ValidationPropertyNames.SolutionTextbox);
|
|
ValidateProperty(ValidationPropertyNames.ErrorTypeValue);
|
|
}
|
|
}), System.Windows.Threading.DispatcherPriority.Loaded);
|
|
|
|
|
|
dynamicStatusChild = dialog;
|
|
break;
|
|
case enumCloseCaseTicketStatus.OnHold:
|
|
var holdTicketDialog = new HoldTicketDialog(DataProvider = DataProvider);
|
|
dynamicStatusChild = holdTicketDialog;
|
|
holdTicketDialog.SelectedReminderDateChanged += ReminderDateValueChanged;
|
|
holdTicketDialog.CommentChanged += HoldCommentChanged;
|
|
_h = Dispatcher.BeginInvoke((Action)(() =>
|
|
{
|
|
if (holdTicketDialog.IsLoaded)
|
|
{
|
|
ValidateProperty(ValidationPropertyNames.ReminderDate);
|
|
ValidateProperty(ValidationPropertyNames.HoldComment);
|
|
}
|
|
}), System.Windows.Threading.DispatcherPriority.Loaded);
|
|
break;
|
|
case enumCloseCaseTicketStatus.Forward:
|
|
var forwardTicketDialog = new ForwardTicketDialog(DataProvider);
|
|
dynamicStatusChild = forwardTicketDialog;
|
|
forwardTicketDialog.SelectedPersonChanged += SelectedPersonChanged;
|
|
forwardTicketDialog.SelectedRoleChanged += SelectedRoleChanged;
|
|
forwardTicketDialog.CommentChanged += ForwardCommentChanged;
|
|
_h = Dispatcher.BeginInvoke((Action)(() =>
|
|
{
|
|
if (forwardTicketDialog.IsLoaded)
|
|
{
|
|
ValidateProperty(ValidationPropertyNames.SelectedRoleAndPerson);
|
|
ValidateProperty(ValidationPropertyNames.ForwardComment);
|
|
}
|
|
}), System.Windows.Threading.DispatcherPriority.Loaded);
|
|
break;
|
|
case enumCloseCaseTicketStatus.Save:
|
|
break;
|
|
}
|
|
if (dynamicStatusChild != null)
|
|
{
|
|
DynamicStatusAdditionBorder.Visibility = Visibility.Visible;
|
|
DynamicStatusAdditionBorder.Child = dynamicStatusChild;
|
|
}
|
|
else
|
|
DynamicStatusAdditionBorder.Visibility = Visibility.Collapsed;
|
|
this.VerticalAlignment = VerticalAlignment.Center;
|
|
}
|
|
private void ForwardCommentChanged(object sender, EventArgs e)
|
|
{
|
|
ValidateProperty(ValidationPropertyNames.ForwardComment);
|
|
}
|
|
private void HoldCommentChanged(object sender, EventArgs e)
|
|
{
|
|
ValidateProperty(ValidationPropertyNames.HoldComment);
|
|
}
|
|
private void SelectedRoleChanged(object sender, EventArgs e)
|
|
{
|
|
ValidateProperty(ValidationPropertyNames.SelectedRoleAndPerson);
|
|
}
|
|
|
|
private void SelectedPersonChanged(object sender, EventArgs e)
|
|
{
|
|
ValidateProperty(ValidationPropertyNames.SelectedRoleAndPerson);
|
|
}
|
|
|
|
private void ReminderDateValueChanged(object sender, EventArgs e)
|
|
{
|
|
ValidateProperty(ValidationPropertyNames.ReminderDate);
|
|
}
|
|
private void SolutionTextboxValueChanged(object sender, EventArgs e)
|
|
{
|
|
ValidateProperty(ValidationPropertyNames.SolutionTextbox);
|
|
}
|
|
|
|
private void Dialog_ErrorTypeValueChanged(object sender, EventArgs e)
|
|
{
|
|
ValidateProperty(ValidationPropertyNames.ErrorTypeValue);
|
|
}
|
|
|
|
private static void validateComboboxNotEmpty(object sender)
|
|
{
|
|
//var comboBox = sender as ComboBox;
|
|
//if (comboBox != null)
|
|
//{
|
|
// if (!(comboBox.SelectedItem is ComboBoxItem selectedItem))
|
|
// return;
|
|
|
|
|
|
|
|
// // Überprüfe den Inhalt und setze die Hintergrundfarbe entsprechend
|
|
// if (selectedItem.Tag == null)
|
|
// {
|
|
// // Setze die Hintergrundfarbe auf Rot, um einen Validierungsfehler anzuzeigen
|
|
// comboBox.BorderBrush = SharedValidationBorderBrush;
|
|
// }
|
|
// else
|
|
// {
|
|
// // Setze die ursprüngliche Hintergrundfarbe zurück, wenn die Validierung erfolgreich ist
|
|
// comboBox.BorderBrush = (SolidColorBrush)new BrushConverter().ConvertFromString("#DEE2E6");
|
|
// }
|
|
//}
|
|
}
|
|
|
|
private void TicketSelectionBorder_Click()
|
|
{
|
|
var _h = Dispatcher.Invoke(async () =>
|
|
{
|
|
await Task.Delay(50);
|
|
|
|
if (!TicketSelectionPopUp.IsOpen)
|
|
DropDownOpened(TicketSelectionBorder, EventArgs.Empty);
|
|
|
|
TicketSelectionPopUp.IsOpen = !TicketSelectionPopUp.IsOpen;
|
|
});
|
|
}
|
|
|
|
private void TicketSelectionBorder_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
|
|
{
|
|
TicketSelectionBorder_Click();
|
|
}
|
|
|
|
private void TicketSelectionBorder_TouchDown(object sender, TouchEventArgs e)
|
|
{
|
|
TicketSelectionBorder_Click();
|
|
}
|
|
|
|
private void TicketSummaryTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
if (SelectedTicket?.Infos is null)
|
|
return;
|
|
|
|
SelectedTicket.Infos[TicketInfoKeys.Summary] = TicketSummaryTextBox.Text;
|
|
ValidateProperty(ValidationPropertyNames.TicketSummaryTextBox);
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
|
|
}
|
|
|
|
private void TicketCaseNotesTextBlock_TextChanged(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
if (SelectedTicket?.Infos is null)
|
|
return;
|
|
|
|
if (string.IsNullOrWhiteSpace(CaseNotesPreview.Text))
|
|
CaseNotesPreview.Text = string.Empty;
|
|
|
|
SelectedTicket.Infos[TicketInfoKeys.Summary] = CaseNotesPreview.Text;
|
|
ValidateProperty(ValidationPropertyNames.CaseNotesPreview);
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
}
|
|
|
|
private static void validateTextboxNotEmpty(object sender)
|
|
{
|
|
if (sender is TextBox textBox)
|
|
{
|
|
// Text aus der TextBox holen
|
|
string text = textBox.Text;
|
|
|
|
// Überprüfe den Inhalt und setze die Hintergrundfarbe entsprechend
|
|
if (string.IsNullOrWhiteSpace(text))
|
|
{
|
|
// Setze die Hintergrundfarbe auf Rot, um einen Validierungsfehler anzuzeigen
|
|
textBox.BorderBrush = SharedValidationBorderBrush;
|
|
}
|
|
else
|
|
{
|
|
// Setze die ursprüngliche Hintergrundfarbe zurück, wenn die Validierung erfolgreich ist
|
|
textBox.BorderBrush = (SolidColorBrush)new BrushConverter().ConvertFromString("#DEE2E6");
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private bool CheckTextBlockNotEmpty(TextBlock _textBlock, bool notEmpty)
|
|
{
|
|
var _retVal = false;
|
|
Brush _borderCaseNores = DefaultTextBoxBorderBrush;
|
|
if (notEmpty && string.IsNullOrWhiteSpace(_textBlock.Text))
|
|
{
|
|
_retVal = true;
|
|
_borderCaseNores = SharedValidationBorderBrush;
|
|
}
|
|
CaseNotesPreviewBorder.BorderBrush = _borderCaseNores;
|
|
return _retVal;
|
|
}
|
|
|
|
|
|
private static void setTextboxErrorState(object sender, bool hasError)
|
|
{
|
|
var textBox = sender as TextBox;
|
|
if (textBox == null)
|
|
return;
|
|
|
|
textBox.BorderBrush = hasError
|
|
? SharedValidationBorderBrush
|
|
: DefaultTextBoxBorderBrush;
|
|
}
|
|
|
|
private void UpdateCategoryValidationVisualState(bool hasError) =>
|
|
UpdateValidationBorderState(CategoryValidationBorder, ref defaultCategoryBorderBrush, ref defaultCategoryBorderThickness, hasError);
|
|
|
|
private void UpdateQuickTicketValidationVisualState(bool hasError) =>
|
|
UpdateValidationBorderState(QuickTicketValidationBorder, ref defaultQuickTicketBorderBrush, ref defaultQuickTicketBorderThickness, hasError);
|
|
|
|
private void UpdateTicketStatusValidationVisualState(bool hasError) =>
|
|
UpdateValidationBorderState(TicketStatusValidationBorder, ref defaultTicketStatusBorderBrush, ref defaultTicketStatusBorderThickness, hasError);
|
|
|
|
private void UpdateValidationBorderState(Border border, ref Brush defaultBrush, ref Thickness? defaultThickness, bool hasError)
|
|
{
|
|
if (border == null)
|
|
return;
|
|
|
|
if (defaultBrush == null)
|
|
{
|
|
var borderBrush = border.BorderBrush;
|
|
defaultBrush = borderBrush != null ? borderBrush.CloneCurrentValue() : null;
|
|
}
|
|
|
|
if (!defaultThickness.HasValue)
|
|
defaultThickness = border.BorderThickness;
|
|
|
|
border.BorderBrush = hasError ? validationErrorBrush : defaultBrush;
|
|
border.BorderThickness = hasError ? new Thickness(1) : defaultThickness ?? new Thickness(0);
|
|
}
|
|
|
|
|
|
|
|
#region DropDown
|
|
private static bool IsInsidePageable(FrameworkElement fe) => cUiElementHelper.GetFirstParentOfType<ComboBoxPageable>(fe) != null;
|
|
|
|
private void DropDownOpened(object sender, EventArgs e)
|
|
{
|
|
if (!(sender is FrameworkElement fe)) return;
|
|
if (IsInsidePageable(fe)) return; // ComboBoxPageable fired itself
|
|
|
|
var parentBorder = cUiElementHelper.GetFirstParentOfType<Border>(fe);
|
|
if (parentBorder != null)
|
|
cFocusInvoker.InvokeGotFocus(parentBorder, e);
|
|
}
|
|
|
|
private void DropDownClosed(object sender, EventArgs e)
|
|
{
|
|
if (!(sender is FrameworkElement fe)) return;
|
|
if (IsInsidePageable(fe)) return;
|
|
|
|
var parentBorder = cUiElementHelper.GetFirstParentOfType<Border>(fe);
|
|
if (parentBorder != null)
|
|
cFocusInvoker.InvokeLostFocus(parentBorder, e);
|
|
|
|
DynamicStatusAdditionBorder?.Focus();
|
|
}
|
|
|
|
#endregion
|
|
|
|
private void TicketSelectionPopUp_Closed(object sender, EventArgs e)
|
|
{
|
|
DropDownClosed(TicketSelectionBorder, e);
|
|
}
|
|
|
|
private void TransferCaseNotesCheck_Checked(object sender, RoutedEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
CaseNotesPreview?.ClearValue(OpacityProperty);
|
|
CaseNotesPreviewBorder?.ClearValue(IsHitTestVisibleProperty);
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
|
|
}
|
|
private void ComputerSelection_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
{
|
|
SelectedComputer = (cF4sdApiSearchResultRelation)ComputerSelection.SelectedItem;
|
|
}
|
|
|
|
private void QuickTicketSelection_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
{
|
|
ValidateProperty(ValidationPropertyNames.QuickTicketSelection);
|
|
}
|
|
|
|
private void TransferCaseNotesCheck_Unchecked(object sender, RoutedEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
if (CaseNotesPreview != null)
|
|
CaseNotesPreview.Opacity = 0.7;
|
|
|
|
if (CaseNotesPreviewBorder != null)
|
|
CaseNotesPreviewBorder.IsHitTestVisible = false;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
|
|
}
|
|
|
|
private void CloseCaseDialogUc_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
if (!(e.NewValue is bool isVisible && !isVisible))
|
|
return;
|
|
|
|
foreach (Window window in _openedWindows)
|
|
{
|
|
if (window is null)
|
|
continue;
|
|
|
|
window.Close();
|
|
}
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
|
|
}
|
|
|
|
private void Combobox_PreviewKeyDown(object sender, KeyEventArgs e)
|
|
{
|
|
if (e.Key == Key.Escape)
|
|
{
|
|
if (sender is FrameworkElement fe && IsInsidePageable(fe)) return;
|
|
DropDownClosed(sender, e);
|
|
}
|
|
}
|
|
}
|
|
}
|