Merge branch 'master' of ssh://float.ownsoft.de/git/beyondSoft/BeWo

This commit is contained in:
2026-03-03 14:29:35 +01:00
46 changed files with 2358 additions and 754 deletions

View File

@@ -20,7 +20,7 @@
d:DesignWidth="500"
Focusable="True"
mc:Ignorable="d">
<Grid Margin="0" Background="{DynamicResource ObjectEditBackgroundBrush}" >
<Grid Margin="0" Background="{DynamicResource ObjectEditBackgroundBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
@@ -31,63 +31,72 @@
Height="Auto"
VerticalAlignment="Center"
Orientation="Vertical">
<Button x:Name="ButtonStart"
Click="ButtonStartStop_Click"
Grid.Row="1"
HorizontalAlignment="Center"
Width="220"
Height="50"
Margin="0,10,0,0">
<Button
x:Name="ButtonStart"
Grid.Row="1"
Width="220"
Height="50"
Margin="0,10,0,0"
HorizontalAlignment="Center"
Click="ButtonStartStop_Click">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="120"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="120" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Image Source="/BeWoPlaner;component/Ressources/Icons/KI/Icon_KI_Chat_Weiss+Orange.png"
Width="32"
Height="32"
Margin="0,0,10,0"/>
<TextBlock Grid.Column="1" x:Name="ButtonText" VerticalAlignment="Center" Text="{t:Translate Aufnahme initiieren}"/>
<Viewbox Grid.Column="2" x:Name="VBPlay" Width="40" Height="40" Visibility="Visible">
<Image
Width="32"
Height="32"
Margin="0,0,10,0"
Source="/BeWoPlaner;component/Ressources/Icons/KI/Icon_KI_Chat_Weiss+Orange.png" />
<TextBlock
x:Name="ButtonText"
Grid.Column="1"
VerticalAlignment="Center"
Text="{t:Translate Aufnahme initiieren}" />
<Viewbox
x:Name="VBPlay"
Grid.Column="2"
Width="40"
Height="40"
Visibility="Visible">
<Grid Width="100" Height="100">
<Ellipse
Width="80"
Height="80"
Stroke="White"
StrokeThickness="6"
Fill="Transparent"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
Width="80"
Height="80"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Fill="Transparent"
Stroke="White"
StrokeThickness="6" />
<Path
Fill="White"
Data="M 40,30 L 40,70 L 70,50 Z"/>
<Path Data="M 40,30 L 40,70 L 70,50 Z" Fill="White" />
</Grid>
</Viewbox>
<Viewbox Grid.Column="2" x:Name="VBStop" Width="40" Height="40" Visibility="Hidden">
<Viewbox
x:Name="VBStop"
Grid.Column="2"
Width="40"
Height="40"
Visibility="Hidden">
<Grid Width="100" Height="100">
<Ellipse
Width="80"
Height="80"
StrokeThickness="6"
Fill="Transparent"
HorizontalAlignment="Center"
VerticalAlignment="Center">
Width="80"
Height="80"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Fill="Transparent"
StrokeThickness="6">
<Ellipse.Stroke>
<LinearGradientBrush
x:Name="RingGradient"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush x:Name="RingGradient" StartPoint="0,0" EndPoint="1,0">
<LinearGradientBrush.RelativeTransform>
<RotateTransform x:Name="GradientRotate"
CenterX="0.5"
CenterY="0.5"/>
<RotateTransform x:Name="GradientRotate" CenterX="0.5" CenterY="0.5" />
</LinearGradientBrush.RelativeTransform>
<GradientStop Color="Red" Offset="0"/>
<GradientStop Color="#00FF0000" Offset="1"/>
<GradientStop Offset="0" Color="Red" />
<GradientStop Offset="1" Color="#00FF0000" />
</LinearGradientBrush>
</Ellipse.Stroke>
@@ -96,11 +105,11 @@
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever">
<DoubleAnimation
Storyboard.TargetName="GradientRotate"
Storyboard.TargetProperty="Angle"
From="0"
To="360"
Duration="0:0:2"/>
Storyboard.TargetName="GradientRotate"
Storyboard.TargetProperty="Angle"
From="0"
To="360"
Duration="0:0:2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
@@ -108,73 +117,92 @@
</Ellipse>
<Rectangle
Width="33"
Height="33"
Fill="Red"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
Width="33"
Height="33"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Fill="Red" />
</Grid>
</Viewbox>
</Grid>
</Button>
<Label x:Name="lblStatus" Height="23" HorizontalAlignment="Center"></Label>
<StackPanel x:Name="PanelAnimation" Visibility="Hidden" Orientation="Horizontal"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Label
x:Name="lblStatus"
Height="23"
HorizontalAlignment="Center" />
<StackPanel
x:Name="PanelAnimation"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Horizontal"
Visibility="Hidden">
<StackPanel.Resources>
<Storyboard x:Key="DotAnimation"
RepeatBehavior="Forever">
<Storyboard x:Key="DotAnimation" RepeatBehavior="Forever">
<DoubleAnimation
Storyboard.TargetProperty="Opacity"
From="0.3"
To="1"
Duration="0:0:0.6"
AutoReverse="True"/>
AutoReverse="True"
Storyboard.TargetProperty="Opacity"
From="0.3"
To="1"
Duration="0:0:0.6" />
</Storyboard>
</StackPanel.Resources>
<!-- Punkt 1 -->
<Ellipse Width="8" Height="8" Fill="#007ACC" Margin="3">
<!-- Punkt 1 -->
<Ellipse
Width="8"
Height="8"
Margin="3"
Fill="#007ACC">
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard Storyboard="{StaticResource DotAnimation}"/>
<BeginStoryboard Storyboard="{StaticResource DotAnimation}" />
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
<!-- Punkt 2 -->
<Ellipse Width="8" Height="8" Fill="#007ACC" Margin="3" Opacity="0.3">
<!-- Punkt 2 -->
<Ellipse
Width="8"
Height="8"
Margin="3"
Fill="#007ACC"
Opacity="0.3">
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever">
<DoubleAnimation
Storyboard.TargetProperty="Opacity"
From="0.3"
To="1"
Duration="0:0:0.6"
BeginTime="0:0:0.2"
AutoReverse="True"/>
AutoReverse="True"
BeginTime="0:0:0.2"
Storyboard.TargetProperty="Opacity"
From="0.3"
To="1"
Duration="0:0:0.6" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
<!-- Punkt 3 -->
<Ellipse Width="8" Height="8" Fill="#007ACC" Margin="3" Opacity="0.3">
<!-- Punkt 3 -->
<Ellipse
Width="8"
Height="8"
Margin="3"
Fill="#007ACC"
Opacity="0.3">
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever">
<DoubleAnimation
Storyboard.TargetProperty="Opacity"
From="0.3"
To="1"
Duration="0:0:0.6"
BeginTime="0:0:0.4"
AutoReverse="True"/>
AutoReverse="True"
BeginTime="0:0:0.4"
Storyboard.TargetProperty="Opacity"
From="0.3"
To="1"
Duration="0:0:0.6" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
@@ -183,9 +211,9 @@
</StackPanel>
<StackPanel
x:Name="PanelAiButtons"
HorizontalAlignment="Right"
Orientation="Horizontal"
x:Name="PanelAiButtons"
HorizontalAlignment="Right"
Orientation="Horizontal"
Visibility="Collapsed">
<StackPanel.Resources>
<ResourceDictionary>
@@ -196,27 +224,26 @@
</StackPanel.Resources>
<Button
x:Name="btn_AiPromptbaustein"
Padding="0"
Command="{Binding OpenAiPromptSelectionCommand}"
Content="{StaticResource AiDesignsIconKIFunktionWeissGruen}"
Style="{StaticResource PrimaryButton}" />
x:Name="btn_AiPromptbaustein"
Padding="0"
Command="{Binding OpenAiPromptSelectionCommand}"
Content="{StaticResource AiDesignsIconKIFunktionWeissGruen}"
Style="{StaticResource PrimaryButton}" />
</StackPanel>
</StackPanel>
<TextBox
Style="{x:Null}"
x:Name="TextBoxErgebnis"
Grid.Row="1"
AcceptsReturn="True"
AcceptsTab="True"
HorizontalScrollBarVisibility="Disabled"
TextWrapping="Wrap"
VerticalScrollBarVisibility="Auto"
x:Name="TextBoxErgebnis"
Grid.Row="1"
Margin="3"
/>
AcceptsReturn="True"
AcceptsTab="True"
HorizontalScrollBarVisibility="Disabled"
Style="{x:Null}"
TextWrapping="Wrap"
VerticalScrollBarVisibility="Auto" />
<StackPanel

View File

@@ -15,7 +15,7 @@ namespace BeWo
{
var baseVersion = new Version(BeWoApp.ShortVersion);
var stage = BeWoClientReleaseStage.Release;
var stageVersion = new Version("3.1");
var stageVersion = new Version("4.0");
var feature = BeWoClientFeature.None;
BeWoAppVersion = new BeWoAppVersion(baseVersion, stage, stageVersion, feature);

View File

@@ -11,12 +11,11 @@ namespace BeWo.Core.Commands
{
public static class CommandFactory
{
public static DelegateCommand GetAiViewCommand(Action openView, UserRightType userRightType, Func<bool> additionalCheckup = null, bool? useCommandManager = null)
public static DelegateCommand GetAiViewCommand(Action openView, UserRightType? userRightType, Func<bool> additionalCheckup = null, bool? useCommandManager = null)
{
bool canExecute() =>
BeWoAppInfo.IsInAiMode &&
(BeWoApp.AppSettings?.ModuleAiEnabled ?? BeWoApp.AppSettings?.ShowAI ?? false) &&
BeWoApp.HasLoggedOnUserRight(userRightType) &&
(userRightType is null || BeWoApp.HasLoggedOnUserRight(userRightType.Value)) &&
(additionalCheckup is null || additionalCheckup());
return new DelegateCommand(openView, () => CheckupSafe(canExecute), useCommandManager);

View File

@@ -2176,7 +2176,24 @@ namespace BeWo.Scheduler.View
{
GetCacheObjects((c, e, r) =>
{
ServiceFacade.DoResourceServiceAsync(s2 => s2.LoadFilteredAppointmentsMitAufgaben(BeWoApp.HasLoggedOnUserRight(new[] {UserRightType.KalenderMitarbeitertermineAnsehen}), BeWoApp.LoggedOnEmployee.EmployeeOid.Value, start, end, pSelectedEmployees, pSelectedCustomer, pSelectedResources, pEmployeesOnly, pCustomersOnly, pResourcesOnly, pPrivateAppointmentsOnly, pOnlyMyAppointments, IsTasksVisible),
ServiceFacade.DoResourceServiceAsync(s2 => s2.LoadFilteredAppointmentsMitAufgaben(
BeWoApp.HasLoggedOnUserRight(new[]
{
UserRightType.KalenderMitarbeitertermineAnsehen
}),
BeWoApp.LoggedOnEmployee.EmployeeOid.Value,
start,
end,
pSelectedEmployees,
pSelectedCustomer,
pSelectedResources,
pEmployeesOnly,
pCustomersOnly,
pResourcesOnly,
pPrivateAppointmentsOnly,
pOnlyMyAppointments,
IsTasksVisible
),
appointments =>
{
ServiceFacade.DoResourceServiceAsync(s3 => s3.GetAllActiveEmployeeAbsenceTimesInInterval(start, end, BeWoApp.LoggedOnEmployee.EmployeeOid.Value, SelectedEmployees.Select(employee => employee.EmployeeOid).ToList()),

View File

@@ -1509,8 +1509,8 @@
Grid.Row="1"
Grid.ColumnSpan="2"
HorizontalAlignment="Right"
Orientation="Horizontal"
DataContext="">
DataContext=""
Orientation="Horizontal">
<StackPanel.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>

View File

@@ -3,6 +3,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ai="clr-namespace:BeWo.View.Controls.AI"
xmlns:ai1="clr-namespace:BeWo.AI.Controls"
xmlns:core="clr-namespace:BS.Shared.Core;assembly=BS.Shared"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:detail="clr-namespace:BeWo.View.Detail"
@@ -25,8 +26,7 @@
xmlns:uc="clr-namespace:BeWo.Controls;assembly=BeWo.Controls"
xmlns:val="clr-namespace:BeWo.Validation"
xmlns:ve="http://schemas.devexpress.com/winfx/2008/xaml/docking/visualelements"
xmlns:zeit="clr-namespace:BeWo.View.Detail.Zeiterfassung"
xmlns:ai1="clr-namespace:BeWo.AI.Controls"
xmlns:zeit="clr-namespace:BeWo.View.Detail.Zeiterfassung"
Width="Auto"
Height="Auto"
HorizontalAlignment="Stretch"
@@ -1723,7 +1723,7 @@
Content="{StaticResource AiDesignsIconKIFunktionWeissGruen}"
Style="{StaticResource PrimaryButton}" />
<ai1:VoiceToTextButtonControl TargetTextBox="{Binding ElementName=dokumentationsTextBox}"/>
<ai1:VoiceToTextButtonControl TargetTextBox="{Binding ElementName=dokumentationsTextBox}" />
</StackPanel>
<Button

View File

@@ -9,6 +9,7 @@ using System.Windows.Media;
using System.Windows.Threading;
using BeWo.Core;
using BeWo.Core.Commands;
using BeWo.Core.Service;
using BeWo.ServiceProxy;
using BeWo.View.Controls.AI;
@@ -188,35 +189,38 @@ namespace BeWo.ViewModel.ListViewModel
vm_doku.PromptAccepted += PromptAccepted;
OpenAiPromptSelectionCommand = new DelegateCommand(() =>
{
BeWoApp.MainControl.WindowService.Show(vm_doku);
}, () => !string.IsNullOrWhiteSpace(AktuellerDokutext));
OpenAiPromptSelectionCommand = CommandFactory.GetAiViewCommand(
() => BeWoApp.MainControl.WindowService.Show(vm_doku),
null,
() => !string.IsNullOrWhiteSpace(AktuellerDokutext));
UndoAiActionCommand = new DelegateCommand(UndoAiAction);
RedoAiActionCommand = new DelegateCommand(RedoAiAction);
UndoAiActionCommand = new DelegateCommand(UndoAiAction, () => IsAiButtonVisible);
RedoAiActionCommand = new DelegateCommand(RedoAiAction, () => IsAiButtonVisible);
var vm_edit_doku = new AiPromptbausteinSelectionComplexViewModel(AiActionType.ServiceRecordDocumentation);
vm_edit_doku.PromptAccepted += EditPromptAccepted;
OpenEditAiPromptSelectionCommand = new DelegateCommand(() =>
OpenEditAiPromptSelectionCommand = CommandFactory.GetAiViewCommand(() =>
{
_EditAiActionHistory = new List<string>();
_EditAiActionHistory.Add(AktuellerEditDokutext);
_EditAiActionHistoryIndex = 0;
BeWoApp.MainControl.WindowService.Show(vm_edit_doku);
}, () => !string.IsNullOrWhiteSpace(AktuellerEditDokutext));
},
null,
() => !string.IsNullOrWhiteSpace(AktuellerEditDokutext));
UndoEditAiActionCommand = new DelegateCommand(UndoEditAiAction);
RedoEditAiActionCommand = new DelegateCommand(RedoEditAiAction);
UndoEditAiActionCommand = new DelegateCommand(UndoEditAiAction, () => IsAiButtonVisible);
RedoEditAiActionCommand = new DelegateCommand(RedoEditAiAction, () => IsAiButtonVisible);
_AiActionHistory = new List<string>();
_AiActionHistory.Add(AktuellerDokutext);
_AiActionHistoryIndex = 0;
}
public AiConversationButtonState AiConversationButtonState {
public AiConversationButtonState AiConversationButtonState
{
get => _AiConversationButtonState;
set => SetProperty(ref _AiConversationButtonState, value, nameof(AiConversationButtonState));
}
@@ -243,7 +247,8 @@ namespace BeWo.ViewModel.ListViewModel
}
}
public bool IsAiButtonVisible => SelectedCustomerNode is object && (BeWoApp.AppSettings.ShowAI || BeWoApp.AppSettings.ShowAIVoice);
public bool IsAiModuleEnabled => (BeWoApp.AppSettings.ShowAI || BeWoApp.AppSettings.ShowAIVoice);
public bool IsAiButtonVisible => SelectedCustomerNode is object && IsAiModuleEnabled;
public bool IsUndoButtonVisible => _AiActionHistoryIndex > 0;
public bool IsRedoButtonVisible => _AiActionHistoryIndex < _AiActionHistory.Count - 1;
@@ -466,30 +471,27 @@ namespace BeWo.ViewModel.ListViewModel
public void UpdateViewYearFilter(IEnumerable<ServiceRecordVM> enumerable)
{
if (BeWoApp.AppSettings.ShowAI)
if (!IsAiModuleEnabled)
{
AiConversationButtonState = AiConversationButtonState.Loading;
var context = GetVisibleInformationReferences(enumerable);
if (context != null)
{
var context2 = context.ToDictionary(kv => kv.Key, kv => kv.Value.ToList());
ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.CheckContextSize(AiContextType.ServiceRecord, context2, null),
isValid =>
{
if (isValid)
AiConversationButtonState = AiConversationButtonState.Normal;
else
AiConversationButtonState = AiConversationButtonState.Warning;
},
(exp) => AiConversationButtonState = AiConversationButtonState.Disabled);
}
}
else
{
AiConversationButtonState = AiConversationButtonState.Hidden;
return;
}
AiConversationButtonState = AiConversationButtonState.Loading;
var context = GetVisibleInformationReferences(enumerable);
if (context != null)
{
var context2 = context.ToDictionary(kv => kv.Key, kv => kv.Value.ToList());
ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.CheckContextSize(AiContextType.ServiceRecord, context2, null),
isValid =>
{
if (isValid)
AiConversationButtonState = AiConversationButtonState.Normal;
else
AiConversationButtonState = AiConversationButtonState.Warning;
},
(exp) => AiConversationButtonState = AiConversationButtonState.Disabled);
}
}
@@ -947,7 +949,7 @@ namespace BeWo.ViewModel.ListViewModel
_AiActionHistoryIndex++;
AktuellerDokutext = _AiActionHistory[_AiActionHistoryIndex];
}
public void UndoEditAiAction()
{
if (_EditAiActionHistoryIndex <= 0)

File diff suppressed because one or more lines are too long

View File

@@ -208,7 +208,9 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Lib\NHibernate.dll</HintPath>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="PresentationCore">
<Private>True</Private>
</Reference>
<Reference Include="PresentationFramework" />
<Reference Include="RestSharp, Version=106.13.0.0, Culture=neutral, PublicKeyToken=598062e77f915f75, processorArchitecture=MSIL">
<HintPath>..\packages\RestSharp.106.13.0\lib\net452\RestSharp.dll</HintPath>
@@ -318,6 +320,8 @@
<Compile Include="Controllers\ReportViewerController.cs" />
<Compile Include="Controllers\SchedulerController.cs" />
<Compile Include="Models\AbstractModel.cs" />
<Compile Include="Models\AppointmentModel.cs" />
<Compile Include="Models\AppointmentSessionModel.cs" />
<Compile Include="Models\DevExpressSchedulerSessionModel.cs" />
<Compile Include="Models\EmployeeModel.cs" />
<Compile Include="Models\EmployeeSessionModel.cs" />
@@ -343,6 +347,7 @@
<Compile Include="Models\ReportModel.cs" />
<Compile Include="Models\ReportViewerModel.cs" />
<Compile Include="Models\SchedulerModel.cs" />
<Compile Include="Util\Constants\ViewDataConstants.cs" />
<Compile Include="Util\DcToMokMapper.cs" />
<Compile Include="Util\ISignable.cs" />
<Compile Include="Util\MokSettings.cs" />
@@ -389,6 +394,8 @@
<Compile Include="Util\ReportUtils\QuittierungsbelegsReportSettings.cs" />
<Compile Include="Util\ReportUtils\ReportTimeFrame.cs" />
<Compile Include="Util\JsonPerson.cs" />
<Compile Include="Util\SchedulerUtils\CustomAppointmentTemplateContainer.cs" />
<Compile Include="Util\SchedulerUtils\EmployeeAvailabilityObject.cs" />
<Compile Include="Util\ServiceRecord2Validation.cs" />
<Compile Include="Util\SignatureUtils.cs" />
<Compile Include="Util\SupportConceptStatisticsData.cs" />
@@ -700,6 +707,12 @@
<Content Include="Views\Employee\Employee.cshtml" />
<Content Include="Views\Shared\AbsenceTimeFormPartial.cshtml" />
<Content Include="Views\Shared\AbsenceTimePartial.cshtml" />
<Content Include="Views\DevExpressScheduler\CustomAppointmentFormPartial.cshtml" />
<Content Include="Views\DevExpressScheduler\CustomerMultiSelectPartial.cshtml" />
<Content Include="Views\DevExpressScheduler\ResourceMultiSelectPartial.cshtml" />
<Content Include="Views\DevExpressScheduler\EmployeeMultiSelectPartial.cshtml" />
<Content Include="Views\DevExpressScheduler\VerticalAppointmentTemplatePartial.cshtml" />
<Content Include="Views\DevExpressScheduler\HorizontalAppointmentTemplatePartial.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="packages.config" />

View File

@@ -680,7 +680,6 @@ namespace BeWoPlanerMobil.Controllers
#endregion
#region Bargeldkassen
[Authorize]
private void ReloadBargeldkassen()
{
@@ -1240,7 +1239,6 @@ namespace BeWoPlanerMobil.Controllers
#endregion
#region Abwesenheiten
[Authorize]
[HttpPost]
public ActionResult CreateOrUpdateAbsenceTime(FormCollection formCollection)

View File

@@ -1,16 +1,40 @@
using System;
using System.Collections.Generic;
using System.Web.Mvc;
using BeWoPlanerMobil.Models;
using BeWoPlanerMobil.Models;
using BeWoPlanerMobil.Service;
using BeWoPlanerMobil.Views.DevExpressScheduler;
using BS.Shared;
using BS.Shared.Core;
using BS.Shared.DataContracts;
using BS.Shared.DataContracts.Compact;
using BS.Shared.Extensions;
using DevExpress.Web.Mvc;
using DevExpress.XtraScheduler;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using BeWoPlanerMobil.Util.Constants;
using BeWoPlanerMobil.Util.SchedulerUtils;
namespace BeWoPlanerMobil.Controllers
{
/*
* ToDo:
* 1. Filterung einbauen (Mitarbeiter, Klienten, Ressourcen, Privat, Aufgaben, Abwesenheiten)
* 2. "In die Zeiterfassung übertragen" und "Verfügbare Mitarbeiter prüfen" einbauen
* 3. Rechte implementieren!
* 4. Ressourcen-Farben einbauen -> Templates wie im DemoCenter benutzen
* 5. Übersetzungen
*/
public class DevExpressSchedulerController : AbstractBaseController
{
[Authorize]
public override string SaveCollapsibleStatus(bool isOpen, string identifier)
{
return SaveCollapsibleStatusToModel(Model, isOpen, identifier);
}
private DevExpressSchedulerModel _Model;
public DevExpressSchedulerModel Model
{
@@ -29,11 +53,96 @@ namespace BeWoPlanerMobil.Controllers
_Model = new DevExpressSchedulerModel();
InitModel(_Model);
InitViewModel();
return _Model;
}
}
private AppointmentModel _AppointmentModel;
public AppointmentModel AppointmentModel
{
get
{
if(false == MobileSessionFacade.IsUserLoggedIn())
{
Logout();
return null;
}
if(_AppointmentModel != null)
{
return _AppointmentModel;
}
_AppointmentModel = new AppointmentModel();
InitModel(_AppointmentModel);
InitAppointmentModel();
return _AppointmentModel;
}
}
private void InitAppointmentModel()
{
AppointmentModel.PossibleEmployees = EmployeeService.GetAllAuthorizedCompactEmployees();
AppointmentModel.PossibleCustomers = CustomerService.GetAllAuthorizedCompactCustomers();
AppointmentModel.PossibleResources = KalenderService.GetAllResources();
}
private void InitViewModel()
{
if(!MobileSessionFacade.IsUserLoggedIn() || Request.Browser.Browser.Equals("InternetExplorer") || Model?.LoggedInEmployee?.EmployeeOid is null)
{
Logout();
return;
}
Model.PossibleEmployees = EmployeeService.GetAllAuthorizedCompactEmployees();
Model.PossibleCustomers = CustomerService.GetAllAuthorizedCompactCustomers();
Model.PossibleResources = KalenderService.GetAllResources();
ReloadAppointments();
}
private void ReloadAppointments()
{
if(Model.LoggedInEmployee.EmployeeOid is null)
{
throw new Exception("Bei DevExpressSchedulerController.ReloadAppointments() ist die Oid des angemeldeten Benutzers ist wider Erwarten NULL!");
}
// ToDo: ausgewählte Ansicht laden und speichern!
//Model.ShowBetrag = UserSettingsUtils.GetSettingValueAsBool(Model.Mandator.Settings, SettingsKeys.ShowBetrag);
var user = LoggedInUser;
var userSettings = user?.Settings.FirstOrDefault(f => f.Type.Equals(SettingsType.ApplicationSettings))?.Value;
Model.CurrentViewType = (SchedulerViewType) UserSettingsUtils.GetSettingValueAsInteger(userSettings, SettingsKeys.SchedulerViewType);
var intervalStart = DateTimeExtensions.GetDayOfWeek(DayOfWeek.Monday);
var intervalEnd = intervalStart.AddDays(7);
var appointments = KalenderService.LoadFilteredAppointmentsMitAufgaben
(
Model.HasRightKalenderMitarbeitertermineAnsehen,
Model.LoggedInEmployee.EmployeeOid.Value,
intervalStart,
intervalEnd,
new List<long>(),
new List<long>(),
new List<long>(),
false,
false,
false,
false,
false,
true
);
Model.Appointments = appointments;
}
[Authorize]
public ActionResult DevExpressScheduler()
{
@@ -41,29 +150,12 @@ namespace BeWoPlanerMobil.Controllers
{
return RedirectToActionPermanent("Index", "Login");
}
var appointments = KalenderService.LoadFilteredAppointments(
true,
Model.LoggedInEmployee?.EmployeeOid ?? 1,
DateTime.Today.AddDays(-60),
DateTime.Today.AddDays(60),
new List<long>(),
new List<long>(),
new List<long>(),
false,
false,
false,
false,
false);
Model.Appointments = appointments;
Model.Resources = new List<object>();
return View(Model);
}
[Authorize]
public ActionResult SchedulerPagePartial()
{
@@ -80,15 +172,191 @@ namespace BeWoPlanerMobil.Controllers
[Authorize]
private void UpdateAppointment()
{
var appointmentsToInsert = SchedulerExtension.GetAppointmentsToInsert<SchedulerAppointmentDC>(SchedulerHelper.GetSchedulerSettings(), Model.Appointments);
var appointmentsToUpdate = SchedulerExtension.GetAppointmentsToUpdate<SchedulerAppointmentDC>(SchedulerHelper.GetSchedulerSettings(), Model.Appointments);
var appointmentsToRemove = SchedulerExtension.GetAppointmentsToRemove<SchedulerAppointmentDC>(SchedulerHelper.GetSchedulerSettings(), Model.Appointments);
var appointmentsToInsert = SchedulerExtension.GetAppointmentsToInsert<SchedulerAppointmentDC>(
"scheduler",
Model.Appointments,
SchedulerHelper.DefaultAppointmentStorage,
SchedulerHelper.DefaultResourceStorage);
var appointmentsToUpdate = SchedulerExtension.GetAppointmentsToUpdate<SchedulerAppointmentDC>(
"scheduler",
Model.Appointments,
SchedulerHelper.DefaultAppointmentStorage,
SchedulerHelper.DefaultResourceStorage
);
var appointmentsToRemove = SchedulerExtension.GetAppointmentsToRemove<SchedulerAppointmentDC>(
"scheduler",
Model.Appointments,
SchedulerHelper.DefaultAppointmentStorage,
SchedulerHelper.DefaultResourceStorage
);
foreach(var appointment in appointmentsToInsert)
{
appointment.CustomerList = AppointmentModel.SelectedCustomers;
appointment.ResourceList = AppointmentModel.SelectedResources;
appointment.EmployeeList = new List<Employee2SchedulerAppointmentDC>();
foreach(var selectedEmployee in AppointmentModel.SelectedEmployees ?? new List<CompactEmployeeDC>())
{
appointment.EmployeeList.Add(new Employee2SchedulerAppointmentDC { Employee = selectedEmployee });
}
appointment.Originator = Model.LoggedInUser.Employee;
KalenderService.InsertSchedulerAppointment(appointment);
ViewData["EditableAppointmentModel"] = appointment;
}
foreach(var appointment in appointmentsToUpdate)
{
if(AppointmentModel.SelectedCustomers != null)
{
appointment.CustomerList = AppointmentModel.SelectedCustomers;
}
if(AppointmentModel.SelectedResources != null)
{
appointment.ResourceList = AppointmentModel.SelectedResources;
}
if(AppointmentModel.SelectedEmployees != null)
{
appointment.EmployeeList = new List<Employee2SchedulerAppointmentDC>();
foreach(var selectedEmployee in AppointmentModel.SelectedEmployees)
{
appointment.EmployeeList.Add(new Employee2SchedulerAppointmentDC { Employee = selectedEmployee });
}
}
appointment.ActivationType = ActivationTypeId.Active;
KalenderService.UpdateSchedulerAppointments(new List<SchedulerAppointmentDC> { appointment });
}
KalenderService.DeleteSchedulerAppointments(
appointmentsToRemove
.Where(appointment => appointment.SchedulerAppointmentOid.HasValue && appointment.NewSchedulerAppointmentVersion.HasValue)
.ToDictionary(k => k.SchedulerAppointmentOid.Value, v => v.NewSchedulerAppointmentVersion.Value));
ReloadAppointments();
}
[HttpPost]
public ActionResult CustomerMultiSelectPartial(string value)
{
var selectedCustomerOids = GridLookupExtension.GetSelectedValues<long?>("CustomerGridLookup") ?? Array.Empty<long?>();
AppointmentModel.SelectedCustomerOids = selectedCustomerOids.Where(oid => oid.HasValue).Select(oid => oid.Value).ToList();
return PartialView("CustomerMultiSelectPartial", AppointmentModel);
}
[HttpPost]
public ActionResult ResourceGridLookupPartial(string value)
{
var selectedResourceOids = GridLookupExtension.GetSelectedValues<long?>("ResourceGridLookup") ?? Array.Empty<long?>();
AppointmentModel.SelectedResourceOids = selectedResourceOids.Where(oid => oid.HasValue).Select(oid => oid.Value).ToList();
return PartialView("ResourceMultiSelectPartial", AppointmentModel);
}
[HttpPost]
public ActionResult EmployeeGridLookupPartial(string value)
{
/*
* Im AppointmentModel müssen die PossibleEmployees bleiben, denn daraus wählt man die Mitarbeiter, die noch nicht mit dem Termin
* verknüpft sind und es müssen - zumindest beim Bearbeiten - die bereits mit dem Termin verbundenen Mitarbeiter-zu-Termin-Relationen
* zwischengespeichert werden.
*
*/
var selectedEmployeeOids = GridLookupExtension.GetSelectedValues<long?>("EmployeeGridLookup") ?? Array.Empty<long?>();
AppointmentModel.SelectedEmployeeOids = selectedEmployeeOids.Where(oid => oid.HasValue).Select(oid => oid.Value).ToList();
return PartialView("EmployeeMultiSelectPartial", AppointmentModel);
}
[Authorize]
public override string SaveCollapsibleStatus(bool isOpen, string identifier)
public string SelectActiveViewType(string viewTypeName)
{
return SaveCollapsibleStatusToModel(Model, isOpen, identifier);
if(Enum.TryParse<SchedulerViewType>(viewTypeName, out var viewType))
{
Model.CurrentViewType = viewType;
UpdateUserSettingsWithoutReload(SettingsKeys.SchedulerViewType, ((int) viewType).ToString());
}
return LeerzeichenFuerGetMethoden;
}
[Authorize]
public ActionResult CustomCallbackAction(string apptID, string actionId, string[] args)
{
if(actionId == "ToServiceRecord")
{
// Serientermin
if(apptID.Contains("_"))
{
var splitApptId = apptID.Split('_');
var selectedAppointmentOid = long.Parse(splitApptId[0]);
var recurrenceIndex = int.Parse(splitApptId[1]);
// Hier dann Ausnahme bilden mit ServiceRecord?
var appointment = GetAppointmentFromModelByOid(selectedAppointmentOid);
var test = appointment is null;
}
else
{
if(long.TryParse(apptID, out var selectedAppointmentOid))
{
var appointment = GetAppointmentFromModelByOid(selectedAppointmentOid);
var test = appointment is null;
}
}
return RedirectToActionPermanent("Main", "Main");
}
if(actionId == "ShowAvailableEmployees")
{
var startString = args[0];
var endString = args[1];
var start = DateTime.Parse(startString);
var end = DateTime.Parse(endString);
var availabilities = ReportService.GetMitarbeiterverfuegbarkeiten(AppointmentModel.PossibleEmployees, start, end);
var employee2Overtime = new EmployeeAvailabilityObject(start, end, availabilities);
Model.EmployeeAvailabilityObject = employee2Overtime;
//ViewData[ViewDataConstants.SchedulerEmployeeAvailabilityConstant] = employee2Overtime;
return PartialView("SchedulerPagePartial", Model);
}
return PartialView("SchedulerPagePartial", Model);
}
private SchedulerAppointmentDC GetAppointmentFromModelByOid(long oid)
{
foreach(SchedulerAppointmentDC appointment in Model.Appointments)
{
if(appointment.SchedulerAppointmentOid == oid)
{
return appointment;
}
}
return null;
}
}
}

View File

@@ -3371,7 +3371,7 @@ namespace BeWoPlanerMobil.Controllers
[Authorize]
public ActionResult RedirectToPersons()
{
return RedirectToActionPermanent("Person", "Person", new { id = Model.LoggedInEmployee?.EmployeeOid });
return RedirectToActionPermanent("Person", "Person");
}
[Authorize]
@@ -4232,7 +4232,7 @@ namespace BeWoPlanerMobil.Controllers
return LeerzeichenFuerGetMethoden;
}
/// <summary>

View File

@@ -144,7 +144,6 @@ namespace BeWoPlanerMobil.Controllers
}
#region Dokumente
[Authorize]
public ActionResult SaveDescriptionChange(string descriptionText, long? fileOid)
{

View File

@@ -1,12 +1,14 @@
using DevExpress.Web.Mvc;
using log4net.Config;
using System;
using System.Globalization;
using System.Net;
using System.Threading;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using DevExpress.Web.Mvc;
using log4net.Config;
namespace BeWoPlanerMobil
@@ -16,9 +18,14 @@ namespace BeWoPlanerMobil
public class MvcApplication : HttpApplication
{
protected void Application_Start()
private readonly CultureInfo _CultureInfo = new CultureInfo("de-DE");
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
Thread.CurrentThread.CurrentCulture = _CultureInfo;
Thread.CurrentThread.CurrentUICulture = _CultureInfo;
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
@@ -38,7 +45,11 @@ namespace BeWoPlanerMobil
protected void Application_PreRequestHandlerExecute(object sender, EventArgs e)
{
DevExpressHelper.Theme = "Metropolis";
DevExpressHelper.Theme = "MaterialCompact";
DevExpress.Web.ASPxWebControl.GlobalThemeBaseColor = "#FF5A00";
Thread.CurrentThread.CurrentCulture = _CultureInfo;
Thread.CurrentThread.CurrentUICulture = _CultureInfo;
}
}
}

View File

@@ -289,5 +289,7 @@ namespace BeWoPlanerMobil.Models
public bool HasRightToViewPersonDocuments => CheckForAtLeastOneRight(new[] { UserRightType.ViewAll, UserRightType.DokumentePersonen });
public bool HasRightToViewPersonUmfeld => CheckForAtLeastOneRight(new[] { UserRightType.ViewAll, UserRightType.Person_FamilyView });
public bool HasRightKalenderMitarbeitertermineAnsehen => CheckRight(UserRightType.KalenderMitarbeitertermineAnsehen);
}
}
}

View File

@@ -0,0 +1,201 @@
using BS.Shared.DataContracts;
using System;
using System.Collections.Generic;
using System.Linq;
using BS.Shared.DataContracts.Compact;
namespace BeWoPlanerMobil.Models
{
[Serializable]
public class AppointmentModel : AbstractModel
{
public AppointmentSessionModel AppointmentSessionModel => SessionModel as AppointmentSessionModel;
public long? Oid { get; set; }
public int? EventType { get; set; }
public int? Label { get; set; }
public bool AllDay { get; set; }
public string Location { get; set; }
public int? Status { get; set; }
public string RecurrenceInfo { get; set; }
public string Subject { get; set; }
public DateTime? StartTime { get; set; }
public DateTime? EndTime { get; set; }
public string Description { get; set; }
public bool IsPrivate { get; set; }
public bool CanBeEdited { get; set; }
public bool IsTask { get; set; }
public DateTime? DueDate { get; set; }
public DateTime? CompletedDate { get; set; }
public string CompletedNotice { get; set; }
public string CompletedUser { get; set; }
public string TaskDescription { get; set; }
public List<CompactCustomerDC> SelectedCustomers
{
get
{
return SelectedCustomerOids is null ?
null :
PossibleCustomers.Where(customer => SelectedCustomerOids.Contains(customer.CustomerOid)).ToList();
}
set
{
SelectedCustomerOids = value?.Select(customer => customer.CustomerOid).ToList();
}
}
public List<ResourceDC> SelectedResources
{
get
{
return SelectedResourceOids is null ?
null :
PossibleResources.Where(resource => resource.ResourceOid.HasValue && SelectedResourceOids.Contains(resource.ResourceOid.Value)).ToList();
}
set
{
SelectedResourceOids = value?.Where(resource => resource.ResourceOid.HasValue).Select(resource => resource.ResourceOid.Value).ToList();
}
}
public bool HasServiceRecordEntry { get; set; }
public List<ServiceRecordDC> ServiceRecordList { get; set; }
public List<CompactCustomerDC> PossibleCustomers { get; set; }
public List<ResourceDC> PossibleResources { get; set; }
public List<long> SelectedCustomerOids
{
get => AppointmentSessionModel.SelectedCustomerOids;
set => AppointmentSessionModel.SelectedCustomerOids = value;
}
public List<long> SelectedResourceOids
{
get => AppointmentSessionModel.SelectedResourceOids;
set => AppointmentSessionModel.SelectedResourceOids = value;
}
/* Mitarbeiter */
public List<CompactEmployeeDC> PossibleEmployees { get; set; }
public List<Employee2SchedulerAppointmentDC> SelectedEmployee2SchedulerAppointments { get; set; }
public List<CompactEmployeeDC> SelectedEmployees { get; set; }
public List<long> SelectedEmployeeOids
{
get => AppointmentSessionModel.SelectedEmployeeOids;
set => AppointmentSessionModel.SelectedEmployeeOids = value;
}
public List<long> SelectedEmployees2Appointments
{
get => AppointmentSessionModel.SelectedEmployees2Appointments;
set => AppointmentSessionModel.SelectedEmployees2Appointments = value;
}
/* /Mitarbeiter */
public AppointmentModel()
{
SessionModel = new AppointmentSessionModel();
}
public AppointmentModel(List<CompactCustomerDC> possibleCustomers, List<ResourceDC> possibleResources, List<CompactEmployeeDC> possibleEmployees)
{
PossibleCustomers = possibleCustomers;
PossibleResources = possibleResources;
PossibleEmployees = possibleEmployees;
SessionModel = new AppointmentSessionModel();
}
public AppointmentModel(SchedulerAppointmentDC appointment)
{
if(appointment is null)
{
return;
}
SessionModel = new AppointmentSessionModel();
Oid = appointment.SchedulerAppointmentOid;
EventType = appointment.Type;
AllDay = appointment.AllDay;
Location = appointment.Location;
Status = appointment.Status;
RecurrenceInfo = appointment.RecurrenceInfo;
Subject = appointment.Subject;
StartTime = appointment.StartDate;
EndTime = appointment.EndDate;
Description = appointment.Description;
SelectedCustomers = appointment.CustomerList;
SelectedEmployees = appointment.EmployeeList?.Select(employee2Appointment => employee2Appointment.Employee)?.ToList();
SelectedEmployee2SchedulerAppointments = appointment.EmployeeList;
SelectedResources = appointment.ResourceList;
HasServiceRecordEntry = appointment.HasServiceRecordEntry;
ServiceRecordList = appointment.ServiceRecordList;
CanBeEdited = appointment.CanBeEdited;
IsPrivate = appointment.IsPrivate;
IsTask = appointment.IsTask;
DueDate = appointment.DueDate;
CompletedDate = appointment.CompletedDate;
CompletedNotice = appointment.CompletedNotice;
CompletedUser = appointment.CompletedUser;
TaskDescription = appointment.TaskDescription;
}
public virtual void Assign(AppointmentModel source)
{
if(source is null)
{
return;
}
Oid = source.Oid;
EventType = source.EventType;
Label = source.Label;
AllDay = source.AllDay;
Location = source.Location;
Status = source.Status;
RecurrenceInfo = source.RecurrenceInfo;
Subject = source.Subject;
StartTime = source.StartTime;
EndTime = source.EndTime;
Description = source.Description;
SelectedCustomers = source.SelectedCustomers;
SelectedEmployees = source.SelectedEmployees;
SelectedEmployee2SchedulerAppointments = source.SelectedEmployee2SchedulerAppointments;
SelectedResources = source.SelectedResources;
HasServiceRecordEntry = source.HasServiceRecordEntry;
ServiceRecordList = source.ServiceRecordList;
CanBeEdited = source.CanBeEdited;
IsPrivate = source.IsPrivate;
IsTask = source.IsTask;
DueDate = source.DueDate;
CompletedDate = source.CompletedDate;
CompletedNotice = source.CompletedNotice;
CompletedUser = source.CompletedUser;
TaskDescription = source.TaskDescription;
}
}
}

View File

@@ -0,0 +1,23 @@
using System.Collections.Generic;
namespace BeWoPlanerMobil.Models
{
public class AppointmentSessionModel : BaseSessionModel
{
public List<long> SelectedCustomerOids { get; set; }
public List<long> SelectedEmployeeOids { get; set; }
public List<long> SelectedResourceOids { get; set; }
public List<long> SelectedEmployees2Appointments { get; set; }
public override void ResetValues()
{
base.ResetValues();
SelectedCustomerOids = null;
SelectedEmployeeOids = null;
SelectedResourceOids = null;
SelectedEmployees2Appointments = null;
}
}
}

View File

@@ -1,19 +1,57 @@
using System.Collections;
using DevExpress.Web.ASPxScheduler;
using System.Collections.Generic;
using BeWoPlanerMobil.Util.SchedulerUtils;
using BS.Shared.DataContracts;
using BS.Shared.DataContracts.Compact;
using DevExpress.XtraScheduler;
namespace BeWoPlanerMobil.Models
{
public class DevExpressSchedulerModel : AbstractModel
{
public DevExpressSchedulerModel()
{
SessionModel = new DevExpressSchedulerSessionModel();
SessionModel.ResetValues();
}
public SchedulerViewType CurrentViewType
{
get => DevExpressSchedulerSessionModel.CurrentSchedulerViewType;
set => DevExpressSchedulerSessionModel.CurrentSchedulerViewType = value;
}
public DevExpressSchedulerSessionModel DevExpressSchedulerSessionModel => SessionModel as DevExpressSchedulerSessionModel;
public List<CompactCustomerDC> PossibleCustomers { get; set; }
public List<ResourceDC> PossibleResources { get; set; }
public List<CompactEmployeeDC> PossibleEmployees { get; set; }
public List<CompactCustomerDC> SelectedCustomers { get; set; }
public List<ResourceDC> SelectedResources { get; set; }
public List<CompactEmployeeDC> SelectedEmployees { get; set; }
public List<long> SelectedCustomerOids
{
get => DevExpressSchedulerSessionModel.SelectedCustomerOids;
set => DevExpressSchedulerSessionModel.SelectedCustomerOids = value;
}
public List<long> SelectedEmployeeOids
{
get => DevExpressSchedulerSessionModel.SelectedEmployeeOids;
set => DevExpressSchedulerSessionModel.SelectedEmployeeOids = value;
}
public List<long> SelectedResourceOids
{
get => DevExpressSchedulerSessionModel.SelectedResourceOids;
set => DevExpressSchedulerSessionModel.SelectedResourceOids = value;
}
public EmployeeAvailabilityObject EmployeeAvailabilityObject { get; set; }
public IEnumerable Appointments { get; set; }
public IEnumerable Resources { get; set; }
public string Type { get; set; }
}
public class CustomAppointmentTemplateContainer : AppointmentFormTemplateContainer
{
public CustomAppointmentTemplateContainer(ASPxScheduler scheduler) : base(scheduler) { }
public string CustomInfo => Appointment.CustomFields["AppointmentCustomField"] != null ? Appointment.CustomFields["AppointmentCustomField"].ToString() : "";
}
}

View File

@@ -1,12 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Collections.Generic;
using DevExpress.XtraScheduler;
namespace BeWoPlanerMobil.Models
{
public class DevExpressSchedulerSessionModel
public class DevExpressSchedulerSessionModel : BaseSessionModel
{
public List<long> SelectedCustomerOids { get; set; }
public List<long> SelectedEmployeeOids { get; set; }
public List<long> SelectedResourceOids { get; set; }
public SchedulerViewType CurrentSchedulerViewType { get; set; }
public override void ResetValues()
{
base.ResetValues();
SelectedCustomerOids = null;
SelectedEmployeeOids = null;
SelectedResourceOids = null;
}
}
}

View File

@@ -528,4 +528,28 @@ function array2Csv(array) {
}
return result.replace(/,\s*$/, "");
}
function getTimeStamp(dateObject, showSeconds, showMilliseconds) {
if(showSeconds === false) {
showMilliseconds = false;
}
const dd = String(dateObject.getDate()).padStart(2, "0");
const MM = String(dateObject.getMonth() + 1).padStart(2, "0");
const yyyy = dateObject.getFullYear();
const HH = String(dateObject.getHours()).padStart(2, "0");
const mm = String(dateObject.getMinutes()).padStart(2, "0");
const ss = String(dateObject.getSeconds()).padStart(2, "0");
const ms = String(dateObject.getMilliseconds()).padStart(2, "0");
if(showSeconds === true) {
if(showMilliseconds === true) {
return `${dd}.${MM}.${yyyy} ${HH}:${mm}:${ss}.${ms}`;
} else {
return `${dd}.${MM}.${yyyy} ${HH}:${mm}:${ss}`;
}
} else {
return `${dd}.${MM}.${yyyy} ${HH}:${mm}`;
}
}

View File

@@ -1,15 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Web;
using BeWo.Data.Entities;
using BeWo.Service.DCEntityMapper;
using System.Web;
using BeWo.Service.ServiceContracts;
using BeWo.Service.ServiceImplementations;
using BeWoPlanerMobil.Models;
using BS.Shared;
using BS.Shared.DataContracts;
using BS.Shared.DataContracts.Compact;
using ReportingService.ServiceContracts;
using ReportingService.ServiceImplementations;

View File

@@ -0,0 +1,7 @@
namespace BeWoPlanerMobil.Util.Constants
{
public class ViewDataConstants
{
public static string SchedulerEmployeeAvailabilityConstant => "SchedulerEmployeeAvailability";
}
}

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Text;
@@ -531,5 +532,98 @@ namespace BeWoPlanerMobil.Util
return $"{(serviceRecord.Start.Value.AddMinutes(duration))}";
}
public static string GetColorAsHex(System.Windows.Media.Color color)
{
return $"{color.R:X2}{color.G:X2}{color.B:X2}";
}
public static string ColorArgbToRgbHex(string color)
{
if(color.StartsWith("#") && color.Length == 9)
{
return $"#{color.Substring(3)}";
}
return null;
}
public static string GetAppointmentRightGradient(bool hasCustomers, List<string> colors, int colorCountLimit = 4)
{
if(colors is null)
{
colors = new List<string>();
}
if(colors.Count == 0 && false == hasCustomers)
{
return string.Empty;
}
if(hasCustomers && colors.Count == 0)
{
return "linear-gradient(#3B7799 100.0%)";
}
if(colors.Count > colorCountLimit)
{
colors = colors.GetRange(0, colorCountLimit);
}
var colorCount = colors.Count;
var startingPoint = hasCustomers ? 50 : 0;
var divisor = hasCustomers ? 50 : 100;
if(colorCount == 1)
{
var color = colors.First();
return hasCustomers ? $"linear-gradient(#3B7799 50.0%, {color} 50.0%)" : $"linear-gradient({color})";
}
var result = hasCustomers ? "#3B7799 50.0%, " : string.Empty;
for(var i = 0; i < colorCount; i++)
{
var currentColor = colors[i];
var colorWidth = (double)divisor / colorCount;
var colorStartingPoint = startingPoint + i * colorWidth;
var colorStart = FormattableString.Invariant($"{colorStartingPoint:F1}");
var colorEnd = FormattableString.Invariant($"{colorStartingPoint + colorWidth:F1}");
result += $"{currentColor} {colorStart}%, {currentColor} {colorEnd}%, ";
}
return $"linear-gradient({result.TrimEnd().TrimEnd(',')})";
}
public static string GetAppointmentRightBackground(DevExpress.XtraScheduler.Appointment appointment)
{
var hasCustomers = appointment.CustomFields["Customers"] is List<CompactCustomerDC> customerList && customerList.Any();
var customFieldValue = appointment.CustomFields["Resources"];
var resourceList = customFieldValue as List<ResourceDC> ?? new List<ResourceDC>();
var resourcesWithColors = resourceList.Where(resource => false == IsNullOrWhiteSpace(resource.Color)).ToList();
var resourceColors = (resourcesWithColors.Count > 4 ? resourcesWithColors.GetRange(0, 4) : resourcesWithColors).Select(resource => ColorArgbToRgbHex(resource.Color)).ToList();
return GetAppointmentRightGradient(hasCustomers, resourceColors);
}
public static string GetLeftAppointmentBorder(DevExpress.XtraScheduler.Appointment appointment)
{
if(appointment.CustomFields[nameof(SchedulerAppointmentDC.Originator)] is CompactEmployeeDC originator && originator.FilterableBrush?.Color != null)
{
var color = originator.FilterableBrush.Color;
return $"5px solid #{GetColorAsHex(color)}";
}
return "5px solid #C0FFD0";
}
}
}

View File

@@ -0,0 +1,9 @@
using DevExpress.Web.ASPxScheduler;
namespace BeWoPlanerMobil.Util.SchedulerUtils
{
public class CustomAppointmentTemplateContainer : AppointmentFormTemplateContainer
{
public CustomAppointmentTemplateContainer(ASPxScheduler scheduler) : base(scheduler) { }
}
}

View File

@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using BS.Shared.DataContracts.Compact;
using BS.Shared.Extensions;
namespace BeWoPlanerMobil.Util.SchedulerUtils
{
public class EmployeeAvailabilityObject
{
public DateTime IntervalStart { get; set; }
public DateTime IntervalEnd { get; set; }
public Dictionary<CompactEmployeeDC, decimal> Employee2Overtime { get; set; }
public string Interval
{
get
{
var von = IntervalStart.IsTimeZero() ? $"{IntervalStart:dd.MM.yy}" : $"{IntervalStart:dd.MM.yy HH:mm}";
var bis = IntervalEnd.IsTimeZero() ? $"{IntervalStart:dd.MM.yy}" : $"{IntervalStart:dd.MM.yy HH:mm}";
return $"Verfügbarkeit vom {von} bis {bis}";
}
}
public EmployeeAvailabilityObject(DateTime intervalStart, DateTime intervalEnd, Dictionary<CompactEmployeeDC, decimal> employee2Overtime)
{
IntervalStart = intervalStart;
IntervalEnd = intervalEnd;
Employee2Overtime = employee2Overtime.OrderBy(kvp => kvp.Key.DetailDescription).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
}
}
}

View File

@@ -0,0 +1,255 @@
@model BeWoPlanerMobil.Models.AppointmentModel
@using BS.Shared.DataContracts
@using DevExpress.Web.Mvc.UI
@{
Html.EnableClientValidation();
Html.EnableUnobtrusiveJavaScript();
}
<style type="text/css">
.centeredLabel {
margin: 0 auto;
padding-left: .25em;
}
</style>
@using(Html.BeginForm())
{
<table id="abc-table">
@* Start *@
<tr>
<td style="white-space: nowrap;">
@Html.DevExpress().Label(
settings =>
{
settings.AssociatedControlName = nameof(SchedulerAppointmentDC.StartDate);
settings.Text = "Start:";
settings.Width = Unit.Percentage(100);
}).GetHtml()
</td>
<td colspan="3" style="padding: .25em;">
@Html.DevExpress().DateEdit(
settings =>
{
settings.Name = nameof(SchedulerAppointmentDC.StartDate);
settings.Properties.EditFormat = EditFormat.DateTime;
settings.ShowModelErrors = true;
settings.Properties.ValidationSettings.Display = Display.Dynamic;
settings.Width = Unit.Percentage(100);
}).Bind(Model.StartTime).GetHtml()
</td>
</tr>
@* Ende *@
<tr>
<td style="white-space: nowrap;">
@Html.DevExpress().Label(
settings =>
{
settings.AssociatedControlName = nameof(SchedulerAppointmentDC.EndDate);
settings.Text = "Ende:";
settings.Width = Unit.Percentage(100);
}).GetHtml()
</td>
<td colspan="3" style="padding: .25em;">
@Html.DevExpress().DateEdit(
settings =>
{
settings.Name = nameof(SchedulerAppointmentDC.EndDate);
settings.Properties.EditFormat = EditFormat.DateTime;
settings.ShowModelErrors = true;
settings.Properties.ValidationSettings.Display = Display.Dynamic;
settings.Width = Unit.Percentage(100);
}).Bind(Model.EndTime).GetHtml()
</td>
</tr>
@* Private & Ganztägig *@
<tr>
<td colspan="4">
<table style="width: 100%;">
<tr>
<td style="width: 1%; wihte-space: nowrap;">
@Html.DevExpress().CheckBox(
settings =>
{
settings.Name = nameof(SchedulerAppointmentDC.IsPrivate);
settings.Width = Unit.Percentage(100);
}).Bind(Model.IsPrivate).GetHtml()
</td>
<td style="margin-right: 1em;">
@Html.DevExpress().Label(
settings =>
{
settings.AssociatedControlName = nameof(SchedulerAppointmentDC.IsPrivate);
settings.Text = "Privat";
settings.Width = Unit.Percentage(100);
settings.ControlStyle.CssClass = "centeredLabel";
}).GetHtml()
</td>
<td style="width: 1%; wihte-space: nowrap;">
@Html.DevExpress().CheckBox(
settings =>
{
settings.Name = nameof(SchedulerAppointmentDC.AllDay);
settings.Width = Unit.Percentage(100);
}).Bind(Model.AllDay).GetHtml()
</td>
<td style="margin-right: 1em;">
@Html.DevExpress().Label(
settings =>
{
settings.AssociatedControlName = nameof(SchedulerAppointmentDC.AllDay);
settings.Text = "Ganztägig";
settings.Width = Unit.Percentage(100);
settings.ControlStyle.CssClass = "centeredLabel";
}).GetHtml()
</td>
</tr>
</table>
</td>
</tr>
@* Mitarbeiter, Klienten, Ressourcen *@
<tr>
<td colspan="4">
<table>
<tr>
<td style="width: 33%; padding: .25em;">
@Html.Partial("EmployeeMultiSelectPartial")
</td>
<td style="width: 33%; padding: .25em;">
@Html.Partial("CustomerMultiSelectPartial")
</td>
<td style="width: 33%; padding: .25em;">
@Html.Partial("ResourceMultiSelectPartial")
</td>
</tr>
</table>
</td>
</tr>
@* Betreff *@
<tr>
<td>
@Html.DevExpress().Label(
settings =>
{
settings.AssociatedControlName = nameof(SchedulerAppointmentDC.Subject);
settings.Text = "Betreff:";
settings.Width = Unit.Percentage(100);
}).GetHtml()
</td>
<td colspan="3" style="width: 100%; padding: .25em;">
@Html.DevExpress().TextBox(
settings =>
{
settings.Name = nameof(SchedulerAppointmentDC.Subject);
settings.ShowModelErrors = true;
settings.Properties.ValidationSettings.Display = Display.Dynamic;
settings.Width = Unit.Percentage(100);
}).Bind(Model.Subject).GetHtml()
</td>
</tr>
@* Ort *@
<tr>
<td>
@Html.DevExpress().Label(
settings =>
{
settings.AssociatedControlName = nameof(SchedulerAppointmentDC.Location);
settings.Text = "Ort:";
settings.Width = Unit.Percentage(100);
}).GetHtml()
</td>
<td colspan="3" style="width: 100%; padding: .25em;">
@Html.DevExpress().TextBox(
settings =>
{
settings.Name = nameof(SchedulerAppointmentDC.Location);
settings.ShowModelErrors = true;
settings.Properties.ValidationSettings.Display = Display.Dynamic;
settings.Width = Unit.Percentage(100);
}).Bind(Model.Location).GetHtml()
</td>
</tr>
@* Notiz *@
<tr>
<td colspan="4">
@Html.DevExpress().Label(
settings =>
{
settings.AssociatedControlName = nameof(SchedulerAppointmentDC.Description);
settings.Text = "Notiz:";
settings.Width = Unit.Percentage(100);
}).GetHtml()
</td>
</tr>
<tr>
<td colspan="4">
@Html.DevExpress().Memo(
settings =>
{
settings.Name = nameof(SchedulerAppointmentDC.Description);
settings.Properties.Rows = 4;
settings.ShowModelErrors = true;
settings.Properties.ValidationSettings.Display = Display.Dynamic;
settings.Width = Unit.Percentage(100);
}).Bind(Model.Description).GetHtml()
</td>
</tr>
</table>
@Html.DevExpress().AppointmentRecurrenceForm(ViewBag.AppointmentRecurrenceFormSettings).GetHtml()
<table style="width: 100%">
<tr>
<td style="padding: .25em;">
@Html.DevExpress().Button(
settings =>
{
settings.Name = "Apply";
settings.Text = "OK";
settings.ClientSideEvents.Click = "OnAppointmentFormSave";
}).GetHtml()
</td>
<td style="padding: .25em;">
@Html.DevExpress().Button(
settings =>
{
settings.Name = "Cancel";
settings.Text = "Abbrechen";
settings.ClientSideEvents.Click = "function(s, e){ scheduler.AppointmentFormCancel(); }";
}).GetHtml()
</td>
<td style="padding: .25em;">
@Html.DevExpress().Button(
settings =>
{
settings.Name = "Delete";
settings.Text = "Löschen";
settings.Enabled = ViewBag.DeleteButtonEnabled;
settings.ClientSideEvents.Click = "function(s, e){ scheduler.AppointmentFormDelete(); }";
}).GetHtml()
</td>
</tr>
</table>
<table class="w-100">
<tr>
<td style="width: 100%;">
@Html.DevExpress().SchedulerStatusInfo(
settings =>
{
settings.Name = "schedulerStatusInfo";
settings.Priority = 1;
settings.SchedulerName = "scheduler";
}).GetHtml()
</td>
</tr>
</table>
}

View File

@@ -0,0 +1,50 @@
@model BeWoPlanerMobil.Models.AppointmentModel
@using BS.Shared.DataContracts.Compact
@using DevExpress.Web.Mvc.UI
@Html.DevExpress().GridLookup(settings =>
{
settings.Name = "CustomerGridLookup";
settings.GridViewProperties.CallbackRouteValues = new { controller = "DevExpressScheduler", Action = "CustomerMultiSelectPartial" };
settings.KeyFieldName = nameof(CompactCustomerDC.CustomerOid);
settings.CommandColumn.ShowSelectCheckbox = true;
settings.CommandColumn.Visible = true;
settings.Columns.Add(c =>
{
c.FieldName = nameof(CompactCustomerDC.CustomerOid);
c.Visible = false;
});
settings.Columns.Add(c =>
{
c.FieldName = nameof(CompactCustomerDC.DetailDescription);
c.Caption = nameof(CompactCustomerDC.DetailDescription);
});
settings.Width = Unit.Percentage(100);
settings.Properties.SelectionMode = GridLookupSelectionMode.Multiple;
settings.Properties.TextFormatString = "{1}";
settings.Properties.MultiTextSeparator = "; ";
settings.Properties.Width = 250;
settings.Properties.NullText = "Klienten";
settings.GridViewProperties.Settings.ShowFilterRow = true;
settings.GridViewProperties.Settings.ShowStatusBar = GridViewStatusBarMode.Visible;
settings.GridViewProperties.SettingsPager.EnableAdaptivity = true;
settings.GridViewProperties.SettingsPager.PageSize = 7;
settings.GridViewProperties.SetStatusBarTemplateContent(c =>
{
ViewContext.Writer.Write("<div style=\"padding: 2px 8px 2px 0; float: right\">");
Html.DevExpress().Button(btnSettings =>
{
btnSettings.Name = "btnClose";
btnSettings.UseSubmitBehavior = false;
btnSettings.Text = "Schließen";
btnSettings.ClientSideEvents.Click = "CloseCustomerGridLookup";
}).Render();
ViewContext.Writer.Write("</div>");
});
}).BindList(Model.PossibleCustomers).Bind(Model.SelectedCustomerOids).GetHtml()

View File

@@ -1,7 +1,127 @@
@model BeWoPlanerMobil.Models.DevExpressSchedulerModel
@using BeWoPlanerMobil.Util.Constants
@using BeWoPlanerMobil.Util.SchedulerUtils
@using BS.Shared.DataContracts.Compact
@model BeWoPlanerMobil.Models.DevExpressSchedulerModel
@{
ViewBag.Title = "DevExpressScheduler";
}
@Html.Partial("SchedulerPagePartial", Model)
<script type="text/javascript">
function UpdateSchedulerHeight() {
scheduler.SetHeight(1);
var containerHeight = ASPxClientUtils.GetDocumentClientHeight();
if(document.body.scrollHeight > containerHeight) {
containerHeight = document.body.scrollHeight;
}
scheduler.SetHeight(containerHeight);
}
function resizeSchedulerEditForm() {
const editFormPopup = $("#abc-table").parent().parent().parent();
const vw = $(window).width();
if(editFormPopup.outerWidth() !== undefined && vw < 678) {
const newWidth = vw * .95;
const allChildren = editFormPopup.parent().find("*");
allChildren.each((index, element) => {
const item = $(element);
if(item[0].tagName === "SCRIPT") {
return;
}
if(item.width() > newWidth) {
item.outerWidth(newWidth);
item.css("max-width", newWidth);
}
});
$("#abc-table").siblings().css("max-width", newWidth);
editFormPopup.outerWidth(newWidth);
editFormPopup.css("max-width", newWidth);
editFormPopup.css("left", "0");
editFormPopup.css("top", "0");
editFormPopup.css("position", "relative");
editFormPopup.css("margin", "0 auto");
}
}
function OnAppointmentFormSave(s, e) {
if(IsValidAppointment()) {
scheduler.AppointmentFormSave();
}
}
function IsValidAppointment() {
$.validator.unobtrusive.parse("form");
return $("form").valid();
}
function CloseCustomerGridLookup() {
CustomerGridLookup.ConfirmCurrentSelection();
CustomerGridLookup.HideDropDown();
}
function CloseEmployeeGridLookup() {
EmployeeGridLookup.ConfirmCurrentSelection();
EmployeeGridLookup.HideDropDown();
}
function CloseResourceGridLookup() {
ResourceGridLookup.ConfirmCurrentSelection();
ResourceGridLookup.HideDropDown();
}
ASPxClientControl.GetControlCollection().ControlsInitialized.AddHandler(function(s, e) {
UpdateSchedulerHeight();
});
ASPxClientControl.GetControlCollection().BrowserWindowResized.AddHandler(function(s, e) {
UpdateSchedulerHeight();
});
function onActiveViewChanged(s, e) {
$.get("@Url.Action("SelectActiveViewType")", { viewTypeName: e.newView });
}
function onMenuItemClicked(s, e) {
try {
if(e.itemName === "ToServiceRecord") {
e.handled = true;
scheduler.PerformCallback({ apptID: scheduler.GetSelectedAppointmentIds()[0], actionId: e.itemName });
}
if(e.itemName === "ShowAvailableEmployees") {
const start = scheduler.selection.interval.start;
const duration = scheduler.selection.interval.duration;
const tmpDate = new Date();
const end = new Date(tmpDate.setTime(start.getTime() + duration));
e.handled = true;
scheduler.PerformCallback(
{
apptID: scheduler.GetSelectedAppointmentIds()[0],
actionId: e.itemName,
args: [getTimeStamp(start, false, false), getTimeStamp(end, false, false)]
});
}
} catch(error) {
console.error(error);
}
}
</script>
@using(Html.BeginForm())
{
@Html.Partial("SchedulerPagePartial", Model)
}

View File

@@ -0,0 +1,50 @@
@model BeWoPlanerMobil.Models.AppointmentModel
@using BS.Shared.DataContracts.Compact
@using DevExpress.Web.Mvc.UI
@Html.DevExpress().GridLookup(settings =>
{
// ToDo: Es müssen CompcatEmployee-Objekte sein!
settings.Name = "EmployeeGridLookup";
settings.GridViewProperties.CallbackRouteValues = new { controller = "DevExpressScheduler", Action = "EmployeeGridLookupPartial" };
settings.KeyFieldName = nameof(CompactEmployeeDC.EmployeeOid);
settings.CommandColumn.ShowSelectCheckbox = true;
settings.CommandColumn.Visible = true;
settings.Columns.Add(c =>
{
c.FieldName = nameof(CompactEmployeeDC.EmployeeOid);
c.Visible = false;
});
settings.Columns.Add(c =>
{
c.FieldName = nameof(CompactEmployeeDC.DetailDescription);
c.Caption = nameof(CompactEmployeeDC.DetailDescription);
});
settings.Width = Unit.Percentage(100);
settings.Properties.SelectionMode = GridLookupSelectionMode.Multiple;
settings.Properties.TextFormatString = "{1}";
settings.Properties.MultiTextSeparator = "; ";
settings.Properties.Width = 250;
settings.Properties.NullText = "Mitarbeiter";
settings.GridViewProperties.Settings.ShowFilterRow = true;
settings.GridViewProperties.Settings.ShowStatusBar = GridViewStatusBarMode.Visible;
settings.GridViewProperties.SettingsPager.EnableAdaptivity = true;
settings.GridViewProperties.SettingsPager.PageSize = 7;
settings.GridViewProperties.SetStatusBarTemplateContent(c =>
{
ViewContext.Writer.Write("<div style=\"padding: 2px 8px 2px 0; float: right\">");
Html.DevExpress().Button(btnSettings =>
{
btnSettings.Name = "btnClose3";
btnSettings.UseSubmitBehavior = false;
btnSettings.Text = "Schließen";
btnSettings.ClientSideEvents.Click = "CloseEmployeeGridLookup";
}).Render();
ViewContext.Writer.Write("</div>");
});
}).BindList(Model.PossibleEmployees).Bind(Model.SelectedEmployeeOids).GetHtml()

View File

@@ -0,0 +1,52 @@
@using BeWoPlanerMobil.Util
@model DevExpress.XtraScheduler.Appointment
@functions
{
string GetSubjectAndLocation()
{
var locationPart = false == string.IsNullOrWhiteSpace(Model.Location) ? $" ({Model.Location})" : string.Empty;
return $" {Model.Subject}{locationPart}";
}
string GetHeaderTime()
{
return Model.AllDay ? string.Empty : $"{Model.Start.ToShortTimeString()} - {Model.End.ToShortTimeString()}";
}
}
<style type="text/css">
.horizontal-appointment-template-div {
cursor: default;
background-color: #C0FFD0;
font-family: "Signika Negative";
border-radius: 5px;
}
.horizontal-appointment-info {
white-space: nowrap;
overflow: hidden;
font: 10pt 'Signika Negative';
color: #37414D;
display: block;
}
.horizontal-appointment-label .recurring-label-span {
margin-left: auto;
margin-right: 0;
}
.horizonta.horizontal-appointment-label {
display: inline-block;
margin-right: 5px;
}
</style>
<div class="horizontal-appointment-template-div" style="border-left: @MobileUtils.GetLeftAppointmentBorder(Model);background: @MobileUtils.GetAppointmentRightBackground(Model) right / 5px 100% no-repeat, #C0FFD0;">
<div class="horizontal-appointment-info">
<label class="horizontal-appointment-label">
@GetHeaderTime() <span style="font-weight: bold;">@GetSubjectAndLocation()</span>
</label>
</div>
</div>

View File

@@ -0,0 +1,48 @@
@model BeWoPlanerMobil.Models.AppointmentModel
@using BS.Shared.DataContracts
@using DevExpress.Web.Mvc.UI
@Html.DevExpress().GridLookup(settings =>
{
settings.Name = "ResourceGridLookup";
settings.GridViewProperties.CallbackRouteValues = new { Controller = "DevExpressScheduler", Action = "ResourceGridLookupPartial" };
settings.KeyFieldName = nameof(ResourceDC.ResourceOid);
settings.CommandColumn.ShowSelectCheckbox = true;
settings.CommandColumn.Visible = true;
settings.Columns.Add(c =>
{
c.FieldName = nameof(ResourceDC.ResourceOid);
c.Visible = false;
});
settings.Columns.Add(c =>
{
c.FieldName = nameof(ResourceDC.Name);
c.Caption = nameof(ResourceDC.Name);
});
settings.Width = Unit.Percentage(100);
settings.Properties.SelectionMode = GridLookupSelectionMode.Multiple;
settings.Properties.TextFormatString = "{1}";
settings.Properties.MultiTextSeparator = "; ";
settings.Properties.NullText = "Ressourcen";
settings.GridViewProperties.Settings.ShowFilterRow = true;
settings.GridViewProperties.Settings.ShowStatusBar = GridViewStatusBarMode.Visible;
settings.GridViewProperties.SettingsPager.EnableAdaptivity = true;
settings.GridViewProperties.SettingsPager.PageSize = 7;
settings.GridViewProperties.SetStatusBarTemplateContent(c =>
{
ViewContext.Writer.Write("<div style=\"padding: 2px 8px 2px 0; float: right\">");
Html.DevExpress().Button(btnSettings =>
{
btnSettings.Name = "btnClose2";
btnSettings.UseSubmitBehavior = false;
btnSettings.Text = "Schließen";
btnSettings.ClientSideEvents.Click = "CloseResourceGridLookup";
}).Render();
ViewContext.Writer.Write("</div>");
});
}).BindList(Model.PossibleResources).Bind(Model.SelectedResourceOids).GetHtml()

View File

@@ -1,83 +1,62 @@
using System;
using System.Web.Mvc;
using System.Web.UI.WebControls;
using DevExpress.Web.ASPxScheduler;
using DevExpress.Web.Mvc;
using DevExpress.XtraScheduler;
using DayView = DevExpress.Web.ASPxScheduler.DayView;
// TODO:
/*
*
* ToDo am 08.12.2025: Folgende Klassen erstellen:
*
* 1: SchedulerDataHelper mit Datenbankzugriffen
* GetAppointments()
* GetResources()
*
*
*
*
*
*
*
* 1. SchedulerDataObject
*
*/
using BS.Shared.DataContracts;
namespace BeWoPlanerMobil.Views.DevExpressScheduler
{
public static class SchedulerHelper
{
private static MVCxAppointmentStorage _DefaultAppointmentStorage;
public static MVCxAppointmentStorage DefaultAppointmentStorage => _DefaultAppointmentStorage ?? (_DefaultAppointmentStorage = CreateDefaultAppointmentStorage());
private static MVCxResourceStorage _DefaultResourceStorage;
public static MVCxResourceStorage DefaultResourceStorage => _DefaultResourceStorage ?? (_DefaultResourceStorage = CreateDefaultResourceStorage());
private static MVCxAppointmentStorage CreateDefaultAppointmentStorage()
{
var appointmentStorage = new MVCxAppointmentStorage();
SetupMappings(appointmentStorage);
appointmentStorage.Mappings.AppointmentId = nameof(SchedulerAppointmentDC.SchedulerAppointmentOid);
appointmentStorage.Mappings.Type = nameof(SchedulerAppointmentDC.Type);
appointmentStorage.Mappings.Label = nameof(SchedulerAppointmentDC.LabelKey);
appointmentStorage.Mappings.AllDay = nameof(SchedulerAppointmentDC.AllDay);
appointmentStorage.Mappings.Location = nameof(SchedulerAppointmentDC.Location);
appointmentStorage.Mappings.Status = nameof(SchedulerAppointmentDC.Status);
appointmentStorage.Mappings.RecurrenceInfo = nameof(SchedulerAppointmentDC.RecurrenceInfo);
appointmentStorage.Mappings.Subject = nameof(SchedulerAppointmentDC.Subject);
appointmentStorage.Mappings.Start = nameof(SchedulerAppointmentDC.StartDate);
appointmentStorage.Mappings.End = nameof(SchedulerAppointmentDC.EndDate);
appointmentStorage.Mappings.Description = nameof(SchedulerAppointmentDC.Description);
appointmentStorage.Mappings.ReminderInfo = nameof(SchedulerAppointmentDC.ReminderInfo);
appointmentStorage.Mappings.ResourceId = "ResourceID";
appointmentStorage.CustomFieldMappings.Add("CustomFieldStorage", "CustomFieldStorage");
appointmentStorage.CustomFieldMappings.Add(new ASPxAppointmentCustomFieldMapping("Originator", nameof(SchedulerAppointmentDC.Originator)));
appointmentStorage.CustomFieldMappings.Add(new ASPxAppointmentCustomFieldMapping("Customers", nameof(SchedulerAppointmentDC.CustomerList)));
appointmentStorage.CustomFieldMappings.Add(new ASPxAppointmentCustomFieldMapping("Employees", nameof(SchedulerAppointmentDC.EmployeeList)));
appointmentStorage.CustomFieldMappings.Add(new ASPxAppointmentCustomFieldMapping("Resources", nameof(SchedulerAppointmentDC.ResourceList)));
appointmentStorage.CustomFieldMappings.Add(new ASPxAppointmentCustomFieldMapping("IsPrivate", "IsPrivate"));
appointmentStorage.CustomFieldMappings.Add(new ASPxAppointmentCustomFieldMapping("CanBeEdited", "CanBeEdited"));
appointmentStorage.CustomFieldMappings.Add(new ASPxAppointmentCustomFieldMapping("HasServiceRecordEntry", "HasServiceRecordEntry"));
appointmentStorage.CustomFieldMappings.Add(new ASPxAppointmentCustomFieldMapping("ServiceRecordList", "ServiceRecordList"));
appointmentStorage.CustomFieldMappings.Add(new ASPxAppointmentCustomFieldMapping("IsAbsenceTime", "IsAbsenceTime"));
appointmentStorage.CustomFieldMappings.Add(new ASPxAppointmentCustomFieldMapping("IsCustomerAbsenceTime", "IsCustomerAbsenceTime"));
appointmentStorage.CustomFieldMappings.Add(new ASPxAppointmentCustomFieldMapping("AbsenceTimeStart", "AbsenceTimeStart"));
appointmentStorage.CustomFieldMappings.Add(new ASPxAppointmentCustomFieldMapping("AbsenceTimeEnd", "AbsenceTimeEnd"));
appointmentStorage.CustomFieldMappings.Add(new ASPxAppointmentCustomFieldMapping("AbsenceTimeOid", "AbsenceTimeOid"));
appointmentStorage.CustomFieldMappings.Add(new ASPxAppointmentCustomFieldMapping("IsTask", "IsTask"));
appointmentStorage.CustomFieldMappings.Add(new ASPxAppointmentCustomFieldMapping("DueDate", "DueDate"));
appointmentStorage.CustomFieldMappings.Add(new ASPxAppointmentCustomFieldMapping("CompletedDate", "CompletedDate"));
appointmentStorage.CustomFieldMappings.Add(new ASPxAppointmentCustomFieldMapping("CompletedNotice", "CompletedNotice"));
appointmentStorage.CustomFieldMappings.Add(new ASPxAppointmentCustomFieldMapping("CompletedUser", "CompletedUser"));
appointmentStorage.CustomFieldMappings.Add(new ASPxAppointmentCustomFieldMapping("TaskDescription", "TaskDescription"));
return appointmentStorage;
}
public static void SetupMappings(MVCxAppointmentStorage storage)
{
storage.Mappings.AppointmentId = "Oid";
storage.Mappings.Start = "StartDate";
storage.Mappings.End = "EndDate";
storage.Mappings.Subject = "Subject";
storage.Mappings.Description = "Description";
storage.Mappings.Label = "LabelId";
storage.Mappings.AllDay = "AllDay";
storage.Mappings.ResourceId = "ResourceId";
storage.Mappings.RecurrenceInfo = "RecurrenceInfo";
storage.Mappings.ReminderInfo = "ReminderInfo";
storage.Mappings.Location = "Location";
storage.Mappings.Type = "EventType";
storage.Mappings.Status = "Status";
}
public static void ApplyCommonViewSettings(DayView view)
{
view.ResourcesPerPage = 1;
ApplyWorkTime(view);
}
private static void ApplyWorkTime(DayView view)
{
view.WorkTime.Start = TimeSpan.FromHours(7);
view.WorkTime.End = TimeSpan.FromHours(20);
view.ShowWorkTimeOnly = true;
}
private static MVCxResourceStorage _DefaultResourceStorage;
public static MVCxResourceStorage DefaultResourceStorage => _DefaultResourceStorage ?? (_DefaultResourceStorage = CreateDefaultResourceStorage());
private static MVCxResourceStorage CreateDefaultResourceStorage()
{
var resourceStorage = new MVCxResourceStorage();
@@ -87,54 +66,5 @@ namespace BeWoPlanerMobil.Views.DevExpressScheduler
return resourceStorage;
}
public static SchedulerSettings GetSchedulerSettings()
{
return GetSchedulerSettings(null);
}
public static SchedulerSettings GetSchedulerSettings(this HtmlHelper customHtml)
{
var settings = new SchedulerSettings
{
Name = "scheduler",
CallbackRouteValues = new { Controller = "DevExpressScheduler", Action = "SchedulerPagePartial" },
EditAppointmentRouteValues = new { Controller = "DevExpressScheduler", Action = "EditAppointment" },
};
ApplyCommonViewSettings(settings.Views.DayView);
ApplyCommonViewSettings(settings.Views.WorkWeekView);
ApplyCommonViewSettings(settings.Views.FullWeekView);
settings.Views.FullWeekView.Enabled = true;
settings.Views.WeekView.Enabled = false;
settings.Views.MonthView.ResourcesPerPage = 1;
settings.Views.MonthView.AppointmentDisplayOptions.StartTimeVisibility = AppointmentTimeVisibility.Never;
settings.Views.MonthView.AppointmentDisplayOptions.EndTimeVisibility = AppointmentTimeVisibility.Never;
settings.Views.MonthView.AppointmentDisplayOptions.StatusDisplayType = AppointmentStatusDisplayType.Bounds;
settings.Views.MonthView.AppointmentDisplayOptions.ShowRecurrence = true;
settings.Views.MonthView.MonthViewStyles.DateCellBody.Height = Unit.Pixel(170);
TimeScale[] timeScales =
{
new TimeScaleYear { Enabled = false },
new TimeScaleQuarter { Enabled = false },
new TimeScaleMonth(),
new TimeScaleFixedInterval { Enabled = false },
new TimeScaleDay(),
new TimeScaleHour { Enabled = false }
};
settings.Views.TimelineView.Scales.AddRange(timeScales);
settings.Views.TimelineView.ResourcesPerPage = 2;
settings.Storage.EnableReminders = false;
settings.Storage.Resources.Assign(DefaultResourceStorage);
settings.Storage.Appointments.Assign(DefaultAppointmentStorage);
settings.Views.DayView.Styles.ScrollAreaHeight = new Unit(500);
return settings;
}
}
}

View File

@@ -1,62 +1,246 @@
@using BeWoPlanerMobil.Views.DevExpressScheduler
@using BeWoPlanerMobil.Models
@using BeWoPlanerMobil.Util.Constants
@using BeWoPlanerMobil.Util.SchedulerUtils
@using BeWoPlanerMobil.Views.DevExpressScheduler
@using BS.Shared.DataContracts
@using DevExpress.Data.Helpers
@using BS.Shared.DataContracts.Compact
@using DevExpress.XtraScheduler
@using MenuItem = DevExpress.Web.MenuItem
@using PopupMenuShowingEventArgs = DevExpress.Web.ASPxScheduler.PopupMenuShowingEventArgs
@model BeWoPlanerMobil.Models.DevExpressSchedulerModel
@functions
{
//ToDo: So das EditForm verändern!
//https://docs.devexpress.com/AspNetMvc/119776/components/scheduler/get-started/how-to-customize-the-appointment-dialog-using-view-model-api-working-with-custom-fields?utm_source=SupportCenter&utm_medium=website&utm_campaign=docs-feedback&utm_content=T743814
static AppointmentRecurrenceFormSettings CreateAppointmentRecurrenceFormSettings(CustomAppointmentTemplateContainer container)
{
return new AppointmentRecurrenceFormSettings
{
Name = "appointmentRecurrenceForm",
Width = Unit.Percentage(100),
IsRecurring = container.Appointment.IsRecurring,
DayNumber = container.RecurrenceDayNumber,
End = container.RecurrenceEnd,
Month = container.RecurrenceMonth,
OccurrenceCount = container.RecurrenceOccurrenceCount,
Periodicity = container.RecurrencePeriodicity,
RecurrenceRange = container.RecurrenceRange,
Start = container.Start,
WeekDays = container.RecurrenceWeekDays,
WeekOfMonth = container.RecurrenceWeekOfMonth,
RecurrenceType = container.RecurrenceType,
IsFormRecreated = container.IsFormRecreated
};
}
static void PopupMenuShowing(object s, PopupMenuShowingEventArgs e)
{
var menuId = e.Menu.MenuId;
var invisibleMenuItemNames = new List<string>
{
"StatusSubMenu",
"LabelSubMenu",
"StatusSubMenu",
"LabelSubMenu",
"NewAllDayEvent",
"NewRecurringEvent"
};
if(menuId == SchedulerMenuItemId.AppointmentMenu)
{
e.Menu.Items.Add(new MenuItem("In die Zeiterfassung übertragen", "ToServiceRecord"));
}
if(menuId == SchedulerMenuItemId.DefaultMenu)
{
e.Menu.Items.Add(new MenuItem("Verfügbare Mitarbeiter anzeigen", "ShowAvailableEmployees"));
}
foreach(MenuItem item in e.Menu.Items)
{
if(invisibleMenuItemNames.Contains(item.Name))
{
item.Visible = false;
}
if(item.Name == "SwitchViewMenu")
{
foreach(MenuItem subItem in item.Items)
{
switch(subItem.Text)
{
case "Day View":
subItem.Text = "Tag";
break;
case "Work Week View":
subItem.Text = "Arbeitswoche";
break;
case "Week View":
subItem.Text = "Woche";
break;
case "Month View":
subItem.Text = "Monat";
break;
case "Timeline View":
subItem.Text = "Zeitstrahl";
break;
case "Agenda View":
subItem.Text = "Agenda";
break;
}
}
}
switch(item.Text)
{
case "Open":
item.Text = "Öffnen";
break;
case "Edit Series":
item.Text = "Serie bearbeiten";
break;
case "Restore Default State":
item.Text = "Serienelement wiederherstellen";
break;
case "Delete":
item.Text = "Löschen";
break;
case "New Appointment":
item.Text = "Neuer Termin";
break;
case "New Recurring Appointment":
item.Text = "Neuer Serientermin";
break;
case "Go to Today":
item.Text = "Heute";
break;
case "Go to Date...":
item.Text = "Gehe zu Datum...";
break;
case "Change View To":
item.Text = "Ansicht wechseln";
break;
case "60 Minutes":
item.Text = "60 Minuten";
break;
case "30 Minutes":
item.Text = "30 Minuten";
break;
case "15 Minutes":
item.Text = "15 Minuten";
break;
case "10 Minutes":
item.Text = "10 Minuten";
break;
case "6 Minutes":
item.Text = "6 Minuten";
break;
case "5 Minutes":
item.Text = "5 Minuten";
break;
}
}
}
}
@{
var scheduler = Html.DevExpress().Scheduler(
settings =>
{
settings.Name = "scheduler";
settings.OptionsAdaptivity.Enabled = true;
settings.CallbackRouteValues = new { Controller = "DevExpressScheduler", Action = "SchedulerPagePartial" };
settings.EditAppointmentRouteValues = new { Controller = "DevExpressScheduler", Action = "EditAppointment" };
settings.CustomActionRouteValues = new { Controller = "DevExpressScheduler", Action = "CustomCallBackAction" };
settings.ActiveViewType = Model.CurrentViewType;
settings.OptionsView.VerticalScrollBarMode = ScrollBarMode.Auto;
settings.OptionsToolTips.ShowSelectionToolTip = false;
settings.ClientSideEvents.ActiveViewChanging = "onActiveViewChanged";
settings.ClientSideEvents.MenuItemClicked = "onMenuItemClicked";
settings.PopupMenuShowing = PopupMenuShowing;
settings.Storage.Appointments.Assign(SchedulerHelper.DefaultAppointmentStorage);
settings.Storage.EnableReminders = false;
settings.OptionsBehavior.ClientTimeZoneId = "W. Europe Standard Time";
settings.Width = Unit.Percentage(100);
settings.Height = Unit.Percentage(100);
SchedulerHelper.ApplyCommonViewSettings(settings.Views.DayView);
SchedulerHelper.ApplyCommonViewSettings(settings.Views.WorkWeekView);
SchedulerHelper.ApplyCommonViewSettings(settings.Views.FullWeekView);
settings.Views.DayView.DayCount = 1;
settings.Views.FullWeekView.Enabled = true;
settings.Views.WeekView.Enabled = false;
settings.Views.MonthView.ResourcesPerPage = 1;
settings.Views.MonthView.AppointmentDisplayOptions.StartTimeVisibility = AppointmentTimeVisibility.Never;
settings.Views.MonthView.AppointmentDisplayOptions.EndTimeVisibility = AppointmentTimeVisibility.Never;
settings.Views.MonthView.AppointmentDisplayOptions.StatusDisplayType = AppointmentStatusDisplayType.Bounds;
settings.Views.MonthView.AppointmentDisplayOptions.ShowRecurrence = true;
settings.Views.MonthView.MonthViewStyles.DateCellBody.Height = Unit.Pixel(170);
settings.Start = BS.Shared.Extensions.DateTimeExtensions.GetDayOfWeek(DayOfWeek.Monday);
settings.OptionsForms.RecurrenceFormName = "appointmentRecurrenceForm";
TimeScale[] timeScales =
settings.ClientSideEvents.EndCallback = "resizeSchedulerEditForm";
settings.ClientSideEvents.Init = "resizeSchedulerEditForm";
settings.AppointmentFormShowing = (sender, e) =>
{
new TimeScaleYear { Enabled = false },
new TimeScaleQuarter { Enabled = false },
new TimeScaleMonth(),
new TimeScaleFixedInterval { Enabled = false },
new TimeScaleDay(),
new TimeScaleHour { Enabled = false }
if(sender is MVCxScheduler scheduler)
{
e.Container = new CustomAppointmentTemplateContainer(scheduler);
}
};
settings.Views.TimelineView.Scales.AddRange(timeScales);
settings.Views.TimelineView.ResourcesPerPage = 2;
settings.Views.WeekView.SetHorizontalAppointmentTemplateContent(c => { Html.RenderPartial("HorizontalAppointmentTemplatePartial", c.AppointmentViewInfo); });
settings.Storage.EnableReminders = false;
settings.Storage.Resources.Assign(SchedulerHelper.DefaultResourceStorage);
settings.Storage.Appointments.Assign(SchedulerHelper.DefaultAppointmentStorage);
settings.Views.MonthView.SetHorizontalAppointmentTemplateContent(c => { Html.RenderPartial("HorizontalAppointmentTemplatePartial", c.AppointmentViewInfo); });
settings.Storage.Appointments.Assign(SchedulerHelper.DefaultAppointmentStorage);
settings.Storage.Resources.Assign(SchedulerHelper.DefaultResourceStorage);
settings.Storage.Appointments.Mappings.Start = nameof(SchedulerAppointmentDC.StartDate);
settings.Storage.Appointments.Mappings.End = nameof(SchedulerAppointmentDC.EndDate);
settings.Storage.Appointments.Mappings.Subject = nameof(SchedulerAppointmentDC.Subject);
settings.Storage.Appointments.Mappings.AllDay = nameof(SchedulerAppointmentDC.AllDay);
settings.Storage.Appointments.Mappings.Description = nameof(SchedulerAppointmentDC.Description);
settings.Storage.Appointments.Mappings.Status = nameof(SchedulerAppointmentDC.Status);
settings.Storage.Appointments.Mappings.Label = nameof(SchedulerAppointmentDC.LabelKey);
settings.Storage.Appointments.Mappings.Type = nameof(SchedulerAppointmentDC.Type);
settings.Views.DayView.SetVerticalAppointmentTemplateContent(c => { Html.RenderPartial("VerticalAppointmentTemplatePartial", c.AppointmentViewInfo); });
settings.Views.DayView.SetHorizontalAppointmentTemplateContent(c => { Html.RenderPartial("HorizontalAppointmentTemplatePartial", c.AppointmentViewInfo); });
settings.Views.DayView.Styles.ScrollAreaHeight = new Unit(500);
settings.Views.WorkWeekView.SetVerticalAppointmentTemplateContent(c => { Html.RenderPartial("VerticalAppointmentTemplatePartial", c.AppointmentViewInfo); });
settings.Views.WorkWeekView.SetHorizontalAppointmentTemplateContent(c => { Html.RenderPartial("HorizontalAppointmentTemplatePartial", c.AppointmentViewInfo.Appointment); });
settings.OptionsForms.SetAppointmentFormTemplateContent(c =>
{
var container = (CustomAppointmentTemplateContainer) c;
var oid = (long?) container.Appointment.Id;
// Die bereits ausgewählten Mitarbeiter-Termin-Relationen beim Bearbeiten:
var employees2Appointment = container.Appointment.CustomFields["Employees"] as List<Employee2SchedulerAppointmentDC> ?? new List<Employee2SchedulerAppointmentDC>();
var customerList = container.Appointment.CustomFields["Customers"] as List<CompactCustomerDC>;
var resourceList = container.Appointment.CustomFields["Resources"] as List<ResourceDC>;
var newModel = new AppointmentModel(Model.PossibleCustomers, Model.PossibleResources, Model.PossibleEmployees)
{
Oid = oid,
Subject = container.Appointment.Subject,
Location = container.Appointment.Location,
StartTime = container.Appointment.Start,
EndTime = container.Appointment.End,
AllDay = container.Appointment.AllDay,
Description = container.Appointment.Description,
EventType = (int?)container.Appointment.Type,
SelectedEmployee2SchedulerAppointments = employees2Appointment,
SelectedCustomers = customerList,
SelectedResources = resourceList,
SelectedEmployeeOids = employees2Appointment.Select(employee2Appointment => employee2Appointment.Employee.EmployeeOid).ToList(),
CompletedNotice = container.Appointment.CustomFields["CompletedNotice"]?.ToString(),
CompletedUser = container.Appointment.CustomFields["CompletedUser"]?.ToString(),
TaskDescription = container.Appointment.CustomFields["TaskDescription"]?.ToString(),
HasServiceRecordEntry = container.Appointment.CustomFields["HasServiceRecordEntry"] is true,
CanBeEdited = container.Appointment.CustomFields["CanBeEdited"] is true,
IsPrivate = container.Appointment.CustomFields["IsPrivate"] is true,
IsTask = container.Appointment.CustomFields["IsTask"] is true,
DueDate = container.Appointment.CustomFields["DueDate"] is DateTime dueDate ? dueDate : null,
CompletedDate = container.Appointment.CustomFields["CompletedDate"] is DateTime completedDate ? completedDate : null
};
var appointmentModel = ViewData["EditableAppointmentModel"] != null ? (AppointmentModel)ViewData["EditableAppointmentModel"] : newModel;
ViewBag.DeleteButtonEnabled = container.CanDeleteAppointment;
ViewBag.IsRecurring = container.Appointment.IsRecurring;
ViewBag.AppointmentRecurrenceFormSettings = CreateAppointmentRecurrenceFormSettings(container);
Html.RenderPartial("CustomAppointmentFormPartial", appointmentModel);
});
});
if(ViewData["SchedulerErrorText"] != null)
@@ -65,4 +249,49 @@
}
}
@scheduler.Bind(Model.Appointments,Model.Resources).GetHtml()
@scheduler.Bind(Model.Appointments,Model.Resources).GetHtml()
@* Mitarbeiterverfügbarkeitenpopup *@
@if(Model.EmployeeAvailabilityObject != null)
{
@*<script type="text/javascript">
$(document).ready(() => {
$("#employee-availability-popup").modal("show");
});
</script>*@
<div class="modal" data-backdrop="static" tabindex="-1" role="dialog" id="employee-availability-popup">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
@Model.EmployeeAvailabilityObject.Interval
</div>
<div class="modal-body">
<table class="table table-sm table-striped">
<thead>
<tr>
<th scope="col">Mitarbeiter</th>
<th scope="col">Überstunden</th>
</tr>
</thead>
@foreach(var emp2Overtime in Model.EmployeeAvailabilityObject.Employee2Overtime)
{
<tr>
<td>
@emp2Overtime.Key.DetailDescription
</td>
<td>
@emp2Overtime.Value.ToString("0.00")
</td>
</tr>
}
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Schließen</button>
</div>
</div>
</div>
</div>
}

View File

@@ -0,0 +1,80 @@
@using BeWoPlanerMobil.Util
@using BS.Shared.DataContracts
@using DevExpress.Web.ASPxScheduler.Drawing
@model AppointmentViewInfo
@functions{
string GetHeaderText(){
return $"{Model.AppointmentInterval.Start.ToShortTimeString()} - {Model.Appointment.End.ToShortTimeString()}";
}
string GetRight()
{
var serviceRecords = Model.Appointment.CustomFields[nameof(SchedulerAppointmentDC.ServiceRecordList)] as List<ServiceRecordDC> ?? new List<ServiceRecordDC>();
return serviceRecords.Any() ? "40px" : "23px";
}
}
<style type="text/css">
.verticalTemplate {
position: absolute;
top: 3px;
left: 3px;
height: 90%;
width: 90%;
overflow: hidden;
cursor: default;
background-color: #C0FFD0;
font-family: "Signika Negative";
border-radius: 5px;
}
.verticalTemplateInfoDiv {
white-space: nowrap;
overflow: hidden;
font: 10pt 'Signika Negative';
color: #37414D;
margin: .25em;
display: block;
}
.vertical-appointment-label .recurring-label-span {
margin-left: auto;
margin-right: 0;
}
.vertical-appointment-label {
display: inline-block;
margin-right: 5px;
}
</style>
<div class="verticalTemplate" style="border-left: @MobileUtils.GetLeftAppointmentBorder(Model.Appointment);background: @MobileUtils.GetAppointmentRightBackground(Model.Appointment) right / 5px 100% no-repeat, #C0FFD0;">
<div class="verticalTemplateInfoDiv">
<label class="vertical-appointment-label text-truncate" style="width: 90%;">
@GetHeaderText() <span style="font-weight: bold;">@Model.Appointment.Subject (@Model.Appointment.Location)</span>
</label>
<div class="clearfix d-inline">
@if(Model.Appointment.CustomFields[nameof(SchedulerAppointmentDC.ServiceRecordList)] is List<ServiceRecordDC> serviceRecords && serviceRecords.Any())
{
<i class="fas fa-clock text-bewo-service-records float-right recurring-label-span mr-1"></i>
}
@if(Model.Appointment.IsRecurring)
{
if(Model.Appointment.Id is long)
{
<span class="fa-stack fa-1x text-info float-right" style="height:fit-content;width:fit-content;position:absolute;top:10px;right:@GetRight();">
<i class="fas fa-solid fa-stack-1x fa-slash"></i>
<i class="fas fa-solid fa-stack-1x fa-sync-alt"></i>
</span>
}
else
{
<i class="fas fa-sync-alt text-info float-right mr-1 recurring-label-span"></i>
}
}
</div>
</div>
</div>

View File

@@ -1,5 +1,4 @@
@using BeWoPlanerMobil.Controllers
@using BeWoPlanerMobil.Models
@using BeWoPlanerMobil.Service
@using BeWoPlanerMobil.Util
@@ -29,6 +28,7 @@
<script type="text/javascript" src="@Scripts.Url("~/Scripts/jquery/jquery-3.7.1.min.js")"></script>
<script type="text/javascript" src="@Scripts.Url("~/Scripts/devexpress-dependencies/jquery/jquery.validate.min.js")"></script>
<script type="text/javascript" src="@Scripts.Url("~/Scripts/devexpress-dependencies/jquery/jquery.unobtrusive-ajax.min.js")"></script>
<script type="text/javascript" src="@Scripts.Url("~/Scripts/jquery.validate.unobtrusive.min.js")"></script>
<script type="text/javascript" src="@Scripts.Url("~/Scripts/knockout-3.5.1.js")"></script>
<script type="text/javascript" src="@Scripts.Url("~/Scripts/bootstrap/bootstrap.bundle.min.js")"></script>

View File

@@ -1,173 +1,177 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- GLOBAL -->
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
<sectionGroup name="devExpress">
<section name="compression" type="DevExpress.Web.CompressionConfigurationSection, DevExpress.Web.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" requirePermission="false" />
<section name="themes" type="DevExpress.Web.ThemesConfigurationSection, DevExpress.Web.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" requirePermission="false" />
<section name="errors" type="DevExpress.Web.ErrorsConfigurationSection, DevExpress.Web.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" requirePermission="false" />
<section name="settings" type="DevExpress.Web.SettingsConfigurationSection, DevExpress.Web.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" requirePermission="false" />
<section name="resources" type="DevExpress.Web.ResourcesConfigurationSection, DevExpress.Web.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" requirePermission="false" />
</sectionGroup>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<system.diagnostics>
<sources>
<source name="System.ServiceModel" switchValue="All">
<listeners>
<add type="System.Diagnostics.DefaultTraceListener" name="Default">
<filter type="" />
</add>
<add initializeData="logs\Traces.svclog" type="System.Diagnostics.XmlWriterTraceListener" name="traceListener" traceOutputOptions="DateTime">
<filter type="" />
</add>
</listeners>
</source>
</sources>
</system.diagnostics>
<log4net debug="true">
<appender name="logFile" type="log4net.Appender.RollingFileAppender,log4net">
<param name="File" value="logs\mobilelog.txt" />
<param name="AppendToFile" value="true" />
<param name="RollingStyle" value="Date" />
<param name="DatePattern" value="dd.MM.yyyy" />
<param name="StaticLogFileName" value="true" />
<layout type="log4net.Layout.PatternLayout,log4net">
<param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" />
</layout>
</appender>
<root>
<priority value="DEBUG" />
<appender-ref ref="logFile" />
</root>
<logger name="NHibernate">
<level value="WARN" />
</logger>
<logger name="NHibernate.Caches">
<level value="WARN" />
</logger>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
<sectionGroup name="devExpress">
<section name="compression" type="DevExpress.Web.CompressionConfigurationSection, DevExpress.Web.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" requirePermission="false" />
<section name="themes" type="DevExpress.Web.ThemesConfigurationSection, DevExpress.Web.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" requirePermission="false" />
<section name="errors" type="DevExpress.Web.ErrorsConfigurationSection, DevExpress.Web.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" requirePermission="false" />
<section name="settings" type="DevExpress.Web.SettingsConfigurationSection, DevExpress.Web.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" requirePermission="false" />
<section name="resources" type="DevExpress.Web.ResourcesConfigurationSection, DevExpress.Web.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" requirePermission="false" />
</sectionGroup>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<system.diagnostics>
<sources>
<source name="System.ServiceModel" switchValue="All">
<listeners>
<add type="System.Diagnostics.DefaultTraceListener" name="Default">
<filter type="" />
</add>
<add initializeData="logs\Traces.svclog" type="System.Diagnostics.XmlWriterTraceListener" name="traceListener" traceOutputOptions="DateTime">
<filter type="" />
</add>
</listeners>
</source>
</sources>
</system.diagnostics>
<log4net debug="true">
<appender name="logFile" type="log4net.Appender.RollingFileAppender,log4net">
<param name="File" value="logs\mobilelog.txt" />
<param name="AppendToFile" value="true" />
<param name="RollingStyle" value="Date" />
<param name="DatePattern" value="dd.MM.yyyy" />
<param name="StaticLogFileName" value="true" />
<layout type="log4net.Layout.PatternLayout,log4net">
<param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" />
</layout>
</appender>
<root>
<priority value="DEBUG" />
<appender-ref ref="logFile" />
</root>
<logger name="NHibernate">
<level value="WARN" />
</logger>
<logger name="NHibernate.Caches">
<level value="WARN" />
</logger>
<logger name="NHibernate.Engine.Cascade">
<level value="WARN" />
</logger>
<logger name="NHibernate.Engine.Cascade">
<level value="WARN" />
</logger>
<logger name="NHibernate.Loader.Loader">
<level value="WARN" />
</logger>
<logger name="NHibernate.Loader.Loader">
<level value="WARN" />
</logger>
<logger name="NHibernate.SQL">
<level value="WARN" />
</logger>
<logger name="NHibernate.SQL">
<level value="WARN" />
</logger>
<logger name="NHibernate.Search">
<level value="WARN" />
</logger>
</log4net>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true">
<add name="ASPHibernateSession" type="BeWoPlanerMobil.Service.ASPHibernateSessionManager, BeWoPlanerMobil, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<add type="DevExpress.Web.ASPxHttpHandlerModule, DevExpress.Web.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" name="ASPxHttpHandlerModule" />
</modules>
<directoryBrowse enabled="true" />
<handlers>
<add type="DevExpress.Web.ASPxUploadProgressHttpHandler, DevExpress.Web.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" verb="GET,POST" path="ASPxUploadProgressHandlerPage.ashx" name="ASPxUploadProgressHandler" preCondition="integratedMode" />
<add type="DevExpress.Web.ASPxHttpHandlerModule, DevExpress.Web.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" verb="GET,POST" path="DXXRD.axd" name="ASPxReportDesignerHandlerModule" preCondition="integratedMode" />
<add type="DevExpress.Web.ASPxHttpHandlerModule, DevExpress.Web.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" verb="GET,POST" path="DXXRDV.axd" name="ASPxWebDocumentViewerHandlerModule" preCondition="integratedMode" />
<add name="ASPxQueryBuilderDesignerHandlerModule" preCondition="integratedMode" verb="GET,POST" path="DXQB.axd" type="DevExpress.Web.ASPxHttpHandlerModule, DevExpress.Web.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" /><remove name="OPTIONSVerbHandler" /><remove name="TRACEVerbHandler" /><add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /></handlers>
<security>
<requestFiltering allowDoubleEscaping="true" >
<requestLimits maxQueryString="32768" maxUrl="65535" maxAllowedContentLength="20971520" />
</requestFiltering>
</security>
<staticContent>
<clientCache cacheControlMode="UseMaxAge" />
</staticContent>
</system.webServer>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="SecurityBehavior">
<MultitenancyExtension />
<SecurityExtension />
</behavior>
<behavior name="SecurityAndSessionBehavior">
<!--wichtig: erst Mulittenancy, dann session, dann security!-->
<MultitenancyExtension />
<HibernateSessionExtension />
<SecurityExtension />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="returnFaults">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceThrottling maxConcurrentCalls="1000" maxConcurrentSessions="1000" />
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
</behavior>
</serviceBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<add name="MultitenancyExtension" type="BeWo.Service.Multitenancy.MultitenancyBehaviorExtension, BeWo.Service, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" />
<add name="SecurityExtension" type="BeWo.Service.Security.SecurityBehaviorExtension, BeWo.Service, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" />
<add name="HibernateSessionExtension" type="BeWo.Service.UnitOfWork.HibernateSessionBehaviorExtension, BeWo.Service, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" />
</behaviorExtensions>
</extensions>
<bindings>
<basicHttpBinding>
<binding name="BeWoBasicEndpoint" closeTimeout="00:05:00" openTimeout="00:05:00" receiveTimeout="00:10:00" sendTimeout="00:05:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="2147483647" maxBufferPoolSize="524288" maxReceivedMessageSize="2147483647" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None" />
</binding>
<binding name="BeWoStreamingEndpoint" receiveTimeout="10:10:00" sendTimeout="10:01:00" maxBufferSize="65536" maxReceivedMessageSize="67108864" messageEncoding="Text" transferMode="StreamedRequest" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None" />
</binding>
<binding name="QueryServiceEndpoint" closeTimeout="00:05:00" openTimeout="00:05:00" receiveTimeout="00:10:00" sendTimeout="00:05:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="2147483647" maxBufferPoolSize="524288" maxReceivedMessageSize="2147483647" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None" realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint binding="basicHttpBinding" bindingConfiguration="QueryServiceEndpoint" contract="QueryService.IQueryService" name="QueryServiceEndpoint" />
<endpoint binding="basicHttpBinding" bindingConfiguration="BeWoStreamingEndpoint" contract="BeWo.ServiceProxy.IStreamingService" name="StreamingServiceEndpoint" />
<endpoint binding="basicHttpBinding" bindingConfiguration="BeWoBasicEndpoint" contract="BeWo.ServiceProxy.IEmployeeService" name="EmployeeServiceEndpoint" />
<endpoint behaviorConfiguration="BeWoServiceBehavior" binding="basicHttpBinding" bindingConfiguration="BeWoBasicEndpoint" contract="BeWo.ServiceProxy.ICustomerService" name="CustomerServiceEndpoint" />
<endpoint binding="basicHttpBinding" bindingConfiguration="BeWoBasicEndpoint" contract="BeWo.ServiceProxy.IUserService" name="UserServiceEndpoint" />
<endpoint binding="basicHttpBinding" bindingConfiguration="BeWoBasicEndpoint" contract="BeWo.ServiceProxy.IValueListService" name="ValueListServiceEndpoint" />
<endpoint binding="basicHttpBinding" bindingConfiguration="BeWoBasicEndpoint" contract="BeWo.ServiceProxy.IDownloadService" name="DownloadServiceEndpoint" />
<endpoint binding="basicHttpBinding" bindingConfiguration="BeWoBasicEndpoint" contract="BeWo.ServiceProxy.IResourceService" name="BeWoBasicEndpoint" />
<endpoint behaviorConfiguration="BeWoServiceBehavior" binding="basicHttpBinding" bindingConfiguration="BeWoBasicEndpoint" contract="BeWo.ServiceProxy.IOperationsService" name="OperationsServiceEndpoint" />
<endpoint behaviorConfiguration="BeWoServiceBehavior" binding="basicHttpBinding" bindingConfiguration="BeWoBasicEndpoint" contract="BeWo.ServiceProxy.IAccountingService" name="AccountingServiceEndpoint" />
<endpoint behaviorConfiguration="BeWoServiceBehavior" binding="basicHttpBinding" bindingConfiguration="BeWoBasicEndpoint" contract="BeWo.ServiceProxy.IAnalysisService" name="AnalysisServiceEndpoint" />
<endpoint binding="basicHttpBinding" bindingConfiguration="BeWoBasicEndpoint" contract="BeWo.ServiceProxy.IMailService" name="MailServiceEndpoint" />
</client>
</system.serviceModel>
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="PreserveLoginUrl" value="true" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<add key="MultitenancyPath" value="..\Host\Multitenancy\" />
<add key="LicenseInfoUrl" value="https://support.bewoplaner.de/api/getlicensecount.php?k=[TENANT]" />
<add key="LicenseOrderUrl" value="https://support.bewoplaner.de/lizenzbestellung/?k=[TENANT]" />
<add key="LicenseCancellationUrl" value="https://support.bewoplaner.de/api/licencecancellation.php?k=[TENANT]" />
<add key="ContractStateUrl" value="https://support.bewoplaner.de/api/getcontractstate.php?CustomerID=[TENANT]" />
<!--<add key="PluginPathtest" value="D:\Projects\beyondSoft\BeWoPlaner\BeWo\Host\bin" />-->
<add key="PluginBasePath" value="..\CustomerDlls" />
<add key="PluginPath" value="..\CustomerDlls" />
<add key="FileRootDirectory" value="\BWP-Files" />
</appSettings>
<!--
<logger name="NHibernate.Search">
<level value="WARN" />
</logger>
</log4net>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true">
<add name="ASPHibernateSession" type="BeWoPlanerMobil.Service.ASPHibernateSessionManager, BeWoPlanerMobil, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<add type="DevExpress.Web.ASPxHttpHandlerModule, DevExpress.Web.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" name="ASPxHttpHandlerModule" />
</modules>
<directoryBrowse enabled="true" />
<handlers>
<add type="DevExpress.Web.ASPxUploadProgressHttpHandler, DevExpress.Web.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" verb="GET,POST" path="ASPxUploadProgressHandlerPage.ashx" name="ASPxUploadProgressHandler" preCondition="integratedMode" />
<add type="DevExpress.Web.ASPxHttpHandlerModule, DevExpress.Web.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" verb="GET,POST" path="DXXRD.axd" name="ASPxReportDesignerHandlerModule" preCondition="integratedMode" />
<add type="DevExpress.Web.ASPxHttpHandlerModule, DevExpress.Web.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" verb="GET,POST" path="DXXRDV.axd" name="ASPxWebDocumentViewerHandlerModule" preCondition="integratedMode" />
<add name="ASPxQueryBuilderDesignerHandlerModule" preCondition="integratedMode" verb="GET,POST" path="DXQB.axd" type="DevExpress.Web.ASPxHttpHandlerModule, DevExpress.Web.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" /><remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
<security>
<requestFiltering allowDoubleEscaping="true">
<requestLimits maxQueryString="32768" maxUrl="65535" maxAllowedContentLength="20971520" />
</requestFiltering>
</security>
<staticContent>
<clientCache cacheControlMode="UseMaxAge" />
</staticContent>
</system.webServer>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="SecurityBehavior">
<MultitenancyExtension />
<SecurityExtension />
</behavior>
<behavior name="SecurityAndSessionBehavior">
<!--wichtig: erst Mulittenancy, dann session, dann security!-->
<MultitenancyExtension />
<HibernateSessionExtension />
<SecurityExtension />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="returnFaults">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceThrottling maxConcurrentCalls="1000" maxConcurrentSessions="1000" />
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
</behavior>
</serviceBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<add name="MultitenancyExtension" type="BeWo.Service.Multitenancy.MultitenancyBehaviorExtension, BeWo.Service, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" />
<add name="SecurityExtension" type="BeWo.Service.Security.SecurityBehaviorExtension, BeWo.Service, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" />
<add name="HibernateSessionExtension" type="BeWo.Service.UnitOfWork.HibernateSessionBehaviorExtension, BeWo.Service, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" />
</behaviorExtensions>
</extensions>
<bindings>
<basicHttpBinding>
<binding name="BeWoBasicEndpoint" closeTimeout="00:05:00" openTimeout="00:05:00" receiveTimeout="00:10:00" sendTimeout="00:05:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="2147483647" maxBufferPoolSize="524288" maxReceivedMessageSize="2147483647" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None" />
</binding>
<binding name="BeWoStreamingEndpoint" receiveTimeout="10:10:00" sendTimeout="10:01:00" maxBufferSize="65536" maxReceivedMessageSize="67108864" messageEncoding="Text" transferMode="StreamedRequest" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None" />
</binding>
<binding name="QueryServiceEndpoint" closeTimeout="00:05:00" openTimeout="00:05:00" receiveTimeout="00:10:00" sendTimeout="00:05:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="2147483647" maxBufferPoolSize="524288" maxReceivedMessageSize="2147483647" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None" realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint binding="basicHttpBinding" bindingConfiguration="QueryServiceEndpoint" contract="QueryService.IQueryService" name="QueryServiceEndpoint" />
<endpoint binding="basicHttpBinding" bindingConfiguration="BeWoStreamingEndpoint" contract="BeWo.ServiceProxy.IStreamingService" name="StreamingServiceEndpoint" />
<endpoint binding="basicHttpBinding" bindingConfiguration="BeWoBasicEndpoint" contract="BeWo.ServiceProxy.IEmployeeService" name="EmployeeServiceEndpoint" />
<endpoint behaviorConfiguration="BeWoServiceBehavior" binding="basicHttpBinding" bindingConfiguration="BeWoBasicEndpoint" contract="BeWo.ServiceProxy.ICustomerService" name="CustomerServiceEndpoint" />
<endpoint binding="basicHttpBinding" bindingConfiguration="BeWoBasicEndpoint" contract="BeWo.ServiceProxy.IUserService" name="UserServiceEndpoint" />
<endpoint binding="basicHttpBinding" bindingConfiguration="BeWoBasicEndpoint" contract="BeWo.ServiceProxy.IValueListService" name="ValueListServiceEndpoint" />
<endpoint binding="basicHttpBinding" bindingConfiguration="BeWoBasicEndpoint" contract="BeWo.ServiceProxy.IDownloadService" name="DownloadServiceEndpoint" />
<endpoint binding="basicHttpBinding" bindingConfiguration="BeWoBasicEndpoint" contract="BeWo.ServiceProxy.IResourceService" name="BeWoBasicEndpoint" />
<endpoint behaviorConfiguration="BeWoServiceBehavior" binding="basicHttpBinding" bindingConfiguration="BeWoBasicEndpoint" contract="BeWo.ServiceProxy.IOperationsService" name="OperationsServiceEndpoint" />
<endpoint behaviorConfiguration="BeWoServiceBehavior" binding="basicHttpBinding" bindingConfiguration="BeWoBasicEndpoint" contract="BeWo.ServiceProxy.IAccountingService" name="AccountingServiceEndpoint" />
<endpoint behaviorConfiguration="BeWoServiceBehavior" binding="basicHttpBinding" bindingConfiguration="BeWoBasicEndpoint" contract="BeWo.ServiceProxy.IAnalysisService" name="AnalysisServiceEndpoint" />
<endpoint binding="basicHttpBinding" bindingConfiguration="BeWoBasicEndpoint" contract="BeWo.ServiceProxy.IMailService" name="MailServiceEndpoint" />
</client>
</system.serviceModel>
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="PreserveLoginUrl" value="true" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<add key="MultitenancyPath" value="..\Host\Multitenancy\" />
<add key="LicenseInfoUrl" value="https://support.bewoplaner.de/api/getlicensecount.php?k=[TENANT]" />
<add key="LicenseOrderUrl" value="https://support.bewoplaner.de/lizenzbestellung/?k=[TENANT]" />
<add key="LicenseCancellationUrl" value="https://support.bewoplaner.de/api/licencecancellation.php?k=[TENANT]" />
<add key="ContractStateUrl" value="https://support.bewoplaner.de/api/getcontractstate.php?CustomerID=[TENANT]" />
<!--<add key="PluginPathtest" value="D:\Projects\beyondSoft\BeWoPlaner\BeWo\Host\bin" />-->
<add key="PluginBasePath" value="..\CustomerDlls" />
<add key="PluginPath" value="..\CustomerDlls" />
<add key="FileRootDirectory" value="\BWP-Files" />
</appSettings>
<!--
Eine Beschreibung der Änderungen von 'web.config' finden Sie unter 'http://go.microsoft.com/fwlink/?LinkId=235367'.
Die folgenden Attribute können für die <httpRuntime>-Kennung festgelegt werden.
@@ -175,193 +179,194 @@
<httpRuntime targetFramework="4.5" />
</system.Web>
-->
<system.web>
<compilation debug="true" defaultLanguage="c#" targetFramework="4.7.2">
<assemblies>
<add assembly="BeWo.Service, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" />
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Helpers, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Mvc, Version=5.3.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
<add assembly="DevExpress.Data.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.Drawing.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.CodeParser.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.Web.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.Web.Resources.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.Web.ASPxThemes.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.Web.Mvc5.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.Charts.v23.2.Core, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.DataAccess.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.Office.v23.2.Core, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.PivotGrid.v23.2.Core, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.Printing.v23.2.Core, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.RichEdit.v23.2.Core, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.Sparkline.v23.2.Core, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.Utils.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.Web.ASPxScheduler.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.Xpo.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.XtraEditors.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.XtraPrinting.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.XtraReports.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.XtraReports.v23.2.Web, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.XtraReports.v23.2.Web.WebForms, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.XtraScheduler.v23.2.Core, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.XtraScheduler.v23.2.Core.Desktop, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.XtraScheduler.v23.2.Reporting, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.XtraScheduler.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
</assemblies>
</compilation>
<pages controlRenderingCompatibilityVersion="4.0">
<namespaces>
<add namespace="System.Web.Helpers" />
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Optimization" />
<add namespace="System.Web.Routing" />
<add namespace="System.Web.WebPages" />
<add namespace="System.Drawing" />
<add namespace="DevExpress.Utils" />
<add namespace="DevExpress.Web" />
<add namespace="DevExpress.Web.Mvc" />
<add namespace="DevExpress.Web.Mvc.UI" />
</namespaces>
</pages>
<httpHandlers>
<add type="DevExpress.Web.ASPxUploadProgressHttpHandler, DevExpress.Web.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" verb="GET,POST" path="ASPxUploadProgressHandlerPage.ashx" validate="false" />
<add type="DevExpress.Web.ASPxHttpHandlerModule, DevExpress.Web.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" verb="GET,POST" path="DXXRD.axd" validate="false" />
<add type="DevExpress.Web.ASPxHttpHandlerModule, DevExpress.Web.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" verb="GET,POST" path="DXXRDV.axd" validate="false" />
<add validate="false" verb="GET,POST" path="DXQB.axd" type="DevExpress.Web.ASPxHttpHandlerModule, DevExpress.Web.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
</httpHandlers>
<httpModules>
<add type="DevExpress.Web.ASPxHttpHandlerModule, DevExpress.Web.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" name="ASPxHttpHandlerModule" />
</httpModules>
<authentication mode="Forms">
<forms loginUrl="~/Login" />
</authentication>
<sessionState timeout="20" />
<identity impersonate="false" />
<httpRuntime maxQueryStringLength="32768" maxRequestLength="20480" maxUrlLength="65536" />
</system.web>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-1.6.5135.21930" newVersion="1.6.5135.21930" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Castle.Core" publicKeyToken="407dd0808d44fbdc" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.5.1.0" newVersion="2.5.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="EntityFramework" publicKeyToken="b77a5c561934e089" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.4.0.0" newVersion="4.4.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Antlr3.Runtime" publicKeyToken="eb42632606e9261f" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.5.0.2" newVersion="3.5.0.2" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.5.0" newVersion="4.0.5.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Numerics.Vectors" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.6.0" newVersion="4.1.6.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-5.3.0.0" newVersion="5.3.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Web.Infrastructure" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.5.0" newVersion="4.0.5.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.7" newVersion="9.0.0.7" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Reflection.Metadata" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.7" newVersion="9.0.0.7" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Text.Encoding.CodePages" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.7" newVersion="9.0.0.7" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Composition.AttributedModel" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.7" newVersion="9.0.0.7" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Composition.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.7" newVersion="9.0.0.7" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Composition.TypedParts" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.7" newVersion="9.0.0.7" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Composition.Hosting" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.7" newVersion="9.0.0.7" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.IO.Pipelines" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.7" newVersion="9.0.0.7" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Bcl.AsyncInterfaces" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.7" newVersion="9.0.0.7" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Channels" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<devExpress>
<compression enableHtmlCompression="false" enableCallbackCompression="true" enableResourceCompression="true" enableResourceMerging="true" />
<themes enableThemesAssembly="true" />
<errors callbackErrorRedirectUrl="" />
<settings rightToLeft="false" doctypeMode="Html5" ieCompatibilityVersion="edge" />
<resources>
</resources>
</devExpress>
<entityFramework>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
<system.codedom>
<compilers>
<compiler language="c#;cs;csharp" extension=".cs" warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701;612;618" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" warningLevel="4" compilerOptions="/langversion:default /nowarn:41008,40000,40008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</compilers>
</system.codedom>
<system.web>
<globalization culture="de-DE" uiCulture="de-DE" />
<compilation debug="true" defaultLanguage="c#" targetFramework="4.7.2">
<assemblies>
<add assembly="BeWo.Service, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" />
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Helpers, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Mvc, Version=5.3.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
<add assembly="DevExpress.Data.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.Drawing.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.CodeParser.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.Web.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.Web.Resources.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.Web.ASPxThemes.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.Web.Mvc5.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.Charts.v23.2.Core, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.DataAccess.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.Office.v23.2.Core, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.PivotGrid.v23.2.Core, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.Printing.v23.2.Core, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.RichEdit.v23.2.Core, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.Sparkline.v23.2.Core, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.Utils.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.Web.ASPxScheduler.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.Xpo.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.XtraEditors.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.XtraPrinting.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.XtraReports.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.XtraReports.v23.2.Web, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.XtraReports.v23.2.Web.WebForms, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.XtraScheduler.v23.2.Core, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.XtraScheduler.v23.2.Core.Desktop, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.XtraScheduler.v23.2.Reporting, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<add assembly="DevExpress.XtraScheduler.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
</assemblies>
</compilation>
<pages controlRenderingCompatibilityVersion="4.0">
<namespaces>
<add namespace="System.Web.Helpers" />
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Optimization" />
<add namespace="System.Web.Routing" />
<add namespace="System.Web.WebPages" />
<add namespace="System.Drawing" />
<add namespace="DevExpress.Utils" />
<add namespace="DevExpress.Web" />
<add namespace="DevExpress.Web.Mvc" />
<add namespace="DevExpress.Web.Mvc.UI" />
</namespaces>
</pages>
<httpHandlers>
<add type="DevExpress.Web.ASPxUploadProgressHttpHandler, DevExpress.Web.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" verb="GET,POST" path="ASPxUploadProgressHandlerPage.ashx" validate="false" />
<add type="DevExpress.Web.ASPxHttpHandlerModule, DevExpress.Web.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" verb="GET,POST" path="DXXRD.axd" validate="false" />
<add type="DevExpress.Web.ASPxHttpHandlerModule, DevExpress.Web.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" verb="GET,POST" path="DXXRDV.axd" validate="false" />
<add validate="false" verb="GET,POST" path="DXQB.axd" type="DevExpress.Web.ASPxHttpHandlerModule, DevExpress.Web.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
</httpHandlers>
<httpModules>
<add type="DevExpress.Web.ASPxHttpHandlerModule, DevExpress.Web.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" name="ASPxHttpHandlerModule" />
</httpModules>
<authentication mode="Forms">
<forms loginUrl="~/Login" />
</authentication>
<sessionState timeout="20" />
<identity impersonate="false" />
<httpRuntime maxQueryStringLength="32768" maxRequestLength="20480" maxUrlLength="65536" />
</system.web>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-1.6.5135.21930" newVersion="1.6.5135.21930" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Castle.Core" publicKeyToken="407dd0808d44fbdc" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.5.1.0" newVersion="2.5.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="EntityFramework" publicKeyToken="b77a5c561934e089" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.4.0.0" newVersion="4.4.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Antlr3.Runtime" publicKeyToken="eb42632606e9261f" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.5.0.2" newVersion="3.5.0.2" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.5.0" newVersion="4.0.5.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Numerics.Vectors" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.6.0" newVersion="4.1.6.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-5.3.0.0" newVersion="5.3.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Web.Infrastructure" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.5.0" newVersion="4.0.5.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.7" newVersion="9.0.0.7" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Reflection.Metadata" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.7" newVersion="9.0.0.7" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Text.Encoding.CodePages" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.7" newVersion="9.0.0.7" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Composition.AttributedModel" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.7" newVersion="9.0.0.7" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Composition.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.7" newVersion="9.0.0.7" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Composition.TypedParts" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.7" newVersion="9.0.0.7" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Composition.Hosting" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.7" newVersion="9.0.0.7" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.IO.Pipelines" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.7" newVersion="9.0.0.7" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Bcl.AsyncInterfaces" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.7" newVersion="9.0.0.7" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Channels" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<devExpress>
<compression enableHtmlCompression="false" enableCallbackCompression="true" enableResourceCompression="true" enableResourceMerging="true" />
<themes enableThemesAssembly="true" />
<errors callbackErrorRedirectUrl="" />
<settings rightToLeft="false" doctypeMode="Html5" ieCompatibilityVersion="edge" />
<resources>
</resources>
</devExpress>
<entityFramework>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
<system.codedom>
<compilers>
<compiler language="c#;cs;csharp" extension=".cs" warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701;612;618" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" warningLevel="4" compilerOptions="/langversion:default /nowarn:41008,40000,40008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</compilers>
</system.codedom>
</configuration>

View File

@@ -239,6 +239,7 @@ namespace BeWo.Data.Security
|| r == UserRightType.AiModulePromptbausteineRemove
|| r == UserRightType.AiModulePromptbausteineSeeAll
|| r == UserRightType.AiModulePromptbausteineView
//|| r == UserRightType.AiModulePromptbausteineExecute
|| r == UserRightType.AiVoiceView;
}
}

View File

@@ -6,7 +6,6 @@
<appSettings>
<add key="OpenWebUIKey" value=""/>
<add key="OllamaKey" value=""/>
<add key="Ollama2Key" value=""/>
<add key="GetGkvSumApiKey" value=""/>

View File

@@ -1,3 +1,6 @@
INSERT INTO `.executedscripts`
VALUES ('Changes_2026-02-10_AiVoiceData', CURDATE());
CREATE TABLE IF NOT EXISTS `AiVoiceData` (
`Oid` bigint NOT NULL AUTO_INCREMENT,
`Tid` int NOT NULL,

View File

@@ -1,3 +1,6 @@
INSERT INTO `.executedscripts`
VALUES ('Changes_2026-02-25_VermittlungGemeinnuetzigerArbeit Frist_Delikt_BWH', CURDATE());
ALTER TABLE `CustomerVermittlungArbeit` ADD COLUMN Frist datetime NULL DEFAULT NULL;
ALTER TABLE `CustomerVermittlungArbeit` ADD COLUMN Delikt VARCHAR(256) NULL DEFAULT NULL;
ALTER TABLE `CustomerVermittlungArbeit` ADD COLUMN Bewaehrungshelfer VARCHAR(256) NULL DEFAULT NULL;

View File

@@ -37,6 +37,9 @@ namespace ForumEV
this.topMarginBand1 = new DevExpress.XtraReports.UI.TopMarginBand();
this.xrPictureBox1 = new DevExpress.XtraReports.UI.XRPictureBox();
this.bottomMarginBand1 = new DevExpress.XtraReports.UI.BottomMarginBand();
this.xrRichText9 = new DevExpress.XtraReports.UI.XRRichText();
this.xrRichText8 = new DevExpress.XtraReports.UI.XRRichText();
this.xrRichText7 = new DevExpress.XtraReports.UI.XRRichText();
this.Page1 = new DevExpress.XtraReports.UI.GroupHeaderBand();
this.xrRichText2 = new DevExpress.XtraReports.UI.XRRichText();
this.xrRichText1 = new DevExpress.XtraReports.UI.XRRichText();
@@ -90,9 +93,9 @@ namespace ForumEV
this.xrTableCell1 = new DevExpress.XtraReports.UI.XRTableCell();
this.xrTableCell5 = new DevExpress.XtraReports.UI.XRTableCell();
this.bindingSource1 = new System.Windows.Forms.BindingSource(this.components);
this.xrRichText9 = new DevExpress.XtraReports.UI.XRRichText();
this.xrRichText8 = new DevExpress.XtraReports.UI.XRRichText();
this.xrRichText7 = new DevExpress.XtraReports.UI.XRRichText();
((System.ComponentModel.ISupportInitialize)(this.xrRichText9)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.xrRichText8)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.xrRichText7)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.xrRichText2)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.xrRichText1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.xrTable2)).BeginInit();
@@ -101,9 +104,6 @@ namespace ForumEV
((System.ComponentModel.ISupportInitialize)(this.xrTable5)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.xrTable1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.bindingSource1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.xrRichText9)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.xrRichText8)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.xrRichText7)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this)).BeginInit();
//
// Detail
@@ -152,6 +152,33 @@ namespace ForumEV
this.bottomMarginBand1.Name = "bottomMarginBand1";
this.bottomMarginBand1.StylePriority.UseFont = false;
//
// xrRichText9
//
this.xrRichText9.Font = new DevExpress.Drawing.DXFont("Arial", 8F);
this.xrRichText9.LocationFloat = new DevExpress.Utils.PointFloat(0.2499898F, 0F);
this.xrRichText9.Name = "xrRichText9";
this.xrRichText9.SerializableRtfString = resources.GetString("xrRichText9.SerializableRtfString");
this.xrRichText9.SizeF = new System.Drawing.SizeF(225F, 97.29169F);
this.xrRichText9.StylePriority.UseFont = false;
//
// xrRichText8
//
this.xrRichText8.Font = new DevExpress.Drawing.DXFont("Arial", 8F);
this.xrRichText8.LocationFloat = new DevExpress.Utils.PointFloat(226.7499F, 0F);
this.xrRichText8.Name = "xrRichText8";
this.xrRichText8.SerializableRtfString = resources.GetString("xrRichText8.SerializableRtfString");
this.xrRichText8.SizeF = new System.Drawing.SizeF(225F, 97.29169F);
this.xrRichText8.StylePriority.UseFont = false;
//
// xrRichText7
//
this.xrRichText7.Font = new DevExpress.Drawing.DXFont("Arial", 8F);
this.xrRichText7.LocationFloat = new DevExpress.Utils.PointFloat(451.7499F, 0F);
this.xrRichText7.Name = "xrRichText7";
this.xrRichText7.SerializableRtfString = resources.GetString("xrRichText7.SerializableRtfString");
this.xrRichText7.SizeF = new System.Drawing.SizeF(225F, 97.29169F);
this.xrRichText7.StylePriority.UseFont = false;
//
// Page1
//
this.Page1.BorderWidth = 2F;
@@ -333,6 +360,7 @@ namespace ForumEV
this.xrTableCell7.StylePriority.UseFont = false;
this.xrTableCell7.StylePriority.UsePadding = false;
this.xrTableCell7.StylePriority.UseTextAlignment = false;
this.xrTableCell7.Text = "490517594";
this.xrTableCell7.TextAlignment = DevExpress.XtraPrinting.TextAlignment.MiddleRight;
this.xrTableCell7.Weight = 0.53122488360866615D;
//
@@ -859,33 +887,6 @@ namespace ForumEV
this.xrTableCell5.TextAlignment = DevExpress.XtraPrinting.TextAlignment.MiddleRight;
this.xrTableCell5.Weight = 0.41733623261820113D;
//
// xrRichText9
//
this.xrRichText9.Font = new DevExpress.Drawing.DXFont("Arial", 8F);
this.xrRichText9.LocationFloat = new DevExpress.Utils.PointFloat(0.2499898F, 0F);
this.xrRichText9.Name = "xrRichText9";
this.xrRichText9.SerializableRtfString = resources.GetString("xrRichText9.SerializableRtfString");
this.xrRichText9.SizeF = new System.Drawing.SizeF(225F, 97.29169F);
this.xrRichText9.StylePriority.UseFont = false;
//
// xrRichText8
//
this.xrRichText8.Font = new DevExpress.Drawing.DXFont("Arial", 8F);
this.xrRichText8.LocationFloat = new DevExpress.Utils.PointFloat(226.7499F, 0F);
this.xrRichText8.Name = "xrRichText8";
this.xrRichText8.SerializableRtfString = resources.GetString("xrRichText8.SerializableRtfString");
this.xrRichText8.SizeF = new System.Drawing.SizeF(225F, 97.29169F);
this.xrRichText8.StylePriority.UseFont = false;
//
// xrRichText7
//
this.xrRichText7.Font = new DevExpress.Drawing.DXFont("Arial", 8F);
this.xrRichText7.LocationFloat = new DevExpress.Utils.PointFloat(451.7499F, 0F);
this.xrRichText7.Name = "xrRichText7";
this.xrRichText7.SerializableRtfString = resources.GetString("xrRichText7.SerializableRtfString");
this.xrRichText7.SizeF = new System.Drawing.SizeF(225F, 97.29169F);
this.xrRichText7.StylePriority.UseFont = false;
//
// SoziotherapieRechnung
//
this.Bands.AddRange(new DevExpress.XtraReports.UI.Band[] {
@@ -908,6 +909,9 @@ namespace ForumEV
this.Version = "23.2";
xrWatermark1.Id = "Watermark1";
this.Watermarks.Add(xrWatermark1);
((System.ComponentModel.ISupportInitialize)(this.xrRichText9)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.xrRichText8)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.xrRichText7)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.xrRichText2)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.xrRichText1)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.xrTable2)).EndInit();
@@ -916,9 +920,6 @@ namespace ForumEV
((System.ComponentModel.ISupportInitialize)(this.xrTable5)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.xrTable1)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.bindingSource1)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.xrRichText9)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.xrRichText8)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.xrRichText7)).EndInit();
((System.ComponentModel.ISupportInitialize)(this)).EndInit();
}

View File

@@ -84,7 +84,7 @@ namespace BS.Shared.AppSender
}
catch (Exception e)
{
throw new GkvException(e.Message, "KundenApp");
throw new GkvException(e.ToString() + $" ({url})", "KundenApp");
}
if (app8_response is null)

View File

@@ -652,6 +652,7 @@ namespace BS.Shared
AiModulePromptbausteineEdit = 201009,
AiModulePromptbausteineRemove = 201010,
AiModulePromptbausteineSeeAll = 201011,
//AiModulePromptbausteineExecute = 201012,
AiVoiceView= 201020,
}

View File

@@ -687,7 +687,7 @@ namespace BS.Shared.Core
{
var dict = new Dictionary<UserRightType, String>();
var action_keywords = new string[] { "ansehen", "verwalten", "anlegen", "bearbeiten", "löschen", "senden", "klonen", "alle ansehen" };
var action_keywords = new string[] { "ansehen", "verwalten", "anlegen", "bearbeiten", "löschen", "senden", "klonen", "alle ansehen", "ausführen" };
dict.Add(UserRightType.CreateAll, Translator.Translate("Alles anlegen"));
@@ -779,6 +779,7 @@ namespace BS.Shared.Core
dict.Add(UserRightType.AiModulePromptbausteineEdit, Translator.Translate($"KI-Promptbaustein {action_keywords[3]}"));
dict.Add(UserRightType.AiModulePromptbausteineRemove, Translator.Translate($"KI-Promptbaustein {action_keywords[4]}"));
dict.Add(UserRightType.AiModulePromptbausteineSeeAll, Translator.Translate($"KI-Promptbausteine {action_keywords[7]}"));
//dict.Add(UserRightType.AiModulePromptbausteineExecute, Translator.Translate($"KI-Promptbausteine {action_keywords[8]}"));
dict.Add(UserRightType.PersonView_Create, Translator.Translate("Personen anlegen"));
dict.Add(UserRightType.PersonView_Delete, Translator.Translate("Personen löschen"));

View File

@@ -15,7 +15,7 @@ namespace BS.Shared.DataContracts
public long? AppointmentVersion { get; set; }
[DataMember]
public Object ContextObject { get; set; }
public object ContextObject { get; set; }
[DataMember]
public string Subject { get; set; }

View File

@@ -750,5 +750,14 @@ namespace BS.Shared.Extensions
return date;
}
public static DateTime GetDayOfWeek(DayOfWeek dayOfWeek)
{
var today = DateTime.Today;
var diff = (7 + (today.DayOfWeek - dayOfWeek)) % 7;
return today.AddDays(-diff);
}
}
}