Files
BeWoPlaner/BeWo/Scheduling/View/SchedulingView.xaml.cs
Lyndon Jetten e0447d0a05 MoK:
Intervallfinder überarbeitet & Bug gefixt, der zu einem Fehler beim Suchen nach freien Intervallen über mehrere Tage geführt hatte, wenn die Enduhrzeit vor der Startuhrzeit lag.

Berichte mit Parametern.

Verbesserte Mitarbeiter-, Klienten-, Team-, und Organisationsdropdowns mit Suche.

Quittierungsbelegresultate (zum Unterschreiben) wird wie die Zeiterfassung paginiert.

FaC:

neuer Kalender noch nicht fertig.
2024-11-12 18:37:23 +01:00

2080 lines
87 KiB
C#

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 static 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()
{
LoadRelatedTeamOids();
LoadSchedulingViewType();
}
private void LoadRelatedTeamOids()
{
Cache.GetInstance().GetTeamRelatedCustomerOidsForEmployee(BeWoApp.CompactLoggedOnEmployee.EmployeeOid, false, teamMemberCustomerOids =>
{
this.Dispatch(() =>
{
ViewModel.TeamRelatedCustomerOids = teamMemberCustomerOids;
});
});
}
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<CompactCustomerDC>(customers);
ViewModel.FilteredCustomers = new ObservableSortCollection<CompactCustomerDC>(customers);
ViewModel.AllEmployees = new ObservableSortCollection<CompactEmployeeDC>(employees);
ViewModel.Employees = new ObservableSortCollection<EmployeeDependencyObject>();
ViewModel.FilteredEmployees = new ObservableSortCollection<EmployeeDependencyObject>();
foreach(var employee in employees)
{
var employeeDependencyObject = new EmployeeDependencyObject(employee);
ViewModel.Employees.AddIfNotIn(employeeDependencyObject);
ViewModel.FilteredEmployees.AddIfNotIn(employeeDependencyObject);
}
ViewModel.SelectEmployeesAfterReload();
var cats2Res = new ObservableDictionary<CategoryDependencyObject, List<ResourceDependencyObject>>();
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<CompactCustomerDC>, List<CompactEmployeeDC>, Dictionary<ValueListEntryDC, List<ResourceDC>>> 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 = 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<SchedulerAppointmentDC> _OpenAppointments = new List<SchedulerAppointmentDC>();
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<long>();
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<SchedulerAppointmentDC>();
var dates = new List<DateTime>();
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<string, object>
{
{"appointmentOidListe", appointmentOids},
{"datesList", dates},
{"employeeOid", BeWoApp.LoggedOnEmployee.EmployeeOid},
{"serienTermine", withoutOid},
{"mehrtaegigeTermine", createdAppointments}
};
BeWoUtils.ShowReport("Kalender", variables, ReportEnum.KalenderMonatsReportEnum);
}
public static List<SchedulerAppointmentDC> BreakDownMultipleDaysAppointments(List<SchedulerAppointmentDC> appointments)
{
var result = new List<SchedulerAppointmentDC>();
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))
{
return;
}
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))
{
return;
}
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))
{
return;
}
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))
{
return;
}
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))
{
return;
}
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 is null)
{
return;
}
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))
{
return;
}
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 != 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<Employee2SchedulerAppointmentDC>();
foreach(var employee in ViewModel.SelectedEmployees)
{
viewModel.EmployeeList.Add(new Employee2SchedulerAppointmentDC { Employee = employee });
}
}
_IsComingFromHomeDragPanel = false;
var teamsRelatedCustomerOids = new List<long>();
ServiceFacade.DoEmployeeServiceAsync(s => teamsRelatedCustomerOids = s.LoadTeamsRelatedCustomerOids(BeWoApp.CompactLoggedOnEmployee.EmployeeOid));
_AppointmentWindowVM = new AppointmentWindowVM(appointmentItem, (SchedulerControl) sender, ViewModel.AllEmployees, ViewModel.AllCustomers, ViewModel.Categories2Resources, viewModel.Originator ?? BeWoApp.CompactLoggedOnEmployee, teamsRelatedCustomerOids, 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.CompactLoggedOnEmployee.EmployeeOid;
var date = DeleteForGoodIntervalEndDateEdit.DateTime;
var userRights = new Dictionary<UserRightType, bool>
{
{
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.Where(resource => resource.ResourceOid.HasValue).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.Where(resource => resource.ResourceOid.HasValue).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)
{
if(e.Appointment is null)
{
return;
}
CanAppointmentBeEdited(e.Appointment, allow =>
{
e.Allow = allow;
});
}
private void SchedulerControl_CustomAllowAppointmentEdit(object sender, AppointmentItemOperationEventArgs e)
{
if(e.Appointment is null)
{
return;
}
CanAppointmentBeEdited(e.Appointment, allow =>
{
e.Allow = allow;
});
}
private void CanAppointmentBeEdited(AppointmentItem appointment, Action<bool> callback)
{
if(appointment is null)
{
callback?.Invoke(false);
return;
}
var viewModel = appointment.CustomFields["VMForCustomField"] as SchedulingAppointmentVM;
var customers = viewModel?.CustomerList ?? new List<CompactCustomerDC>();
var employees = viewModel?.EmployeeList ?? new ObservableCollection<Employee2SchedulerAppointmentDC>();
var resources = viewModel?.ResourceList;
var originator = viewModel?.Originator;
var canBeEdited = viewModel?.CanBeEdited ?? false;
if(canBeEdited is false)
{
callback?.Invoke(false);
return;
}
Cache.GetInstance().GetTeamRelatedCustomerOidsForEmployee(BeWoApp.CompactLoggedOnEmployee.EmployeeOid, false, teamMemberCustomerOids =>
{
this.Dispatch(() =>
{
var result = BS.Shared.Core.Utils.CheckSchedulerRights(customers, resources, employees.ToList(), originator, true, SchedulerRightsCheckType.Create, BeWoApp.LoggedOnUser, teamMemberCustomerOids);
callback?.Invoke(result);
});
});
}
private void SchedulerControl_CustomAllowAppointmentDrag(object sender, AppointmentItemOperationEventArgs e)
{
if(e.Appointment is null)
{
return;
}
CanAppointmentBeEdited(e.Appointment, allow =>
{
e.Allow = allow;
});
}
private void SchedulerControl_CustomAllowAppointmentResize(object sender, AppointmentItemOperationEventArgs e)
{
if(e.Appointment is null)
{
return;
}
CanAppointmentBeEdited(e.Appointment, allow =>
{
e.Allow = allow;
});
}
private void SchedulerControl_CustomAllowAppointmentDragBetweenResources(object sender, AppointmentItemOperationEventArgs e)
{
if(e.Appointment is null)
{
return;
}
CanAppointmentBeEdited(e.Appointment, allow =>
{
e.Allow = allow;
});
}
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)
{
continue;
}
var content = menuItem.Content.ToString();
if(!content.Equals("Ansichtwechsel"))
{
continue;
}
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<AppointmentItem> 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<AppointmentItem> selectedAppointments)
{
var hasRightToDelete = false;
var dataContracts = new List<SchedulerAppointmentDC>();
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)
{
return;
}
var selectedAppointment = selectedAppointments.FirstOrDefault();
if(selectedAppointment is null || selectedAppointment.Type != AppointmentType.ChangedOccurrence || !(selectedAppointment.CustomFields["VMForCustomField"] is SchedulingAppointmentVM vm) || vm.EventType != (int) AppointmentType.ChangedOccurrence)
{
return;
}
var pattern = SchedulerControl.GetPattern(selectedAppointment);
if(!(pattern.CustomFields["VMForCustomField"] is SchedulingAppointmentVM patternVM))
{
return;
}
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.Where(resource => resource.ResourceOid.HasValue).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) || !(e.Appointment.CustomFields["VMForCustomField"] is SchedulingAppointmentVM vm))
{
return;
}
if(recurrenceEditView.IsCancelled)
{
vm.RecurrenceInfo = _AppointmentWindowVM.OriginalRecurrenceInfo;
_AppointmentEditView?.SetRecurrenceInfo(vm.RecurrenceInfo);
}
else
{
if(!(recurrenceEditView.DataContext is RecurrenceWindowViewModel viewModel))
{
return;
}
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<SchedulerAppointmentDC>();
draggedAppointments.DoForEach(app =>
{
if(!(app.CustomFields["VMForCustomField"] is SchedulingAppointmentVM viewModel))
{
return;
}
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)
{
return;
}
if(vm.IsAbsenceTime)
{
e.Cancel = true;
return;
}
if(sourceAppointment.Type == AppointmentType.Occurrence && resizeAppointment.Type == AppointmentType.ChangedOccurrence)
{
vm = CreateChangedOccurrence(resizeAppointment);
}
vm.End = resizeAppointment.End;
InsertOrUpdateAppointments(new List<SchedulerAppointmentDC> { 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<Employee2SchedulerAppointmentDC> ?? new ObservableCollection<Employee2SchedulerAppointmentDC>();
var customerList = vm.CustomerList;// appointment.CustomFields["CustomerList"] as List<CompactCustomerDC>;
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<SchedulerAppointmentDC> { vm.CommitToDataContract() }, BeWoApp.LoggedOnUser),
appointments2Insert =>
{
// Ist maximal ein Termin
var app = appointments2Insert.FirstOrDefault();
if(!(app is null))
{
ServiceFacade.DoResourceServiceAsync(s2 => s2.InsertSchedulerAppointments(new List<SchedulerAppointmentDC> { 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<SchedulerAppointmentDC> { 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<long, long> { { appointmentOid, appointmentVersion } }), () =>
{
this.Dispatch(() =>
{
ReloadViewModel(true);
});
});
}
});
}
private void InsertOrUpdateAppointments(List<SchedulerAppointmentDC> 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<SchedulerAppointmentDC> 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<AppointmentItem> appointmentItems)
{
if(appointmentItems is null)
{
return;
}
var applyForAllOccurrences = false;
bool? createChangedOccurrencesOrAbort = false;
var dataContracts = new List<SchedulerAppointmentDC>();
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, $"<RecurrenceInfo Id=\"{appointment.RecurrenceInfoId}\" Index=\"{appointment.RecurrenceIndex}\" />");
}
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<SchedulerAppointmentDC>();
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<SchedulerAppointmentDC>();
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<SchedulerAppointmentDC>();
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, $"<RecurrenceInfo Id=\"{appointmentItem.RecurrenceInfoId}\" Index=\"{appointmentItem.RecurrenceIndex}\" />");
}
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;
}
}
}