diff --git a/BeWo/BeWo.csproj b/BeWo/BeWo.csproj
index 8b2f5a65d..9d06e26af 100644
--- a/BeWo/BeWo.csproj
+++ b/BeWo/BeWo.csproj
@@ -43,12 +43,12 @@
de-DE
BeWoPlaner
ownSoft GmbH
- 2.0.1.233
+ 2.0.1.240
true
publish.htm
false
true
- 234
+ 241
2.0.1.%2a
false
true
@@ -129,6 +129,7 @@
+
@@ -212,6 +213,26 @@
Designer
MSBuild:Compile
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
MSBuild:Compile
Designer
@@ -497,6 +518,10 @@
MSBuild:UpdateDesignTimeXaml
+
+ Designer
+ MSBuild:Compile
+
MSBuild:Compile
Designer
@@ -849,6 +874,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ AppointmentEditView.xaml
+
+
+ AppointmentRecurrenceEditView.xaml
+
+
+ OccurrenceParticipationConfirmationView.xaml
+
+
+ OpenAppointmentsView.xaml
+
+
+ SchedulingView.xaml
+
SchulbegleitenderDienstEmployeeView.xaml
@@ -969,6 +1035,7 @@
+
@@ -1233,6 +1300,9 @@
DokumenteView.xaml
+
+ SchedulingMasterView.xaml
+
TwoFactorAuthMessageDialog.xaml
@@ -2603,392 +2673,392 @@
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
False
+ Include
+ True
- Include
- True
Assembly
@@ -3117,6 +3187,12 @@
+<<<<<<< HEAD
+=======
+
+
+
+>>>>>>> master
diff --git a/BeWo/BeWo.csproj.user b/BeWo/BeWo.csproj.user
index 93dc2c0b3..3eff8c8d2 100644
--- a/BeWo/BeWo.csproj.user
+++ b/BeWo/BeWo.csproj.user
@@ -2,7 +2,7 @@
D:\Projects\beyondsoft\BeWoPlaner\Publish\|publish\|D:\Projects\beyondsoft\BeWoPlaner\PublishTest\|D:\Projects\beyondsoft\BeWoPlaner\PublishDev\|D:\Projects\beyondsoft\BeWoPlaner\Publish45\
- https://app.ownsoft.de/|https://app.ownsoft.de/dev/|http://app.ownsoft.de/dev/|http://app.beyondsoft.de/dev/|http://app.beyondsoft.de/
+ https://app.ownsoft.de/|https://app.ownsoft.de/test/|https://app.ownsoft.de/dev/|http://app.ownsoft.de/dev/|http://app.beyondsoft.de/dev/
https://app.ownsoft.de/|https://app.ownsoft.de/bewoplaner.application/
diff --git a/BeWo/BeWoApp.xaml.cs b/BeWo/BeWoApp.xaml.cs
index 4cdc2fc85..3a560fb8a 100644
--- a/BeWo/BeWoApp.xaml.cs
+++ b/BeWo/BeWoApp.xaml.cs
@@ -50,7 +50,7 @@ namespace BeWo
public static MainControl MainControl;
public static string ShortVersion = "3.20";
- public static string Version = "Version 3.20";
+ public static string Version = "Version 3.20.2";
public static int RenderTier = 0;
diff --git a/BeWo/Core/BeWoUtils.cs b/BeWo/Core/BeWoUtils.cs
index beae06e1a..aebbe9a58 100644
--- a/BeWo/Core/BeWoUtils.cs
+++ b/BeWo/Core/BeWoUtils.cs
@@ -60,6 +60,9 @@ using Control = System.Windows.Controls.Control;
using Utils = BS.Shared.Core.Utils;
using Brush = System.Windows.Media.Brush;
using BeWo.View.Detail.Zeiterfassung;
+using DevExpress.Xpf.Scheduling;
+using CommandBarStyle = DevExpress.Xpf.DocumentViewer.CommandBarStyle;
+using ImageSource = System.Windows.Media.ImageSource;
namespace BeWo.Core
{
@@ -2097,6 +2100,37 @@ namespace BeWo.Core
newView.ShowDialog();
}
+ // Zeiterfassungseintrag aus dem neuen Kalendermodul erstellen
+ public static void CreateZeiterfassung(DateTime start, DateTime end, List customer, List employees, String notice, AppointmentItem appointment, Action schedulerCallback)
+ {
+ ChatDokumentationsView newView;
+
+ if(customer.Count == 0)
+ {
+ // Normale Buchung
+ newView = new ChatDokumentationsView(notice, null, null, start, end, schedulerCallback, appointment);
+ }
+ else if(customer.Count == 1 && employees.Count < 2)
+ {
+ var compactKlient = ServiceFacade.DoCustomerServiceSync(s => s.GetCompactCustomerDC(customer[0].CustomerOid));
+
+ // Normale Buchung
+ newView = new ChatDokumentationsView(notice, compactKlient, employees.Count == 1 ? employees[0] : null, start, end, schedulerCallback, appointment);
+ }
+ else
+ {
+ if(employees.Count == 0)
+ {
+ employees.Add(BeWoApp.CompactLoggedOnEmployee);
+ }
+
+ // Gruppenbuchungen
+ newView = new ChatDokumentationsView(appointment, notice, start, end, customer, employees, schedulerCallback);
+ }
+
+ newView.ShowDialog();
+ }
+
public static void CreateZeiterfassung(DateTime start, DateTime end, List customer, List employees, String notice)
{
ChatDokumentationsView newView;
diff --git a/BeWo/Core/Config/AppSettings.cs b/BeWo/Core/Config/AppSettings.cs
index df315e236..5d44738d7 100644
--- a/BeWo/Core/Config/AppSettings.cs
+++ b/BeWo/Core/Config/AppSettings.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using BeWo.View.Navigation.Filter;
using BS.Shared;
+using DevExpress.Xpf.Scheduling;
using DevExpress.XtraScheduler;
namespace BeWo.Core.Config
@@ -462,6 +463,20 @@ namespace BeWo.Core.Config
}
}
+ private ViewType _SchedulingViewType;
+ public ViewType SchedulingViewType
+ {
+ get => _SchedulingViewType;
+ set
+ {
+ if(_SchedulingViewType != value)
+ {
+ _SchedulingViewType = value;
+ IsDirty = true;
+ }
+ }
+ }
+
private int _SchedulerTimelineViewDayCount;
public int SchedulerTimelineViewDayCount
{
diff --git a/BeWo/Core/Service/Cache.cs b/BeWo/Core/Service/Cache.cs
index 03b91b21b..837c44ef3 100644
--- a/BeWo/Core/Service/Cache.cs
+++ b/BeWo/Core/Service/Cache.cs
@@ -590,5 +590,51 @@ namespace BeWo.Core.Service
});
});
}
+
+
+ // Für neuen SchedulingView hinzugefügt
+ private List _FilteredCustomers;
+ public void GetAllActiveCustomersCompactForEmployee(long employeeOid, bool forceReload, Action> callback)
+ {
+ if(_FilteredCustomers is null || forceReload)
+ {
+ ServiceFacade.DoEmployeeServiceAsync(s => s.GetActiveCompactCustomersForEmployee(employeeOid), customers =>
+ {
+ customers.Sort((x, y) => $"{x.LastName}, {x.FirstName}".CompareTo($"{y.LastName}, {y.FirstName}"));
+ _FilteredCustomers = customers;
+ callback(customers);
+ });
+ }
+ else
+ {
+ callback(_FilteredCustomers);
+ }
+ }
+ public void ClearFilteredCustomers()
+ {
+ _FilteredCustomers = null;
+ }
+
+ private List _FilteredEmployees;
+ public void GetAllActiveCompactEmployeesForEmployee(long employeeOid, bool forceReload, Action> callback)
+ {
+ if(_FilteredEmployees is null || forceReload)
+ {
+ ServiceFacade.DoEmployeeServiceAsync(s => s.GetActiveCompactEmployeesForEmployee(employeeOid), employees =>
+ {
+ employees.Sort((x, y) => $"{x.LastName}, {x.FirstName}".CompareTo($"{y.LastName}, {y.FirstName}"));
+ _FilteredEmployees = employees;
+ callback(employees);
+ });
+ }
+ else
+ {
+ callback(_FilteredEmployees);
+ }
+ }
+ public void ClearFilteredEmployees()
+ {
+ _FilteredEmployees = null;
+ }
}
}
\ No newline at end of file
diff --git a/BeWo/LoginControl.xaml.cs b/BeWo/LoginControl.xaml.cs
index c2a9751be..39df78623 100644
--- a/BeWo/LoginControl.xaml.cs
+++ b/BeWo/LoginControl.xaml.cs
@@ -690,7 +690,7 @@ namespace BeWo
if (!isNet45OrNewer)
{
- if (!CheckStatusMessage(String.Format(GETNETMESSAGE_URL, profile.Tenant, BeWoApp.Version)))
+ if (!CheckStatusMessage(String.Format(GETNETMESSAGE_URL, profile.Tenant, BeWoApp.ShortVersion)))
{
return;
}
diff --git a/BeWo/MainControl.xaml b/BeWo/MainControl.xaml
index 20728c592..e5de4b7c2 100644
--- a/BeWo/MainControl.xaml
+++ b/BeWo/MainControl.xaml
@@ -294,6 +294,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
();
@@ -201,7 +215,8 @@ namespace BeWo
}
}
- } else if(ActiveView?.GetType() == typeof(HomeView))
+ }
+ else if(ActiveView?.GetType() == typeof(HomeView))
{
var homeDragPanelView = (HomeView) ActiveView;
homeDragPanelView.UpdateRequestsHyperLink();
@@ -268,6 +283,9 @@ namespace BeWo
case UIContext.CustomerTeam:
view = new CustomerTeamNavigationView();
break;
+ case UIContext.Scheduling:
+ view = new SchedulingMasterView();
+ break;
}
_Views[uiContext] = view;
}
@@ -1757,5 +1775,13 @@ namespace BeWo
NavigateTo(GetViewForUIContext(UIContext.Vertretungen));
}
}
+
+ private void Button_Scheduling_Click(object sender, RoutedEventArgs e)
+ {
+ if(DoSaveCheck())
+ {
+ NavigateTo(GetViewForUIContext(UIContext.Scheduling));
+ }
+ }
}
}
\ No newline at end of file
diff --git a/BeWo/Ressources/Icons/AB.png b/BeWo/Ressources/Icons/AB.png
new file mode 100644
index 000000000..0826fd292
Binary files /dev/null and b/BeWo/Ressources/Icons/AB.png differ
diff --git a/BeWo/Ressources/Icons/BoyAndGirl.png b/BeWo/Ressources/Icons/BoyAndGirl.png
new file mode 100644
index 000000000..6cd2fca7d
Binary files /dev/null and b/BeWo/Ressources/Icons/BoyAndGirl.png differ
diff --git a/BeWo/Ressources/Icons/CalendarDisabledUnderConstruction.png b/BeWo/Ressources/Icons/CalendarDisabledUnderConstruction.png
new file mode 100644
index 000000000..343ba124e
Binary files /dev/null and b/BeWo/Ressources/Icons/CalendarDisabledUnderConstruction.png differ
diff --git a/BeWo/Scheduler/Converter/BitmapToBitmapSourceConverter.cs b/BeWo/Scheduler/Converter/BitmapToBitmapSourceConverter.cs
index 525f4a3a7..483b851e9 100644
--- a/BeWo/Scheduler/Converter/BitmapToBitmapSourceConverter.cs
+++ b/BeWo/Scheduler/Converter/BitmapToBitmapSourceConverter.cs
@@ -1,6 +1,6 @@
using System;
+using System.Drawing;
using System.Globalization;
-using System.Windows;
using System.Windows.Data;
using System.Windows.Media;
using System.IO;
@@ -10,20 +10,19 @@ namespace BeWo.Scheduler.Converter
{
public class BitmapToBitmapSourceConverter : IValueConverter
{
-
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
//return null;
- System.Drawing.Bitmap source = value as System.Drawing.Bitmap;
- if (source == null || targetType != typeof(ImageSource))
+ if (!(value is Bitmap source) || targetType != typeof(ImageSource))
+ {
return null;
-
+ }
- MemoryStream stream = new MemoryStream();
+ var stream = new MemoryStream();
source.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
stream.Position = 0;
- BitmapImage result = new BitmapImage();
+ var result = new BitmapImage();
result.BeginInit();
result.StreamSource = stream;
result.EndInit();
@@ -31,14 +30,9 @@ namespace BeWo.Scheduler.Converter
return result;
}
-
-
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
}
-
-
-
}
\ No newline at end of file
diff --git a/BeWo/Scheduling/Converter/AppointmentBorderThicknessConverter.cs b/BeWo/Scheduling/Converter/AppointmentBorderThicknessConverter.cs
new file mode 100644
index 000000000..7968ed052
--- /dev/null
+++ b/BeWo/Scheduling/Converter/AppointmentBorderThicknessConverter.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Globalization;
+using System.Windows;
+using System.Windows.Data;
+using System.Windows.Media;
+
+namespace BeWo.Scheduling.Converter
+{
+ public class AppointmentBorderThicknessConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ var defaultThickness = new Thickness(0);
+
+ if(value is SolidColorBrush solidColorBrush)
+ {
+ return solidColorBrush.Color == Colors.Transparent ? defaultThickness : new Thickness(2);
+ }
+
+ return defaultThickness;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/BeWo/Scheduling/Converter/CustomerAndResourceBackgroundConverter.cs b/BeWo/Scheduling/Converter/CustomerAndResourceBackgroundConverter.cs
new file mode 100644
index 000000000..d8293d4bb
--- /dev/null
+++ b/BeWo/Scheduling/Converter/CustomerAndResourceBackgroundConverter.cs
@@ -0,0 +1,148 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Windows;
+using System.Windows.Data;
+using System.Windows.Media;
+using BeWo.Scheduler.ViewModel;
+using BS.Shared.DataContracts;
+using DevExpress.XtraScheduler;
+using ColorConverter = System.Windows.Media.ColorConverter;
+
+namespace BeWo.Scheduling.Converter
+{
+ public class CustomerAndResourceBackgroundConverter : IMultiValueConverter
+ {
+ public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
+ {
+ var farbe = Color.FromRgb(192, 255, 208);
+
+ try
+ {
+ if(!(values[0] is List selectedItems) || !selectedItems.Any())
+ {
+ return new LinearGradientBrush(new GradientStopCollection { new GradientStop(farbe, 1) }, new Point(.5, 0), new Point(.5, 1));
+ }
+
+ if(!(values[1] is CustomFieldCollection customViewInfo))
+ {
+ return new LinearGradientBrush(new GradientStopCollection { new GradientStop(farbe, 1) }, new Point(.5, 0), new Point(.5, 1));
+ }
+
+ var customFieldStorage = (CustomFieldStorage) customViewInfo[nameof(CustomFieldStorage)];
+
+ var isTask = customFieldStorage.IsTask;
+
+ if(isTask)
+ {
+ farbe = Color.FromRgb(153, 59, 59);
+ }
+
+ var aptCustomers = customFieldStorage.CustomerList;
+ var aptResources = customFieldStorage.ResourceList;
+
+ var gradientCollection = new GradientStopCollection();
+ var farbKollektion = new List();
+
+ if(selectedItems.Any(aptCustomers.Contains))
+ {
+ farbKollektion.Add(Color.FromRgb(59, 119, 153));
+ }
+
+ if(selectedItems.Any(aptResources.Contains))
+ {
+ farbKollektion.Add(Color.FromRgb(4, 180, 208));
+ }
+
+ switch(farbKollektion.Count)
+ {
+ case 1:
+ if(BeWoApp.AppSettings.ShowMultipleResourceColors)
+ {
+ AddResourceColors(gradientCollection, aptResources, false);
+ }
+ else
+ {
+ var first = aptResources.FirstOrDefault();
+
+ gradientCollection.Add(first != null ? new GradientStop((Color) (ColorConverter.ConvertFromString(first.Color) ?? Color.FromRgb(4, 180, 208)), 1) : new GradientStop(farbKollektion[0], 1));
+ }
+
+ break;
+ case 2:
+ // 1. Klientenfarbe
+ gradientCollection.Add(new GradientStop(farbKollektion[0], 0.5));
+
+ // 2. Resourcenfarben
+ if(BeWoApp.AppSettings.ShowMultipleResourceColors)
+ {
+ AddResourceColors(gradientCollection, aptResources, true);
+ }
+ else
+ {
+ var first2 = aptResources.FirstOrDefault();
+
+ if(first2 != null)
+ {
+ gradientCollection.Add(new GradientStop((Color) (ColorConverter.ConvertFromString(first2.Color) ?? Color.FromRgb(4, 180, 208)), 0.5));
+ }
+ }
+
+ break;
+ default:
+ gradientCollection.Add(new GradientStop(farbe, 1));
+ break;
+ }
+
+ return new LinearGradientBrush(gradientCollection, new Point(.5, 0), new Point(.5, 1));
+ }
+ catch(Exception)
+ {
+ return new LinearGradientBrush(new GradientStopCollection { new GradientStop(farbe, 1) }, new Point(.5, 0), new Point(.5, 1));
+ }
+ }
+
+ public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+
+ private static void AddResourceColors(GradientStopCollection gradientCollection, IReadOnlyList resourceList, bool hasCustomers)
+ {
+ var previousOffset = hasCustomers ? 0.5 : 0;
+
+ var numberOfResources = resourceList.Count;
+
+ if(numberOfResources == 0)
+ {
+ return;
+ }
+
+ if(numberOfResources > 4)
+ {
+ numberOfResources = 4;
+ }
+
+ var iterator = hasCustomers == false ? 1d / numberOfResources : previousOffset / numberOfResources;
+
+ for(var i = 0; i < numberOfResources; i++)
+ {
+ var resource = resourceList[i];
+
+ var currentOffset = previousOffset;
+ var nextOffset = currentOffset + iterator;
+
+ if(nextOffset > 1)
+ {
+ nextOffset = 1;
+ }
+
+ previousOffset = nextOffset;
+
+ gradientCollection.Add(new GradientStop((Color) (ColorConverter.ConvertFromString(resource.Color) ?? Color.FromRgb(4, 180, 208)), currentOffset));
+ gradientCollection.Add(new GradientStop((Color) (ColorConverter.ConvertFromString(resource.Color) ?? Color.FromRgb(4, 180, 208)), nextOffset));
+ }
+ }
+ }
+}
diff --git a/BeWo/Scheduling/Converter/DayViewDayCountVisibilityConverter.cs b/BeWo/Scheduling/Converter/DayViewDayCountVisibilityConverter.cs
new file mode 100644
index 000000000..d02850fd4
--- /dev/null
+++ b/BeWo/Scheduling/Converter/DayViewDayCountVisibilityConverter.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Globalization;
+using System.Windows;
+using System.Windows.Data;
+
+namespace BeWo.Scheduling.Converter
+{
+ public class DayViewDayCountVisibilityConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if(value is DevExpress.Xpf.Scheduling.ViewType.DayView && parameter is string stringParameter && stringParameter == "DayCount")
+ {
+ return Visibility.Visible;
+ }
+ else if(value is DevExpress.Xpf.Scheduling.ViewType.TimelineView && parameter is string strParameter && strParameter == "IntervalCount")
+ {
+ return Visibility.Visible;
+ }
+
+ return Visibility.Collapsed;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/BeWo/Scheduling/Converter/EmployeeBackgroundColorConverter.cs b/BeWo/Scheduling/Converter/EmployeeBackgroundColorConverter.cs
new file mode 100644
index 000000000..05b0006fd
--- /dev/null
+++ b/BeWo/Scheduling/Converter/EmployeeBackgroundColorConverter.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Globalization;
+using System.Windows.Data;
+using System.Windows.Media;
+
+namespace BeWo.Scheduling.Converter
+{
+ public class EmployeeBackgroundColorConverter : IMultiValueConverter
+ {
+ public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
+ {
+ if(values.Length == 3 && values[0] is bool showEmployeeBackgroundColor && values[1] is LinearGradientBrush backgroundBrush && values[2] is SolidColorBrush defaultBackgroundColor)
+ {
+ return showEmployeeBackgroundColor ? new SolidColorBrush(backgroundBrush.GradientStops[0].Color) : defaultBackgroundColor;
+ }
+
+ return new SolidColorBrush(Color.FromRgb(192, 255, 208));
+ }
+
+ public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/BeWo/Scheduling/Converter/EmployeeListConfirmationToolTipConverter.cs b/BeWo/Scheduling/Converter/EmployeeListConfirmationToolTipConverter.cs
new file mode 100644
index 000000000..cb085fe2b
--- /dev/null
+++ b/BeWo/Scheduling/Converter/EmployeeListConfirmationToolTipConverter.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Globalization;
+using System.Windows.Data;
+using System.Windows.Media;
+using BS.Shared;
+using BS.Shared.DataContracts;
+
+namespace BeWo.Scheduling.Converter
+{
+ public class EmployeeListConfirmationToolTipConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if(value is Employee2SchedulerAppointmentDC e2s)
+ {
+ if(parameter?.Equals("EmployeeName") ?? false)
+ {
+ return e2s.Employee?.DetailDescription;
+ }
+
+ var color = Color.FromRgb(255, 255, 255);
+
+ switch(e2s.ParticipationAnswer)
+ {
+ case ParticipationAnswer.Vorbehalt:
+ color = Color.FromRgb(185, 39, 217);
+ break;
+ case ParticipationAnswer.Zusage:
+ color = Color.FromRgb(72, 212, 78);
+ break;
+ case ParticipationAnswer.Absage:
+ color = Color.FromRgb(171, 0, 48);
+ break;
+ }
+
+ return new SolidColorBrush(color);
+ }
+
+ return null;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
\ No newline at end of file
diff --git a/BeWo/Scheduling/Converter/InfoButtonVisibilityConverter.cs b/BeWo/Scheduling/Converter/InfoButtonVisibilityConverter.cs
new file mode 100644
index 000000000..ae3f392fc
--- /dev/null
+++ b/BeWo/Scheduling/Converter/InfoButtonVisibilityConverter.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Globalization;
+using System.Windows;
+using System.Windows.Data;
+
+namespace BeWo.Scheduling.Converter
+{
+ public class InfoButtonVisibilityConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return BeWoApp.AppSettings.ShowInfoButtonInCalender ? Visibility.Visible : Visibility.Collapsed;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/BeWo/Scheduling/Converter/ParticipationRequestListViewConverter.cs b/BeWo/Scheduling/Converter/ParticipationRequestListViewConverter.cs
new file mode 100644
index 000000000..c6481511a
--- /dev/null
+++ b/BeWo/Scheduling/Converter/ParticipationRequestListViewConverter.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Globalization;
+using System.Linq;
+using System.Windows.Data;
+using BeWo.Scheduling.ViewModel;
+using BS.Shared;
+
+namespace BeWo.Scheduling.Converter
+{
+ public class ParticipationRequestListViewConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if(value is SchedulingAppointmentVM appointment)
+ {
+ if(appointment.LabelKey is null)
+ {
+ return $"{appointment.Start.ToShortDateString()}; {appointment.Subject}";
+ }
+
+ var participationAnswer = string.Empty;
+
+ var correspondingRelation = appointment.EmployeeList.ToList().Find(e2a => e2a.Employee2SchedulerAppointmentOid == appointment.LabelKey);
+
+ switch(correspondingRelation.ParticipationAnswer)
+ {
+ case ParticipationAnswer.Zusage:
+ participationAnswer = "zugesagt";
+ break;
+ case ParticipationAnswer.Vorbehalt:
+ participationAnswer = "mit Vorbehalt zugesagt";
+ break;
+ case ParticipationAnswer.Absage:
+ participationAnswer = "abgesagt";
+ break;
+ }
+
+ return $"{appointment.Start.ToShortDateString()}: {correspondingRelation.Employee.FirstNameLastName} hat {participationAnswer}";
+ }
+
+ return string.Empty;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/BeWo/Scheduling/Converter/RecurringAppointmentDurationConverter.cs b/BeWo/Scheduling/Converter/RecurringAppointmentDurationConverter.cs
new file mode 100644
index 000000000..491ee1341
--- /dev/null
+++ b/BeWo/Scheduling/Converter/RecurringAppointmentDurationConverter.cs
@@ -0,0 +1,208 @@
+using System;
+using System.Globalization;
+using System.Windows.Data;
+using BeWo.Scheduling.ViewModel;
+using DevExpress.XtraScheduler;
+
+namespace BeWo.Scheduling.Converter
+{
+ public class RecurringAppointmentDurationConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if(value is null)
+ {
+ return null;
+ }
+
+ var appointment = (SchedulingAppointmentVM) value;
+
+ if(appointment.RecurrenceInfo is null)
+ {
+ return string.Empty;
+ }
+
+ IRecurrenceInfo recurrenceInfo = new RecurrenceInfo();
+ recurrenceInfo.FromXml(appointment.RecurrenceInfo);
+
+ var rangeString = string.Empty;
+ var suffix = string.Empty;
+ var periodicity = recurrenceInfo.Periodicity;
+ var intervalPlural = string.Empty;
+ var weekDays = string.Empty;
+ string weekOfMonth;
+
+ switch(recurrenceInfo.Range)
+ {
+ case RecurrenceRange.EndByDate:
+ rangeString += $"bis zum {recurrenceInfo.End.ToShortDateString()} ";
+ break;
+ case RecurrenceRange.OccurrenceCount:
+ rangeString += $"{recurrenceInfo.OccurrenceCount} mal ";
+ break;
+ }
+
+ switch(recurrenceInfo.Type)
+ {
+ case RecurrenceType.Daily:
+ if(periodicity == 1)
+ {
+ suffix = recurrenceInfo.WeekDays.Equals(WeekDays.WorkDays) ? "jeden Arbeitstag " : "täglich ";
+ }
+
+ intervalPlural = " Tage ";
+
+ break;
+ case RecurrenceType.Weekly:
+ if(periodicity == 1)
+ {
+ suffix = "wöchentlich ";
+ }
+
+ intervalPlural = " Wochen ";
+
+ weekDays = TranslateWorkDays(recurrenceInfo.WeekDays.ToString(), true);
+
+ break;
+ case RecurrenceType.Yearly:
+ weekDays = TranslateWorkDays(recurrenceInfo.WeekDays.ToString(), false);
+ weekOfMonth = TranslateWeekOfMonth(recurrenceInfo.WeekOfMonth);
+ var tag = recurrenceInfo.DayNumber;
+
+ suffix = "jährlich ";
+
+ if(recurrenceInfo.WeekOfMonth != WeekOfMonth.None)
+ {
+ suffix += $"jeden {weekOfMonth}{weekDays}im {GetMonthByInt(recurrenceInfo.Month)}";
+ }
+ else
+ {
+ suffix += $"am {tag}. {GetMonthByInt(recurrenceInfo.Month)}";
+ }
+
+ weekDays = string.Empty;
+
+ break;
+ case RecurrenceType.Monthly:
+ string monatlichesInterval;
+
+ if(recurrenceInfo.WeekOfMonth != WeekOfMonth.None)
+ {
+ weekOfMonth = TranslateWeekOfMonth(recurrenceInfo.WeekOfMonth);
+ weekDays = TranslateWorkDays(recurrenceInfo.WeekDays.ToString(), false);
+
+ suffix = $"jeden {weekOfMonth}{weekDays}";
+
+ monatlichesInterval = periodicity == 1 ? "jedes Monats " : $"jedes {periodicity}. Monats ";
+
+ suffix += monatlichesInterval;
+ weekDays = "";
+ }
+ else
+ {
+ monatlichesInterval = periodicity == 1 ? "jedes Monats " : $"jedes {periodicity}. Monats ";
+
+ suffix = $"am {recurrenceInfo.DayNumber}. {monatlichesInterval}";
+ weekDays = string.Empty;
+ }
+
+ break;
+ }
+
+ if(periodicity > 1 && recurrenceInfo.Type != RecurrenceType.Monthly)
+ {
+ suffix = $"alle {periodicity}{intervalPlural}";
+ }
+
+ return $"Dieser Termin wird {rangeString}{suffix}{weekDays}wiederholt";
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+
+ private static string TranslateWorkDays(string weekDays, bool mitGenitivS)
+ {
+ weekDays = weekDays.Replace("Monday", mitGenitivS ? "Montags" : "Montag");
+ weekDays = weekDays.Replace("Tuesday", mitGenitivS ? "Dienstags" : "Dienstag");
+ weekDays = weekDays.Replace("Wednesday", mitGenitivS ? "Mittwochs" : "Mittwoch");
+ weekDays = weekDays.Replace("Thursday", mitGenitivS ? "Donnerstags" : "Donnerstag");
+ weekDays = weekDays.Replace("Friday", mitGenitivS ? "Freitags" : "Freitag");
+ weekDays = weekDays.Replace("Saturday", mitGenitivS ? "Samstags" : "Samstag");
+ weekDays = weekDays.Replace("Sunday", mitGenitivS ? "Sonntags" : "Sonntag");
+ weekDays = weekDays.Replace("EveryDay", "jeden Tag");
+
+ var lastComma = weekDays.LastIndexOf(',');
+ if(lastComma != -1)
+ {
+ weekDays = weekDays.Remove(lastComma, 1).Insert(lastComma, " und");
+ }
+
+ return weekDays + " ";
+ }
+
+ private static string TranslateWeekOfMonth(WeekOfMonth weekOfMonth)
+ {
+ var result = " ";
+
+ switch(weekOfMonth)
+ {
+ case WeekOfMonth.First:
+ result = "ersten ";
+ break;
+ case WeekOfMonth.Second:
+ result = "zweiten ";
+ break;
+ case WeekOfMonth.Third:
+ result = "dritten ";
+ break;
+ case WeekOfMonth.Fourth:
+ result = "vierten ";
+ break;
+ case WeekOfMonth.Last:
+ result = "letzten ";
+ break;
+ case WeekOfMonth.None:
+ return result;
+ default:
+ return result;
+ }
+
+ return result;
+ }
+
+ private static string GetMonthByInt(int month)
+ {
+ switch(month)
+ {
+ case 1:
+ return "Januar ";
+ case 2:
+ return "Februar ";
+ case 3:
+ return "März ";
+ case 4:
+ return "April ";
+ case 5:
+ return "Mai ";
+ case 6:
+ return "Juni ";
+ case 7:
+ return "Juli ";
+ case 8:
+ return "August ";
+ case 9:
+ return "September ";
+ case 10:
+ return "Oktober ";
+ case 11:
+ return "November ";
+ case 12:
+ return "Dezember ";
+ default:
+ return " ";
+ }
+ }
+ }
+}
diff --git a/BeWo/Scheduling/Converter/RequestVisibilityConverter.cs b/BeWo/Scheduling/Converter/RequestVisibilityConverter.cs
new file mode 100644
index 000000000..7d2dca4bf
--- /dev/null
+++ b/BeWo/Scheduling/Converter/RequestVisibilityConverter.cs
@@ -0,0 +1,73 @@
+using System;
+using System.Globalization;
+using System.Windows;
+using System.Windows.Data;
+using BeWo.Scheduling.ViewModel;
+using DevExpress.XtraScheduler;
+
+namespace BeWo.Scheduling.Converter
+{
+ public class RequestVisibilityConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if(value is null)
+ {
+ return Visibility.Collapsed;
+ }
+
+ var appointment = (SchedulingAppointmentVM) value;
+
+ var hasNoEnd = false;
+ var liesInPast = appointment.Start < DateTime.Now && appointment.End < DateTime.Now;
+
+ if(!(appointment.RecurrenceInfo is null))
+ {
+ IRecurrenceInfo recurrenceInfo = new RecurrenceInfo();
+ recurrenceInfo.FromXml(appointment.RecurrenceInfo);
+
+ hasNoEnd = recurrenceInfo.Range == RecurrenceRange.NoEndDate;
+ liesInPast = recurrenceInfo.Start < DateTime.Now && recurrenceInfo.End < DateTime.Now;
+ }
+
+ if(parameter?.Equals("ZusagenStack") ?? false)
+ {
+ if(appointment.LabelKey.HasValue)
+ {
+ return Visibility.Collapsed;
+ }
+
+ var shouldBeVisible = !liesInPast;
+
+ if(!(appointment.RecurrenceInfo is null))
+ {
+ shouldBeVisible = !liesInPast || hasNoEnd;
+ }
+
+ return shouldBeVisible ? Visibility.Visible : Visibility.Collapsed;
+ }
+
+ if(parameter?.Equals("OKBtn") ?? false)
+ {
+ return (appointment.LabelKey.HasValue || liesInPast) && !hasNoEnd ? Visibility.Visible : Visibility.Collapsed;
+ }
+
+ if(parameter?.Equals("TerminVerstrichen") ?? false)
+ {
+ return liesInPast && !hasNoEnd ? Visibility.Visible : Visibility.Collapsed;
+ }
+
+ if(parameter?.Equals("SerienterminLabel") ?? false)
+ {
+ return !(appointment.RecurrenceInfo is null) ? Visibility.Visible : Visibility.Collapsed;
+ }
+
+ return appointment.LabelKey.HasValue || liesInPast ? Visibility.Visible : Visibility.Collapsed;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/BeWo/Scheduling/Converter/SchedulingBackgroundConverter.cs b/BeWo/Scheduling/Converter/SchedulingBackgroundConverter.cs
new file mode 100644
index 000000000..bf49375c9
--- /dev/null
+++ b/BeWo/Scheduling/Converter/SchedulingBackgroundConverter.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Globalization;
+using System.Windows.Data;
+using System.Windows.Media;
+using BS.Shared.DataContracts;
+using BS.Shared.DataContracts.Compact;
+
+namespace BeWo.Scheduling.Converter
+{
+ public class SchedulingBackgroundConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ var employeeBrush = new SolidColorBrush(Color.FromArgb(255, 69, 153, 59));
+ var customerBrush = new SolidColorBrush(Color.FromArgb(255, 59, 119, 153));
+ var resourceBrush = new SolidColorBrush(Color.FromArgb(255, 4, 180, 208));
+ var supportConceptBrush = new SolidColorBrush(Color.FromArgb(255, 153, 59, 59));
+
+ if(value is CompactEmployeeDC || value is Employee2SchedulerAppointmentDC)
+ {
+ return employeeBrush;
+ }
+
+ if(value is CompactCustomerDC)
+ {
+ return customerBrush;
+ }
+
+ if(value is CompactSupportConceptDC)
+ {
+ return supportConceptBrush;
+ }
+
+ return resourceBrush;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/BeWo/Scheduling/Converter/SchedulingCheckBoxConverter.cs b/BeWo/Scheduling/Converter/SchedulingCheckBoxConverter.cs
new file mode 100644
index 000000000..653a59ed9
--- /dev/null
+++ b/BeWo/Scheduling/Converter/SchedulingCheckBoxConverter.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Globalization;
+using System.Linq;
+using System.Windows.Data;
+using BeWo.Scheduling.ViewModel;
+
+namespace BeWo.Scheduling.Converter
+{
+ public class SchedulingCheckBoxConverter : IMultiValueConverter
+ {
+ public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
+ {
+ if(values.Length < 2 || parameter == null)
+ {
+ return false;
+ }
+
+ var oid = (long) values[0];
+ var viewModel = (SchedulingAppointmentListVM) values[1];
+
+ switch(parameter.ToString())
+ {
+ case "Klienten":
+ return viewModel.SelectedCustomers.Any(item => item.CustomerOid == oid);
+ default:
+ return false;
+ }
+ }
+
+ public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/BeWo/Scheduling/Converter/SchedulingInformationVisibilityConverter.cs b/BeWo/Scheduling/Converter/SchedulingInformationVisibilityConverter.cs
new file mode 100644
index 000000000..bd9514312
--- /dev/null
+++ b/BeWo/Scheduling/Converter/SchedulingInformationVisibilityConverter.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Globalization;
+using System.Windows;
+using System.Windows.Data;
+using BS.Shared.DataContracts.Compact;
+
+namespace BeWo.Scheduling.Converter
+{
+ public class SchedulingInformationVisibilityConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return value is CompactCustomerDC ? Visibility.Visible : (object) Visibility.Collapsed;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/BeWo/Scheduling/Converter/SchedulingParticipationBrushConverter.cs b/BeWo/Scheduling/Converter/SchedulingParticipationBrushConverter.cs
new file mode 100644
index 000000000..6a29c16c1
--- /dev/null
+++ b/BeWo/Scheduling/Converter/SchedulingParticipationBrushConverter.cs
@@ -0,0 +1,54 @@
+using System;
+using System.Globalization;
+using System.Windows.Data;
+using System.Windows.Media;
+using BS.Shared;
+using BS.Shared.DataContracts;
+
+namespace BeWo.Scheduling.Converter
+{
+ public class SchedulingParticipationBrushConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ var offen = new SolidColorBrush(Color.FromRgb(255, 255, 255));
+ var zusage = new SolidColorBrush(Color.FromRgb(72, 212, 78));
+ var absage = new SolidColorBrush(Color.FromRgb(171, 0, 48));
+ var mitVorbehalt = new SolidColorBrush(Color.FromRgb(185, 39, 217));
+
+ if((string) parameter == "Border")
+ if(value is Employee2SchedulerAppointmentDC)
+ {
+ return new SolidColorBrush(Colors.Black);
+ }
+ else
+ {
+ return new SolidColorBrush(Colors.Transparent);
+ }
+
+ if(value is Employee2SchedulerAppointmentDC wert)
+ {
+ switch(wert.ParticipationAnswer)
+ {
+ case ParticipationAnswer.Zusage:
+ return zusage;
+ case ParticipationAnswer.Absage:
+ return absage;
+ case ParticipationAnswer.Vorbehalt:
+ return mitVorbehalt;
+ }
+ }
+ else
+ {
+ return new SolidColorBrush(Colors.Transparent);
+ }
+
+ return offen;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/BeWo/Scheduling/Converter/SchedulingRemoveElementVisibilityConverter.cs b/BeWo/Scheduling/Converter/SchedulingRemoveElementVisibilityConverter.cs
new file mode 100644
index 000000000..204ef32ed
--- /dev/null
+++ b/BeWo/Scheduling/Converter/SchedulingRemoveElementVisibilityConverter.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Globalization;
+using System.Windows;
+using System.Windows.Data;
+
+namespace BeWo.Scheduling.Converter
+{
+ public class SchedulingRemoveElementVisibilityConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ //if(value == null)
+ //{
+ return Visibility.Visible;
+ //}
+
+ //var isNew = SchedulerAppointmentEditForm.IsNew;
+
+ //var isAllowedToChange = BeWoUtils.CheckSchedulerRights(SchedulerAppointmentEditForm.CurrentAppointment, isNew, SchedulerRightsCheckType.Edit);
+
+
+ //return isAllowedToChange ? Visibility.Visible : Visibility.Hidden;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/BeWo/Scheduling/Converter/SchedulingTextFromIDataContractConverter.cs b/BeWo/Scheduling/Converter/SchedulingTextFromIDataContractConverter.cs
new file mode 100644
index 000000000..b472105e6
--- /dev/null
+++ b/BeWo/Scheduling/Converter/SchedulingTextFromIDataContractConverter.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Globalization;
+using System.Windows.Data;
+using BS.Shared.DataContracts;
+
+namespace BeWo.Scheduling.Converter
+{
+ public class SchedulingTextFromIDataContractConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if(value is ResourceDC resourceDC)
+ {
+ return resourceDC.Name;
+ }
+
+ if(value is Employee2SchedulerAppointmentDC dc)
+ {
+ return dc.Employee.SimpleDescription;
+ }
+
+ var filterableDC = value as IFilterableDC;
+
+ return filterableDC?.SimpleDescription;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/BeWo/Scheduling/Converter/WidthAdditionMultiConverter.cs b/BeWo/Scheduling/Converter/WidthAdditionMultiConverter.cs
new file mode 100644
index 000000000..fcaf6857e
--- /dev/null
+++ b/BeWo/Scheduling/Converter/WidthAdditionMultiConverter.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Globalization;
+using System.Windows.Data;
+
+namespace BeWo.Scheduling.Converter
+{
+ public class WidthAdditionMultiConverter : IMultiValueConverter
+ {
+ public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
+ {
+ var w1 = System.Convert.ToDouble(values[0]);
+ var w2 = System.Convert.ToDouble(values[1]);
+
+ return w1 + w2;
+ }
+
+ public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/BeWo/Scheduling/SchedulingUtils/AppointmentColorHelper.cs b/BeWo/Scheduling/SchedulingUtils/AppointmentColorHelper.cs
new file mode 100644
index 000000000..9c5021ac3
--- /dev/null
+++ b/BeWo/Scheduling/SchedulingUtils/AppointmentColorHelper.cs
@@ -0,0 +1,117 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows;
+using System.Windows.Media;
+
+namespace BeWo.Scheduling.SchedulingUtils
+{
+ public class AppointmentColorHelper
+ {
+ public LinearGradientBrush ResourceAndCustomerBackground { get; set; }
+ public LinearGradientBrush EmployeeBackground { get; set; }
+
+ public AppointmentColorHelper(Color employeeColor, List resourceColors, bool hasCustomers, bool isTask)
+ {
+ var defaultColor = isTask ? Color.FromRgb(153, 59, 59) : Color.FromRgb(192, 255, 208);
+
+ EmployeeBackground = new LinearGradientBrush(new GradientStopCollection { new GradientStop(employeeColor, 1) }, new Point(0, 0), new Point(0, 1));
+
+ if(resourceColors is null)
+ {
+ resourceColors = new List();
+ }
+
+ // Weder Ressourcen noch Klienten vorhanden
+ if(!resourceColors.Any() && !hasCustomers)
+ {
+ ResourceAndCustomerBackground = new LinearGradientBrush(new GradientStopCollection { new GradientStop(defaultColor, 1) }, new Point(.5, 0), new Point(.5, 1));
+ }
+
+ var colorList = new List();
+ var gradientStopCollection = new GradientStopCollection();
+
+ if(hasCustomers)
+ {
+ colorList.Add(Color.FromRgb(59, 119, 153));
+ }
+
+ if(resourceColors.Any())
+ {
+ colorList.Add(Color.FromRgb(4, 180, 208));
+ }
+
+ switch(colorList.Count)
+ {
+ case 1:
+ if(BeWoApp.AppSettings.ShowMultipleResourceColors)
+ {
+ AddResourceColors(gradientStopCollection, resourceColors, hasCustomers);
+ }
+ else
+ {
+ var color = resourceColors.Count >= 1 ? resourceColors[0] : Color.FromRgb(4, 180, 208);
+
+ var gradientStop = new GradientStop(color, 1);
+ gradientStopCollection.Add(gradientStop);
+ }
+ break;
+ case 2:
+ // 1. Klientenfarbe
+ gradientStopCollection.Add(new GradientStop(colorList[0], .5));
+
+ // 2. Ressourcenfarben
+ if(BeWoApp.AppSettings.ShowMultipleResourceColors)
+ {
+ AddResourceColors(gradientStopCollection, resourceColors, hasCustomers);
+ }
+ else
+ {
+ var color = resourceColors.Count >= 1 ? resourceColors[0] : Color.FromRgb(4, 180, 208);
+
+ gradientStopCollection.Add(new GradientStop(color, .5));
+ }
+ break;
+ default:
+ gradientStopCollection.Add(new GradientStop(defaultColor, 1));
+ break;
+ }
+
+ ResourceAndCustomerBackground = new LinearGradientBrush(gradientStopCollection, new Point(.5, 0), new Point(.5, 1));
+ }
+
+ private static void AddResourceColors(GradientStopCollection gradientStopCollection, List resourceColors, bool hasCustomers)
+ {
+ var previousOffset = hasCustomers ? .5 : 0;
+
+ var numberOfResources = resourceColors.Count;
+
+ if(numberOfResources == 0)
+ {
+ return;
+ }
+
+ if(numberOfResources > 4)
+ {
+ numberOfResources = 4;
+ }
+
+ var iterator = hasCustomers ? previousOffset / numberOfResources : 1d / numberOfResources;
+
+ for(var i = 0; i < numberOfResources; i++)
+ {
+ var currentOffset = previousOffset;
+ var nextOffset = currentOffset + iterator;
+
+ if(nextOffset > 1)
+ {
+ nextOffset = 1;
+ }
+
+ previousOffset = nextOffset;
+
+ gradientStopCollection.Add(new GradientStop(resourceColors[i], currentOffset));
+ gradientStopCollection.Add(new GradientStop(resourceColors[i], nextOffset));
+ }
+ }
+ }
+}
diff --git a/BeWo/Scheduling/SchedulingUtils/CategoryDependencyObject.cs b/BeWo/Scheduling/SchedulingUtils/CategoryDependencyObject.cs
new file mode 100644
index 000000000..7cc9af49a
--- /dev/null
+++ b/BeWo/Scheduling/SchedulingUtils/CategoryDependencyObject.cs
@@ -0,0 +1,15 @@
+using System.Windows;
+using BS.Shared.DataContracts;
+
+namespace BeWo.Scheduling.SchedulingUtils
+{
+ public class CategoryDependencyObject : DependencyObject
+ {
+ public ValueListEntryDC ResourceCategory { get; }
+
+ public CategoryDependencyObject(ValueListEntryDC category)
+ {
+ ResourceCategory = category;
+ }
+ }
+}
diff --git a/BeWo/Scheduling/SchedulingUtils/EmployeeDependencyObject.cs b/BeWo/Scheduling/SchedulingUtils/EmployeeDependencyObject.cs
new file mode 100644
index 000000000..cad20a211
--- /dev/null
+++ b/BeWo/Scheduling/SchedulingUtils/EmployeeDependencyObject.cs
@@ -0,0 +1,15 @@
+using System.Windows;
+using BS.Shared.DataContracts.Compact;
+
+namespace BeWo.Scheduling.SchedulingUtils
+{
+ public class EmployeeDependencyObject : DependencyObject
+ {
+ public CompactEmployeeDC Employee { get; }
+
+ public EmployeeDependencyObject(CompactEmployeeDC employee)
+ {
+ Employee = employee;
+ }
+ }
+}
diff --git a/BeWo/Scheduling/SchedulingUtils/ListItemHelper.cs b/BeWo/Scheduling/SchedulingUtils/ListItemHelper.cs
new file mode 100644
index 000000000..6a447920f
--- /dev/null
+++ b/BeWo/Scheduling/SchedulingUtils/ListItemHelper.cs
@@ -0,0 +1,19 @@
+using System.Windows;
+
+namespace BeWo.Scheduling.SchedulingUtils
+{
+ public class ListItemHelper : DependencyObject
+ {
+ public static readonly DependencyProperty IsCheckedProperty = DependencyProperty.RegisterAttached("IsChecked", typeof(bool?), typeof(ListItemHelper), new PropertyMetadata(false, null));
+
+ public static void SetIsChecked(DependencyObject element, bool? isChecked)
+ {
+ element.SetValue(IsCheckedProperty, isChecked);
+ }
+
+ public static bool? GetIsChecked(DependencyObject element)
+ {
+ return (bool?) element.GetValue(IsCheckedProperty);
+ }
+ }
+}
diff --git a/BeWo/Scheduling/SchedulingUtils/ResourceDependencyObject.cs b/BeWo/Scheduling/SchedulingUtils/ResourceDependencyObject.cs
new file mode 100644
index 000000000..7d05f40e7
--- /dev/null
+++ b/BeWo/Scheduling/SchedulingUtils/ResourceDependencyObject.cs
@@ -0,0 +1,15 @@
+using System.Windows;
+using BS.Shared.DataContracts;
+
+namespace BeWo.Scheduling.SchedulingUtils
+{
+ public class ResourceDependencyObject : DependencyObject
+ {
+ public ResourceDC DataContract { get; }
+
+ public ResourceDependencyObject(ResourceDC resource)
+ {
+ DataContract = resource;
+ }
+ }
+}
diff --git a/BeWo/Scheduling/SchedulingUtils/TreeViewItemHelper.cs b/BeWo/Scheduling/SchedulingUtils/TreeViewItemHelper.cs
new file mode 100644
index 000000000..89255a263
--- /dev/null
+++ b/BeWo/Scheduling/SchedulingUtils/TreeViewItemHelper.cs
@@ -0,0 +1,31 @@
+using System.Windows;
+
+namespace BeWo.Scheduling.SchedulingUtils
+{
+ public class TreeViewItemHelper : DependencyObject
+ {
+ public static readonly DependencyProperty IsCheckedProperty = DependencyProperty.RegisterAttached("IsChecked", typeof(bool?), typeof(TreeViewItemHelper), new PropertyMetadata(false, null));
+
+ public static void SetIsChecked(DependencyObject element, bool? isChecked)
+ {
+ element.SetValue(IsCheckedProperty, isChecked);
+ }
+
+ public static bool? GetIsChecked(DependencyObject element)
+ {
+ return (bool?) element.GetValue(IsCheckedProperty);
+ }
+
+ public static readonly DependencyProperty ParentProperty = DependencyProperty.RegisterAttached("Parent", typeof(object), typeof(TreeViewItemHelper));
+
+ public static void SetParent(DependencyObject element, object Parent)
+ {
+ element.SetValue(ParentProperty, Parent);
+ }
+
+ public static object GetParent(DependencyObject element)
+ {
+ return element.GetValue(ParentProperty);
+ }
+ }
+}
diff --git a/BeWo/Scheduling/SchedulingUtils/Utils.cs b/BeWo/Scheduling/SchedulingUtils/Utils.cs
new file mode 100644
index 000000000..b1a756f24
--- /dev/null
+++ b/BeWo/Scheduling/SchedulingUtils/Utils.cs
@@ -0,0 +1,193 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+using BeWo.Scheduling.ViewModel;
+using BS.Shared;
+using BS.Shared.Core;
+using BS.Shared.DataContracts;
+using BS.Shared.DataContracts.Compact;
+using BS.Shared.Extensions;
+using DevExpress.Xpf.Scheduling;
+using DevExpress.XtraScheduler;
+
+namespace BeWo.Scheduling.SchedulingUtils
+{
+ public static class Utils
+ {
+ private static readonly Regex HexColorRegex = new Regex("^#([a-fA-F0-9]{8}|[a-fA-F0-9]{6}|[a-fA-F0-9]{3})$");
+
+ public static bool Categories2ResourcesEquals(ObservableDictionary> dictionary1, ObservableDictionary> dictionary2)
+ {
+ if(dictionary1 is null && dictionary2 != null || dictionary2 is null && dictionary1 != null)
+ {
+ return false;
+ }
+
+ return dictionary1 is null && dictionary2 is null || dictionary1 != null && dictionary2 != null && dictionary1.Count == dictionary2.Count && dictionary1.Except(dictionary2).Any();
+ }
+
+ public static List ConvertAbsenceTimesToAppointments(List absenceTimes, DateTime end, List allEmployees)
+ {
+ var result = new List();
+
+ foreach(var absenceTime in absenceTimes)
+ {
+ if(absenceTime.AbsenceTimeOid == null || absenceTime.Start == null)
+ {
+ continue;
+ }
+
+ var subject = absenceTime.Reason.Description;
+ var employee = absenceTime.EmployeeOid != null ? allEmployees.FirstOrDefault(f => f.EmployeeOid == absenceTime.EmployeeOid.Value) : null;
+
+ if(employee != null)
+ {
+ subject += $" ({employee.SimpleDescription})";
+ }
+
+ var absenceTimeEnd = absenceTime.End?.AddTicks(1);
+
+ result.AddIfNotIn(new SchedulingAppointmentVM(true, subject, absenceTime.Start.Value, absenceTime.End ?? end, employee, absenceTime.Start, absenceTimeEnd));
+ }
+
+ return result;
+ }
+
+ public static string GetDeleteMessageForAppointment(AppointmentItem appointment)
+ {
+ if(appointment is null)
+ {
+ return "Möchten Sie den gewählten Termin wirklich löschen?";
+ }
+
+ var subject = appointment.Subject;
+
+ var interval = GetAppointmentTimeString(appointment);
+
+ return $"Möchten Sie den gewählten Termin \"{subject}\" vom {interval} wirklich löschen?";
+ }
+
+ public static string GetAppointmentTimeString(AppointmentItem appointment)
+ {
+ if(appointment is null)
+ {
+ return string.Empty;
+ }
+
+ var start = appointment.Start;
+ var end = appointment.End;
+
+ // 1. 17. August 2021 09:00 Uhr bis 10:00 Uhr
+ // 2. 17. August 2021
+ // 3. 17. August 2021 09:00 Uhr bis 19. August 2021 10 Uhr
+ // 4. 17. August 2021 bis 19. August 2021
+
+ return start.Date == end.Date ?
+ appointment.AllDay ? $"{start:dd. MMMM yyyy}" : $"{start:dd. MMMM yyyy HH:mm} Uhr bis {end:HH:mm} Uhr" :
+ appointment.AllDay ? $"{start:dd. MMMM yyyy} bis zum {end:dd. MMMM yyyy}" : $"{start: dd. MMMM yyyy HH:mm} Uhr bis zum {end:dd. MMMM yyyy HH:mm} Uhr";
+ }
+
+ public static string GetDeactivationMessageForAppointments(IReadOnlyList appointments2Deactivate)
+ {
+ var message = string.Empty;
+
+ if(appointments2Deactivate.Count > 1)
+ {
+ message = "Möchten Sie folgende Termine wirklich löschen?\n\n";
+
+ foreach(var appointment2Deactivate in appointments2Deactivate.OrderBy(o => o.Start))
+ {
+ var interval = GetAppointmentTimeString(appointment2Deactivate);
+ var subject = appointment2Deactivate.Subject;
+
+ message += $"{interval} \"{subject}\"\n";
+ }
+ }
+ else
+ {
+ var first = appointments2Deactivate.FirstOrDefault();
+
+ if(first is null)
+ {
+ return message;
+ }
+
+ var interval = GetAppointmentTimeString(first);
+ var subject = first.Subject;
+
+ message = $"Möchten Sie den gewählten Termin \"{subject}\" vom {interval} wirklich löschen?";
+ }
+
+ return message;
+ }
+
+ public static AppointmentType GetAppointmentTypeFromViewModel(int eventType)
+ {
+ switch(eventType)
+ {
+ case 0:
+ return AppointmentType.Normal;
+ case 1:
+ return AppointmentType.Pattern;
+ case 2:
+ return AppointmentType.Occurrence;
+ case 3:
+ return AppointmentType.ChangedOccurrence;
+ case 4:
+ return AppointmentType.DeletedOccurrence;
+ default:
+ return AppointmentType.Normal;
+ }
+ }
+
+ public static bool IsValidColorHexString(string hexString)
+ {
+ return !(hexString is null) && HexColorRegex.IsMatch(hexString);
+ }
+
+ public static StatusUpdatesAndAppointments SeperateStatusUpdatesAndAppointments(List statusUpdatesAndAppointments)
+ {
+ var result = new StatusUpdatesAndAppointments();
+
+ foreach(var appointment in statusUpdatesAndAppointments)
+ {
+ if(!(appointment.Originator?.Equals(BeWoApp.CompactLoggedOnEmployee) ?? false) && (appointment.EmployeeList?.Any(e2a => e2a.Employee.Equals(BeWoApp.CompactLoggedOnEmployee) && e2a.ParticipationAnswer == ParticipationAnswer.Offen) ?? false))
+ {
+ result.Appointments.AddIfNotIn(new SchedulingAppointmentVM(appointment));
+ }
+ else if((appointment.Originator?.Equals(BeWoApp.CompactLoggedOnEmployee) ?? false) && (appointment.EmployeeList?.Any(e2a => e2a.IsPChanged && e2a.ParticipationAnswer != ParticipationAnswer.Offen && e2a.ParticipationAnswer != ParticipationAnswer.Verstrichen && !e2a.Employee.Equals(BeWoApp.CompactLoggedOnEmployee)) ?? false))
+ {
+ var vm = new SchedulingAppointmentVM(appointment);
+
+ foreach(var employee2Appointment in appointment.EmployeeList.Where(e2a => e2a.IsPChanged && e2a.ParticipationAnswer != ParticipationAnswer.Offen && e2a.ParticipationAnswer != ParticipationAnswer.Verstrichen && !e2a.Employee.Equals(BeWoApp.CompactLoggedOnEmployee)))
+ {
+ if(result.StatusUpdates.All(a => a.LabelKey != employee2Appointment.Employee2SchedulerAppointmentOid))
+ {
+ if(employee2Appointment.Employee2SchedulerAppointmentOid.HasValue)
+ {
+ vm.LabelKey = employee2Appointment.Employee2SchedulerAppointmentOid;
+ }
+ }
+ }
+
+ result.StatusUpdates.AddIfNotIn(vm);
+ }
+ }
+
+ return result;
+ }
+ }
+
+ public class StatusUpdatesAndAppointments
+ {
+ public List StatusUpdates { get; }
+ public List Appointments { get; }
+
+ public StatusUpdatesAndAppointments()
+ {
+ StatusUpdates = new List();
+ Appointments = new List();
+ }
+ }
+}
diff --git a/BeWo/Scheduling/View/AppointmentEditView.xaml b/BeWo/Scheduling/View/AppointmentEditView.xaml
new file mode 100644
index 000000000..8f59624a7
--- /dev/null
+++ b/BeWo/Scheduling/View/AppointmentEditView.xaml
@@ -0,0 +1,534 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/BeWo/Scheduling/View/AppointmentEditView.xaml.cs b/BeWo/Scheduling/View/AppointmentEditView.xaml.cs
new file mode 100644
index 000000000..290713d79
--- /dev/null
+++ b/BeWo/Scheduling/View/AppointmentEditView.xaml.cs
@@ -0,0 +1,580 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Collections.Specialized;
+using System.ComponentModel;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+using System.Windows.Threading;
+using BeWo.Annotations;
+using BeWo.Core;
+using BeWo.Scheduling.SchedulingUtils;
+using BeWo.Scheduling.ViewModel;
+using BeWo.ServiceProxy;
+using BeWo.View;
+using BeWo.View.Detail;
+using BeWo.View.Search;
+using BS.Shared;
+using BS.Shared.DataContracts;
+using BS.Shared.DataContracts.Compact;
+using BS.Shared.Extensions;
+using DevExpress.Xpf.Editors;
+using DevExpress.XtraScheduler;
+
+namespace BeWo.Scheduling.View
+{
+ public partial class AppointmentEditView : INotifyPropertyChanged
+ {
+ private AppointmentWindowVM ViewModel => DataContext as AppointmentWindowVM;
+
+ private ObservableCollection _SelectedEmployees;
+ public ObservableCollection SelectedEmployees
+ {
+ get => _SelectedEmployees ?? (_SelectedEmployees = ViewModel.EmployeeList ?? new ObservableCollection());
+
+ set
+ {
+ if(!ICollectionExtensions.ListEquals(_SelectedEmployees, value))
+ {
+ _SelectedEmployees = value;
+ SelectedEmployees.CollectionChanged += SelectedEmployeesCollectionChanged;
+
+ ViewModel.EmployeeList = SelectedEmployees;
+ OnPropertyChanged();
+ }
+ }
+ }
+
+ private ObservableCollection _SelectedCustomers;
+ public ObservableCollection SelectedCustomers
+ {
+ get => _SelectedCustomers ?? (_SelectedCustomers = new ObservableCollection(ViewModel?.CustomerList ?? new List()));
+ set
+ {
+ if(!ICollectionExtensions.ListEquals(_SelectedCustomers, value))
+ {
+ _SelectedCustomers = value;
+ SelectedCustomers.CollectionChanged += SelectedCustomersCollectionChanged;
+
+ ViewModel.CustomerList = SelectedCustomers.ToList();
+ OnPropertyChanged();
+ }
+ }
+ }
+
+ private ObservableCollection _SelectedSupportConcepts;
+ public ObservableCollection SelectedSupportConcepts
+ {
+ get => _SelectedSupportConcepts ?? (_SelectedSupportConcepts = new ObservableCollection(ViewModel?.SupportConceptList ?? new ObservableCollection()));
+
+ set
+ {
+ if(!ICollectionExtensions.ListEquals(_SelectedSupportConcepts, value))
+ {
+ _SelectedSupportConcepts = value;
+ SelectedSupportConcepts.CollectionChanged += SelectedSupportConceptsCollectionChanged;
+
+ ViewModel.SupportConceptList = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+
+ private ObservableCollection _SelectedResources;
+ public ObservableCollection SelectedResources
+ {
+ get => _SelectedResources ?? (_SelectedResources = new ObservableCollection(ViewModel?.ResourceList ?? new List()));
+ set
+ {
+ _SelectedResources = value;
+ SelectedResources.CollectionChanged += SelectedResourcesCollectionChanged;
+
+ ViewModel.ResourceList = value.ToList();
+ OnPropertyChanged();
+ }
+ }
+
+
+ #region Ausgewählte Mitarbeiter, Klienten, Ressourcen
+ private void SelectedEmployeesCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
+ {
+ ViewModel.ActualViewModel.EmployeeList = SelectedEmployees;
+ MultiEmployeeSearch.AusgewaehlteMitarbeiter = SelectedEmployees.Select(e2s => e2s.Employee).ToList();
+ }
+
+ private void SelectedCustomersCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
+ {
+ ViewModel.ActualViewModel.CustomerList = SelectedCustomers.ToList();
+ MultiCustomerSearch.AusgewaehlteKlienten = SelectedCustomers.ToList();
+ }
+
+ private void SelectedSupportConceptsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
+ {
+ ViewModel.ActualViewModel.SupportConceptList = SelectedSupportConcepts;
+ }
+
+ private void SelectedResourcesCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
+ {
+ ViewModel.ActualViewModel.ResourceList = SelectedResources.ToList();
+ ResourcesTreeSearchView.AusgewaehlteRessourcen = SelectedResources.ToList();
+ }
+ #endregion
+
+ #region Visibilities
+ private Visibility _EmployeeSelectionVisibility;
+ public Visibility EmployeeSelectionVisibility
+ {
+ get => _EmployeeSelectionVisibility;
+ set
+ {
+ _EmployeeSelectionVisibility = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private Visibility _CustomerSelectionVisibility;
+ public Visibility CustomerSelectionVisibility
+ {
+ get => _CustomerSelectionVisibility;
+ set
+ {
+ _CustomerSelectionVisibility = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private Visibility _ResourceSelectionVisibility;
+ public Visibility ResourceSelectionVisibility
+ {
+ get => _ResourceSelectionVisibility;
+ set
+ {
+ _ResourceSelectionVisibility = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private Visibility _SupportConceptVisibility;
+ public Visibility SupportConceptVisibility
+ {
+ get => _SupportConceptVisibility;
+ set
+ {
+ if(_SupportConceptVisibility != value)
+ {
+ _SupportConceptVisibility = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+
+ public Visibility DeleteButtonVisibility => ViewModel.ActualViewModel.IsNew ? Visibility.Collapsed : ViewModel.IsReadyOnly ? Visibility.Collapsed : Visibility.Visible;
+
+ public Visibility OkButtonVisibility => ViewModel.IsReadyOnly ? Visibility.Collapsed : Visibility.Visible;
+ #endregion
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ [NotifyPropertyChangedInvocator]
+ public virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
+
+
+ public InformationView InformationView { get; set; }
+ public CompactCustomerDC Customer { get; set; }
+
+ public AppointmentEditView()
+ {
+ InitializeComponent();
+ }
+
+ private void InitRights()
+ {
+ var hasRightToSeeEmployees = !ViewModel.ActualViewModel.IsTask && (BeWoUtils.HasRight(UserRightType.Employee_AllowViewOwnTeam) || BeWoUtils.HasRight(UserRightType.EmployeeView_View)) && BeWoUtils.HasRight(UserRightType.KalenderMitarbeitertermineAnsehen);
+ var hasRightToSeeCustomers = !ViewModel.ActualViewModel.IsTask && BeWoUtils.HasRight(UserRightType.CustomerView_View) || BeWoUtils.HasRight(UserRightType.Customer_ViewMyTeams) || BeWoUtils.HasRight(UserRightType.Customer_ViewMyCustomers);
+ var hasRightToSeeResources = !ViewModel.ActualViewModel.IsTask && BeWoUtils.HasRight(UserRightType.KalenderRessourcentermineAnlegen) || BeWoUtils.HasRight(UserRightType.KalenderRessourcentermineAendern);
+ var hasRightToSeeSupportConcepts = ViewModel.ActualViewModel.IsTask && (BeWoUtils.HasRight(UserRightType.SupportConceptView_View) || BeWoUtils.HasRight(UserRightType.ViewAll) || BeWoUtils.HasRight(UserRightType.SupportConcept_ViewMyTeams) || BeWoUtils.HasRight(UserRightType.SupportConcept_ViewAllSupportConcepts));
+
+ EmployeeSelectionVisibility = hasRightToSeeEmployees ? Visibility.Visible : Visibility.Collapsed;
+ CustomerSelectionVisibility = hasRightToSeeCustomers ? Visibility.Visible : Visibility.Collapsed;
+ ResourceSelectionVisibility = hasRightToSeeResources ? Visibility.Visible : Visibility.Collapsed;
+ SupportConceptVisibility = hasRightToSeeSupportConcepts ? Visibility.Visible : Visibility.Collapsed;
+ }
+
+ private void RemoveSupportConceptButton_OnClick(object sender, RoutedEventArgs e)
+ {
+ if(((Button) sender).Tag is CompactSupportConceptDC dc)
+ {
+ SelectedSupportConcepts.Remove(dc);
+ }
+ }
+
+ // KGW?
+ private void InformationButton_OnClick(object sender, RoutedEventArgs e)
+ {
+ if(sender is Button button && button.Tag is CompactCustomerDC customer)
+ {
+ InformationView = new InformationView();
+
+ InformationView.SetXaml(ServiceFacade.DoOperationsServiceSync(s => s.GetXAMLInformationStringForScheduler(Customer.CustomerOid)));
+
+ var beWoWindow = new BeWoWindow();
+ InformationView.ButtonCloseClicked += () => beWoWindow.Close();
+
+ beWoWindow.Height = 200;
+ beWoWindow.Width = 600;
+ beWoWindow.WindowStartupLocation = WindowStartupLocation.CenterOwner;
+ beWoWindow.GroupBoxContent = InformationView;
+ beWoWindow.Owner = BeWoApp.CurrentBeWo.MainWindow;
+
+ beWoWindow.ShowDialog();
+ }
+ }
+
+ private void RemoveElementButton_OnClick(object sender, RoutedEventArgs e)
+ {
+ if(!ViewModel.ActualViewModel.IsTask && sender is Button button)
+ {
+ var obj = button.Tag;
+
+ switch(obj)
+ {
+ case ResourceDC res:
+ SelectedResources.Remove(res);
+ break;
+ case CompactCustomerDC cus:
+ SelectedCustomers.Remove(cus);
+ break;
+ case CompactSupportConceptDC sup:
+ SelectedSupportConcepts.Remove(sup);
+ break;
+ }
+
+ if(obj is Employee2SchedulerAppointmentDC e2s)
+ {
+ SelectedEmployees.Remove(e2s);
+ }
+ }
+ }
+
+ private void MultiEmployeeSearch_OnSelectionChanged(object sender, RoutedEventArgs e)
+ {
+ if(e.Source is MultiEmployeeSearch multiEmployeeSearch)
+ {
+ foreach(var employee in multiEmployeeSearch.SelectedEmployees.Where(employee => !SelectedEmployees.Any(e2s => e2s.Employee.Equals(employee))))
+ {
+ SelectedEmployees.Add(new Employee2SchedulerAppointmentDC { Employee = employee, ParticipationAnswer = ParticipationAnswer.Offen });
+ }
+ }
+ }
+
+ #region Popups
+ private void EmployeePopupClick(object sender, RoutedEventArgs e)
+ {
+ PopupEmployee.IsOpen = true;
+ PopupEmployee.Height = 300;
+ }
+
+ private void CustomerPopUpEditClick(object sender, RoutedEventArgs e)
+ {
+ PopupCustomer.IsOpen = true;
+ PopupCustomer.Height = 300;
+ }
+
+ private void ResourcePopUpClick(object sender, RoutedEventArgs e)
+ {
+ PopupResource.IsOpen = true;
+ PopupResource.Height = 300;
+ }
+
+ private void SupportConceptPopupClick(object sender, RoutedEventArgs e)
+ {
+ PopupSupportConcepts.IsOpen = true;
+ PopupSupportConcepts.Height = 300;
+ }
+ #endregion
+
+ private void CloseButton_OnClick(object sender, RoutedEventArgs e)
+ {
+ if(ViewModel.ActualViewModel.IsDirty && !ViewModel.IsReadOnly)
+ {
+ var result = MessageBox.Show("Wollen Sie die Änderungen am Termin speichern?", ViewModel.ActualViewModel.Subject, MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
+
+ if(result == MessageBoxResult.Yes)
+ {
+ var dc = ViewModel.ActualViewModel.CommitToDataContract();
+ var ri = dc.RecurrenceInfo;
+ if(ViewModel.ActualViewModel.IsNew)
+ {
+ ServiceFacade.DoResourceServiceAsync(s => s.InsertSchedulerAppointments(new List { dc }),
+ cb =>
+ {
+ this.Dispatch(Close);
+ }
+ );
+ }
+ else
+ {
+ ServiceFacade.DoResourceServiceAsync(s => s.UpdateSchedulerAppointments(new List { dc }),
+ cb =>
+ {
+ this.Dispatch(Close);
+ }
+ );
+ }
+ }
+ else
+ {
+ Close();
+ }
+ }
+ else
+ {
+ Close();
+ }
+ }
+
+ private void Window_Loaded(object sender, RoutedEventArgs e)
+ {
+ if(ViewModel is null)
+ {
+ return;
+ }
+
+ InitRights();
+
+ var selectedEmployees = new ObservableCollection();
+
+ foreach(var e2s in ViewModel.EmployeeList)
+ {
+ selectedEmployees.AddIfNotIn(e2s.Employee);
+ }
+
+ SelectedResources.CollectionChanged += SelectedResourcesCollectionChanged;
+ SelectedCustomers.CollectionChanged += SelectedCustomersCollectionChanged;
+ SelectedEmployees.CollectionChanged += SelectedEmployeesCollectionChanged;
+ SelectedSupportConcepts.CollectionChanged += SelectedSupportConceptsCollectionChanged;
+
+ MultiEmployeeSearch.Sauce = ViewModel.AllEmployees;
+ MultiEmployeeSearch.AusgewaehlteMitarbeiter = selectedEmployees.ToList();
+ MultiEmployeeSearch.CommandBindings.Add(new CommandBinding(ApplicationCommands.Close, (s, es) => this.Dispatch(() => { PopupEmployee.IsOpen = false; })));
+
+ MultiCustomerSearch.Sauce = ViewModel.AllCustomers;
+ MultiCustomerSearch.AusgewaehlteKlienten = SelectedCustomers.ToList();
+ MultiCustomerSearch.CommandBindings.Add(new CommandBinding(ApplicationCommands.Close, (s, es) => this.Dispatch(() => { PopupCustomer.IsOpen = false; })));
+
+
+ ResourcesTreeSearchView.Sauce = ViewModel.AllCategories2Resources.ToDictionary(k => k.Key.ResourceCategory, k => k.Value.Select(s => s.DataContract).ToList());
+ ResourcesTreeSearchView.AusgewaehlteRessourcen = SelectedResources.ToList();
+ ResourcesTreeSearchView.CommandBindings.Add(new CommandBinding(ApplicationCommands.Close, (s, es) => this.Dispatch(() => { PopupResource.IsOpen = false; })));
+
+ if(ViewModel.IsTask && !SelectedEmployees.Any(e2a => e2a.Employee.Equals(BeWoApp.CompactLoggedOnEmployee)))
+ {
+ SelectedEmployees.Add(new Employee2SchedulerAppointmentDC { Employee = BeWoApp.CompactLoggedOnEmployee });
+ EmployeeToggleButton.IsChecked = true;
+ }
+
+ if(ViewModel.RecurrenceInfo != null)
+ {
+ _IgnoreRecurrenceTypeChange = true;
+ }
+
+ RecurrenceTypeComboBoxEdit.SelectedItem = ViewModel.RecurrenceTypeName;
+ }
+
+ private bool _IgnoreRecurrenceTypeChange;
+
+ public void SetRecurrenceInfo(string originalRecurrenceInfo)
+ {
+ if(!(originalRecurrenceInfo is null))
+ {
+ ViewModel.Appointment.RecurrenceInfo?.FromXml(originalRecurrenceInfo);
+ ViewModel.ActualViewModel.RecurrenceInfo = originalRecurrenceInfo;
+ }
+ else
+ {
+ ViewModel.Appointment.RecurrenceInfo = null;
+ ViewModel.ActualViewModel.RecurrenceInfo = null;
+ }
+
+ RecurrenceTypeComboBoxEdit.SelectedItem = ViewModel.RecurrenceTypeName;
+ }
+
+ private void OkButton_Click(object sender, RoutedEventArgs e)
+ {
+ if(ViewModel.IsReadyOnly)
+ {
+ MessageBox.Show("Sie verfügen nicht über die benötigten Rechte, um diesen Termin zu speichern!", "Speichern nicht möglich", MessageBoxButton.OK, MessageBoxImage.Error);
+ return;
+ }
+
+ var dataContract = ViewModel.ActualViewModel.CommitToDataContract();
+
+ var start = dataContract.StartDate.Value;
+ var end = dataContract.EndDate.Value;
+ var employeeOids = dataContract.EmployeeList.Select(s => s.Employee.EmployeeOid).ToList();
+ var customerOids = dataContract.CustomerList.Select(s => s.CustomerOid).ToList();
+ var resrouceOids = dataContract.ResourceList.Select(s => s.ResourceOid.Value).ToList();
+ var originatorOid = dataContract.Originator?.EmployeeOid ?? BeWoApp.LoggedOnEmployeeOid.Value;
+ var recurrenceId = dataContract.RecurrenceId;
+ var recurrenceIndex = dataContract.RecurrenceIndex;
+
+
+
+ ServiceFacade.DoResourceServiceAsync(s => s.OverlappingAppointmentsExist(start, end, employeeOids, customerOids, resrouceOids, originatorOid, dataContract.SchedulerAppointmentOid, recurrenceId, recurrenceIndex), isOverlapping =>
+ {
+ Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action) (() =>
+ {
+ if(isOverlapping)
+ {
+ if(MessageBox.Show("Dieser Termin überschneidet sich mit einem anderen, bereits existierenden Termin.\r\n\r\nMöchten Sie trotzdem speichern?", "Überschneidung", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes)
+ {
+ SaveAppointment(dataContract);
+ }
+ }
+ else
+ {
+ SaveAppointment(dataContract);
+ }
+ }));
+ });
+ }
+
+ private void SaveAppointment(SchedulerAppointmentDC dataContract)
+ {
+ if(dataContract.SchedulerAppointmentOid is null)
+ {
+ ServiceFacade.DoResourceServiceAsync(s => s.InsertSchedulerAppointments(new List { dataContract }),
+ () => Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action) Close));
+ }
+ else
+ {
+ ServiceFacade.DoResourceServiceAsync(s => s.UpdateSchedulerAppointments(new List { dataContract }),
+ () => Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action) Close));
+ }
+ }
+
+ private void SupportConceptsPopUpClick(object sender, RoutedEventArgs e)
+ {
+ PopupSupportConcepts.IsOpen = true;
+ }
+
+ private void ResourcesTreeSearchView_OnSelectionChanged(object sender, RoutedEventArgs e)
+ {
+ if(!(e.Source is ResourcesTreeSearchView resourcesTreeSearchView))
+ {
+ return;
+ }
+
+ var resourcesCollection = resourcesTreeSearchView.SelectedResources.ToObservableCollection();
+
+ foreach(var resource in resourcesCollection)
+ {
+ SelectedResources.AddIfNotIn(resource);
+ }
+
+ SelectedResources = SelectedResources.Except(SelectedResources.Where(sr => !resourcesCollection.Contains(sr)).ToList()).ToObservableCollection();
+ }
+
+ private void MultiCustomerSearch_OnSelectionChanged(object sender, RoutedEventArgs e)
+ {
+ if(e.Source is MultiCustomerSearchView multiCustomerSearchView)
+ {
+ SelectedCustomers = multiCustomerSearchView.SelectedCustomers.ToObservableCollection();
+ }
+ }
+
+ private void SupportConceptSelectionControl_ItemSelected(object sender, BS.Shared.Core.EventArgs e)
+ {
+ PopupSupportConcepts.IsOpen = false;
+
+ SelectedSupportConcepts.Clear();
+ SelectedSupportConcepts.Add(e.Data);
+
+ OnPropertyChanged(nameof(SelectedSupportConcepts));
+ }
+
+ private void RecurrenceTypeComboBoxEdit_OnChanged(object sender, EditValueChangedEventArgs e)
+ {
+ if(_IgnoreRecurrenceTypeChange)
+ {
+ _IgnoreRecurrenceTypeChange = false;
+ return;
+ }
+
+ if(e.NewValue is string newValue)
+ {
+ RecurrenceType? type;
+
+ switch(newValue)
+ {
+ case "(keine)":
+ type = null;
+ break;
+ case "täglich":
+ type = RecurrenceType.Daily;
+ break;
+ case "wöchentlich":
+ type = RecurrenceType.Weekly;
+ break;
+ case "monatlich":
+ type = RecurrenceType.Monthly;
+ break;
+ case "jährlich":
+ type = RecurrenceType.Yearly;
+ break;
+ default:
+ type = null;
+ break;
+ }
+
+ if(type is null)
+ {
+ // TODO: Typ bestimmen bzw. beim Loaded-Event merken! Zum zurücksetzen (nötig?)
+ return;
+ }
+
+ ViewModel.Appointment.Type = AppointmentType.Pattern;
+ ViewModel.Appointment.RecurrenceInfo.Type = type.Value;
+
+ ViewModel.ActualViewModel.RecurrenceInfo = ViewModel.Appointment.RecurrenceInfo.ToXml();
+
+ ViewModel.Scheduler.ShowRecurrenceWindow(ViewModel.Appointment);
+ }
+ }
+
+ //private IRecurrenceInfo RecurrenceInfo;
+
+ private void DeleteButton_OnClick(object sender, RoutedEventArgs e)
+ {
+ if(!ViewModel.IsReadyOnly && ViewModel.Appointment.Id is long appointmentOid)
+ {
+ var message = Utils.GetDeleteMessageForAppointment(ViewModel.Appointment);
+
+ if(MessageBox.Show(message, "Termin löschen", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
+ {
+ var dc = ViewModel.ActualViewModel.CommitToDataContract();
+
+ ServiceFacade.DoResourceServiceAsync(s => s.DeleteSchedulerAppointments(new Dictionary { { dc.SchedulerAppointmentOid.Value, dc.NewSchedulerAppointmentVersion.Value } }), () =>
+ {
+ Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action) Close);
+ });
+ }
+ }
+ }
+
+ // TODO: Fertig machen
+ private void EditRecurrenceButton_OnClick(object sender, RoutedEventArgs e)
+ {
+ if(!(ViewModel.Appointment.RecurrenceInfo is null))
+ {
+ ViewModel.Scheduler.ShowRecurrenceWindow(ViewModel.Appointment);
+ }
+ }
+ }
+}
diff --git a/BeWo/Scheduling/View/AppointmentRecurrenceEditView.xaml b/BeWo/Scheduling/View/AppointmentRecurrenceEditView.xaml
new file mode 100644
index 000000000..b619bfff5
--- /dev/null
+++ b/BeWo/Scheduling/View/AppointmentRecurrenceEditView.xaml
@@ -0,0 +1,100 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/BeWo/Scheduling/View/AppointmentRecurrenceEditView.xaml.cs b/BeWo/Scheduling/View/AppointmentRecurrenceEditView.xaml.cs
new file mode 100644
index 000000000..3283ec310
--- /dev/null
+++ b/BeWo/Scheduling/View/AppointmentRecurrenceEditView.xaml.cs
@@ -0,0 +1,53 @@
+using System.ComponentModel;
+using System.Windows;
+using DevExpress.Xpf.Scheduling.VisualData;
+
+namespace BeWo.Scheduling.View
+{
+ public partial class AppointmentRecurrenceEditView
+ {
+ public RecurrenceWindowViewModel ViewModel => DataContext as RecurrenceWindowViewModel;
+
+ public bool IsCancelled
+ {
+ get;
+ private set;
+ }
+
+ private bool _IsCancelButtonClicked;
+
+ public AppointmentRecurrenceEditView()
+ {
+ InitializeComponent();
+ }
+
+ private void AppointmentRecurrenceEditView_OnLoaded(object sender, RoutedEventArgs e)
+ {
+
+ }
+
+ private void OkButton_Click(object sender, RoutedEventArgs e)
+ {
+ IsCancelled = false;
+ _IsCancelButtonClicked = false;
+ Close();
+ }
+
+ // ToDo: den Ursprungszustand wiederherstellen und schließen
+ private void CloseButton_OnClick(object sender, RoutedEventArgs e)
+ {
+ IsCancelled = true;
+ ViewModel.DeleteCommand.Execute(null);
+ _IsCancelButtonClicked = false;
+ Close();
+ }
+
+ private void AppointmentRecurrenceEditView_OnClosing(object sender, CancelEventArgs e)
+ {
+ if(_IsCancelButtonClicked)
+ {
+ IsCancelled = true;
+ }
+ }
+ }
+}
diff --git a/BeWo/Scheduling/View/OccurrenceParticipationConfirmationView.xaml b/BeWo/Scheduling/View/OccurrenceParticipationConfirmationView.xaml
new file mode 100644
index 000000000..1be32e508
--- /dev/null
+++ b/BeWo/Scheduling/View/OccurrenceParticipationConfirmationView.xaml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/BeWo/Scheduling/View/OccurrenceParticipationConfirmationView.xaml.cs b/BeWo/Scheduling/View/OccurrenceParticipationConfirmationView.xaml.cs
new file mode 100644
index 000000000..89e8a5bbb
--- /dev/null
+++ b/BeWo/Scheduling/View/OccurrenceParticipationConfirmationView.xaml.cs
@@ -0,0 +1,77 @@
+using System;
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+using System.Windows;
+using BeWo.Annotations;
+using BS.Shared.Extensions;
+
+namespace BeWo.Scheduling.View
+{
+ public partial class OccurrenceParticipationConfirmationView : INotifyPropertyChanged
+ {
+ public bool? ShouldChangeSeries { get; private set; }
+
+ private readonly string _Subject;
+
+ private readonly string _ParticipationAnswerString;
+
+ public Visibility CheckBoxVisibility { get; }
+
+ public string OkButtonText => $"Ganzer Serie {_ParticipationAnswerString}";
+ public string NoButtonText => $"Nur diesem Termin {_ParticipationAnswerString}";
+
+ public string DateText { get; }
+ public string InfoText => $"Der Termin '{_Subject}' am {DateText} ist Teil einer Serie. Möchten Sie der ganzen Serie {_ParticipationAnswerString} oder nur dem ausgewählten Termin?";
+
+ private bool _ApplyForAllOccurrences;
+ public bool ApplyForAllOccurrences
+ {
+ get => _ApplyForAllOccurrences;
+ set
+ {
+ if(_ApplyForAllOccurrences != value)
+ {
+ _ApplyForAllOccurrences = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+
+ // ToDo: Datum und evtl. Uhrzeit einbauen?
+ public OccurrenceParticipationConfirmationView(string subject, string participationAnswerString, bool isCheckBoxVisible, DateTime start, DateTime end)
+ {
+ InitializeComponent();
+
+ DateText = start.GetDateString(end);
+ _Subject = subject;
+ _ParticipationAnswerString = participationAnswerString;
+
+ CheckBoxVisibility = isCheckBoxVisible ? Visibility.Visible : Visibility.Collapsed;
+
+ DataContext = this;
+ }
+
+ private void YesButton_OnClick(object sender, RoutedEventArgs e)
+ {
+ ShouldChangeSeries = false;
+ }
+
+ private void NoButton_OnClick(object sender, RoutedEventArgs e)
+ {
+ ShouldChangeSeries = true;
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ [NotifyPropertyChangedInvocator]
+ protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
+
+ private void OccurrenceParticipationConfirmationView_OnLoaded(object sender, RoutedEventArgs e)
+ {
+ ShouldChangeSeries = null;
+ }
+ }
+}
diff --git a/BeWo/Scheduling/View/OpenAppointmentsView.xaml b/BeWo/Scheduling/View/OpenAppointmentsView.xaml
new file mode 100644
index 000000000..11f72934f
--- /dev/null
+++ b/BeWo/Scheduling/View/OpenAppointmentsView.xaml
@@ -0,0 +1,172 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dieser Termin liegt in der Vergangenheit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/BeWo/Scheduling/View/OpenAppointmentsView.xaml.cs b/BeWo/Scheduling/View/OpenAppointmentsView.xaml.cs
new file mode 100644
index 000000000..d34a899bb
--- /dev/null
+++ b/BeWo/Scheduling/View/OpenAppointmentsView.xaml.cs
@@ -0,0 +1,261 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Linq;
+using System.Windows;
+using BeWo.Annotations;
+using BeWo.Scheduling.ViewModel;
+using BeWo.ServiceProxy;
+using BS.Shared;
+using BS.Shared.DataContracts;
+using BS.Shared.Extensions;
+using DevExpress.Xpf.Editors;
+
+namespace BeWo.Scheduling.View
+{
+ public partial class OpenAppointmentsView : INotifyPropertyChanged
+ {
+ private bool _RaiseChangeEvent = true;
+
+ public static readonly RoutedEvent ParticipationChangedEvent = EventManager.RegisterRoutedEvent(nameof(ParticipationChanged), RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(OpenAppointmentsView));
+ public event RoutedEventHandler ParticipationChanged
+ {
+ add => AddHandler(ParticipationChangedEvent, value);
+ remove => RemoveHandler(ParticipationChangedEvent, value);
+ }
+
+ private void RaiseParticipationChangedEventEvent()
+ {
+ var newEventArgs = new RoutedEventArgs(ParticipationChangedEvent);
+ RaiseEvent(newEventArgs);
+ }
+
+
+ private ObservableCollection _OpenAppointments;
+ public ObservableCollection OpenAppointments
+ {
+ get => _OpenAppointments ?? (_OpenAppointments = new ObservableCollection());
+
+ set
+ {
+ _OpenAppointments = value is null ?
+ new ObservableCollection() :
+ new ObservableCollection(value.OrderBy(o => o.Start));
+
+ OnPropertyChanged(nameof(OpenAppointments));
+ }
+ }
+
+ private SchedulingAppointmentVM _SelectedAppointment;
+
+ public SchedulingAppointmentVM SelectedAppointment
+ {
+ get => _SelectedAppointment;
+ set
+ {
+ _SelectedAppointment = value;
+ OnPropertyChanged(nameof(SelectedAppointment));
+ }
+ }
+
+
+
+ public OpenAppointmentsView(IEnumerable openAppointments, IEnumerable statusUpdates)
+ {
+ InitializeComponent();
+
+ OpenAppointments = new ObservableCollection(openAppointments.Union(statusUpdates));
+
+ DataContext = this;
+
+ if(OpenAppointments.Any())
+ {
+ OpenAppointmentsList.SelectedIndex = 0;
+ }
+ }
+
+
+
+ private void OpenAppointmentsView_OnClosing(object sender, CancelEventArgs e)
+ {
+ BeWoApp.MainControl.AufOffeneTerminePruefen();
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ [NotifyPropertyChangedInvocator]
+ protected virtual void OnPropertyChanged(string propertyName)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
+
+ private void UpdateView(List updatedAppointments)
+ {
+ ServiceFacade.DoResourceServiceAsync(s => s.GetAllOpenAppointmentsForEmployee(BeWoApp.CompactLoggedOnEmployee.EmployeeOid), openAppointments =>
+ {
+ this.Dispatch(() =>
+ {
+ var statusUpdatesAndAppointments = SchedulingUtils.Utils.SeperateStatusUpdatesAndAppointments(openAppointments);
+
+ OpenAppointments = new ObservableCollection(statusUpdatesAndAppointments.Appointments.Union(statusUpdatesAndAppointments.StatusUpdates));
+
+ RaiseParticipationChangedEventEvent();
+
+ ToggleControls();
+
+ if(_RaiseChangeEvent)
+ {
+ if(OpenAppointments.Count == 0)
+ {
+ Close();
+ }
+ else
+ {
+ OpenAppointmentsList.SelectedIndex = 0;
+ }
+ }
+ });
+ });
+ }
+
+ private void ToggleControls()
+ {
+ ZusagenStack.IsEnabled = !ZusagenStack.IsEnabled;
+ OkButton.IsEnabled = !OkButton.IsEnabled;
+ AlleBestaetigen.IsEnabled = !AlleBestaetigen.IsEnabled;
+ }
+
+ private void UpdateSelectedAppointment(ParticipationAnswer participationAnswer)
+ {
+ if(!(SelectedAppointment is null))
+ {
+ foreach(var employee2Appointment in SelectedAppointment.EmployeeList)
+ {
+ if(employee2Appointment.Employee.Equals(BeWoApp.CompactLoggedOnEmployee))
+ {
+ employee2Appointment.ParticipationAnswer = participationAnswer;
+ }
+ }
+ }
+
+ ToggleControls();
+
+ _RaiseChangeEvent = true;
+
+ ServiceFacade.DoResourceServiceAsync(s => s.UpdateSchedulerAppointments(new List { SelectedAppointment.CommitToDataContract() }), UpdateView);
+ }
+
+ private void CloseButton_OnClick(object sender, RoutedEventArgs e)
+ {
+ Close();
+ }
+
+ private void PopupBaseEdit_OnPopupOpening(object sender, OpenPopupEventArgs e)
+ {
+ // Es wird verhindert, dass das Popup angezeigt wird auch wenn das DateEdit readonly ist, damit man es nicht auf disabled setzen muss, da sonst die Schriftfarbe schwer lesbar ist.
+ e.Cancel = true;
+ }
+
+ private void ConfirmAllButton_OnClick(object sender, RoutedEventArgs e)
+ {
+ var appointments2Update = new List();
+
+ foreach(var appointment in OpenAppointments)
+ {
+ foreach(var employee2Appointment in appointment.EmployeeList)
+ {
+ employee2Appointment.IsPC_CheckedTs = DateTime.Now;
+
+ if(employee2Appointment.Employee.Equals(BeWoApp.CompactLoggedOnEmployee))
+ {
+ if(appointment.Start < DateTime.Now && appointment.End < DateTime.Now)
+ {
+ employee2Appointment.ParticipationAnswer = ParticipationAnswer.Verstrichen;
+ employee2Appointment.IsPC_CheckedTs = DateTime.Now;
+ employee2Appointment.IsPChanged = false;
+ }
+ else
+ {
+ employee2Appointment.IsPChanged = true;
+ employee2Appointment.ParticipationAnswer = ParticipationAnswer.Zusage;
+ }
+ }
+ else
+ {
+ employee2Appointment.IsPChanged = false;
+ }
+ }
+ }
+
+ ToggleControls();
+
+ _RaiseChangeEvent = false;
+
+ ServiceFacade.DoResourceServiceAsync(s => s.UpdateSchedulerAppointments(appointments2Update), updatedAppointments =>
+ {
+ UpdateView(updatedAppointments);
+ this.Dispatch(Close);
+ });
+ }
+
+ private void ConfirmButton_OnClick(object sender, RoutedEventArgs e)
+ {
+ UpdateSelectedAppointment(ParticipationAnswer.Zusage);
+ }
+
+ private void ConfirmWithReservationButton_OnClick(object sender, RoutedEventArgs e)
+ {
+ UpdateSelectedAppointment(ParticipationAnswer.Vorbehalt);
+ }
+
+ private void RejectButton_OnClick(object sender, RoutedEventArgs e)
+ {
+ UpdateSelectedAppointment(ParticipationAnswer.Absage);
+ }
+
+ private void OkButton_OnClick(object sender, RoutedEventArgs e)
+ {
+ if(SelectedAppointment?.LiesInPast ?? false)
+ {
+ var employee2Appointment = SelectedAppointment.EmployeeList.ToList().Find(e2a => e2a.Employee2SchedulerAppointmentOid == SelectedAppointment.LabelKey) ??
+ SelectedAppointment.EmployeeList.ToList().Find(e2a => e2a.Employee.Equals(BeWoApp.CompactLoggedOnEmployee));
+
+ if(!(employee2Appointment is null))
+ {
+ if(employee2Appointment.Employee.Equals(BeWoApp.CompactLoggedOnEmployee))
+ {
+ employee2Appointment.ParticipationAnswer = ParticipationAnswer.Verstrichen;
+ }
+
+ employee2Appointment.IsPC_CheckedTs = DateTime.Now;
+ employee2Appointment.IsPChanged = true;
+
+ ToggleControls();
+ _RaiseChangeEvent = true;
+
+ ServiceFacade.DoResourceServiceAsync(s => s.UpdateSchedulerAppointments(new List { SelectedAppointment.CommitToDataContract() }), UpdateView);
+ return;
+ }
+ }
+
+ if(SelectedAppointment?.LabelKey is null)
+ {
+ return;
+ }
+
+ var employee2Appointment2 = SelectedAppointment.EmployeeList.ToList().Find(e2a => e2a.Employee2SchedulerAppointmentOid == SelectedAppointment.LabelKey);
+
+ if(!(employee2Appointment2 is null))
+ {
+ employee2Appointment2.IsPC_CheckedTs = DateTime.Now;
+ employee2Appointment2.IsPChanged = false;
+
+ ToggleControls();
+ _RaiseChangeEvent = true;
+
+ ServiceFacade.DoResourceServiceAsync(s => s.UpdateSchedulerAppointments(new List { SelectedAppointment.CommitToDataContract() }), UpdateView);
+ }
+ }
+ }
+}
diff --git a/BeWo/Scheduling/View/SchedulingView.xaml b/BeWo/Scheduling/View/SchedulingView.xaml
new file mode 100644
index 000000000..2ab6d025b
--- /dev/null
+++ b/BeWo/Scheduling/View/SchedulingView.xaml
@@ -0,0 +1,994 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Drucken
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/BeWo/Scheduling/View/SchedulingView.xaml.cs b/BeWo/Scheduling/View/SchedulingView.xaml.cs
new file mode 100644
index 000000000..fce59e5df
--- /dev/null
+++ b/BeWo/Scheduling/View/SchedulingView.xaml.cs
@@ -0,0 +1,1989 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Diagnostics;
+using System.Linq;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Controls.Primitives;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Navigation;
+using BeWo.Core;
+using BeWo.Core.Service;
+using BeWo.Scheduler.View;
+using BeWo.Scheduling.Converter;
+using BeWo.Scheduling.SchedulingUtils;
+using BeWo.Scheduling.ViewModel;
+using BeWo.ServiceProxy;
+using BeWo.View;
+using BeWo.View.Detail;
+using BS.Shared;
+using BS.Shared.Core;
+using BS.Shared.DataContracts;
+using BS.Shared.DataContracts.Compact;
+using BS.Shared.Extensions;
+using BS.Shared.Translation;
+using DevExpress.Mvvm;
+using DevExpress.Xpf.Bars;
+using DevExpress.Xpf.Editors;
+using DevExpress.Xpf.Scheduling;
+using DevExpress.Xpf.Scheduling.VisualData;
+using DevExpress.XtraScheduler;
+using PopupMenuShowingEventArgs = DevExpress.Xpf.Scheduling.PopupMenuShowingEventArgs;
+using SchedulerControl = DevExpress.Xpf.Scheduling.SchedulerControl;
+using Utils = BeWo.Scheduling.SchedulingUtils.Utils;
+
+namespace BeWo.Scheduling.View
+{
+ public partial class SchedulingView
+ {
+ private CompactEmployeeDC LoggedOnCompactEmployee => BeWoApp.CompactLoggedOnEmployee;
+
+ public SchedulingAppointmentListVM ViewModel { get; set; }
+
+ private ViewType _CurrentViewType;
+
+ public static TimeSpan FetchPadding = TimeSpan.FromDays(14);
+ private TimeInterval _LastFetchedInterval = new TimeInterval();
+
+ public SchedulingCheckBoxConverter CheckBoxConverter => Resources[nameof(CheckBoxConverter)] as SchedulingCheckBoxConverter;
+
+
+ // ----------- Konstruktor -----------
+ public SchedulingView()
+ {
+ ViewModel = new SchedulingAppointmentListVM
+ {
+ IsEmployeeBrushVisible = true
+ };
+
+ InitializeComponent();
+
+ DataContext = ViewModel;
+
+ InitializeSchedulerControl();
+
+ ReloadViewModel(true, true);
+ }
+
+ private DateTime? _SelectedAppointmentStartDate;
+ private SchedulerAppointmentDC _SelectedAppointmentFromHomePanelView;
+ private bool _IsComingFromHomeDragPanel;
+
+ // Durch Doppelklick auf Termin im HomeView aufgerufen
+ public SchedulingView(DateTime intervalStartDate, SchedulerAppointmentDC appointment)
+ {
+ _IsComingFromHomeDragPanel = true;
+ _SelectedAppointmentFromHomePanelView = appointment;
+ _SelectedAppointmentStartDate = intervalStartDate;
+
+ ViewModel = new SchedulingAppointmentListVM
+ {
+ IsEmployeeBrushVisible = true
+ };
+
+ InitializeComponent();
+
+ DataContext = ViewModel;
+
+ if(_IsComingFromHomeDragPanel && _SelectedAppointmentStartDate.HasValue)
+ {
+ var monday = _SelectedAppointmentStartDate.Value.FirstDateOfWeek(_SelectedAppointmentStartDate.Value.GetIso8601WeekOfYear());
+
+ SchedulerControl.Start = monday;
+
+ var viewType = _SelectedAppointmentStartDate.Value.DayOfWeek == DayOfWeek.Saturday || _SelectedAppointmentStartDate.Value.DayOfWeek == DayOfWeek.Sunday ? ViewType.WeekView : ViewType.WorkWeekView;
+ SchedulerControl.ActiveViewType = viewType;
+
+ _SelectedAppointmentStartDate = null;
+ }
+
+ //InitializeSchedulerControl();
+
+ ReloadViewModel(true, true);
+ }
+ // ----------- /Konstruktor ----------
+
+ private void InitializeSchedulerControl()
+ {
+ LoadSchedulingViewType();
+ }
+
+ private void LoadSchedulingViewType()
+ {
+ _CurrentViewType = BeWoApp.AppSettings.SchedulingViewType;
+ SetViewType(_CurrentViewType);
+ }
+
+ public void ReloadRights()
+ {
+ ViewModel.ReloadRights();
+
+ if(ViewModel.SelectedTabItemIndex > 0 && ViewModel.SelectedTabItemIndex < 3)
+ {
+ switch(ViewModel.SelectedTabItemIndex)
+ {
+ case 0:
+ if(ViewModel.EmployeeControlsVisibility == Visibility.Visible)
+ {
+ ((TabItem) TabControl.Items[0]).IsSelected = true;
+ }
+ else
+ {
+ SelectDefaultTabItem();
+ }
+ break;
+ case 1:
+ if(ViewModel.CustomerControlsVisibility == Visibility.Visible)
+ {
+ ((TabItem) TabControl.Items[1]).IsSelected = true;
+ }
+ else
+ {
+ SelectDefaultTabItem();
+ }
+ break;
+ case 2:
+ if(ViewModel.ResourceControlsVisibility == Visibility.Visible)
+ {
+ ((TabItem) TabControl.Items[2]).IsSelected = true;
+ }
+ else
+ {
+ SelectDefaultTabItem();
+ }
+ break;
+ default:
+ SelectDefaultTabItem();
+ break;
+ }
+ }
+ else
+ {
+ SelectDefaultTabItem();
+ }
+
+ var isLeftSideVisible = ViewModel.SelectionControlVisibility == Visibility.Visible;
+
+ LeftExpanderButton.Visibility = isLeftSideVisible ? Visibility.Visible : Visibility.Collapsed;
+ ZeigeNurMeineTermineCheckBox.Visibility = isLeftSideVisible ? Visibility.Visible : Visibility.Collapsed;
+ AuswahlGrid.Visibility = isLeftSideVisible ? Visibility.Visible : Visibility.Collapsed;
+ ObjectSelectionGrid.Visibility = isLeftSideVisible ? Visibility.Visible : Visibility.Collapsed;
+ }
+
+ private void SelectDefaultTabItem()
+ {
+ if(ViewModel.EmployeeControlsVisibility == Visibility.Visible)
+ {
+ ((TabItem) TabControl.Items[0]).IsSelected = true;
+ }
+ else if(ViewModel.CustomerControlsVisibility == Visibility.Visible)
+ {
+ ((TabItem) TabControl.Items[1]).IsSelected = true;
+ }
+ else if(ViewModel.ResourceControlsVisibility == Visibility.Visible)
+ {
+ ((TabItem) TabControl.Items[2]).IsSelected = true;
+ }
+ }
+
+ public void ReloadViewModel(bool shouldForceReload = false, bool isFirstTimeLoading = false, bool reloadCachedObjects = false)
+ {
+ var visibleIntervals = SchedulerControl.VisibleIntervals;
+
+ var start = visibleIntervals[0].Start;
+ var end = visibleIntervals.Last().End;
+
+ var newFetchingInterval = new TimeInterval(start - FetchPadding, end + FetchPadding);
+
+ var selectedEmployeeOids = ViewModel.SelectedEmployees.Select(s => s.EmployeeOid).ToList();
+ var selectedCustomerOids = ViewModel.SelectedCustomers.Select(s => s.CustomerOid).ToList();
+ var selectedResourceOids = ViewModel.SelectedResources.Where(w => w.ResourceOid.HasValue).Select(s => s.ResourceOid.Value).ToList();
+ var employeesOnly = MitarbeiterEbenenCheckBox.IsChecked ?? false;
+ var customersOnly = KlientenEbenenCheckBox.IsChecked ?? false;
+ var resourcesOnly = RessourcenEbenenCheckBox.IsChecked ?? false;
+ var onlyPrivateAppointments = ShowPrivateAppointmentsCheckBox.IsChecked ?? false;
+ var showOnlyMyAppointments = ViewModel.ZeigeNurMeineTermine;
+ var showAbsenceTimes = AbwesenheitenEinAusCheckBox.IsChecked ?? false;
+ var showTasks = ViewModel.IsTasksVisible;
+
+ if(!shouldForceReload && newFetchingInterval.Equals(_LastFetchedInterval))
+ {
+ return;
+ }
+
+ _LastFetchedInterval = newFetchingInterval;
+
+ GetCachedObjects(reloadCachedObjects, (customers, employees, resources) =>
+ {
+ var hasRightToSeeAllEmployeeAppointments = BeWoApp.LoggedOnUser.HasRight(UserRightType.KalenderMitarbeitertermineAnsehen);
+ var employeeOid = BeWoApp.LoggedOnEmployeeOid;
+
+ if(employeeOid.HasValue)
+ {
+ ServiceFacade.DoResourceServiceAsync(s => s.LoadFilteredAppointmentsMitAufgaben(hasRightToSeeAllEmployeeAppointments, employeeOid.Value, newFetchingInterval.Start, newFetchingInterval.End, selectedEmployeeOids, selectedCustomerOids, selectedResourceOids, employeesOnly, customersOnly, resourcesOnly, onlyPrivateAppointments, showOnlyMyAppointments, showTasks), appointments =>
+ {
+ ServiceFacade.DoResourceServiceAsync(s2 => s2.GetAllActiveAbsenceTimesInInterval(newFetchingInterval.Start, newFetchingInterval.End, employeeOid.Value, hasRightToSeeAllEmployeeAppointments), absenceTimes =>
+ {
+ this.Dispatch(() =>
+ {
+ ViewModel.AllCustomers = new ObservableSortCollection(customers);
+ ViewModel.FilteredCustomers = new ObservableSortCollection(customers);
+
+ ViewModel.AllEmployees = new ObservableSortCollection(employees);
+ ViewModel.Employees = new ObservableSortCollection();
+ ViewModel.FilteredEmployees = new ObservableSortCollection();
+
+ foreach(var employee in employees)
+ {
+ var employeeDependencyObject = new EmployeeDependencyObject(employee);
+
+ ViewModel.Employees.AddIfNotIn(employeeDependencyObject);
+ ViewModel.FilteredEmployees.AddIfNotIn(employeeDependencyObject);
+ }
+
+ ViewModel.SelectEmployeesAfterReload();
+
+ var cats2Res = new ObservableDictionary>();
+
+ foreach(var cat2Res in resources)
+ {
+ cats2Res.Add(new CategoryDependencyObject(cat2Res.Key), cat2Res.Value.Select(s => new ResourceDependencyObject(s)).ToList());
+ }
+
+ ViewModel.Categories2Resources = cats2Res;
+
+ ViewModel.SelectedAppointments.Clear();
+
+ ViewModel.VMList.Clear();
+
+ foreach(var appointment in appointments)
+ {
+ ViewModel.VMList.AddIfNotIn(new SchedulingAppointmentVM(appointment));
+ }
+
+ if(showAbsenceTimes)
+ {
+ ViewModel.VMList.AddRangeIfElementsNotIn(Utils.ConvertAbsenceTimesToAppointments(absenceTimes, end, employees));
+ }
+
+ ViewModel.UpdateSelectedItems();
+
+ if(_IsComingFromHomeDragPanel && !(_SelectedAppointmentFromHomePanelView is null))
+ {
+ var range = new DateTimeRange(start, end);
+ var appointmentItems = SchedulerControl.GetAppointments(range);
+ AppointmentItem appointment2Edit = null;
+
+ if(_SelectedAppointmentFromHomePanelView.SchedulerAppointmentOid.HasValue)
+ {
+ appointment2Edit = appointmentItems.FirstOrDefault(f => long.TryParse(f.Id?.ToString(), out var oid) && oid == _SelectedAppointmentFromHomePanelView.SchedulerAppointmentOid.Value);
+ }
+ else
+ {
+ var recurrenceId = _SelectedAppointmentFromHomePanelView.RecurrenceId;
+ var recurrenceIndex = _SelectedAppointmentFromHomePanelView.RecurrenceIndex;
+
+ if(!string.IsNullOrEmpty(recurrenceId))
+ {
+ appointment2Edit = appointmentItems.FirstOrDefault(f => f.RecurrenceIndex == recurrenceIndex && f.RecurrenceInfoId?.ToString() == recurrenceId);
+ }
+ }
+
+ if(!(appointment2Edit is null))
+ {
+ SchedulerControl.ShowAppointmentWindow(appointment2Edit, false);
+ }
+
+ _SelectedAppointmentFromHomePanelView = null;
+ }
+
+ ReloadRights();
+
+ UpdateRequestString(isFirstTimeLoading);
+
+ if(!string.IsNullOrEmpty(MitarbeiterSuchTextBox.Text))
+ {
+ ViewModel.FilterEmployees(MitarbeiterSuchTextBox.Text);
+ }
+
+ if(!string.IsNullOrEmpty(KlientenSuchTextBox.Text))
+ {
+ ViewModel.FilterCustomers(KlientenSuchTextBox.Text);
+ }
+ });
+ }, true);
+ }, true);
+ }
+ });
+ }
+
+ private static void GetCachedObjects(bool reloadCachedObjects, Action, List, Dictionary>> callback)
+ {
+ if(BeWoApp.LoggedOnEmployeeOid.HasValue)
+ {
+ Cache.GetInstance().GetAllActiveCustomersCompactForEmployee(BeWoApp.LoggedOnEmployeeOid.Value, reloadCachedObjects, customers =>
+ {
+ Cache.GetInstance().GetAllActiveCompactEmployeesForEmployee(BeWoApp.LoggedOnEmployeeOid.Value, reloadCachedObjects, employees =>
+ {
+ ServiceFacade.DoResourceServiceAsync(s => s.GetAllCategories2ResourcesInDictionary(), cat2Res =>
+ {
+ callback?.Invoke(customers, employees, cat2Res);
+ });
+ });
+ });
+ }
+ }
+
+ private void CheckForAppointmentRequests()
+ {
+ var appointments = SchedulingUtils.Utils.SeperateStatusUpdatesAndAppointments(_OpenAppointments);
+
+ if(!appointments.Appointments.Any() && !appointments.StatusUpdates.Any())
+ {
+ return;
+ }
+
+ var openAppointmentsView = new OpenAppointmentsView(appointments.Appointments, appointments.StatusUpdates);
+ openAppointmentsView.Closed += (s, e) => { ReloadAndUpdateRequestStringEvent(); };
+ openAppointmentsView.ParticipationChanged += (s, e) => { ReloadAndUpdateRequestStringEvent(); };
+
+ openAppointmentsView.ShowDialog();
+ }
+
+ private void ReloadAndUpdateRequestStringEvent()
+ {
+ ReloadViewModel(true);
+ UpdateRequestString();
+ }
+
+ private List _OpenAppointments = new List();
+
+ public void UpdateRequestString(bool openConfirmationView = false)
+ {
+ if(ViewModel.DisableUpdateRequestString || BeWoApp.LoggedOnEmployeeOid is null)
+ {
+ return;
+ }
+
+ ServiceFacade.DoResourceServiceAsync(s => s.GetAllOpenAppointmentsForEmployee(BeWoApp.LoggedOnEmployeeOid.Value), openAppointments =>
+ {
+ this.Dispatch(() =>
+ {
+ _OpenAppointments = openAppointments;
+
+ var count = 0;
+ var oidList = new List();
+
+ foreach(var openAppointment in _OpenAppointments)
+ {
+ if(openAppointment.Originator.Equals(BeWoApp.CompactLoggedOnEmployee))
+ {
+ foreach(var employee2Appointment in openAppointment.EmployeeList.Where(e2a => e2a.Employee.Equals(BeWoApp.CompactLoggedOnEmployee)))
+ {
+ if(employee2Appointment.IsPChanged && employee2Appointment.ParticipationAnswer != ParticipationAnswer.Offen && employee2Appointment.ParticipationAnswer != ParticipationAnswer.Verstrichen && employee2Appointment.Employee2SchedulerAppointmentOid.HasValue)
+ {
+ oidList.AddIfNotIn(employee2Appointment.Employee2SchedulerAppointmentOid.Value);
+ count++;
+ }
+ }
+ }
+ else if(openAppointment.EmployeeList.Any(e2a => e2a.Employee.Equals(BeWoApp.CompactLoggedOnEmployee)))
+ {
+ foreach(var employee2Appointment in openAppointment.EmployeeList)
+ {
+ if(employee2Appointment.IsPChanged && employee2Appointment.ParticipationAnswer == ParticipationAnswer.Offen && employee2Appointment.ParticipationAnswer != ParticipationAnswer.Verstrichen && employee2Appointment.Employee2SchedulerAppointmentOid.HasValue)
+ {
+ oidList.AddIfNotIn(employee2Appointment.Employee2SchedulerAppointmentOid.Value);
+ count++;
+ }
+ }
+ }
+ }
+
+ ViewModel.Enabled = count > 0;
+ ViewModel.Requests = $"{(count == 0 ? "keine" : count.ToString())} Benachrichtigung{(count == 1 ? string.Empty : "en")}";
+
+ if(openConfirmationView)
+ {
+ CheckForAppointmentRequests();
+ }
+ });
+ }, true);
+ }
+
+ private void SpinEditDayViewDayCount_OnLostFocus(object sender, RoutedEventArgs e)
+ {
+ BeWoApp.SaveAppSettings();
+ }
+
+ private void SpinEditTimelineViewDayCount_OnLostFocus(object sender, RoutedEventArgs e)
+ {
+ BeWoApp.SaveAppSettings();
+ }
+
+ private void ReloadButton_OnClick(object sender, RoutedEventArgs e)
+ {
+ ReloadViewModel(true);
+ }
+
+ // ToDo: Implementieren!
+ private void ExportButton_OnClick(object sender, RoutedEventArgs e)
+ {
+
+ }
+
+ private void AbwesenheitenEinAusCheckBox_OnChecked(object sender, RoutedEventArgs e)
+ {
+ ReloadViewModel(true);
+ }
+
+ private void ShowTasksCheckBox_OnClick(object sender, RoutedEventArgs e)
+ {
+ ReloadViewModel(true);
+ }
+
+ private void ShowAppointmentRequests(object sender, RequestNavigateEventArgs e)
+ {
+ CheckForAppointmentRequests();
+ }
+
+ private void ShowPrivateAppointmentsCheckBox_OnClick(object sender, RoutedEventArgs e)
+ {
+ ReloadViewModel(true);
+ }
+
+ private void SpinEditDayViewDayCount_EditValueChanged(object sender, EditValueChangedEventArgs e)
+ {
+ if(e.NewValue != null && int.TryParse(e.NewValue.ToString(), out var count) && count > 0)
+ {
+ if(SchedulerControl.ActiveView is DevExpress.Xpf.Scheduling.DayView activeView)
+ {
+ activeView.DayCount = count;
+
+ BeWoApp.AppSettings.SchedulerDayViewDayCount = count;
+ }
+ }
+ }
+
+ private void SpinEditTimelineViewDayCount_EditValueChanged(object sender, EditValueChangedEventArgs e)
+ {
+ if(e.NewValue != null && int.TryParse(e.NewValue.ToString(), out var count) && count > 0)
+ {
+ if(SchedulerControl.ActiveView is DevExpress.Xpf.Scheduling.TimelineView activeView)
+ {
+ activeView.IntervalCount = count;
+ }
+
+ BeWoApp.AppSettings.SchedulerTimelineViewDayCount = count;
+ }
+ }
+
+ private void PrintCalendar(object sender, RequestNavigateEventArgs e)
+ {
+ var visibleIntervals = SchedulerControl.VisibleIntervals;
+
+ var start = visibleIntervals[0].Start;
+ var end = visibleIntervals.Last().End;
+
+ var dtr = new DateTimeRange(start, end);
+
+ var appointmentItems = SchedulerControl.GetAppointments(dtr, null);
+ var appointmentsAndTasks = new List();
+
+ var dates = new List();
+
+ for(var i = 0; i < dtr.Duration.Days; i++)
+ {
+ dates.AddIfNotIn(start.AddDays(i));
+ }
+
+ // Abwesenheiten rausfiltern
+ foreach(var appointmentItem in appointmentItems)
+ {
+ if(appointmentItem.CustomFields["VMForCustomField"] is SchedulingAppointmentVM vm && !vm.IsAbsenceTime)
+ {
+ if(appointmentItem.Type == AppointmentType.Occurrence)
+ {
+ var occurrenceVM = CreateChangedOccurrence(appointmentItem);
+ appointmentsAndTasks.AddIfNotIn(occurrenceVM.CommitToDataContract());
+ }
+ else
+ {
+ appointmentsAndTasks.AddIfNotIn(vm.CommitToDataContract());
+ }
+ }
+ }
+
+ var appointmentOids = appointmentsAndTasks.Where(w => w.SchedulerAppointmentOid.HasValue).Select(s => s.SchedulerAppointmentOid.Value).ToList();
+ var withoutOid = appointmentsAndTasks.Where(w => w.SchedulerAppointmentOid is null).ToList();
+
+ // ToDo: Für Montag, 18.07.2022:
+ // ToDo: Serientermine kommen doppelt vor! Mehrtägige Serientermine aus den appointmentOids herausnehmen!
+ var multipleDaysAppointments = appointmentsAndTasks.Where(
+ w =>
+ {
+ if(w.StartDate is null || w.EndDate is null || w.Type == (int) AppointmentType.Pattern)
+ {
+ return false;
+ }
+
+ if(w.AllDay)
+ {
+ return w.StartDate.Value.Date != w.EndDate.Value.AddMinutes(-1).Date;
+ }
+
+ return w.StartDate.Value.Date != w.EndDate.Value.Date;
+ }).ToList();
+
+ appointmentOids.RemoveRange(multipleDaysAppointments.Where(w => w.SchedulerAppointmentOid.HasValue).Select(s => s.SchedulerAppointmentOid.Value));
+
+ var createdAppointments = BreakDownMultipleDaysAppointments(multipleDaysAppointments);
+
+ var variables = new Dictionary
+ {
+ {"appointmentOidListe", appointmentOids},
+ {"datesList", dates},
+ {"employeeOid", BeWoApp.LoggedOnEmployee.EmployeeOid},
+ {"serienTermine", withoutOid},
+ {"mehrtaegigeTermine", createdAppointments}
+ };
+
+ BeWoUtils.ShowReport("Kalender", variables, ReportEnum.KalenderMonatsReportEnum);
+ }
+
+ public static List BreakDownMultipleDaysAppointments(List appointments)
+ {
+ var result = new List();
+
+ foreach(var appointment in appointments)
+ {
+ if(appointment.StartDate is null || appointment.EndDate is null)
+ {
+ continue;
+ }
+
+ var days = appointment.StartDate.Value.GetDayNumberBetweenTwoDates(appointment.EndDate.Value);
+ if(days > 31)
+ {
+ days = 31;
+ }
+
+ if(appointment.AllDay)
+ {
+ days -= 1;
+ }
+
+ if(days > 0)
+ {
+ if(appointment.AllDay)
+ {
+ for(var i = 0; i <= days; i++)
+ {
+ result.Add(new SchedulerAppointmentDC
+ {
+ AllDay = appointment.AllDay,
+ CustomerList = appointment.CustomerList,
+ Description = appointment.Description,
+ EmployeeList = appointment.EmployeeList,
+ EndDate = new DateTime(appointment.StartDate.Value.AddDays(i + 1).Year, appointment.StartDate.Value.AddDays(i + 1).Month, appointment.StartDate.Value.AddDays(i + 1).Day),
+ FormerBookingSequenceOid = appointment.FormerBookingSequenceOid,
+ IsPrivate = appointment.IsPrivate,
+ LabelKey = appointment.LabelKey,
+ Location = appointment.Location,
+ Originator = appointment.Originator,
+ RecurrenceInfo = appointment.RecurrenceInfo,
+ ReminderInfo = appointment.ReminderInfo,
+ ResourceList = appointment.ResourceList,
+ StartDate = new DateTime(appointment.StartDate.Value.AddDays(i).Year, appointment.StartDate.Value.AddDays(i).Month, appointment.StartDate.Value.AddDays(i).Day),
+ Status = appointment.Status,
+ Subject = appointment.Subject,
+ Type = appointment.Type
+ });
+ }
+ }
+ else
+ {
+ for(var i = 0; i <= days; i++)
+ {
+ if(i == 0)
+ {
+ result.Add(new SchedulerAppointmentDC
+ {
+ AllDay = false,
+ CustomerList = appointment.CustomerList,
+ Description = appointment.Description,
+ EmployeeList = appointment.EmployeeList,
+ EndDate = new DateTime(appointment.StartDate.Value.AddDays(1).Year, appointment.StartDate.Value.AddDays(1).Month, appointment.StartDate.Value.AddDays(1).Day),
+ FormerBookingSequenceOid = appointment.FormerBookingSequenceOid,
+ IsPrivate = appointment.IsPrivate,
+ LabelKey = appointment.LabelKey,
+ Location = appointment.Location,
+ Originator = appointment.Originator,
+ RecurrenceInfo = appointment.RecurrenceInfo,
+ ReminderInfo = appointment.ReminderInfo,
+ ResourceList = appointment.ResourceList,
+ StartDate = appointment.StartDate,
+ Status = appointment.Status,
+ Subject = appointment.Subject,
+ Type = appointment.Type
+ });
+ }
+ else if(i == days)
+ {
+ result.Add(new SchedulerAppointmentDC
+ {
+ AllDay = false,
+ CustomerList = appointment.CustomerList,
+ Description = appointment.Description,
+ EmployeeList = appointment.EmployeeList,
+ EndDate = appointment.EndDate,
+ FormerBookingSequenceOid = appointment.FormerBookingSequenceOid,
+ IsPrivate = appointment.IsPrivate,
+ LabelKey = appointment.LabelKey,
+ Location = appointment.Location,
+ Originator = appointment.Originator,
+ RecurrenceInfo = appointment.RecurrenceInfo,
+ ReminderInfo = appointment.ReminderInfo,
+ ResourceList = appointment.ResourceList,
+ StartDate = new DateTime(appointment.EndDate.Value.Year, appointment.EndDate.Value.Month, appointment.EndDate.Value.Day),
+ Status = appointment.Status,
+ Subject = appointment.Subject,
+ Type = appointment.Type
+ });
+ }
+ else
+ {
+ result.Add(new SchedulerAppointmentDC
+ {
+ AllDay = true,
+ CustomerList = appointment.CustomerList,
+ Description = appointment.Description,
+ EmployeeList = appointment.EmployeeList,
+ EndDate = new DateTime(appointment.StartDate.Value.AddDays(i + 1).Year, appointment.StartDate.Value.AddDays(i + 1).Month, appointment.StartDate.Value.AddDays(i + 1).Day),
+ FormerBookingSequenceOid = appointment.FormerBookingSequenceOid,
+ IsPrivate = appointment.IsPrivate,
+ LabelKey = appointment.LabelKey,
+ Location = appointment.Location,
+ Originator = appointment.Originator,
+ RecurrenceInfo = appointment.RecurrenceInfo,
+ ReminderInfo = appointment.ReminderInfo,
+ ResourceList = appointment.ResourceList,
+ StartDate = new DateTime(appointment.StartDate.Value.AddDays(i).Year, appointment.StartDate.Value.AddDays(i).Month, appointment.StartDate.Value.AddDays(i).Day),
+ Status = appointment.Status,
+ Subject = appointment.Subject,
+ Type = appointment.Type
+ });
+ }
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private void NurMeineTermineEinAusCheckBox_OnChecked(object sender, RoutedEventArgs e)
+ {
+ if(sender is CheckBox checkBox && CheckBoxConverter != null && BeWoApp.LoggedOnEmployee != null)
+ {
+ var isChecked = checkBox.IsChecked ?? false;
+
+ if(isChecked)
+ {
+ ViewModel.SelectedEmployees.Clear();
+ ViewModel.SelectedEmployees.Add(LoggedOnCompactEmployee);
+ }
+ else
+ {
+ ViewModel.SelectedEmployees.Remove(LoggedOnCompactEmployee);
+ }
+
+ ReloadViewModel(true);
+ }
+ }
+
+ // Ändert die Hintergrundfarbe der TabItems
+ private void Selector_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ var tabControl = (TabControl) sender;
+ var selectedItem = (TabItem) tabControl.SelectedItem;
+
+ var mitarbeiterPinsel = new LinearGradientBrush(new GradientStopCollection { new GradientStop(Color.FromRgb(69, 153, 59), 0), new GradientStop(Color.FromRgb(32, 92, 25), 1) }, new Point(0.5, 0), new Point(0.5, 1));
+ var klientenPinsel = new LinearGradientBrush(new GradientStopCollection { new GradientStop(Color.FromRgb(59, 119, 153), 0), new GradientStop(Color.FromRgb(25, 72, 92), 1) }, new Point(0.5, 0), new Point(0.5, 1));
+ var ressourcenPinsel = new LinearGradientBrush(new GradientStopCollection { new GradientStop(Color.FromRgb(4, 180, 208), 0), new GradientStop(Color.FromRgb(3, 129, 149), 1) }, new Point(0.5, 0), new Point(0.5, 1));
+
+ var header = selectedItem.Header.ToString();
+
+ if(header == Translator.Translate("Mitarbeiter"))
+ {
+ tabControl.Background = mitarbeiterPinsel;
+ tabControl.BorderBrush = mitarbeiterPinsel;
+ }
+ else if(header == Translator.Translate("Klienten"))
+ {
+ tabControl.Background = klientenPinsel;
+ tabControl.BorderBrush = klientenPinsel;
+ }
+ else
+ {
+ tabControl.Background = ressourcenPinsel;
+ tabControl.BorderBrush = ressourcenPinsel;
+ }
+ }
+
+
+ #region Mitarbeitersuche
+ private void EmployeeSearchToggleButton_OnCheckedUnchecked(object sender, RoutedEventArgs e)
+ {
+ if(sender is ToggleButton toggleButton)
+ {
+ if(toggleButton.IsChecked ?? false)
+ {
+ MitarbeiterSuchGrid.Visibility = Visibility.Visible;
+ MitarbeiterSuchTextBox.Focus();
+ }
+ else
+ {
+ MitarbeiterSuchGrid.Visibility = Visibility.Collapsed;
+ MitarbeiterSuchTextBox.Clear();
+ }
+ }
+ }
+
+ private void TextBoxEmployees_OnTextChanged(object sender, TextChangedEventArgs e)
+ {
+ if(sender is TextBox textBox)
+ {
+ ViewModel.FilterEmployees(textBox.Text);
+ }
+ }
+ # endregion Mitarbeitersuche
+
+ #region Klientensuche
+ private void CustomerSearchToggleButton_OnCheckedUnchecked(object sender, RoutedEventArgs e)
+ {
+ if(sender is ToggleButton toggleButton)
+ {
+ if(toggleButton.IsChecked ?? false)
+ {
+ KlientenSuchGrid.Visibility = Visibility.Visible;
+ KlientenSuchTextBox.Focus();
+ }
+ else
+ {
+ KlientenSuchGrid.Visibility = Visibility.Collapsed;
+ KlientenSuchTextBox.Clear();
+ }
+ }
+ }
+
+ private void TextBoxCustomers_OnTextChanged(object sender, TextChangedEventArgs e)
+ {
+ if(sender is TextBox textBox)
+ {
+ ViewModel.FilterCustomers(textBox.Text);
+ }
+ }
+ #endregion Klientensuche
+
+
+ private void AllEmployeesCheckBox_OnClick(object sender, RoutedEventArgs e)
+ {
+ if(sender is CheckBox checkBox)
+ {
+ if(checkBox.IsChecked ?? false)
+ {
+ ViewModel.SelectAllEmployees();
+ }
+ else
+ {
+ ViewModel.DeselectAllEmployees();
+ ViewModel.AllEmployeesCheckBoxIsChecked = false;
+ }
+
+ if(ViewModel.SelectedEmployees.Count > 1 || ViewModel.SelectedEmployees.Count == 1 && ViewModel.SelectedEmployees.Any(f => f.EmployeeOid.Equals(LoggedOnCompactEmployee.EmployeeOid)))
+ {
+ ViewModel.OnlyMyCustomersCheckBoxIsChecked = false;
+ }
+
+ ViewModel.UpdateSelectedItems();
+ ReloadViewModel(true);
+ }
+ }
+
+ private void ListItem_OnClick(object sender, RoutedEventArgs e)
+ {
+ if(sender is CheckBox checkBox)
+ {
+ var isChecked = checkBox.IsChecked ?? false;
+
+ var item = checkBox.Tag;
+ switch(item)
+ {
+ case CompactCustomerDC customer:
+ if(!isChecked)
+ {
+ ViewModel.SelectedCustomers.Remove(customer);
+ }
+ else
+ {
+ ViewModel.SelectedCustomers.AddIfNotIn(customer);
+ }
+
+ SelectAllResourcesCheckBox.IsChecked = ViewModel.SelectedResources.Count == ViewModel.AllResources.Count;
+
+ ViewModel.UpdateCustomerSelection();
+ break;
+ }
+
+ ViewModel.UpdateSelectedItems();
+
+ ReloadViewModel(true);
+ }
+ }
+
+ private void EmployeeInformationButton_OnClick(object sender, RoutedEventArgs e)
+ {
+ if(sender is Button button && button.DataContext is CompactEmployeeDC employee)
+ {
+ var control = new InformationView();
+
+ ServiceFacade.DoOperationsServiceAsync(s => s.GetXAMLInformationStringForEmployee(employee.EmployeeOid), xaml =>
+ {
+ this.Dispatch(() =>
+ {
+ control.SetXaml(xaml);
+
+ var beWoWindow = new BeWoWindow();
+
+ control.ButtonCloseClicked += () => beWoWindow.Close();
+
+ beWoWindow.Height = 200;
+ beWoWindow.Width = 400;
+ beWoWindow.WindowStartupLocation = WindowStartupLocation.CenterOwner;
+ beWoWindow.GroupBoxContent = control;
+ beWoWindow.Owner = BeWoApp.CurrentBeWo.MainWindow;
+ beWoWindow.rootGroupBox.Header = "Infos zu " + employee.FirstName + " " + employee.LastName;
+ beWoWindow.ShowDialog();
+ });
+ });
+ }
+ }
+
+ private void AllCustomersCheckBox_Checked(object sender, RoutedEventArgs e)
+ {
+ if(sender is CheckBox checkBox)
+ {
+ if(checkBox.IsChecked ?? false)
+ {
+ ViewModel.SelectedCustomers.AddRangeIfElementsNotIn(ViewModel.AllCustomers);
+ }
+ else
+ {
+ ViewModel.SelectedCustomers.Clear();
+
+ ViewModel.AllCustomersCheckBoxIsChecked = false;
+ }
+
+ ViewModel.UpdateSelectedItems();
+
+ ReloadViewModel(true);
+ }
+ }
+
+
+ private void OnlyMyCustomersCheckBox_Click(object sender, RoutedEventArgs e)
+ {
+ if(sender is CheckBox checkBox)
+ {
+ if(checkBox.IsChecked ?? false)
+ {
+ ViewModel.SelectedCustomers.Clear();
+ ViewModel.SelectedCustomers.AddRangeIfElementsNotIn(ViewModel.OwnCustomers);
+ }
+ else
+ {
+ ViewModel.SelectedCustomers.RemoveRange(ViewModel.OwnCustomers);
+ }
+
+ ViewModel.UpdateSelectedItems();
+
+ ReloadViewModel(true);
+ }
+ }
+
+ private void CustomerInformationButton_OnClick(object sender, RoutedEventArgs e)
+ {
+ if(sender is Button button && button.DataContext is CompactCustomerDC customer)
+ {
+ var control = new InformationView();
+
+ ServiceFacade.DoOperationsServiceAsync(s => s.GetXAMLInformationStringForScheduler(customer.CustomerOid), xaml =>
+ {
+ this.Dispatch(() =>
+ {
+ control.SetXaml(xaml);
+
+ var beWoWindow = new BeWoWindow();
+
+ control.ButtonCloseClicked += () => beWoWindow.Close();
+
+ beWoWindow.Height = 200;
+ beWoWindow.Width = 600;
+ beWoWindow.WindowStartupLocation = WindowStartupLocation.CenterOwner;
+ beWoWindow.GroupBoxContent = control;
+ beWoWindow.Owner = BeWoApp.CurrentBeWo.MainWindow;
+ beWoWindow.rootGroupBox.Header = "Infos zu " + customer.FirstName + " " + customer.LastName;
+ beWoWindow.ShowDialog();
+ });
+ });
+ }
+ }
+
+ private void AllResourcesCheckBox_OnClick(object sender, RoutedEventArgs e)
+ {
+ if(sender is CheckBox checkBox && CheckBoxConverter != null)
+ {
+ if(checkBox.IsChecked ?? false)
+ {
+ ViewModel.SelectAllResources();
+ }
+ else
+ {
+ ViewModel.DeselectAllResources();
+
+ ViewModel.AllResourcesCheckBoxChecked = false;
+ }
+
+ ViewModel.UpdateSelectedItems();
+
+ ReloadViewModel(true);
+ }
+ }
+
+ private void AuswahlAufhebenClick(object sender, RoutedEventArgs e)
+ {
+ ViewModel.DeselectAllResources();
+ ViewModel.DeselectAllEmployees();
+
+ ViewModel.SelectedCustomers.Clear();
+
+ if(ViewModel.SelectedEmployees.Count > 1 || ViewModel.SelectedEmployees.Count == 1 && ViewModel.SelectedEmployees.Any(f => f.EmployeeOid.Equals(LoggedOnCompactEmployee.EmployeeOid)))
+ {
+ ViewModel.OnlyMyCustomersCheckBoxIsChecked = false;
+ }
+
+ AlleMitarbeiterCB.IsChecked = false;
+ SelectAllCustomersCheckBox.IsChecked = false;
+
+ ViewModel.AllEmployeesCheckBoxIsChecked = false;
+ ViewModel.AllCustomersCheckBoxIsChecked = false;
+ ViewModel.AllResourcesCheckBoxChecked = false;
+
+ ViewModel.OnlyMyCustomersCheckBoxIsChecked = false;
+
+ ViewModel.UpdateSelectedItems();
+
+ ReloadViewModel(true);
+ }
+
+ private void LeftExpanderClick(object sender, RoutedEventArgs e)
+ {
+ if(sender is ToggleButton toggleButton)
+ {
+ var isChecked = toggleButton.IsChecked ?? false;
+
+ var visibility = ZeigeNurMeineTermineCheckBox.Visibility = isChecked ? Visibility.Collapsed : Visibility.Visible;
+
+ AuswahlGrid.Visibility = visibility;
+ }
+ }
+
+ private void RightExpanderClick(object sender, RoutedEventArgs e)
+ {
+ if(sender is ToggleButton toggleButton)
+ {
+ var isChecked = toggleButton.IsChecked ?? false;
+
+ var visibility = isChecked ? Visibility.Collapsed : Visibility.Visible;
+
+ DateNavigator.Visibility = visibility;
+ }
+ }
+ // TODO: Alle Klienten auswählen fertig machen!
+ private void RemoveElementButton_OnClick(object sender, RoutedEventArgs e)
+ {
+ if(sender is Button button)
+ {
+ if(button.Tag is IDataContract iDataContract)
+ {
+ switch(iDataContract)
+ {
+ case CompactEmployeeDC employee:
+ ViewModel.DeselectEmployee(employee.EmployeeOid);
+
+ if(ViewModel.Employees.Count != ViewModel.SelectedEmployees.Count)
+ {
+ AlleMitarbeiterCB.IsChecked = false;
+ }
+
+ ViewModel.ZeigeNurMeineTermine = ViewModel.SelectedEmployees.Count == 1 && ViewModel.SelectedEmployees.First().Equals(BeWoApp.CompactLoggedOnEmployee);
+
+ break;
+ case CompactCustomerDC customer:
+ ViewModel.SelectedCustomers.Remove(customer);
+
+ if(ViewModel.SelectedCustomers.Count != ViewModel.AllCustomers.Count)
+ {
+ SelectAllCustomersCheckBox.IsChecked = false;
+ }
+
+ break;
+ case ResourceDC resource:
+ if(resource.ResourceOid.HasValue)
+ {
+ ViewModel.DeselectResource(resource.ResourceOid.Value);
+
+ SelectAllResourcesCheckBox.IsChecked = ViewModel.SelectedResources.Count == ViewModel.AllResources.Count;
+ }
+ break;
+ }
+ }
+
+ ViewModel.UpdateSelectedItems();
+ ReloadViewModel(true);
+ }
+ }
+
+ private void DateNavigator_OnSelectedDatesChanged(object sender, EventArgs e)
+ {
+ var navigator = (DevExpress.Xpf.Editors.DateNavigator.DateNavigator) sender;
+
+ var selectedDates = navigator.SelectedDates;
+
+ var isSelectedDateFetched = _LastFetchedInterval.ContainsEveryDateFromList(selectedDates);
+ if(!isSelectedDateFetched && !(_LastFetchedInterval.Start.Equals(new DateTime(1, 1, 1, 0, 0, 0)) && _LastFetchedInterval.End.Equals(new DateTime(1, 1, 1, 0, 30, 0))))
+ {
+ ReloadViewModel();
+ }
+ }
+
+ private AppointmentWindowVM _AppointmentWindowVM;
+ private AppointmentEditView _AppointmentEditView;
+ private void SchedulerControl_OnAppointmentWindowShowing(object sender, AppointmentWindowShowingEventArgs e)
+ {
+ if(e.Appointment.CustomFields["VMForCustomField"] is SchedulingAppointmentVM viewModel)
+ {
+ var appointmentItem = e.Appointment;
+
+ var appointmentType = Utils.GetAppointmentTypeFromViewModel(viewModel.EventType);
+
+ if(appointmentType == AppointmentType.Pattern && e.Appointment.Type == AppointmentType.Occurrence)
+ {
+ var index = e.Appointment.RecurrenceIndex;
+
+ var patternAppointment = SchedulerControl.GetAppointmentItemById(viewModel.DataContract?.SchedulerAppointmentOid);
+
+ if(!(patternAppointment is null))
+ {
+ var exception = SchedulerControl.GetOccurrenceOrException(patternAppointment, index);
+
+ appointmentItem = exception;
+
+ viewModel = CreateChangedOccurrence(appointmentItem);
+ }
+ else
+ {
+ return;
+ }
+ }
+
+ // Nur, wenn es sich nicht um einen Termin aus dem HomeView handelt
+ // TODO: trifft ebenfalls zu, wenn es sich um eine neuerstellte Ausnahme handelt
+ if(viewModel.IsNew && !_IsComingFromHomeDragPanel && viewModel.EventType != (int) AppointmentType.ChangedOccurrence)
+ {
+ viewModel.CustomerList = ViewModel.SelectedCustomers;
+ viewModel.ResourceList = ViewModel.SelectedResources;
+ viewModel.EmployeeList = new ObservableCollection();
+
+ foreach(var employee in ViewModel.SelectedEmployees)
+ {
+ viewModel.EmployeeList.Add(new Employee2SchedulerAppointmentDC { Employee = employee });
+ }
+ }
+
+ _IsComingFromHomeDragPanel = false;
+
+ var teamMemberCustomerOids = new List();
+ ServiceFacade.DoEmployeeServiceSync(s => teamMemberCustomerOids = s.LoadTeamsRelatedCustomerOids(BeWoApp.CompactLoggedOnEmployee.EmployeeOid));
+
+ _AppointmentWindowVM = new AppointmentWindowVM(appointmentItem, (SchedulerControl) sender, ViewModel.AllEmployees, ViewModel.AllCustomers, ViewModel.Categories2Resources, viewModel.Originator ?? BeWoApp.CompactLoggedOnEmployee, teamMemberCustomerOids, viewModel);
+
+ e.Window.DataContext = _AppointmentWindowVM;
+ e.Cancel = true;
+ e.Window.Closed += (o, args) =>
+ {
+ this.Dispatch(() =>
+ {
+ _AppointmentWindowVM = null;
+ _AppointmentEditView = null;
+ ReloadViewModel(true);
+ });
+ };
+
+ _AppointmentEditView = (AppointmentEditView) e.Window;
+
+ e.Window.ShowDialog();
+ }
+ }
+
+ #region Ansicht ändern
+ private void DayViewButton_OnClick(object sender, RoutedEventArgs e)
+ {
+ SetViewType(ViewType.DayView);
+ }
+
+ private void WorkWeekButton_OnClick(object sender, RoutedEventArgs e)
+ {
+ SetViewType(ViewType.WorkWeekView);
+ }
+
+ private void WeekButton_OnClick(object sender, RoutedEventArgs e)
+ {
+ SetViewType(ViewType.WeekView);
+ }
+
+ private void MonthButton_OnClick(object sender, RoutedEventArgs e)
+ {
+ SetViewType(ViewType.MonthView);
+ }
+
+ private void TimelineButton_OnClick(object sender, RoutedEventArgs e)
+ {
+ SetViewType(ViewType.TimelineView);
+ }
+
+ private void SetViewType(ViewType viewType)
+ {
+ SchedulerControl.ActiveViewType = viewType;
+ _CurrentViewType = SchedulerControl.ActiveViewType ?? ViewType.WorkWeekView;
+
+ if(SchedulerControl.ActiveView is DevExpress.Xpf.Scheduling.DayView activeView)
+ {
+ activeView.DayCount = BeWoApp.AppSettings.SchedulerDayViewDayCount;
+ SpinEditDayViewDayCount.Value = activeView.DayCount;
+ }
+
+ if(SchedulerControl.ActiveView is DevExpress.Xpf.Scheduling.TimelineView timelineView)
+ {
+ timelineView.IntervalCount = BeWoApp.AppSettings.SchedulerTimelineViewDayCount;
+ SpinEditTimelineViewDayCount.Value = timelineView.IntervalCount;
+ }
+
+ BeWoApp.AppSettings.SchedulingViewType = _CurrentViewType;
+
+ BeWoApp.SaveAppSettings();
+ }
+ #endregion Ansicht ändern
+
+ #region Termine endgültig löschen
+ private void DeleteAppointmentsForGood_Click(object sender, RoutedEventArgs e)
+ {
+ var employeesOnly = MitarbeiterEbenenCheckBox.IsChecked ?? false;
+ var customersOnly = KlientenEbenenCheckBox.IsChecked ?? false;
+ var resourcesOnly = RessourcenEbenenCheckBox.IsChecked ?? false;
+ var onlyPrivateAppointments = ShowPrivateAppointmentsCheckBox.IsChecked ?? false;
+ var showOnlyMyAppointments = ViewModel.ZeigeNurMeineTermine;
+
+ var loggedOnUserHasRightToSeeAllAppointments = BeWoApp.LoggedOnUser.HasRight(UserRightType.KalenderKliententermineAlleAnsehen) || BeWoApp.LoggedOnUser.HasRight(UserRightType.ViewAll);
+ var loggedOnEmployeeOid = BeWoApp.LoggedOnEmployee.EmployeeOid.Value;
+ var date = DeleteForGoodIntervalEndDateEdit.DateTime;
+
+ var userRights = new Dictionary
+ {
+ {
+ UserRightType.KalenderKliententermineAendern, BeWoApp.LoggedOnUser.HasRight(UserRightType.KalenderKliententermineAendern)
+ },
+ {
+ UserRightType.KalenderMitarbeitertermineAendern, BeWoApp.LoggedOnUser.HasRight(UserRightType.KalenderMitarbeitertermineAendern)
+ },
+ {
+ UserRightType.KalenderRessourcentermineAendern, BeWoApp.LoggedOnUser.HasRight(UserRightType.KalenderRessourcentermineAendern)
+ },
+ {
+ UserRightType.KalenderRessourcentermineAndererAendern, BeWoApp.LoggedOnUser.HasRight(UserRightType.KalenderRessourcentermineAndererAendern)
+ }
+ };
+
+ var dialog = new MessageDialog(() =>
+ {
+ ServiceFacade.DoOperationsServiceAsync(s => s.DeleteAppointmentsInInterval(
+ loggedOnUserHasRightToSeeAllAppointments,
+ loggedOnEmployeeOid,
+ date,
+ ViewModel.SelectedEmployees.Select(employee => employee.EmployeeOid).ToList(),
+ ViewModel.SelectedCustomers.Select(customer => customer.CustomerOid).ToList(),
+ ViewModel.SelectedResources.Select(resource => resource.ResourceOid.Value).ToList(),
+ employeesOnly,
+ customersOnly,
+ resourcesOnly,
+ onlyPrivateAppointments,
+ showOnlyMyAppointments,
+ userRights), () =>
+ {
+ this.Dispatch(() =>
+ {
+ DeleteAppointmentsPopup.IsOpen = false;
+ ReloadViewModel(true);
+ });
+ });
+ });
+
+ ServiceFacade.DoOperationsServiceAsync(
+ s => s.GetMessageFromServerForDeletingAppointments(
+ loggedOnUserHasRightToSeeAllAppointments,
+ loggedOnEmployeeOid,
+ date,
+ ViewModel.SelectedEmployees.Select(employee => employee.EmployeeOid).ToList(),
+ ViewModel.SelectedCustomers.Select(customer => customer.CustomerOid).ToList(),
+ ViewModel.SelectedResources.Select(resource => resource.ResourceOid.Value).ToList(),
+ employeesOnly,
+ customersOnly,
+ resourcesOnly,
+ onlyPrivateAppointments,
+ showOnlyMyAppointments,
+ userRights), xaml =>
+ {
+ this.Dispatch(() =>
+ {
+ dialog.SetXaml(xaml);
+ dialog.ShowDialog();
+ });
+ });
+ }
+
+ private void AbortDeletingAppointments_Click(object sender, RoutedEventArgs e)
+ {
+ DeleteAppointmentsPopup.IsOpen = false;
+ }
+ #endregion Termine endgültig löschen
+
+ private void SchedulerControl_CustomAllowAppointmentCreate(object sender, AppointmentItemOperationEventArgs e)
+ {
+ var customers = ViewModel.SelectedCustomers;
+ var employees = new List();
+ var resources = ViewModel.SelectedResources;
+ var originator = BeWoApp.CompactLoggedOnEmployee;
+
+ foreach(var employee in ViewModel.SelectedEmployees)
+ {
+ employees.Add(new Employee2SchedulerAppointmentDC
+ {
+ Employee = employee,
+ ParticipationAnswer = ParticipationAnswer.Offen
+ });
+ }
+
+ var teamMemberCustomerOids = new List();
+ ServiceFacade.DoEmployeeServiceSync(s => teamMemberCustomerOids = s.LoadTeamsRelatedCustomerOids(BeWoApp.CompactLoggedOnEmployee.EmployeeOid));
+ e.Allow = BS.Shared.Core.Utils.CheckSchedulerRights(customers, resources, employees, originator, true, SchedulerRightsCheckType.Create, BeWoApp.LoggedOnUser, teamMemberCustomerOids);
+ }
+
+ private void SchedulerControl_CustomAllowAppointmentEdit(object sender, AppointmentItemOperationEventArgs e)
+ {
+ var appointment = e.Appointment;
+
+ var viewModel = appointment.CustomFields["VMForCustomField"] as SchedulingAppointmentVM;
+
+ var id = appointment.Id as long?;
+
+ var customers = viewModel?.CustomerList ?? new List();
+ var employees = viewModel?.EmployeeList ?? new ObservableCollection();
+ var resources = viewModel?.ResourceList;
+ var originator = viewModel?.Originator;
+
+ var canBeEdited = viewModel?.CanBeEdited ?? false;
+
+ var teamMemberCustomerOids = new List();
+ ServiceFacade.DoEmployeeServiceSync(s => teamMemberCustomerOids = s.LoadTeamsRelatedCustomerOids(BeWoApp.CompactLoggedOnEmployee.EmployeeOid));
+ e.Allow = canBeEdited && BS.Shared.Core.Utils.CheckSchedulerRights(customers, resources, employees.ToList(), originator, id is null, SchedulerRightsCheckType.Edit, BeWoApp.LoggedOnUser, teamMemberCustomerOids);
+ }
+
+ private void SchedulerControl_OnEditOccurrenceWindowShowing(object sender, EditOccurrenceWindowShowingEventArgs e)
+ {
+ e.Cancel = true;
+ e.ViewModel.EditSeries = false;
+ }
+
+ private void SchedulerControl_OnPopupMenuShowing(object sender, PopupMenuShowingEventArgs e)
+ {
+ if(e.MenuType == ContextMenuType.AppointmentContextMenu)
+ {
+ var menu = (PopupMenu) e.Menu;
+
+ for(var i = 0; i < menu.Items.Count; i++)
+ {
+ if(menu.Items[i] is BarItem menuItem && !(menuItem.Content is null))
+ {
+ var content = menuItem.Content.ToString();
+
+ if(content.Equals("Terminserie wiederherstellen"))
+ {
+ menuItem.ItemClick -= RestoreChangedOccurrence;
+ menuItem.ItemClick += RestoreChangedOccurrence;
+ }
+ else if(content.Equals("Zusagen") || content.Equals("Mit Vorbehalt zusagen") || content.Equals("Absagen"))
+ {
+ menuItem.IsVisible = GetParticipationMenuItemIsVisibleValue(SchedulerControl.SelectedAppointments);
+ }
+ else if(content.Equals("Agenda View"))
+ {
+ menuItem.IsVisible = false;
+ }
+ else if(content.Equals("Löschen"))
+ {
+ menuItem.IsVisible = GetDeleteContextMenuItemVisibility(SchedulerControl.SelectedAppointments.ToList());
+ }
+ }
+ else if(menu.Items[i] is BarItemSeparator separator)
+ {
+ if(separator.Name?.Contains("ZusagenStackSeperator") ?? false)
+ {
+ separator.IsVisible = GetParticipationMenuItemIsVisibleValue(SchedulerControl.SelectedAppointments);
+ }
+ }
+ }
+ }
+ else if(e.MenuType == ContextMenuType.CellContextMenu)
+ {
+ var menu = (PopupMenu) e.Menu;
+
+ foreach(var item in menu.Items)
+ {
+ if(item is BarItem menuItem && !(menuItem.Content is null))
+ {
+ var content = menuItem.Content.ToString();
+
+ if(content.Equals("Ansichtwechsel"))
+ {
+ var barSubItem = (BarSubItem) item;
+
+ foreach(var item2 in barSubItem.Items)
+ {
+ if(item2 is BarCheckItem barCheckItem && (barCheckItem.Content?.Equals("Agenda View") ?? false))
+ {
+ barCheckItem.IsVisible = false;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private static bool GetParticipationMenuItemIsVisibleValue(IEnumerable selectedAppointments)
+ {
+ return selectedAppointments.Any(appointment => appointment.CustomFields["VMForCustomField"] is SchedulingAppointmentVM vm && vm.EmployeeList.Any(a => a.Employee.Equals(BeWoApp.CompactLoggedOnEmployee)));
+ }
+
+ private static bool GetDeleteContextMenuItemVisibility(List selectedAppointments)
+ {
+ var hasRightToDelete = false;
+
+ var dataContracts = new List();
+
+ foreach(var appointmentItem in selectedAppointments)
+ {
+ if((appointmentItem.Type == AppointmentType.Normal || appointmentItem.Type == AppointmentType.ChangedOccurrence) && appointmentItem.CustomFields["VMForCustomField"] is SchedulingAppointmentVM viewModel)
+ {
+ dataContracts.Add(viewModel.CommitToDataContract());
+ }
+ else
+ {
+ dataContracts.Add(new SchedulingAppointmentVM(appointmentItem).CommitToDataContract());
+ }
+ }
+
+ // ToDo: EINKOMMENTIEREN!
+ //ServiceFacade.DoResourceServiceSync(s => hasRightToDelete = s.CheckSchedulerRightsForAppointmentsToEdit(dataContracts, BeWoApp.LoggedOnUser).Any());
+
+ return hasRightToDelete;
+ }
+
+ private void RestoreChangedOccurrence(object sender, ItemClickEventArgs e)
+ {
+ var selectedAppointments = SchedulerControl.SelectedAppointments;
+
+ if(sender is BarButtonItem barButtonItem && selectedAppointments.Count == 1)
+ {
+ var selectedAppointment = selectedAppointments.FirstOrDefault();
+
+ if(!(selectedAppointment is null) && selectedAppointment.Type == AppointmentType.ChangedOccurrence)
+ {
+ if(selectedAppointment.CustomFields["VMForCustomField"] is SchedulingAppointmentVM vm && vm.EventType == (int) AppointmentType.ChangedOccurrence)
+ {
+ var pattern = SchedulerControl.GetPattern(selectedAppointment);
+
+ if(pattern.CustomFields["VMForCustomField"] is SchedulingAppointmentVM patternVM)
+ {
+ var start = patternVM.Start;
+ var end = patternVM.End;
+ var employees = patternVM.EmployeeList.Select(e2s => e2s.Employee.EmployeeOid).ToList();
+ var customers = patternVM.CustomerList.Select(s => s.CustomerOid).ToList();
+ var resources = patternVM.ResourceList.Select(s => s.ResourceOid.Value).ToList();
+ var originator = patternVM.Originator.EmployeeOid;
+ var recurrenceId = selectedAppointment.RecurrenceInfoId?.ToString();
+ var recurrenceIndex = selectedAppointment.RecurrenceIndex;
+
+ var dataContract = vm.CommitToDataContract();
+
+ ServiceFacade.DoResourceServiceAsync(s => s.OverlappingAppointmentsExist(start, end, employees, customers, resources, originator, dataContract.SchedulerAppointmentOid, recurrenceId, recurrenceIndex), isOverlapping =>
+ {
+ if(isOverlapping)
+ {
+ if(MessageBox.Show("Dieser Termin überschneidet sich mit einem anderen, bereits existierenden Termin.", "Überschneidung", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes)
+ {
+ DeleteAppointment(vm.CommitToDataContract());
+ }
+ else
+ {
+ this.Dispatch(() =>
+ {
+ ReloadViewModel(true);
+ });
+ }
+ }
+ else
+ {
+ DeleteAppointment(vm.CommitToDataContract());
+ }
+ });
+ }
+ }
+ }
+ }
+ }
+
+ private void EmployeeAvailabilityBarItem_OnItemClick(object sender, ItemClickEventArgs e)
+ {
+ var interval = SchedulerControl.SelectedInterval;
+
+ ServiceFacade.DoEmployeeServiceAsync(s1 => s1.GetAllActiveEmployeesCompact(),
+ dcs => ServiceFacade.DoReportServiceAsync(
+ s2 => s2.GetMitarbeiterverfuegbarkeiten(dcs, interval.Start, interval.End), s3 => this.Dispatch(() =>
+ {
+ var employeeAvailabilityView = new MitarbeiterverfuegbarkeitsinfoView(s3, interval.Start, interval.End);
+
+ if(employeeAvailabilityView.CommandBindings.Count == 0)
+ {
+ employeeAvailabilityView.CommandBindings.Add(
+ new CommandBinding(
+ ApplicationCommands.Close,
+ (s, e2) =>
+ {
+ if(!employeeAvailabilityView.DoSaveCheck())
+ {
+ return;
+ }
+
+ PopupContent.Visibility = Visibility.Hidden;
+ PopupContent.Child = null;
+ }));
+ }
+
+ PopupContent.Child = employeeAvailabilityView;
+ PopupContent.Height = 400;
+ PopupContent.Width = 450;
+ PopupContent.Visibility = Visibility.Visible;
+ })));
+ }
+
+ private void SchedulerControl_OnRecurrenceWindowShowing(object sender, RecurrenceWindowShowingEventArgs e)
+ {
+ e.Window.Closed += (sender2, e2) =>
+ {
+ if(sender2 is AppointmentRecurrenceEditView recurrenceEditView)
+ {
+
+ if(e.Appointment.CustomFields["VMForCustomField"] is SchedulingAppointmentVM vm)
+ {
+ if(recurrenceEditView.IsCancelled)
+ {
+ vm.RecurrenceInfo = _AppointmentWindowVM.OriginalRecurrenceInfo;
+
+ _AppointmentEditView?.SetRecurrenceInfo(vm.RecurrenceInfo);
+ }
+ else
+ {
+ if(recurrenceEditView.DataContext is RecurrenceWindowViewModel viewModel)
+ {
+ vm.RecurrenceInfo = viewModel.RecurrenceInfo?.ToXml();
+
+ _AppointmentEditView.SetRecurrenceInfo(vm.RecurrenceInfo);
+ }
+ }
+ }
+ }
+ };
+ }
+
+ private void ResourceTreeViewCheckBox_OnChecked(object sender, RoutedEventArgs e)
+ {
+ ViewModel.UpdateResourceSelection();
+ }
+
+ private void SchedulerControl_OnDropAppointment(object sender, DropAppointmentEventArgs e)
+ {
+ var draggedAppointments = e.DragAppointments;
+
+ var dataContracts = new List();
+
+ draggedAppointments.DoForEach(app =>
+ {
+ if(app.CustomFields["VMForCustomField"] is SchedulingAppointmentVM viewModel)
+ {
+ viewModel.Start = app.Start;
+ viewModel.End = app.End;
+
+ // Serientermin wird immer zu ChangedOccurrence, Normal bleibt Normal und DeletedOccurrence wird erst gar nicht angezeigt
+ if(app.Type == AppointmentType.ChangedOccurrence)
+ {
+ if(viewModel.EventType != (int) app.Type)
+ {
+ viewModel = CreateChangedOccurrence(app);
+ }
+ }
+
+ dataContracts.AddIfNotIn(viewModel.CommitToDataContract());
+ }
+ });
+
+ InsertOrUpdateAppointments(dataContracts);
+ }
+
+ private void SchedulerControl_OnCommitAppointmentResize(object sender, CommitAppointmentResizeEventArgs e)
+ {
+ var sourceAppointment = e.SourceAppointment;
+ var resizeAppointment = e.ResizeAppointment;
+
+ if(sourceAppointment.CustomFields["VMForCustomField"] is SchedulingAppointmentVM vm && BeWoApp.LoggedOnUser.UserOid.HasValue)
+ {
+ if(vm.IsAbsenceTime)
+ {
+ e.Cancel = true;
+ return;
+ }
+
+ // Führt zu einer Ausnahme bei Serienterminausnahme bzw. diese wird nicht erzeugt
+ if(sourceAppointment.Type == AppointmentType.Occurrence && resizeAppointment.Type == AppointmentType.ChangedOccurrence)
+ {
+ vm = CreateChangedOccurrence(resizeAppointment);
+ }
+
+ vm.End = resizeAppointment.End;
+
+ if(vm.DataContract.SchedulerAppointmentOid.HasValue)
+ {
+ InsertOrUpdateAppointments(new List { vm.CommitToDataContract() }, () => { e.Cancel = true; });
+ }
+ else
+ {
+ InsertOrUpdateAppointments(new List { vm.CommitToDataContract() }, () => { e.Cancel = true; });
+ }
+ }
+ }
+
+ private void ZeiterfassungButtonItem_OnItemClick(object sender, ItemClickEventArgs e)
+ {
+ if(SchedulerControl.SelectedAppointments.Count <= 0)
+ {
+ return;
+ }
+
+ var appointment = SchedulerControl.SelectedAppointments.FirstOrDefault();
+
+ if(appointment?.CustomFields["VMForCustomField"] is SchedulingAppointmentVM vm)
+ {
+ var employee2SchedulerAppointmentList = vm.EmployeeList;// appointment.CustomFields["EmployeeList"] as ObservableCollection ?? new ObservableCollection();
+ var customerList = vm.CustomerList;// appointment.CustomFields["CustomerList"] as List;
+
+ var employeeList = employee2SchedulerAppointmentList.Select(employee2SchedulerAppointment => employee2SchedulerAppointment.Employee).ToList();
+
+ BeWoUtils.CreateZeiterfassung(appointment.Start, appointment.End, customerList, employeeList, appointment.Subject, appointment, () =>
+ {
+ // Serientermin; Es wird eine Ausnahme in der Datenbank gespeichert mit der dann der Buchungseintrag verknüpft ist.
+ if(appointment.Type == AppointmentType.Occurrence)
+ {
+ vm = CreateChangedOccurrence(appointment);
+ vm.HasServiceRecordEntry = true;
+
+ ServiceFacade.DoResourceServiceAsync(s => s.CheckSchedulerRightsForAppointmentsToEdit(new List { vm.CommitToDataContract() }, BeWoApp.LoggedOnUser),
+ appointments2Insert =>
+ {
+ // Ist maximal ein Termin
+ var app = appointments2Insert.FirstOrDefault();
+
+ if(!(app is null))
+ {
+ ServiceFacade.DoResourceServiceAsync(s2 => s2.InsertSchedulerAppointments(new List { app }), cb =>
+ {
+ this.Dispatch(() =>
+ {
+ ReloadViewModel(true);
+ });
+ });
+ }
+ else
+ {
+ this.Dispatch(() =>
+ {
+ ReloadViewModel(true);
+ });
+ }
+ });
+ }
+ else
+ {
+ vm.HasServiceRecordEntry = true;
+
+ ServiceFacade.DoResourceServiceAsync(s => s.CheckSchedulerRightsForAppointmentEditing(vm.DataContract.SchedulerAppointmentOid.Value, BeWoApp.LoggedOnUser.UserOid.Value), hasRightToEdit =>
+ {
+ if(hasRightToEdit)
+ {
+ ServiceFacade.DoResourceServiceAsync(s2 => s2.UpdateSchedulerAppointments(new List { vm.CommitToDataContract() }), cb =>
+ {
+ this.Dispatch(() =>
+ {
+ ReloadViewModel(true);
+ });
+ });
+ }
+ else
+ {
+ this.Dispatch(() =>
+ {
+ ReloadViewModel(true);
+ });
+ }
+ });
+ }
+ });
+ }
+ }
+
+ private void DeleteAppointmentsInIntervalButton_OnClick(object sender, RoutedEventArgs e)
+ {
+ DeleteAppointmentsPopup.IsOpen = true;
+ }
+
+ private void DeleteAppointment(SchedulerAppointmentDC dataContract)
+ {
+ if(dataContract is null || !BeWoApp.LoggedOnUser.UserOid.HasValue || dataContract.SchedulerAppointmentOid is null || dataContract.NewSchedulerAppointmentVersion is null)
+ {
+ return;
+ }
+
+ var userOid = BeWoApp.LoggedOnUser.UserOid.Value;
+ var appointmentOid = dataContract.SchedulerAppointmentOid.Value;
+ var appointmentVersion = dataContract.NewSchedulerAppointmentVersion.Value;
+
+ ServiceFacade.DoResourceServiceAsync(s => s.CheckSchedulerRightsForAppointmentEditing(appointmentOid, userOid), hasRightToEdit =>
+ {
+ if(hasRightToEdit)
+ {
+ ServiceFacade.DoResourceServiceAsync(s2 => s2.DeleteSchedulerAppointments(new Dictionary { { appointmentOid, appointmentVersion } }), () =>
+ {
+ this.Dispatch(() =>
+ {
+ ReloadViewModel(true);
+ });
+ });
+ }
+ });
+ }
+
+ private void InsertOrUpdateAppointments(List dataContracts, Action noRightToEditCallback = null)
+ {
+ var stopwatch = new Stopwatch();
+ stopwatch.Start();
+
+ ServiceFacade.DoResourceServiceAsync(s => s.CheckSchedulerRightsForAppointmentsToEdit(dataContracts, BeWoApp.LoggedOnUser), appointments =>
+ {
+ if(appointments.Any())
+ {
+ ServiceFacade.DoResourceServiceAsync(s3 => s3.OverlappingAppointmentsExistForMultiple(dataContracts), app2Overlapping =>
+ {
+ this.Dispatch(() =>
+ {
+ stopwatch.Stop();
+ BeWoApp.LogMessage($"Es hat {stopwatch.ElapsedMilliseconds}ms gedauert, um {dataContracts.Count} Termin{(dataContracts.Count > 1 ? "e" : "")} auf Überschneidungen zu prüfen");
+ });
+
+ var overlappingAppointmentCount = app2Overlapping.Count(c => c.Value);
+
+ if(overlappingAppointmentCount > 0)
+ {
+ this.Dispatch(() =>
+ {
+ var message = "Dieser Termin überschneidet sich mit einem anderen, bereits existierenden Termin.";
+ if(overlappingAppointmentCount > 1)
+ {
+ message = $"{overlappingAppointmentCount} Termine überschneiden sich mit anderen, bereits existierenden Terminen.";
+ }
+
+ message += "\r\n\r\nMöchten Sie trotzdem speichern?";
+
+ if(MessageBox.Show(message, "Überschneidung", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes)
+ {
+ ServiceFacade.DoResourceServiceAsync(s2 => s2.InsertOrUpdateSchedulerAppointments(app2Overlapping.Select(kvp => kvp.Key).ToList()), () =>
+ {
+ this.Dispatch(() =>
+ {
+ ReloadViewModel(true);
+ });
+ });
+ }
+ else
+ {
+ ServiceFacade.DoResourceServiceAsync(s2 => s2.InsertOrUpdateSchedulerAppointments(app2Overlapping.Where(w => w.Value == false).Select(kvp => kvp.Key).ToList()), () =>
+ {
+ this.Dispatch(() =>
+ {
+ ReloadViewModel(true);
+ });
+ });
+ }
+ });
+ }
+ else
+ {
+ ServiceFacade.DoResourceServiceAsync(s2 => s2.InsertOrUpdateSchedulerAppointments(app2Overlapping.Select(kvp => kvp.Key).ToList()), () =>
+ {
+ this.Dispatch(() =>
+ {
+ ReloadViewModel(true);
+ });
+ });
+ }
+ });
+ }
+ else
+ {
+ this.Dispatch(() =>
+ {
+ MessageBox.Show("Sie verfügen nicht über die benötigten Rechte, um diesen Termin zu speichern!", "Speichern nicht möglich", MessageBoxButton.OK, MessageBoxImage.Error);
+
+ ReloadViewModel(true);
+ noRightToEditCallback?.Invoke();
+ });
+ }
+ });
+ }
+
+ private void DeactivateAppointments(List appointments2Deactivate)
+ {
+ ServiceFacade.DoResourceServiceAsync(s => s.CheckSchedulerRightsForAppointmentsToEdit(appointments2Deactivate, BeWoApp.LoggedOnUser), appointments =>
+ {
+ if(appointments.Any())
+ {
+ ServiceFacade.DoResourceServiceAsync(s2 => s2.DeleteOrUpdateSchedulerAppointments(appointments), () =>
+ {
+ this.Dispatch(() =>
+ {
+ ReloadViewModel(true);
+ });
+ });
+ }
+ else
+ {
+ this.Dispatch(() =>
+ {
+ ReloadViewModel(true);
+ });
+ }
+ });
+ }
+
+ private void ConfirmParticipationBarButtonItem_OnClick(object sender, ItemClickEventArgs e)
+ {
+ SetParticipationAnswer(ParticipationAnswer.Zusage, SchedulerControl.SelectedAppointments.ToList());
+ }
+
+ private void AcceptWithReservationParticipationBarButtonItem_OnClick(object sender, ItemClickEventArgs e)
+ {
+ SetParticipationAnswer(ParticipationAnswer.Vorbehalt, SchedulerControl.SelectedAppointments.ToList());
+ }
+
+ private void DeclineParticipationBarButtonItem_OnClick(object sender, ItemClickEventArgs e)
+ {
+ SetParticipationAnswer(ParticipationAnswer.Absage, SchedulerControl.SelectedAppointments.ToList());
+ }
+
+ private void SetParticipationAnswer(ParticipationAnswer participationAnswer, List appointmentItems)
+ {
+ if(!(appointmentItems is null))
+ {
+ var applyForAllOccurrences = false;
+ bool? createChangedOccurrencesOrAbort = false;
+
+ var dataContracts = new List();
+
+ var str = string.Empty;
+ switch(participationAnswer)
+ {
+ case ParticipationAnswer.Zusage:
+ str = "zusagen";
+ break;
+ case ParticipationAnswer.Vorbehalt:
+ str = "mit Vorbehalt zusagen";
+ break;
+ case ParticipationAnswer.Absage:
+ str = "absagen";
+ break;
+ }
+
+ var isCheckBoxVisible = appointmentItems.Count(s => s.Type == AppointmentType.Occurrence) > 1;
+
+ foreach(var appointment in appointmentItems)
+ {
+ var vm = appointment.CustomFields["VMForCustomField"] as SchedulingAppointmentVM;
+
+ if(appointment.Type == AppointmentType.Occurrence && applyForAllOccurrences == false)
+ {
+ var window = new OccurrenceParticipationConfirmationView(appointment.Subject, str, isCheckBoxVisible, appointment.Start, appointment.End) { Owner = BeWoApp.CurrentBeWo.MainWindow };
+ window.ShowDialog();
+
+ createChangedOccurrencesOrAbort = window.ShouldChangeSeries;
+
+ if(createChangedOccurrencesOrAbort is null)
+ {
+ break;
+ }
+
+ applyForAllOccurrences = window.ApplyForAllOccurrences;
+ }
+
+ if(createChangedOccurrencesOrAbort == true)
+ {
+ vm = new SchedulingAppointmentVM(appointment, $"");
+ }
+
+ if(!(vm is null))
+ {
+ var employeeList = vm.EmployeeList;
+
+ foreach(var employee2SchedulerAppointment in employeeList)
+ {
+ if(!employee2SchedulerAppointment.Employee.EmployeeOid.Equals(BeWoApp.LoggedOnEmployeeOid))
+ {
+ continue;
+ }
+
+ employee2SchedulerAppointment.ParticipationAnswer = participationAnswer;
+ employee2SchedulerAppointment.IsPC_CheckedTs = null;
+ }
+
+ dataContracts.AddIfNotIn(vm.CommitToDataContract());
+ }
+ }
+
+ if(dataContracts.Any() && createChangedOccurrencesOrAbort.HasValue)
+ {
+ InsertOrUpdateAppointments(dataContracts);
+ }
+ }
+ }
+
+ private void SchedulerControl_OnAppointmentRemoved(object sender, AppointmentRemovedEventArgs e)
+ {
+ var appointments2Deactivate = new List();
+
+ foreach(var appointmentItem in e.Appointments)
+ {
+ var vm = appointmentItem.CustomFields["VMForCustomField"] as SchedulingAppointmentVM;
+
+ if(appointmentItem.Type == AppointmentType.DeletedOccurrence && vm?.EventType != 4)
+ {
+ vm = CreateChangedOccurrence(appointmentItem);
+ vm.EventType = (int) AppointmentType.DeletedOccurrence;
+
+ appointments2Deactivate.AddIfNotIn(vm.CommitToDataContract());
+ }
+ else if(!(vm is null))
+ {
+ appointments2Deactivate.AddIfNotIn(vm.CommitToDataContract());
+ }
+ }
+
+ DeactivateAppointments(appointments2Deactivate);
+ }
+
+ private void SchedulerControl_OnAppointmentAdded(object sender, AppointmentAddedEventArgs e)
+ {
+ var appointments2Insert = e.Appointments;
+
+ var dataContracts = new List();
+
+ foreach(var appointment in appointments2Insert)
+ {
+ if(appointment.CustomFields["VMForCustomField"] is SchedulingAppointmentVM vm)
+ {
+ vm.Originator = BeWoApp.CompactLoggedOnEmployee;
+ dataContracts.Add(vm.CommitToDataContract());
+ }
+ }
+
+ InsertOrUpdateAppointments(dataContracts);
+ }
+
+ private void SchedulerControl_OnPastingFromClipboard(object sender, SchedulerPastingFromClipboardEventArgs e)
+ {
+ var appointmentItems2Copy = e.Appointments;
+ var dataContracts = new List();
+
+ foreach(var appointmentItem in appointmentItems2Copy)
+ {
+ dataContracts.AddIfNotIn(new SchedulingAppointmentVM(appointmentItem).CommitToDataContract());
+ }
+
+ if(dataContracts.Any())
+ {
+ InsertOrUpdateAppointments(dataContracts);
+ }
+
+ e.Cancel = true;
+ }
+
+ private static SchedulingAppointmentVM CreateChangedOccurrence(AppointmentItem appointmentItem)
+ {
+ return new SchedulingAppointmentVM(appointmentItem, $"");
+ }
+
+ private void SchedulerControl_OnAppointmentRemoving(object sender, AppointmentRemovingEventArgs e)
+ {
+ var message = SchedulingUtils.Utils.GetDeactivationMessageForAppointments(e.Appointments);
+
+ if(MessageBox.Show(message, "BeWoPlaner", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.No)
+ {
+ e.Cancel = true;
+ }
+ }
+
+ private void EmployeeListViewCheckBox_OnChecked(object sender, RoutedEventArgs e)
+ {
+ ViewModel.UpdateEmployeeSelection2();
+ }
+
+ private void ClearEmployeeSearchButton_OnClick(object sender, RoutedEventArgs e)
+ {
+ MitarbeiterSuchTextBox.Text = string.Empty;
+ }
+
+ private void ClearCustomerSearchButton_OnClick(object sender, RoutedEventArgs e)
+ {
+ KlientenSuchTextBox.Text = string.Empty;
+ }
+ }
+}
diff --git a/BeWo/Scheduling/ViewModel/AppointmentWindowVM.cs b/BeWo/Scheduling/ViewModel/AppointmentWindowVM.cs
new file mode 100644
index 000000000..0f42bc853
--- /dev/null
+++ b/BeWo/Scheduling/ViewModel/AppointmentWindowVM.cs
@@ -0,0 +1,222 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Windows;
+using BeWo.Scheduling.SchedulingUtils;
+using BS.Shared;
+using BS.Shared.Core;
+using BS.Shared.DataContracts;
+using BS.Shared.DataContracts.Compact;
+using BS.Shared.Extensions;
+using DevExpress.Xpf.Scheduling;
+using DevExpress.XtraScheduler;
+using SchedulerControl = DevExpress.Xpf.Scheduling.SchedulerControl;
+using Utils = BS.Shared.Core.Utils;
+
+namespace BeWo.Scheduling.ViewModel
+{
+ public class AppointmentWindowVM : AppointmentWindowViewModel
+ {
+ #region Verfügbage Mitarbeiter, Klienten und Ressourcen
+ private ObservableCollection _AllEmployees;
+ public ObservableCollection AllEmployees
+ {
+ get => _AllEmployees;
+ set
+ {
+ if(!ICollectionExtensions.ListEquals(_AllEmployees, value))
+ {
+ _AllEmployees = value;
+
+ RaisePropertyChanged(nameof(AllEmployees));
+ }
+ }
+ }
+
+ private ObservableCollection _AllCustomers;
+ public ObservableCollection AllCustomers
+ {
+ get => _AllCustomers;
+ set
+ {
+ if(!ICollectionExtensions.ListEquals(_AllCustomers, value))
+ {
+ _AllCustomers = value;
+
+ RaisePropertyChanged(nameof(AllCustomers));
+ }
+ }
+ }
+
+ private ObservableDictionary> _AllCategories2Resources;
+ public ObservableDictionary> AllCategories2Resources
+ {
+ get => _AllCategories2Resources;
+ set
+ {
+ if(!SchedulingUtils.Utils.Categories2ResourcesEquals(_AllCategories2Resources, value))
+ {
+ _AllCategories2Resources = value;
+
+ RaisePropertiesChanged(nameof(AllCategories2Resources));
+ }
+ }
+ }
+ #endregion
+
+ public string OriginalRecurrenceInfo { get; }
+
+ public SchedulingAppointmentVM ActualViewModel { get; }
+
+ public ObservableCollection EmployeeList
+ {
+ get => ActualViewModel.EmployeeList; //Appointment.CustomFields["EmployeeList"] as ObservableCollection;
+ set => ActualViewModel.EmployeeList = value; //Appointment.CustomFields["EmployeeList"] = value;
+ }
+
+ public List CustomerList
+ {
+ get => ActualViewModel.CustomerList; //Appointment.CustomFields["CustomerList"] as List;
+ set => ActualViewModel.CustomerList = value; //Appointment.CustomFields["CustomerList"] = value;
+ }
+
+ public List ResourceList
+ {
+ get => ActualViewModel.ResourceList; //Appointment.CustomFields["ResourceList"] as List;
+ set => ActualViewModel.ResourceList = value; //Appointment.CustomFields["ResourceList"] = value;
+ }
+
+ public ObservableCollection SupportConceptList
+ {
+ get => ActualViewModel.SupportConceptList; //Appointment.CustomFields["SupportConceptList"] as List;
+ set => ActualViewModel.SupportConceptList = value; //Appointment.CustomFields["SupportConceptList"] = value;
+ }
+
+ public bool IsTask
+ {
+ get => ActualViewModel.IsTask; //Appointment.CustomFields["IsTask"] is bool isTask && isTask;
+ set => ActualViewModel.IsTask = value; //Appointment.CustomFields["IsTask"] = value;
+ }
+
+ public bool IsPrivate
+ {
+ get => ActualViewModel.IsPrivate; //Appointment.CustomFields["IsPrivate"] is bool isPrivate && isPrivate;
+ set => ActualViewModel.IsPrivate = value; //Appointment.CustomFields["IsPrivate"] = value;
+ }
+
+ public bool IsReadyOnly { get; }
+
+ public bool IsNew => ActualViewModel?.IsNew ?? false;
+
+ public CompactEmployeeDC Originator
+ {
+ get => ActualViewModel.Originator; //Appointment.CustomFields["Originator"] as CompactEmployeeDC;
+ set => ActualViewModel.Originator = value; //Appointment.CustomFields["Originator"] = value;
+ }
+
+ public bool IsAbsenceTime => ActualViewModel.IsAbsenceTime; //Appointment.CustomFields["IsAbsenceTime"] is bool isAbsenceTime && isAbsenceTime;
+
+ public string TaskDescription
+ {
+ get => ActualViewModel.TaskDescription; //Appointment.CustomFields["TaskDescription"] as string;
+ set => ActualViewModel.TaskDescription = value; //Appointment.CustomFields["TaskDescription"] = value;
+ }
+
+ public string CompletedNotice
+ {
+ get => ActualViewModel.CompletedNotice; //Appointment.CustomFields["CompletedNotice"] as string;
+ set => ActualViewModel.CompletedNotice = value; //Appointment.CustomFields["CompletedNotice"] = value;
+ }
+
+ public DateTime? CompletedDate
+ {
+ get => ActualViewModel.CompletedDate; //Appointment.CustomFields["CompletedDate"] as DateTime?;
+ set => ActualViewModel.CompletedDate = value; //Appointment.CustomFields["CompletedDate"] = value;
+ }
+
+ public DateTime? DueDate
+ {
+ get => ActualViewModel.DueDate; //Appointment.CustomFields["DueDate"] as DateTime?;
+ set => ActualViewModel.DueDate = value; //Appointment.CustomFields["DueDate"] = value;
+ }
+
+ public DateTime? DueTime
+ {
+ get => ActualViewModel.DueTime; //Appointment.CustomFields["DueTime"] as DateTime?;
+ set => ActualViewModel.DueTime = value; //Appointment.CustomFields["DueTime"] = value;
+ }
+
+ public long? Oid => Appointment.Id as long?;
+
+ public string RecurrenceTypeName => TranslateRecurrenceInfoType();
+
+
+ public ObservableCollection AvailableAppointmentRecurrenceTypes
+ {
+ get;
+ }
+
+ public Visibility RecurrenceButtonVisibility => (Appointment.Type == AppointmentType.Pattern || Appointment.Type == AppointmentType.Normal) && !IsTask ? Visibility.Visible : Visibility.Collapsed;
+
+ public AppointmentWindowVM(
+ AppointmentItem appointmentItem,
+ SchedulerControl scheduler,
+ ObservableCollection allEmployees,
+ ObservableCollection allCustomers,
+ ObservableDictionary> allCategories2Resources,
+ CompactEmployeeDC originator,
+ List teamMemberCustomerOids,
+ SchedulingAppointmentVM viewModel)
+ : base(appointmentItem, scheduler)
+ {
+ ActualViewModel = viewModel;
+
+ OriginalRecurrenceInfo = viewModel.RecurrenceInfo;
+
+ AllEmployees = allEmployees;
+ AllCustomers = allCustomers;
+ AllCategories2Resources = allCategories2Resources;
+
+ ActualViewModel.Originator = originator;
+
+ ActualViewModel.SetDirty(false);
+
+ var userRightsCheckType = IsNew ? SchedulerRightsCheckType.Create : SchedulerRightsCheckType.Edit;
+
+ IsReadyOnly = !Utils.CheckSchedulerRights(CustomerList.ToList(), ResourceList.ToList(), EmployeeList.ToList(), Originator, IsNew, userRightsCheckType, BeWoApp.LoggedOnUser, teamMemberCustomerOids);
+
+ AvailableAppointmentRecurrenceTypes = new ObservableCollection
+ {
+ "(keine)",
+ "täglich",
+ "wöchentlich",
+ "monatlich",
+ "jährlich"
+ };
+ }
+
+
+ private string TranslateRecurrenceInfoType()
+ {
+ if(RecurrenceInfo is null)
+ {
+ return "(keine)";
+ }
+
+ switch(RecurrenceInfo.Type)
+ {
+ case RecurrenceType.Daily:
+ return "täglich";
+ case RecurrenceType.Weekly:
+ return "wöchentlich";
+ case RecurrenceType.Monthly:
+ return "monatlich";
+ case RecurrenceType.Yearly:
+ return "jährlich";
+ default:
+ return "(keine)";
+ }
+ }
+ }
+}
diff --git a/BeWo/Scheduling/ViewModel/SchedulingAppointmentListVM.cs b/BeWo/Scheduling/ViewModel/SchedulingAppointmentListVM.cs
new file mode 100644
index 000000000..433ec1f31
--- /dev/null
+++ b/BeWo/Scheduling/ViewModel/SchedulingAppointmentListVM.cs
@@ -0,0 +1,699 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Windows;
+using BeWo.Scheduling.SchedulingUtils;
+using BeWo.ViewModel.ListViewModel;
+using BS.Shared;
+using BS.Shared.Core;
+using BS.Shared.DataContracts;
+using BS.Shared.DataContracts.Compact;
+using BS.Shared.Extensions;
+using DevExpress.Mvvm;
+
+namespace BeWo.Scheduling.ViewModel
+{
+ public class SchedulingAppointmentListVM : AbstractDCListMapperVM
+ {
+ #region Filtereinstellungen
+ private bool _IsAbsenceTimeVisible;
+ public bool IsAbsenceTimeVisible
+ {
+ get => _IsAbsenceTimeVisible;
+
+ set
+ {
+ _IsAbsenceTimeVisible = value;
+ FirePropertyChanged(nameof(IsAbsenceTimeVisible));
+ }
+ }
+
+ private bool _IsTasksVisible;
+ public bool IsTasksVisible
+ {
+ get => _IsTasksVisible;
+
+ set
+ {
+ _IsTasksVisible = value;
+ FirePropertyChanged(nameof(IsTasksVisible));
+ }
+ }
+
+ private bool _OnlyPrivateAppointments;
+ public bool OnlyPrivateAppointments
+ {
+ get => _OnlyPrivateAppointments;
+ set
+ {
+ _OnlyPrivateAppointments = value;
+ FirePropertyChanged(nameof(OnlyPrivateAppointments));
+ }
+ }
+
+ public bool ZeigeNurMeineTermine
+ {
+ get => BeWoApp.AppSettings.ZeigeNurMeineTermine;
+ set
+ {
+ if(BeWoApp.AppSettings.ZeigeNurMeineTermine != value)
+ {
+ BeWoApp.AppSettings.ZeigeNurMeineTermine = value;
+ BeWoApp.SaveAppSettings();
+ FirePropertyChanged(nameof(ZeigeNurMeineTermine));
+ }
+ }
+ }
+ #endregion Filtereinstellungen
+
+
+ private int _SelectedTabItemIndex;
+ public int SelectedTabItemIndex
+ {
+ get => _SelectedTabItemIndex;
+ set
+ {
+ _SelectedTabItemIndex = value;
+ FirePropertyChanged(nameof(SelectedTabItemIndex));
+ }
+ }
+
+
+ public bool DisableUpdateRequestString = false;
+ private string _Requests;
+
+ public string Requests
+ {
+ get => _Requests ?? (_Requests = "keine Benachrichtigung");
+ set
+ {
+ if(AreDifferent(_Requests, value))
+ {
+ _Requests = value ?? string.Empty;
+ FirePropertyChanged(nameof(Requests));
+ }
+ }
+ }
+
+ private bool _IsEmployeeBrushVisible;
+
+ public bool IsEmployeeBrushVisible
+ {
+ get => _IsEmployeeBrushVisible;
+
+ set
+ {
+ _IsEmployeeBrushVisible = value;
+ FirePropertyChanged(nameof(IsEmployeeBrushVisible));
+ }
+ }
+
+ public bool IsInCustomerViewMode { get; set; }
+
+
+ public ObservableCollection AllResources
+ {
+ get
+ {
+ if(Categories2Resources?.Any() ?? false)
+ {
+ var result = new ObservableCollection();
+
+ foreach(var cat2Res in Categories2Resources)
+ {
+ foreach(var res in cat2Res.Value)
+ {
+ result.AddIfNotIn(res.DataContract);
+ }
+ }
+
+ return result;
+ }
+
+ return new ObservableCollection();
+ }
+ }
+
+ private ObservableSortCollection _FilteredEmployees;
+ ///
+ /// Die nach Suchtext gefilterten Mitarbeiter
+ ///
+ public ObservableSortCollection FilteredEmployees
+ {
+ get => _FilteredEmployees ?? (_FilteredEmployees = new ObservableSortCollection(Employees));
+
+ set
+ {
+ if(!ICollectionExtensions.ListEquals(_FilteredEmployees, value))
+ {
+ _FilteredEmployees = value;
+ _FilteredEmployees.Sort((x, y) => string.Compare(x.Employee.LastName + ", " + x.Employee.FirstName, y.Employee.LastName + ", " + y.Employee.FirstName, StringComparison.Ordinal));
+
+ FirePropertyChanged(nameof(FilteredEmployees));
+ }
+ }
+ }
+
+ private ObservableSortCollection _FilteredCustomers;
+ ///
+ /// Die nach Suchtext gefilterten Klienten
+ ///
+ public ObservableSortCollection FilteredCustomers
+ {
+ get => _FilteredCustomers ?? (_FilteredCustomers = new ObservableSortCollection(AllCustomers));
+
+ set
+ {
+ if(!ICollectionExtensions.ListEquals(_FilteredCustomers, value))
+ {
+ _FilteredCustomers = value;
+ _FilteredCustomers.Sort((x, y) => string.Compare(x.LastName + ", " + x.FirstName, y.LastName + ", " + y.FirstName, StringComparison.Ordinal));
+
+ FirePropertyChanged(nameof(FilteredCustomers));
+ }
+ }
+ }
+
+ private ObservableSortCollection _CustomerList;
+ public ObservableSortCollection CustomerList
+ {
+ get => _CustomerList ?? (_CustomerList = new ObservableSortCollection());
+
+ set
+ {
+ if(!ICollectionExtensions.ListEquals(_CustomerList, value))
+ {
+ _CustomerList = value;
+ _CustomerList.Sort((x, y) => string.Compare(x.LastName + ", " + x.FirstName, y.LastName + ", " + y.FirstName, StringComparison.Ordinal));
+ FirePropertyChanged(nameof(CustomerList));
+ }
+ }
+ }
+
+ private List _SelectedEmployees = new List();
+ public List SelectedEmployees
+ {
+ get => _SelectedEmployees;
+ set
+ {
+ if(!ICollectionExtensions.ListEquals(_SelectedEmployees, value))
+ {
+ _SelectedEmployees = value;
+ _SelectedEmployees.Sort((x, y) => string.Compare(x.LastName + ", " + x.FirstName, y.LastName + ", " + y.FirstName, StringComparison.Ordinal));
+
+ AllEmployeesCheckBoxIsChecked = ICollectionExtensions.ListEquals(value, AllEmployees);
+
+ ZeigeNurMeineTermine = value.Count == 1 && value.Contains(BeWoApp.CompactLoggedOnEmployee);
+
+ UpdateSelectedItems();
+ }
+ }
+ }
+
+ private List _SelectedCustomers = new List();
+ public List SelectedCustomers
+ {
+ get => _SelectedCustomers;
+ set
+ {
+ if(!ICollectionExtensions.ListEquals(_SelectedCustomers, value))
+ {
+ _SelectedCustomers = value;
+ _SelectedCustomers.Sort((x, y) => string.Compare(x.LastName + ", " + x.FirstName, y.LastName + ", " + y.FirstName, StringComparison.Ordinal));
+
+ if(OnlyMyCustomersCheckBoxIsChecked || ICollectionExtensions.ListEquals(AllCustomers, value))
+ {
+ AllCustomersCheckBoxIsChecked = true;
+ }
+
+ UpdateSelectedItems();
+ }
+ }
+ }
+
+ private List _SelectedResources = new List();
+ public List SelectedResources
+ {
+ get => _SelectedResources;
+ set
+ {
+ if(!ICollectionExtensions.ListEquals(_SelectedResources, value))
+ {
+ _SelectedResources = value;
+
+ AllResourcesCheckBoxChecked = ICollectionExtensions.ListEquals(value, AllResources);
+
+ UpdateSelectedItems();
+ }
+ }
+ }
+
+
+
+
+
+ private bool _AllEmployeesCheckBoxIsChecked;
+ public bool AllEmployeesCheckBoxIsChecked
+ {
+ get => _AllEmployeesCheckBoxIsChecked;
+
+ set
+ {
+ _AllEmployeesCheckBoxIsChecked = value;
+
+ FirePropertyChanged(nameof(AllEmployeesCheckBoxIsChecked));
+ UpdateSelectedItems();
+ }
+ }
+
+
+ private bool _OnlyMyCustomersCheckBoxIsChecked;
+ public bool OnlyMyCustomersCheckBoxIsChecked
+ {
+ get => _OnlyMyCustomersCheckBoxIsChecked;
+ set
+ {
+ if(AreDifferent(_OnlyMyCustomersCheckBoxIsChecked, value))
+ {
+ _OnlyMyCustomersCheckBoxIsChecked = value;
+ FilterCustomers();
+ SelectedCustomers.Clear();
+ SelectedCustomers = FilteredCustomers.ToList();
+ FirePropertyChanged(nameof(OnlyMyCustomersCheckBoxIsChecked));
+ UpdateSelectedItems();
+ }
+ }
+ }
+
+
+ private bool _AllCustomersCheckBoxIsChecked;
+ public bool AllCustomersCheckBoxIsChecked
+ {
+ get => _AllCustomersCheckBoxIsChecked;
+
+ set
+ {
+ _AllCustomersCheckBoxIsChecked = value;
+
+ FirePropertyChanged(nameof(AllCustomersCheckBoxIsChecked));
+ UpdateSelectedItems();
+ }
+ }
+
+ private bool _AllResourcesCheckBoxChecked;
+ public bool AllResourcesCheckBoxChecked
+ {
+ get => _AllResourcesCheckBoxChecked;
+
+ set
+ {
+ _AllResourcesCheckBoxChecked = value;
+
+ FirePropertyChanged(nameof(AllResourcesCheckBoxChecked));
+ UpdateSelectedItems();
+ }
+ }
+
+
+
+
+ public ObservableCollection SelectedItems
+ {
+ get
+ {
+ var selectedItems = new ObservableCollection();
+
+ selectedItems.AddRange(SelectedEmployees);
+ selectedItems.AddRange(SelectedCustomers);
+ selectedItems.AddRange(SelectedResources);
+
+ return selectedItems;
+ }
+ }
+
+ public IEnumerable AllItems
+ {
+ get
+ {
+ var allItems = new List();
+
+ allItems.AddRange(FilteredEmployees.Select(s => s.Employee));
+ allItems.AddRange((IEnumerable)FilteredCustomers);
+ allItems.AddRange(AllResources);
+
+ return allItems;
+ }
+ }
+
+ public Visibility EmployeeControlsVisibility => BeWoApp.LoggedOnUser.HasRight(UserRightType.KalenderMitarbeitertermineAnsehen) ? Visibility.Visible : Visibility.Collapsed;
+ public Visibility ResourceControlsVisibility => BeWoApp.LoggedOnUser.HasRight(UserRightType.KalenderRessourcentermineAnsehen) ? Visibility.Visible : Visibility.Collapsed;
+ public Visibility CustomerControlsVisibility => BeWoApp.LoggedOnUser.HasRight(UserRightType.CustomerView_View) || BeWoApp.LoggedOnUser.HasRight(UserRightType.Customer_ViewMyTeams) || BeWoApp.LoggedOnUser.HasRight(UserRightType.Customer_ViewMyCustomers) || BeWoApp.LoggedOnUser.HasRight(UserRightType.ViewAll) ? Visibility.Visible : Visibility.Collapsed;
+
+ public Visibility SelectionControlVisibility => EmployeeControlsVisibility == Visibility.Visible || ResourceControlsVisibility == Visibility.Visible || CustomerControlsVisibility == Visibility.Visible ? Visibility.Visible : Visibility.Collapsed;
+
+ public Visibility DeleteInInvervalButtonVisibility => BeWoApp.LoggedOnUser.HasRight(UserRightType.Termine_IntervalDelete) ? Visibility.Visible : Visibility.Collapsed;
+
+ private DateTimeRange _Interval;
+
+ public DateTimeRange Interval
+ {
+ get => _Interval;
+ set
+ {
+ if(AreDifferent(_Interval, value))
+ {
+ _Interval = value;
+ FirePropertyChanged(nameof(Interval));
+ }
+ }
+ }
+
+ public void ReloadRights()
+ {
+ FirePropertyChanged(nameof(EmployeeControlsVisibility));
+ FirePropertyChanged(nameof(ResourceControlsVisibility));
+ FirePropertyChanged(nameof(CustomerControlsVisibility));
+ FirePropertyChanged(nameof(SelectionControlVisibility));
+ FirePropertyChanged(nameof(DeleteInInvervalButtonVisibility));
+ }
+
+ public bool ShouldLockOverlappingAppointmentCheck { get; set; }
+
+
+ private ObservableSortCollection _AllCustomers;
+ public ObservableSortCollection AllCustomers
+ {
+ get => _AllCustomers ?? (_AllCustomers = new ObservableSortCollection());
+ set
+ {
+ if(AreDifferent(_AllCustomers, value))
+ {
+ _AllCustomers = value;
+ FilterCustomers();
+ FirePropertyChanged(nameof(AllCustomers));
+ }
+ }
+ }
+
+ private ObservableSortCollection _AllEmployees;
+ public ObservableSortCollection AllEmployees
+ {
+ get => _AllEmployees ?? (_AllEmployees = new ObservableSortCollection());
+ set
+ {
+ if(AreDifferent(_AllEmployees, value))
+ {
+ _AllEmployees = value;
+ FirePropertyChanged(nameof(AllEmployees));
+ }
+ }
+ }
+
+ public ObservableCollection SelectedAppointments { get; set; }
+
+ private ObservableDictionary> _Categories2Resources;
+
+ public ObservableDictionary> Categories2Resources
+ {
+ get => _Categories2Resources ?? (_Categories2Resources = new ObservableDictionary>());
+
+ set
+ {
+ if(!SchedulingUtils.Utils.Categories2ResourcesEquals(_Categories2Resources, value))
+ {
+ _Categories2Resources = value;
+ FirePropertyChanged(nameof(Categories2Resources));
+ }
+ }
+ }
+
+
+ public List OwnCustomers { get; }
+
+ public SchedulingAppointmentListVM()
+ {
+ Categories2Resources = new ObservableDictionary>();
+ AllCustomers = new ObservableSortCollection();
+ AllEmployees = new ObservableSortCollection();
+
+ SelectedAppointments = new ObservableCollection();
+
+ OwnCustomers = BeWoApp.LoggedOnEmployee.RelatedCustomers.Select(s => s.Customer).ToList();
+
+ UpdateSelectedItems();
+
+ InitViewModel();
+ }
+
+ public void AddAbsenceTimes(List absenceTimes, DateTime intervalEnd)
+ {
+ foreach(var absenceTime in absenceTimes.Where(w => w.Start != null))
+ {
+ var subject = absenceTime.Reason.Description;
+ var employee = absenceTime.EmployeeOid != null ? AllEmployees.FirstOrDefault(e => e.EmployeeOid == absenceTime.EmployeeOid.Value) : null;
+
+ if(employee != null)
+ {
+ subject += $" ({employee.SimpleDescription})";
+ }
+
+ var absenceTimeEnd = absenceTime.End?.AddTicks(1);
+
+ VMList.Add(new SchedulingAppointmentVM(true, subject, absenceTime.Start.Value, absenceTime.End ?? intervalEnd, employee, absenceTime.Start, absenceTimeEnd));
+ }
+ }
+
+ private bool _Enabled;
+
+ public bool Enabled
+ {
+ get => _Enabled;
+ set
+ {
+ _Enabled = value;
+ FirePropertyChanged(nameof(Enabled));
+ }
+ }
+
+ private void InitViewModel()
+ {
+ foreach(var item in VMList)
+ {
+ item.Id = item.DataContract.SchedulerAppointmentOid;
+
+ if(!item.IsPrivate || item.Originator.EmployeeOid.Equals(BeWoApp.LoggedOnEmployee.EmployeeOid) || item.EmployeeList.Select(s => s.Employee).Contains(BeWoApp.CompactLoggedOnEmployee))
+ {
+ continue;
+ }
+
+ item.Description = "Privater Termin";
+ item.Subject = $"Privat ({item.Originator})";
+ }
+ }
+
+ private ObservableCollection _OpenAppointments;
+
+ public ObservableCollection OpenAppointments
+ {
+ get => _OpenAppointments;
+ set
+ {
+ if(AreDifferent(_OpenAppointments, value))
+ {
+ _OpenAppointments = value;
+ FirePropertyChanged(nameof(OpenAppointments));
+ }
+ }
+ }
+
+ public void FilterCustomers()
+ {
+ FilteredCustomers.Clear();
+
+ var customersToAdd = OnlyMyCustomersCheckBoxIsChecked ? AllCustomers.Where(customer => customer.IsRelatedToEmployee) : AllCustomers;
+
+ FilteredCustomers.AddRange(customersToAdd);
+ }
+
+ public void UpdateSelectedItems()
+ {
+ FirePropertyChanged(nameof(SelectedItems));
+ FirePropertyChanged(nameof(SelectedEmployees));
+ FirePropertyChanged(nameof(SelectedCustomers));
+ FirePropertyChanged(nameof(SelectedResources));
+ FirePropertyChanged(nameof(VMList));
+ FirePropertyChanged(nameof(Categories2Resources));
+ FirePropertyChanged(nameof(FilteredEmployees));
+ FirePropertyChanged(nameof(Employees));
+ FirePropertyChanged(nameof(AllEmployeesCheckBoxIsChecked));
+ }
+
+ public void UpdateEmployeeSelection()
+ {
+ AllEmployeesCheckBoxIsChecked = SelectedEmployees.Count == AllEmployees.Count;
+ }
+
+ public void UpdateEmployeeSelection2()
+ {
+ SelectedEmployees = GetSelectedEmployees();
+
+ FirePropertyChanged(nameof(Employees));
+ AllEmployeesCheckBoxIsChecked = SelectedEmployees.Count == AllEmployees.Count;
+ }
+
+ public void UpdateCustomerSelection()
+ {
+ AllCustomersCheckBoxIsChecked = SelectedCustomers.Count == AllCustomers.Count;
+ }
+
+ public void UpdateResourceSelection()
+ {
+ SelectedResources = new List(GetSelectedResources());
+
+ FirePropertyChanged(nameof(Categories2Resources));
+ AllResourcesCheckBoxChecked = SelectedResources.Count == AllResources.Count;
+ }
+
+ public void FilterEmployees(string searchText)
+ {
+ FilteredEmployees.Clear();
+ FilteredEmployees.AddRangeIfElementsNotIn(
+ Employees.Where(employeeDependencyObject => employeeDependencyObject.Employee.FirstName.ToLower().Contains(searchText.ToLower()) ||
+ employeeDependencyObject.Employee.LastName.ToLower().Contains(searchText.ToLower())
+ ));
+ }
+
+ public void FilterCustomers(string searchText)
+ {
+ FilteredCustomers.Clear();
+ FilteredCustomers.AddRangeIfElementsNotIn(AllCustomers.Where(customer => customer.FirstName.ToLower().Contains(searchText.ToLower()) || customer.LastName.ToLower().Contains(searchText.ToLower())));
+ }
+
+ private IEnumerable GetSelectedResources()
+ {
+ var result = new List();
+
+ foreach(var cat2Res in Categories2Resources)
+ {
+ foreach(var resource in cat2Res.Value)
+ {
+ if(resource.GetValue(TreeViewItemHelper.IsCheckedProperty) is bool value && value)
+ {
+ result.AddIfNotIn(resource.DataContract);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ public void DeselectResource(long oid)
+ {
+ foreach(var cat2Res in Categories2Resources)
+ {
+ foreach(var resource in cat2Res.Value)
+ {
+ if(resource.DataContract.ResourceOid.HasValue && resource.DataContract.ResourceOid.Value == oid)
+ {
+ resource.SetValue(TreeViewItemHelper.IsCheckedProperty, false);
+ }
+ }
+ }
+ }
+
+ public void DeselectAllResources()
+ {
+ foreach(var cat2Res in Categories2Resources)
+ {
+ foreach(var resource in cat2Res.Value)
+ {
+ resource.SetValue(TreeViewItemHelper.IsCheckedProperty, false);
+ }
+ }
+
+ SelectedResources.Clear();
+ }
+
+ public void SelectAllResources()
+ {
+ foreach(var cat2Res in Categories2Resources)
+ {
+ foreach(var resource in cat2Res.Value)
+ {
+ resource.SetValue(TreeViewItemHelper.IsCheckedProperty, true);
+ }
+ }
+
+ UpdateResourceSelection();
+ }
+
+ private ObservableSortCollection _Employees;
+ public ObservableSortCollection Employees
+ {
+ get => _Employees ?? (_Employees = new ObservableSortCollection());
+ set
+ {
+ if(AreDifferent(_Employees, value))
+ {
+ _Employees = value;
+ FirePropertyChanged(nameof(Employees));
+ }
+ }
+ }
+
+ private List GetSelectedEmployees()
+ {
+ var result = new List();
+
+ foreach(var employee in Employees)
+ {
+ if(employee.GetValue(ListItemHelper.IsCheckedProperty) is bool isChecked && isChecked)
+ {
+ result.AddIfNotIn(employee.Employee);
+ }
+ }
+
+ return result;
+ }
+
+ public void DeselectEmployee(long oid)
+ {
+ foreach(var employeeDependencyObject in Employees)
+ {
+ if(employeeDependencyObject.Employee.EmployeeOid == oid)
+ {
+ employeeDependencyObject.SetValue(ListItemHelper.IsCheckedProperty, false);
+ }
+ }
+ }
+
+ public void DeselectAllEmployees()
+ {
+ foreach(var employeeDependencyObject in Employees)
+ {
+ employeeDependencyObject.SetValue(ListItemHelper.IsCheckedProperty, false);
+ }
+
+ SelectedEmployees.Clear();
+ }
+
+ public void SelectAllEmployees()
+ {
+ foreach(var employeeDependencyObject in Employees)
+ {
+ employeeDependencyObject.SetValue(ListItemHelper.IsCheckedProperty, true);
+ }
+ }
+
+ public void SelectEmployeesAfterReload()
+ {
+ foreach(var employeeDependencyObject in Employees)
+ {
+ var val = SelectedEmployees.Any(employee => employee.EmployeeOid == employeeDependencyObject.Employee.EmployeeOid);
+
+ employeeDependencyObject.SetValue(ListItemHelper.IsCheckedProperty, val);
+ }
+ }
+ }
+}
diff --git a/BeWo/Scheduling/ViewModel/SchedulingAppointmentVM.cs b/BeWo/Scheduling/ViewModel/SchedulingAppointmentVM.cs
new file mode 100644
index 000000000..80f7e7f48
--- /dev/null
+++ b/BeWo/Scheduling/ViewModel/SchedulingAppointmentVM.cs
@@ -0,0 +1,875 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Windows;
+using System.Windows.Media;
+using BeWo.Scheduling.SchedulingUtils;
+using BeWo.ViewModel;
+using BS.Shared;
+using BS.Shared.DataContracts;
+using BS.Shared.DataContracts.Compact;
+using BS.Shared.Extensions;
+using DevExpress.XtraScheduler;
+using DevExpress.Xpf.Scheduling;
+
+namespace BeWo.Scheduling.ViewModel
+{
+ public class SchedulingAppointmentVM : AbstractDCMapperVM
+ {
+ public SchedulingAppointmentVM VMForCustomField => this;
+
+ private bool _AllDay;
+ private string _Description;
+ private DateTime _End;
+ private string _Location;
+ private string _RecurrenceInfo;
+ private DateTime _Start;
+ private int _Status;
+ private string _Subject;
+ private int _Type;
+ private bool _IsPrivate;
+ private ObservableCollection _EmployeeList;
+ private List _CustomerList;
+ private List _ResourceList;
+ private ObservableCollection _SupportConceptList;
+ private CompactEmployeeDC _Originator;
+ private bool _IsTask;
+ private string _TaskDescription;
+ private string _CompletedNotice;
+ private DateTime? _CompletedDate;
+ private DateTime? _DueDate;
+ private DateTime? _DueTime;
+ private bool _HasServiceRecordEntry;
+ private bool _IsArchived;
+
+
+ public bool HasServiceRecordEntry
+ {
+ get => _HasServiceRecordEntry;
+ set
+ {
+ if(AreDifferent(_HasServiceRecordEntry, value))
+ {
+ _HasServiceRecordEntry = value;
+
+ StoreDirtyInformation(AreDifferent(DataContract.HasServiceRecordEntry, value), nameof(HasServiceRecordEntry));
+ FirePropertyChanged(nameof(HasServiceRecordEntry));
+ }
+ }
+ }
+
+ public bool IsArchived
+ {
+ get => _IsArchived;
+
+ set
+ {
+ if(AreDifferent(_IsArchived, value))
+ {
+ _IsArchived = value;
+ StoreDirtyInformation((value && DataContract.ActivationType == ActivationTypeId.Active) || (!value && DataContract.ActivationType == ActivationTypeId.Archived), nameof(IsArchived));
+ FirePropertyChanged(nameof(IsArchived));
+ }
+ }
+ }
+
+ public DateTime? AbsenceTimeStart { get; set; }
+ public DateTime? AbsenceTimeEnd { get; set; }
+
+ public virtual string ReminderInfo { get; set; }
+ public virtual object Id { get; set; }
+ public virtual long? LabelKey { get; set; }
+
+ ///
+ /// Der AppointmentType des Termins als Integer; 0 = Pattern; 1 = Normal; 2 = Occurrence; 3 = ChangedOccurrence; 4 = DeletedOccurrence
+ ///
+ public virtual int EventType
+ {
+ get => _Type;
+ set
+ {
+ if(AreDifferent(_Type, value))
+ {
+ _Type = value;
+ StoreDirtyInformation(AreDifferent(DataContract.Type, value), nameof(Type));
+ FirePropertyChanged(nameof(Type));
+ }
+ }
+ }
+
+ public virtual DateTime End
+ {
+ get => _End;
+ set
+ {
+ if(AreDifferent(_End, value))
+ {
+ _End = value;
+
+ if(IsAbsenceTime)
+ {
+ return;
+ }
+
+ StoreDirtyInformation(AreDifferent(DataContract.EndDate, value), nameof(End));
+ FirePropertyChanged(nameof(End));
+ }
+ }
+ }
+
+ public virtual DateTime Start
+ {
+ get => _Start;
+ set
+ {
+ if(AreDifferent(_Start, value))
+ {
+ _Start = value;
+
+ if(IsAbsenceTime)
+ {
+ return;
+ }
+
+ StoreDirtyInformation(AreDifferent(DataContract.StartDate, value), nameof(Start));
+ FirePropertyChanged(nameof(Start));
+ }
+ }
+ }
+
+ public virtual bool AllDay
+ {
+ get => _AllDay;
+ set
+ {
+ if(AreDifferent(_AllDay, value))
+ {
+ _AllDay = value;
+
+ if(IsAbsenceTime)
+ {
+ return;
+ }
+
+ StoreDirtyInformation(AreDifferent(DataContract.AllDay, value), nameof(AllDay));
+ FirePropertyChanged(nameof(AllDay));
+ }
+ }
+ }
+
+ public virtual string Subject
+ {
+ get => _Subject;
+ set
+ {
+ if(AreDifferent(_Subject, value))
+ {
+ _Subject = value;
+
+ if(IsAbsenceTime)
+ {
+ return;
+ }
+
+ StoreDirtyInformation(AreDifferent(DataContract.Subject, value), nameof(Subject));
+ FirePropertyChanged(nameof(Subject));
+ }
+ }
+ }
+
+ public virtual string Location
+ {
+ get => _Location;
+ set
+ {
+ if(AreDifferent(_Location, value))
+ {
+ _Location = value;
+
+ if(IsAbsenceTime)
+ {
+ return;
+ }
+
+ StoreDirtyInformation(AreDifferent(DataContract.Location, value), nameof(Location));
+ FirePropertyChanged(nameof(Location));
+ }
+ }
+ }
+
+ public virtual int Status
+ {
+ get => _Status;
+ set
+ {
+ if(AreDifferent(_Status, value))
+ {
+ _Status = value;
+
+ if(IsAbsenceTime)
+ {
+ return;
+ }
+
+ StoreDirtyInformation(AreDifferent(DataContract.Status, value), nameof(Status));
+ FirePropertyChanged(nameof(Status));
+ }
+ }
+ }
+
+ public bool IsTeilnahmeBestaetigung { get; }
+
+ public virtual string RecurrenceInfo
+ {
+ get => _RecurrenceInfo;
+ set
+ {
+ if(AreDifferent(_RecurrenceInfo, value))
+ {
+ _RecurrenceInfo = value;
+
+ if(IsAbsenceTime)
+ {
+ return;
+ }
+
+ StoreDirtyInformation(AreDifferent(DataContract.RecurrenceInfo, value), nameof(RecurrenceInfo));
+ FirePropertyChanged(nameof(RecurrenceInfo));
+ }
+ }
+ }
+
+ public virtual string Description
+ {
+ get => _Description;
+ set
+ {
+ if(AreDifferent(_Description, value))
+ {
+ _Description = value;
+
+ if(IsAbsenceTime)
+ {
+ return;
+ }
+
+ StoreDirtyInformation(AreDifferent(DataContract.Description, value), nameof(Description));
+ FirePropertyChanged(nameof(Description));
+ }
+ }
+ }
+
+ public ObservableCollection EmployeeList
+ {
+ get => _EmployeeList ?? (_EmployeeList = new ObservableCollection());
+ set
+ {
+ if(AreDifferent(_EmployeeList, value))
+ {
+ _EmployeeList = value;
+
+ if(IsAbsenceTime)
+ {
+ return;
+ }
+
+ StoreDirtyInformation(AreDifferent(DataContract.EmployeeList, value), nameof(EmployeeList));
+ FirePropertyChanged(nameof(EmployeeList));
+ }
+ }
+ }
+
+ public List CustomerList
+ {
+ get => _CustomerList ?? (_CustomerList = new List());
+ set
+ {
+ if(AreDifferent(_CustomerList, value))
+ {
+ _CustomerList = value;
+
+ if(IsAbsenceTime)
+ {
+ return;
+ }
+
+ StoreDirtyInformation(AreDifferent(DataContract.CustomerList, value), nameof(CustomerList));
+ FirePropertyChanged(nameof(CustomerList));
+ }
+ }
+ }
+
+ public List ResourceList
+ {
+ get => _ResourceList ?? (ResourceList = new List());
+ set
+ {
+ if(AreDifferent(_ResourceList, value))
+ {
+ _ResourceList = value;
+
+ if(IsAbsenceTime)
+ {
+ return;
+ }
+
+ StoreDirtyInformation(AreDifferent(DataContract.ResourceList, value), nameof(ResourceList));
+ FirePropertyChanged(nameof(ResourceList));
+ }
+ }
+ }
+
+ public ObservableCollection SupportConceptList
+ {
+ get => _SupportConceptList ?? (SupportConceptList = new ObservableCollection());
+ set
+ {
+ if(AreDifferent(_SupportConceptList, value))
+ {
+ _SupportConceptList = value;
+
+ if(IsAbsenceTime)
+ {
+ return;
+ }
+
+ StoreDirtyInformation(AreDifferent(DataContract.SupportConceptList, value), nameof(SupportConceptList));
+ FirePropertyChanged(nameof(SupportConceptList));
+ }
+ }
+ }
+
+ public bool IsPrivate
+ {
+ get => _IsPrivate;
+ set
+ {
+ if(AreDifferent(_IsPrivate, value))
+ {
+ _IsPrivate = value;
+
+ if(IsAbsenceTime)
+ {
+ return;
+ }
+
+ StoreDirtyInformation(AreDifferent(DataContract.IsPrivate, value), nameof(IsPrivate));
+ FirePropertyChanged(nameof(IsPrivate));
+ }
+ }
+ }
+
+ public virtual CompactEmployeeDC Originator
+ {
+ get => _Originator;
+ set
+ {
+ if(AreDifferent(_Originator, value))
+ {
+ _Originator = value;
+
+ if(IsAbsenceTime)
+ {
+ return;
+ }
+
+ StoreDirtyInformation(AreDifferent(DataContract.Originator, value), nameof(Originator));
+ FirePropertyChanged(nameof(Originator));
+ }
+ }
+ }
+
+ public virtual TimeSpan EndTime => End.TimeOfDay;
+
+ public virtual TimeSpan StartTime => Start.TimeOfDay;
+
+ public virtual bool IsAbsenceTime { get; }
+
+ public bool IsTask
+ {
+ get => _IsTask;
+
+ set
+ {
+ if(AreDifferent(_IsTask, value))
+ {
+ _IsTask = value;
+
+ if(IsAbsenceTime)
+ {
+ return;
+ }
+
+ StoreDirtyInformation(AreDifferent(DataContract.IsTask, value), nameof(IsTask));
+ FirePropertyChanged(nameof(IsTask));
+ }
+ }
+ }
+
+ public string TaskDescription
+ {
+ get => _TaskDescription;
+
+ set
+ {
+ if(AreDifferent(_TaskDescription, value))
+ {
+ _TaskDescription = value;
+
+ if(IsAbsenceTime)
+ {
+ return;
+ }
+
+ StoreDirtyInformation(AreDifferent(DataContract.TaskDescription, value), nameof(TaskDescription));
+ FirePropertyChanged(nameof(TaskDescription));
+ }
+ }
+ }
+
+ public string CompletedNotice
+ {
+ get => _CompletedNotice;
+
+ set
+ {
+ if(AreDifferent(_CompletedNotice, value))
+ {
+ _CompletedNotice = value;
+
+ if(IsAbsenceTime)
+ {
+ return;
+ }
+
+ StoreDirtyInformation(AreDifferent(DataContract.CompletedNotice, value), nameof(CompletedNotice));
+ FirePropertyChanged(nameof(CompletedNotice));
+ }
+ }
+ }
+
+ public DateTime? CompletedDate
+ {
+ get => _CompletedDate;
+
+ set
+ {
+ if(AreDifferent(_CompletedDate, value))
+ {
+ _CompletedDate = value;
+
+ if(IsAbsenceTime)
+ {
+ return;
+ }
+
+ StoreDirtyInformation(AreDifferent(DataContract.CompletedDate, value), nameof(CompletedDate));
+ FirePropertyChanged(nameof(CompletedDate));
+ }
+ }
+ }
+
+ public DateTime? DueDate
+ {
+ get => _DueDate;
+
+ set
+ {
+ if(AreDifferent(_DueDate, value))
+ {
+ _DueDate = value;
+
+ if(IsAbsenceTime)
+ {
+ return;
+ }
+
+ StoreDirtyInformation(AreDifferent(DataContract.DueDate, value), nameof(DueDate));
+ FirePropertyChanged(nameof(DueDate));
+ }
+ }
+ }
+
+ public DateTime? DueTime
+ {
+ get => _DueTime;
+
+ set
+ {
+ if(AreDifferent(_DueTime, value))
+ {
+ _DueTime = value;
+ StoreDirtyInformation(AreDifferent(DataContract.DueDate, value), nameof(DueTime));
+ FirePropertyChanged(nameof(DueTime));
+ }
+ }
+ }
+
+ public Guid? RecurrenceId => BS.Shared.Core.Utils.GetRecurrenceIdFromRecurrenceInfo(RecurrenceInfo);
+
+ public int RecurrenceIndex => BS.Shared.Core.Utils.GetRecurrenceIndexFromRecurrenceInfo(RecurrenceInfo);
+
+ public bool CanBeEdited { get; set; } = true;
+
+ public AppointmentColorHelper AppointmentColors { get; set; }
+
+ public SolidColorBrush BackgroundColor { get; set; }
+
+ public SolidColorBrush ForegroundColor { get; set; }
+
+ public SolidColorBrush AppointmentBorderBrush
+ {
+ get
+ {
+ if(EmployeeList?.Any(e2a => e2a.Employee.Equals(BeWoApp.CompactLoggedOnEmployee) && e2a.ParticipationAnswer == ParticipationAnswer.Vorbehalt) ?? false)
+ {
+ return new SolidColorBrush(Color.FromRgb(185, 39, 217));
+ }
+
+ return new SolidColorBrush(Colors.Transparent);
+ }
+ }
+
+ public string ToolTip
+ {
+ get
+ {
+ var result = Subject;
+
+ if(IsTask)
+ {
+ result = result ?? "";
+
+ if(CompletedDate.HasValue)
+ {
+ result += $" erledigt am {CompletedDate.Value:dd.MM.yyyy}";
+ }
+ else if(DueDate.HasValue)
+ {
+ result += $" bis {DueDate.Value:dd.MM.yyyy HH:mm}";
+ }
+ }
+
+ if(IsAbsenceTime && AbsenceTimeStart.HasValue)
+ {
+ result += AbsenceTimeStart.Value.GetIntervalDescription(AbsenceTimeEnd);
+ }
+
+ return result;
+ }
+ }
+
+ public Visibility ToolTipTimeVisibility => IsTask || IsAbsenceTime || AllDay ? Visibility.Collapsed : Visibility.Visible;
+
+ public Visibility ToolTipResourcesVisibility => ResourceList?.Count > 0 ? Visibility.Visible : Visibility.Collapsed;
+
+ public Visibility ToolTipEmployeesVisibility => EmployeeList?.Count > 0 ? Visibility.Visible : Visibility.Collapsed;
+
+ public Visibility ToolTipCustomersVisibility => CustomerList?.Count > 0 ? Visibility.Visible : Visibility.Collapsed;
+
+ public Visibility ToolTipTrennstrichVisibility => EmployeeList?.Count > 0 || CustomerList?.Count > 0 || ResourceList?.Count > 0 ? Visibility.Visible : Visibility.Collapsed;
+
+ public Visibility ToolTipZusageVisibility => IsTask ? Visibility.Collapsed : Visibility.Visible;
+
+ public string ResourcesToolTip => GetIFiltereableInfo(ResourceList.Cast().ToList());
+ public string EmployeesToolTip => GetIFiltereableInfo(EmployeeList.Select(s => s.Employee).Cast().ToList());
+ public string CustomersToolTip => GetIFiltereableInfo(CustomerList.Cast().ToList());
+
+ public bool LiesInPast => Start < DateTime.Now && End < DateTime.Now;
+
+ private static string GetIFiltereableInfo(List list)
+ {
+ var tooltip = string.Empty;
+
+ foreach(var item in list)
+ {
+ var index = list.IndexOf(item);
+
+ if(index % 3 == 0 && index < list.Count - 1 && index > 0)
+ {
+ tooltip += "\n";
+ }
+
+ tooltip += item.ToString();
+
+ if(index < list.Count - 1)
+ {
+ tooltip += "; ";
+ }
+ }
+
+ return tooltip;
+ }
+
+ // Für DevExpress
+ public SchedulingAppointmentVM() : base(new SchedulerAppointmentDC(), true)
+ {
+ CanBeEdited = true;
+ }
+
+
+ public SchedulingAppointmentVM(SchedulerAppointmentDC dataContract) : base(dataContract, dataContract.SchedulerAppointmentOid == null)
+ {
+ IsTeilnahmeBestaetigung = dataContract.IsTeilnahmeBestaetigung;
+ CanBeEdited = dataContract.CanBeEdited;
+
+ InitAppointmentColors();
+ }
+
+ // Wird für Abwesenheiten genutzt
+ public SchedulingAppointmentVM(bool pAllDay, string pSubject, DateTime pStart, DateTime pEnd, CompactEmployeeDC pOriginator, DateTime? absenceTimeStart, DateTime? absenceTimeEnd)
+ {
+ _AllDay = pAllDay;
+ _Subject = pSubject;
+ _Start = pStart;
+ _End = pEnd;
+ _Originator = pOriginator;
+
+ AbsenceTimeStart = absenceTimeStart;
+ AbsenceTimeEnd = absenceTimeEnd;
+
+ IsAbsenceTime = true;
+
+ InitAppointmentColors();
+ }
+
+ // Zum Erstellen einer neuen Serienausnahme
+ ///
+ /// Zur Erstellung einer Serienausnahme (ChangedOccurrence) aus einem AppointmentItem.
+ ///
+ /// AppointmentItem aus dem ein SchedulingAppointmentVM mit Typ 'ChangedOccurrence' erzeugt werden soll
+ /// Wiederholungsinfo für das SchedulerControl mit Id und Index
+ public SchedulingAppointmentVM(AppointmentItem appointmentItem, string recurrenceInfoXml) : base(new SchedulerAppointmentDC(), true)
+ {
+ if(appointmentItem.Type == AppointmentType.Normal)
+ {
+ return;
+ }
+
+ _AllDay = appointmentItem.AllDay;
+ _Start = appointmentItem.Start;
+ _End = appointmentItem.End;
+ _Location = appointmentItem.Location;
+ _RecurrenceInfo = recurrenceInfoXml;
+ _Description = appointmentItem.Description;
+ _Subject = appointmentItem.Subject;
+ _Type = 3; // ChangedOccurrence, Occurrence ist nicht in der Datenbank gespeichert
+ _IsPrivate = appointmentItem.CustomFields["IsPrivate"] is bool b && b;
+ _EmployeeList = appointmentItem.CustomFields["EmployeeList"] as ObservableCollection ?? new ObservableCollection();
+ _CustomerList = appointmentItem.CustomFields["CustomerList"] as List ?? new List();
+ _ResourceList = appointmentItem.CustomFields["ResourceList"] as List ?? new List();
+ _Originator = appointmentItem.CustomFields["Originator"] as CompactEmployeeDC ?? BeWoApp.CompactLoggedOnEmployee;
+ }
+
+ ///
+ /// Wird für Strg + V und zur Rechteprüfung bei der Erstellung des Löschen-Buttons des Contextmenüs benutzt.
+ ///
+ /// AppointmentItem aus dem ein SchedulingAppointmentVM erzeugt werden soll
+ public SchedulingAppointmentVM(AppointmentItem appointmentItem) : base(new SchedulerAppointmentDC(), true)
+ {
+ _AllDay = appointmentItem.AllDay;
+ _Start = appointmentItem.Start;
+ _End = appointmentItem.End;
+ _Location = appointmentItem.Location;
+ _RecurrenceInfo = appointmentItem.RecurrenceInfo?.ToString();
+ _Description = appointmentItem.Description;
+ _Subject = appointmentItem.Subject;
+ _Type = (int) appointmentItem.Type;
+ _IsPrivate = appointmentItem.CustomFields["IsPrivate"] is bool b && b;
+
+ var tempEmployeeList = appointmentItem.CustomFields["EmployeeList"] as ObservableCollection ?? new ObservableCollection();
+ var tempCustomerList = appointmentItem.CustomFields["CustomerList"] as List ?? new List();
+ var tempResourceList = appointmentItem.CustomFields["ResourceList"] as List ?? new List();
+ var tempSupportConceptList = appointmentItem.CustomFields["SupportConceptList"] as List ?? new List();
+
+ _EmployeeList = new ObservableCollection();
+ _CustomerList = new List();
+ _ResourceList = new List();
+ _SupportConceptList = new ObservableCollection();
+
+ foreach(var e2a in tempEmployeeList)
+ {
+ _EmployeeList.AddIfNotIn(new Employee2SchedulerAppointmentDC { Employee = e2a.Employee });
+ }
+
+ foreach(var customer in tempCustomerList)
+ {
+ _CustomerList.AddIfNotIn(customer);
+ }
+
+ foreach(var resource in tempResourceList)
+ {
+ _ResourceList.AddIfNotIn(resource);
+ }
+
+ foreach(var supportConcept in tempSupportConceptList)
+ {
+ _SupportConceptList.AddIfNotIn(supportConcept);
+ }
+
+ _Originator = appointmentItem.CustomFields["Originator"] as CompactEmployeeDC ?? BeWoApp.CompactLoggedOnEmployee;
+ }
+
+ protected override void InitByDataContract(SchedulerAppointmentDC pDataContract)
+ {
+ _AllDay = pDataContract.AllDay;
+ _Description = pDataContract.Description;
+ _End = pDataContract.EndDate ?? DateTime.Now;
+ _Location = pDataContract.Location;
+ _RecurrenceInfo = pDataContract.RecurrenceInfo;
+ _Start = pDataContract.StartDate ?? DateTime.Now;
+ _Status = pDataContract.Status;
+ _Subject = pDataContract.Subject;
+ _Type = pDataContract.Type;
+ _IsPrivate = pDataContract.IsPrivate;
+ _Originator = pDataContract.Originator;
+ _CustomerList = pDataContract.CustomerList ?? new List();
+ _EmployeeList = new ObservableCollection(pDataContract.EmployeeList ?? new List());
+ _ResourceList = pDataContract.ResourceList ?? new List();
+ _IsTask = pDataContract.IsTask;
+ _TaskDescription = pDataContract.TaskDescription;
+ _CompletedNotice = pDataContract.CompletedNotice;
+ _CompletedDate = pDataContract.CompletedDate;
+ _SupportConceptList = new ObservableCollection(pDataContract.SupportConceptList ?? new List());
+ _HasServiceRecordEntry = pDataContract.HasServiceRecordEntry;
+
+ _IsArchived = pDataContract.ActivationType == ActivationTypeId.Archived;
+ CanBeEdited = pDataContract.CanBeEdited;
+
+ Id = pDataContract.SchedulerAppointmentOid;
+
+ if(pDataContract.DueDate.HasValue)
+ {
+ _DueDate = pDataContract.DueDate;
+ _DueTime = pDataContract.DueDate;
+ }
+
+ InitAppointmentColors();
+ }
+
+ private void InitAppointmentColors()
+ {
+ var employeeColor = Color.FromRgb(192, 255, 208);
+
+ if(Utils.IsValidColorHexString(Originator?.EmployeeColor))
+ {
+ employeeColor = (Color) ColorConverter.ConvertFromString(Originator.EmployeeColor);
+ }
+
+ if(IsTask)
+ {
+ employeeColor = Color.FromRgb(153, 59, 59);
+ }
+
+ var resourceColors = new List();
+
+ foreach(var resource in ResourceList)
+ {
+ if(Utils.IsValidColorHexString(resource.Color))
+ {
+ resourceColors.AddIfNotIn((Color) ColorConverter.ConvertFromString(resource.Color));
+ }
+ }
+
+ AppointmentColors = new AppointmentColorHelper(employeeColor, resourceColors, CustomerList?.Any() ?? false, IsTask);
+
+ var colorHexValue = IsTask ? Color.FromRgb(153, 59, 59) : Color.FromRgb(192, 255, 208);
+ BackgroundColor = new SolidColorBrush(colorHexValue);
+
+ var foregroundColorHexValue = IsTask ? Color.FromRgb(224, 224, 224) : Color.FromRgb(0, 0, 0);
+ ForegroundColor = new SolidColorBrush(foregroundColorHexValue);
+ }
+
+ protected override SchedulerAppointmentDC MapToDataContract(SchedulerAppointmentDC pDataContract, bool doCommit)
+ {
+ pDataContract.AllDay = _AllDay;
+ pDataContract.Description = _Description;
+ pDataContract.EndDate = _End;
+ pDataContract.Location = _Location;
+ pDataContract.RecurrenceInfo = _RecurrenceInfo;
+ pDataContract.StartDate = _Start;
+ pDataContract.Status = _Status;
+ pDataContract.Subject = _Subject;
+ pDataContract.Type = _Type;
+ pDataContract.IsPrivate = _IsPrivate;
+ pDataContract.Originator = _Originator;
+ pDataContract.CustomerList = _CustomerList;
+ pDataContract.EmployeeList = _EmployeeList.ToList();
+ pDataContract.ResourceList = _ResourceList;
+ pDataContract.IsTask = _IsTask;
+ pDataContract.TaskDescription = _TaskDescription;
+ pDataContract.CompletedNotice = _CompletedNotice;
+ pDataContract.CompletedDate = _CompletedDate;
+ pDataContract.SupportConceptList = _SupportConceptList.ToList();
+ pDataContract.HasServiceRecordEntry = _HasServiceRecordEntry;
+ pDataContract.ActivationType = _IsArchived ? ActivationTypeId.Archived : ActivationTypeId.Active;
+
+ if(_DueDate.HasValue && _DueTime.HasValue)
+ {
+ pDataContract.DueDate = new DateTime(_DueDate.Value.Year, _DueDate.Value.Month, _DueDate.Value.Day, _DueTime.Value.Hour, _DueTime.Value.Minute, 0);
+ }
+ else
+ {
+ pDataContract.DueDate = _DueDate;
+ }
+
+ return pDataContract;
+ }
+
+ public override bool Equals(object pObj)
+ {
+ if(!(pObj is SchedulingAppointmentVM schedulingAppointmentVM))
+ {
+ return false;
+ }
+
+ var customFieldsAreEqual = true;
+
+ var areEqual =
+ Equals(Subject, schedulingAppointmentVM.Subject) &&
+ LabelKey == schedulingAppointmentVM.LabelKey &&
+ AllDay == schedulingAppointmentVM.AllDay &&
+ IsPrivate == schedulingAppointmentVM.IsPrivate &&
+ IsDirty == schedulingAppointmentVM.IsDirty &&
+ IsNew == schedulingAppointmentVM.IsNew &&
+ IsTask == schedulingAppointmentVM.IsTask &&
+ TaskDescription == schedulingAppointmentVM.TaskDescription &&
+ Equals(CompletedDate, schedulingAppointmentVM.CompletedDate) &&
+ Equals(DueDate, schedulingAppointmentVM.DueDate) &&
+ Equals(CompletedNotice, schedulingAppointmentVM.CompletedNotice) &&
+ customFieldsAreEqual &&
+ CustomerList.AreEqual(schedulingAppointmentVM.CustomerList) &&
+ Equals(Description, schedulingAppointmentVM.Description) &&
+ EmployeeList.AreEqual(schedulingAppointmentVM.EmployeeList) &&
+ Equals(End, schedulingAppointmentVM.End) &&
+ Equals(EndTime, schedulingAppointmentVM.EndTime) &&
+ Equals(Location, schedulingAppointmentVM.Location) &&
+ ResourceList.AreEqual(schedulingAppointmentVM.ResourceList) &&
+ Equals(RecurrenceInfo, schedulingAppointmentVM.RecurrenceInfo) &&
+ HasServiceRecordEntry == schedulingAppointmentVM.HasServiceRecordEntry
+ ;
+
+ return areEqual;
+ }
+
+ public override int GetHashCode()
+ {
+ if(DataContract?.SchedulerAppointmentOid.HasValue ?? false)
+ {
+ return GetType().Name.GetHashCode() ^ DataContract.SchedulerAppointmentOid.Value.GetHashCode();
+ }
+
+ return base.GetHashCode();
+ }
+
+ public override bool IsDirty => !IsAbsenceTime && base.IsDirty;
+
+ public new bool IsNew
+ {
+ get => !IsAbsenceTime && base.IsNew;
+
+ set => base.IsNew = value;
+ }
+ }
+}
diff --git a/BeWo/ServiceProxy/Generated.cs b/BeWo/ServiceProxy/Generated.cs
index fec0e225d..57a8acb8f 100644
--- a/BeWo/ServiceProxy/Generated.cs
+++ b/BeWo/ServiceProxy/Generated.cs
@@ -11,6 +11,7 @@
namespace BeWo.ServiceProxy
{
using System.Runtime.Serialization;
+ using System;
[System.Diagnostics.DebuggerStepThroughAttribute()]
@@ -1842,24 +1843,26 @@ namespace BeWo.ServiceProxy
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(BS.Shared.QueryParameterType))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(BS.Shared.Core.DateTimeSpan))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(System.Collections.Generic.List>))]
- [System.ServiceModel.ServiceKnownTypeAttribute(typeof(BS.Shared.ResourceBookingFrequencyType))]
- [System.ServiceModel.ServiceKnownTypeAttribute(typeof(BS.Shared.ParticipationAnswer))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(System.Collections.Generic.List))]
- [System.ServiceModel.ServiceKnownTypeAttribute(typeof(System.Collections.Generic.List))]
- [System.ServiceModel.ServiceKnownTypeAttribute(typeof(BS.Shared.DataContracts.BookingSequenceDC))]
- [System.ServiceModel.ServiceKnownTypeAttribute(typeof(System.Collections.Generic.List))]
- [System.ServiceModel.ServiceKnownTypeAttribute(typeof(BS.Shared.DataContracts.ResourceBookingDC))]
- [System.ServiceModel.ServiceKnownTypeAttribute(typeof(BS.Shared.DataContracts.ResourceDC))]
- [System.ServiceModel.ServiceKnownTypeAttribute(typeof(System.Collections.Generic.List))]
- [System.ServiceModel.ServiceKnownTypeAttribute(typeof(System.Collections.Generic.List))]
- [System.ServiceModel.ServiceKnownTypeAttribute(typeof(BS.Shared.DataContracts.ResourceAppointmentDC))]
+ [System.ServiceModel.ServiceKnownTypeAttribute(typeof(System.Collections.Generic.Dictionary))]
+ [System.ServiceModel.ServiceKnownTypeAttribute(typeof(System.Collections.Generic.Dictionary>))]
+ [System.ServiceModel.ServiceKnownTypeAttribute(typeof(System.Collections.Generic.Dictionary>))]
+ [System.ServiceModel.ServiceKnownTypeAttribute(typeof(System.Collections.Generic.Dictionary>))]
+ [System.ServiceModel.ServiceKnownTypeAttribute(typeof(BS.Shared.ParticipationAnswer))]
+ [System.ServiceModel.ServiceKnownTypeAttribute(typeof(BS.Shared.ResourceBookingFrequencyType))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(System.Collections.Generic.List))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(BS.Shared.DataContracts.SchedulerAppointmentDC))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(System.Collections.Generic.List))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(BS.Shared.DataContracts.Employee2SchedulerAppointmentDC))]
- [System.ServiceModel.ServiceKnownTypeAttribute(typeof(System.Collections.Generic.Dictionary>))]
- [System.ServiceModel.ServiceKnownTypeAttribute(typeof(System.Collections.Generic.Dictionary>))]
- [System.ServiceModel.ServiceKnownTypeAttribute(typeof(System.Collections.Generic.Dictionary>))]
+ [System.ServiceModel.ServiceKnownTypeAttribute(typeof(System.Collections.Generic.List))]
+ [System.ServiceModel.ServiceKnownTypeAttribute(typeof(BS.Shared.DataContracts.ResourceDC))]
+ [System.ServiceModel.ServiceKnownTypeAttribute(typeof(System.Collections.Generic.List))]
+ [System.ServiceModel.ServiceKnownTypeAttribute(typeof(BS.Shared.DataContracts.BookingSequenceDC))]
+ [System.ServiceModel.ServiceKnownTypeAttribute(typeof(System.Collections.Generic.List))]
+ [System.ServiceModel.ServiceKnownTypeAttribute(typeof(BS.Shared.DataContracts.ResourceBookingDC))]
+ [System.ServiceModel.ServiceKnownTypeAttribute(typeof(System.Collections.Generic.List))]
+ [System.ServiceModel.ServiceKnownTypeAttribute(typeof(BS.Shared.DataContracts.ResourceAppointmentDC))]
+ [System.ServiceModel.ServiceKnownTypeAttribute(typeof(System.MarshalByRefObject))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(System.Collections.Generic.List))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(BS.Shared.DataContracts.BargeldtransaktionshistoryDC))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(System.Collections.Generic.List))]
@@ -2012,6 +2015,7 @@ namespace BeWo.ServiceProxy
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(BS.Shared.DataContracts.Reports.AuslastungAnalysisEmployeeDC))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(System.Collections.Generic.List))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(BS.Shared.DataContracts.Reports.AuslastungAnalysisSupportConceptDC))]
+ [System.ServiceModel.ServiceKnownTypeAttribute(typeof(System.IO.Stream))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(System.Collections.Generic.List