From 48612379cc137f18ec83830a48b30fbe57dd8820 Mon Sep 17 00:00:00 2001 From: Alexandra Date: Thu, 12 Mar 2026 16:34:06 +0100 Subject: [PATCH 01/11] =?UTF-8?q?MalteserJohanniterJohanneshaus/Invoicing/?= =?UTF-8?q?AnwesenheitenZeiterfassungRO=20-=20Filter=20auf=20Eintr=C3=A4ge?= =?UTF-8?q?=20>=200=20Minuten?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Invoicing/AnwesenheitenZeiterfassungRO.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ReportImp/MalteserJohanniterJohanneshaus/Invoicing/AnwesenheitenZeiterfassungRO.cs b/ReportImp/MalteserJohanniterJohanneshaus/Invoicing/AnwesenheitenZeiterfassungRO.cs index aa67351f7..d384fa15b 100644 --- a/ReportImp/MalteserJohanniterJohanneshaus/Invoicing/AnwesenheitenZeiterfassungRO.cs +++ b/ReportImp/MalteserJohanniterJohanneshaus/Invoicing/AnwesenheitenZeiterfassungRO.cs @@ -60,7 +60,7 @@ namespace MalteserJohanniterJohanneshaus.Invoicing foreach (var c2s in hpsTsh) { var allRecords = DAOFactory.SearchDAO.FindServiceRecordsInSpan(c2s.Oid.Value, newSpan); - var records = allRecords.Where(r => r.ServiceDescription.ServiceCategory.Name.Contains("LT23") || r.ServiceDescription.ServiceCategory.Name.Contains("LT24")).ToList(); + var records = allRecords.Where(r => r.RoundedDuration > 0 && (r.ServiceDescription.ServiceCategory.Name.Contains("LT23") || r.ServiceDescription.ServiceCategory.Name.Contains("LT24"))).ToList(); var daysWithRecords = records.GroupBy(r => r.Start.Value.Date).Select(g => g.Key).ToList(); foreach (var d in daysWithRecords) { From 05ec57a0a2d56b6863b143d8390845932128757d Mon Sep 17 00:00:00 2001 From: Rene Evertz Date: Fri, 13 Mar 2026 10:06:51 +0100 Subject: [PATCH 02/11] Prompt MaxLength entfernt --- BeWo/View/Detail/AI/AiPromptbausteinPromptView.xaml | 1 - 1 file changed, 1 deletion(-) diff --git a/BeWo/View/Detail/AI/AiPromptbausteinPromptView.xaml b/BeWo/View/Detail/AI/AiPromptbausteinPromptView.xaml index 6732d038a..d48de16f8 100644 --- a/BeWo/View/Detail/AI/AiPromptbausteinPromptView.xaml +++ b/BeWo/View/Detail/AI/AiPromptbausteinPromptView.xaml @@ -70,7 +70,6 @@ Grid.Row="2" Grid.Column="2" IsEnabled="{Binding ViewModel.CanEdit}" - MaxLength="1024" Style="{StaticResource TextBoxNoticeLarge}" Text="{Binding ViewModel.Prompt, UpdateSourceTrigger=PropertyChanged}" TextWrapping="Wrap" /> From d9242e2b0dfe51bcb5be1f6752bf251d50b90ca5 Mon Sep 17 00:00:00 2001 From: Rene Evertz Date: Fri, 13 Mar 2026 10:10:15 +0100 Subject: [PATCH 03/11] Popup / Window mehr getrennt behandelt --- BeWo/Services/BeWoWindowService.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/BeWo/Services/BeWoWindowService.cs b/BeWo/Services/BeWoWindowService.cs index d2b01c7f3..d9eecc28a 100644 --- a/BeWo/Services/BeWoWindowService.cs +++ b/BeWo/Services/BeWoWindowService.cs @@ -54,19 +54,19 @@ namespace BeWo.Services } else if (windowViewModel is AiPromptbausteinFolderViewModel viewModel3) { - ShowAiPromptbausteinFolderPopup(viewModel3); + ShowAiPromptbausteinFolderWindow(viewModel3); } else if(windowViewModel is AiPromptbausteinPromptViewModel viewModel4) { - ShowAiPromptbausteinPromptPopup(viewModel4); + ShowAiPromptbausteinPromptWindow(viewModel4); } else if(windowViewModel is AiPromptbausteinActionResultViewModel viewModel5) { - ShowAiPromptbausteinActionResultPopup(viewModel5); + ShowAiPromptbausteinActionResultWindow(viewModel5); } else if(windowViewModel is AiPromptbausteinSelectionComplexViewModel viewModel6) { - ShowAiPromptbausteinSelectionComplexPopup(viewModel6); + ShowAiPromptbausteinSelectionComplexWindow(viewModel6); } else { @@ -85,7 +85,7 @@ namespace BeWo.Services }; Show(title, control, viewModel, options); } - public void ShowAiPromptbausteinFolderPopup(AiPromptbausteinFolderViewModel viewModel) + public void ShowAiPromptbausteinFolderWindow(AiPromptbausteinFolderViewModel viewModel) { var control = new AiPromptbausteinFolderView(viewModel); var options = new BeWoWindowOptions() @@ -95,7 +95,7 @@ namespace BeWo.Services }; Show("KI Promptbaustein Ordner", control, viewModel, options); } - public void ShowAiPromptbausteinPromptPopup(AiPromptbausteinPromptViewModel viewModel) + public void ShowAiPromptbausteinPromptWindow(AiPromptbausteinPromptViewModel viewModel) { var control = new AiPromptbausteinPromptView(viewModel); var options = new BeWoWindowOptions() @@ -105,7 +105,7 @@ namespace BeWo.Services }; Show("KI Promptbaustein Prompt", control, viewModel, options); } - public void ShowAiPromptbausteinActionResultPopup(AiPromptbausteinActionResultViewModel viewModel) + public void ShowAiPromptbausteinActionResultWindow(AiPromptbausteinActionResultViewModel viewModel) { var control = new AiPromptbausteinActionResultView(viewModel); var options = new BeWoWindowOptions() @@ -116,7 +116,7 @@ namespace BeWo.Services Show("KI Promptbaustein Ergebnis", control, viewModel, options); } - public void ShowAiPromptbausteinSelectionComplexPopup(AiPromptbausteinSelectionComplexViewModel viewModel) + public void ShowAiPromptbausteinSelectionComplexWindow(AiPromptbausteinSelectionComplexViewModel viewModel) { var control = new AiPromptbausteinComplexSelectionView(viewModel); var options = new BeWoWindowOptions() From 98e06d7f4782f2c9c2203d1c6b3abb701d8adbca Mon Sep 17 00:00:00 2001 From: Rene Evertz Date: Fri, 13 Mar 2026 11:38:18 +0100 Subject: [PATCH 04/11] =?UTF-8?q?AI=20Promptbaustein=20Button=20ausgelager?= =?UTF-8?q?t.=20Input=20State+ActionType,=20Output=20Event=20SelectedPromp?= =?UTF-8?q?t=20AI=20Promptbaustein=20Auswahl=20fl=C3=BCssiger=20(IsSelecte?= =?UTF-8?q?d=20Bug)=20Reset=20Selection=20bei=20Popup=20Closed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BeWo/BeWo.csproj | 7 + .../Controls/AI/AiConversationButton.xaml.cs | 4 +- .../Controls/AI/AiPromptbausteinButton.xaml | 60 +++++++ .../AI/AiPromptbausteinButton.xaml.cs | 160 ++++++++++++++++++ .../AiPromptbausteinComplexSelectionView.xaml | 2 +- ...PromptbausteinComplexSelectionView.xaml.cs | 13 +- .../Zeiterfassung/ServiceRecordView2.xaml | 4 + .../Zeiterfassung/ServiceRecordView2.xaml.cs | 29 ++-- BeWo/ViewModel/AiPromptbausteinPromptVM.cs | 18 +- .../ListViewModel/ServiceRecordListVM.cs | 38 ++--- ...PromptbausteinComplexSelectionViewModel.cs | 23 ++- Service/Plugins/AiFunctionService.cs | 3 + 12 files changed, 319 insertions(+), 42 deletions(-) create mode 100644 BeWo/View/Controls/AI/AiPromptbausteinButton.xaml create mode 100644 BeWo/View/Controls/AI/AiPromptbausteinButton.xaml.cs diff --git a/BeWo/BeWo.csproj b/BeWo/BeWo.csproj index 3ee8d1721..34a5cc250 100644 --- a/BeWo/BeWo.csproj +++ b/BeWo/BeWo.csproj @@ -155,6 +155,9 @@ AiConversationButton.xaml + + AiPromptbausteinButton.xaml + AiPromptbausteinActionResultView.xaml @@ -256,6 +259,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + Designer MSBuild:Compile diff --git a/BeWo/View/Controls/AI/AiConversationButton.xaml.cs b/BeWo/View/Controls/AI/AiConversationButton.xaml.cs index 4e6961f56..5ad874de0 100644 --- a/BeWo/View/Controls/AI/AiConversationButton.xaml.cs +++ b/BeWo/View/Controls/AI/AiConversationButton.xaml.cs @@ -170,13 +170,15 @@ namespace BeWo.View.Controls.AI { var viewmodel = new AiPromptbausteinSelectionComplexViewModel(actionType, listvm); viewmodel.PromptAccepted += PromptAccepted; + popup_promptbaustein_all.Closed += (s, e) => viewmodel.ResetSelection(); var view = new AiPromptbausteinComplexSelectionView(viewmodel); view.Padding = new Thickness(3); view.Background = FindResource("ObjectEditBackgroundBrush") as System.Windows.Media.Brush; border_promptbaustein_al.Child = view; - var viewmodel2 = new AiPromptbausteinSelectionComplexViewModel(actionType, listvm); + var viewmodel2 = new AiPromptbausteinSelectionComplexViewModel(actionType, listvm, true); viewmodel2.PromptAccepted += PromptAccepted; + popup_promptbaustein_favoriten.Closed += (s, e) => viewmodel2.ResetSelection(); var view2 = new AiPromptbausteinComplexSelectionView(viewmodel2); view2.ReduceSelection(); viewmodel2.SelectedFolder = viewmodel2.Folders.VMList[0]; diff --git a/BeWo/View/Controls/AI/AiPromptbausteinButton.xaml b/BeWo/View/Controls/AI/AiPromptbausteinButton.xaml new file mode 100644 index 000000000..d7d1203c9 --- /dev/null +++ b/BeWo/View/Controls/AI/AiPromptbausteinButton.xaml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/BeWo/View/Controls/AI/AiPromptbausteinButton.xaml.cs b/BeWo/View/Controls/AI/AiPromptbausteinButton.xaml.cs new file mode 100644 index 000000000..1194dd585 --- /dev/null +++ b/BeWo/View/Controls/AI/AiPromptbausteinButton.xaml.cs @@ -0,0 +1,160 @@ +using BeWo.ServiceProxy; +using BeWo.View.Detail.AI; +using BeWo.ViewModel; +using BeWo.ViewModel.View.AI; +using BS.Shared; +using BS.Shared.DataContracts.Feature.AI; +using DevExpress.Utils.Mdi; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Remoting.Messaging; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace BeWo.View.Controls.AI +{ + public enum AiPromptbausteinButtonState + { + Hidden, + Normal, + Loading, + Disabled + } + + /// + /// Interaktionslogik für AiPromptbausteinButton.xaml + /// + public partial class AiPromptbausteinButton : UserControl + { + public static readonly DependencyProperty StateProperty = + DependencyProperty.Register("State", typeof(AiPromptbausteinButtonState), typeof(AiPromptbausteinButton), new PropertyMetadata(AiPromptbausteinButtonState.Normal, OnStateChanged)); + + public static readonly DependencyProperty ActionTypeProperty = + DependencyProperty.Register("ActionType", typeof(AiActionType), typeof(AiPromptbausteinButton), new PropertyMetadata(AiActionType.ServiceRecord, OnActionTypeChanged)); + + public event EventHandler PromptAccepted; + + public AiPromptbausteinButtonState State + { + get { return (AiPromptbausteinButtonState)GetValue(StateProperty); } + set { SetValue(StateProperty, value); } + } + public AiActionType ActionType + { + get { return (AiActionType)GetValue(ActionTypeProperty); } + set { SetValue(ActionTypeProperty, value); } + } + + public AiActionType LoadedActionType { get; set; } + + public AiPromptbausteinButton() + { + InitializeComponent(); + + + } + + private static void OnStateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var control = (AiPromptbausteinButton)d; + var state = (AiPromptbausteinButtonState)e.NewValue; + control.UpdateState(state); + } + private static void OnActionTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var control = (AiPromptbausteinButton)d; + var actionType = (AiActionType)e.NewValue; + control.UpdateActionType(actionType); + } + + public void AiPromptOpenAll() + { + popup_promptbaustein_all.IsOpen = true; + } + public void AiPromptOpenFavorite() + { + popup_promptbaustein_favoriten.IsOpen = true; + } + + private void btnOpenAi5_Click(object sender, RoutedEventArgs e) + { + AiPromptOpenAll(); + } + private void btnOpenAi5_MouseRightButtonUp(object sender, MouseButtonEventArgs e) + { + AiPromptOpenFavorite(); + } + + private void InitPromptbausteine(AiActionType actionType, List folders) + { + VMFactory.CreateAiPromptbausteinFolderListVM(folders, (listvm) => + { + var viewmodel = new AiPromptbausteinSelectionComplexViewModel(actionType, listvm); + viewmodel.PromptAccepted += PromptAccepted; + popup_promptbaustein_all.Closed += (s, e) => viewmodel.ResetSelection(); + var view = new AiPromptbausteinComplexSelectionView(viewmodel); + view.Padding = new Thickness(3); + view.Background = FindResource("ObjectEditBackgroundBrush") as System.Windows.Media.Brush; + border_promptbaustein_al.Child = view; + + var viewmodel2 = new AiPromptbausteinSelectionComplexViewModel(actionType, listvm, true); + viewmodel2.PromptAccepted += PromptAccepted; + popup_promptbaustein_favoriten.Closed += (s, e) => viewmodel2.ResetSelection(); + var view2 = new AiPromptbausteinComplexSelectionView(viewmodel2); + view2.ReduceSelection(); + viewmodel2.SelectedFolder = viewmodel2.Folders.VMList[0]; + view2.Padding = new Thickness(3); + view2.Background = FindResource("ObjectEditBackgroundBrush") as System.Windows.Media.Brush; + border_promptbaustein_favoriten.Child = view2; + State = AiPromptbausteinButtonState.Normal; + }); + } + private void UpdateState(AiPromptbausteinButtonState state) + { + switch (state) + { + case AiPromptbausteinButtonState.Hidden: + root.Visibility = Visibility.Collapsed; + root.IsEnabled = true; + break; + case AiPromptbausteinButtonState.Normal: + root.Visibility = Visibility.Visible; + root.IsEnabled = true; + break; + case AiPromptbausteinButtonState.Loading: + root.Visibility = Visibility.Visible; + root.IsEnabled = false; + break; + case AiPromptbausteinButtonState.Disabled: + throw new NotImplementedException(); + default: + throw new NotImplementedException(); + break; + } + + } + private void UpdateActionType(AiActionType actionType) + { + ActionType = actionType; + + if (!BeWoApp.AppSettings.ShowAI) + { + State = AiPromptbausteinButtonState.Hidden; + return; + } + + State = AiPromptbausteinButtonState.Loading; + ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.GetAiPromptbausteinFolder(actionType), folders => InitPromptbausteine(actionType, folders)); + } + } +} diff --git a/BeWo/View/Detail/AI/AiPromptbausteinComplexSelectionView.xaml b/BeWo/View/Detail/AI/AiPromptbausteinComplexSelectionView.xaml index 24be48a9b..1fef54bc8 100644 --- a/BeWo/View/Detail/AI/AiPromptbausteinComplexSelectionView.xaml +++ b/BeWo/View/Detail/AI/AiPromptbausteinComplexSelectionView.xaml @@ -74,9 +74,9 @@ diff --git a/BeWo/View/Detail/AI/AiPromptbausteinComplexSelectionView.xaml.cs b/BeWo/View/Detail/AI/AiPromptbausteinComplexSelectionView.xaml.cs index 316a14706..712e31f42 100644 --- a/BeWo/View/Detail/AI/AiPromptbausteinComplexSelectionView.xaml.cs +++ b/BeWo/View/Detail/AI/AiPromptbausteinComplexSelectionView.xaml.cs @@ -31,7 +31,18 @@ namespace BeWo.View.Detail.AI DataContext = ViewModel = viewModel; - Loaded += (s, e) => ViewModel.InitVMList(); + Loaded += (s, e) => + { + ViewModel.InitVMList(); + + TreeViewItem item = treeView.ItemContainerGenerator.ContainerFromIndex(0) as TreeViewItem; + if (item != null) + { + item.IsSelected = true; + + item.IsSelected = false; + } + }; } public void ReduceSelection() diff --git a/BeWo/View/Detail/Zeiterfassung/ServiceRecordView2.xaml b/BeWo/View/Detail/Zeiterfassung/ServiceRecordView2.xaml index b9ee550e7..f3795aa83 100644 --- a/BeWo/View/Detail/Zeiterfassung/ServiceRecordView2.xaml +++ b/BeWo/View/Detail/Zeiterfassung/ServiceRecordView2.xaml @@ -1724,6 +1724,10 @@ Command="{Binding OpenAiPromptSelectionCommand}" Content="{StaticResource AiDesignsIconKIFunktionWeissGruen}" Style="{StaticResource PrimaryButton}" /> + diff --git a/BeWo/View/Detail/Zeiterfassung/ServiceRecordView2.xaml.cs b/BeWo/View/Detail/Zeiterfassung/ServiceRecordView2.xaml.cs index 301311a92..cfe415dcc 100644 --- a/BeWo/View/Detail/Zeiterfassung/ServiceRecordView2.xaml.cs +++ b/BeWo/View/Detail/Zeiterfassung/ServiceRecordView2.xaml.cs @@ -5100,15 +5100,15 @@ namespace BeWo.View.Detail.Zeiterfassung MainControl.WindowService.ShowAiConversationWindow(getAiConversationChatViewModel()); } - private void PromptAccepted(object sender, AiPromptbausteinPromptVM prompt) - { - if (prompt is null) - throw new NotImplementedException(); + private void PromptAccepted(object sender, AiPromptbausteinPromptVM prompt) + { + if (prompt is null) + throw new NotImplementedException(); - // 1. Information aufbereiten - // 1.1 Prompt - var prompt_oid = prompt.DataContract.Oid.Value; - var prompt_version = prompt.DataContract.Version; + // 1. Information aufbereiten + // 1.1 Prompt + var prompt_oid = prompt.DataContract.Oid.Value; + var prompt_version = prompt.DataContract.Version; // 1.2 Restliche Informationen var vm = getAiConversationChatViewModel(); @@ -5117,12 +5117,12 @@ namespace BeWo.View.Detail.Zeiterfassung // 3 Auswerten vm.MessageInput = prompt.Prompt; - vm.SendAfterLoaded = true; + vm.SendAfterLoaded = true; - MainControl.WindowService.ShowAiConversationWindow(vm); - } + MainControl.WindowService.ShowAiConversationWindow(vm); + } - private IEnumerable GetVisibleRecordVMs() + private IEnumerable GetVisibleRecordVMs() { var list = new List(); @@ -5146,6 +5146,11 @@ namespace BeWo.View.Detail.Zeiterfassung return list; } + + private void btn_AiPromptbaustein2_PromptAccepted(object sender, AiPromptbausteinPromptVM e) + { + ViewModel.PromptAccepted(sender, e); + } } //public class RowBackgroundHelper diff --git a/BeWo/ViewModel/AiPromptbausteinPromptVM.cs b/BeWo/ViewModel/AiPromptbausteinPromptVM.cs index 96da4f4be..41c85ef53 100644 --- a/BeWo/ViewModel/AiPromptbausteinPromptVM.cs +++ b/BeWo/ViewModel/AiPromptbausteinPromptVM.cs @@ -103,9 +103,10 @@ namespace BeWo.ViewModel public bool IsFavorite { get => _IsFavorite; - set { - var success = SetProperty(ref _IsFavorite, value, nameof(IsFavorite), () => DataContract.IsFavorite); - if(success) + set + { + var success = SetProperty(ref _IsFavorite, value, nameof(IsFavorite), () => DataContract.IsFavorite); + if (success) FirePropertyChanged(nameof(FontWeight)); } } @@ -124,7 +125,12 @@ namespace BeWo.ViewModel public bool IsSelected { get => _IsSelected; - set => SetProperty(ref _IsSelected, value, nameof(IsInfoVisible)); + set + { + var success = SetProperty(ref _IsSelected, value, nameof(IsSelected)); + if (success) + FirePropertyChanged(nameof(IsInfoVisible)); + } } public bool IsInfoVisible @@ -190,13 +196,13 @@ namespace BeWo.ViewModel ActionType = pDataContract.ActionType; } - public override bool IsDirty + public override bool IsDirty { get { if (!CanEdit) return _DirtyProps.Contains(nameof(IsFavorite)); - return _DirtyProps.Count > 0; + return _DirtyProps.Count > 0; } } } diff --git a/BeWo/ViewModel/ListViewModel/ServiceRecordListVM.cs b/BeWo/ViewModel/ListViewModel/ServiceRecordListVM.cs index 9071f6bb1..a69b0a8b3 100644 --- a/BeWo/ViewModel/ListViewModel/ServiceRecordListVM.cs +++ b/BeWo/ViewModel/ListViewModel/ServiceRecordListVM.cs @@ -185,31 +185,31 @@ namespace BeWo.ViewModel.ListViewModel private void InitAiStuff() { - var vm_doku = new AiPromptbausteinSelectionComplexViewModel(AiActionType.ServiceRecordDocumentation); + //var vm_doku = new AiPromptbausteinSelectionComplexViewModel(AiActionType.ServiceRecordDocumentation); - vm_doku.PromptAccepted += PromptAccepted; + //vm_doku.PromptAccepted += PromptAccepted; - OpenAiPromptSelectionCommand = CommandFactory.GetAiViewCommand( - () => BeWoApp.MainControl.WindowService.Show(vm_doku), - null, - () => !string.IsNullOrWhiteSpace(AktuellerDokutext)); + //OpenAiPromptSelectionCommand = CommandFactory.GetAiViewCommand( + // () => BeWoApp.MainControl.WindowService.Show(vm_doku), + // null, + // () => !string.IsNullOrWhiteSpace(AktuellerDokutext)); UndoAiActionCommand = new DelegateCommand(UndoAiAction); RedoAiActionCommand = new DelegateCommand(RedoAiAction); - var vm_edit_doku = new AiPromptbausteinSelectionComplexViewModel(AiActionType.ServiceRecordDocumentation); + //var vm_edit_doku = new AiPromptbausteinSelectionComplexViewModel(AiActionType.ServiceRecordDocumentation); - vm_edit_doku.PromptAccepted += EditPromptAccepted; + //vm_edit_doku.PromptAccepted += EditPromptAccepted; - OpenEditAiPromptSelectionCommand = CommandFactory.GetAiViewCommand(() => - { - _EditAiActionHistory = new List(); - _EditAiActionHistory.Add(AktuellerEditDokutext); - _EditAiActionHistoryIndex = 0; - BeWoApp.MainControl.WindowService.Show(vm_edit_doku); - }, - null, - () => !string.IsNullOrWhiteSpace(AktuellerEditDokutext)); + //OpenEditAiPromptSelectionCommand = CommandFactory.GetAiViewCommand(() => + //{ + // _EditAiActionHistory = new List(); + // _EditAiActionHistory.Add(AktuellerEditDokutext); + // _EditAiActionHistoryIndex = 0; + // BeWoApp.MainControl.WindowService.Show(vm_edit_doku); + //}, + //null, + //() => !string.IsNullOrWhiteSpace(AktuellerEditDokutext)); UndoEditAiActionCommand = new DelegateCommand(UndoEditAiAction); RedoEditAiActionCommand = new DelegateCommand(RedoEditAiAction); @@ -256,7 +256,7 @@ namespace BeWo.ViewModel.ListViewModel public bool IsEditUndoButtonVisible => _EditAiActionHistoryIndex > 0; public bool IsEditRedoButtonVisible => _EditAiActionHistoryIndex < (_EditAiActionHistory?.Count ?? 0) - 1; - private void PromptAccepted(object sender, AiPromptbausteinPromptVM prompt) + public void PromptAccepted(object sender, AiPromptbausteinPromptVM prompt) { if (prompt is null) throw new NotImplementedException(); @@ -363,7 +363,7 @@ namespace BeWo.ViewModel.ListViewModel ); } - private void EditPromptAccepted(object sender, AiPromptbausteinPromptVM prompt) + public void EditPromptAccepted(object sender, AiPromptbausteinPromptVM prompt) { if (prompt is null) throw new NotImplementedException(); diff --git a/BeWo/ViewModel/View/AI/AiPromptbausteinComplexSelectionViewModel.cs b/BeWo/ViewModel/View/AI/AiPromptbausteinComplexSelectionViewModel.cs index 7f30a0cd7..b57f83cdc 100644 --- a/BeWo/ViewModel/View/AI/AiPromptbausteinComplexSelectionViewModel.cs +++ b/BeWo/ViewModel/View/AI/AiPromptbausteinComplexSelectionViewModel.cs @@ -19,6 +19,7 @@ namespace BeWo.ViewModel.View.AI public event EventHandler PromptAccepted; private AiPromptbausteinFolderVM _SelectedFolder; + private AiPromptbausteinPromptVM _SelectedPrompt; public AiPromptbausteinSelectionComplexViewModel() { @@ -33,12 +34,15 @@ namespace BeWo.ViewModel.View.AI { AiActionType = aiActionType; } - public AiPromptbausteinSelectionComplexViewModel(AiActionType aiActionType, AiPromptbausteinFolderListVM viewModel) : this(aiActionType) + public AiPromptbausteinSelectionComplexViewModel(AiActionType aiActionType, AiPromptbausteinFolderListVM viewModel, bool isFavorite = false) : this(aiActionType) { LoadedActionType = aiActionType; Folders = viewModel; + IsFavorite = isFavorite; } + public bool IsFavorite { get; set; } + public ICommand SendCommand { get; set; } public AiActionType AiActionType { get; set; } @@ -52,10 +56,25 @@ namespace BeWo.ViewModel.View.AI FirePropertyChanged(nameof(SelectedFolder)); } } - public AiPromptbausteinPromptVM SelectedPrompt { get; set; } + public AiPromptbausteinPromptVM SelectedPrompt + { + get => _SelectedPrompt; + set + { + _SelectedPrompt = value; + FirePropertyChanged(nameof(SelectedPrompt)); + } + } public AiPromptbausteinFolderListVM Folders { get; private set; } public AiActionType LoadedActionType { get; set; } + public void ResetSelection() + { + if (!IsFavorite) + SelectedFolder = null; + + SelectedPrompt = null; + } public void Send() { CloseDialogCommand.Execute(null); diff --git a/Service/Plugins/AiFunctionService.cs b/Service/Plugins/AiFunctionService.cs index 93b6d1c45..22389a96e 100644 --- a/Service/Plugins/AiFunctionService.cs +++ b/Service/Plugins/AiFunctionService.cs @@ -75,6 +75,9 @@ namespace BeWo.Service.Plugins if (model == null) throw new NotImplementedException(); + if (user_prompt == null) + user_prompt = string.Empty; + var messages = new List() { system, user_prompt From aff1829c43f26cb49ff19b762697e2d07e64000a Mon Sep 17 00:00:00 2001 From: Alexandra Date: Fri, 13 Mar 2026 13:38:14 +0100 Subject: [PATCH 05/11] PariMobil/Reporting/CustomReportCreator - Kommentierung Filter QB an Rechnungen --- ReportImp/PariMobil/Reporting/CustomReportCreator.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ReportImp/PariMobil/Reporting/CustomReportCreator.cs b/ReportImp/PariMobil/Reporting/CustomReportCreator.cs index 5632a7617..c156797ef 100644 --- a/ReportImp/PariMobil/Reporting/CustomReportCreator.cs +++ b/ReportImp/PariMobil/Reporting/CustomReportCreator.cs @@ -85,6 +85,7 @@ namespace PariMobil.Reporting public override XtraReport CreateSettlementReportMitQB(String dcId, long? invoiceBaseOid) { + // Override nur für CreateBelegeForSpitzabrechnung - CreateBelegeForInvoice ist in der Basis schreibgeschützt - Auswahl QBs mit nur FLS (Oid = 1) XtraReport report = null; String reportId = null; var lSettlementDC = GetSettlementDC(dcId, invoiceBaseOid); @@ -126,6 +127,7 @@ namespace PariMobil.Reporting if (invoiceBase.CostBearer2SupportConcept != null) { var customerOid = invoiceBase.CostBearer2SupportConcept.SupportConcept.Customer.Oid.Value; + //Auswahl QBs mit nur FLS(Oid = 1) return CreateServiceOverviewReportNew(QBFilterEnum.KlientenAuswahl, customerOid, null, null, null, 1, invoiceBase.AccountingPeriodStart.Value, invoiceBase.AccountingPeriodEnd.Value, false); } From e20af24af84d33de46aa8b8cce9aa8395af9251d Mon Sep 17 00:00:00 2001 From: Alexandra Date: Fri, 13 Mar 2026 13:38:47 +0100 Subject: [PATCH 06/11] AWOMuensterlandRecklinghausen/Service/CustomTranslationDictionary - Weitere Eigenschaften Planungsdetails umbenannt --- .../AWOMuensterlandRecklinghausen.csproj | 1 + .../Service/CustomTranslationDictionary.cs | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 ReportImp/AWOMuensterlandRecklinghausen/Service/CustomTranslationDictionary.cs diff --git a/ReportImp/AWOMuensterlandRecklinghausen/AWOMuensterlandRecklinghausen.csproj b/ReportImp/AWOMuensterlandRecklinghausen/AWOMuensterlandRecklinghausen.csproj index 92f251dad..70a85c0ad 100644 --- a/ReportImp/AWOMuensterlandRecklinghausen/AWOMuensterlandRecklinghausen.csproj +++ b/ReportImp/AWOMuensterlandRecklinghausen/AWOMuensterlandRecklinghausen.csproj @@ -98,6 +98,7 @@ SbdRechnung2024.cs + Component diff --git a/ReportImp/AWOMuensterlandRecklinghausen/Service/CustomTranslationDictionary.cs b/ReportImp/AWOMuensterlandRecklinghausen/Service/CustomTranslationDictionary.cs new file mode 100644 index 000000000..aef44e1d9 --- /dev/null +++ b/ReportImp/AWOMuensterlandRecklinghausen/Service/CustomTranslationDictionary.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using BeWo.Data.Access; +using BeWo.Data.Entities; +using BeWo.Service.DCEntityMapper; +using BeWo.Service.Plugins; +using BS.Shared; +using BS.Shared.Core; +using BS.Shared.DataContracts.Compact; +using BS.Shared.Extensions; + +namespace AutismusKoelnBonn.Translation +{ + public class CustomTranslationDictionary : TranslationDictionary + { + public override Dictionary GetTranslationDictionary() + { + var dict = base.GetTranslationDictionary(); + AddOrReplaceTranslation(dict, "CustomerVarFieldsTitle", "Planungsdetails"); + return dict; + } + } +} From b8adba6251cb8324f9ae3375dc6faaf8e55f385e Mon Sep 17 00:00:00 2001 From: Alexandra Date: Fri, 13 Mar 2026 13:39:13 +0100 Subject: [PATCH 07/11] =?UTF-8?q?HshCologne/Invoicing/CustomInvoiceCreatio?= =?UTF-8?q?n=20-=20Unterscheidung=20Qualifikation=20auch=20f=C3=BCr=20Wess?= =?UTF-8?q?eling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../HshCologne/Invoicing/CustomInvoiceCreation.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ReportImp/HshCologne/Invoicing/CustomInvoiceCreation.cs b/ReportImp/HshCologne/Invoicing/CustomInvoiceCreation.cs index e6ff502ba..824f4c05a 100644 --- a/ReportImp/HshCologne/Invoicing/CustomInvoiceCreation.cs +++ b/ReportImp/HshCologne/Invoicing/CustomInvoiceCreation.cs @@ -247,7 +247,7 @@ namespace HshCologne.Invoicing } // Da diverse Kostenträger liegen deren Stundensätze unter Preise - // Während Wesseling und Geilenkirchen für ALLES nur einen Stundensatz haben + // Während Wesseling und Geilenkirchen für (fast) ALLES nur einen Stundensatz haben // Und Erftstadt macht sowieso ALLES anders :D decimal stundensatz = 0; if (iServiceRecord.ServiceDescription.CategoryName == "FAM") @@ -262,6 +262,14 @@ namespace HshCologne.Invoicing if (iServiceRecord.CostBearer.Name.Contains("Wesseling")) { stundensatz = GetStundensatz(scap.CostBearer2SupportConcept, null, iServiceRecord.Start); + // AB, 13.03.2026: bisher nur der Stundensatz unter Organisation, jetzt erste Ausnahme -> eigene Quali dafür + var qOid = iServiceRecord.Employee.ValueListEntries + .Where(i => i.Value == ValueListEntryType.StaffQualificationsType).Select(i => i.Key).OrderByDescending(q => q).ToList(); + if (qOid.Any(q => q == 1477)) + { + stundensatz = preisAK; + ii.UnitDescription = "Assistenzkraft"; + } } // Erfstadt hat in der Familienhilfe teileweise noch den Sonderfall UMA, dort wird geringer bezahlt, Stundensatz nach Quali bei Organisation, sonst normal // Erftstadt hat keine SB From 18f1e89b6528cefcb20d22ba1ebc4859d28cd4ca Mon Sep 17 00:00:00 2001 From: Alexandra Date: Fri, 13 Mar 2026 13:39:39 +0100 Subject: [PATCH 08/11] IBAHSeV/Import/CustomDataImporter - LWL Bankingimport --- ReportImp/IBAHSeV/IBAHSeV.csproj | 2 +- .../IBAHSeV/Import/CustomDataImporter.cs | 155 ++++++++++++++++++ 2 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 ReportImp/IBAHSeV/Import/CustomDataImporter.cs diff --git a/ReportImp/IBAHSeV/IBAHSeV.csproj b/ReportImp/IBAHSeV/IBAHSeV.csproj index 969de4adf..24b39a1de 100644 --- a/ReportImp/IBAHSeV/IBAHSeV.csproj +++ b/ReportImp/IBAHSeV/IBAHSeV.csproj @@ -65,6 +65,7 @@ + @@ -139,7 +140,6 @@ - diff --git a/ReportImp/IBAHSeV/Import/CustomDataImporter.cs b/ReportImp/IBAHSeV/Import/CustomDataImporter.cs new file mode 100644 index 000000000..16d3dbe1b --- /dev/null +++ b/ReportImp/IBAHSeV/Import/CustomDataImporter.cs @@ -0,0 +1,155 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; +using BeWo.Data.Access; +using BeWo.Data.Entities; +using BeWo.Service.Core; +using BeWo.Service.Import.AvisImport; +using BeWo.Service.Plugins; +using BS.Shared.Core; +using BS.Shared.DataContracts; +using Utils = BS.Shared.Core.Utils; + +namespace IBAHS.Import +{ + public class CustomLvrAviseImporter : LvrAviseImporter + { + public override String ImportCsvAvise(String csv) + { + var reader = new LvrAvisCsvReader(); + var avise = LeseEinzelAviseLWL(csv); + var hilfeplaene = CreateHilfeplanInfos(); + + return ImportAvise(avise, hilfeplaene); + } + + private List LeseEinzelAviseLWL(string importfile) + { + List liste = new List(); + String[] lines = importfile.Split('\n'); + + for (int i = 0; i < lines.Count(); i++) + { + string line = lines[i]; + var fields = line.Split(';'); + if (fields.Length >= 10) + { + if (!String.IsNullOrEmpty(fields[4]) && !String.IsNullOrEmpty(fields[5]) && !String.IsNullOrEmpty(fields[8]) + && (fields[5].ToString().Contains("Westfalen-Lippe") || fields[5].ToString().Contains("LWL"))) + { + try + { + DateTime gueltigkeitsTag = DateTime.Now; + decimal betrag = 0m; + + var neuerAvis = new Avis(); + decimal.TryParse(fields[8], out betrag); + neuerAvis.Betrag = betrag; + fields[4] = fields[4].Trim(); + if (!String.IsNullOrEmpty(fields[4])) + { + var zweck = fields[4]; + string pattern = @"^(?:[^/]*/){5}([^/]*)"; // Sucht den gesamten Text nach dem 5. / -> also der Teil mit Aktenzeichen und Name + Match matchVerwendung = Regex.Match(zweck, pattern); + if (matchVerwendung.Success) + { + neuerAvis.Klient = matchVerwendung.Groups[1].Value.Substring(8).Trim(); + neuerAvis.Klient = Regex.Replace(neuerAvis.Klient, @"\b([A-ZÄÖÜ][a-zäöüß]+)\s*\1\b", "$1"); // Der Nachname kommt fast immer doppelt vor, wird hier gefiltert + neuerAvis.Verwendungszweck = matchVerwendung.Groups[1].Value.Substring(8).Trim(); + neuerAvis.Aktenzeichen = matchVerwendung.Groups[1].Value.Substring(0, 7); + } + else + { + neuerAvis.Klient = zweck; + neuerAvis.Verwendungszweck = zweck; + neuerAvis.Aktenzeichen = zweck; + } + + var teilEins = zweck.Substring(0, 50).Replace(" ", ""); + var date = teilEins.Substring(23, 10); + if (int.TryParse(date, out int resultMonat) && int.TryParse(date, out int resultJahr)) + { + gueltigkeitsTag = new DateTime(resultJahr, resultMonat, 1); + } + else + { + if (DateTime.TryParse(date, out DateTime resultHp)) + { + gueltigkeitsTag = resultHp; + } + else + { + var datumMonat = fields[1].Substring(fields[1].Length - 7, 2); + var datumJahr = fields[1].Substring(fields[1].Length - 4, 4); + if (int.TryParse(datumMonat, out int resultMonth) && int.TryParse(datumJahr, out int resultYear)) + { + gueltigkeitsTag = new DateTime(resultYear, resultMonth, 1); + } + else + { + if (DateTime.TryParse(fields[4], out DateTime resultDate)) + { + gueltigkeitsTag = resultDate; + } + } + } + } + neuerAvis.GueltigkeitsDatum = gueltigkeitsTag; + } + else + { + neuerAvis.Verwendungszweck = "kein Text"; + neuerAvis.Aktenzeichen = "kein Text"; + } + neuerAvis.BuchungsDatum = DateTime.Now; + //neuerAvis.Sachbearbeiter = fields[13] + ", " + fields[14]; + if (neuerAvis.Betrag != 0) + { + liste.Add(neuerAvis); + } + } + catch (Exception e) + { + //ignore + } + } + } + } + return liste; + } + + public override List CreateHilfeplanInfos() + { + List liste = new List(); + var scList = DAOFactory.GenericDAO.GetAllActiveAndArchived(); + + foreach (var supportConcept in scList) + { + foreach (var cb2sc in supportConcept.CostBearer2SupportConceptList) + { + HilfeplanInfo hi = new HilfeplanInfo(); + hi.Start = cb2sc.StartDate; + hi.Ende = cb2sc.EndDate; + var reference = cb2sc.CustomerReferenceNumber; + if (!String.IsNullOrEmpty(reference)) + { + reference = reference.Replace("-", ""); + reference = reference.Replace("/", "").Trim(); + } + hi.Aktenzeichen = reference; + hi.CostBearer2SupportConcept = cb2sc; + hi.CustomerFirstName = cb2sc.SupportConcept.Customer.Person.FirstName; + hi.CustomerLastName = cb2sc.SupportConcept.Customer.Person.LastName; + + if (hi.Start.HasValue && hi.Ende.HasValue && !String.IsNullOrEmpty(hi.Aktenzeichen)) + { + liste.Add(hi); + } + } + } + + return liste; + } + } +} From 04d8ab035bb16459f18712324d1122a2ce7d191e Mon Sep 17 00:00:00 2001 From: Alexandra Date: Fri, 13 Mar 2026 13:40:08 +0100 Subject: [PATCH 09/11] LebenshilfeBadKreuznachFUD/Export/SageExporter - Abrechnung Kita als neuen Export aufgenommen --- .../Export/SageExporter.cs | 40 +++++++++++++++++-- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/ReportImp/LebenshilfeBadKreuznachFUD/Export/SageExporter.cs b/ReportImp/LebenshilfeBadKreuznachFUD/Export/SageExporter.cs index 50c147b4e..657c262fd 100644 --- a/ReportImp/LebenshilfeBadKreuznachFUD/Export/SageExporter.cs +++ b/ReportImp/LebenshilfeBadKreuznachFUD/Export/SageExporter.cs @@ -35,6 +35,11 @@ namespace LebenshilfeBadKreuznachFUD.Export query.FileName = String.Format("SageExportAutismus{0:yyyyMM}.csv", dt); query.QueryResult = GetAbrechnungenString(dt, "Autismus"); } + else if (query.Oid == 103) + { + query.FileName = String.Format("SageExportKita{0:yyyyMM}.csv", dt); + query.QueryResult = GetAbrechnungenString(dt, "Kita"); + } return query; } @@ -95,7 +100,7 @@ ib.AccountingPeriodEnd, String buchungstext = GetBuchungstext(row, teamname); sb.Append(buchungstext); sb.Append(";"); - if (teamname == "Integration") + if (teamname == "Integration"|| teamname == "Kita") { sb.Append(String.Format("{0}", row[7])); // Sollkonto - Kundennr. Kostenträger } @@ -113,12 +118,27 @@ ib.AccountingPeriodEnd, String costCenter = GetKostenstelle(row[9], teamname); sb.Append(costCenter + ";"); // Kostenstelle (String.Format("{0}", row[9])); sb.Append(costCenter + ";"); // Kostenstelle Haben (String.Format("{0}", row[9])); - sb.Append(";;;12"); // Buchungskreis + String buchungskreis = GetBuchungskreis(row[9], teamname); + sb.Append(String.Format(";;;{0}", buchungskreis)); // Buchungskreis } return sb.ToString(); } + private static string GetBuchungskreis(object v, string teamname) + { + string kreis = "12"; + if (teamname == "Kita") // Kostenstelle ist bei Kind hinterlegt; Kostenstelle spezifisch für jede Kita, damit Buchungskreis ableitbar (ansonsten müsste man über Team des Kindes gehen) + { + kreis = "2"; + if (v.ToString() != null && v.ToString().ToLower().Contains("t80600")) + { + kreis = "3"; + } + } + return kreis; + } + private static string GetBuchungstext(DataRow row, string teamname) { String text = String.Format("{0:MM}/{0:yyyy} {1} - {2}", row[11], row[5], row[6]); @@ -130,6 +150,10 @@ ib.AccountingPeriodEnd, { text = "AR-ENT " + text; } + else if (teamname == "Kita") + { + text = "AR-PS " + text; + } return text; } @@ -161,6 +185,14 @@ ib.AccountingPeriodEnd, kto = "S82029"; } } + else if (teamname == "Kita") // Kostenstelle ist bei Kind hinterlegt; Kostenstelle spezifisch für jede Kita, damit Konto ableitbar (ansonsten müsste man über Team des Kindes gehen) + { + kto = "S82002"; + if (row[9].ToString() != null && row[9].ToString().ToLower().Contains("t80600")) + { + kto = "S82003"; + } + } return kto; } @@ -171,7 +203,7 @@ ib.AccountingPeriodEnd, { stelle = "T70400"; } - else if (teamname == "Entlastung") + else if (teamname == "Entlastung" || teamname == "Kita") { stelle = String.Format("{0}", v); } @@ -209,7 +241,7 @@ inner join serviceinvoiceperiod sip on sip.serviceinvoiceoid = si.oid inner join invoiceitem ii on ii.serviceinvoiceperiodoid = sip.oid WHERE ib.`AccountingPeriodEnd` >= ':Monat_Start' AND ib.`AccountingPeriodEnd` < ':Monat_End' and ib.IsActive = 1 ORDER BY p.`LastName`, p.`FirstName`, cb2sc.`ApprovedStartDate`, ii.GrossAmountTotal desc) AS sqry -WHERE Team = ':teamname' +WHERE Team like ':teamname%' "; return sql; From 505ec6f2d0fd787e3b18e486e85ab1f94a07a03b Mon Sep 17 00:00:00 2001 From: Alexandra Date: Fri, 13 Mar 2026 13:40:26 +0100 Subject: [PATCH 10/11] MalteserJohanniterJohanneshaus/CustomReportCreator - Filter QB an Spitzabrechnung auf FLS --- .../CustomReportCreator.cs | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/ReportImp/MalteserJohanniterJohanneshaus/CustomReportCreator.cs b/ReportImp/MalteserJohanniterJohanneshaus/CustomReportCreator.cs index f2ac0289f..f0b23144d 100644 --- a/ReportImp/MalteserJohanniterJohanneshaus/CustomReportCreator.cs +++ b/ReportImp/MalteserJohanniterJohanneshaus/CustomReportCreator.cs @@ -235,5 +235,56 @@ namespace MalteserJohanniterJohanneshaus return report as XtraReport; } + + public override XtraReport CreateSettlementReportMitQB(String dcId, long? invoiceBaseOid) + { + // Override nur für CreateBelegeForSpitzabrechnung - CreateBelegeForInvoice ist in der Basis schreibgeschützt - Auswahl QBs mit nur FLS (Oid = 1) + XtraReport report = null; + String reportId = null; + var lSettlementDC = GetSettlementDC(dcId, invoiceBaseOid); + + if (lSettlementDC.CostBearer2SupportConceptOid.HasValue) + { + CostBearer2SupportConcept c2s = DAOFactory.GenericDAO.LoadByID(lSettlementDC.CostBearer2SupportConceptOid.Value); + reportId = c2s.CostBearer.ID; + } + + if (lSettlementDC.DifferentHourlyRateCount > 0) + { + + IBeWoReport lSettlementReport = FindReportImp(reportId); + var ro = SettlementRO.Create(lSettlementDC); + lSettlementReport.SetReportDataSource(ro); + + report = lSettlementReport as XtraReport; + } + else + { + IBeWoReport lSettlementReport = FindReportImp(reportId); + lSettlementReport.SetReportDataSource(Settlement2RO.Create(lSettlementDC)); + report = lSettlementReport as XtraReport; + } + + if (lSettlementDC.InvoiceBaseOid.HasValue) + { + var sb = DAOFactory.GenericDAO.LoadByID(lSettlementDC.InvoiceBaseOid.Value); + var qb = CreateBelegeForSpitzabrechnung(sb); + + AddReportPagesToMaster(report, qb); + } + return report; + } + + protected virtual XtraReport CreateBelegeForSpitzabrechnung(InvoiceBase invoiceBase) + { + if (invoiceBase.CostBearer2SupportConcept != null) + { + var customerOid = invoiceBase.CostBearer2SupportConcept.SupportConcept.Customer.Oid.Value; + //Auswahl QBs mit nur FLS(Oid = 1) + return CreateServiceOverviewReportNew(QBFilterEnum.KlientenAuswahl, customerOid, null, null, null, 1, invoiceBase.AccountingPeriodStart.Value, invoiceBase.AccountingPeriodEnd.Value, false); + } + + return null; + } } } From afe3e5cd656c3ee2fecbd16c25ff37ddca061fe6 Mon Sep 17 00:00:00 2001 From: Rene Evertz Date: Fri, 13 Mar 2026 14:45:56 +0100 Subject: [PATCH 11/11] AiDocu Button Popup Update --- BeWo/BeWo.csproj | 1 + BeWo/BeWoApp.xaml | 1 + BeWo/Converter/StringEmptyBoolConverter.cs | 28 ++++++++++++++ .../Controls/AI/AiPromptbausteinButton.xaml | 2 +- .../AI/AiPromptbausteinButton.xaml.cs | 37 +++++++++++++++---- .../Zeiterfassung/ServiceRecordView2.xaml | 13 ++----- .../ListViewModel/ServiceRecordListVM.cs | 4 +- 7 files changed, 67 insertions(+), 19 deletions(-) create mode 100644 BeWo/Converter/StringEmptyBoolConverter.cs diff --git a/BeWo/BeWo.csproj b/BeWo/BeWo.csproj index 34a5cc250..cf1c9e42d 100644 --- a/BeWo/BeWo.csproj +++ b/BeWo/BeWo.csproj @@ -106,6 +106,7 @@ + diff --git a/BeWo/BeWoApp.xaml b/BeWo/BeWoApp.xaml index 042c908b3..43aa8902a 100644 --- a/BeWo/BeWoApp.xaml +++ b/BeWo/BeWoApp.xaml @@ -86,6 +86,7 @@ + diff --git a/BeWo/Converter/StringEmptyBoolConverter.cs b/BeWo/Converter/StringEmptyBoolConverter.cs new file mode 100644 index 000000000..3bb495e3a --- /dev/null +++ b/BeWo/Converter/StringEmptyBoolConverter.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; + +namespace BeWo.Converter +{ + public class StringEmptyBoolConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is string stringi) + { + return !string.IsNullOrEmpty(stringi); + } + + return false; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/BeWo/View/Controls/AI/AiPromptbausteinButton.xaml b/BeWo/View/Controls/AI/AiPromptbausteinButton.xaml index d7d1203c9..df37ce2af 100644 --- a/BeWo/View/Controls/AI/AiPromptbausteinButton.xaml +++ b/BeWo/View/Controls/AI/AiPromptbausteinButton.xaml @@ -22,10 +22,10 @@