Kalender:
Die Abfrage nach der Ressourcenbelegung kommt nur ein mal und das Abbrechen des Speicherns hat keinen "kaputten" Reload zur Folge
Das Löschen eines Serientermins mit veränderten oder gelöschten Elementen führt zu keiner Exception mehr, da ich den Service-Aufruf auf synchron geändert habe.
Es gibt allerdings noch Bugs! -> Serientermin erstellen und ein Element davon ändern führt zu einer doppelten Abfrage, ausgelöst durch die Überlappungsprüfung, die eine Überlappung mit der Serie selbst feststellt!
This commit is contained in:
@@ -917,7 +917,7 @@
|
||||
<dxsch:SchedulerControl Grid.Column="2" x:Name="Scheduler" dx:ThemeManager.ThemeName="Office2010Black"
|
||||
FormCustomizationUsingMVVMLocal="False"
|
||||
InplaceEditorShowing="Scheduler_OnInplaceEditorShowing"
|
||||
GroupType="None" AppointmentDrag="Scheduler_OnAppointmentDrag"
|
||||
GroupType="None" AppointmentDrag="Scheduler_OnAppointmentDrag" AppointmentDrop="Scheduler_OnAppointmentDrop"
|
||||
VerticalAlignment="Stretch"
|
||||
EditAppointmentFormShowing="Scheduler_EditAppointmentFormShowing"
|
||||
EditRecurrentAppointmentFormShowing="SchedulerControl_EditRecurrentAppointmentFormShowing"
|
||||
|
||||
@@ -38,6 +38,7 @@ using DevExpress.Xpf.Scheduler.Reporting;
|
||||
using DevExpress.XtraScheduler;
|
||||
using DevExpress.XtraScheduler.Compatibility;
|
||||
using DevExpress.XtraScheduler.iCalendar;
|
||||
using DevExpress.XtraScheduler.Services;
|
||||
using Microsoft.Win32;
|
||||
using Appointment = DevExpress.XtraScheduler.Appointment;
|
||||
using AppointmentViewInfoCustomizingEventArgs = DevExpress.Xpf.Scheduler.AppointmentViewInfoCustomizingEventArgs;
|
||||
@@ -1029,23 +1030,22 @@ namespace BeWo.Scheduler.View
|
||||
var idList = (from item in dcList where item.SchedulerAppointmentOid.HasValue select item.SchedulerAppointmentOid.Value).ToList();
|
||||
|
||||
IgnoreChangeEvents = true;
|
||||
|
||||
ServiceFacade.DoResourceServiceAsync(s => s.GetSchedulerAppointmentsById(idList), appointments =>
|
||||
{
|
||||
ServiceFacade.DoResourceServiceAsync(s2 => s2.DeactivateSchedulerAppointmentsForSync(appointments.ToDictionary(dc => dc.SchedulerAppointmentOid.Value, dc => dc.NewSchedulerAppointmentVersion.Value)), updatedAppointments =>
|
||||
{
|
||||
ViewModel.ActiveAppointmentViewModel.UpdateViewModel(updatedAppointments);
|
||||
|
||||
this.Dispatch(() =>
|
||||
{
|
||||
Scheduler.ActiveView.LayoutChanged();
|
||||
UpdateRequestString();
|
||||
ReloadVM(true);
|
||||
});
|
||||
|
||||
IgnoreChangeEvents = false;
|
||||
});
|
||||
});
|
||||
|
||||
var appointments = new List<SchedulerAppointmentDC>();
|
||||
var updatedAppointments = new List<SchedulerAppointmentDC>();
|
||||
ServiceFacade.DoResourceServiceSync(s => appointments = s.GetSchedulerAppointmentsById(idList));
|
||||
if(appointments.Any())
|
||||
{
|
||||
ServiceFacade.DoResourceServiceSync(s => updatedAppointments = s.DeactivateSchedulerAppointmentsForSync(appointments.ToDictionary(dc => dc.SchedulerAppointmentOid.Value, dc => dc.NewSchedulerAppointmentVersion.Value)));
|
||||
|
||||
ViewModel.ActiveAppointmentViewModel.UpdateViewModel(updatedAppointments);
|
||||
|
||||
Scheduler.ActiveView.LayoutChanged();
|
||||
UpdateRequestString();
|
||||
ReloadVM(true);
|
||||
|
||||
IgnoreChangeEvents = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1754,91 +1754,108 @@ namespace BeWo.Scheduler.View
|
||||
var start = pIntervalStart - FetchPadding;
|
||||
var end = pIntervalEnd + FetchPadding;
|
||||
|
||||
GetCacheObjects((c, e, r) =>
|
||||
var service = Scheduler.GetService<ISchedulerStateService>();
|
||||
|
||||
this.Dispatch(() =>
|
||||
{
|
||||
ServiceFacade.DoResourceServiceAsync(s2 => s2.LoadFilteredAppointmentsMitAufgaben(BeWoApp.HasLoggedOnUserRight(new[] {UserRightType.KalenderMitarbeitertermineAnsehen}), BeWoApp.LoggedOnEmployee.EmployeeOid.Value, start, end, pSelectedEmployees, pSelectedCustomer, pSelectedResources, pEmployeesOnly, pCustomersOnly, pResourcesOnly, pPrivateAppointmentsOnly, pOnlyMyAppointments, IsTasksVisible),
|
||||
appointments =>
|
||||
{
|
||||
ServiceFacade.DoResourceServiceAsync(s3 => s3.GetAllActiveAbsenceTimesInInterval(start, end, BeWoApp.LoggedOnEmployee.EmployeeOid.Value, BeWoApp.LoggedOnUser.HasRight(UserRightType.KalenderMitarbeitertermineAnsehen)),
|
||||
absenceTimes =>
|
||||
{
|
||||
this.Dispatch(() =>
|
||||
{
|
||||
var prefilteredAppointments = appointments.Where(w => (w.EmployeeList.Count == 0 && w.Originator.EmployeeOid.Equals(BeWoApp.LoggedOnEmployee.EmployeeOid) ||
|
||||
w.EmployeeList.Count > 0 && w.EmployeeList.Any(a => a.Employee.EmployeeOid.Equals(BeWoApp.LoggedOnEmployee.EmployeeOid)) ||
|
||||
BeWoUtils.HasRight(UserRightType.KalenderMitarbeitertermineAnsehen)) && (!w.EmployeeList.TrueForAll(e2a => e2a.ParticipationAnswer == ParticipationAnswer.Absage) || w.EmployeeList == null || w.EmployeeList.Count == 0)).ToList();
|
||||
if(service.IsDataRefreshAllowed)
|
||||
{
|
||||
GetCacheObjects((c, e, r) =>
|
||||
{
|
||||
ServiceFacade.DoResourceServiceAsync(s2 => s2.LoadFilteredAppointmentsMitAufgaben(BeWoApp.HasLoggedOnUserRight(new[] { UserRightType.KalenderMitarbeitertermineAnsehen }), BeWoApp.LoggedOnEmployee.EmployeeOid.Value, start, end, pSelectedEmployees, pSelectedCustomer, pSelectedResources, pEmployeesOnly, pCustomersOnly, pResourcesOnly, pPrivateAppointmentsOnly, pOnlyMyAppointments, IsTasksVisible),
|
||||
appointments =>
|
||||
{
|
||||
ServiceFacade.DoResourceServiceAsync(s3 => s3.GetAllActiveAbsenceTimesInInterval(start, end, BeWoApp.LoggedOnEmployee.EmployeeOid.Value, BeWoApp.LoggedOnUser.HasRight(UserRightType.KalenderMitarbeitertermineAnsehen)),
|
||||
absenceTimes =>
|
||||
{
|
||||
this.Dispatch(() =>
|
||||
{
|
||||
var prefilteredAppointments = appointments.Where(w => (w.EmployeeList.Count == 0 && w.Originator.EmployeeOid.Equals(BeWoApp.LoggedOnEmployee.EmployeeOid) ||
|
||||
w.EmployeeList.Count > 0 && w.EmployeeList.Any(a => a.Employee.EmployeeOid.Equals(BeWoApp.LoggedOnEmployee.EmployeeOid)) ||
|
||||
BeWoUtils.HasRight(UserRightType.KalenderMitarbeitertermineAnsehen)) && (!w.EmployeeList.TrueForAll(e2a => e2a.ParticipationAnswer == ParticipationAnswer.Absage) || w.EmployeeList == null || w.EmployeeList.Count == 0)).ToList();
|
||||
|
||||
var vm = new SchedulerAppointmentListVM(prefilteredAppointments, c, e, r);
|
||||
if(pShouldShowAbsenceTimes)
|
||||
{
|
||||
vm.Appointments.AddRange(ViewModel.ConvertAbsenceTimesToAppointments(absenceTimes.Where(w =>
|
||||
{
|
||||
return SelectedEmployees.Count == 0 || SelectedEmployees.Any(a => a.EmployeeOid == w.EmployeeOid);
|
||||
}), end, e));
|
||||
}
|
||||
if(!IsTasksVisible)
|
||||
{
|
||||
prefilteredAppointments = prefilteredAppointments.Where(app => !app.IsTask).ToList();
|
||||
}
|
||||
|
||||
ViewModel.ActiveAppointmentViewModel = vm;
|
||||
var vm = new SchedulerAppointmentListVM(prefilteredAppointments, c, e, r);
|
||||
if(pShouldShowAbsenceTimes)
|
||||
{
|
||||
vm.Appointments.AddRange(ViewModel.ConvertAbsenceTimesToAppointments(absenceTimes.Where(w =>
|
||||
{
|
||||
return SelectedEmployees.Count == 0 || SelectedEmployees.Any(a => a.EmployeeOid == w.EmployeeOid);
|
||||
}), end, e));
|
||||
}
|
||||
|
||||
ViewModel.SchedulerSettings = ViewModel.GetActiveSettings();
|
||||
ViewModel.SchedulerSettings.StartDate = pIntervalStart;
|
||||
ViewModel.ActiveAppointmentViewModel = vm;
|
||||
|
||||
GefilterteMitarbeiter = ViewModel.ActiveAppointmentViewModel.AllEmployees;
|
||||
AllEmployees = ViewModel.ActiveAppointmentViewModel.AllEmployees;
|
||||
GefilterteKlienten = ViewModel.ActiveAppointmentViewModel.AllCustomers;
|
||||
AllCustomers = ViewModel.ActiveAppointmentViewModel.AllCustomers;
|
||||
ViewModel.SchedulerSettings = ViewModel.GetActiveSettings();
|
||||
ViewModel.SchedulerSettings.StartDate = pIntervalStart;
|
||||
|
||||
Category2ResourcesDictionary = ViewModel.ActiveAppointmentViewModel.Categories2Resources;
|
||||
GefilterteMitarbeiter = ViewModel.ActiveAppointmentViewModel.AllEmployees;
|
||||
AllEmployees = ViewModel.ActiveAppointmentViewModel.AllEmployees;
|
||||
GefilterteKlienten = ViewModel.ActiveAppointmentViewModel.AllCustomers;
|
||||
AllCustomers = ViewModel.ActiveAppointmentViewModel.AllCustomers;
|
||||
|
||||
SelectedEmployees = AllEmployees.Where(w => SelectedEmployees.Any(a => a.EmployeeOid.Equals(w.EmployeeOid))).ToList();
|
||||
SelectedCustomers = AllCustomers.Where(w => SelectedCustomers.Any(a => a.CustomerOid.Equals(w.CustomerOid))).ToList();
|
||||
SelectedResources = AllResources.Where(w => SelectedResources.Any(a => a.ResourceOid.Equals(w.ResourceOid))).ToList();
|
||||
Category2ResourcesDictionary = ViewModel.ActiveAppointmentViewModel.Categories2Resources;
|
||||
|
||||
var items = SelectedItems;
|
||||
SelectedEmployees = AllEmployees.Where(w => SelectedEmployees.Any(a => a.EmployeeOid.Equals(w.EmployeeOid))).ToList();
|
||||
SelectedCustomers = AllCustomers.Where(w => SelectedCustomers.Any(a => a.CustomerOid.Equals(w.CustomerOid))).ToList();
|
||||
SelectedResources = AllResources.Where(w => SelectedResources.Any(a => a.ResourceOid.Equals(w.ResourceOid))).ToList();
|
||||
|
||||
var testtesttest = ViewModel.ActiveAppointmentViewModel;
|
||||
var items = SelectedItems;
|
||||
|
||||
_ReloadingViewModel = false;
|
||||
var testtesttest = ViewModel.ActiveAppointmentViewModel;
|
||||
|
||||
Scheduler.Storage.RefreshData();
|
||||
Scheduler.Storage.RefreshUI();
|
||||
_ReloadingViewModel = false;
|
||||
|
||||
if (_IsComingFromHomeDragPanel && _SelectedAppointmentFromHomePanelView != null)
|
||||
{
|
||||
var apps = Scheduler.ActiveView.GetAppointments().ToList();
|
||||
Scheduler.Storage.RefreshData();
|
||||
Scheduler.Storage.RefreshUI();
|
||||
|
||||
var oid = _SelectedAppointmentFromHomePanelView.SchedulerAppointmentOid;
|
||||
Appointment appointmentToOpen;
|
||||
if(_IsComingFromHomeDragPanel && _SelectedAppointmentFromHomePanelView != null)
|
||||
{
|
||||
var apps = Scheduler.ActiveView.GetAppointments().ToList();
|
||||
|
||||
if (oid != null)
|
||||
{
|
||||
appointmentToOpen = apps.Find(app =>
|
||||
{
|
||||
var oidValue = app.CF_SchedulerAppointmentOid();
|
||||
var oid = _SelectedAppointmentFromHomePanelView.SchedulerAppointmentOid;
|
||||
Appointment appointmentToOpen;
|
||||
|
||||
return oidValue.HasValue && oidValue.Value == oid;
|
||||
});
|
||||
if(oid != null)
|
||||
{
|
||||
appointmentToOpen = apps.Find(app =>
|
||||
{
|
||||
var oidValue = app.CF_SchedulerAppointmentOid();
|
||||
|
||||
return oidValue.HasValue && oidValue.Value == oid;
|
||||
});
|
||||
|
||||
|
||||
if (appointmentToOpen != null)
|
||||
{
|
||||
Scheduler.ShowEditAppointmentForm(appointmentToOpen);
|
||||
}
|
||||
}
|
||||
else if (_SelectedAppointmentFromHomePanelView.RecurrenceId != null && _SelectedAppointmentFromHomePanelView.RecurrenceIndex > 0)
|
||||
{
|
||||
appointmentToOpen = apps.Find(appointment => appointment.RecurrenceInfo.Id.ToString().Equals(_SelectedAppointmentFromHomePanelView.RecurrenceId));
|
||||
if(appointmentToOpen != null)
|
||||
{
|
||||
Scheduler.ShowEditAppointmentForm(appointmentToOpen);
|
||||
}
|
||||
}
|
||||
else if(_SelectedAppointmentFromHomePanelView.RecurrenceId != null && _SelectedAppointmentFromHomePanelView.RecurrenceIndex > 0)
|
||||
{
|
||||
appointmentToOpen = apps.Find(appointment => appointment.RecurrenceInfo.Id.ToString().Equals(_SelectedAppointmentFromHomePanelView.RecurrenceId));
|
||||
|
||||
if (appointmentToOpen != null)
|
||||
{
|
||||
Scheduler.ShowEditAppointmentForm(appointmentToOpen);
|
||||
}
|
||||
}
|
||||
if(appointmentToOpen != null)
|
||||
{
|
||||
Scheduler.ShowEditAppointmentForm(appointmentToOpen);
|
||||
}
|
||||
}
|
||||
|
||||
_IsComingFromHomeDragPanel = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
_IsComingFromHomeDragPanel = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
_ReloadingViewModel = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1855,7 +1872,7 @@ namespace BeWo.Scheduler.View
|
||||
}
|
||||
}
|
||||
|
||||
void ExportAppointmentsAs_iCal(Stream stream)
|
||||
private void ExportAppointmentsAs_iCal(Stream stream)
|
||||
{
|
||||
if (stream == null)
|
||||
return;
|
||||
@@ -2385,8 +2402,7 @@ namespace BeWo.Scheduler.View
|
||||
var editedIsTask = editedAppointment.CF_IsTask();
|
||||
var editedEnd = editedAppointment.End;
|
||||
var editedDueDate = editedAppointment.CF_DueDate();
|
||||
|
||||
|
||||
|
||||
var sourceAppointment = e.SourceAppointment;
|
||||
|
||||
var sourceIsTask = sourceAppointment.CF_IsTask();
|
||||
@@ -2424,6 +2440,11 @@ namespace BeWo.Scheduler.View
|
||||
|
||||
WriteToDebug(sb.ToString());
|
||||
}
|
||||
|
||||
private void Scheduler_OnAppointmentDrop(object sender, AppointmentDragEventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#region Converter
|
||||
@@ -2503,6 +2524,12 @@ namespace BeWo.Scheduler.View
|
||||
try
|
||||
{
|
||||
var customFields = (CustomFieldCollection) value;
|
||||
|
||||
if(customFields == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
var customFieldStorage = (CustomFieldStorage) customFields[nameof(CustomFieldStorage)];
|
||||
|
||||
var mitarbeiter = customFieldStorage.EmployeeList;
|
||||
|
||||
@@ -57,11 +57,7 @@ namespace BeWo.Scheduler.ViewModel
|
||||
}
|
||||
}
|
||||
|
||||
private readonly List<CompactCustomerDC> _AllCustomers;
|
||||
private readonly List<CompactEmployeeDC> _AllEmployees;
|
||||
private readonly Dictionary<ValueListEntryDC, List<ResourceDC>> _Categories2Resources;
|
||||
|
||||
private static void AppointmentListAddingNew(object sender, AddingNewEventArgs e)
|
||||
private static void AppointmentListAddingNew(object sender, AddingNewEventArgs e)
|
||||
{
|
||||
var dc = new SchedulerAppointmentDC
|
||||
{
|
||||
@@ -79,19 +75,19 @@ namespace BeWo.Scheduler.ViewModel
|
||||
private Dictionary<Guid, Dictionary<string, Dictionary<string, object>>> _ChangedOccurenceCustomFields;
|
||||
public Dictionary<Guid, Dictionary<string, Dictionary<string, object>>> ChangedOccurenceCustomFields { get; }
|
||||
|
||||
public List<CompactCustomerDC> AllCustomers => _AllCustomers;
|
||||
public List<CompactCustomerDC> AllCustomers { get; }
|
||||
|
||||
public List<CompactEmployeeDC> AllEmployees => _AllEmployees;
|
||||
public List<CompactEmployeeDC> AllEmployees { get; }
|
||||
|
||||
public Dictionary<ValueListEntryDC, List<ResourceDC>> Categories2Resources => _Categories2Resources;
|
||||
public Dictionary<ValueListEntryDC, List<ResourceDC>> Categories2Resources { get; }
|
||||
|
||||
private Appointment _GeoeffneterTermin;
|
||||
private Appointment _GeoeffneterTermin;
|
||||
|
||||
public SchedulerAppointmentListVM(List<SchedulerAppointmentDC> appList, List<CompactCustomerDC> allCustomers, List<CompactEmployeeDC> allEmployees, Dictionary<ValueListEntryDC, List<ResourceDC>> lCategoriesToResources) : base(appList)
|
||||
{
|
||||
_Categories2Resources = lCategoriesToResources;
|
||||
_AllCustomers = allCustomers;
|
||||
_AllEmployees = allEmployees;
|
||||
Categories2Resources = lCategoriesToResources;
|
||||
AllCustomers = allCustomers;
|
||||
AllEmployees = allEmployees;
|
||||
|
||||
// TODO: Hier Rechte beachten!
|
||||
|
||||
@@ -150,7 +146,14 @@ namespace BeWo.Scheduler.ViewModel
|
||||
|
||||
UpdateSchedulerAppointment(item, vm);
|
||||
|
||||
if(vm.ResourceList.Any())
|
||||
var shouldSkipResourceAvailablityCheck = false;
|
||||
|
||||
if(_RecurrenceInfoId != null && item.RecurrenceInfo?.Id is Guid recurrenceId)
|
||||
{
|
||||
shouldSkipResourceAvailablityCheck = recurrenceId.Equals(_RecurrenceInfoId);
|
||||
}
|
||||
|
||||
if(vm.ResourceList.Any() && !shouldSkipResourceAvailablityCheck)
|
||||
{
|
||||
if(!CheckForUnavailableResources(vm))
|
||||
{
|
||||
@@ -158,7 +161,21 @@ namespace BeWo.Scheduler.ViewModel
|
||||
}
|
||||
}
|
||||
|
||||
if (!ShouldLockOverlappingAppointmentCheck && vm.EventType != 3 && !vm.IsTask)
|
||||
/*
|
||||
* EventTypes:
|
||||
* 0: Normal
|
||||
* 1: Pattern
|
||||
* 2: Occurrence
|
||||
* 3: ChangedOccurrence
|
||||
* 4: DeletedOccurrence
|
||||
*
|
||||
*
|
||||
*
|
||||
* Wozu ist das gut?
|
||||
* !ShouldLockOverlappingAppointmentCheck &&
|
||||
*/
|
||||
|
||||
if(!vm.IsTask && vm.EventType != 4 && !(vm.EventType == 3 && vm.DataContract?.SchedulerAppointmentOid == null))
|
||||
{
|
||||
var isOverlapping = false;
|
||||
|
||||
@@ -203,10 +220,13 @@ namespace BeWo.Scheduler.ViewModel
|
||||
var mostRecentAppointments = new List<SchedulerAppointmentDC>();
|
||||
ServiceFacade.DoResourceServiceSync(sync => mostRecentAppointments = sync.UpdateSchedulerAppointments(dcList));
|
||||
UpdateViewModel(mostRecentAppointments);
|
||||
_RecurrenceInfoId = null;
|
||||
control.ActiveView.LayoutChanged();
|
||||
NewSchedulerView.IgnoreChangeEvents = false;
|
||||
}
|
||||
|
||||
private Guid? _RecurrenceInfoId;
|
||||
|
||||
public void InsertAppointments(SchedulerControl control, IEnumerable<Appointment> list)
|
||||
{
|
||||
var dcList = new List<SchedulerAppointmentDC>();
|
||||
@@ -218,25 +238,25 @@ namespace BeWo.Scheduler.ViewModel
|
||||
{
|
||||
var dc = new SchedulerAppointmentDC
|
||||
{
|
||||
IsPrivate = item.CF_IsPrivate(),
|
||||
Subject = item.Subject,
|
||||
Description = item.Description,
|
||||
StartDate = item.Start,
|
||||
EndDate = item.End,
|
||||
Originator = item.CF_Originator(),
|
||||
LabelId = item.LabelId,
|
||||
AllDay = item.AllDay,
|
||||
Status = item.StatusId,
|
||||
Type = (int) item.Type,
|
||||
Location = item.Location,
|
||||
RecurrenceInfo = item.RecurrenceInfo.ToXml(),
|
||||
ReminderInfo = item.Reminder?.ToXml(),
|
||||
CustomerList = item.CF_CustomerList(),
|
||||
EmployeeList = item.CF_EmployeeList().ToList(),
|
||||
ResourceList = item.CF_ResourceList(),
|
||||
SupportConceptList = item.CF_SupportConceptList(),
|
||||
RecurrenceIndex = item.RecurrenceIndex,
|
||||
RecurrenceId = item.RecurrenceInfo.Id.ToString(),
|
||||
IsPrivate = item.CF_IsPrivate(),
|
||||
Subject = item.Subject,
|
||||
Description = item.Description,
|
||||
StartDate = item.Start,
|
||||
EndDate = item.End,
|
||||
Originator = item.CF_Originator(),
|
||||
LabelId = item.LabelId,
|
||||
AllDay = item.AllDay,
|
||||
Status = item.StatusId,
|
||||
Type = (int) item.Type,
|
||||
Location = item.Location,
|
||||
RecurrenceInfo = item.RecurrenceInfo.ToXml(),
|
||||
ReminderInfo = item.Reminder?.ToXml(),
|
||||
CustomerList = item.CF_CustomerList(),
|
||||
EmployeeList = item.CF_EmployeeList().ToList(),
|
||||
ResourceList = item.CF_ResourceList(),
|
||||
SupportConceptList = item.CF_SupportConceptList(),
|
||||
RecurrenceIndex = item.RecurrenceIndex,
|
||||
RecurrenceId = item.RecurrenceInfo.Id.ToString(),
|
||||
HasServiceRecordEntry = item.CF_HasServiceRecordEntry()
|
||||
};
|
||||
|
||||
@@ -247,7 +267,12 @@ namespace BeWo.Scheduler.ViewModel
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(item.RecurrenceInfo != null)
|
||||
{
|
||||
_RecurrenceInfoId = (Guid) item.RecurrenceInfo.Id;
|
||||
}
|
||||
|
||||
UpdateSchedulerAppointment(item, vm);
|
||||
|
||||
if(vm.ResourceList.Any())
|
||||
@@ -258,7 +283,7 @@ namespace BeWo.Scheduler.ViewModel
|
||||
}
|
||||
}
|
||||
|
||||
if (!ShouldLockOverlappingAppointmentCheck && !vm.IsTask)
|
||||
if (!ShouldLockOverlappingAppointmentCheck && !vm.IsTask && vm.EventType != 4)
|
||||
{
|
||||
var isOverlapping = false;
|
||||
ServiceFacade.DoResourceServiceSync(s => isOverlapping = s.OverlappingAppointmentsExist(
|
||||
@@ -384,7 +409,7 @@ namespace BeWo.Scheduler.ViewModel
|
||||
|
||||
if (!appointment.Type.Equals(AppointmentType.ChangedOccurrence))
|
||||
{
|
||||
return new SchedulerAppointmentEditForm(this, control, appointment, _AllEmployees, _AllCustomers, _Categories2Resources, isTask);
|
||||
return new SchedulerAppointmentEditForm(this, control, appointment, AllEmployees, AllCustomers, Categories2Resources, isTask);
|
||||
}
|
||||
|
||||
var index = appointment.RecurrenceIndex;
|
||||
@@ -402,7 +427,7 @@ namespace BeWo.Scheduler.ViewModel
|
||||
}
|
||||
}
|
||||
|
||||
return new SchedulerAppointmentEditForm(this, control, appointment, _AllEmployees, _AllCustomers, _Categories2Resources, isTask);
|
||||
return new SchedulerAppointmentEditForm(this, control, appointment, AllEmployees, AllCustomers, Categories2Resources, isTask);
|
||||
}
|
||||
|
||||
public void ApplyChangesToChangedOccurencyCustomFields(ObservableCollection<Employee2SchedulerAppointmentDC> employees, List<CompactCustomerDC> customers, List<ResourceDC> resources, CompactEmployeeDC originator, bool isPrivate, string index, Guid id, bool isTask, string taskDescription, DateTime? completedDate, DateTime? dueDate, string completedNotice, List<CompactSupportConceptDC> supportConcepts, string subject, bool isAllDay)
|
||||
@@ -524,8 +549,8 @@ namespace BeWo.Scheduler.ViewModel
|
||||
|
||||
var istEigen = ersteller.EmployeeOid.Equals(BeWoApp.LoggedOnEmployee.EmployeeOid);
|
||||
|
||||
var mVorhanden = appEList.Any(a2app => _AllEmployees.Contains(a2app.Employee));
|
||||
var kVorhanden = customerList.Any(_AllCustomers.Contains);
|
||||
var mVorhanden = appEList.Any(a2app => AllEmployees.Contains(a2app.Employee));
|
||||
var kVorhanden = customerList.Any(AllCustomers.Contains);
|
||||
|
||||
wirdAngezeigt = liste[0] && mVorhanden || liste[1] && resourceList.Any() || liste[2] && kVorhanden;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
|
||||
using BeWo.ViewModel;
|
||||
|
||||
using BS.Shared;
|
||||
using BS.Shared.DataContracts;
|
||||
using BS.Shared.DataContracts.Compact;
|
||||
|
||||
@@ -58,9 +58,10 @@ namespace BeWo.Scheduler.ViewModel
|
||||
private DateTime? _DueDate;
|
||||
private DateTime? _DueTime;
|
||||
private bool _HasServiceRecordEntry;
|
||||
private bool _IsArchived;
|
||||
|
||||
|
||||
public bool HasServiceRecordEntry
|
||||
public bool HasServiceRecordEntry
|
||||
{
|
||||
get => _HasServiceRecordEntry;
|
||||
set
|
||||
@@ -75,6 +76,21 @@ namespace BeWo.Scheduler.ViewModel
|
||||
}
|
||||
}
|
||||
|
||||
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; }
|
||||
|
||||
@@ -530,6 +546,15 @@ namespace BeWo.Scheduler.ViewModel
|
||||
}
|
||||
}
|
||||
|
||||
public Guid? RecurrenceId => BS.Shared.Core.Utils.GetRecurrenceIdFromRecurrenceInfo(RecurrenceInfo);
|
||||
|
||||
public int RecurrenceIndex {
|
||||
get
|
||||
{
|
||||
return BS.Shared.Core.Utils.GetRecurrenceIndexFromRecurrenceInfo(RecurrenceInfo);
|
||||
}
|
||||
}
|
||||
|
||||
public SchedulerAppointmentVM(SchedulerAppointmentDC pDC) : base(pDC, pDC.SchedulerAppointmentOid == null)
|
||||
{
|
||||
IsTeilnahmeBestaetigung = pDC.IsTeilnahmeBestaetigung;
|
||||
@@ -583,6 +608,8 @@ namespace BeWo.Scheduler.ViewModel
|
||||
_SupportConceptList = pDataContract.SupportConceptList ?? new List<CompactSupportConceptDC>();
|
||||
_HasServiceRecordEntry = pDataContract.HasServiceRecordEntry;
|
||||
|
||||
_IsArchived = pDataContract.ActivationType == ActivationTypeId.Archived;
|
||||
|
||||
|
||||
if(pDataContract.DueDate.HasValue)
|
||||
{
|
||||
@@ -613,7 +640,7 @@ namespace BeWo.Scheduler.ViewModel
|
||||
pDataContract.CompletedDate = _CompletedDate;
|
||||
pDataContract.SupportConceptList = _SupportConceptList;
|
||||
pDataContract.HasServiceRecordEntry = _HasServiceRecordEntry;
|
||||
|
||||
pDataContract.ActivationType = _IsArchived ? ActivationTypeId.Archived : ActivationTypeId.Active;
|
||||
|
||||
if(_DueDate.HasValue && _DueTime.HasValue)
|
||||
{
|
||||
@@ -679,7 +706,8 @@ namespace BeWo.Scheduler.ViewModel
|
||||
Equals(Location, obj.Location) &&
|
||||
ResourceList.AreEqual(obj.ResourceList) &&
|
||||
Equals(RecurrenceInfo, obj.RecurrenceInfo) &&
|
||||
HasServiceRecordEntry == obj.HasServiceRecordEntry;
|
||||
HasServiceRecordEntry == obj.HasServiceRecordEntry
|
||||
;
|
||||
|
||||
return areEqual;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@
|
||||
<IISExpressWindowsAuthentication />
|
||||
<IISExpressUseClassicPipelineMode />
|
||||
<UseGlobalApplicationHostFile />
|
||||
<LastActiveSolutionConfig>Release|Any CPU</LastActiveSolutionConfig>
|
||||
<LastActiveSolutionConfig>Debug|Any CPU</LastActiveSolutionConfig>
|
||||
<ProjectView>ShowAllFiles</ProjectView>
|
||||
<WebStackScaffolding_ViewDialogWidth>600</WebStackScaffolding_ViewDialogWidth>
|
||||
<Controller_SelectedScaffolderID>MvcControllerEmptyScaffolder</Controller_SelectedScaffolderID>
|
||||
|
||||
@@ -27,9 +27,12 @@ namespace BeWoPlanerMobil.Controllers
|
||||
{
|
||||
var loginState = MobileUtils.GetLoginState(MobileSessionFacade.Tenant);
|
||||
|
||||
#if DEBUG
|
||||
loginState = new BeWoLoginState(1, "Das ist nur ein Test");
|
||||
#endif
|
||||
|
||||
if (loginState.Message != null && loginState.State > -1)
|
||||
{
|
||||
|
||||
TempData[MobileUtils.TempDataLoginStateKey] = loginState;
|
||||
}
|
||||
|
||||
|
||||
@@ -628,27 +628,6 @@ namespace BeWoPlanerMobil.Controllers
|
||||
|
||||
Model.Textbausteine.AddRangeIfElementsNotIn(Utils.GetParentTextModules(Model.Textbausteine));
|
||||
|
||||
// TODO: Hier Html-erzeugen -> aufklappen, einklappen bzw. toggle in main.js implementieren
|
||||
/*
|
||||
* <div class="list-group">
|
||||
* <a href="#" class="list-group-item list-group-item-action">Mein Textbaustein I</a>
|
||||
* <a href="#" class="list-group-item list-group-item-action">
|
||||
* <span class="fas fa-angle-down"></span>
|
||||
* Mein Textbaustein I
|
||||
* </a>
|
||||
* <div class="list-group">
|
||||
* <a href="#" class="list-group-item list-group-item-action">Arztbesuch</a>
|
||||
* <a href="#" class="list-group-item list-group-item-action">Amtsbesuch</a>
|
||||
* <a href="#" class="list-group-item list-group-item-action">Einkaufen</a>
|
||||
* <a href="#" class="list-group-item list-group-item-action">
|
||||
* <span class="fas -fa-angle-up"></span>
|
||||
* Inoffiziell
|
||||
* </a>
|
||||
* </div>
|
||||
* </div>
|
||||
*/
|
||||
|
||||
//TextbausteinDisplayItem(string name, string text, List<TextbausteinDisplayItem> children, long? parentOid, long oid, bool isExpanded)
|
||||
var newItems = Model.Textbausteine.Where(tb => tb.TextModuleOid.HasValue).Select(tb => new TextbausteinDisplayItem(tb.Name, tb.Text, tb.Parent?.TextModuleOid, tb.TextModuleOid.Value, tb.IsExpanded)).ToList();
|
||||
|
||||
foreach(var item in newItems)
|
||||
@@ -660,35 +639,24 @@ namespace BeWoPlanerMobil.Controllers
|
||||
parent?.Children.AddIfNotIn(item);
|
||||
}
|
||||
}
|
||||
|
||||
var test = newItems.Where(item => item.ParentOid == null).ToList();
|
||||
|
||||
|
||||
|
||||
var displayItems = Model.Textbausteine.Select(s => new TextbausteinDisplayItem(s.Name, new List<string> {s.TextModuleOid.Value.ToString()}, s.Parent?.TextModuleOid, s.TextModuleOid.Value, s.IsParent)).ToList();
|
||||
|
||||
foreach(var item in displayItems)
|
||||
if(test.Count == 0)
|
||||
{
|
||||
if(item.ParentOid != null)
|
||||
{
|
||||
var parent = displayItems.FirstOrDefault(f => f.Oid == item.ParentOid);
|
||||
|
||||
if (parent != null)
|
||||
{
|
||||
if (parent.nodes == null)
|
||||
{
|
||||
parent.nodes = new List<TextbausteinDisplayItem>();
|
||||
}
|
||||
|
||||
parent.nodes.AddIfNotIn(item);
|
||||
}
|
||||
}
|
||||
return _LeerzeichenFuerGetMethoden;
|
||||
}
|
||||
|
||||
displayItems = displayItems.Where(w => w.ParentOid == null).OrderBy(t => t.Name).ToList();
|
||||
_TextModuleTreeHtml = "<div class=\"list-group\">";
|
||||
|
||||
return JsonConvert.SerializeObject(displayItems, Formatting.None, new JsonSerializerSettings
|
||||
foreach(var item in test)
|
||||
{
|
||||
NullValueHandling = NullValueHandling.Ignore
|
||||
});
|
||||
BuildTextModuleTreeBranch(item);
|
||||
}
|
||||
|
||||
_TextModuleTreeHtml += "</div>";
|
||||
|
||||
return _TextModuleTreeHtml;
|
||||
}
|
||||
catch(Exception exception)
|
||||
{
|
||||
@@ -697,6 +665,31 @@ namespace BeWoPlanerMobil.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
private string _TextModuleTreeHtml = "";
|
||||
|
||||
private void BuildTextModuleTreeBranch(TextbausteinDisplayItem textModuleItem)
|
||||
{
|
||||
if(textModuleItem.IsParent)
|
||||
{
|
||||
_TextModuleTreeHtml += $"<a href=\"#\" class=\"list-group-item list-group-item-action mx-0 px-1\" onclick=\"textCategoryOnClick('{textModuleItem.Oid}')\">" +
|
||||
$"<span id=\"{textModuleItem.Oid}-icon-span\" class=\"fas fa-angle-up mr-1\"></span>" +
|
||||
$"{textModuleItem.Name}" +
|
||||
"</a>" +
|
||||
$"<div id=\"{textModuleItem.Oid}-children-container\" style=\"display: none;\" class=\"list-group list-group-item mx-0 px-1\">";
|
||||
|
||||
foreach(var child in textModuleItem.Children)
|
||||
{
|
||||
BuildTextModuleTreeBranch(child);
|
||||
}
|
||||
|
||||
_TextModuleTreeHtml += "</div>";
|
||||
}
|
||||
else
|
||||
{
|
||||
_TextModuleTreeHtml += $"<a href=\"#\" id=\"{textModuleItem.Oid}\" class=\"list-group-item list-group-item-action mx-0 px-1\" onclick=\"textModuleOnClick('{textModuleItem.Oid}')\">{textModuleItem.Name}</a>";
|
||||
}
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
public string LoadCompleteTextbausteinByOid(long pTextbausteinOid)
|
||||
{
|
||||
@@ -936,6 +929,8 @@ namespace BeWoPlanerMobil.Controllers
|
||||
Log.Error(e.Message, e);
|
||||
}
|
||||
|
||||
ResetGroupBookingMode(true);
|
||||
|
||||
return ResetEditingMode(null);
|
||||
}
|
||||
|
||||
@@ -1579,6 +1574,16 @@ namespace BeWoPlanerMobil.Controllers
|
||||
var cb2ScOids = group.ServiceRecordList.Where(w => w.CostBearer2SupportConceptOid.HasValue).Select(s => s.CostBearer2SupportConceptOid.Value).ToList();
|
||||
|
||||
Model.SelectedConceptCostBearerRelations.AddRangeIfElementsNotIn(OperationsService.GetSupportConceptCostBearerRelDCsByOids(cb2ScOids));
|
||||
|
||||
var selectedSupportConcepts = new List<SupportConceptDC>();
|
||||
selectedSupportConcepts.AddRangeIfElementsNotIn(OperationsService.GetSupportConceptsById(group.ServiceRecordList.Select(s => s.SupportConcept.SupportConceptOid)));
|
||||
|
||||
// TODO: WARUM SIND DIE NICHT GLEICH?
|
||||
var first = selectedSupportConcepts[0];
|
||||
var second = selectedSupportConcepts[1];
|
||||
var areEqual = first.Equals(second);
|
||||
|
||||
Model.SelectedSupportConcepts = selectedSupportConcepts;
|
||||
}
|
||||
|
||||
return RedirectToActionPermanent("Main");
|
||||
@@ -2592,7 +2597,7 @@ namespace BeWoPlanerMobil.Controllers
|
||||
|
||||
if(Model.IsInGroupBookingMode && Model.SelectedSupportConcepts.Count > 1)
|
||||
{
|
||||
ResetGroupBookingMode(true);
|
||||
// ResetGroupBookingMode(true);
|
||||
|
||||
return SaveGroupBooking();
|
||||
}
|
||||
|
||||
@@ -230,6 +230,7 @@ function logColorfulMessage(message, color) {
|
||||
function isUndefinedOrNull(obj) {
|
||||
return obj == null;
|
||||
}
|
||||
|
||||
function areUndefinedOrNull(array) {
|
||||
if (array == null) {
|
||||
return true;
|
||||
|
||||
@@ -58,12 +58,7 @@ function loadServiceDescriptions() {
|
||||
}
|
||||
|
||||
$.get(getLoadTextbausteineForServiceCategoryUrl(), { pServiceCategoryOid: selectedCategoryOid }).done(function(result) {
|
||||
if(checkJson(result) === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
var test = $.parseJSON(result);
|
||||
if(test.length === 0) {
|
||||
if(result.length <= 2) {
|
||||
$("#textmodule-container").hide();
|
||||
|
||||
return;
|
||||
@@ -71,45 +66,47 @@ function loadServiceDescriptions() {
|
||||
|
||||
$("#textmodule-container").show();
|
||||
|
||||
$("#tree").treeview({
|
||||
data: result,
|
||||
onNodeSelected: function (event, data) {
|
||||
var tags = data.tags;
|
||||
$("#tree").html(result);
|
||||
|
||||
if (tags === undefined || tags === null || tags.length === 0) {
|
||||
return;
|
||||
}
|
||||
//$("#tree").treeview({
|
||||
// data: result,
|
||||
// onNodeSelected: function (event, data) {
|
||||
// var tags = data.tags;
|
||||
|
||||
var textbausteinOid = parseInt(tags[0], 10);
|
||||
var focusedDokuFeld;
|
||||
// if (tags === undefined || tags === null || tags.length === 0) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
$.get(getLoadCompleteTextbausteinByOidUrl(), { pTextbausteinOid: textbausteinOid }).done(function (textModuleText) {
|
||||
if ($("#dokufeld").length > 0) {
|
||||
focusedDokuFeld = $("#dokufeld");
|
||||
} else {
|
||||
var numberOfDokutypes = getNumberOfDokutypes();
|
||||
// var textbausteinOid = parseInt(tags[0], 10);
|
||||
// var focusedDokuFeld;
|
||||
|
||||
for (var i = 0; i < numberOfDokutypes; i++) {
|
||||
var currentElement = $("#doku_" + i);
|
||||
// $.get(getLoadCompleteTextbausteinByOidUrl(), { pTextbausteinOid: textbausteinOid }).done(function (textModuleText) {
|
||||
// if ($("#dokufeld").length > 0) {
|
||||
// focusedDokuFeld = $("#dokufeld");
|
||||
// } else {
|
||||
// var numberOfDokutypes = getNumberOfDokutypes();
|
||||
|
||||
if (currentElement.css("display") !== "none") {
|
||||
focusedDokuFeld = $("#doku-textarea-" + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// for (var i = 0; i < numberOfDokutypes; i++) {
|
||||
// var currentElement = $("#doku_" + i);
|
||||
|
||||
var cursorPosition = focusedDokuFeld.prop("selectionStart");
|
||||
var v = focusedDokuFeld.val();
|
||||
var textBefore = v.substring(0, cursorPosition);
|
||||
var textAfter = v.substring(cursorPosition, v.length);
|
||||
// if (currentElement.css("display") !== "none") {
|
||||
// focusedDokuFeld = $("#doku-textarea-" + i);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
focusedDokuFeld.val(textBefore + textModuleText + textAfter);
|
||||
// var cursorPosition = focusedDokuFeld.prop("selectionStart");
|
||||
// var v = focusedDokuFeld.val();
|
||||
// var textBefore = v.substring(0, cursorPosition);
|
||||
// var textAfter = v.substring(cursorPosition, v.length);
|
||||
|
||||
$("#textbausteine-popup").modal("hide");
|
||||
});
|
||||
}
|
||||
});
|
||||
// focusedDokuFeld.val(textBefore + textModuleText + textAfter);
|
||||
|
||||
// $("#textbausteine-popup").modal("hide");
|
||||
// });
|
||||
// }
|
||||
//});
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -626,4 +623,49 @@ function toggleHoursMinutesDropdownButton(element) {
|
||||
setInputFilter();
|
||||
|
||||
calculateDuration(true);
|
||||
}
|
||||
|
||||
function textCategoryOnClick(categoryId) {
|
||||
var childrenContainer = $("#" + categoryId + "-children-container");
|
||||
var iconSpan = $("#" + categoryId + "-icon-span");
|
||||
|
||||
var displayValue = childrenContainer.css("display");
|
||||
|
||||
var classToRemove = displayValue === "block" ? "fa-angle-down" : "fa-angle-up";
|
||||
var classToAdd = displayValue === "block" ? "fa-angle-up" : "fa-angle-down";
|
||||
|
||||
iconSpan.removeClass(classToRemove);
|
||||
iconSpan.addClass(classToAdd);
|
||||
|
||||
childrenContainer.toggle();
|
||||
}
|
||||
|
||||
function textModuleOnClick(textModuleOid) {
|
||||
var focusedDokuFeld;
|
||||
|
||||
$.get(getLoadCompleteTextbausteinByOidUrl(), { pTextbausteinOid: textModuleOid }).done(function(textModuleText) {
|
||||
if ($("#dokufeld").length > 0) {
|
||||
focusedDokuFeld = $("#dokufeld");
|
||||
} else {
|
||||
var numberOfDokutypes = getNumberOfDokutypes();
|
||||
|
||||
for (var i = 0; i < numberOfDokutypes; i++) {
|
||||
var currentElement = $("#doku_" + i);
|
||||
|
||||
if (currentElement.css("display") !== "none") {
|
||||
focusedDokuFeld = $("#doku-textarea-" + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var cursorPosition = focusedDokuFeld.prop("selectionStart");
|
||||
var v = focusedDokuFeld.val();
|
||||
var textBefore = v.substring(0, cursorPosition);
|
||||
var textAfter = v.substring(cursorPosition, v.length);
|
||||
|
||||
focusedDokuFeld.val(textBefore + textModuleText + textAfter);
|
||||
|
||||
$("#textbausteine-popup").modal("hide");
|
||||
});
|
||||
}
|
||||
@@ -354,8 +354,6 @@ namespace BeWoPlanerMobil.Util
|
||||
|
||||
public static BeWoLoginState GetLoginState(string tenant)
|
||||
{
|
||||
Debug.WriteLine($"GetLoginState {DateTime.Now:DD.MM.yyyy HH:mm:sss}");
|
||||
|
||||
var result = new BeWoLoginState(-1, null);
|
||||
|
||||
const string baseUrl = "https://support.bewoplaner.de/api";
|
||||
|
||||
@@ -1,51 +1,30 @@
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using System.Linq;
|
||||
|
||||
namespace BeWoPlanerMobil.Util
|
||||
{
|
||||
public class TextbausteinDisplayItem
|
||||
{
|
||||
public bool selectable { get; }
|
||||
|
||||
public string text { get; set; }
|
||||
|
||||
public List<TextbausteinDisplayItem> nodes { get; set; }
|
||||
|
||||
public List<string> tags { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public string Name { get; set; }
|
||||
[JsonIgnore]
|
||||
|
||||
public long Oid { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public long? ParentOid { get; set; }
|
||||
[JsonIgnore]
|
||||
public bool IsParent { get; set; }
|
||||
[JsonIgnore]
|
||||
|
||||
public bool IsParent => Children.Any();
|
||||
|
||||
public string Text { get; set; }
|
||||
|
||||
[JsonIgnore] public List<TextbausteinDisplayItem> Children { get; set; } = new List<TextbausteinDisplayItem>();
|
||||
public List<TextbausteinDisplayItem> Children { get; set; } = new List<TextbausteinDisplayItem>();
|
||||
|
||||
[JsonIgnore]
|
||||
public bool IsExpanded { get; set; }
|
||||
|
||||
public TextbausteinDisplayItem(string pText, List<string> pTags, long? pParentOid, long pOid, bool pIsParent)
|
||||
{
|
||||
text = pText;
|
||||
tags = pTags;
|
||||
ParentOid = pParentOid;
|
||||
Oid = pOid;
|
||||
selectable = !pIsParent;
|
||||
}
|
||||
|
||||
public TextbausteinDisplayItem(string name, string text, long? parentOid, long oid, bool isExpanded)
|
||||
{
|
||||
Name = name;
|
||||
Text = text;
|
||||
Oid = oid;
|
||||
IsExpanded = isExpanded;
|
||||
IsParent = parentOid != null;
|
||||
ParentOid = parentOid;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1301,36 +1301,26 @@ namespace BeWo.Data.Access
|
||||
return c.List<ApplicationUser>().Count > 0;
|
||||
}
|
||||
|
||||
// TODO: Ändert man einen Serientermin, wird ZWEIMAL eine Warnung angezeigt, dass sich der Termin mit einem anderen Termin überschneidet! Dieser Termin ist die Serie selbst!
|
||||
public bool OverlappingAppointmentsExist(DateTime start, DateTime end, IEnumerable<long> employees, IEnumerable<long> customers, IEnumerable<long> resources, long originator, long? appointmentOid, string recurrenceId = "", int occurrenceIndex = 0)
|
||||
{
|
||||
{
|
||||
var isRecurrenceException = appointmentOid == null;
|
||||
|
||||
Guid? recurrenceGuid = null;
|
||||
|
||||
if(Guid.TryParse(recurrenceId, out var parsedGuid))
|
||||
{
|
||||
recurrenceGuid = parsedGuid;
|
||||
}
|
||||
|
||||
var betweenDateTimesCriterion = CreateBetweenDateTimesCriterion(start, end, nameof(SchedulerAppointment.StartDate), nameof(SchedulerAppointment.EndDate));
|
||||
|
||||
var criteria = CreateCriteria<SchedulerAppointment>()
|
||||
.Add(Restrictions.Eq(nameof(BeWoEntityBase.IsActive), ActivationTypeId.Active))
|
||||
.Add(Restrictions.Eq(nameof(SchedulerAppointment.IsTask), false))
|
||||
.Add(Restrictions.Or(
|
||||
Restrictions.Or(
|
||||
Restrictions.And(
|
||||
Restrictions.Gt(SchedulerAppointment.PropertyName_EndDate, start),
|
||||
Restrictions.Lt(SchedulerAppointment.PropertyName_EndDate, end)
|
||||
),
|
||||
Restrictions.And(
|
||||
Restrictions.Gt(SchedulerAppointment.PropertyName_StartDate, start),
|
||||
Restrictions.Lt(SchedulerAppointment.PropertyName_StartDate, end)
|
||||
)
|
||||
),
|
||||
Restrictions.Or(
|
||||
Restrictions.And(
|
||||
Restrictions.Lt(SchedulerAppointment.PropertyName_StartDate, start),
|
||||
Restrictions.Gt(SchedulerAppointment.PropertyName_EndDate, start)
|
||||
),
|
||||
Restrictions.And(
|
||||
Restrictions.Eq(SchedulerAppointment.PropertyName_StartDate, start),
|
||||
Restrictions.Eq(SchedulerAppointment.PropertyName_EndDate, end)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
.Add(betweenDateTimesCriterion);
|
||||
|
||||
if (appointmentOid != null)
|
||||
if (isRecurrenceException == false)
|
||||
{
|
||||
criteria.Add(Restrictions.Not(Restrictions.Eq(BeWoEntityBase.PropertyName_Oid, appointmentOid)));
|
||||
}
|
||||
@@ -1344,11 +1334,9 @@ namespace BeWo.Data.Access
|
||||
return true;
|
||||
}
|
||||
|
||||
var recId = GetSpecificValueFromRecurrenceInfo(a.RecurrenceInfo, a.RecurrenceInfo.IndexOf("Id=\"") + 4);
|
||||
var index = GetSpecificValueFromRecurrenceInfo(a.RecurrenceInfo, a.RecurrenceInfo.IndexOf("Index=\"") + 7);
|
||||
int.TryParse(index, out var intIndex);
|
||||
var recId2 = a.GetRecurrenceIdAndIndex(out var index);
|
||||
|
||||
return !(recurrenceId.Equals(recId) && occurrenceIndex == intIndex);
|
||||
return !(Guid.TryParse(recurrenceId, out var guid) && guid.Equals(recId2) && occurrenceIndex == index);
|
||||
});
|
||||
|
||||
var schedulerAppointments = appointments as IList<SchedulerAppointment> ?? appointments.ToList();
|
||||
@@ -1357,8 +1345,7 @@ namespace BeWo.Data.Access
|
||||
var deletedOccurences = schedulerAppointments.Where(app => app.Type == 4).Select(app => Utils.GetOccurrenceId(app.RecurrenceInfo)).ToList();
|
||||
var changedOccurences = schedulerAppointments.Where(app => app.Type == 3).Select(app => Utils.GetOccurrenceId(app.RecurrenceInfo)).ToList();
|
||||
|
||||
var recurringAppointmentsCriteria = CreateRecurrenceCriteria(start, end)
|
||||
.Add(Restrictions.Eq(nameof(SchedulerAppointment.Type), 1));
|
||||
var recurringAppointmentsCriteria = CreateRecurrenceCriteria(start, end).Add(Restrictions.Eq(nameof(SchedulerAppointment.Type), 1));
|
||||
|
||||
var recurringAppointments = recurringAppointmentsCriteria.List<SchedulerAppointment>().ToList();
|
||||
|
||||
@@ -1381,9 +1368,9 @@ namespace BeWo.Data.Access
|
||||
var interval = new TimeInterval(start, end);
|
||||
|
||||
// Die Serientermine werden berechnet (ausnahmslos, d.h. es werden auch bearbeitete und gelöschte Termine erstellt, die herausgefiltert werden müssen).
|
||||
var occurences = occurenceCalculator.CalcOccurrences(interval, pattern);
|
||||
var occurrences = occurenceCalculator.CalcOccurrences(interval, pattern);
|
||||
|
||||
foreach(var occurence in occurences.GetAppointments(interval))
|
||||
foreach(var occurrence in occurrences.GetAppointments(interval))
|
||||
{
|
||||
if(appointment.EndDate == null || appointment.StartDate == null)
|
||||
{
|
||||
@@ -1391,35 +1378,82 @@ namespace BeWo.Data.Access
|
||||
}
|
||||
|
||||
// Terminindex in der Serie
|
||||
var index = occurence.RecurrenceIndex;
|
||||
var index = occurrence.RecurrenceIndex;
|
||||
|
||||
// Das Ende ist offen, da die Terminserie kein Ende hat. Deshalb wird das Ende berechnet.
|
||||
var duration = (appointment.EndDate.Value - appointment.StartDate.Value).TotalMinutes;
|
||||
|
||||
var guidParsingSuccessful = Guid.TryParse(occurrence.RecurrenceInfo?.Id?.ToString(), out var occurrenceGuid);
|
||||
|
||||
// Der generierte Serientermin muss sich zeitlich mit dem neuen Termin überschneiden
|
||||
// und darf nicht in der Liste der geänderten Serientermine oder der Liste der gelöschten Serientermine sein.
|
||||
if(!start.IsInInterval(end, occurence.Start, occurence.Start.AddMinutes(duration)) ||
|
||||
if(!start.IsInInterval(end, occurrence.Start, occurrence.Start.AddMinutes(duration)) ||
|
||||
changedOccurences.Any(changedOccurence => changedOccurence.PatternId.Equals(patternId) && changedOccurence.Index == index) ||
|
||||
deletedOccurences.Any(deletedOccurence => deletedOccurence.PatternId.Equals(patternId) && deletedOccurence.Index == index))
|
||||
deletedOccurences.Any(deletedOccurence => deletedOccurence.PatternId.Equals(patternId) && deletedOccurence.Index == index) ||
|
||||
index == occurrenceIndex && guidParsingSuccessful && recurrenceGuid.Equals(occurrenceGuid))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Prüfen, ob es eine Ausnahme an dem Tag gibt, die zu dem Pattern gehört, um das Pattern auszuschließen
|
||||
var relatedAppointments = FindAppointmentsByRecurrenceId(new List<string> {recurrenceInfo.Id.ToString()}, true);
|
||||
var relatedAppointmentsInInterval = relatedAppointments.Where(a =>
|
||||
{
|
||||
if(a.StartDate == null || a.EndDate == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var myStart = a.StartDate.Value.Date;
|
||||
var myEnd = a.EndDate.Value.Date;
|
||||
|
||||
var isInInterval = start.Date.InBetween(myStart.GetShortDateTime(), myEnd, true);
|
||||
|
||||
return isInInterval && a.Type != 4;
|
||||
}).ToList();
|
||||
|
||||
var hasToStop = false;
|
||||
// Indices und Ids der RecurrenceInfo vergleichen. Stimmen sie überein, dann wird das generiert Serienelement ignoriert.
|
||||
if(occurrence.RecurrenceInfo?.Id != null)
|
||||
{
|
||||
if(Guid.TryParse(occurrence.RecurrenceInfo.Id.ToString(), out var guid))
|
||||
{
|
||||
foreach(var relatedAppointment in relatedAppointmentsInInterval)
|
||||
{
|
||||
var relatedAppointmentRecurrenceId = relatedAppointment.GetRecurrenceIdAndIndex(out var relatedAppointmentRecurrenceIndex);
|
||||
|
||||
if(relatedAppointmentRecurrenceId != null)
|
||||
{
|
||||
if(guid.Equals(relatedAppointmentRecurrenceId) && relatedAppointmentRecurrenceIndex.Equals(occurrence.RecurrenceIndex))
|
||||
{
|
||||
hasToStop = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(hasToStop)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var recurringAppointment = new SchedulerAppointment
|
||||
{
|
||||
AllDay = occurence.AllDay,
|
||||
AllDay = occurrence.AllDay,
|
||||
CustomerList = appointment.CustomerList,
|
||||
Notice = appointment.Notice,
|
||||
EmployeeList = appointment.EmployeeList,
|
||||
EndDate = occurence.Start.AddMinutes(duration),
|
||||
EndDate = occurrence.Start.AddMinutes(duration),
|
||||
FormerBookingSequenceOid = appointment.FormerBookingSequenceOid,
|
||||
IsPrivate = appointment.IsPrivate,
|
||||
Location = appointment.Location,
|
||||
Originator = appointment.Originator,
|
||||
RecurrenceInfo = occurence.RecurrenceInfo.ToXml(),
|
||||
RecurrenceInfo = occurrence.RecurrenceInfo.ToXml(),
|
||||
ReminderInfo = appointment.ReminderInfo,
|
||||
ResourceList = appointment.ResourceList,
|
||||
StartDate = occurence.Start,
|
||||
StartDate = occurrence.Start,
|
||||
Subject = appointment.Subject ?? "",
|
||||
Type = appointment.Type
|
||||
};
|
||||
@@ -1429,58 +1463,94 @@ namespace BeWo.Data.Access
|
||||
}
|
||||
// --------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Falls es sich um eine Ausnahme einer Serie handelt, muss die Serie ignoriert werden
|
||||
var shouldIgnoreAppointment = false;
|
||||
if(isRecurrenceException && recurrenceId != null)
|
||||
{
|
||||
if(recurrenceGuid.HasValue)
|
||||
{
|
||||
shouldIgnoreAppointment = true;
|
||||
}
|
||||
}
|
||||
|
||||
var oidList = new List<long>();
|
||||
foreach (var appointment in schedulerAppointments)
|
||||
{
|
||||
|
||||
schedulerAppointments = schedulerAppointments.Where(appointment => appointment.Type != 4).ToList();
|
||||
|
||||
foreach (var appointment in schedulerAppointments)
|
||||
{
|
||||
if(shouldIgnoreAppointment)
|
||||
{
|
||||
if(!ShouldDoAppointmentOverlappingCheck(appointment, recurrenceGuid.Value))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
oidList.AddRange(appointment.EmployeeList.Select(rel => rel.ParticipationAnswer != ParticipationAnswer.Absage && rel.Employee.Oid != null ? rel.Employee.Oid.Value : 0));
|
||||
}
|
||||
|
||||
var hasOverlappingEmployeeAppointments = oidList.Intersect(employees).Any();
|
||||
var hasOverlappingCustomerAppointments = schedulerAppointments.Any(app => app.CustomerList.Select(c => c.Oid ?? 0).Intersect(customers).Any());
|
||||
var hasOverlappingResourceAppointments = schedulerAppointments.Any(app => app.ResourceList.Select(r => r.Oid ?? 0).Intersect(resources).Any());
|
||||
var hasOverlappingCustomerAppointments = schedulerAppointments.Any(app =>
|
||||
{
|
||||
return ShouldDoAppointmentOverlappingCheck(app, recurrenceGuid) && app.CustomerList.Select(c => c.Oid ?? 0).Intersect(customers).Any();
|
||||
});
|
||||
|
||||
var hasOverlappingOriginatorAppointments = schedulerAppointments.Any(appointment =>
|
||||
appointment.Originator.Oid.HasValue &&
|
||||
appointment.Originator.Oid.Value == originator &&
|
||||
(appointment.EmployeeList.Count == 0 || appointment.EmployeeList.Any(a => a.Employee.Oid.HasValue && a.Employee.Oid.Value == originator)));
|
||||
var hasOverlappingResourceAppointments = schedulerAppointments.Any(app =>
|
||||
{
|
||||
return ShouldDoAppointmentOverlappingCheck(app, recurrenceGuid) && app.ResourceList.Select(r => r.Oid ?? 0).Intersect(resources).Any();
|
||||
});
|
||||
|
||||
var hasOverlappingOriginatorAppointments = schedulerAppointments.Any(appointment =>
|
||||
{
|
||||
if(!ShouldDoAppointmentOverlappingCheck(appointment, recurrenceGuid))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return appointment.Originator.Oid.HasValue &&
|
||||
appointment.Originator.Oid.Value == originator &&
|
||||
(appointment.EmployeeList.Count == 0 || appointment.EmployeeList.Any(a => a.Employee.Oid.HasValue && a.Employee.Oid.Value == originator));
|
||||
});
|
||||
|
||||
return hasOverlappingEmployeeAppointments || hasOverlappingCustomerAppointments || hasOverlappingResourceAppointments || hasOverlappingOriginatorAppointments;
|
||||
}
|
||||
|
||||
private static bool ShouldDoAppointmentOverlappingCheck(SchedulerAppointment appointment, Guid? recurrenceId)
|
||||
{
|
||||
if(appointment.Oid.HasValue && recurrenceId.HasValue)
|
||||
{
|
||||
var recId = appointment.GetRecurrenceIdAndIndex(out var recIndex);
|
||||
|
||||
if(appointment.RecurrenceInfo != null && recId != null)
|
||||
{
|
||||
if(recId.Equals(recurrenceId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public IEnumerable<SchedulerAppointment> GetAllActiveAppointmentsForEmployeeInInterval(DateTime start, DateTime end, long pEmployeeOid)
|
||||
{
|
||||
var hasResources = $"{BeWoEntityBase.PropertyName_Oid} IN (SELECT newschappoid FROM resource2newschapp)";
|
||||
{
|
||||
var hasResources = $"{BeWoEntityBase.PropertyName_Oid} IN (SELECT newschappoid FROM resource2newschapp)";
|
||||
|
||||
var criteria = CreateRecurrenceCriteria(start, end)
|
||||
.Add(Restrictions.Or(
|
||||
Expression.Sql(new SqlString(hasResources)),
|
||||
CreateOwnAppointmentsCriteria(pEmployeeOid)));
|
||||
var criteria = CreateRecurrenceCriteria(start, end)
|
||||
.Add(Restrictions.Or(
|
||||
Expression.Sql(new SqlString(hasResources)),
|
||||
CreateOwnAppointmentsCriteria(pEmployeeOid)));
|
||||
|
||||
return criteria.List<SchedulerAppointment>();
|
||||
}
|
||||
return criteria.List<SchedulerAppointment>();
|
||||
}
|
||||
|
||||
public IEnumerable<SchedulerAppointment> GetAllActiveAppointmentsInInterval(DateTime start, DateTime end)
|
||||
public IEnumerable<SchedulerAppointment> GetAllActiveAppointmentsInInterval(DateTime start, DateTime end)
|
||||
{
|
||||
return CreateRecurrenceCriteria(start, end).List<SchedulerAppointment>();
|
||||
}
|
||||
|
||||
private static string GetSpecificValueFromRecurrenceInfo(string str, int startIndex)
|
||||
{
|
||||
var valueBuilder = new StringBuilder();
|
||||
|
||||
for (; startIndex < str.Length; startIndex++)
|
||||
{
|
||||
var cr = str[startIndex];
|
||||
|
||||
if (cr.Equals('"'))
|
||||
break;
|
||||
|
||||
valueBuilder.Append(cr);
|
||||
}
|
||||
|
||||
return valueBuilder.ToString();
|
||||
}
|
||||
|
||||
public ResourceBooking GetFirstResourceBookingFromSequence(long sequenceOid)
|
||||
{
|
||||
return CreateCriteria<ResourceBooking>()
|
||||
@@ -2839,6 +2909,20 @@ namespace BeWo.Data.Access
|
||||
return c.List<SchedulerAppointment>();
|
||||
}
|
||||
|
||||
public SchedulerAppointment FindRootAppointmentByRecurrenceId(string recurrenceId)
|
||||
{
|
||||
if(Guid.TryParse(recurrenceId, out var guid))
|
||||
{
|
||||
var criteria = CreateCriteria<SchedulerAppointment>()
|
||||
.Add(Restrictions.Like(nameof(SchedulerAppointment.RecurrenceInfo), recurrenceId, MatchMode.Anywhere))
|
||||
.Add(Restrictions.Eq(nameof(Appointment.Type), 1));
|
||||
|
||||
return criteria.List<SchedulerAppointment>().FirstOrDefault();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public IList<SchedulerAppointment> FindAppointmentsForCustomer(long pCustomerOid)
|
||||
{
|
||||
var blah = $"{BeWoEntityBase.PropertyName_Oid} IN (SELECT newschappoid FROM customer2newschapp WHERE customeroid IN ({pCustomerOid}))";
|
||||
@@ -3128,7 +3212,7 @@ namespace BeWo.Data.Access
|
||||
|
||||
private static AbstractCriterion CreateBetweenDateTimesCriterion(DateTime start, DateTime end, string propertyNameStart, string propertyNameEnd)
|
||||
{
|
||||
/*
|
||||
/* -- VERALTET ----- VERALTET ----- VERALTET ----- VERALTET ----- VERALTET ----- VERALTET ----- VERALTET ----- VERALTET --
|
||||
* Sql für Spalten namens 'StartDate' und 'EndDate':
|
||||
* WHERE
|
||||
* ((start >= StartDate AND end <= StartDate) OR (start <= StartDate AND end >= EndDate))
|
||||
@@ -3136,12 +3220,35 @@ namespace BeWo.Data.Access
|
||||
* ((start <= StartDate AND start >= EndDate) OR (start >= StartDate AND end <= EndDate))
|
||||
*/
|
||||
|
||||
var inBetween1 = Restrictions.And(Restrictions.Ge(propertyNameStart, start), Restrictions.Le(propertyNameStart, end));
|
||||
var inBetween2 = Restrictions.And(Restrictions.Le(propertyNameStart, start), Restrictions.Ge(propertyNameEnd, end));
|
||||
var inBetween3 = Restrictions.And(Restrictions.Le(propertyNameStart, start), Restrictions.Ge(propertyNameEnd, start));
|
||||
var inBetween4 = Restrictions.And(Restrictions.Ge(propertyNameStart, start), Restrictions.Le(propertyNameEnd, end));
|
||||
//var inBetween1 = Restrictions.And(Restrictions.Ge(propertyNameStart, start), Restrictions.Le(propertyNameStart, end));
|
||||
//var inBetween2 = Restrictions.And(Restrictions.Le(propertyNameStart, start), Restrictions.Ge(propertyNameEnd, end));
|
||||
//var inBetween3 = Restrictions.And(Restrictions.Le(propertyNameStart, start), Restrictions.Ge(propertyNameEnd, start));
|
||||
//var inBetween4 = Restrictions.And(Restrictions.Ge(propertyNameStart, start), Restrictions.Le(propertyNameEnd, end));
|
||||
|
||||
return Restrictions.Or(Restrictions.Or(inBetween1, inBetween2), Restrictions.Or(inBetween3, inBetween4));
|
||||
//return Restrictions.Or(Restrictions.Or(inBetween1, inBetween2), Restrictions.Or(inBetween3, inBetween4));
|
||||
// -- VERALTET ----- VERALTET ----- VERALTET ----- VERALTET ----- VERALTET ----- VERALTET ----- VERALTET ----- VERALTET --
|
||||
|
||||
// NEU -- NEU -- NEU -- NEU -- NEU -- NEU -- NEU -- NEU -- NEU -- NEU -- NEU -- NEU -- NEU -- NEU -- NEU -- NEU -- NEU
|
||||
/* Sql für Spalten namens 'StartDate' und 'EndDate':
|
||||
* (StartDate < '2020-11-19 10:00:00' AND EndDate <= '2020-11-19 12:00:00' AND EndDate > '2020-11-19 10:00:00')
|
||||
OR
|
||||
(StartDate < '2020-11-19 10:00:00' AND EndDate > '2020-11-19 12:00:00')
|
||||
OR
|
||||
(StartDate > '2020-11-19 10:00:00' AND StartDate < '2020-11-19 12:00:00')
|
||||
OR
|
||||
(StartDate = '2020-11-19 10:00:00' AND EndDate = '2020-11-19 12:00:00')
|
||||
OR
|
||||
(StartDate = '2020-11-19 10:00:00' AND EndDate >= '2020-11-19 12:00:00')
|
||||
*/
|
||||
// NEU -- NEU -- NEU -- NEU -- NEU -- NEU -- NEU -- NEU -- NEU -- NEU -- NEU -- NEU -- NEU -- NEU -- NEU -- NEU -- NEU
|
||||
|
||||
var inBetween1 = Restrictions.And(Restrictions.Lt(propertyNameStart, start), Restrictions.And(Restrictions.Le(propertyNameEnd, end), Restrictions.Gt(propertyNameEnd, start)));
|
||||
var inBetween2 = Restrictions.And(Restrictions.Lt(propertyNameStart, start), Restrictions.Gt(propertyNameEnd, end));
|
||||
var inBetween3 = Restrictions.And(Restrictions.Gt(propertyNameStart, start), Restrictions.Lt(propertyNameStart, end));
|
||||
var inBetween4 = Restrictions.And(Restrictions.Eq(propertyNameStart, start), Restrictions.Eq(propertyNameEnd, end));
|
||||
var inBetween5 = Restrictions.And(Restrictions.Eq(propertyNameStart, start), Restrictions.Le(propertyNameEnd, end));
|
||||
|
||||
return Restrictions.Or(inBetween1, Restrictions.Or(Restrictions.Or(inBetween2, inBetween3), Restrictions.Or(inBetween4, inBetween5)));
|
||||
}
|
||||
|
||||
public bool CheckForOverlappingAbsenceTimes(DateTime startDate, DateTime endDate, long? employeeOid, long? customerOid)
|
||||
@@ -3322,7 +3429,7 @@ namespace BeWo.Data.Access
|
||||
|
||||
var sql = "Oid IN " +
|
||||
"(SELECT resourceoid FROM resource2newschapp r2n WHERE r2n.newschappoid IN " +
|
||||
$"(SELECT oid FROM newschedulerappointment WHERE {excludingSelectedAppointment}('{start:yyyy-MM-dd HH:mm:ss}' > startdate OR '{end:yyyy-MM-dd HH:mm:ss}' > startdate) AND ('{start:yyyy-MM-dd HH:mm:ss}' < enddate OR '{end:yyyy-MM-dd HH:mm:ss}' < enddate)))";
|
||||
$"(SELECT oid FROM newschedulerappointment WHERE IsActive = 1 AND {excludingSelectedAppointment}('{start:yyyy-MM-dd HH:mm:ss}' > startdate OR '{end:yyyy-MM-dd HH:mm:ss}' > startdate) AND ('{start:yyyy-MM-dd HH:mm:ss}' < enddate OR '{end:yyyy-MM-dd HH:mm:ss}' < enddate)))";
|
||||
|
||||
var criterion = Expression.Sql(sql);
|
||||
|
||||
|
||||
@@ -241,9 +241,78 @@ namespace BeWo.Data.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public virtual Guid? GetRecurrenceIdAndIndex(out int index)
|
||||
{
|
||||
if(RecurrenceInfo != null)
|
||||
{
|
||||
var recurrenceId = BS.Shared.Core.Utils.GetSpecificValueFromRecurrenceInfo(RecurrenceInfo, RecurrenceInfo.IndexOf("Id=\"") + 4);
|
||||
var recurrenceIndex = BS.Shared.Core.Utils.GetSpecificValueFromRecurrenceInfo(RecurrenceInfo, RecurrenceInfo.IndexOf("Index=\"") + 7);
|
||||
|
||||
int.TryParse(recurrenceIndex, out index);
|
||||
|
||||
if(Guid.TryParse(recurrenceId, out var guid))
|
||||
{
|
||||
return guid;
|
||||
}
|
||||
}
|
||||
|
||||
index = -1;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual string GetAppointmentType()
|
||||
{
|
||||
switch(Type)
|
||||
{
|
||||
case 0:
|
||||
return "Normal";
|
||||
case 1:
|
||||
return "Pattern";
|
||||
case 2:
|
||||
return "Occurrence";
|
||||
case 3:
|
||||
return "Changed Occurrence";
|
||||
case 4:
|
||||
return "Deleted Occurrence";
|
||||
default:
|
||||
return "Normal";
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{StartDate?.ToString("dd.MM.yyyy HH:mm:ss")} - {EndDate?.ToString("dd.MM.yyyy HH:mm:ss")}: {Subject}";
|
||||
}
|
||||
|
||||
public virtual int? GetRecurrenceIndex()
|
||||
{
|
||||
if(RecurrenceInfo != null)
|
||||
{
|
||||
var indexString = BS.Shared.Core.Utils.GetSpecificValueFromRecurrenceInfo(RecurrenceInfo, RecurrenceInfo.IndexOf("Index=\\") + 7);
|
||||
|
||||
if(int.TryParse(indexString, out var index))
|
||||
{
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual Guid? GetRecurrenceId()
|
||||
{
|
||||
if(RecurrenceInfo != null)
|
||||
{
|
||||
var idString = BS.Shared.Core.Utils.GetSpecificValueFromRecurrenceInfo(RecurrenceInfo, RecurrenceInfo.IndexOf("Id=\"") + 4);
|
||||
|
||||
if(Guid.TryParse(idString, out var guid))
|
||||
{
|
||||
return guid;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,6 +52,8 @@ namespace BeWo.Service.DCEntityMapper
|
||||
pDataContract.Originator = MapperFactory.CompactEmployeeDC_Employee.MapToNewDC(pEntity.Originator);
|
||||
}
|
||||
|
||||
pDataContract.ActivationType = pEntity.IsActive;
|
||||
|
||||
return pDataContract;
|
||||
}
|
||||
|
||||
@@ -109,6 +111,8 @@ namespace BeWo.Service.DCEntityMapper
|
||||
throw new InternalException(e.Message);
|
||||
}
|
||||
|
||||
pEntity.IsActive = pDataContract.ActivationType;
|
||||
|
||||
return pEntity;
|
||||
}
|
||||
|
||||
|
||||
@@ -983,5 +983,9 @@ namespace BeWo.Service.ServiceContracts
|
||||
[FaultContract(typeof(BeWoFault))]
|
||||
[OperationContract]
|
||||
List<ConfirmationReceiptSignatureDC> FindConfirmationReceiptSignaturesByEmployeeAndServiceRecords(long employeeOid, IEnumerable<long> serviceRecordOids);
|
||||
|
||||
[FaultContract(typeof(BeWoFault))]
|
||||
[OperationContract]
|
||||
List<SupportConceptDC> GetSupportConceptsById(IEnumerable<long> supportConceptOids);
|
||||
}
|
||||
}
|
||||
@@ -204,5 +204,9 @@ namespace BeWo.Service.ServiceContracts
|
||||
[FaultContract(typeof(BeWoFault))]
|
||||
[OperationContract]
|
||||
List<ResourceDC> CheckResourceAvailability(DateTime start, DateTime end, List<long> resourceOids, long? selectedAppointmentOid);
|
||||
|
||||
[FaultContract(typeof(BeWoFault))]
|
||||
[OperationContract]
|
||||
SchedulerAppointmentDC FindRootAppointmentByRecurrenceId(string recurrenceId);
|
||||
}
|
||||
}
|
||||
@@ -6549,5 +6549,19 @@ namespace BeWo.Service.ServiceImplementations
|
||||
throw Utils.CreateBeWoFaultException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public List<SupportConceptDC> GetSupportConceptsById(IEnumerable<long> supportConceptOids)
|
||||
{
|
||||
try
|
||||
{
|
||||
var supportConcepts = DAOFactory.GenericDAO.LoadByIDs<SupportConcept>(supportConceptOids);
|
||||
|
||||
return MapperFactory.SupportConceptDC_SupportConcept.MapToNewDCs(supportConcepts);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
throw Utils.CreateBeWoFaultException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2249,5 +2249,12 @@ namespace BeWo.Service.ServiceImplementations
|
||||
{
|
||||
return MapperFactory.ResourceDC_Resource.MapToNewDCs(DAOFactory.SearchDAO.CheckAvailabilityOfResources(resourceOids, start, end, selectedAppointmentOid));
|
||||
}
|
||||
|
||||
public SchedulerAppointmentDC FindRootAppointmentByRecurrenceId(string recurrenceId)
|
||||
{
|
||||
var rootAppointment = DAOFactory.SearchDAO.FindRootAppointmentByRecurrenceId(recurrenceId);
|
||||
|
||||
return rootAppointment == null ? null : MapperFactory.SchedulerAppointmentDCSchedulerAppointment.MapToNewDC(rootAppointment);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -985,6 +985,111 @@ namespace BS.Shared.Core
|
||||
String saveFilename = filename.Replace("..", "").Replace("\"", "").Replace("/", "").Replace(":", "").Replace(";", "");
|
||||
return Path.Combine(tempPath, saveFilename);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Vergleicht die Elemente zweier Listen. Diese müssen vorher sortiert werden!
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Typ. Muss gleich sein</typeparam>
|
||||
/// <param name="a">Die erste Liste</param>
|
||||
/// <param name="b">Die Liste mit der die erste Liste verglichen wird</param>
|
||||
/// <returns>True, wenn die Elemente beider Listen gleich sind</returns>
|
||||
public static bool ListsEqual<T>(IEnumerable<T> a, IEnumerable<T> b)
|
||||
{
|
||||
if(a == null && b == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if(a == null || b == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var x = a.ToArray();
|
||||
var y = b.ToArray();
|
||||
|
||||
if(x.Length != y.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for(var i = 0; i < x.Length; i++)
|
||||
{
|
||||
var obj1 = x[i];
|
||||
var obj2 = y[i];
|
||||
|
||||
if(!Equals(obj1, obj2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static string GetSpecificValueFromRecurrenceInfo(string recurrenecInfoString, int startIndex)
|
||||
{
|
||||
var valueBuilder = new StringBuilder();
|
||||
|
||||
for(; startIndex < recurrenecInfoString.Length; startIndex++)
|
||||
{
|
||||
var cr = recurrenecInfoString[startIndex];
|
||||
|
||||
if(cr.Equals('"'))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
valueBuilder.Append(cr);
|
||||
}
|
||||
|
||||
return valueBuilder.ToString();
|
||||
}
|
||||
|
||||
public static Guid? GetRecurrenceIdFromRecurrenceInfo(string recurrenceInfo)
|
||||
{
|
||||
if(recurrenceInfo?.Length > 0)
|
||||
{
|
||||
var idString = GetSpecificValueFromRecurrenceInfo(recurrenceInfo, recurrenceInfo.IndexOf("Id=\"", StringComparison.InvariantCulture) + 4);
|
||||
|
||||
if(Guid.TryParse(idString, out var recurrenceId))
|
||||
{
|
||||
return recurrenceId;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int GetRecurrenceIndexFromRecurrenceInfo(string recurrenceInfo)
|
||||
{
|
||||
if(recurrenceInfo?.Length > 0)
|
||||
{
|
||||
var indexString = GetSpecificValueFromRecurrenceInfo(recurrenceInfo, recurrenceInfo.IndexOf("Index=\"", StringComparison.InvariantCulture) + 7);
|
||||
|
||||
if(int.TryParse(indexString, out var index))
|
||||
{
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static void WriteToTextFileOnDesktop(string fileName, string text)
|
||||
{
|
||||
#if DEBUG
|
||||
var path = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
|
||||
|
||||
using(var fileStream = new FileStream($"{path}/{fileName}", FileMode.Append, FileAccess.Write))
|
||||
{
|
||||
using(var streamWriter = new StreamWriter(fileStream))
|
||||
{
|
||||
streamWriter.WriteLine(text);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
public struct NullCompareResult
|
||||
|
||||
@@ -10,6 +10,9 @@ namespace BS.Shared.DataContracts
|
||||
[DataContract]
|
||||
public class SchedulerAppointmentDC : IDataContract
|
||||
{
|
||||
[DataMember]
|
||||
public ActivationTypeId ActivationType { get; set; }
|
||||
|
||||
[DataMember]
|
||||
public long? SchedulerAppointmentOid { get; set; }
|
||||
|
||||
|
||||
@@ -90,5 +90,52 @@ namespace BS.Shared.DataContracts
|
||||
|
||||
[DataMember]
|
||||
public Bewilligungsart Bewilligungsart { get; set; }
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if(obj is SupportConceptApprovalPeriodDC x)
|
||||
{
|
||||
var a = Equals(ApprovedBEInterval, x.ApprovedBEInterval);
|
||||
var b = Equals(ApprovedBEPerInterval, x.ApprovedBEPerInterval);
|
||||
var c = Equals(ContactCountInterval, x.ContactCountInterval);
|
||||
var d = Equals(ContactCountPerInterval, x.ContactCountPerInterval);
|
||||
var e = Equals(ApprovedBETotal, x.ApprovedBETotal);
|
||||
var f = Equals(ApprovedFixedAmount, x.ApprovedFixedAmount);
|
||||
var g = Equals(ApprovedFixedAmountInterval, x.ApprovedFixedAmountInterval);
|
||||
var h = Equals(EndDate, x.EndDate);
|
||||
var i = Equals(IsApprovedBEShifting, x.IsApprovedBEShifting);
|
||||
var j = Equals(IsApprovedFixedAmountShifting, x.IsApprovedFixedAmountShifting);
|
||||
var k = Equals(MonthlyPayment, x.MonthlyPayment);
|
||||
var l = Equals(Span, x.Span);
|
||||
var m = Equals(StartDate, x.StartDate);
|
||||
var n = Equals(Percentage, x.Percentage);
|
||||
var o = Equals(SupportConceptApprovalPeriodOid, x.SupportConceptApprovalPeriodOid);
|
||||
var p = Equals(SupportConceptApprovalPeriodVersion, x.SupportConceptApprovalPeriodVersion);
|
||||
var q = Equals(ServiceCategory, x.ServiceCategory);
|
||||
var r = Equals(BudgetDC, x.BudgetDC);
|
||||
var s = Utils.ListsEqual(SupportConceptApprovalPeriodEmployeeRelations, x.SupportConceptApprovalPeriodEmployeeRelations);
|
||||
var t = Equals(Bewilligungsart, x.Bewilligungsart);
|
||||
|
||||
return a && b && c && d && e && f && g && h && i && j && k && l && m && n && o && p && q && r && s && t;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
const int hashingBase = (int)2166136261;
|
||||
const int hashingMultiplier = 16777619;
|
||||
|
||||
var hash = hashingBase;
|
||||
|
||||
hash = (hash * hashingMultiplier) ^ (SupportConceptApprovalPeriodOid?.GetHashCode() ?? 0);
|
||||
hash = (hash * hashingMultiplier) ^ (SupportConceptApprovalPeriodVersion?.GetHashCode() ?? 0);
|
||||
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,5 +21,37 @@ namespace BS.Shared.DataContracts
|
||||
|
||||
[DataMember]
|
||||
public long? SupportConceptApprovalPeriod2EmployeeOid { get; set; }
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if(obj is SupportConceptApprovalPeriodEmployeeRelDC x)
|
||||
{
|
||||
var a = Employee?.Equals(x.Employee) ?? false;
|
||||
var b = Betreuungsschluessel == x.Betreuungsschluessel;
|
||||
var c = IsAbsolut == x.IsAbsolut;
|
||||
var d = SupportConceptApprovalPeriod2EmployeeVersion?.Equals(x.SupportConceptApprovalPeriod2EmployeeVersion) ?? false;
|
||||
var e = SupportConceptApprovalPeriod2EmployeeOid?.Equals(x.SupportConceptApprovalPeriod2EmployeeOid) ?? false;
|
||||
|
||||
return a && b && c && d && e;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
const int hashingBase = (int) 2166136261;
|
||||
const int hashingMultiplier = 16777619;
|
||||
|
||||
var hash = hashingBase;
|
||||
|
||||
hash = (hash * hashingMultiplier) ^ (SupportConceptApprovalPeriod2EmployeeOid?.GetHashCode() ?? 0);
|
||||
hash = (hash * hashingMultiplier) ^ (SupportConceptApprovalPeriod2EmployeeVersion?.GetHashCode() ?? 0);
|
||||
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
using BS.Shared.Core;
|
||||
using BS.Shared.DataContracts.Compact;
|
||||
|
||||
namespace BS.Shared.DataContracts
|
||||
@@ -96,5 +97,37 @@ namespace BS.Shared.DataContracts
|
||||
|
||||
[DataMember]
|
||||
public List<VarFieldDC> VarFields { get; set; }
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if(obj is SupportConceptDC sc)
|
||||
{
|
||||
var c = Equals(ActivationType, sc.ActivationType);
|
||||
var d = Equals(ApprovalDate, sc.ApprovalDate);
|
||||
var e = Equals(Conference, sc.Conference);
|
||||
var f = Equals(ConferenceDate, sc.ConferenceDate);
|
||||
var g = Equals(ConferenceVenue, sc.ConferenceVenue);
|
||||
var h = Equals(ConsultingNeeded, sc.ConsultingNeeded);
|
||||
var i = Utils.ListsEqual(CostBearerRelations.OrderBy(z => z.CostBearer2SupportConceptOid), sc.CostBearerRelations.OrderBy(z => z.CostBearer2SupportConceptOid));
|
||||
var k = Utils.ListsEqual(Ratings.OrderBy(z => z.RatingOid), sc.Ratings.OrderBy(z => z.RatingOid));
|
||||
var l = Equals(Customer, sc.Customer);
|
||||
var m = Equals(DocumentUploadLockedBy, sc.DocumentUploadLockedBy);
|
||||
var n = Equals(DocumentUploadLockedOn, sc.DocumentUploadLockedOn);
|
||||
var o = Utils.ListsEqual(Goals.OrderBy(z => z.ValueListEntryOid), sc.Goals.OrderBy(z => z.ValueListEntryOid));
|
||||
var p = Equals(Notice, sc.Notice);
|
||||
var q = Equals(Originator, sc.Originator);
|
||||
var r = Equals(RenewalSendDate, sc.RenewalSendDate);
|
||||
var s = Equals(RequisitionSendDate, sc.RequisitionSendDate);
|
||||
var t = Utils.ListsEqual(ServiceAccountings.OrderBy(z => z.ServiceAccountingOid), sc.ServiceAccountings.OrderBy(z => z.ServiceAccountingOid));
|
||||
var u = Utils.ListsEqual(VarFields.OrderBy(z => z.VarFieldDefOid), sc.VarFields.OrderBy(z => z.VarFieldDefOid));
|
||||
|
||||
var x = SupportConceptOid?.Equals(sc.SupportConceptOid) ?? false;
|
||||
var y = SupportConceptVersion?.Equals(sc.SupportConceptVersion) ?? false;
|
||||
|
||||
return c && d && e && f && g && h && i && k && l && m && n && o && p && q && r && s && t && u && x && y;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,5 +50,31 @@ namespace BS.Shared.DataContracts
|
||||
|
||||
[DataMember]
|
||||
public int YCoordinate { get; set; }
|
||||
|
||||
//public override bool Equals(object obj)
|
||||
//{
|
||||
// if(obj is VarFieldDC varField)
|
||||
// {
|
||||
// var a = Equals(ColumnSpan, varField.ColumnSpan);
|
||||
// var b = Equals(ControlType, varField.ControlType);
|
||||
// var c = Equals(DecimalPlaces, varField.DecimalPlaces);
|
||||
// var d = Equals(Group, varField.Group);
|
||||
// var e = Equals(Height, varField.Height);
|
||||
// var f = Equals(Label, varField.Label);
|
||||
// var g = Equals(PossibleItems, varField.PossibleItems);
|
||||
// var h = Equals(RowSpan, varField.RowSpan);
|
||||
// var i = Equals(VarFieldDefOid, varField.VarFieldDefOid);
|
||||
// var j = Equals(VarFieldValue, varField.VarFieldValue);
|
||||
// var k = Equals(VarFieldValueOid, varField.VarFieldValueOid);
|
||||
// var l = Equals(VarFieldValueVersion, varField.VarFieldValueVersion);
|
||||
// var m = Equals(Width, varField.Width);
|
||||
// var n = Equals(XCoordinate, varField.XCoordinate);
|
||||
// var o = Equals(YCoordinate, varField.YCoordinate);
|
||||
|
||||
// return a && b && c && d && e && f && g && h && i && j && k && l && m && n && o;
|
||||
// }
|
||||
|
||||
// return false;
|
||||
//}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user