NullPointerException bei Zusagen/Absagen von Serienterminen gefixt.
Terminanzeige im HomeView hat "In Zeiterfassung übertragen"-Icons
Terminanzeige Termine werden wie folgt dargestellt: [Datum]: [Betreff]

MoK:
Auswahl des Ladeintervalls der Zeiterfassungseinträge ist standardmäßig auf "Letzte 7 Tage" und die Änderung wird nur in der Session gespeichert.
Termine in die Zeiterfassung übertragen
This commit is contained in:
2023-03-03 21:54:36 +01:00
parent 1a265b641f
commit f99d674f8c
39 changed files with 975 additions and 344 deletions

View File

@@ -6,6 +6,7 @@ using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
@@ -794,6 +795,12 @@ namespace BeWo
RenderTier = RenderCapability.Tier >> 16;
// Die Sprache für alle Threads auf Deutsch stellen.
var cultureInfo = CultureInfo.CreateSpecificCulture("de-DE");
Thread.CurrentThread.CurrentUICulture = cultureInfo;
Thread.CurrentThread.CurrentCulture = cultureInfo;
CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;
base.OnStartup(e);
//AppDomain.CurrentDomain.UnhandledException += (s, ex) => ShowError(null, ex.ExceptionObject as Exception, true);

View File

@@ -13,6 +13,8 @@ namespace BeWo.Scheduler.Utils
{
public static class AppointmentExtensions
{
#region CustomField Getters
public static CustomFieldStorage GetCustomFieldStorage(this Appointment appointment)
{
return appointment.CustomFields[nameof(CustomFieldStorage)] as CustomFieldStorage;
@@ -37,7 +39,6 @@ namespace BeWo.Scheduler.Utils
{
return appointment.GetCustomFieldStorage()?.IsAllDay ?? false;
}
public static ObservableCollection<Employee2SchedulerAppointmentDC> CF_EmployeeList(this Appointment appointment)
{
@@ -116,6 +117,15 @@ namespace BeWo.Scheduler.Utils
return appointment.GetCustomFieldStorage()?.ServiceRecordList ?? new List<ServiceRecordDC>();
}
public static string CF_CompletedUser(this Appointment appointment)
{
return appointment.GetCustomFieldStorage()?.CompletedUser;
}
#endregion
#region CustomField Setters
public static void CF_IsTask(this Appointment appointment, bool pIsTask)
{
@@ -167,15 +177,11 @@ namespace BeWo.Scheduler.Utils
appointment.GetCustomFieldStorage().SupportConceptList = pSupportConceptList;
}
public static void CF_Originator(this Appointment appointment, CompactEmployeeDC pOriginator)
{
appointment.GetCustomFieldStorage().Originator = pOriginator;
}
public static void CF_DueDate(this Appointment appointment, DateTime? pDueDate)
{
appointment.GetCustomFieldStorage().DueDate = pDueDate;
@@ -205,5 +211,12 @@ namespace BeWo.Scheduler.Utils
{
appointment.GetCustomFieldStorage().ServiceRecordList = serviceRecords;
}
public static void CF_CompletedUser(this Appointment appointment, string completedUser)
{
appointment.GetCustomFieldStorage().CompletedUser = completedUser;
}
#endregion
}
}

View File

@@ -1246,7 +1246,7 @@ namespace BeWo.Scheduler.View
stringBuilder.AppendLine($"\tOid:\t\t{oid}\r\n\tBetreff: {appointment.Subject}\r\n\tStart:\t\t{start:dd.MM.yyyy HH:mm}\r\n\tEnde:\t\t{end:dd.MM.yyyy HH:mm}\r\n\tTyp:\t\t{type}\r\n");
}
BeWoApp.LogMessage($"DeleteAppointments aufgerufen. Es {(_AppointmentsToDelete.Count == 1 ? "wird" : "werden")} {_AppointmentsToDelete.Count} {(_AppointmentsToDelete.Count == 1 ? "Termin" : "Termine")} gelöscht\n{stringBuilder}", Colors.Red);
//BeWoApp.LogMessage($"DeleteAppointments aufgerufen. Es {(_AppointmentsToDelete.Count == 1 ? "wird" : "werden")} {_AppointmentsToDelete.Count} {(_AppointmentsToDelete.Count == 1 ? "Termin" : "Termine")} gelöscht\n{stringBuilder}", Colors.Red);
var idList = (from item in _AppointmentsToDelete where item.SchedulerAppointmentOid.HasValue && item.SchedulerAppointmentOid.Value > 0 select item.SchedulerAppointmentOid.Value).ToList();
@@ -1825,9 +1825,9 @@ namespace BeWo.Scheduler.View
ZusageAendern(ParticipationAnswer.Absage, Scheduler.SelectedAppointments[0]);
}
private void ZusageAendern(ParticipationAnswer antwort, Appointment sa)
private void ZusageAendern(ParticipationAnswer antwort, Appointment selectedAppointment)
{
var el = sa.CF_EmployeeList();
var el = selectedAppointment.CF_EmployeeList();
var neu = new ObservableCollection<Employee2SchedulerAppointmentDC>(el.DoForEach(dfe =>
{
if(!dfe.Employee.EmployeeOid.Equals(BeWoApp.LoggedOnEmployee.EmployeeOid))
@@ -1838,11 +1838,71 @@ namespace BeWo.Scheduler.View
dfe.ParticipationAnswer = antwort;
dfe.IsPC_CheckedTs = null;
}).ToList());
sa.CF_EmployeeList(neu);
selectedAppointment.CF_EmployeeList(neu);
var appointment = (SchedulerAppointmentVM) sa.GetSourceObject(Scheduler.GetCoreStorage());
// ToDo: Ausnahme erstellen und als abgesagt speichern
ServiceFacade.DoResourceServiceAsync(s => s.UpdateSchedulerAppointments(new List<SchedulerAppointmentDC> {appointment.CommitToDataContract()}), delegate { this.Dispatch(() => { ReloadVM(true); }); });
if(selectedAppointment.Type == AppointmentType.Occurrence)
{
var id = selectedAppointment.RecurrenceInfo.Id.ToString();
var index = selectedAppointment.RecurrenceIndex;
ServiceFacade.DoResourceServiceAsync(s => s.FindRootAppointmentByRecurrenceId(id), rootAppointment =>
{
this.Dispatch(() =>
{
var changedOccurrence = new SchedulerAppointmentDC
{
ActivationType = ActivationTypeId.Active,
AllDay = selectedAppointment.AllDay,
CanBeEdited = rootAppointment.CanBeEdited,
CompletedDate = selectedAppointment.CF_CompletedDate(),
CompletedNotice = selectedAppointment.CF_CompletedNotice(),
CompletedUser = selectedAppointment.CF_CompletedUser(),
CustomerList = selectedAppointment.CF_CustomerList() ?? new List<CompactCustomerDC>(),
Description = selectedAppointment.Description,
DueDate = selectedAppointment.CF_DueDate(),
EmployeeList = selectedAppointment.CF_EmployeeList()?.ToList() ?? new List<Employee2SchedulerAppointmentDC>(),
EndDate = selectedAppointment.End,
FormerBookingSequenceOid = rootAppointment.FormerBookingSequenceOid,
FormerTaskOid = rootAppointment.FormerTaskOid,
HasServiceRecordEntry = selectedAppointment.CF_HasServiceRecordEntry(),
IsPrivate = rootAppointment.IsPrivate,
IsTask = rootAppointment.IsTask,
IsTeilnahmeBestaetigung = rootAppointment.IsTeilnahmeBestaetigung,
LabelKey = rootAppointment.LabelKey,
Location = rootAppointment.Location,
Originator = selectedAppointment.CF_Originator() ?? BeWoApp.CompactLoggedOnEmployee,
RecurrenceInfo = $"<RecurrenceInfo Id=\"{id}\" Index=\"{index}\" />",
ReminderInfo = rootAppointment.ReminderInfo,
ResourceList = selectedAppointment.CF_ResourceList() ?? new List<ResourceDC>(),
ServiceRecordList = new List<ServiceRecordDC>(),
StartDate = selectedAppointment.Start,
Status = rootAppointment.Status,
Subject = selectedAppointment.Subject,
SupportConceptList = new List<CompactSupportConceptDC>(),
TaskDescription = rootAppointment.TaskDescription,
Type = (int) AppointmentType.ChangedOccurrence
};
ServiceFacade.DoResourceServiceAsync(s2 => s2.InsertSchedulerAppointments(new List<SchedulerAppointmentDC>{changedOccurrence}), () =>
{
this.Dispatch(() =>
{
ReloadVM(true);
});
});
});
});
}
else
{
var appointment = (SchedulerAppointmentVM)selectedAppointment.GetSourceObject(Scheduler.GetCoreStorage());
ServiceFacade.DoResourceServiceAsync(s => s.UpdateSchedulerAppointments(new List<SchedulerAppointmentDC> { appointment.CommitToDataContract() }), delegate { this.Dispatch(() => { ReloadVM(true); }); });
}
}
private void ZeiterfassungButtonItem_OnItemClick(object sender, ItemClickEventArgs e)
@@ -2315,7 +2375,9 @@ namespace BeWo.Scheduler.View
LabelKey = (long?) appointment.LabelKey,
Type = (int)appointment.Type,
Originator = basistermin.Originator,
RecurrenceInfo = appointment.RecurrenceInfo.ToXml()
RecurrenceInfo = appointment.RecurrenceInfo.ToXml(),
ServiceRecordList = basistermin.ServiceRecordList,
SupportConceptList = basistermin.SupportConceptList
});
}
}
@@ -2337,13 +2399,13 @@ namespace BeWo.Scheduler.View
if(sourceObject is SchedulerAppointmentVM vm)
{
mehrTaegigeTermine.Add(vm.CommitToDataContract());
BeWoApp.LogMessage($"{vm.Subject}: {vm.Start:dd.MM.yyyy HH:mm} - {vm.End:dd.MM.yyyy HH:mm}; {(AppointmentType) vm.EventType}", Colors.Green);
//BeWoApp.LogMessage($"{vm.Subject}: {vm.Start:dd.MM.yyyy HH:mm} - {vm.End:dd.MM.yyyy HH:mm}; {(AppointmentType) vm.EventType}", Colors.Green);
}
else
{
var occurrenceVM = new SchedulerAppointmentVM(app);
mehrTaegigeTermine.Add(occurrenceVM.CommitToDataContract());
BeWoApp.LogMessage($"{occurrenceVM.Subject}: {occurrenceVM.Start:dd.MM.yyyy HH:mm} - {occurrenceVM.End:dd.MM.yyyy HH:mm}; {(AppointmentType)occurrenceVM.EventType}", Colors.Purple);
//BeWoApp.LogMessage($"{occurrenceVM.Subject}: {occurrenceVM.Start:dd.MM.yyyy HH:mm} - {occurrenceVM.End:dd.MM.yyyy HH:mm}; {(AppointmentType)occurrenceVM.EventType}", Colors.Purple);
}
}
@@ -3001,18 +3063,18 @@ namespace BeWo.Scheduler.View
farbe = Color.FromRgb(59, 119, 153);
}
var aptCustomers = customFieldStorage.CustomerList;
var aptResources = customFieldStorage.ResourceList;
var appointmentCustomers = customFieldStorage.CustomerList;
var appointmentResources = customFieldStorage.ResourceList;
var gradientCollection = new GradientStopCollection();
var farbKollektion = new List<Color>();
if(selectedItems.Any(aptCustomers.Contains))
if(selectedItems.Any(appointmentCustomers.Contains))
{
farbKollektion.Add(Color.FromRgb(59, 119, 153));
}
if(selectedItems.Any(aptResources.Contains))
if(selectedItems.Any(appointmentResources.Contains))
{
farbKollektion.Add(Color.FromRgb(4, 180, 208));
}
@@ -3020,13 +3082,13 @@ namespace BeWo.Scheduler.View
switch(farbKollektion.Count)
{
case 1:
if (BeWoApp.AppSettings.ShowMultipleResourceColors)
if(BeWoApp.AppSettings.ShowMultipleResourceColors)
{
AddResourceColors(gradientCollection, aptResources, false);
AddResourceColors(gradientCollection, appointmentResources, appointmentCustomers.Any());
}
else
//else
{
var first = aptResources.FirstOrDefault();
var first = appointmentResources.FirstOrDefault();
gradientCollection.Add(first != null ? new GradientStop((Color)(ColorConverter.ConvertFromString(first.Color) ?? Color.FromRgb(4, 180, 208)), 1) : new GradientStop(farbKollektion[0], 1));
}
@@ -3039,11 +3101,11 @@ namespace BeWo.Scheduler.View
// 2. Resourcenfarben
if(BeWoApp.AppSettings.ShowMultipleResourceColors)
{
AddResourceColors(gradientCollection, aptResources, true);
AddResourceColors(gradientCollection, appointmentResources, true);
}
else
{
var first2 = aptResources.FirstOrDefault();
var first2 = appointmentResources.FirstOrDefault();
if (first2 != null)
{

View File

@@ -110,7 +110,8 @@ namespace BeWo.Scheduler.View
Originator = customFieldStorage.Originator,
IsTeilnahmeBestaetigung = true,
SupportConceptList = customFieldStorage.SupportConceptList,
ActivationType = dc.ActivationType
ActivationType = dc.ActivationType,
ServiceRecordList = customFieldStorage.ServiceRecordList
})
{
CustomFields = item.CustomFields, LabelKey = emp2AppOid

View File

@@ -495,8 +495,11 @@ namespace BeWo.Scheduler.View
ViewModel.ShouldLockOverlappingAppointmentCheck = Appointment.Type == AppointmentType.ChangedOccurrence;
if (Appointment.RecurrenceInfo != null)
{
ViewModel.ApplyChangesToChangedOccurencyCustomFields(employees, customers, resources, originator, isPrivate, Appointment.RecurrenceIndex.ToString(), new Guid(Appointment.RecurrenceInfo.Id.ToString()), isTask, taskDescription, completedDate, dueDate, completedNotice, supportConceptList, Appointment.Subject, Appointment.AllDay);
{
var customFieldStorage = Appointment.GetCustomFieldStorage();
var serviceRecords = customFieldStorage?.ServiceRecordList ?? new List<ServiceRecordDC>();
ViewModel.ApplyChangesToChangedOccurencyCustomFields(employees, customers, resources, originator, isPrivate, Appointment.RecurrenceIndex.ToString(), new Guid(Appointment.RecurrenceInfo.Id.ToString()), isTask, taskDescription, completedDate, dueDate, completedNotice, supportConceptList, Appointment.Subject, Appointment.AllDay, serviceRecords);
var oldRecurrenceInfo = Appointment.RecurrenceInfo.ToXml();
var newRecurrenceInfo = ViewModel.NewVM.RecurrenceInfo;

View File

@@ -132,6 +132,7 @@ namespace BeWo.Scheduler.ViewModel
CustomerList = pAppointment.CustomerList;
ResourceList = pAppointment.ResourceList;
SupportConceptList = pAppointment.SupportConceptList;
ServiceRecordList = pAppointment.ServiceRecordList;
DueDate = pAppointment.DueDate;
CompletedDate = pAppointment.CompletedDate;
@@ -151,7 +152,7 @@ namespace BeWo.Scheduler.ViewModel
CanBeEdited = pAppointment.CanBeEdited;
}
public CustomFieldStorage(ObservableCollection<Employee2SchedulerAppointmentDC> pEmployees, List<CompactCustomerDC> pCustomers, List<ResourceDC> pResources, CompactEmployeeDC pOriginator, bool pIsPrivate, bool pIsTask, string pTaskDescription, DateTime? pDueDate, DateTime? pCompletedDate, string pCompletedNotice, List<CompactSupportConceptDC> pSupportConcepts, string pSubject, bool pIsAllDay)
public CustomFieldStorage(ObservableCollection<Employee2SchedulerAppointmentDC> pEmployees, List<CompactCustomerDC> pCustomers, List<ResourceDC> pResources, CompactEmployeeDC pOriginator, bool pIsPrivate, bool pIsTask, string pTaskDescription, DateTime? pDueDate, DateTime? pCompletedDate, string pCompletedNotice, List<CompactSupportConceptDC> pSupportConcepts, string pSubject, bool pIsAllDay, List<ServiceRecordDC> serviceRecords)
{
IsTask = pIsTask;
IsPrivate = pIsPrivate;
@@ -160,7 +161,9 @@ namespace BeWo.Scheduler.ViewModel
EmployeeList = pEmployees;
CustomerList = pCustomers;
ResourceList = pResources;
SupportConceptList = pSupportConcepts;
ServiceRecordList = serviceRecords;
DueDate = pDueDate;
CompletedDate = pCompletedDate;

View File

@@ -75,10 +75,12 @@ namespace BeWo.Scheduler.ViewModel
{
var dc = new SchedulerAppointmentDC
{
EmployeeList = new List<Employee2SchedulerAppointmentDC>(),
CustomerList = new List<CompactCustomerDC>(),
ResourceList = new List<ResourceDC>(),
Status = 0
EmployeeList = new List<Employee2SchedulerAppointmentDC>(),
CustomerList = new List<CompactCustomerDC>(),
ResourceList = new List<ResourceDC>(),
ServiceRecordList = new List<ServiceRecordDC>(),
SupportConceptList = new List<CompactSupportConceptDC>(),
Status = 0
};
var neu = new SchedulerAppointmentVM(dc);
@@ -265,6 +267,7 @@ namespace BeWo.Scheduler.ViewModel
EmployeeList = item.CF_EmployeeList().ToList(),
ResourceList = item.CF_ResourceList(),
SupportConceptList = item.CF_SupportConceptList(),
ServiceRecordList = item.CF_ServiceRecordList(),
RecurrenceIndex = item.RecurrenceIndex,
RecurrenceId = item.RecurrenceInfo.Id.ToString(),
HasServiceRecordEntry = item.CF_HasServiceRecordEntry()
@@ -432,14 +435,14 @@ namespace BeWo.Scheduler.ViewModel
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)
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, List<ServiceRecordDC> serviceRecords)
{
if (!_ChangedOccurenceCustomFields.ContainsKey(id) || !_ChangedOccurenceCustomFields[id].ContainsKey(index))
{
return;
}
_ChangedOccurenceCustomFields[id][index][nameof(CustomFieldStorage)] = new CustomFieldStorage(employees, customers, resources, originator, isPrivate, isTask, taskDescription, dueDate, completedDate, completedNotice, supportConcepts, subject, isAllDay);
_ChangedOccurenceCustomFields[id][index][nameof(CustomFieldStorage)] = new CustomFieldStorage(employees, customers, resources, originator, isPrivate, isTask, taskDescription, dueDate, completedDate, completedNotice, supportConcepts, subject, isAllDay, serviceRecords);
}
public void AddCustomFieldsMapping(SchedulerStorage schedulerStorage)

View File

@@ -12,6 +12,7 @@
xmlns:dxp="http://schemas.devexpress.com/winfx/2008/xaml/printing"
xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars"
xmlns:dxpbars="http://schemas.devexpress.com/winfx/2008/xaml/printing/bars"
xmlns:converter="clr-namespace:BeWo.Scheduler.Converter"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Focusable="True">
<localView:BeWoView.Resources>
@@ -23,6 +24,8 @@
<localView:BorderHeightConverter x:Key="BorderHeightConverter" />
<localView:TaskAppointmentVisibilityConverter x:Key="TaskAppointmentVisibilityConverter" />
<localView:BorderCornerRadiusConverter x:Key="BorderCornerRadiusConverter" />
<localView:AptToServRecsIconVisibilityConverter x:Key="AptToServRecsIconVisibilityConverter" />
<localView:SubjectTextConverter x:Key="SubjectTextConverter" />
<ControlTemplate x:Key="HomeViewListBoxTemplate" TargetType="{x:Type ListBox}">
<Border x:Name="Bd" SnapsToDevicePixels="True" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}">
@@ -195,6 +198,7 @@
<Button Content="🠞" x:Name="TimeIntervalForwardsButton" Click="TimeIntervalForwardsButtonOnClick" />
</StackPanel>
<!-- ToDo: ServiceRecord-Icon einbauen -->
<ListBox Grid.Row="2" ScrollViewer.CanContentScroll="True" IsSynchronizedWithCurrentItem="True" x:Name="listboxTasks"
Margin="0,3,0,0" Padding="0,0,0,0" Width="Auto" HorizontalAlignment="Stretch" MinWidth="0"
HorizontalContentAlignment="Stretch" Style="{DynamicResource HomeViewListStyle}" ItemContainerStyle="{DynamicResource HomeViewListBoxItemStyle}"
@@ -231,11 +235,14 @@
<Separator Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Height="1" Background="DimGray" Visibility="{Binding Converter={StaticResource TaskAppointmentVisibilityConverter}, ConverterParameter=ToolTipTrennstrichVisibility}" />
<TextBlock Margin="0,0,3,0" Grid.Row="2" Grid.Column="0" Text="Ressourcen:" Visibility="{Binding Converter={StaticResource TaskAppointmentVisibilityConverter}, ConverterParameter=ToolTipResourcesVisibility}" />
<TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding Converter={StaticResource TaskAppointmentToolTipConverter}, ConverterParameter=Resources}"
Visibility="{Binding Converter={StaticResource TaskAppointmentVisibilityConverter}, ConverterParameter=ToolTipResourcesVisibility}" />
Visibility="{Binding Converter={StaticResource TaskAppointmentVisibilityConverter}, ConverterParameter=ToolTipResourcesVisibility}" />
<TextBlock Margin="0,0,3,0" Grid.Row="3" Grid.Column="0" Text="{t:Translate MitarbeiterSingular:}" Visibility="{Binding Converter={StaticResource TaskAppointmentVisibilityConverter}, ConverterParameter=ToolTipEmployeesVisibility}" />
<ListView Margin="-6,-3,0,0" Grid.Row="3" Background="Transparent" BorderThickness="0" ItemsSource="{Binding Converter={StaticResource TaskAppointmentToolTipConverter}, ConverterParameter=Employees}" Grid.Column="1" Visibility="{Binding Converter={StaticResource TaskAppointmentVisibilityConverter}, ConverterParameter=ToolTipEmployeesVisibility}" Name="ToolTipEmployeeList">
<ListView Margin="-6,-3,0,0" Grid.Row="3" Background="Transparent" BorderThickness="0" Grid.Column="1"
ItemsSource="{Binding Converter={StaticResource TaskAppointmentToolTipConverter}, ConverterParameter=Employees}"
Visibility="{Binding Converter={StaticResource TaskAppointmentVisibilityConverter}, ConverterParameter=ToolTipEmployeesVisibility}"
Name="ToolTipEmployeeList">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Width="{Binding (FrameworkElement.ActualWidth), RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}"
@@ -262,7 +269,7 @@
<TextBlock Margin="0,0,3,0" Grid.Row="4" Grid.Column="0" Text="{t:Translate Klienten:}"
Visibility="{Binding Converter={StaticResource TaskAppointmentVisibilityConverter}, ConverterParameter=ToolTipCustomersVisibility}" />
<TextBlock Grid.Row="4" Grid.Column="1" Text="{Binding Converter={StaticResource TaskAppointmentToolTipConverter}, ConverterParameter=Customers}"
Visibility="{Binding Converter={StaticResource TaskAppointmentVisibilityConverter}, ConverterParameter=ToolTipCustomersVisibility}" />
Visibility="{Binding Converter={StaticResource TaskAppointmentVisibilityConverter}, ConverterParameter=ToolTipCustomersVisibility}" />
</Grid>
</Grid.ToolTip>
<Grid.ColumnDefinitions>
@@ -273,13 +280,14 @@
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border x:Name="BackgroundColorBorder" CornerRadius="5" MinHeight="24"
Background="{Binding Converter={StaticResource TaskListItemBackgroundConverter}}" Grid.ColumnSpan="3"
Grid.Column="0" Margin="0,0,0,0" OpacityMask="{x:Null}" />
<Border CornerRadius="5,0,0,5" Grid.Row="0" Grid.Column="0" Background="{Binding Converter={StaticResource TaskListItemBackgroundConverter}, ConverterParameter=EmployeeBackgroundBrush}" MinHeight="24"
<!-- [Mitarbeiterfarbe] [Datum] [Betreff] [Icon] -->
<Border Grid.Column="0" Grid.ColumnSpan="3" x:Name="BackgroundColorBorder" CornerRadius="5" MinHeight="24"
Background="{Binding Converter={StaticResource TaskListItemBackgroundConverter}}"
Margin="0,0,0,0" OpacityMask="{x:Null}" />
<Border Grid.Column="0" Grid.Row="0" CornerRadius="5,0,0,5" Background="{Binding Converter={StaticResource TaskListItemBackgroundConverter}, ConverterParameter=EmployeeBackgroundBrush}" MinHeight="24"
VerticalAlignment="Center" Width="10" Margin="1" HorizontalAlignment="Left"
Visibility="{Binding Converter={StaticResource TaskAppointmentVisibilityConverter}, ConverterParameter=EmployeeBorderVisibility}" />
<Border x:Name="ItemBorder" CornerRadius="5" MinHeight="24" Background="#FF000000" Grid.ColumnSpan="3" Grid.Column="0" Margin="0,0,0,0">
<Border Grid.Column="0" Grid.ColumnSpan="3" x:Name="ItemBorder" CornerRadius="5" MinHeight="24" Background="#FF000000" Margin="0,0,0,0">
<Border.OpacityMask>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#19000000" Offset="0" />
@@ -287,7 +295,7 @@
</LinearGradientBrush>
</Border.OpacityMask>
</Border>
<Border CornerRadius="{Binding Converter={StaticResource BorderCornerRadiusConverter}, ConverterParameter=Resources}" Grid.Column="2" Grid.Row="0"
<Border Grid.Column="2" Grid.Row="0" CornerRadius="{Binding Converter={StaticResource BorderCornerRadiusConverter}, ConverterParameter=Resources}"
Background="{Binding Converter={StaticResource TaskListItemBackgroundConverter}, ConverterParameter=ResourceBackgroundBrush}" Width="10" VerticalAlignment="Bottom"
HorizontalAlignment="Right" Margin="1" MaxHeight="24"
Visibility="{Binding Converter={StaticResource TaskAppointmentVisibilityConverter}, ConverterParameter=ResourceBorderVisibility}">
@@ -298,7 +306,7 @@
</MultiBinding>
</Border.Height>
</Border>
<Border CornerRadius="{Binding Converter={StaticResource BorderCornerRadiusConverter}, ConverterParameter=Customers}" Grid.Column="2" Grid.Row="0"
<Border Grid.Column="2" Grid.Row="0" CornerRadius="{Binding Converter={StaticResource BorderCornerRadiusConverter}, ConverterParameter=Customers}"
Background="{Binding Converter={StaticResource TaskListItemBackgroundConverter}, ConverterParameter=CustomerBackgroundBrush}" Width="10" VerticalAlignment="Top"
HorizontalAlignment="Right" Margin="1" MaxHeight="24"
Visibility="{Binding Converter={StaticResource TaskAppointmentVisibilityConverter}, ConverterParameter=CustomerBorderVisibility}">
@@ -309,8 +317,25 @@
</MultiBinding>
</Border.Height>
</Border>
<TextBlock Margin="15, 5, 5, 5" FontSize="12" Foreground="{Binding Converter={StaticResource TaskListItemForegroundConverter}}" Grid.Column="0" Grid.Row="0" Text="{Binding Path=Subject}" />
<TextBlock Text="{Binding Converter={StaticResource TaskDateDescriptionConverter}}" Margin="5, 5, 15, 5" FontSize="12" Foreground="{Binding Converter={StaticResource TaskListItemForegroundConverter}}" Grid.Column="2" Grid.Row="0" />
<!--<TextBlock Grid.Column="0" Grid.Row="0" Margin="15, 5, 5, 5" FontSize="12" VerticalAlignment="Center"
Text="{Binding Converter={StaticResource TaskDateDescriptionConverter}}"
Foreground="{Binding Converter={StaticResource TaskListItemForegroundConverter}}"/>-->
<TextBlock Grid.Column="0" Grid.Row="0" Margin="15, 5, 5, 5" FontSize="12"
Foreground="{Binding Converter={StaticResource TaskListItemForegroundConverter}}"
Text="{Binding Converter={StaticResource SubjectTextConverter}}" />
<StackPanel Grid.Column="2" Grid.Row="0" Orientation="Horizontal" Margin="0,0,15,0" VerticalAlignment="Center">
<TextBlock Text="{Binding Converter={StaticResource TaskDateDescriptionConverter}}"
FontSize="12" VerticalAlignment="Center"
Foreground="{Binding Converter={StaticResource TaskListItemForegroundConverter}}" />
<Image SnapsToDevicePixels="True" Height="20" Width="20"
Source="/BeWoPlaner;component/Ressources/Icons/HistoryDisabled.png" Margin="0"
Visibility="{Binding Converter={StaticResource AptToServRecsIconVisibilityConverter}}" />
</StackPanel>
</Grid>
<DataTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">

View File

@@ -477,7 +477,7 @@ namespace BeWo.View
Login _login = new Login(kundennummer, "kihqx-PiGka", "cb", "bewo", "0b50c09aff87f20d9ced75340e04e5ccaa11dd3e7bcf25e9c4f94dc20d3cbb97");
_login = new Login("4368658436", "B7x0b-FhhJA", "jettenl", "n8-yR+3Q=6nX#", "0000");
//_login = new Login("4368658436", "B7x0b-FhhJA", "jettenl", "", "0000");
var x1 = _login.AnmeldevorgangDurchFuehren();
@@ -1591,7 +1591,8 @@ namespace BeWo.View
Status = patternAppointment.Status,
LabelKey = patternAppointment.LabelKey,
RecurrenceIndex = devExpressAppointment.RecurrenceIndex,
RecurrenceId = appointment.RecurrenceId
RecurrenceId = appointment.RecurrenceId,
ServiceRecordList = new List<ServiceRecordDC>()
};
_AllSchedulerTasks.Add(occurrence);
@@ -2120,28 +2121,29 @@ namespace BeWo.View
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is SchedulerAppointmentDC task)
if(value is SchedulerAppointmentDC task && task.IsTask)
{
if (task.CompletedDate.HasValue)
if(task.CompletedDate.HasValue)
{
return $"erledigt am: {task.CompletedDate:d}";
}
if (task.DueDate.HasValue && task.DueDate.Equals(DateTime.MaxValue))
if(task.DueDate.HasValue && task.DueDate.Equals(DateTime.MaxValue))
{
return string.Empty;
}
if (task.DueDate.HasValue)
if(task.DueDate.HasValue)
{
return string.Format("bis {0:d} {0:t}", task.DueDate);
}
if (task.StartDate.HasValue)
if(task.StartDate.HasValue)
{
return task.AllDay ? $"{task.StartDate:d}" : $"{task.StartDate:d} {task.StartDate:t}";
}
}
return string.Empty;
}
@@ -2366,5 +2368,41 @@ namespace BeWo.View
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) => throw new NotImplementedException();
}
public class AptToServRecsIconVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if(value is SchedulerAppointmentDC appointment)
{
return appointment.ServiceRecordList.Any() ? Visibility.Visible : Visibility.Collapsed;
}
return Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class SubjectTextConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if(value is SchedulerAppointmentDC appointment)
{
return appointment.IsTask ? appointment.Subject : $"{(appointment.AllDay ? $"{appointment.StartDate:d}" : $"{appointment.StartDate:d} {appointment.StartDate:t}")}: {appointment.Subject}";
}
return string.Empty;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
#endregion
}

View File

@@ -104,7 +104,7 @@ namespace BeWo.ownChat
//}
//Konstruktor für Kalender
public ChatDokumentationsView(string notice, CompactCustomerDC _compactCustomer, DateTime firstTime, DateTime lastTime, CompactEmployeeDC employee, Action<List<ServiceRecordDC>> schedulerCallback = null, Appointment appointment = null)
public ChatDokumentationsView(string notice, CompactCustomerDC _compactCustomer, DateTime startDate, DateTime endDate, CompactEmployeeDC employee, Action<List<ServiceRecordDC>> schedulerCallback = null, Appointment appointment = null)
{
InitializeComponent();
@@ -116,11 +116,17 @@ namespace BeWo.ownChat
vm => this.Dispatch(
delegate
{
if(appointment?.AllDay ?? false)
{
startDate = startDate.MergeDateWithHoursMinutesSeconds(0, 0, 1);
endDate = endDate.MergeDateWithHoursMinutesSeconds(0, 0, 1);
}
var serviceRecordEditView = new ServiceRecordEditView();
vm.DispatcherObject = this;
var dc = SupportConceptService.ErstelleServiceRecordDC(firstTime, lastTime, customerCompact, scList);
var dc = SupportConceptService.ErstelleServiceRecordDC(startDate, endDate, customerCompact, scList);
if(employee != null)
{
dc.Employee = employee;
@@ -211,7 +217,7 @@ namespace BeWo.ownChat
//GruppenBuchung Konstruktor für Kalender
public ChatDokumentationsView(string notice, DateTime firstTime, DateTime lastTime, List<CompactCustomerDC> _compactCustomer, List<CompactEmployeeDC> _compactEmployee, Action<List<ServiceRecordDC>> schedulerCallback = null, Appointment appointment = null)
public ChatDokumentationsView(string notice, DateTime startDate, DateTime endDate, List<CompactCustomerDC> _compactCustomer, List<CompactEmployeeDC> _compactEmployee, Action<List<ServiceRecordDC>> schedulerCallback = null, Appointment appointment = null)
{
InitializeComponent();
@@ -221,14 +227,20 @@ namespace BeWo.ownChat
vm => this.Dispatch(
delegate
{
if(appointment?.AllDay ?? false)
{
startDate = startDate.MergeDateWithHoursMinutesSeconds(0, 0, 1);
endDate = endDate.MergeDateWithHoursMinutesSeconds(0, 0, 1);
}
var newView = new ServiceRecordGroupEditView();
vm.DispatcherObject = this;
var serviceRecordGroup = new ServiceRecordGroupDC
{
StartDate = firstTime,
EndDate = lastTime,
StartDate = startDate,
EndDate = endDate,
CustomerCount = _compactCustomer.Count,
EmployeeCount = _compactEmployee.Count,
Notice = notice
@@ -240,17 +252,17 @@ namespace BeWo.ownChat
{
foreach(var cus in _compactCustomer)
{
var supportConcept = SupportConceptService.HoleHilfeplanAusListe(scList, cus, firstTime, lastTime);
var supportConcept = SupportConceptService.HoleHilfeplanAusListe(scList, cus, startDate, endDate);
if(supportConcept != null)
{
var serviceRecord = new ServiceRecordDC
{
Start = firstTime,
End = lastTime,
Start = startDate,
End = endDate,
Employee = emp,
Customer = cus,
SupportConcept = SupportConceptService.HoleHilfeplanAusListe(scList, cus, firstTime, lastTime),
SupportConcept = SupportConceptService.HoleHilfeplanAusListe(scList, cus, startDate, endDate),
GroupEmployeeCount = _compactEmployee.Count,
GroupPersonCount = _compactCustomer.Count
};

View File

@@ -65,15 +65,18 @@ namespace BeWo.ownChat
private void ChatMainControl_OnOnEmoji(Button emojiButton)
{
if (EmojiView == null)
if(EmojiView is null)
{
EmojiView = new ChatEmojiView(ChatMainControl);
var x = emojiButton.PointToScreen(new Point(0, 0));
var source = PresentationSource.FromVisual(emojiButton);
EmojiView.Top = x.Y / source.CompositionTarget.TransformToDevice.M22 - EmojiView.Height - 5;
EmojiView.Left = x.X / source.CompositionTarget.TransformToDevice.M11;
if(!(source is null))
{
EmojiView.Top = x.Y / source.CompositionTarget.TransformToDevice.M22 - EmojiView.Height - 5;
EmojiView.Left = x.X / source.CompositionTarget.TransformToDevice.M11;
}
EmojiView.Show();
}
@@ -86,8 +89,11 @@ namespace BeWo.ownChat
var x = emojiButton.PointToScreen(new Point(0, 0));
var source = PresentationSource.FromVisual(emojiButton);
EmojiView.Top = x.Y / source.CompositionTarget.TransformToDevice.M22 - EmojiView.Height - 5;
EmojiView.Left = x.X / source.CompositionTarget.TransformToDevice.M11;
if(!(source is null))
{
EmojiView.Top = x.Y / source.CompositionTarget.TransformToDevice.M22 - EmojiView.Height - 5;
EmojiView.Left = x.X / source.CompositionTarget.TransformToDevice.M11;
}
EmojiView.Show();
}
@@ -229,35 +235,42 @@ namespace BeWo.ownChat
{
var liste = ChatMainControl.GetContactsWithoutUnreadMessages();
if (liste.Count != 0)
if(liste.Count == 0)
{
var text = liste.Aggregate(string.Empty, (current, item) => current + item.GroupId + ";" + item.TimeStamp + ";" + "&");
ServiceFacade.DoEmployeeServiceSync(r => r.CreateOrUpdateChatBewoMessageSync(BeWoApp.LoggedOnUser.Employee.EmployeeOid,text));
return;
}
var text = liste.Aggregate(string.Empty, (current, item) => current + item.GroupId + ";" + item.TimeStamp + ";" + "&");
ServiceFacade.DoEmployeeServiceSync(r => r.CreateOrUpdateChatBewoMessageSync(BeWoApp.LoggedOnUser.Employee.EmployeeOid,text));
}
private void LadeMessageInfoAusDatenBank()
{
var item = ServiceFacade.DoEmployeeServiceSync(r => r.GetChatBewoMessageSync(BeWoApp.LoggedOnUser.Employee.EmployeeOid));
if (item != null)
{
var messageSynctext = item.MessageSyncText.Split('&');
var aa = new Dictionary<long, DateTime>();
foreach (var text in messageSynctext)
{
if (!string.IsNullOrEmpty(text)) {
var splitten = text.Split(';');
aa.Add(Convert.ToInt64(splitten[0]), DateTime.Parse(splitten[1]));
}
}
ChatMainControl.ResetNumberOfUnreadMessages(aa);
if(item is null)
{
return;
}
var messageSynctext = item.MessageSyncText.Split('&');
var aa = new Dictionary<long, DateTime>();
foreach (var text in messageSynctext)
{
if(string.IsNullOrEmpty(text))
{
continue;
}
var splitten = text.Split(';');
aa.Add(Convert.ToInt64(splitten[0]), DateTime.Parse(splitten[1]));
}
ChatMainControl.ResetNumberOfUnreadMessages(aa);
}
private void ChatView_OnClosing(object sender, CancelEventArgs e)

View File

@@ -17,7 +17,7 @@
<AssemblyName>BeWoPlanerMobil</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<MvcBuildViews>false</MvcBuildViews>
<UseIISExpress>true</UseIISExpress>
<UseIISExpress>false</UseIISExpress>
<IISExpressSSLPort />
<IISExpressAnonymousAuthentication />
<IISExpressWindowsAuthentication />
@@ -87,8 +87,8 @@
<Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll</HintPath>
</Reference>
<Reference Include="log4net, Version=2.0.13.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\packages\log4net.2.0.13\lib\net45\log4net.dll</HintPath>
<Reference Include="log4net, Version=2.0.15.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\packages\log4net.2.0.15\lib\net45\log4net.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=3.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.3.6.0\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll</HintPath>
@@ -818,9 +818,9 @@
<Content Include="Scripts\jquery-3.6.0.slim.js" />
<Content Include="Scripts\jquery-3.6.0.slim.min.js" />
<Content Include="Scripts\devexpress-scripts\knockout-3.5.1.js" />
<None Include="Scripts\jquery.validate-vsdoc.js" />
<Content Include="Scripts\jquery-ui-1.13.0.js" />
<Content Include="Scripts\jquery-ui-1.13.0.min.js" />
<None Include="Scripts\jquery.validate-vsdoc.js" />
<Content Include="Scripts\jquery.validate.js" />
<Content Include="Scripts\jquery.validate.min.js" />
<Content Include="Scripts\jquery.validate.unobtrusive.js" />
@@ -1591,7 +1591,7 @@
<AutoAssignPort>False</AutoAssignPort>
<DevelopmentServerPort>8808</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:8808/</IISUrl>
<IISUrl>http://localhost/BeWoPlanerMobil</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<UseIISExpress>true</UseIISExpress>
<UseIISExpress>false</UseIISExpress>
<Use64BitIISExpress>false</Use64BitIISExpress>
<IISExpressSSLPort />
<IISExpressAnonymousAuthentication />

View File

@@ -21,6 +21,8 @@ using BS.Shared.DataContracts;
using BS.Shared.DataContracts.Compact;
using BS.Shared.Extensions;
using BS.Shared.Services;
using DevExpress.XtraScheduler;
using DevExpress.XtraScheduler.Compatibility;
using Newtonsoft.Json;
using NHibernate.Criterion;
using static BS.Shared.ServiceRecordValidationResult;
@@ -254,7 +256,7 @@ namespace BeWoPlanerMobil.Controllers
{
Model.LastSelectedServiceRecordMonth = UserSettingsUtils.GetSettingValueAsDateTime(userSettings, SettingsKeys.LastSelectedServiceRecordMonth) ?? DateTime.Today;
var serviceRecordTimeInterval = MobileUserSettingsUtils.GetSettingValueAsEnum(userSettings, SettingsKeys.LastSelectedServiceRecordTimeInterval, ServiceRecordTimeInterval.LastWeek);
var serviceRecordTimeInterval = LoadServiceRecordTimeIntervalFromSession();
if(serviceRecordTimeInterval == ServiceRecordTimeInterval.ZeitraumWaehlen && (Model.SelectedZeitraum?.StartDate is null || Model.SelectedZeitraum.EndDate is null))
{
@@ -264,7 +266,7 @@ namespace BeWoPlanerMobil.Controllers
Model.LastSelectedServiceRecordTimeIntervalDays = UserSettingsUtils.GetSettingValueAsInteger(userSettings, SettingsKeys.LastSelectedServiceRecordTimeIntervalDays);
Model.ServiceRecordTimeInterval = serviceRecordTimeInterval;
Model.ServiceRecordTimeInterval = LoadServiceRecordTimeIntervalFromSession();
if(Model.ServiceRecordTimeInterval == ServiceRecordTimeInterval.Monatsauswahl)
{
@@ -274,6 +276,35 @@ namespace BeWoPlanerMobil.Controllers
CalculateSelectedDayCount(Model.LastSelectedServiceRecordTimeIntervalDays, Model.LastSelectedServiceRecordMonth, Model.SelectedZeitraum?.StartDate, Model.SelectedZeitraum?.EndDate);
}
[Authorize]
private void SaveServiceRecordTimeIntervalToSession(ServiceRecordTimeInterval serviceRecordTimeInterval)
{
if(Model is null)
{
return;
}
Session[SessionConstants.ServiceRecordTimeIntervalKey] = serviceRecordTimeInterval;
}
[Authorize]
private ServiceRecordTimeInterval LoadServiceRecordTimeIntervalFromSession()
{
if(Model is null)
{
return ServiceRecordTimeInterval.LastWeek;
}
if(Session[SessionConstants.ServiceRecordTimeIntervalKey] is ServiceRecordTimeInterval serviceRecordTimeInterval)
{
return serviceRecordTimeInterval;
}
SaveServiceRecordTimeIntervalToSession(ServiceRecordTimeInterval.LastWeek);
return ServiceRecordTimeInterval.LastWeek;
}
[Authorize]
public void LoadGoalRatings()
{
@@ -826,7 +857,7 @@ namespace BeWoPlanerMobil.Controllers
}
}
Model.TextModules = textModuleDisplayItems.Where(item => item.ParentOid is null).ToList(); ;
Model.TextModules = textModuleDisplayItems.Where(item => item.ParentOid is null).OrderBy(item => item.Name).ToList();
}
return PartialView("TextModulePartial", Model);
@@ -843,6 +874,13 @@ namespace BeWoPlanerMobil.Controllers
return Logout();
}
AppointmentListItem appointmentListItemPrototype = null;
if(TempData[TempDataConstants.AppointmentListItemKey] is AppointmentListItem appointmentListItem && Model.Employee.EmployeeOid.HasValue)
{
appointmentListItemPrototype = appointmentListItem;
}
string doku1;
if(Model.Dokutypes != null && Model.Dokutypes.Length > 0)
@@ -1047,7 +1085,56 @@ namespace BeWoPlanerMobil.Controllers
if(Model.NewServiceRecord.CostBearer != null && Model.ShowSignature)
{
TempData[FormCollectionConstants.ShowSignatureSuggestionPopup] = true;
TempData[TempDataConstants.ShowSignatureSuggestionPopup] = true;
}
if(!(appointmentListItemPrototype is null))
{
var appointment = appointmentListItemPrototype.SchedulerAppointment;
var isRecurring = !(appointment.RecurrenceInfo is null);
if(isRecurring && appointment.Type != (int) AppointmentType.ChangedOccurrence)
{
var id = appointment.RecurrenceIdReference;
var recurrenceInfo = new RecurrenceInfo();
recurrenceInfo.FromXml(appointment.RecurrenceInfo);
var occurrenceCalculator = OccurrenceCalculator.CreateInstance(recurrenceInfo);
var pattern = StaticAppointmentFactory.CreateAppointment(AppointmentType.Pattern);
pattern.RecurrenceInfo.FromXml(appointment.RecurrenceInfo);
pattern.Start = pattern.RecurrenceInfo.Start;
pattern.End = pattern.RecurrenceInfo.End;
var occurrence = occurrenceCalculator.CalcOccurrences(new TimeInterval(appointment.StartDate.Value, appointment.EndDate.Value), pattern).FirstOrDefault();
if(!(occurrence is null))
{
var index = occurrence.RecurrenceIndex;
appointment = SchedulerController.CloneAppointment(appointment, $"<RecurrenceInfo Id=\"{id}\" Index=\"{index}\" />", (int)AppointmentType.ChangedOccurrence);
}
else
{
appointment = null;
}
}
if(!(appointment is null))
{
var serviceRecord = OperationsService.GetServiceRecordById(Model.ServiceRecordOid);
appointment.ServiceRecordList.AddIfNotIn(serviceRecord);
if(appointment.SchedulerAppointmentOid.HasValue)
{
KalenderService.UpdateSchedulerAppointments(new List<SchedulerAppointmentDC> { appointment });
}
else
{
KalenderService.InsertSchedulerAppointments(new List<SchedulerAppointmentDC> { appointment });
}
}
}
}
else
@@ -1132,7 +1219,18 @@ namespace BeWoPlanerMobil.Controllers
groupDC.RoundedDuration = Model.NewServiceRecord.GroupRoundedDuration.Value;
}
OperationsService.InsertNewServiceRecordGroup(groupDC);
groupDC = OperationsService.InsertNewServiceRecordGroup(groupDC);
var serviceRecords = groupDC.ServiceRecordList;
if(TempData["AppointmentListItem"] is AppointmentListItem appointmentListItem && Model.Employee.EmployeeOid.HasValue)
{
var appointment = appointmentListItem.SchedulerAppointment;
appointment.ServiceRecordList.AddRange(serviceRecords);
KalenderService.UpdateSchedulerAppointments(new List<SchedulerAppointmentDC> { appointment });
}
}
}
@@ -1701,7 +1799,7 @@ namespace BeWoPlanerMobil.Controllers
CalculateSelectedDayCount(dayCountNumber, lastSelectedServiceRecordMonth, parsedVon, parsedBis);
UpdateUserSettingsWithoutReload(SettingsKeys.LastSelectedServiceRecordTimeInterval, ((int) serviceRecordTimeInterval).ToString());
SaveServiceRecordTimeIntervalToSession(serviceRecordTimeInterval);
LoadRecordsToModel();
@@ -2417,6 +2515,9 @@ namespace BeWoPlanerMobil.Controllers
return Logout();
}
TempData[TempDataConstants.IsInTransferModeKey] = null;
TempData[TempDataConstants.AppointmentListItemKey] = null;
var bookingMode = "true,false" == pFormCollection[FormCollectionConstants.IsInGroupBookingModeKey] ? BookingMode.GroupBookingMode : BookingMode.SingleBookingMode;
ResetBookingMode(bookingMode);
@@ -2441,6 +2542,8 @@ namespace BeWoPlanerMobil.Controllers
Model.IsInGroupBookingMode = bookingMode == BookingMode.GroupBookingMode;
Model.IsInMultiBookingMode = bookingMode == BookingMode.MultiBookingMode;
ResetModel();
if(bookingMode == BookingMode.GroupBookingMode)
{
ResetMultiBookingMode();
@@ -2533,21 +2636,51 @@ namespace BeWoPlanerMobil.Controllers
[Authorize]
public ActionResult ResetEditingMode()
{
if (Model is null)
if(Model is null)
{
return Logout();
}
Model.NewServiceRecord = new ServiceRecordDC();
Model.SelectedServiceRecord = null;
Model.IsInEditingMode = false;
ResetModel();
return RedirectToActionPermanent("Main");
}
[Authorize]
[HttpPost]
public ActionResult ResetTransferMode()
{
if(Model is null)
{
return Logout();
}
ResetModel();
return RedirectToScheduler();
}
[Authorize]
private void ResetModel()
{
if(Model is null)
{
return;
}
TempData[TempDataConstants.AppointmentListItemKey] = null;
TempData[TempDataConstants.IsInTransferModeKey] = null;
Model.NewServiceRecord = new ServiceRecordDC();
Model.SelectedServiceRecord = null;
Model.IsInEditingMode = false;
Model.GroupBookingSelectedSupportConcepts.Clear();
Model.SelectedConceptCostBearerRelations.Clear();
Model.GroupBookingSelectedCostbearerRelOids.Clear();
Model.GroupBookingSelectedGroupOfPeopleOids.Clear();
Model.GroupBookingSelectedEmployees = new List<CompactEmployeeDC> { MobileSessionFacade.LoggedInCompactEmployee };
Model.SelectedEmployee = MobileSessionFacade.LoggedInCompactEmployee;
Model.IsInMultiBookingMode = false;
Model.GroupBookingSelectedEmployees = new List<CompactEmployeeDC> { MobileSessionFacade.LoggedInCompactEmployee };
Model.SelectedEmployee = MobileSessionFacade.LoggedInCompactEmployee;
Model.IsInMultiBookingMode = false;
Model.MultiBookingSelectedCostbearerRelOids.Clear();
Model.MultiBookingSelectedEmployees.Clear();
Model.MultiBookingSelectedConceptCostBearerRelations.Clear();
@@ -2559,17 +2692,17 @@ namespace BeWoPlanerMobil.Controllers
var serviceDescriptions = Model.GetServiceDesctiptions();
if(Model.ServiceCategories.Any() && serviceDescriptions.Any())
if(!Model.ServiceCategories.Any() || !serviceDescriptions.Any())
{
var firstServiceDescription = serviceDescriptions.First();
Model.SelectedServiceDescriptionOid = firstServiceDescription.ServiceDescriptionOid;
Model.SelectedServiceCategoryOid = firstServiceDescription.Category.ServiceCategoryOid;
return;
}
return RedirectToActionPermanent("Main");
var firstServiceDescription = serviceDescriptions.First();
Model.SelectedServiceDescriptionOid = firstServiceDescription.ServiceDescriptionOid;
Model.SelectedServiceCategoryOid = firstServiceDescription.Category.ServiceCategoryOid;
}
[Authorize]
public string AddSupportConceptCostBearerRelationsToGroupBooking(string pRelOids, string pGroupOids)
{
@@ -3024,23 +3157,30 @@ namespace BeWoPlanerMobil.Controllers
return Logout();
}
// Nach dem Speichern das SchedulerAppointmentDC-Objekt updaten!
if(TempData["AppointmentListItem"] is AppointmentListItem appointmentListItem && Model.Employee.EmployeeOid.HasValue)
if(TempData[TempDataConstants.AppointmentListItemKey] is AppointmentListItem appointmentListItem && Model.Employee.EmployeeOid.HasValue)
{
TempData[TempDataConstants.IsInTransferModeKey] = true;
var appointment = appointmentListItem.SchedulerAppointment;
var start = appointment.StartDate;
var end = appointment.EndDate;
var customerOids = appointment.CustomerList.Select(customer => customer.CustomerOid).ToList();
var employeeOids = appointment.EmployeeList.Select(e2a => e2a.Employee.EmployeeOid).ToList();
var notice = appointment.Description;
if(start is null || end is null)
if(appointment.AllDay && start.HasValue && end.HasValue)
{
// ToDo: Fehler anzeigen!
return View("Main", Model);
start = start.Value.MergeDateWithHoursMinutesSeconds(0, 0, 1);
end = end.Value.MergeDateWithHoursMinutesSeconds(0, 0, 1);
}
if(employeeOids.Count == 0)
{
employeeOids.Add(Model.Employee.EmployeeOid.Value);
}
var notice = appointment.Description;
var customerService = PluginLoader.FindClass<CustomerService>();
var supportConcepts = customerService.GetAllActiveSupportConceptCostbearer(false, true, Model.Employee.EmployeeOid.Value);
supportConcepts = supportConcepts.Where(sc => customerOids.Contains(sc.Customer.CustomerOid) && sc.StartDate.HasValue && sc.EndDate.HasValue && start.Value.AreInBetweenDates(end.Value, sc.StartDate.Value, sc.EndDate.Value)).ToList();
@@ -3059,12 +3199,11 @@ namespace BeWoPlanerMobil.Controllers
supportConceptList.AddIfNotIn(supportConcept);
}
// ToDo: Hier weitermachen: Update des Termins durchführen. In TempData speichern/belassen und beim Speichern dann Updaten?
// Ohne Hilfeplan
if(supportConceptList.Count == 0)
{
Model.IsInGroupBookingMode = false;
ResetBookingMode(BookingMode.SingleBookingMode);
Model.SelectedEmployee = Model.AllEmployees.FirstOrDefault(e => e.EmployeeOid.Equals(Model.Employee.EmployeeOid.Value));
LoadSupportConceptThings(-2);
@@ -3081,30 +3220,77 @@ namespace BeWoPlanerMobil.Controllers
}
}
// Einzelbuchung
else if(supportConceptList.Count == 1 && employeeOids.Count == 1)
{
Model.IsInGroupBookingMode = false;
Model.SelectedEmployee = Model.AllEmployees.FirstOrDefault(e => e.EmployeeOid.Equals(Model.Employee.EmployeeOid.Value));
ResetBookingMode(BookingMode.SingleBookingMode);
Model.SelectedEmployee = Model.AllEmployees.FirstOrDefault(e => e.EmployeeOid.Equals(employeeOids.FirstOrDefault()));
// ToDo: Beim Wählen des CostBearers den nehmen, der aktiv ist?
var compactSupportConcept = supportConceptList.First();
var supportConcept = Model.SupportConcepts.FirstOrDefault(f => f.SupportConceptOid.HasValue && f.SupportConceptOid.Value.Equals(compactSupportConcept.SupportConceptOid));
var serviceRecord = CreateServiceRecordFromScratch(start.Value, end.Value, supportConcept?.Customer, Model.SelectedEmployee, notice);
var costBearer2SupportConcept = supportConcept.CostBearerRelations.FirstOrDefault();
var costBearer2SupportConcept = supportConcept?.CostBearerRelations.FirstOrDefault();
Model.SelectedServiceRecord = serviceRecord;
LoadSupportConceptThings(costBearer2SupportConcept?.CostBearer2SupportConceptOid ?? -2);
var serviceCategory = Model.ServiceCategories.FirstOrDefault();
var serviceDescription = serviceCategory?.ServiceDescriptions.FirstOrDefault();
serviceRecord.CostBearer = costBearer2SupportConcept?.CostBearer;
serviceRecord.CostBearer2SupportConceptOid = costBearer2SupportConcept?.CostBearer2SupportConceptOid;
serviceRecord.ServiceDescription = serviceDescription;
if(!(serviceDescription is null))
{
Model.SelectedServiceRecord = serviceRecord;
}
}
// Gruppenbuchung
else
else // Gruppenbuchung
{
Model.IsInGroupBookingMode = true;
ResetBookingMode(BookingMode.GroupBookingMode);
Model.GroupBookingSelectedEmployees = Model.AllEmployees.Where(w => employeeOids.Contains(w.EmployeeOid)).ToList();
var roundedDuration = (int)((end - start)?.TotalMinutes ?? 0);
Model.SelectedServiceRecord = new ServiceRecordDC()
{
Start = start,
End = end,
RoundedDuration = roundedDuration,
Notice = notice,
ServiceDescription = Model.ServiceCategories.FirstOrDefault()?.ServiceDescriptions.FirstOrDefault()
};
var supportConceptsForGroupBooking = Model.SupportConcepts.Where(sc => sc.SupportConceptOid.HasValue && supportConceptList.Any(csc => csc.SupportConceptOid.Equals(sc.SupportConceptOid.Value))).ToList();
var costBearer2SupportConceptOids = new List<long>();
var costBearer2SupportConcepts = new List<SupportConceptCostBearerRelDC>();
foreach(var supportConcept in supportConceptsForGroupBooking)
{
var costBearer2SupportConcept = supportConcept.CostBearerRelations.FirstOrDefault();
if(costBearer2SupportConcept?.CostBearer2SupportConceptOid is null)
{
continue;
}
costBearer2SupportConceptOids.AddIfNotIn(costBearer2SupportConcept.CostBearer2SupportConceptOid.Value);
costBearer2SupportConcepts.AddIfNotIn(costBearer2SupportConcept);
}
if(costBearer2SupportConceptOids.Any())
{
Model.GroupBookingSelectedCostbearerRelOids = costBearer2SupportConceptOids;
Model.SelectedConceptCostBearerRelations = costBearer2SupportConcepts;
Model.GroupBookingSelectedSupportConcepts = supportConceptsForGroupBooking;
}
}
TempData[TempDataConstants.AppointmentListItemKey] = appointmentListItem;
}
return View("Main", Model);

View File

@@ -165,7 +165,7 @@ namespace BeWoPlanerMobil.Controllers
Model.Appointments = holySweetFlyingFuck.Where(w => w.IsTask == Model.ShouldLoadTasks).OrderBy(appointment => appointment.StartDate).ToList();
Model.WeekViewObject = new WeekViewObject(Model.Appointments, Model.SelectedDate.GetInSameCalendarWeek(DayOfWeek.Monday));
Model.WeekViewObject = new WeekViewObject(Model.Appointments, Model.SelectedDate.GetInSameCalendarWeek(DayOfWeek.Monday), Model.Employee);
if(AbstractModel.HasRightToViewCustomerSelectionInScheduler)
{
@@ -203,7 +203,7 @@ namespace BeWoPlanerMobil.Controllers
foreach(var app in occurrences.GetAppointments(interval))
{
var index = app.RecurrenceIndex;
var duration = (appointment.EndDate.Value - appointment.StartDate.Value).TotalMinutes;
var isOutOfInterval = app.Start.GetShortDateTime().AreInBetweenDates(app.Start.AddMinutes(duration), start, end) == false;
@@ -228,11 +228,14 @@ namespace BeWoPlanerMobil.Controllers
Location = appointment.Location,
Originator = appointment.Originator,
RecurrenceInfo = app.RecurrenceInfo.ToXml(),
RecurrenceIndex = index,
ReminderInfo = appointment.ReminderInfo,
ResourceList = appointment.ResourceList,
StartDate = app.Start,
Subject = appointment.Subject ?? "",
Type = appointment.Type
Type = (int) app.Type,
ServiceRecordList = appointment.ServiceRecordList,
SupportConceptList = appointment.SupportConceptList
};
result.AddIfNotIn(recurringAppointment);
@@ -257,7 +260,7 @@ namespace BeWoPlanerMobil.Controllers
{
if(Model is null)
{
Logout();
return Logout();
}
var rawStartDate = formCollection[FormCollectionConstants.AppointmentStartDateKey];
@@ -268,8 +271,8 @@ namespace BeWoPlanerMobil.Controllers
var location = formCollection[FormCollectionConstants.AppointmentLocationKey];
var notice = formCollection[FormCollectionConstants.AppointmentNoticeKey];
var isPrivate = formCollection[FormCollectionConstants.AppointmentIsPrivate] == "true,false";
var allDay = formCollection[FormCollectionConstants.AppointmentIsAllDay] == "true,false";
var isPrivate = formCollection[FormCollectionConstants.AppointmentIsPrivateKey] == "true,false";
var allDay = formCollection[FormCollectionConstants.AppointmentIsAllDayKey] == "true,false";
var isSuccessfulStartTime = DateTime.TryParseExact(rawStartTime, "HH:mm", null, DateTimeStyles.None, out var startTime);
var isSuccessfulEndTime = DateTime.TryParseExact(rawEndTime, "HH:mm", null, DateTimeStyles.None, out var endTime);
@@ -376,7 +379,7 @@ namespace BeWoPlanerMobil.Controllers
{
if (Model is null)
{
Logout();
return Logout();
}
Model.SelectedDate = Model.SelectedDate.AddDays(-1);
@@ -396,7 +399,7 @@ namespace BeWoPlanerMobil.Controllers
{
if(Model is null)
{
Logout();
return Logout();
}
Model.SelectedDate = Model.SelectedDate.AddDays(1);
@@ -413,9 +416,9 @@ namespace BeWoPlanerMobil.Controllers
[Authorize]
[HttpPost]
public ActionResult SelectSchedulerDate(FormCollection formCollection) {
if (Model is null)
if(Model is null)
{
Logout();
return Logout();
}
var rawSchedulerDate = formCollection[FormCollectionConstants.AppointmentSchedulerDateKey];
@@ -424,11 +427,8 @@ namespace BeWoPlanerMobil.Controllers
Model.SelectedDate = schedulerDate;
if(Model != null)
{
Model.SelectedAppointment = null;
Model.SelectedResources.Clear();
}
Model.SelectedAppointment = null;
Model.SelectedResources.Clear();
return RedirectToActionPermanent("Scheduler");
}
@@ -437,22 +437,29 @@ namespace BeWoPlanerMobil.Controllers
[HttpPost]
public ActionResult SelectAppointmentToEdit(FormCollection formCollection)
{
if(Model is null)
{
return Logout();
}
var rawOid = formCollection[FormCollectionConstants.AppointmentSchedulerOidHolderKey];
var isSuccessful = long.TryParse(rawOid, out var appointmentOid);
if (isSuccessful)
if(!isSuccessful)
{
Model.SelectedAppointment = Model.Appointments.FirstOrDefault(app => app.SchedulerAppointmentOid.HasValue && app.SchedulerAppointmentOid.Value == appointmentOid);
return RedirectToActionPermanent("Scheduler");
}
if(Model.SelectedAppointment != null)
{
Model.IsAllDay = Model.SelectedAppointment.AllDay;
Model.IsPrivate = Model.SelectedAppointment.IsPrivate;
Model.SelectedResources = Model.SelectedAppointment?.ResourceList ?? new List<ResourceDC>();
Model.SelectedEmployees = Model.SelectedAppointment?.EmployeeList.Select(e2a => e2a.Employee).ToList() ?? new List<CompactEmployeeDC>();
Model.SelectedCustomers = Model.SelectedAppointment?.CustomerList ?? new List<CompactCustomerDC>();
}
Model.SelectedAppointment = Model.Appointments.FirstOrDefault(app => app.SchedulerAppointmentOid.HasValue && app.SchedulerAppointmentOid.Value == appointmentOid);
if(Model.SelectedAppointment != null)
{
Model.IsAllDay = Model.SelectedAppointment.AllDay;
Model.IsPrivate = Model.SelectedAppointment.IsPrivate;
Model.SelectedResources = Model.SelectedAppointment?.ResourceList ?? new List<ResourceDC>();
Model.SelectedEmployees = Model.SelectedAppointment?.EmployeeList.Select(e2a => e2a.Employee).ToList() ?? new List<CompactEmployeeDC>();
Model.SelectedCustomers = Model.SelectedAppointment?.CustomerList ?? new List<CompactCustomerDC>();
}
return RedirectToActionPermanent("Scheduler");
@@ -948,7 +955,7 @@ namespace BeWoPlanerMobil.Controllers
}
[Authorize]
public string DeleteAppointment(long appointmentOid)
public string DeleteAppointment(string appointmentIdentifier, bool deleteSeries)
{
if(Model?.Employee?.EmployeeOid is null)
{
@@ -956,33 +963,110 @@ namespace BeWoPlanerMobil.Controllers
return LeerzeichenFuerGetMethoden;
}
var appointment = Model.Appointments.FirstOrDefault(app => app.SchedulerAppointmentOid?.Equals(appointmentOid) ?? false);
if(!(appointment is null))
if(!Guid.TryParse(appointmentIdentifier, out var identifier))
{
var teamMemberCustomerOids = EmployeeService.LoadTeamsRelatedCustomerOids(Model.Employee.EmployeeOid.Value);
return LeerzeichenFuerGetMethoden;
}
var customerList = appointment.CustomerList;
var employeeList = appointment.EmployeeList;
var resourceList = appointment.ResourceList;
var originator = appointment.Originator;
var isNew = false;
var checkType = SchedulerRightsCheckType.Edit;
var loggedOnUser = MobileSessionFacade.LoggedInUserDC;
var schedulerAppointment = Model.AppointmentListItems.FirstOrDefault(app => app.Identifier.Equals(identifier))?.SchedulerAppointment;
if(schedulerAppointment is null)
{
return LeerzeichenFuerGetMethoden;
}
var isAllowedToDelete = BS.Shared.Core.Utils.CheckSchedulerRights(customerList, resourceList, employeeList, originator, isNew, checkType, loggedOnUser, teamMemberCustomerOids);
if(schedulerAppointment.SchedulerAppointmentOid is null && !(schedulerAppointment.RecurrenceInfo is null))
{
var recurrenceInfo = new RecurrenceInfo();
recurrenceInfo.FromXml(schedulerAppointment.RecurrenceInfo);
if(isAllowedToDelete && appointment.SchedulerAppointmentOid.HasValue && appointment.NewSchedulerAppointmentVersion.HasValue)
var pattern = StaticAppointmentFactory.CreateAppointment(AppointmentType.Pattern);
pattern.RecurrenceInfo.FromXml(schedulerAppointment.RecurrenceInfo);
pattern.Start = pattern.RecurrenceInfo.Start;
pattern.End = pattern.RecurrenceInfo.End;
var exception = pattern.CreateException(AppointmentType.DeletedOccurrence, schedulerAppointment.RecurrenceIndex);
var recurrenceId = exception.RecurrenceInfo.Id.ToString();
schedulerAppointment = deleteSeries ?
KalenderService.FindRootAppointmentByRecurrenceId(recurrenceId) :
CloneAppointment(schedulerAppointment, $"<RecurrenceInfo Id=\"{recurrenceId}\" Index=\"{schedulerAppointment.RecurrenceIndex}\" />", (int)exception.Type);
}
if(schedulerAppointment is null)
{
return LeerzeichenFuerGetMethoden;
}
var teamMemberCustomerOids = EmployeeService.LoadTeamsRelatedCustomerOids(Model.Employee.EmployeeOid.Value);
var customerList = schedulerAppointment.CustomerList;
var employeeList = schedulerAppointment.EmployeeList;
var resourceList = schedulerAppointment.ResourceList;
var originator = schedulerAppointment.Originator;
var isNew = schedulerAppointment.SchedulerAppointmentOid is null;
var loggedOnUser = MobileSessionFacade.LoggedInUserDC;
var isAllowedToDelete = BS.Shared.Core.Utils.CheckSchedulerRights(customerList, resourceList, employeeList, originator, isNew, SchedulerRightsCheckType.Edit, loggedOnUser, teamMemberCustomerOids);
if(isAllowedToDelete)
{
if(schedulerAppointment.SchedulerAppointmentOid.HasValue && schedulerAppointment.NewSchedulerAppointmentVersion.HasValue)
{
var oid2Version = new Dictionary<long, long> {{appointment.SchedulerAppointmentOid.Value, appointment.NewSchedulerAppointmentVersion.Value}};
var oid2Version = new Dictionary<long, long> { { schedulerAppointment.SchedulerAppointmentOid.Value, schedulerAppointment.NewSchedulerAppointmentVersion.Value } };
KalenderService.DeactivateSchedulerAppointments(oid2Version);
}
// DeletedOccurrence
if(schedulerAppointment.Type == 4 && !deleteSeries)
{
KalenderService.InsertSchedulerAppointments(new List<SchedulerAppointmentDC> { schedulerAppointment });
}
}
return LeerzeichenFuerGetMethoden;
}
[Authorize]
public static SchedulerAppointmentDC CloneAppointment(SchedulerAppointmentDC schedulerAppointment, string recurrenceInfo, int type)
{
return new SchedulerAppointmentDC
{
StartDate = schedulerAppointment.StartDate,
EndDate = schedulerAppointment.EndDate,
ServiceRecordList = schedulerAppointment.ServiceRecordList ?? new List<ServiceRecordDC>(),
EmployeeList = schedulerAppointment.EmployeeList ?? new List<Employee2SchedulerAppointmentDC>(),
ActivationType = ActivationTypeId.Active,
AllDay = schedulerAppointment.AllDay,
CanBeEdited = schedulerAppointment.CanBeEdited,
CompletedDate = schedulerAppointment.CompletedDate,
CompletedNotice = schedulerAppointment.CompletedNotice,
CompletedUser = schedulerAppointment.CompletedUser,
CustomerList = schedulerAppointment.CustomerList ?? new List<CompactCustomerDC>(),
Description = schedulerAppointment.Description,
DueDate = schedulerAppointment.DueDate,
FormerBookingSequenceOid = schedulerAppointment.FormerBookingSequenceOid,
FormerTaskOid = schedulerAppointment.FormerTaskOid,
HasServiceRecordEntry = schedulerAppointment.HasServiceRecordEntry,
IsPrivate = schedulerAppointment.IsPrivate,
IsTask = schedulerAppointment.IsTask,
IsTeilnahmeBestaetigung = schedulerAppointment.IsTeilnahmeBestaetigung,
LabelKey = schedulerAppointment.LabelKey,
Location = schedulerAppointment.Location,
Originator = schedulerAppointment.Originator,
RecurrenceInfo = recurrenceInfo,
ReminderInfo = schedulerAppointment.ReminderInfo,
ResourceList = schedulerAppointment.ResourceList ?? new List<ResourceDC>(),
Status = schedulerAppointment.Status,
Subject = schedulerAppointment.Subject,
SupportConceptList = schedulerAppointment.SupportConceptList ?? new List<CompactSupportConceptDC>(),
TaskDescription = schedulerAppointment.TaskDescription,
Type = type
};
}
[Authorize]
public string SelectTeamForIntervalFinder(string teamOidString)
{
@@ -1016,40 +1100,30 @@ namespace BeWoPlanerMobil.Controllers
return Logout();
}
// ToDo Serienausnahme erstellen möglich machen? Wenn ja, dann auch für das Bearbeiten und Löschen.
if(Guid.TryParse(formCollection["appointment-id-input"], out var identifier))
if(!Guid.TryParse(formCollection[FormCollectionConstants.AppointmentIdInputKey], out var identifier))
{
var ids = Model.AppointmentListItems.Select(s => s.Identifier).ToList();
var appointmentListItem = Model.AppointmentListItems.FirstOrDefault(f => f.Identifier.Equals(identifier));
if(!(appointmentListItem is null))
{
var appointment = appointmentListItem.SchedulerAppointment;
var employeeOids = appointment.EmployeeList.Select(e2a => e2a.Employee.EmployeeOid).ToList();
if(employeeOids.Count == 0)
{
employeeOids.Add(appointment.Originator.EmployeeOid);
}
var employeeOids2 = employeeOids.ToArray();
var customerOids = appointment.CustomerList.Select(c => c.CustomerOid).ToArray();
var notice = appointment.Description;
var start = appointment.StartDate;
var end = appointment.EndDate;
// ToDo: Appointment aktualisieren, bzw. eine Serienausnahme erstellen!
TempData["AppointmentListItem"] = appointmentListItem;
return RedirectToActionPermanent("PrepareServiceRecordInsert", "Main");
}
return RedirectToActionPermanent("PrepareServiceRecordInsert", "Main");
}
var appointmentListItem = Model.AppointmentListItems.FirstOrDefault(f => f.Identifier.Equals(identifier));
if(appointmentListItem is null)
{
return RedirectToActionPermanent("PrepareServiceRecordInsert", "Main");
}
var appointment = appointmentListItem.SchedulerAppointment;
var employeeOids = appointment.EmployeeList.Select(employee2Appointment => employee2Appointment.Employee.EmployeeOid).ToList();
if(employeeOids.Count == 0)
{
employeeOids.Add(appointment.Originator.EmployeeOid);
}
TempData[TempDataConstants.AppointmentListItemKey] = appointmentListItem;
return RedirectToActionPermanent("PrepareServiceRecordInsert", "Main");
}
}
}

View File

@@ -572,7 +572,7 @@ namespace BeWoPlanerMobil.Models
public string SubmitButtonValue => IsInEditingMode || IsInGroupBookingMode ? "Speichern" : "Anlegen";
public long SelectedServiceRecordsServiceDescriptionOid => SelectedServiceRecord?.ServiceDescription.ServiceDescriptionOid ?? 0L;
public long SelectedServiceRecordsServiceDescriptionOid => SelectedServiceRecord?.ServiceDescription?.ServiceDescriptionOid ?? 0L;
public ServiceRecordDC GetServiceRecord(long serviceRecordOid)
{

View File

@@ -51,16 +51,11 @@ namespace BeWoPlanerMobil.Models
private List<AppointmentListItem> _AppointmentListItems;
public List<AppointmentListItem> AppointmentListItems => _AppointmentListItems ?? (_AppointmentListItems = new List<AppointmentListItem>());
public bool HasRightToEditAppointment(long? appointmentOid)
public bool HasRightToEditAppointment(Guid identifier)
{
if (appointmentOid == null)
{
return false;
}
var appointment = AppointmentListItems.FirstOrDefault(app => app.Identifier.Equals(identifier))?.SchedulerAppointment; //Appointments.FirstOrDefault(app => app.SchedulerAppointmentOid.HasValue && app.SchedulerAppointmentOid.Value == appointmentOid);
var appointment = Appointments.FirstOrDefault(app => app.SchedulerAppointmentOid.HasValue && app.SchedulerAppointmentOid.Value == appointmentOid);
if (appointment == null)
if(appointment == null)
{
return false;
}
@@ -238,7 +233,7 @@ namespace BeWoPlanerMobil.Models
public KeyValuePair<DateTime, List<AppointmentListItem>> SaturdayAppointments { get; set; }
public KeyValuePair<DateTime, List<AppointmentListItem>> SundayAppointments { get; set; }
public WeekViewObject(IEnumerable<SchedulerAppointmentDC> appointments, DateTime monday)
public WeekViewObject(IEnumerable<SchedulerAppointmentDC> appointments, DateTime monday, EmployeeDC loggedInEmployee)
{
var first = monday.Date;
var last = first.AddDays(6);

View File

@@ -3,8 +3,8 @@
* You should not use this file at runtime inside the browser--it is only
* intended to be used only for design-time IntelliSense. Please use the
* standard jQuery library for all production use.
*
* Comment version: 1.19.3
* Comment version: 1.19.5
*/
/*
@@ -15,7 +15,7 @@
* for informational purposes only and are not the license terms under
* which Microsoft distributed this file.
*
* jQuery Validation Plugin - v1.19.3 - 8/12/2020
* jQuery Validation Plugin - v1.19.5 - 12/5/2016
* https://github.com/jzaefferer/jquery-validation
* Copyright (c) 2013 Jörn Zaefferer; Licensed MIT
*

View File

@@ -1,9 +1,9 @@
/*!
* jQuery Validation Plugin v1.19.3
* jQuery Validation Plugin v1.19.5
*
* https://jqueryvalidation.org/
*
* Copyright (c) 2021 Jörn Zaefferer
* Copyright (c) 2022 Jörn Zaefferer
* Released under the MIT license
*/
(function( factory ) {
@@ -1050,6 +1050,10 @@ $.extend( $.validator, {
// meta-characters that should be escaped in order to be used with JQuery
// as a literal part of a name/id or any selector.
escapeCssMeta: function( string ) {
if ( string === undefined ) {
return "";
}
return string.replace( /([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g, "\\$1" );
},
@@ -1126,8 +1130,8 @@ $.extend( $.validator, {
}
delete this.pending[ element.name ];
$( element ).removeClass( this.settings.pendingClass );
if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) {
$( this.currentForm ).submit();
if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() && this.pendingRequest === 0 ) {
$( this.currentForm ).trigger( "submit" );
// Remove the hidden input that was used as a replacement for the
// missing submit button. The hidden input is added by `handle()`
@@ -1232,7 +1236,7 @@ $.extend( $.validator, {
// Exception: the jquery validate 'range' method
// does not test for the html5 'range' type
rules[ method ] = true;
rules[ type === "date" ? "dateISO" : method ] = true;
}
},
@@ -1430,7 +1434,7 @@ $.extend( $.validator, {
// https://gist.github.com/dperini/729294
// see also https://mathiasbynens.be/demo/url-regex
// modified to allow protocol-relative URLs
return this.optional( element ) || /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u00a1-\uffff][a-z0-9\u00a1-\uffff_-]{0,62})?[a-z0-9\u00a1-\uffff]\.)+(?:[a-z\u00a1-\uffff]{2,}\.?))(?::\d{2,5})?(?:[/?#]\S*)?$/i.test( value );
return this.optional( element ) || /^(?:(?:(?:https?|ftp):)?\/\/)(?:(?:[^\]\[?\/<~#`!@$^&*()+=}|:";',>{ ]|%[0-9A-Fa-f]{2})+(?::(?:[^\]\[?\/<~#`!@$^&*()+=}|:";',>{ ]|%[0-9A-Fa-f]{2})*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u00a1-\uffff][a-z0-9\u00a1-\uffff_-]{0,62})?[a-z0-9\u00a1-\uffff]\.)+(?:[a-z\u00a1-\uffff]{2,}\.?))(?::\d{2,5})?(?:[/?#]\S*)?$/i.test( value );
},
// https://jqueryvalidation.org/date-method/

File diff suppressed because one or more lines are too long

View File

@@ -2,7 +2,9 @@
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using BeWoPlanerMobil.Models;
using BS.Shared.DataContracts;
using BS.Shared.DataContracts.Compact;
using BS.Shared.Extensions;
namespace BeWoPlanerMobil.Util
@@ -63,7 +65,9 @@ namespace BeWoPlanerMobil.Util
public bool HasEmployeesCustomersOrResources => !string.IsNullOrWhiteSpace(EmployeeListInfo + CustomerListInfo + ResourceListInfo);
public bool AllDay { get; }
public bool HasServiceRecord { get; }
public bool HasServiceRecord => SchedulerAppointment?.ServiceRecordList?.Any() ?? false;
public string Subject { get; }
public SchedulerAppointmentDC SchedulerAppointment { get; }
@@ -82,6 +86,8 @@ namespace BeWoPlanerMobil.Util
{
Identifier = Guid.NewGuid();
Subject = schedulerAppointment.Subject;
SchedulerAppointment = schedulerAppointment;
CanBeEdited = schedulerAppointment.CanBeEdited;
@@ -99,8 +105,6 @@ namespace BeWoPlanerMobil.Util
var customerColor = string.Empty;
var resourceColor = string.Empty;
HasServiceRecord = schedulerAppointment.ServiceRecordList?.Any() ?? false;
if(string.IsNullOrWhiteSpace(employeeColor) && schedulerAppointment.EmployeeList.Count == 0 && !string.IsNullOrWhiteSpace(schedulerAppointment.Originator?.EmployeeColor))
{
employeeColor = schedulerAppointment.Originator.EmployeeColor;

View File

@@ -38,8 +38,9 @@
public static string AppointmentNoticeKey => "Notice";
public static string AppointmentSchedulerDateKey => "SchedulerDate";
public static string AppointmentSchedulerOidHolderKey => "scheduler-oid-holder";
public static string AppointmentIsPrivate => "IsPrivate";
public static string AppointmentIsAllDay => "IsAllDay";
public static string AppointmentIsPrivateKey => "IsPrivate";
public static string AppointmentIsAllDayKey => "IsAllDay";
public static string AppointmentIdInputKey => "appointment-id-input";
// Auswertung
@@ -47,7 +48,6 @@
public static string SelectedMonthKey => "SelectedMonth";
public static string SelectedYearKey => "SelectedYear";
public static string SelectedTeamOidKey => "SelectedTeamOid";
public static string ShowSignatureSuggestionPopup => "ShowSignatureSuggestionPopup";
public static string ServiceRecordOidForSignature => "ServiceRecordOidForSignature";
}
@@ -60,4 +60,16 @@
public static string DevelopmentModelKey => "DevelopmentModel";
public static string DevExpressReportModelKey => "DevExpressReportModel";
}
public class SessionConstants
{
public static string ServiceRecordTimeIntervalKey => "ServiceRecordTimeInterval";
}
public class TempDataConstants
{
public static string ShowSignatureSuggestionPopup => "ShowSignatureSuggestionPopup";
public static string AppointmentListItemKey => "AppointmentListItem";
public static string IsInTransferModeKey => "IsInTransferMode";
}
}

View File

@@ -46,6 +46,28 @@
logError(error);
}
}
(function() {
'use strict';
window.addEventListener('load', function() {
var forms = document.getElementsByClassName("needs-validation");
var validation = Array.prototype.filter.call(forms, function(form) {
form.addEventListener('submit', function (event) {
if(form.checkValidity() === false) {
hideSpinner();
event.preventDefault();
event.stopPropagation();
$([document.documentElement, document.body]).animate({
scrollTop: $("#stammdaten-container").offset().top
}, 10);
}
form.classList.add('was-validated');
}, false);
});
}, false);
})();
</script>
<div class="container-fluid mt-3">
@@ -78,7 +100,7 @@
@if(Model?.SelectedJsonCustomer != null)
{
using(Html.BeginForm("UpdateCustomer", "Customer", FormMethod.Post, new { id = "stammdaten-form" }))
using(Html.BeginForm("UpdateCustomer", "Customer", FormMethod.Post, new { id = "stammdaten-form", @class = "needs-validation", novalidate="novalidate" }))
{
<div class="row my-3" id="stammdaten-container">
<div class="col-sm-6 col-md-6 col-lg-3 mt-3">
@@ -95,7 +117,10 @@
Vorname
</div>
</div>
<input type="text" class="form-control" id="vorname" name="vorname" value="@Model.SelectedJsonCustomer.Vorname" />
<input required type="text" class="form-control" id="vorname" name="vorname" value="@Model.SelectedJsonCustomer.Vorname" />
<div class="invalid-feedback">
Dieses Feld darf nicht leer sein!
</div>
</div>
</div>
</div>
@@ -107,7 +132,10 @@
Nachname
</div>
</div>
<input type="text" class="form-control" id="nachname" name="nachname" value="@Model.SelectedJsonCustomer.Nachname" />
<input required type="text" class="form-control" id="nachname" name="nachname" value="@Model.SelectedJsonCustomer.Nachname" />
<div class="invalid-feedback">
Dieses Feld darf nicht leer sein!
</div>
</div>
</div>
</div>
@@ -342,26 +370,23 @@
</div>
</div>
@if(Model.SelectedJsonCustomer.Kommentar != null)
{
<div class="col-sm-12 col-md-6 my-3">
<div class="card w-100 h-100">
<div class="card-header">
<div class="clearfix">
<h5 class="text-bewo-customer-card-header d-inline float-left">Kommentar</h5>
</div>
<div class="col-sm-12 col-md-6 my-3">
<div class="card w-100 h-100">
<div class="card-header">
<div class="clearfix">
<h5 class="text-bewo-customer-card-header d-inline float-left">Kommentar</h5>
</div>
<div class="card-body">
<div class="container-fluid">
<textarea id="notice-textarea" name="notiz" class="w-100" style="resize: vertical;">@Model.SelectedJsonCustomer.Kommentar</textarea>
</div>
</div>
<div class="card-body">
<div class="container-fluid">
<textarea id="notice-textarea" name="notiz" class="w-100" style="resize: vertical;">@Model.SelectedJsonCustomer.Kommentar</textarea>
</div>
</div>
</div>
}
</div>
<div class="col-12 my-3">
<button type="button" class="btn btn-primary float-right w-100" onclick="submitStammdatenForm()">Speichern</button>
<button type="submit" class="btn btn-primary float-right w-100" onclick="showSpinner()">Speichern</button>
</div>
<div class="col-12">

View File

@@ -1,4 +1,5 @@
@using BeWoPlanerMobil.Models
@using BeWoPlanerMobil.Util
@model BeWoPlanerMobil.Models.MainModel
<script>
@@ -347,10 +348,21 @@
<!-- dient nur als Abstandshalter-->
</div>
<div class="ml-3 bd-highlight">
@using (Html.BeginForm("ResetEditingMode", "Main", FormMethod.Post))
@if(TempData[TempDataConstants.IsInTransferModeKey] is bool isInTransferMode && isInTransferMode)
{
<button type="submit" class="btn btn-primary" onclick="showSpinner()">Abbrechen</button>
using(Html.BeginForm("ResetTransferMode", "Main", FormMethod.Post))
{
<button type="submit" class="btn btn-primary" onclick="showSpinner()">Abbrechen</button>
}
}
else
{
using(Html.BeginForm("ResetEditingMode", "Main", FormMethod.Post))
{
<button type="submit" class="btn btn-primary" onclick="showSpinner()">Abbrechen</button>
}
}
</div>
<div class="ml-3 bd-highlight">
<button type="button" class="btn btn-primary" id="create-button" onclick="submitGroupBookingForm()">@submitButtonText</button>

View File

@@ -222,7 +222,7 @@
}
@{
var shouldShowSignaturePopup = TempData[FormCollectionConstants.ShowSignatureSuggestionPopup]?.GetType() == typeof(bool) && (bool) TempData[FormCollectionConstants.ShowSignatureSuggestionPopup];
var shouldShowSignaturePopup = TempData[TempDataConstants.ShowSignatureSuggestionPopup]?.GetType() == typeof(bool) && (bool) TempData[TempDataConstants.ShowSignatureSuggestionPopup];
if(Model.ServiceRecordOid > 0)
{

View File

@@ -374,29 +374,36 @@
</div>
}
<div class="d-flex bd-highlight mt-3">
<div class="mr-auto bd-highlight">
<div class="d-flex bd-highlight mt-3">
<div class="mr-auto bd-highlight">
</div>
@if(Model.IsInEditingMode)
{
using(Html.BeginForm("ResetEditingMode", "Main", FormMethod.Post))
{
<button type="submit" class="btn btn-primary" onclick="showSpinner()">Abbrechen</button>
}
}
else
{
<div class="ml-3 bd-highlight">
<button type="button" class="btn btn-primary" id="reset-button" onclick="resetSingleBookingForm()">Abbrechen</button>
</div>
}
<div class="ml-3 bd-highlight">
<button type="button" class="btn btn-primary" id="create-button" onclick="submitSingleBookingForm()">@Model.SubmitButtonValue</button>
</div>
</div>
@if(Model.IsInEditingMode)
{
using(Html.BeginForm("ResetEditingMode", "Main", FormMethod.Post))
{
<button type="submit" class="btn btn-primary" onclick="showSpinner()">Abbrechen</button>
}
}
else if(TempData[TempDataConstants.IsInTransferModeKey] is bool isInTransferMode && isInTransferMode)
{
using(Html.BeginForm("ResetTransferMode", "Main", FormMethod.Post))
{
<button type="submit" class="btn btn-primary" onclick="showSpinner()">Abbrechen</button>
}
}
else
{
<div class="ml-3 bd-highlight">
<button type="button" class="btn btn-primary" id="reset-button" onclick="resetSingleBookingForm()">Abbrechen</button>
</div>
}
<div class="ml-3 bd-highlight">
<button type="button" class="btn btn-primary" id="create-button" onclick="submitSingleBookingForm()">@Model.SubmitButtonValue</button>
</div>
</div>
}
</div>
<!-- /Einzelbuchungsformular -->
<!-- Liste mit den Einträgen und dem Auswahl-Select -->

View File

@@ -274,7 +274,7 @@
Notiz
</div>
</div>
<textarea class="form-control" id="notice" name="Notice" maxlength="1024">@Model.DescriptionToEdit</textarea>
<textarea class="form-control" id="notice" name="Notice" maxlength="1024" >@Model.DescriptionToEdit</textarea>
</div>
</div>
</div>

View File

@@ -1,20 +1,41 @@
@model BeWoPlanerMobil.Models.SchedulerModel
<script>
function deleteAppointment(appointmentOid) {
function deleteAppointment(appointmentOid, appointmentIdentifier, isException, subject) {
try {
$.get("@Url.Action("DeleteAppointment")", { appointmentOid: appointmentOid}).done(function() {
if(isException === false && appointmentOid === 0) {
$("#appointment-deletion-message").html("Wollen Sie alle Ereignisse des aktuellen Termins \"" + subject + "\", oder nur diesen einen löschen?");
$("#delete-popup-btn").on("click",
function () {
var deleteSeries = $("#deleteSeriesRadio").prop("checked");
submitDeletionForm(appointmentIdentifier, deleteSeries);
});
$("#delete-occurring-appoinment-popup").modal("show");
} else {
submitDeletionForm(appointmentIdentifier, false);
}
} catch(error) {
logError(error);
}
}
function submitDeletionForm(appointmentIdentifier, deleteSeries) {
try {
$.get("@Url.Action("DeleteAppointment")", { appointmentIdentifier: appointmentIdentifier, deleteSeries: deleteSeries}).done(function() {
$("#appointment-list-container").load("@Url.Action("FetchAppointments")");
$("#delete-occurring-appoinment-popup").modal("hide");
});
} catch(error) {
logError(error);
}
}
function copyToServiceRecord(appointmentOid) {
function copyToServiceRecord(appointmentIdentifier) {
try {
showSpinner();
$("#transformAppToServiceRecForm").submit();
$("#transformAppToServiceRecForm-" + appointmentIdentifier).submit();
} catch(error) {
hideSpinner();
logError(error);
@@ -22,6 +43,35 @@
}
</script>
<!-- Popup -->
<div class="modal" tabindex="-1" role="dialog" id="delete-occurring-appoinment-popup">
<div class="modal-dialog modal-dialog-scrollable" role="document">
<div class="modal-content">
<div class="modal-header">
<h6 class="modal-title">Termin löschen</h6>
<button type="button" class="close" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<div class="modal-body pb-0">
<p id="appointment-deletion-message"></p>
<div class="form-check">
<input class="form-check-input" type="radio" name="deleteRadios" id="deleteSeriesRadio" />
<label class="form-check-label" for="deleteSeriesRadio">Lösche die Serie</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="deleteRadios" id="deleteOccurrenceRadio" checked />
<label class="form-check-label" for="deleteOccurrenceRadio">Lösche dieses Ereignis</label>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Schließen</button>
<button type="button" class="btn btn-primary" data-dismiss="model" id="delete-popup-btn">OK</button>
</div>
</div>
</div>
</div>
@* Ganztagestermine in eine Liste mit weniger Margin und Padding *@
<div id="one-day-scheduler-partial-container">
@if(Model.AppointmentListItems.Any(a => a.AllDay))
@@ -95,19 +145,35 @@
<hr />
}
@if(Model.HasRightToEditAppointment(appointment.Oid) && !appointment.IsTask && appointment.Oid.HasValue && appointment.CanBeEdited)
@if(Model.HasRightToEditAppointment(appointment.Identifier) && !appointment.IsTask && appointment.CanBeEdited)
{
using(Html.BeginForm("SelectAppointmentToEdit", "Scheduler", FormMethod.Post))
{
<div class="row mb-3">
<div class="col-auto">
<button type="submit" class="btn btn-primary" onclick="showSpinner()">
<span class="fas fa-edit"></span>
</button>
<input type="hidden" name="scheduler-oid-holder" value="@appointment.Oid" />
</div>
<div class="row mb-3">
<div class="col-auto">
@if(appointment.Oid.HasValue)
{
using(Html.BeginForm("SelectAppointmentToEdit", "Scheduler", FormMethod.Post))
{
<button type="submit" class="btn btn-primary" onclick="showSpinner()">
<span class="fas fa-edit"></span>
</button>
<input type="hidden" name="scheduler-oid-holder" value="@appointment.Oid" />
}
}
</div>
}
<div class="col-auto">
<button type="button" class="btn btn-bewo-service-records" onclick="copyToServiceRecord('@appointment.Identifier')">
<span>
<i class="fas fa-external-link-alt"></i>
<i class="fas fa-clock"></i>
</span>
</button>
</div>
@using(Html.BeginForm("TransformAppointmentToServiceRecord", "Scheduler", FormMethod.Post, new {id="transformAppToServiceRecForm-" + appointment.Identifier}))
{
<input type="hidden" value="@appointment.Identifier" name="appointment-id-input" />
}
</div>
}
<p>@appointment.Description</p>
</div>
@@ -188,33 +254,39 @@
<hr />
}
@if(Model.HasRightToEditAppointment(appointment.Oid) && !appointment.IsTask && appointment.Oid.HasValue && appointment.CanBeEdited)
@if(Model.HasRightToEditAppointment(appointment.Identifier) && !appointment.IsTask && appointment.CanBeEdited)
{
<div class="row mb-3">
@if(appointment.Oid.HasValue)
{
using(Html.BeginForm("SelectAppointmentToEdit", "Scheduler", FormMethod.Post))
{
<div class="row mb-3">
<div class="col-auto">
<button type="submit" class="btn btn-primary" onclick="showSpinner()">
<span class="fas fa-edit"></span>
</button>
<input type="hidden" name="scheduler-oid-holder" value="@appointment.Oid" />
</div>
<div class="col-auto">
<button type="button" class="btn btn-primary" onclick="deleteAppointment(@appointment.Oid)">
<span class="fas fa-trash-alt"></span>
</button>
</div>
@*<div class="col-auto">
<button type="button" class="btn btn-bewo-service-records" onclick="copyToServiceRecord(@appointment.Oid)">
<span>
<i class="fas fa-external-link-alt"></i>
<i class="fas fa-clock"></i>
</span>
</button>
</div>*@
<div class="col-auto">
<button type="submit" class="btn btn-primary" onclick="showSpinner()">
<span class="fas fa-edit"></span>
</button>
<input type="hidden" name="scheduler-oid-holder" value="@appointment.Oid" />
</div>
}
using(Html.BeginForm("TransformAppointmentToServiceRecord", "Scheduler", FormMethod.Post, new {id="transformAppToServiceRecForm"}))
}
<div class="col-auto">
<button type="button" class="btn btn-primary" onclick="deleteAppointment(@(appointment.Oid ?? 0), '@appointment.Identifier', @appointment.IsException.ToString().ToLower(), '@appointment.Subject')">
<span class="fas fa-trash-alt"></span>
</button>
</div>
<div class="col-auto">
<button type="button" class="btn btn-bewo-service-records" onclick="copyToServiceRecord('@appointment.Identifier')">
<span>
<i class="fas fa-external-link-alt"></i>
<i class="fas fa-clock"></i>
</span>
</button>
</div>
</div>
using(Html.BeginForm("TransformAppointmentToServiceRecord", "Scheduler", FormMethod.Post, new {id="transformAppToServiceRecForm-" + appointment.Identifier}))
{
<input type="hidden" value="@appointment.Identifier" name="appointment-id-input" />
}

View File

@@ -16,6 +16,7 @@
<script src="@Url.Content("~/Scripts/jquery-3.6.0.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery-ui-1.13.0.min.js")"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.js")"></script>
<script src="@Url.Content("~/Scripts/src-min/ace.js")"></script>
<script src="@Url.Content("~/Scripts/devexpress-scripts/knockout-3.5.1.js")"></script>
<script src="@Url.Content("~/node_modules/cldrjs/dist/cldr.js")"></script>

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>

View File

@@ -5,8 +5,8 @@
<package id="EntityFramework" version="6.4.4" targetFramework="net472" />
<package id="jQuery" version="3.6.0" targetFramework="net472" />
<package id="jQuery.UI.Combined" version="1.13.0" targetFramework="net472" />
<package id="jQuery.Validation" version="1.19.3" targetFramework="net472" />
<package id="log4net" version="2.0.13" targetFramework="net472" />
<package id="jQuery.Validation" version="1.19.5" targetFramework="net472" />
<package id="log4net" version="2.0.15" targetFramework="net472" />
<package id="Microsoft.AspNet.Mvc" version="5.2.7" targetFramework="net472" />
<package id="Microsoft.AspNet.Providers.Core" version="2.0.0" targetFramework="net472" />
<package id="Microsoft.AspNet.Razor" version="3.2.7" targetFramework="net472" />

View File

@@ -107,7 +107,9 @@ namespace CaritasKleve.Service
Subject = booking.Notice,
Originator = MapperFactory.CompactEmployeeDC_Employee.MapToNewDC(originator),
Type = 0,
FormerBookingSequenceOid = booking.Sequence.Oid
FormerBookingSequenceOid = booking.Sequence.Oid,
ServiceRecordList = new List<ServiceRecordDC>(),
SupportConceptList = new List<CompactSupportConceptDC>()
};
if (kvp.Value.Count > 1 && booking.SequencePosition > 0)

View File

@@ -338,7 +338,7 @@ namespace BeWo.Service.Plugins
//t = "2986016022"; // Ev Verein für Wohnraumhilfe Frankfurt a.M.
//t = "2181497347"; // BetreuungsserviceFuerAlltagUndWohnen
//t = "5433105975"; // aha e.V.
//t = "7396826106"; // SKF Sozialdienst katholischer Frauen e.V. Leverkusen
t = "7396826106"; // SKF Sozialdienst katholischer Frauen e.V. Leverkusen
//t = "4748304562"; // BeWo Darmstadt
//t = "5315865694"; // Wismarer Werkstätten GmbH

View File

@@ -1295,5 +1295,9 @@ namespace BeWo.Service.ServiceContracts
[FaultContract(typeof(BeWoFault))]
[OperationContract]
List<ConfirmationReceiptSignatureDC> GetConfirmationReceiptSignatures(List<long> oids);
[FaultContract(typeof(BeWoFault))]
[OperationContract]
SchedulerAppointmentDC GetRootAppointment(string recurrenceId);
}
}

View File

@@ -7673,5 +7673,24 @@ namespace BeWo.Service.ServiceImplementations
throw Utils.CreateBeWoFaultException(e);
}
}
public SchedulerAppointmentDC GetRootAppointment(string recurrenceId)
{
try
{
if(Guid.TryParse(recurrenceId, out var guid))
{
var rootAppointment = DAOFactory.SearchDAO.FindRootAppointmentByRecurrenceId(recurrenceId);
return MapperFactory.SchedulerAppointmentDCSchedulerAppointment.MapToNewDC(rootAppointment);
}
return null;
}
catch(Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
}
}

View File

@@ -403,7 +403,9 @@ namespace BeWo.Service.ServiceImplementations
Subject = booking.Notice,
Originator = MapperFactory.CompactEmployeeDC_Employee.MapToNewDC(originator),
Type = 0,
FormerBookingSequenceOid = booking.Sequence.Oid
FormerBookingSequenceOid = booking.Sequence.Oid,
ServiceRecordList = new List<ServiceRecordDC>(),
SupportConceptList = new List<CompactSupportConceptDC>()
};
if(kvp.Value.Count > 1 && booking.SequencePosition > 0)

View File

@@ -95,7 +95,9 @@ namespace BS.Shared.Core
StartDate = startDate,
Status = appointment.Status,
Subject = appointment.Subject,
Type = appointment.Type
Type = appointment.Type,
ServiceRecordList = appointment.ServiceRecordList,
SupportConceptList = appointment.SupportConceptList
};
}
}

View File

@@ -5,6 +5,7 @@ using System.Runtime.Serialization;
using System.Text.RegularExpressions;
using BS.Shared.DataContracts.Compact;
using BS.Shared.Extensions;
using DevExpress.XtraScheduler;
namespace BS.Shared.DataContracts
{
@@ -104,20 +105,23 @@ namespace BS.Shared.DataContracts
{
get
{
if (!(RecurrenceInfo is null))
if(RecurrenceInfo is null)
{
var match = RecurrenceIdRegex.Match(RecurrenceInfo);
if (match.Success)
{
var matchValue = match.Value;
var idValue = matchValue.Split("\"");
return idValue[1];
}
return null;
}
return null;
var match = RecurrenceIdRegex.Match(RecurrenceInfo);
if(!match.Success)
{
return null;
}
var matchValue = match.Value;
var idValue = matchValue.Split("\"");
return idValue[1];
}
}
@@ -127,20 +131,22 @@ namespace BS.Shared.DataContracts
{
get
{
if (!(RecurrenceInfo is null))
if(RecurrenceInfo is null)
{
var match = RecurrenceIndexRegex.Match(RecurrenceInfo);
if (match.Success)
{
var matchValue = match.Value;
var indexValue = matchValue.Split("\"");
return int.TryParse(indexValue[1], out var indexInt) ? (int?)indexInt : null;
}
return null;
}
return null;
var match = RecurrenceIndexRegex.Match(RecurrenceInfo);
if(!match.Success)
{
return null;
}
var matchValue = match.Value;
var indexValue = matchValue.Split("\"");
return int.TryParse(indexValue[1], out var indexInt) ? (int?)indexInt : null;
}
}
@@ -163,14 +169,37 @@ namespace BS.Shared.DataContracts
return false;
}
if (SchedulerAppointmentOid is null && schedulerAppointmentDC.SchedulerAppointmentOid is null)
var oidEqualsValue = false;
if(SchedulerAppointmentOid is null && schedulerAppointmentDC.SchedulerAppointmentOid is null)
{
return GetHashCode() == schedulerAppointmentDC.GetHashCode();
// Prüfen, ob es sich um einen Serientermin handelt und index und id vergleichen
var appointmentType1 = (AppointmentType)Type;
var appointmentType2 = (AppointmentType)schedulerAppointmentDC.Type;
if(appointmentType1.Equals(AppointmentType.Occurrence) && appointmentType2.Equals(AppointmentType.Occurrence))
{
var recurrenceId1 = RecurrenceIdReference;
var recurrenceIndex1 = RecurrenceIndex;
var recurrenceId2 = schedulerAppointmentDC.RecurrenceIdReference;
var recurrenceIndex2 = schedulerAppointmentDC.RecurrenceIndex;
if(!(recurrenceId1 is null || recurrenceId2 is null))
{
oidEqualsValue = recurrenceId1.Equals(recurrenceId2) && recurrenceIndex1.Equals(recurrenceIndex2);
}
}
else
{
oidEqualsValue = GetHashCode() == schedulerAppointmentDC.GetHashCode();
}
}
if (SchedulerAppointmentOid != null && schedulerAppointmentDC.SchedulerAppointmentOid != null)
if(SchedulerAppointmentOid != null && schedulerAppointmentDC.SchedulerAppointmentOid != null)
{
return SchedulerAppointmentOid == schedulerAppointmentDC.SchedulerAppointmentOid;
oidEqualsValue = SchedulerAppointmentOid == schedulerAppointmentDC.SchedulerAppointmentOid;
}
var value = StartDate == schedulerAppointmentDC.StartDate && EndDate == schedulerAppointmentDC.EndDate && Type == schedulerAppointmentDC.Type && Description == schedulerAppointmentDC.Description &&
@@ -178,7 +207,8 @@ namespace BS.Shared.DataContracts
ResourceList.SequenceEqual(schedulerAppointmentDC.ResourceList) &&
CustomerList.SequenceEqual(schedulerAppointmentDC.CustomerList) &&
ServiceRecordList.SequenceEqual(schedulerAppointmentDC.ServiceRecordList) &&
SupportConceptList.SequenceEqual(schedulerAppointmentDC.SupportConceptList);
SupportConceptList.SequenceEqual(schedulerAppointmentDC.SupportConceptList) &&
oidEqualsValue;
return value;
}

View File

@@ -129,7 +129,7 @@ namespace BS.Shared.Extensions
return false;
}
return list1.Count == list2.Count && list1.All(list2.Contains);
return list1.Count == list2.Count && list1.All(list2.Contains) && list2.All(list1.Contains);
}
}
}