Files
BeWoPlaner/BeWo/Scheduler/View/RequestAnswerView.xaml.cs

675 lines
25 KiB
C#

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using BeWo.Annotations;
using BeWo.Core.Service;
using BeWo.Scheduler.ViewModel;
using BeWo.ServiceProxy;
using BS.Shared;
using BS.Shared.DataContracts;
using BS.Shared.Extensions;
using DevExpress.Xpf.Editors;
using DevExpress.XtraScheduler;
namespace BeWo.Scheduler.View
{
public partial class RequestAnswerView : INotifyPropertyChanged
{
private bool raiseChangeEvent = true;
public static readonly RoutedEvent ParticipationChangedEvent = EventManager.RegisterRoutedEvent(nameof(ParticipationChanged), RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(RequestAnswerView));
public event RoutedEventHandler ParticipationChanged
{
add => AddHandler(ParticipationChangedEvent, value);
remove => RemoveHandler(ParticipationChangedEvent, value);
}
private void RaiseParticipationChangedEventEvent()
{
var newEventArgs = new RoutedEventArgs(ParticipationChangedEvent);
RaiseEvent(newEventArgs);
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public ObservableCollection<IBeWoAppointment> OffeneTermine { get; set; }
private IBeWoAppointment _SelektierterTermin;
public IBeWoAppointment SelektierterTermin
{
get => _SelektierterTermin;
set
{
_SelektierterTermin = value;
OnPropertyChanged(nameof(SelektierterTermin));
}
}
public RequestAnswerView(IEnumerable<IBeWoAppointment> appointments, IEnumerable<IBeWoAppointment> statusUpdates)
{
InitViewModel(appointments, statusUpdates);
DataContext = this;
InitializeComponent();
}
private void InitViewModel(IEnumerable<IBeWoAppointment> appointments, IEnumerable<IBeWoAppointment> statusUpdates)
{
var statusUpdatesAsAppointments = new List<IBeWoAppointment>();
foreach(var beWoAppointment in statusUpdates)
{
var item = (SchedulerAppointmentVM) beWoAppointment;
foreach(var relation in item.EmployeeList.Where(emp => emp.IsPChanged && emp.ParticipationAnswer != ParticipationAnswer.Offen && emp.ParticipationAnswer != ParticipationAnswer.Verstrichen && !emp.Employee.EmployeeOid.Equals(BeWoApp.LoggedOnEmployee.EmployeeOid)))
{
if(statusUpdatesAsAppointments.Any(a => a.LabelKey == relation.Employee2SchedulerAppointmentOid))
{
continue;
}
if(relation.Employee2SchedulerAppointmentOid != null)
{
statusUpdatesAsAppointments.Add(BuildNewVMFromOldVM(item, relation.Employee2SchedulerAppointmentOid.Value));
}
}
}
OffeneTermine = appointments.ToObservableCollection();
OffeneTermine.AddRange(new List<IBeWoAppointment>(statusUpdatesAsAppointments));
OnPropertyChanged(nameof(OffeneTermine));
}
private static SchedulerAppointmentVM BuildNewVMFromOldVM(SchedulerAppointmentVM item, long emp2AppOid)
{
var customFieldStorage = (CustomFieldStorage) item.CustomFields[nameof(CustomFieldStorage)];
var dc = item.CommitToDataContract();
return new SchedulerAppointmentVM(new SchedulerAppointmentDC
{
SchedulerAppointmentOid = dc.SchedulerAppointmentOid,
NewSchedulerAppointmentVersion = dc.NewSchedulerAppointmentVersion,
IsPrivate = item.IsPrivate,
RecurrenceInfo = item.RecurrenceInfo,
Type = item.EventType,
CustomerList = customFieldStorage.CustomerList,
ResourceList = customFieldStorage.ResourceList,
AllDay = item.AllDay,
EmployeeList = item.EmployeeList.ToList(),
Description = item.Description,
EndDate = item.End,
StartDate = item.Start,
Location = item.Location,
Subject = item.Subject,
Status = 1,
Originator = customFieldStorage.Originator,
IsTeilnahmeBestaetigung = true,
SupportConceptList = customFieldStorage.SupportConceptList,
ActivationType = dc.ActivationType,
ServiceRecordList = customFieldStorage.ServiceRecordList
})
{
CustomFields = item.CustomFields, LabelKey = emp2AppOid
};
}
private void CloseButton_Click(object sender, RoutedEventArgs e)
{
Close();
}
private void Selector_OnSelected(object sender, RoutedEventArgs e)
{
var lv = (ListView) sender;
SelektierterTermin = (IBeWoAppointment) lv.SelectedItem;
}
private void Zusagen_OnClick(object sender, RoutedEventArgs e)
{
var meinTermin = SelektierterTermin as SchedulerAppointmentVM;
UpdateTeilnahme(ParticipationAnswer.Zusage, meinTermin);
}
private void Absagen_OnClick(object sender, RoutedEventArgs e)
{
var meinTermin = SelektierterTermin as SchedulerAppointmentVM;
UpdateTeilnahme(ParticipationAnswer.Absage, meinTermin);
}
private void MitVorbehalt_OnClick(object sender, RoutedEventArgs e)
{
var meinTermin = SelektierterTermin as SchedulerAppointmentVM;
UpdateTeilnahme(ParticipationAnswer.Vorbehalt, meinTermin);
}
private void UpdateTeilnahme(ParticipationAnswer antwort, SchedulerAppointmentVM termin)
{
termin.EmployeeList.DoForEach(e =>
{
if (e.Employee.EmployeeOid.Equals(BeWoApp.LoggedOnEmployee.EmployeeOid))
{
e.ParticipationAnswer = antwort;
}
});
ToggleControls();
raiseChangeEvent = true;
ServiceFacade.DoResourceServiceAsync(s => s.UpdateSchedulerAppointments(new List<SchedulerAppointmentDC> { termin.CommitToDataContract() }), UpdateView);
}
private void UpdateView(List<SchedulerAppointmentDC> aktualisierteTermine)
{
if(BeWoApp.LoggedOnEmployeeOid is null)
{
return;
}
ServiceFacade.DoResourceServiceAsync(s => s.GetAllOpenAppointmentsForEmployee(BeWoApp.LoggedOnEmployeeOid.Value), offeneTermine =>
{
Cache.GetInstance().GetSchedulerObjects((customers, employees, categoriesToResources) =>
{
this.Dispatch(() =>
{
var listVm = new SchedulerAppointmentListVM(offeneTermine, customers, employees, categoriesToResources);
var appointmentsToAnswer = NewSchedulerView.InitAppointmentsToAnswer(listVm);
var appointmentStatusUpdates = NewSchedulerView.InitAppointmentStatusUpdates(listVm);
InitViewModel(appointmentsToAnswer, appointmentStatusUpdates);
RaiseParticipationChangedEventEvent();
ToggleControls();
if(!raiseChangeEvent)
{
return;
}
if(OffeneTermine.Count == 0 && OTListView.Items.Count == 0)
{
Close();
}
else
{
OTListView.SelectedIndex = 0;
}
});
});
});
}
private void OK_OnClick(object sender, RoutedEventArgs e)
{
SelektierterTermin = OTListView.SelectedItem as IBeWoAppointment;
if(_SelektierterTermin != null && _SelektierterTermin.Start < DateTime.Now && _SelektierterTermin.End < DateTime.Now)
{
if(SelektierterTermin != null && BeWoApp.LoggedOnEmployee.EmployeeOid.HasValue)
{
var customFieldStorage = (CustomFieldStorage) SelektierterTermin.CustomFields[nameof(CustomFieldStorage)];
var emp2App = customFieldStorage.EmployeeList.ToList().Find(f => f.Employee2SchedulerAppointmentOid == SelektierterTermin.LabelKey) ??
customFieldStorage.EmployeeList.ToList().Find(f => f.Employee.EmployeeOid == BeWoApp.LoggedOnEmployee.EmployeeOid.Value);
if(emp2App.Employee.EmployeeOid == BeWoApp.LoggedOnEmployee.EmployeeOid.Value)
{
emp2App.ParticipationAnswer = ParticipationAnswer.Verstrichen;
}
emp2App.IsPC_CheckedTs = DateTime.Now;
emp2App.IsPChanged = false;
}
ToggleControls();
raiseChangeEvent = true;
ServiceFacade.DoResourceServiceAsync(s => s.UpdateSchedulerAppointments(new List<SchedulerAppointmentDC> { ((SchedulerAppointmentVM)SelektierterTermin).DataContract }), UpdateView);
return;
}
if(SelektierterTermin?.LabelKey is null)
{
return;
}
var customFieldStorage2 = (CustomFieldStorage)SelektierterTermin.CustomFields[nameof(CustomFieldStorage)];
customFieldStorage2.EmployeeList.ToList().Find(f => f.Employee2SchedulerAppointmentOid == SelektierterTermin.LabelKey).IsPC_CheckedTs = DateTime.Now;
customFieldStorage2.EmployeeList.ToList().Find(f => f.Employee2SchedulerAppointmentOid == SelektierterTermin.LabelKey).IsPChanged = false;
ToggleControls();
raiseChangeEvent = true;
ServiceFacade.DoResourceServiceAsync(s => s.UpdateSchedulerAppointments(new List<SchedulerAppointmentDC> {((SchedulerAppointmentVM) SelektierterTermin).DataContract}), UpdateView);
}
private void ToggleControls()
{
ZusagenStack.IsEnabled = !ZusagenStack.IsEnabled;
OkButton.IsEnabled = !OkButton.IsEnabled;
CloseBtn.IsEnabled = !CloseBtn.IsEnabled;
AlleBestaetigen.IsEnabled = !AlleBestaetigen.IsEnabled;
}
private void PopupBaseEdit_OnPopupOpening(object sender, OpenPopupEventArgs e)
{
// Es wird verhindert, dass das Popup angezeigt wird auch wenn das DateEdit readonly ist, damit man es nicht auf disabled setzen muss, da sonst die Schriftfarbe schwer lesbar ist.
e.Cancel = true;
}
private void RequestAnswerView_OnClosing(object sender, CancelEventArgs e)
{
BeWoApp.MainControl.AufOffeneTerminePruefen();
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
var appointmentsToUpdate = new List<SchedulerAppointmentDC>();
foreach(var appointment in OffeneTermine)
{
if(appointment.CustomFields["CustomFieldStorage"] is CustomFieldStorage customFieldStorage)
{
var employeeList = customFieldStorage.EmployeeList ?? new ObservableCollection<Employee2SchedulerAppointmentDC>();
foreach(var e2Sa in employeeList)
{
e2Sa.IsPC_CheckedTs = DateTime.Now;
if (e2Sa.Employee.EmployeeOid == BeWoApp.LoggedOnEmployee.EmployeeOid)
{
if(appointment.Start < DateTime.Now && appointment.End < DateTime.Now)
{
e2Sa.ParticipationAnswer = ParticipationAnswer.Verstrichen;
e2Sa.IsPC_CheckedTs = DateTime.Now;
e2Sa.IsPChanged = false;
}
else
{
e2Sa.IsPChanged = true;
e2Sa.ParticipationAnswer = ParticipationAnswer.Zusage;
}
}
else
{
e2Sa.IsPChanged = false;
}
}
if (employeeList.Any())
{
if(appointment is SchedulerAppointmentVM vm)
{
appointmentsToUpdate.AddIfNotIn(vm.CommitToDataContract());
}
}
}
}
ToggleControls();
raiseChangeEvent = false;
ServiceFacade.DoResourceServiceAsync(s => s.UpdateSchedulerAppointments(appointmentsToUpdate), UpdateView);
Close();
}
}
public class LVItemConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var app = (IBeWoAppointment) value;
if(app == null)
{
return string.Empty;
}
if(app.LabelKey is null)
{
return $"{app.Start.ToShortDateString()}: {app.Subject}";
}
var s = string.Empty;
var customFieldStorage = (CustomFieldStorage) app.CustomFields[nameof(CustomFieldStorage)];
var l = customFieldStorage.EmployeeList.ToList().Find(f => f.Employee2SchedulerAppointmentOid == app.LabelKey);
switch(l.ParticipationAnswer)
{
case ParticipationAnswer.Zusage:
s = "zugesagt";
break;
case ParticipationAnswer.Vorbehalt:
s = "mit Vorbehalt zugesagt";
break;
case ParticipationAnswer.Absage:
s = "abgesagt";
break;
}
return $"{app.Start.ToShortDateString()}: {l.Employee.FirstName} {l.Employee.LastName} hat {s}";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class OriginatorExtraxtor : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if(value == null)
{
return null;
}
var app = (IBeWoAppointment)value;
var customFieldStorage = (CustomFieldStorage) app.CustomFields[nameof(CustomFieldStorage)];
var originator = customFieldStorage.Originator;
return originator.FirstName + " " + originator.LastName;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class Int2VisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if(value == null)
{
return Visibility.Collapsed;
}
var appointment = (SchedulerAppointmentVM) value;
var eternalEh = false;
var liegtInDerVergangenheit = appointment.Start < DateTime.Now && appointment.End < DateTime.Now;
if(appointment.RecurrenceInfo != null)
{
IRecurrenceInfo info = new RecurrenceInfo();
info.FromXml(appointment.RecurrenceInfo);
eternalEh = info.Range == RecurrenceRange.NoEndDate;
liegtInDerVergangenheit = info.Start < DateTime.Now && info.End < DateTime.Now;
}
if(parameter != null && parameter.Equals("ZusagenStack"))
{
if(appointment.IsTeilnahmeBestaetigung)
{
return Visibility.Collapsed;
}
var shouldBeVisible = !liegtInDerVergangenheit;
if(appointment.RecurrenceInfo != null)
{
shouldBeVisible = !liegtInDerVergangenheit || eternalEh;
}
return shouldBeVisible ? Visibility.Visible : Visibility.Collapsed;
}
if(parameter != null && parameter.Equals("OKBtn"))
{
return appointment.IsTeilnahmeBestaetigung || liegtInDerVergangenheit && !eternalEh ? Visibility.Visible : Visibility.Collapsed;
}
if(parameter != null && parameter.Equals("TerminVerstrichen"))
{
return liegtInDerVergangenheit && !eternalEh ? Visibility.Visible : Visibility.Collapsed;
}
if(parameter != null && parameter.Equals("SerienterminLabel"))
{
return appointment.RecurrenceInfo != null ? Visibility.Visible : Visibility.Collapsed;
}
return appointment.IsTeilnahmeBestaetigung || liegtInDerVergangenheit ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class SerienterminDauerAnzeigeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if(value == null)
{
return null;
}
var appointment = (SchedulerAppointmentVM) value;
if(appointment.RecurrenceInfo == null)
{
return "";
}
IRecurrenceInfo info = new RecurrenceInfo();
info.FromXml(appointment.RecurrenceInfo);
var rangeString = "";
var suffix = "";
var periodicity = info.Periodicity;
var intervalPlural = "";
var wochentage = "";
string wocheDesMonats;
switch(info.Range)
{
case RecurrenceRange.EndByDate:
rangeString += "bis zum " + info.End.ToShortDateString() + " ";
break;
case RecurrenceRange.OccurrenceCount:
rangeString += info.OccurrenceCount + " mal ";
break;
}
switch(info.Type)
{
case RecurrenceType.Daily:
if(periodicity == 1)
{
suffix = info.WeekDays.Equals(WeekDays.WorkDays) ? "jeden Arbeitstag " : "täglich ";
}
intervalPlural = " Tage ";
break;
case RecurrenceType.Weekly:
if(periodicity == 1)
{
suffix = "wöchentlich ";
}
intervalPlural = " Wochen ";
wochentage = TranslateWorkDays(info.WeekDays.ToString(), true);
break;
case RecurrenceType.Yearly:
wochentage = TranslateWorkDays(info.WeekDays.ToString(), false);
wocheDesMonats = TranslateWeekOfMonth(info.WeekOfMonth);
var tag = info.DayNumber;
suffix = "jährlich ";
if(info.WeekOfMonth != WeekOfMonth.None)
{
suffix += "jeden " + wocheDesMonats + wochentage + "im " + GetMonthByInt(info.Month);
}
else
{
suffix += "am " + tag + ". " + GetMonthByInt(info.Month);
}
wochentage = "";
break;
case RecurrenceType.Monthly:
string monatlichesInterval;
if(info.WeekOfMonth != WeekOfMonth.None)
{
wocheDesMonats = TranslateWeekOfMonth(info.WeekOfMonth);
wochentage = TranslateWorkDays(info.WeekDays.ToString(), false);
suffix = "jeden " + wocheDesMonats + wochentage;
if(periodicity == 1)
{
monatlichesInterval = "jedes Monats ";
}
else
{
monatlichesInterval = "jedes " + periodicity + ". Monats ";
}
suffix += monatlichesInterval;
wochentage = "";
}
else
{
if(periodicity == 1)
{
monatlichesInterval = "jedes Monats ";
}
else
{
monatlichesInterval = "jedes " + periodicity + ". Monats ";
}
suffix = "am " + info.DayNumber + ". " + monatlichesInterval;
wochentage = "";
}
break;
}
if(periodicity > 1 && info.Type != RecurrenceType.Monthly)
{
suffix = "alle " + periodicity + intervalPlural;
}
return "Dieser Termin wird " + rangeString + suffix + wochentage + "wiederholt";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
private static string TranslateWorkDays(string weekDays, bool mitGenitivS)
{
weekDays = weekDays.Replace("Monday", mitGenitivS ? "Montags" : "Montag");
weekDays = weekDays.Replace("Tuesday", mitGenitivS ? "Dienstags" : "Dienstag");
weekDays = weekDays.Replace("Wednesday", mitGenitivS ? "Mittwochs" : "Mittwoch");
weekDays = weekDays.Replace("Thursday", mitGenitivS ? "Donnerstags" : "Donnerstag");
weekDays = weekDays.Replace("Friday", mitGenitivS ? "Freitags" : "Freitag");
weekDays = weekDays.Replace("Saturday", mitGenitivS ? "Samstags" : "Samstag");
weekDays = weekDays.Replace("Sunday", mitGenitivS ? "Sonntags" : "Sonntag");
weekDays = weekDays.Replace("EveryDay", "jeden Tag");
var lastComma = weekDays.LastIndexOf(',');
if(lastComma != -1)
{
weekDays = weekDays.Remove(lastComma, 1).Insert(lastComma, " und");
}
return weekDays + " ";
}
private static string TranslateWeekOfMonth(WeekOfMonth weekOfMonth)
{
var result = " ";
switch(weekOfMonth)
{
case WeekOfMonth.First:
result = "ersten ";
break;
case WeekOfMonth.Second:
result = "zweiten ";
break;
case WeekOfMonth.Third:
result = "dritten ";
break;
case WeekOfMonth.Fourth:
result = "vierten ";
break;
case WeekOfMonth.Last:
result = "letzten ";
break;
case WeekOfMonth.None:
return result;
default:
return result;
}
return result;
}
private static string GetMonthByInt(int month)
{
switch(month)
{
case 1:
return "Januar ";
case 2:
return "Februar ";
case 3:
return "März ";
case 4:
return "April ";
case 5:
return "Mai ";
case 6:
return "Juni ";
case 7:
return "Juli ";
case 8:
return "August ";
case 9:
return "September ";
case 10:
return "Oktober ";
case 11:
return "November ";
case 12:
return "Dezember ";
default:
return " ";
}
}
}
}