using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Windows; using System.Windows.Media; using BeWo.Scheduling.SchedulingUtils; using BeWo.ViewModel; using BS.Shared; using BS.Shared.DataContracts; using BS.Shared.DataContracts.Compact; using BS.Shared.Extensions; using DevExpress.XtraScheduler; using DevExpress.Xpf.Scheduling; namespace BeWo.Scheduling.ViewModel { public class SchedulingAppointmentVM : AbstractDCMapperVM { public SchedulingAppointmentVM VMForCustomField => this; private bool _AllDay; private string _Description; private DateTime _End; private string _Location; private string _RecurrenceInfo; private DateTime _Start; private int _Status; private string _Subject; private int _Type; private bool _IsPrivate; private ObservableCollection _EmployeeList; private List _CustomerList; private List _ResourceList; private ObservableCollection _SupportConceptList; private CompactEmployeeDC _Originator; private bool _IsTask; private string _TaskDescription; private string _CompletedNotice; private DateTime? _CompletedDate; private DateTime? _DueDate; private DateTime? _DueTime; private bool _HasServiceRecordEntry; private bool _IsArchived; public bool HasServiceRecordEntry { get => _HasServiceRecordEntry; set { if(AreDifferent(_HasServiceRecordEntry, value)) { _HasServiceRecordEntry = value; StoreDirtyInformation(AreDifferent(DataContract.HasServiceRecordEntry, value), nameof(HasServiceRecordEntry)); FirePropertyChanged(nameof(HasServiceRecordEntry)); } } } public bool IsArchived { get => _IsArchived; set { if(AreDifferent(_IsArchived, value)) { _IsArchived = value; StoreDirtyInformation((value && DataContract.ActivationType == ActivationTypeId.Active) || (!value && DataContract.ActivationType == ActivationTypeId.Archived), nameof(IsArchived)); FirePropertyChanged(nameof(IsArchived)); } } } public DateTime? AbsenceTimeStart { get; set; } public DateTime? AbsenceTimeEnd { get; set; } public virtual string ReminderInfo { get; set; } public virtual object Id { get; set; } public virtual long? LabelKey { get; set; } /// /// Der AppointmentType des Termins als Integer; 0 = Pattern; 1 = Normal; 2 = Occurrence; 3 = ChangedOccurrence; 4 = DeletedOccurrence /// public virtual int EventType { get => _Type; set { if(AreDifferent(_Type, value)) { _Type = value; StoreDirtyInformation(AreDifferent(DataContract.Type, value), nameof(Type)); FirePropertyChanged(nameof(Type)); } } } public virtual DateTime End { get => _End; set { if(AreDifferent(_End, value)) { _End = value; if(IsAbsenceTime) { return; } StoreDirtyInformation(AreDifferent(DataContract.EndDate, value), nameof(End)); FirePropertyChanged(nameof(End)); } } } public virtual DateTime Start { get => _Start; set { if(AreDifferent(_Start, value)) { _Start = value; if(IsAbsenceTime) { return; } StoreDirtyInformation(AreDifferent(DataContract.StartDate, value), nameof(Start)); FirePropertyChanged(nameof(Start)); } } } public virtual bool AllDay { get => _AllDay; set { if(AreDifferent(_AllDay, value)) { _AllDay = value; if(IsAbsenceTime) { return; } StoreDirtyInformation(AreDifferent(DataContract.AllDay, value), nameof(AllDay)); FirePropertyChanged(nameof(AllDay)); } } } public virtual string Subject { get => _Subject; set { if(AreDifferent(_Subject, value)) { _Subject = value; if(IsAbsenceTime) { return; } StoreDirtyInformation(AreDifferent(DataContract.Subject, value), nameof(Subject)); FirePropertyChanged(nameof(Subject)); } } } public virtual string Location { get => _Location; set { if(AreDifferent(_Location, value)) { _Location = value; if(IsAbsenceTime) { return; } StoreDirtyInformation(AreDifferent(DataContract.Location, value), nameof(Location)); FirePropertyChanged(nameof(Location)); } } } public virtual int Status { get => _Status; set { if(AreDifferent(_Status, value)) { _Status = value; if(IsAbsenceTime) { return; } StoreDirtyInformation(AreDifferent(DataContract.Status, value), nameof(Status)); FirePropertyChanged(nameof(Status)); } } } public bool IsTeilnahmeBestaetigung { get; } public virtual string RecurrenceInfo { get => _RecurrenceInfo; set { if(AreDifferent(_RecurrenceInfo, value)) { _RecurrenceInfo = value; if(IsAbsenceTime) { return; } StoreDirtyInformation(AreDifferent(DataContract.RecurrenceInfo, value), nameof(RecurrenceInfo)); FirePropertyChanged(nameof(RecurrenceInfo)); } } } public virtual string Description { get => _Description; set { if(AreDifferent(_Description, value)) { _Description = value; if(IsAbsenceTime) { return; } StoreDirtyInformation(AreDifferent(DataContract.Description, value), nameof(Description)); FirePropertyChanged(nameof(Description)); } } } public ObservableCollection EmployeeList { get => _EmployeeList ?? (_EmployeeList = new ObservableCollection()); set { if(AreDifferent(_EmployeeList, value)) { _EmployeeList = value; if(IsAbsenceTime) { return; } StoreDirtyInformation(AreDifferent(DataContract.EmployeeList, value), nameof(EmployeeList)); FirePropertyChanged(nameof(EmployeeList)); } } } public List CustomerList { get => _CustomerList ?? (_CustomerList = new List()); set { if(AreDifferent(_CustomerList, value)) { _CustomerList = value; if(IsAbsenceTime) { return; } StoreDirtyInformation(AreDifferent(DataContract.CustomerList, value), nameof(CustomerList)); FirePropertyChanged(nameof(CustomerList)); } } } public List ResourceList { get => _ResourceList ?? (ResourceList = new List()); set { if(AreDifferent(_ResourceList, value)) { _ResourceList = value; if(IsAbsenceTime) { return; } StoreDirtyInformation(AreDifferent(DataContract.ResourceList, value), nameof(ResourceList)); FirePropertyChanged(nameof(ResourceList)); } } } public ObservableCollection SupportConceptList { get => _SupportConceptList ?? (SupportConceptList = new ObservableCollection()); set { if(AreDifferent(_SupportConceptList, value)) { _SupportConceptList = value; if(IsAbsenceTime) { return; } StoreDirtyInformation(AreDifferent(DataContract.SupportConceptList, value), nameof(SupportConceptList)); FirePropertyChanged(nameof(SupportConceptList)); } } } public bool IsPrivate { get => _IsPrivate; set { if(AreDifferent(_IsPrivate, value)) { _IsPrivate = value; if(IsAbsenceTime) { return; } StoreDirtyInformation(AreDifferent(DataContract.IsPrivate, value), nameof(IsPrivate)); FirePropertyChanged(nameof(IsPrivate)); } } } public virtual CompactEmployeeDC Originator { get => _Originator; set { if(AreDifferent(_Originator, value)) { _Originator = value; if(IsAbsenceTime) { return; } StoreDirtyInformation(AreDifferent(DataContract.Originator, value), nameof(Originator)); FirePropertyChanged(nameof(Originator)); } } } public virtual TimeSpan EndTime => End.TimeOfDay; public virtual TimeSpan StartTime => Start.TimeOfDay; public virtual bool IsAbsenceTime { get; } public bool IsTask { get => _IsTask; set { if(AreDifferent(_IsTask, value)) { _IsTask = value; if(IsAbsenceTime) { return; } StoreDirtyInformation(AreDifferent(DataContract.IsTask, value), nameof(IsTask)); FirePropertyChanged(nameof(IsTask)); } } } public string TaskDescription { get => _TaskDescription; set { if(AreDifferent(_TaskDescription, value)) { _TaskDescription = value; if(IsAbsenceTime) { return; } StoreDirtyInformation(AreDifferent(DataContract.TaskDescription, value), nameof(TaskDescription)); FirePropertyChanged(nameof(TaskDescription)); } } } public string CompletedNotice { get => _CompletedNotice; set { if(AreDifferent(_CompletedNotice, value)) { _CompletedNotice = value; if(IsAbsenceTime) { return; } StoreDirtyInformation(AreDifferent(DataContract.CompletedNotice, value), nameof(CompletedNotice)); FirePropertyChanged(nameof(CompletedNotice)); } } } public DateTime? CompletedDate { get => _CompletedDate; set { if(AreDifferent(_CompletedDate, value)) { _CompletedDate = value; if(IsAbsenceTime) { return; } StoreDirtyInformation(AreDifferent(DataContract.CompletedDate, value), nameof(CompletedDate)); FirePropertyChanged(nameof(CompletedDate)); } } } public DateTime? DueDate { get => _DueDate; set { if(AreDifferent(_DueDate, value)) { _DueDate = value; if(IsAbsenceTime) { return; } StoreDirtyInformation(AreDifferent(DataContract.DueDate, value), nameof(DueDate)); FirePropertyChanged(nameof(DueDate)); } } } public DateTime? DueTime { get => _DueTime; set { if(AreDifferent(_DueTime, value)) { _DueTime = value; StoreDirtyInformation(AreDifferent(DataContract.DueDate, value), nameof(DueTime)); FirePropertyChanged(nameof(DueTime)); } } } public Guid? RecurrenceId => BS.Shared.Core.Utils.GetRecurrenceIdFromRecurrenceInfo(RecurrenceInfo); public int RecurrenceIndex => BS.Shared.Core.Utils.GetRecurrenceIndexFromRecurrenceInfo(RecurrenceInfo); public bool CanBeEdited { get; set; } = true; public AppointmentColorHelper AppointmentColors { get; set; } public SolidColorBrush BackgroundColor { get; set; } public SolidColorBrush ForegroundColor { get; set; } public SolidColorBrush AppointmentBorderBrush { get { if(EmployeeList?.Any(e2a => e2a.Employee.Equals(BeWoApp.CompactLoggedOnEmployee) && e2a.ParticipationAnswer == ParticipationAnswer.Vorbehalt) ?? false) { return new SolidColorBrush(Color.FromRgb(185, 39, 217)); } return new SolidColorBrush(Colors.Transparent); } } public string ToolTip { get { var result = Subject; if(IsTask) { result = result ?? ""; if(CompletedDate.HasValue) { result += $" erledigt am {CompletedDate.Value:dd.MM.yyyy}"; } else if(DueDate.HasValue) { result += $" bis {DueDate.Value:dd.MM.yyyy HH:mm}"; } } if(IsAbsenceTime && AbsenceTimeStart.HasValue) { result += AbsenceTimeStart.Value.GetIntervalDescription(AbsenceTimeEnd); } return result; } } public Visibility ToolTipTimeVisibility => IsTask || IsAbsenceTime || AllDay ? Visibility.Collapsed : Visibility.Visible; public Visibility ToolTipResourcesVisibility => ResourceList?.Count > 0 ? Visibility.Visible : Visibility.Collapsed; public Visibility ToolTipEmployeesVisibility => EmployeeList?.Count > 0 ? Visibility.Visible : Visibility.Collapsed; public Visibility ToolTipCustomersVisibility => CustomerList?.Count > 0 ? Visibility.Visible : Visibility.Collapsed; public Visibility ToolTipTrennstrichVisibility => EmployeeList?.Count > 0 || CustomerList?.Count > 0 || ResourceList?.Count > 0 ? Visibility.Visible : Visibility.Collapsed; public Visibility ToolTipZusageVisibility => IsTask ? Visibility.Collapsed : Visibility.Visible; public string ResourcesToolTip => GetIFiltereableInfo(ResourceList.Cast().ToList()); public string EmployeesToolTip => GetIFiltereableInfo(EmployeeList.Select(s => s.Employee).Cast().ToList()); public string CustomersToolTip => GetIFiltereableInfo(CustomerList.Cast().ToList()); public bool LiesInPast => Start < DateTime.Now && End < DateTime.Now; private static string GetIFiltereableInfo(List list) { var tooltip = string.Empty; foreach(var item in list) { var index = list.IndexOf(item); if(index % 3 == 0 && index < list.Count - 1 && index > 0) { tooltip += "\n"; } tooltip += item.ToString(); if(index < list.Count - 1) { tooltip += "; "; } } return tooltip; } // Für DevExpress public SchedulingAppointmentVM() : base(new SchedulerAppointmentDC(), true) { CanBeEdited = true; } public SchedulingAppointmentVM(SchedulerAppointmentDC dataContract) : base(dataContract, dataContract.SchedulerAppointmentOid == null) { IsTeilnahmeBestaetigung = dataContract.IsTeilnahmeBestaetigung; CanBeEdited = dataContract.CanBeEdited; InitAppointmentColors(); if(dataContract.IsPrivate == false || dataContract.Originator.EmployeeOid.Equals(BeWoApp.LoggedOnEmployee.EmployeeOid) || dataContract.EmployeeList.Any(e2a => e2a.Employee.Equals(BeWoApp.CompactLoggedOnEmployee))) { return; } CanBeEdited = false; dataContract.Description = "Privater Termin"; dataContract.Subject = $"Privat ({dataContract.Originator})"; } // Wird für Abwesenheiten genutzt public SchedulingAppointmentVM(bool pAllDay, string pSubject, DateTime pStart, DateTime pEnd, CompactEmployeeDC pOriginator, DateTime? absenceTimeStart, DateTime? absenceTimeEnd) { _AllDay = pAllDay; _Subject = pSubject; _Start = pStart; _End = pEnd; _Originator = pOriginator; AbsenceTimeStart = absenceTimeStart; AbsenceTimeEnd = absenceTimeEnd; IsAbsenceTime = true; InitAppointmentColors(); } // Zum Erstellen einer neuen Serienausnahme /// /// Zur Erstellung einer Serienausnahme (ChangedOccurrence) aus einem AppointmentItem. /// /// AppointmentItem aus dem ein SchedulingAppointmentVM mit Typ 'ChangedOccurrence' erzeugt werden soll /// Wiederholungsinfo für das SchedulerControl mit Id und Index public SchedulingAppointmentVM(AppointmentItem appointmentItem, string recurrenceInfoXml) : base(new SchedulerAppointmentDC(), true) { if(appointmentItem.Type == AppointmentType.Normal) { return; } _AllDay = appointmentItem.AllDay; _Start = appointmentItem.Start; _End = appointmentItem.End; _Location = appointmentItem.Location; _RecurrenceInfo = recurrenceInfoXml; _Description = appointmentItem.Description; _Subject = appointmentItem.Subject; _Type = 3; // ChangedOccurrence, Occurrence ist nicht in der Datenbank gespeichert _IsPrivate = appointmentItem.CustomFields["IsPrivate"] is bool b && b; _EmployeeList = appointmentItem.CustomFields["EmployeeList"] as ObservableCollection ?? new ObservableCollection(); _CustomerList = appointmentItem.CustomFields["CustomerList"] as List ?? new List(); _ResourceList = appointmentItem.CustomFields["ResourceList"] as List ?? new List(); _Originator = appointmentItem.CustomFields["Originator"] as CompactEmployeeDC ?? BeWoApp.CompactLoggedOnEmployee; } /// /// Wird für Strg + V und zur Rechteprüfung bei der Erstellung des Löschen-Buttons des Contextmenüs benutzt. /// /// AppointmentItem aus dem ein SchedulingAppointmentVM erzeugt werden soll public SchedulingAppointmentVM(AppointmentItem appointmentItem) : base(new SchedulerAppointmentDC(), true) { _AllDay = appointmentItem.AllDay; _Start = appointmentItem.Start; _End = appointmentItem.End; _Location = appointmentItem.Location; _RecurrenceInfo = appointmentItem.RecurrenceInfo?.ToString(); _Description = appointmentItem.Description; _Subject = appointmentItem.Subject; _Type = (int) appointmentItem.Type; _IsPrivate = appointmentItem.CustomFields["IsPrivate"] is bool b && b; var tempEmployeeList = appointmentItem.CustomFields["EmployeeList"] as ObservableCollection ?? new ObservableCollection(); var tempCustomerList = appointmentItem.CustomFields["CustomerList"] as List ?? new List(); var tempResourceList = appointmentItem.CustomFields["ResourceList"] as List ?? new List(); var tempSupportConceptList = appointmentItem.CustomFields["SupportConceptList"] as List ?? new List(); _EmployeeList = new ObservableCollection(); _CustomerList = new List(); _ResourceList = new List(); _SupportConceptList = new ObservableCollection(); foreach(var e2a in tempEmployeeList) { _EmployeeList.AddIfNotIn(new Employee2SchedulerAppointmentDC { Employee = e2a.Employee }); } foreach(var customer in tempCustomerList) { _CustomerList.AddIfNotIn(customer); } foreach(var resource in tempResourceList) { _ResourceList.AddIfNotIn(resource); } foreach(var supportConcept in tempSupportConceptList) { _SupportConceptList.AddIfNotIn(supportConcept); } _Originator = appointmentItem.CustomFields["Originator"] as CompactEmployeeDC ?? BeWoApp.CompactLoggedOnEmployee; } protected override void InitByDataContract(SchedulerAppointmentDC pDataContract) { _AllDay = pDataContract.AllDay; _Description = pDataContract.Description; _End = pDataContract.EndDate ?? DateTime.Now; _Location = pDataContract.Location; _RecurrenceInfo = pDataContract.RecurrenceInfo; _Start = pDataContract.StartDate ?? DateTime.Now; _Status = pDataContract.Status; _Subject = pDataContract.Subject; _Type = pDataContract.Type; _IsPrivate = pDataContract.IsPrivate; _Originator = pDataContract.Originator; _CustomerList = pDataContract.CustomerList ?? new List(); _EmployeeList = new ObservableCollection(pDataContract.EmployeeList ?? new List()); _ResourceList = pDataContract.ResourceList ?? new List(); _IsTask = pDataContract.IsTask; _TaskDescription = pDataContract.TaskDescription; _CompletedNotice = pDataContract.CompletedNotice; _CompletedDate = pDataContract.CompletedDate; _SupportConceptList = new ObservableCollection(pDataContract.SupportConceptList ?? new List()); _HasServiceRecordEntry = pDataContract.HasServiceRecordEntry; _IsArchived = pDataContract.ActivationType == ActivationTypeId.Archived; CanBeEdited = pDataContract.CanBeEdited; Id = pDataContract.SchedulerAppointmentOid; if(pDataContract.DueDate.HasValue) { _DueDate = pDataContract.DueDate; _DueTime = pDataContract.DueDate; } InitAppointmentColors(); } private void InitAppointmentColors() { var employeeColor = Color.FromRgb(192, 255, 208); if(Utils.IsValidColorHexString(Originator?.EmployeeColor)) { employeeColor = (Color) ColorConverter.ConvertFromString(Originator.EmployeeColor); } if(IsTask) { employeeColor = Color.FromRgb(153, 59, 59); } var resourceColors = new List(); foreach(var resource in ResourceList) { if(Utils.IsValidColorHexString(resource.Color)) { resourceColors.AddIfNotIn((Color) ColorConverter.ConvertFromString(resource.Color)); } } AppointmentColors = new AppointmentColorHelper(employeeColor, resourceColors, CustomerList?.Any() ?? false, IsTask); var colorHexValue = IsTask ? Color.FromRgb(153, 59, 59) : Color.FromRgb(192, 255, 208); BackgroundColor = new SolidColorBrush(colorHexValue); var foregroundColorHexValue = IsTask ? Color.FromRgb(224, 224, 224) : Color.FromRgb(0, 0, 0); ForegroundColor = new SolidColorBrush(foregroundColorHexValue); } protected override SchedulerAppointmentDC MapToDataContract(SchedulerAppointmentDC pDataContract, bool doCommit) { pDataContract.AllDay = _AllDay; pDataContract.Description = _Description; pDataContract.EndDate = _End; pDataContract.Location = _Location; pDataContract.RecurrenceInfo = _RecurrenceInfo; pDataContract.StartDate = _Start; pDataContract.Status = _Status; pDataContract.Subject = _Subject; pDataContract.Type = _Type; pDataContract.IsPrivate = _IsPrivate; pDataContract.Originator = _Originator; pDataContract.CustomerList = _CustomerList; pDataContract.EmployeeList = _EmployeeList.ToList(); pDataContract.ResourceList = _ResourceList; pDataContract.IsTask = _IsTask; pDataContract.TaskDescription = _TaskDescription; pDataContract.CompletedNotice = _CompletedNotice; pDataContract.CompletedDate = _CompletedDate; pDataContract.SupportConceptList = _SupportConceptList.ToList(); pDataContract.HasServiceRecordEntry = _HasServiceRecordEntry; pDataContract.ActivationType = _IsArchived ? ActivationTypeId.Archived : ActivationTypeId.Active; if(_DueDate.HasValue && _DueTime.HasValue) { pDataContract.DueDate = new DateTime(_DueDate.Value.Year, _DueDate.Value.Month, _DueDate.Value.Day, _DueTime.Value.Hour, _DueTime.Value.Minute, 0); } else { pDataContract.DueDate = _DueDate; } return pDataContract; } public override bool Equals(object pObj) { if(!(pObj is SchedulingAppointmentVM schedulingAppointmentVM)) { return false; } var customFieldsAreEqual = true; var areEqual = Equals(Subject, schedulingAppointmentVM.Subject) && LabelKey == schedulingAppointmentVM.LabelKey && AllDay == schedulingAppointmentVM.AllDay && IsPrivate == schedulingAppointmentVM.IsPrivate && IsDirty == schedulingAppointmentVM.IsDirty && IsNew == schedulingAppointmentVM.IsNew && IsTask == schedulingAppointmentVM.IsTask && TaskDescription == schedulingAppointmentVM.TaskDescription && Equals(CompletedDate, schedulingAppointmentVM.CompletedDate) && Equals(DueDate, schedulingAppointmentVM.DueDate) && Equals(CompletedNotice, schedulingAppointmentVM.CompletedNotice) && customFieldsAreEqual && CustomerList.AreEqual(schedulingAppointmentVM.CustomerList) && Equals(Description, schedulingAppointmentVM.Description) && EmployeeList.AreEqual(schedulingAppointmentVM.EmployeeList) && Equals(End, schedulingAppointmentVM.End) && Equals(EndTime, schedulingAppointmentVM.EndTime) && Equals(Location, schedulingAppointmentVM.Location) && ResourceList.AreEqual(schedulingAppointmentVM.ResourceList) && Equals(RecurrenceInfo, schedulingAppointmentVM.RecurrenceInfo) && HasServiceRecordEntry == schedulingAppointmentVM.HasServiceRecordEntry ; return areEqual; } public override int GetHashCode() { if(DataContract?.SchedulerAppointmentOid.HasValue ?? false) { return GetType().Name.GetHashCode() ^ DataContract.SchedulerAppointmentOid.Value.GetHashCode(); } return base.GetHashCode(); } public override bool IsDirty => !IsAbsenceTime && base.IsDirty; public new bool IsNew { get => !IsAbsenceTime && base.IsNew; set => base.IsNew = value; } } }