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.
2080 lines
87 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|