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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + \ No newline at end of file diff --git a/BeWo/View/Detail/Accounting/InvoiceOverview.xaml.cs b/BeWo/View/Detail/Accounting/InvoiceOverview.xaml.cs index 23a57c080..3c1bce601 100644 --- a/BeWo/View/Detail/Accounting/InvoiceOverview.xaml.cs +++ b/BeWo/View/Detail/Accounting/InvoiceOverview.xaml.cs @@ -17,7 +17,7 @@ using BS.Shared; using BS.Shared.Core; using BS.Shared.DataContracts; using BS.Shared.Extensions; - +using BS.Shared.Translation; using DevExpress.Xpf.Editors; using DevExpress.Xpf.Grid; using Microsoft.Win32; @@ -46,6 +46,7 @@ namespace BeWo.View.Detail.Accounting this.ViewModel = vm; this.DownloadLinkEngine = new DownloadLinkEngine(); this.linkExcelExport.NavigateUri = this.DownloadLinkEngine.GenerateNewExcelLink(); + this.linkPdfExport.NavigateUri = new Uri("http://www.ownsoft.de"); this.gridView.ShownEditor += this.gridView_ShownEditor; //this.gridView.HiddenEditor += new EditorEventHandler(gridView_HiddenEditor); @@ -156,16 +157,6 @@ namespace BeWo.View.Detail.Accounting }); } - private void SaveIsPaidChange(InvoiceBaseVM vm, bool isPaid) - { - if (!mIgnoreCheckChanges) - { - vm.IsPaid = isPaid; - - ServiceFacade.DoAccountingServiceAsync(s => s.SetInvoicePaid(new[] { vm.CommitToDataContract() }.ToList(), vm.IsPaid), cb => vm.DataContract.InvoiceBaseVersion = cb[0], false); - } - } - private void YearMonthFilter_FilterSpanChanged(object sender, EventArgs e) { mIgnoreCheckChanges = true; @@ -176,8 +167,13 @@ namespace BeWo.View.Detail.Accounting private void btn_delete_Click(object sender, RoutedEventArgs e) { - mIgnoreCheckChanges = true; var vm = this.datagrid_invoices.GetCurrentValue(); + if (vm.IsSent && !BeWoApp.LoggedOnUser.HasRight(UserRightType.FinanzenRechnungenNachVersandBearbeiten)) + { + MessageBox.Show(Translator.Translate("Sie besitzen nicht das Recht Rechnungen nach Versand zu bearbeiten. Bitte wenden Sie sich an den Administrator!"), "BeWoPlaner", MessageBoxButton.OK, MessageBoxImage.Exclamation); + return; + } + mIgnoreCheckChanges = true; if (MessageBox.Show("Sind Sie sicher, dass Sie die gewählte Rechnung löschen möchten?", "Rechnung löschen", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes) { @@ -216,7 +212,11 @@ namespace BeWo.View.Detail.Accounting private void btn_edit_Click(object sender, RoutedEventArgs e) { var vm = this.datagrid_invoices.GetCurrentValue(); - + if (vm.IsSent && !BeWoApp.LoggedOnUser.HasRight(UserRightType.FinanzenRechnungenNachVersandBearbeiten)) + { + MessageBox.Show(Translator.Translate("Sie besitzen nicht das Recht Rechnungen nach Versand zu bearbeiten. Bitte wenden Sie sich an den Administrator!"), "BeWoPlaner", MessageBoxButton.OK, MessageBoxImage.Exclamation); + return; + } switch (vm.DataContract.Type) { case InvoiceType.CustomerEquity: @@ -261,7 +261,6 @@ namespace BeWo.View.Detail.Accounting } } - private void gridView_Loaded(object sender, RoutedEventArgs e) { this.gridView.BestFitColumns(); @@ -292,11 +291,9 @@ namespace BeWo.View.Detail.Accounting // //} //} - private void linkExcelExport_RequestNavigate(object sender, RequestNavigateEventArgs e) { var list = ViewModel.VMList; - var lHeaderCaptions = new List(); var lContent = new List>(); @@ -308,16 +305,22 @@ namespace BeWo.View.Detail.Accounting lHeaderCaptions.Add(BS.Shared.Translation.Translator.Translate("EmpfängerSingular")); lHeaderCaptions.Add("Betrag"); lHeaderCaptions.Add("Bemerkung"); + lHeaderCaptions.Add("Geprüft"); + lHeaderCaptions.Add("Versendet"); + lHeaderCaptions.Add("Exportiert"); lHeaderCaptions.Add("Bezahlt"); + lHeaderCaptions.Add("Teilzahlung"); if (list != null) { lContent.AddRange(list.Select(vm => new List { - vm.TypeString, vm.CustomerName, vm.AccountingPeriodString, vm.InvoiceNumber, vm.InvoiceDate.Value.ToShortDateString(), vm.RecipientString, string.Format("{0:0.00}", vm.TotalAmount), vm.Notice, vm.IsPaid ? "Ja" : "" + vm.TypeString, vm.CustomerName, vm.AccountingPeriodString, vm.InvoiceNumber, vm.InvoiceDate.Value.ToShortDateString(), + vm.RecipientString, string.Format("{0:0.00}", vm.TotalAmount), vm.Notice, vm.IsReviewed ? "Ja" : "", vm.IsSent ? "Ja" : "", + vm.IsExported ? "Ja" : "", vm.IsPaid ? "Ja" : "", vm.PartialPayment })); } - var path = BeWoApp.GetAndCreateUserAppDataPath() + "\\Rechnungen.xls"; + var path = BeWoApp.GetAndCreateUserAppDataPath() + "\\Rechnungen.xls"; var sf = new SaveFileDialog { FileName = Path.GetFileName(path), Filter = "Microsoft Excel 97-2003-Arbeitsblatt|*.xls|Alle Dateien|*.*" }; if (sf.ShowDialog() != true) @@ -325,9 +328,23 @@ namespace BeWo.View.Detail.Accounting ServiceFacade.DoDownloadServiceSync(s => BeWoUtils.WriteExcelFile(s.PrepareExcelFile(DownloadLinkEngine.ExcelFileId, lHeaderCaptions, lContent), sf.FileName)); } + private void linkPdfExport_RequestNavigate(object sender, RequestNavigateEventArgs e) + { + var list = ViewModel.VMList; + var oids = list.Select(r => r.DataContract.InvoiceBaseOid.Value).ToList(); + + ServiceFacade.DoReportServiceAsync(s => s.CreateInvoiceOverviewReport(oids), r => + { + this.Dispatch(() => + { + BeWoUtils.ShowReportWindow(r, Translator.Translate("Rechnungen")); + }); + }); + } + private void Hyperlink_OnRequestNavigate(object sender, RequestNavigateEventArgs e) { - BeWoUtils.NavigateToReportUri(((Hyperlink)sender).NavigateUri.ToString(), "Druckvorschau"); + BeWoUtils.NavigateToReportUri(((Hyperlink)sender).NavigateUri.ToString(), "Druckvorschau"); } private void ReloadButton_OnClick(object sender, RoutedEventArgs e) @@ -346,11 +363,61 @@ namespace BeWo.View.Detail.Accounting private void gridView_CellValueChanged(object sender, CellValueChangedEventArgs e) { - if (e.Column != null && e.Column.FieldName == "IsPaid") + var vm = e.Row as InvoiceBaseVM; + + if (vm != null) { - if (e.Value is bool b && e.Row is InvoiceBaseVM vm) + if (e.Column != null && e.Column.FieldName == "PartialPayment") { - SaveIsPaidChange(vm, b); + var dc = vm.CommitToDataContract(); + dc.PartialPayment = (String)e.Value; + ServiceFacade.DoAccountingServiceAsync(s => s.UpdateInvoiceBases(new[] { dc }.ToList()), cb => vm.DataContract.InvoiceBaseVersion = cb[0], false); + } + } + } + + private void gridView_CellValueChanging(object sender, CellValueChangedEventArgs e) + { + var vm = e.Row as InvoiceBaseVM; + + if (vm != null) + { + bool save = false; + var dc = vm.CommitToDataContract(); + + if (e.Column != null && e.Column.FieldName == "IsPaid") + { + dc.IsPaid = (bool)e.Value; + save = true; + } + + if (e.Column != null && e.Column.FieldName == "IsReviewed") + { + dc.IsReviewed = (bool)e.Value; + save = true; + } + + if (e.Column != null && e.Column.FieldName == "IsSent") + { + if (vm.IsSent && (bool)e.Value == false && !BeWoApp.LoggedOnUser.HasRight(UserRightType.FinanzenRechnungenNachVersandBearbeiten)) + { + MessageBox.Show(Translator.Translate("Sie besitzen nicht das Recht Rechnungen nach Versand zu bearbeiten. Bitte wenden Sie sich an den Administrator!"), "BeWoPlaner", MessageBoxButton.OK, MessageBoxImage.Exclamation); + RefreshInvoiceList(); + return; + } + dc.IsSent = (bool)e.Value; + save = true; + } + + if (e.Column != null && e.Column.FieldName == "IsExported") + { + dc.IsExported = (bool)e.Value; + save = true; + } + + if (save) + { + ServiceFacade.DoAccountingServiceAsync(s => s.UpdateInvoiceBases(new[] { dc }.ToList()), cb => vm.DataContract.InvoiceBaseVersion = cb[0], false); } } } @@ -409,6 +476,123 @@ namespace BeWo.View.Detail.Accounting PrintInvoices(list); } + private void button_reviewInvoices_Click(object sender, RoutedEventArgs e) + { + var list = new List(); + var items = datagrid_invoices.ItemsSource as IList; + if (items != null) + { + for (int i = 0; i < items.Count; i++) + { + var vm = datagrid_invoices.GetRow(i) as InvoiceBaseVM; + if (vm != null && vm.IsChecked) + { + list.Add(vm); + } + } + } + + ChangeAllInvoices(list, "reviewed"); + } + + private void button_sentInvoices_Click(object sender, RoutedEventArgs e) + { + var list = new List(); + var items = datagrid_invoices.ItemsSource as IList; + if (items != null) + { + for (int i = 0; i < items.Count; i++) + { + var vm = datagrid_invoices.GetRow(i) as InvoiceBaseVM; + if (vm != null && vm.IsChecked) + { + list.Add(vm); + } + } + } + ChangeAllInvoices(list, "sent"); + } + + private void button_exportedInvoices_Click(object sender, RoutedEventArgs e) + { + var list = new List(); + var items = datagrid_invoices.ItemsSource as IList; + if (items != null) + { + for (int i = 0; i < items.Count; i++) + { + var vm = datagrid_invoices.GetRow(i) as InvoiceBaseVM; + if (vm != null && vm.IsChecked) + { + list.Add(vm); + } + } + } + ChangeAllInvoices(list, "export"); + } + + private void button_paidInvoices_Click(object sender, RoutedEventArgs e) + { + var list = new List(); + var items = datagrid_invoices.ItemsSource as IList; + if (items != null) + { + for (int i = 0; i < items.Count; i++) + { + var vm = datagrid_invoices.GetRow(i) as InvoiceBaseVM; + if (vm != null && vm.IsChecked) + { + list.Add(vm); + } + } + } + ChangeAllInvoices(list, "paid"); + } + + private void ChangeAllInvoices(List list, String function) + { + var dcList = new List(); + foreach (var item in list) + { + if (function == "reviewed" && !item.IsReviewed) + { + item.IsReviewed = true; + var dc = item.CommitToDataContract(); + dc.IsReviewed = true; + dcList.Add(dc); + } + else if (function == "sent" && !item.IsSent) + { + item.IsSent = true; + var dc = item.CommitToDataContract(); + dc.IsSent = true; + dcList.Add(dc); + } + else if (function == "export" && !item.IsExported) + { + item.IsExported = true; + var dc = item.CommitToDataContract(); + dc.IsExported = true; + dcList.Add(dc); + } + else if (function == "paid" && !item.IsPaid) + { + item.IsPaid = true; + var dc = item.CommitToDataContract(); + dc.IsPaid = true; + dcList.Add(dc); + } + } + if (dcList.Count > 0) + { + ServiceFacade.DoAccountingServiceSync(s => s.UpdateInvoiceBases(dcList)); + foreach (var item in dcList) + { + item.InvoiceBaseVersion++; + } + } + } + private void PrintInvoices(List list) { var oidList = list.Select(i => i.DataContract.InvoiceBaseOid.Value).ToList(); @@ -441,5 +625,4 @@ namespace BeWo.View.Detail.Accounting return list; } } - } \ No newline at end of file diff --git a/BeWo/View/Detail/Accounting/ServiceInvoiceView.xaml.cs b/BeWo/View/Detail/Accounting/ServiceInvoiceView.xaml.cs index fe4e06cda..bfd3faf76 100644 --- a/BeWo/View/Detail/Accounting/ServiceInvoiceView.xaml.cs +++ b/BeWo/View/Detail/Accounting/ServiceInvoiceView.xaml.cs @@ -18,6 +18,7 @@ using BS.Shared.Core; using BS.Shared.DataContracts; using BS.Shared.DataContracts.Compact; using BS.Shared.Extensions; +using BS.Shared.Translation; namespace BeWo.View.Detail.Accounting { @@ -210,13 +211,17 @@ namespace BeWo.View.Detail.Accounting private void btnDelete_Click(object sender, RoutedEventArgs e) { + var vm = BeWoWpfUtils.GetTag(sender); + if (vm.InvoiceBase.IsSent && !BeWoApp.LoggedOnUser.HasRight(UserRightType.FinanzenRechnungenNachVersandBearbeiten)) + { + MessageBox.Show(Translator.Translate("Sie besitzen nicht das Recht Rechnungen nach Versand zu bearbeiten. Bitte wenden Sie sich an den Administrator!"), "BeWoPlaner", MessageBoxButton.OK, MessageBoxImage.Exclamation); + return; + } if (MessageBox.Show("Sind Sie sicher, dass Sie den gewählten Eintrag löschen möchten?", "Spitzabrechnung löschen", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes) { - var vm = BeWoWpfUtils.GetTag(sender); - ServiceFacade.DoAccountingServiceAsync(s => s.DeactivateServiceInvoices(new[] { vm.DataContract @@ -227,7 +232,13 @@ namespace BeWo.View.Detail.Accounting private void btnEdit_Click(object sender, RoutedEventArgs e) { - this._EditView.ViewModel = BeWoWpfUtils.GetTag(sender); + var vm = BeWoWpfUtils.GetTag(sender); + if (vm.InvoiceBase.IsSent && !BeWoApp.LoggedOnUser.HasRight(UserRightType.FinanzenRechnungenNachVersandBearbeiten)) + { + MessageBox.Show(Translator.Translate("Sie besitzen nicht das Recht Rechnungen nach Versand zu bearbeiten. Bitte wenden Sie sich an den Administrator!"), "BeWoPlaner", MessageBoxButton.OK, MessageBoxImage.Exclamation); + return; + } + this._EditView.ViewModel = vm; this.MainControl.ShowControlAsModalPopup(this._EditView); } diff --git a/BeWo/View/Detail/Accounting/SettlementInvoiceItemEditView2.xaml b/BeWo/View/Detail/Accounting/SettlementInvoiceItemEditView2.xaml index 7a6054caa..c8e922559 100644 --- a/BeWo/View/Detail/Accounting/SettlementInvoiceItemEditView2.xaml +++ b/BeWo/View/Detail/Accounting/SettlementInvoiceItemEditView2.xaml @@ -185,7 +185,7 @@ - + + - + - - + + - - + + - + - - + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + +
+
+
+
+ @foreach(var selectedCb2ScRelation in Model.GroupBookingSelectionObject.SelectedRelations) + { +
+
+
+ + @selectedCb2ScRelation.Text1 +
+ + @selectedCb2ScRelation.Text2 + +
+
+
+ +
+
+
+ } +
+
+
+
+ + +
+
+
+ +
+
+
+ + + @if((Model.GroupBookingSelectedSupportConcepts?.Any() ?? false) && Model.GroupBookingSelectedSupportConcepts.Any(sc => sc.Goals.Any())) + { +
+
+ +
+
+
+
+
+
+
+ } + + + + + + + @* Kategorie und Leistungen *@ +
+ @Html.Partial("Category2ServiceDescriptionPartial", Model) +
+ + + + @if(Model.ShowMarker) + { + var markerCheckedValue = Model.SelectedServiceRecord?.ServiceRecordType == ServiceRecordTypeId.Content ? "checked" : string.Empty; + +
+
+
+ + +
+
+
+ } + +
+
+
+
+
+ + +
+
+
+
+
+
+ Startdatum +
+
+ +
+
+ +
+
+
+
+
+ + @if(Model.IsEndDateVisible) + { +
+
+
+
+
+ Enddatum +
+
+ +
+
+ +
+
+
+
+
+ } +
+ +
+ @{ + var startTimeValue = Model.StartTimeToEdit; + var endTimeValue = Model.EndTimeToEdit; + var divisor = Model.SelectedDurationUnit == "Stunden" ? 60 : 1; + var durationValue = string.Empty; + + if(!(Model.SelectedServiceRecord is null)) + { + durationValue = (Model.SelectedServiceRecord?.RoundedDuration / divisor).ToString(); + } + + var afterValidationState = TempData[TempDataConstants.AfterValidationStateKey]; + + if(Model.SetStartTimeToEndTimeAfterSave && !Model.IsInEditingMode && afterValidationState is bool isAfterValidation && isAfterValidation == false) + { + startTimeValue = Model.NewStartTime; + endTimeValue = Model.NewEndTime; + if(Model.NewDuration.HasValue) + { + durationValue = (Model.NewDuration / divisor).ToString(); + } + } + } + +
+
+
+
+
+ Von +
+
+ +
+
+ +
+
+
+
+
+ + +
+
+
+
+
+ Bis +
+
+ +
+
+ +
+
+
+
+
+
+ + +
+
+
+
+
+ @{ + var labelText = Model.EinheitZeiterfassung == 1 ? "Dauer (h)" : "Dauer"; + } +
+ @labelText +
+
+ + @if(Model.IsZeiterfassungInStdMin) + { +
+ + +
+ } +
+
+
+
+ + @if(Model.ShowDistanceField) + { + +
+
+
+
+
+
Gefahrene Kilometer
+
+ +
+
+
+
+ } + + @if(AbstractModel.HasRightToSeeTextModules) + { + +
+
+ +
+
+ } + + +
+
+ @if(Model.NumberOfDokuTypes == 0) + { +
+ + +
+ } + else + { + +
+ @for(var i = 0; i < Model.Dokutypes.Length; i++) + { + var textareaName = i + 1 < 1 ? "Dokumentation" : "Dokumentation" + (i + 1); + +
+ +
+ } +
+ } +
+
+ + } +
+
+ +
+
+ @if(TempData[TempDataConstants.IsInTransferModeKey] is bool isInTransferMode && isInTransferMode) + { + using(Html.BeginForm("ResetTransferMode", "Main", FormMethod.Post)) + { + + } + } + else + { + using(Html.BeginForm("ResetEditingMode", "Main", FormMethod.Post)) + { + + } + } + +
+
+ +
+
+} \ No newline at end of file diff --git a/BeWoPlanerMobil/Views/Main/GroupBookingPartial.cshtml b/BeWoPlanerMobil/Views/Main/GroupBookingPartial.cshtml index de5d1a2e9..0f9b957f1 100644 --- a/BeWoPlanerMobil/Views/Main/GroupBookingPartial.cshtml +++ b/BeWoPlanerMobil/Views/Main/GroupBookingPartial.cshtml @@ -1,7 +1,4 @@ -@using BeWoPlanerMobil.Models -@using BeWoPlanerMobil.Util -@using BS.Shared -@model BeWoPlanerMobil.Models.MainModel +@model BeWoPlanerMobil.Models.MainModel + +
+
    + @foreach(var cb2Sc in Model.SupportConceptListObjectsForGroupBooking) + { +
  • + @{ + var timeSpanColorClass2 = cb2Sc.IsAboutToExpire ? "text-bewo-is-about-to-expire" : cb2Sc.ExpiresInThreeMonthsOrLess ? "text-bewo-expires-in-three-months" : "text-dark"; + + var wasSuccessful = long.TryParse(cb2Sc.CostBearer2SupportConceptOid, out var cb2ScOid); + + var checkedValue = wasSuccessful ? Model.SelectedConceptCostBearerRelations.Any(a => a.CostBearer2SupportConceptOid.Equals(cb2ScOid)) : wasSuccessful; + } + +
    + + +
    +
  • + } +
+
+
+
    + @foreach(var group in Model.GroupOfPeopleListItems) + { +
  • + @{ + var wasSuccessful = long.TryParse(group.Value, out var groupOid); + + var shouldBeChecked = wasSuccessful ? Model.GroupBookingSelectedGroupOfPeopleOids.Contains(groupOid) : wasSuccessful; + + var attribute = shouldBeChecked ? "checked=\"checked\"" : string.Empty; + } +
    + + +
    +
  • + } +
+
\ No newline at end of file diff --git a/BeWoPlanerMobil/Views/Main/Main.cshtml b/BeWoPlanerMobil/Views/Main/Main.cshtml index 9cedab8d7..83f58bad1 100644 --- a/BeWoPlanerMobil/Views/Main/Main.cshtml +++ b/BeWoPlanerMobil/Views/Main/Main.cshtml @@ -16,11 +16,11 @@ } + + @@ -90,336 +92,6 @@ new Script { ExtensionType = ExtensionType.WebDocumentViewer } ) - -