diff --git a/BeWo/BeWo.csproj b/BeWo/BeWo.csproj index bfdadcc00..901c45e52 100644 --- a/BeWo/BeWo.csproj +++ b/BeWo/BeWo.csproj @@ -109,6 +109,9 @@ + + + @@ -117,6 +120,9 @@ AiConfigView.xaml + + AiPromptbausteinView.xaml + RtfEditView.xaml @@ -136,6 +142,10 @@ Designer MSBuild:Compile + + MSBuild:Compile + Designer + MSBuild:Compile Designer diff --git a/BeWo/View/Detail/AI/AiPromptbausteinView.xaml b/BeWo/View/Detail/AI/AiPromptbausteinView.xaml new file mode 100644 index 000000000..31709b097 --- /dev/null +++ b/BeWo/View/Detail/AI/AiPromptbausteinView.xaml @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BeWo/View/Detail/AI/AiPromptbausteinView.xaml.cs b/BeWo/View/Detail/AI/AiPromptbausteinView.xaml.cs new file mode 100644 index 000000000..40e7baee9 --- /dev/null +++ b/BeWo/View/Detail/AI/AiPromptbausteinView.xaml.cs @@ -0,0 +1,304 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Input; + +using BeWo.ServiceProxy; +using BeWo.ViewModel; +using BeWo.ViewModel.ListViewModel; + +using BS.Shared; +using BS.Shared.Extensions; +using BS.Shared.Translation; +using DevExpress.Xpf.Editors; +using DevExpress.Xpf.Grid; + +namespace BeWo.View.Detail +{ + public partial class AiPromptbausteinView + { + private AiPromptbausteinListVM _ViewModel; + + public AiPromptbausteinListVM ViewModel + { + get => _ViewModel; + + set + { + _ViewModel = value; + root.DataContext = value; + } + } + + public override bool IsDirty => ViewModel != null && ViewModel.IsDirty; + + private readonly bool _IsInAdministrationView; + + public AiPromptbausteinView(AiPromptbausteinListVM pViewModel, bool pIsInAdministrationView = false) + { + InitializeComponent(); + + _IsInAdministrationView = pIsInAdministrationView; + + ViewModel = pViewModel; + } + + protected override void Save() + { + Save(null); + } + + public void Save(Action pCallBack) + { + var lToDos = new List>(); + + if(ViewModel.ChangedCount == 0 && ViewModel.RemovedCount == 0 && ViewModel.AddedCount == 0) + { + return; + } + + if (ViewModel.AddedCount > 0) + { + lToDos.Add(s => s.InsertNewAiPromptbausteine(ViewModel.CommitAdded())); + } + + if (ViewModel.RemovedCount > 0) + { + lToDos.Add(s => s.DeleteAiPromptbausteine(ViewModel.GetRemoved().ToDictionary(dc => dc.Oid.Value, dc => dc.Version.Value))); + } + + if (ViewModel.ChangedCount > 0) + { + lToDos.Add(s => s.UpdateAiPromptbausteine(ViewModel.CommitChanged())); + } + + ServiceFacade.DoMultipleOperationsServicesAsync(lToDos, () => + { + pCallBack?.Invoke(); + ReloadViewModel(); + }); + } + + private void ReloadViewModel() + { + VMFactory.CreateAiPromptbausteinListVMAsync(r => this.Dispatch(delegate + { + TreeListControl.BeginDataUpdate(); + + ViewModel = r; + + TreeListControl.EndDataUpdate(); + + TreeListControl.SelectedItems.Clear(); + + }), _IsInAdministrationView); + } + + private void DeleteButton_Click(object sender, RoutedEventArgs e) + { + var focusedNode = TreeListView.FocusedNode; + var selectedAiPromptbaustein = (AiPromptbausteinVM) focusedNode.Content; + + String msg = "der ausgewähte KI-Prompt"; + if (selectedAiPromptbaustein.IsParent) + { + msg = "die ausgewähte Kategorie"; + } + + if (MessageBox.Show(Translator.Translate("Sie Sie sicher, dass {0} \"{1}\" gelöscht werden soll?", msg, selectedAiPromptbaustein.Name), "Löschen", MessageBoxButton.YesNo, MessageBoxImage.Exclamation) == MessageBoxResult.Yes) + { + _ChildrenToDelete.Add(selectedAiPromptbaustein); + + if (selectedAiPromptbaustein.IsParent) + { + RetrieveChildAiPromptbausteinsFromParent(selectedAiPromptbaustein); + } + + ViewModel.VMList.RemoveRange(_ChildrenToDelete); + _ChildrenToDelete.Clear(); + } + } + + private readonly List _ChildrenToDelete = new List(); + + private void RetrieveChildAiPromptbausteinsFromParent(AiPromptbausteinVM parent) + { + var children = ViewModel.VMList.Where(w => w.Parent != null && w.Parent.Equals(parent)); + + foreach(var child in children) + { + _ChildrenToDelete.Add(child); + RetrieveChildAiPromptbausteinsFromParent(child); + } + } + + public static bool CheckEditorRights(AiPromptbausteinVM textbausteinVM, object parameter) + { + if (textbausteinVM != null) + { + var isOwn = textbausteinVM.Employee != null && textbausteinVM.Employee.EmployeeOid.Equals(BeWoApp.LoggedOnEmployee.EmployeeOid); + + var hasRight2EditAll = BeWoApp.LoggedOnUser.HasRight(UserRightType.TextbausteineAlleBearbeiten); + var hasRight2EditOwn = BeWoApp.LoggedOnUser.HasRight(UserRightType.TextbausteineNurEigeneBearbeiten); + var hasRight2Create4All = BeWoApp.LoggedOnUser.HasRight(UserRightType.TextbausteineAlleBearbeiten); + + if (parameter != null && parameter.ToString().Equals("IsOnlyForEmployeeCheckBox")) + { + return isOwn && hasRight2EditOwn && hasRight2Create4All || hasRight2EditAll; + } + + return isOwn && hasRight2EditOwn || hasRight2EditAll; + } + + return false; + } + + private void ContextMenuAiPromptbausteins_Click(object sender, RoutedEventArgs e) + { + if(e.OriginalSource is MenuItem twi) + { + var selectedItem = TreeListControl.SelectedItem as AiPromptbausteinVM; + + ViewModel.NewVM.IsParent = twi.Header.Equals("Neue Textbausteinkategorie"); + ViewModel.NewVM.IsExpanded = twi.Header.Equals("Neue Textbausteinkategorie"); + ViewModel.NewVM.IsOnlyForEmployee = !_IsInAdministrationView; + ViewModel.NewVM.Name = GenerateNewAiPromptbausteinName(twi.Header.ToString()); + + if(selectedItem != null) + { + ViewModel.NewVM.Parent = selectedItem; + } + + ViewModel.AddNewVMToList(false); + Save(); + } + } + + private string GenerateNewAiPromptbausteinName(string pName) + { + var newName = pName; + var counter = 1; + + while(ViewModel.VMList.Any(a => a.Name != null && a.Name.Equals(newName))) + { + newName = pName + " " + counter; + counter++; + } + + return newName; + } + + private void ContextMenuAiPromptbausteins_Opened(object sender, RoutedEventArgs e) + { + if (e.OriginalSource is ContextMenu menu) + { + var aiPromptbaustein = TreeListControl.SelectedItem as AiPromptbausteinVM; + + foreach (var menuitem in menu.Items.OfType().Select(item => item)) + { + if(aiPromptbaustein != null && !aiPromptbaustein.IsParent) + { + menuitem.IsEnabled = false; + } + else + { + menuitem.IsEnabled = true; + } + } + } + } + + private void TreeListControl_ItemsSourceChanged(object sender, DevExpress.Xpf.Grid.ItemsSourceChangedEventArgs e) + { + TreeListControl.SelectedItem = null; + } + + private void TreeListControl_OnPreviewMouseDown(object sender, MouseButtonEventArgs e) + { + var hitInfo = TreeListView.CalcHitInfo(e.OriginalSource as DependencyObject); + if(!hitInfo.InRowCell) + { + TreeListControl.SelectedItem = null; + } + + e.Handled = false; + } + + private void ButtonInfo_OnClick(object sender, RoutedEventArgs e) + { + if(sender is Button btn && btn.TemplatedParent is ButtonContainer bc) + { + if(bc.Content is ButtonInfo bi) + { + if(bi.Tag is EditGridCellData cellData) + { + var vm = (AiPromptbausteinVM) cellData.RowData.Row; + + vm.Parent = null; + vm.IsParent = false; + } + } + } + } + + // TODO: wird das gebraucht? Was tut es? + private void PART_Editor_OnEditValueChanged(object sender, EditValueChangedEventArgs e) + { + var comboBoxEdit = (ComboBoxEdit) sender; + var selectedAiPromptbaustein = (AiPromptbausteinVM) comboBoxEdit.Tag; + + var oldValue = e.OldValue; + var newValue = e.NewValue; + + if(e.NewValue != null) + { + selectedAiPromptbaustein.Parent = (AiPromptbausteinVM) e.NewValue; + } + } + + private void FrameworkElement_OnLoaded(object sender, RoutedEventArgs e) + { + var comboBoxEdit = (ComboBoxEdit) sender; + + var aiPromptbaustein = (AiPromptbausteinVM) comboBoxEdit.Tag; + + comboBoxEdit.ItemsSource = ViewModel.GetAiPromptbausteinParents(aiPromptbaustein); + } + + private void RemoveParentAiPromptbausteinFromNewVM_OnClick(object sender, RoutedEventArgs e) + { + ViewModel.NewVM.Parent = null; + } + + private void IsAiPromptbausteinParent_Checked(object sender, RoutedEventArgs e) + { + ViewModel.NewVM.Text = null; + } + + private void AddAiPromptbausteinButton_Click(object sender, RoutedEventArgs e) + { + ViewModel.NewVM.IsOnlyForEmployee = !_IsInAdministrationView; + ViewModel.AddNewVMToList(false); + Save(); + } + } + + public class IsOnlyForEmployeeRightsConverter2 : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + var aiPromptbausteinVM = (AiPromptbausteinVM)value; + + return AiPromptbausteinView.CheckEditorRights(aiPromptbausteinVM, parameter) && aiPromptbausteinVM != null && !aiPromptbausteinVM.IsParent; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/BeWo/ViewModel/AiPromptbausteinVM.cs b/BeWo/ViewModel/AiPromptbausteinVM.cs new file mode 100644 index 000000000..7baa020b5 --- /dev/null +++ b/BeWo/ViewModel/AiPromptbausteinVM.cs @@ -0,0 +1,250 @@ +using System.Windows; + +using BeWo.ServiceProxy; +using BeWo.Validation; + +using BS.Shared; +using BS.Shared.DataContracts; +using BS.Shared.DataContracts.Compact; + +namespace BeWo.ViewModel +{ + public class AiPromptbausteinVM : AbstractDCMapperVM + { + private int _Position; + + private string _Text; + + private string _Name; + + private CompactEmployeeDC _Employee; + + private ServiceCategoryDC _ServiceCategory; + + private bool _IsOnlyForEmployee; + + private bool _IsParent; + + private bool _IsExpanded; + + private AiPromptbausteinVM _Parent; + + private ActivationTypeId _ActivationType; + + public AiPromptbausteinVM(AiPromptbausteinDC pDataContract) : base(pDataContract, pDataContract.Oid == null) {} + + + public bool IsExpanded + { + get => _IsExpanded; + + set + { + if(AreDifferent(_IsExpanded, value)) + { + _IsExpanded = value; + StoreDirtyInformation(AreDifferent(DataContract.IsExpanded, value), nameof(IsExpanded)); + FirePropertyChanged(nameof(IsExpanded)); + } + } + } + + public CompactEmployeeDC Employee + { + get => _Employee; + + set + { + if (AreDifferent(_Employee, value)) + { + _Employee = value; + StoreDirtyInformation(AreDifferent(DataContract.Employee, value), nameof(Employee)); + FirePropertyChanged(nameof(Employee)); + } + } + } + + public ActivationTypeId ActivationType + { + get => _ActivationType; + + set + { + if(AreDifferent(_ActivationType, value)) + { + _ActivationType = value; + StoreDirtyInformation(AreDifferent(DataContract.ActivationType, value), nameof(ActivationType)); + + FirePropertyChanged(nameof(ActivationType)); + } + } + } + + public int Position + { + get => _Position; + + set + { + if (AreDifferent(_Position, value)) + { + _Position = value; + StoreDirtyInformation(AreDifferent(DataContract.Position, value), nameof(Position)); + FirePropertyChanged(nameof(Position)); + } + } + } + + public string Text + { + get => _Text; + + set + { + if (AreDifferent(_Text, value)) + { + _Text = value; + StoreDirtyInformation(AreDifferent(DataContract.Text, value), nameof(Text)); + FirePropertyChanged(nameof(Text)); + } + } + } + + public bool IsOnlyForEmployee + { + get => _IsOnlyForEmployee; + + set + { + if (AreDifferent(_IsOnlyForEmployee, value)) + { + _IsOnlyForEmployee = value; + StoreDirtyInformation(AreDifferent(DataContract.IsOnlyForEmployee, value), nameof(IsOnlyForEmployee)); + FirePropertyChanged(nameof(IsOnlyForEmployee)); + } + } + } + + public bool IsParent + { + get => _IsParent; + + set + { + if(AreDifferent(_IsParent, value)) + { + _IsParent = value; + StoreDirtyInformation(AreDifferent(DataContract.IsParent, value), nameof(IsParent)); + FirePropertyChanged(nameof(IsParent)); + } + } + } + + public AiPromptbausteinVM Parent + { + get => _Parent; + + set + { + if(AreDifferent(_Parent, value) && AreDifferent(value, this)) + { + _Parent = value; + StoreDirtyInformation(AreDifferent(DataContract.Parent, value), nameof(Parent)); + FirePropertyChanged(nameof(Parent)); + } + } + } + + public FontWeight FontWeight => _IsParent ? FontWeights.Bold : FontWeights.Normal; + + public long? KeyField => DataContract?.Oid; + + public long? ParentField => Parent?.DataContract?.Oid; + + [Validation(ValidationRule = ValidationRules.NotNullOrStringEmpty)] + public string Name + { + get => _Name; + + set + { + if (AreDifferent(_Name, value)) + { + _Name = value; + StoreDirtyInformation(AreDifferent(DataContract.Name, value), nameof(Name)); + FirePropertyChanged(nameof(Name)); + } + } + } + + protected override void InitByDataContract(AiPromptbausteinDC pDataContract) + { + if (!IsNew) + { + _Text = pDataContract.Text; + _Position = pDataContract.Position; + _Name = pDataContract.Name; + _Employee = pDataContract.Employee; + _IsOnlyForEmployee = pDataContract.IsOnlyForEmployee; + _IsParent = pDataContract.IsParent; + _Parent = pDataContract.Parent != null ? new AiPromptbausteinVM(pDataContract.Parent) : null; + _IsExpanded = pDataContract.IsExpanded; + + } + else + { + ServiceFacade.DoEmployeeServiceSync(s => _Employee = s.LoadCompactEmployee(BeWoApp.LoggedOnEmployee.EmployeeOid.Value)); + + if (BeWoApp.LoggedOnUser.HasRight(UserRightType.TextbausteineNurEigeneBearbeiten) && !BeWoApp.LoggedOnUser.HasRight(UserRightType.TextbausteineAlleBearbeiten)) + { + _IsOnlyForEmployee = true; + } + } + } + + protected override AiPromptbausteinDC MapToDataContract(AiPromptbausteinDC pDataContract, bool doCommit) + { + pDataContract.Text = _Text; + pDataContract.Position = _Position; + pDataContract.Name = _Name; + pDataContract.IsParent = _IsParent; + pDataContract.IsExpanded = _IsExpanded; + pDataContract.ActivationType = _ActivationType; + + pDataContract.IsOnlyForEmployee = _IsOnlyForEmployee; + + pDataContract.Parent = _Parent?.CommitToDataContract(); + + pDataContract.Employee = _Employee; + + return pDataContract; + } + + public override bool Equals(object pObj) + { + if (!(pObj is AiPromptbausteinVM)) + { + return false; + } + + var obj = (AiPromptbausteinVM) pObj; + + return + Equals(IsNew, obj.IsNew) && + Equals(ServiceCategory, obj.ServiceCategory) && + Equals(Text, obj.Text) && + Equals(Position, obj.Position) && + Equals(Parent, obj.Parent) && + Equals(Name, obj.Name) && + Equals(Employee, obj.Employee) && + Equals(IsOnlyForEmployee, obj.IsOnlyForEmployee) && + Equals(IsParent, obj.IsParent) && + Equals(IsDirty, obj.IsDirty); + } + + public override string ToString() + { + return _Name; + } + } +} diff --git a/BeWo/ViewModel/ListViewModel/AiPromptbausteinListVM.cs b/BeWo/ViewModel/ListViewModel/AiPromptbausteinListVM.cs new file mode 100644 index 000000000..c60560d29 --- /dev/null +++ b/BeWo/ViewModel/ListViewModel/AiPromptbausteinListVM.cs @@ -0,0 +1,28 @@ +using System.Collections.Generic; +using System.Linq; + +using BS.Shared.DataContracts; + +namespace BeWo.ViewModel.ListViewModel +{ + public class AiPromptbausteinListVM : AbstractDCListMapperVM + { + public static string PropertyName_PossibleAiPromptbausteinParents = "PossibleAiPromptbausteinParents"; + + private readonly List _PossibleAiPromptbausteinParents; + + + public AiPromptbausteinListVM(IEnumerable pDataContracts) : base(pDataContracts) + { + _PossibleAiPromptbausteinParents = VMList.Where(w => w.IsParent).ToList(); + } + + + public IEnumerable PossibleAiPromptbausteinParents => _PossibleAiPromptbausteinParents; + + public IEnumerable GetAiPromptbausteinParents(AiPromptbausteinVM aiPromptbaustein) + { + return _PossibleAiPromptbausteinParents.Except(new List {aiPromptbaustein}); + } + } +} diff --git a/BeWo/app.config b/BeWo/app.config index 81b961f06..dd34948a5 100644 --- a/BeWo/app.config +++ b/BeWo/app.config @@ -13,19 +13,19 @@ - - + + - - + + - + diff --git a/Data/Access/SearchDAO.cs b/Data/Access/SearchDAO.cs index 2b85c06d9..937ed0e19 100644 --- a/Data/Access/SearchDAO.cs +++ b/Data/Access/SearchDAO.cs @@ -2778,6 +2778,41 @@ WHERE sc.Billable = 1 and sr.StartDate >= '{0:yyyy-MM-dd}' and sr.StartDate < '{ return criteria.List(); } + public IEnumerable GetActiveAiPromptbausteine(bool shouldOnlyLoadOwnAiPromptbausteine, bool hasRightToSeeAll, bool isInAdministrationView, long employeeOid) + { + var criteria = CreateCriteriaIsActive(); + + if (isInAdministrationView) + { + criteria.Add(Restrictions.Eq(nameof(AiPromptbaustein.IsOnlyForEmployee), false)); + } + else if (!hasRightToSeeAll) + { + criteria.Add(Restrictions.Eq(nameof(AiPromptbaustein.IsOnlyForEmployee), true)) + .Add(Restrictions.Eq(nameof(AiPromptbaustein.Employee) + "." + nameof(BeWoEntityBase.Oid), employeeOid)); + } + else + { + criteria.Add( + Restrictions.Or( + Restrictions.And( + Restrictions.Eq(nameof(AiPromptbaustein.IsOnlyForEmployee), true), + Restrictions.Eq(nameof(AiPromptbaustein.Employee) + "." + nameof(BeWoEntityBase.Oid), employeeOid)), + Restrictions.Eq(nameof(AiPromptbaustein.IsOnlyForEmployee), false))); + } + + return criteria.List(); + } + + public IEnumerable GetChildAiPromptbausteine(AiPromptbaustein aiPromptbaustein) + { + var criteria = CreateCriteria(); + + criteria.Add(Restrictions.Eq(nameof(AiPromptbaustein.Parent), aiPromptbaustein)); + + return criteria.List(); + } + public IEnumerable FindEmployeeChatBewoMessageSync(long oid) { var c = CreateCriteriaIsActive() diff --git a/Data/Data.csproj b/Data/Data.csproj index a7ff94fef..f2d235039 100644 --- a/Data/Data.csproj +++ b/Data/Data.csproj @@ -235,6 +235,7 @@ + @@ -842,6 +843,9 @@ Designer + + Designer + Designer diff --git a/Data/Entities/AiPromptbaustein.cs b/Data/Entities/AiPromptbaustein.cs new file mode 100644 index 000000000..1efcbff7b --- /dev/null +++ b/Data/Entities/AiPromptbaustein.cs @@ -0,0 +1,21 @@ +using BS.Shared; + +namespace BeWo.Data.Entities +{ + public class AiPromptbaustein : BeWoEntityBase + { + public AiPromptbaustein() + { + _Tid = TableID.AiPromptbaustein; + } + + public virtual string Text { get; set; } + public virtual int Position { get; set; } + public virtual string Name { get; set; } + public virtual Employee Employee { get; set; } + public virtual bool IsOnlyForEmployee { get; set; } + public virtual AiPromptbaustein Parent { get; set; } + public virtual bool IsParent { get; set; } + public virtual bool IsExpanded { get; set; } + } +} diff --git a/Data/Mappings/AiPromptbaustein.hbm.xml b/Data/Mappings/AiPromptbaustein.hbm.xml new file mode 100644 index 000000000..48c3f1d56 --- /dev/null +++ b/Data/Mappings/AiPromptbaustein.hbm.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Model/Changes_2025-09-29 AI Promptbaustein.txt b/Model/Changes_2025-09-29 AI Promptbaustein.txt new file mode 100644 index 000000000..01da1db29 --- /dev/null +++ b/Model/Changes_2025-09-29 AI Promptbaustein.txt @@ -0,0 +1,24 @@ +CREATE TABLE `AiPromptbaustein` ( + `Oid` bigint NOT NULL AUTO_INCREMENT, + `Tid` int DEFAULT NULL, + `IsActive` tinyint(1) DEFAULT NULL, + `Notice` varchar(1024) DEFAULT NULL, + `InsTs` datetime DEFAULT NULL, + `InsUser` varchar(256) DEFAULT NULL, + `Version` bigint DEFAULT NULL, + `UdpUser` varchar(256) DEFAULT NULL, + `SystemEntryID` int DEFAULT NULL, + `Text` mediumtext, + `Position` int DEFAULT NULL, + `Name` varchar(256) DEFAULT NULL, + `EmployeeOid` bigint DEFAULT NULL, + `IsOnlyForEmployee` tinyint(1) DEFAULT NULL, + `ParentOid` bigint DEFAULT NULL, + `IsParent` tinyint(1) DEFAULT NULL, + `IsExpanded` tinyint DEFAULT NULL, + PRIMARY KEY (`Oid`), + KEY `EMPLOYEE_AIPROMPTBAUSTEIN_FK` (`EmployeeOid`), + KEY `FK_AIPROMPTBAUSTEIN2PARENT` (`ParentOid`), + CONSTRAINT `FK_EMPLOYEE_AIPROMPT` FOREIGN KEY (`EmployeeOid`) REFERENCES `employee` (`Oid`), + CONSTRAINT `FK_AIPROMPTBAUSTEIN2PARENT` FOREIGN KEY (`ParentOid`) REFERENCES `AiPromptbaustein` (`Oid`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; diff --git a/Service/DCEntityMapper/AiPromptbausteinDC_AiPromptbaustein.cs b/Service/DCEntityMapper/AiPromptbausteinDC_AiPromptbaustein.cs new file mode 100644 index 000000000..df9f2a894 --- /dev/null +++ b/Service/DCEntityMapper/AiPromptbausteinDC_AiPromptbaustein.cs @@ -0,0 +1,108 @@ +using BeWo.Data.Access; +using BeWo.Data.Entities; + +using BS.Shared.DataContracts; +using System.Collections.Generic; + +namespace BeWo.Service.DCEntityMapper +{ + public class AiPromptbausteinDC_AiPromptbaustein : AbstractIDCEntityMapper + { + public IList CreateDcList(IEnumerable aiPromptbausteine) + { + var list = new List(); + Dictionary> parentChildDict = new Dictionary>(); + foreach (var aiPromptbaustein in aiPromptbausteine) + { + var dc = CreateAiPromptbausteinDC(aiPromptbaustein, parentChildDict); + list.Add(dc); + } + + return list; + } + + private AiPromptbausteinDC CreateAiPromptbausteinDC(AiPromptbaustein tm, Dictionary> parentChildDict) + { + var dc = new AiPromptbausteinDC(); + dc.Position = tm.Position; + dc.Version = tm.Version.Value; + dc.Oid = tm.Oid.Value; + dc.Text = tm.Text; + dc.Name = tm.Name; + dc.IsOnlyForEmployee = tm.IsOnlyForEmployee; + dc.IsParent = tm.IsParent; + dc.IsExpanded = tm.IsExpanded; + dc.ActivationType = tm.IsActive; + + dc.Employee = tm.Employee != null ? MapperFactory.CompactEmployeeDC_Employee.MapToNewDC(tm.Employee) : null; + + if (tm.Parent != null) + { + // Endlosschleifen vermeiden: Parent eines Bausteins darf nicht gleichzeitig Kind des gleichen Bausteins sein + if (!parentChildDict.ContainsKey(tm.Parent.Oid.Value)) + { + parentChildDict.Add(tm.Parent.Oid.Value, new List()); + } + parentChildDict[tm.Parent.Oid.Value].Add(tm.Oid.Value); + + bool addParent = true; + if (parentChildDict.ContainsKey(tm.Oid.Value)) + { + var childOids = parentChildDict[tm.Oid.Value]; + + if (childOids.Contains(tm.Parent.Oid.Value)) + { + addParent = false; + } + } + + if (addParent && tm.Parent.IsActive != BS.Shared.ActivationTypeId.Deleted) + { + dc.Parent = CreateAiPromptbausteinDC(tm.Parent, parentChildDict); + } + } + + return dc; + } + + public override AiPromptbausteinDC MergeWithDC(AiPromptbaustein entity, AiPromptbausteinDC dataContract) + { + dataContract.Position = entity.Position; + dataContract.Version = entity.Version.Value; + dataContract.Oid = entity.Oid.Value; + dataContract.Text = entity.Text; + dataContract.Name = entity.Name; + dataContract.IsOnlyForEmployee = entity.IsOnlyForEmployee; + dataContract.ActivationType = entity.IsActive; + + if (entity.Employee != null) + dataContract.Employee = MapperFactory.CompactEmployeeDC_Employee.MapToNewDC(entity.Employee); + + return dataContract; + } + + public override AiPromptbaustein MergeWithEntity(AiPromptbausteinDC dataContract, AiPromptbaustein entity) + { + ConcurrencyCheck(dataContract.Version, entity); + + entity.Position = dataContract.Position; + entity.Oid = dataContract.Oid; + entity.Text = dataContract.Text; + entity.Name = dataContract.Name; + entity.IsOnlyForEmployee = dataContract.IsOnlyForEmployee; + entity.IsActive = dataContract.ActivationType; + + if (dataContract.Employee != null) + { + entity.Employee = DAOFactory.GenericDAO.LoadByID(dataContract.Employee.EmployeeOid); + } + + return entity; + } + + protected override bool AreDCAndEntityEqual(AiPromptbausteinDC dc, AiPromptbaustein entity) + { + return dc.Oid == entity.Oid; + } + } +} diff --git a/Service/DCEntityMapper/MapperFactory.cs b/Service/DCEntityMapper/MapperFactory.cs index 44f7e7199..c21adf31f 100644 --- a/Service/DCEntityMapper/MapperFactory.cs +++ b/Service/DCEntityMapper/MapperFactory.cs @@ -263,6 +263,8 @@ namespace BeWo.Service.DCEntityMapper private static TextbausteinDC_Textbaustein _TextbausteinDC_Textbaustein; + private static AiPromptbausteinDC_AiPromptbaustein _AiPromptbausteinDC_AiPromptbaustein; + private static BargeldtransaktionDC_Bargeldtransaktion _BargeldtransaktionDC_Bargeldtransaktion; private static BargeldkassenDC_Bargeldkasse _bargeldkassenDCBargeldkasseDCBargeldkassenDCBargeldkasse; @@ -357,6 +359,9 @@ namespace BeWo.Service.DCEntityMapper public static TextbausteinDC_Textbaustein TextbausteinDC_Textbaustein => _TextbausteinDC_Textbaustein ?? (_TextbausteinDC_Textbaustein = new TextbausteinDC_Textbaustein()); + public static AiPromptbausteinDC_AiPromptbaustein AiPromptbausteinDC_AiPromptbaustein => + _AiPromptbausteinDC_AiPromptbaustein ?? (_AiPromptbausteinDC_AiPromptbaustein = new AiPromptbausteinDC_AiPromptbaustein()); + public static DepotRhythmusDC_DepotRhythmus DepotRhythmusDC_DepotRhythmus => _DepotRhythmusDC_DepotRhythmus ?? (_DepotRhythmusDC_DepotRhythmus = new DepotRhythmusDC_DepotRhythmus()); diff --git a/Service/Service.csproj b/Service/Service.csproj index bb1fdf534..930bb5f78 100644 --- a/Service/Service.csproj +++ b/Service/Service.csproj @@ -340,6 +340,7 @@ + diff --git a/Service/ServiceContracts/IOperationsService.cs b/Service/ServiceContracts/IOperationsService.cs index 730195d86..cf39252c7 100644 --- a/Service/ServiceContracts/IOperationsService.cs +++ b/Service/ServiceContracts/IOperationsService.cs @@ -555,7 +555,31 @@ namespace BeWo.Service.ServiceContracts [OperationContract] IList GetTextModulesByServiceCategory(long pServiceCategoryOid); - [FaultContract(typeof(BeWoFault))] + [FaultContract(typeof(BeWoFault))] + [OperationContract] + IList GetAllAiPromptbausteine(); + + [FaultContract(typeof(BeWoFault))] + [OperationContract] + IList GetAiPromptbausteine(bool shouldShowAllAiPromptbausteine, long employeeOid, bool hasRightToSeeAllAiPromptbausteine, bool isInAdministrationView); + + [FaultContract(typeof(BeWoFault))] + [OperationContract] + IList GetAiPromptbausteineForSelectedSupportConcept(bool shouldShowAllAiPromptbausteine, long employeeOid, bool hasRightToSeeAllAiPromptbausteine, bool isInAdministrationView, long? cb2scOid); + + [FaultContract(typeof(BeWoFault))] + [OperationContract] + IList InsertNewAiPromptbausteine(IEnumerable aiPromptbausteine); + + [FaultContract(typeof(BeWoFault))] + [OperationContract] + void UpdateAiPromptbausteine(List aiPrompotBausteine); + + [FaultContract(typeof(BeWoFault))] + [OperationContract] + void DeleteAiPromptbausteine(Dictionary oid2Version); + + [FaultContract(typeof(BeWoFault))] [OperationContract] IList FindServiceRecordsInSpan(long pCostBearer2SupportConceptOid, DateTimeSpan period); diff --git a/Service/ServiceImplementations/OperationsServiceImp.cs b/Service/ServiceImplementations/OperationsServiceImp.cs index 8659bea39..7f26f5b9d 100644 --- a/Service/ServiceImplementations/OperationsServiceImp.cs +++ b/Service/ServiceImplementations/OperationsServiceImp.cs @@ -418,7 +418,7 @@ namespace BeWo.Service.ServiceImplementations .Select(i => GenerateInitialSettlementDCForPeriod(i.CostBearerOids2CostBearerRelOids[pCostBearer], periodStart, periodEnd)) .ToList(); } - + public Settlement2DC GenerateDifferenzSettlementDC(long pCostBearer2SupportConceptOid) { try @@ -3524,6 +3524,122 @@ namespace BeWo.Service.ServiceImplementations modulesToDelete.Add(textModule); } + public IList GetAllAiPromptbausteine() + { + try + { + var allAiPromptbausteine = DAOFactory.GenericDAO.GetAll(); + + return null; // MapperFactory.AiPromptbausteinDC_AiPromptbaustein.CreateDcList(allAiPromptbausteine); + } + catch (Exception e) + { + throw Utils.CreateBeWoFaultException(e); + } + } + + public IList GetAiPromptbausteineForSelectedSupportConcept(bool shouldShowAllAiPromptbausteine, long employeeOid, bool hasRightToSeeAllAiPromptbausteine, bool isInAdministrationView, long? cb2scOid) + { + try + { + var s = PluginLoader.FindClass(); + + return null; // s.GetAiPromptbausteineForSelectedSupportConcept(shouldShowAllAiPromptbausteine, employeeOid, hasRightToSeeAllAiPromptbausteine, isInAdministrationView, cb2scOid); + } + catch (Exception e) + { + throw Utils.CreateBeWoFaultException(e); + } + } + + + public IList GetAiPromptbausteine(bool shouldShowAllAiPromptbausteine, long employeeOid, bool hasRightToSeeAllAiPromptbausteine, bool isInAdministrationView) + { + try + { + var s = PluginLoader.FindClass(); + + return null; // s.GetAiPromptbausteine(shouldShowAllAiPromptbausteine, employeeOid, hasRightToSeeAllAiPromptbausteine, isInAdministrationView); + } + catch (Exception e) + { + throw Utils.CreateBeWoFaultException(e); + } + } + + public IList InsertNewAiPromptbausteine(IEnumerable aiPromptbausteinDCs) + { + try + { + var aiPromptbausteine = MapperFactory.AiPromptbausteinDC_AiPromptbaustein.MapToNewEntities(aiPromptbausteinDCs); + + foreach (var tm in aiPromptbausteine) + { + tm.IsActive = ActivationTypeId.Active; + } + DAOFactory.GenericDAO.Insert(aiPromptbausteine); + + return aiPromptbausteine.Select(asb => asb.Oid.Value).ToList(); + } + catch (Exception e) + { + throw Utils.CreateBeWoFaultException(e); + } + } + + public void UpdateAiPromptbausteine(List pTextbausteine) + { + try + { + var lOriginals = DAOFactory.GenericDAO.LoadByIDs(pTextbausteine.Select(sc => sc.Oid.Value)); + foreach (var item in pTextbausteine) + { + item.ActivationType = ActivationTypeId.Active; + } + MapperFactory.AiPromptbausteinDC_AiPromptbaustein.MergeWithEntitys(pTextbausteine, lOriginals); + + DAOFactory.GenericDAO.Update(lOriginals); + } + catch (Exception e) + { + throw Utils.CreateBeWoFaultException(e); + } + } + + public void DeleteAiPromptbausteine(Dictionary pOid2Version) + { + try + { + var lOriginals = DAOFactory.GenericDAO.LoadByIDs(pOid2Version.Select(e => e.Key)); + lOriginals.DoForEach(or => MapperFactory.AiPromptbausteinDC_AiPromptbaustein.ConcurrencyCheck(pOid2Version[or.Oid.Value], or)); + + IList modulesToDelete = new List(); + + foreach (var aiPromptbaustein in lOriginals) + { + AddAiPromptbausteinAndChildsToList(aiPromptbaustein, modulesToDelete); + } + + DAOFactory.GenericDAO.Delete(modulesToDelete); + } + catch (Exception e) + { + throw Utils.CreateBeWoFaultException(e); + } + } + + private void AddAiPromptbausteinAndChildsToList(AiPromptbaustein aiPromptbaustein, IList aiPromptbausteineToDelete) + { + var children = DAOFactory.SearchDAO.GetChildAiPromptbausteine(aiPromptbaustein); + + foreach (var child in children) + { + AddAiPromptbausteinAndChildsToList(child, aiPromptbausteineToDelete); + } + + aiPromptbausteineToDelete.Add(aiPromptbaustein); + } + public IList FindServiceRecordsInSpan(long pCostBearer2SupportConceptOid, DateTimeSpan period) { try @@ -9030,5 +9146,25 @@ namespace BeWo.Service.ServiceImplementations throw Utils.CreateBeWoFaultException(e); } } + + IList IOperationsService.GetAiPromptbausteine(bool shouldShowAllAiPromptbausteine, long employeeOid, bool hasRightToSeeAllAiPromptbausteine, bool isInAdministrationView) + { + throw new NotImplementedException(); + } + + IList IOperationsService.GetAiPromptbausteineForSelectedSupportConcept(bool shouldShowAllAiPromptbausteine, long employeeOid, bool hasRightToSeeAllAiPromptbausteine, bool isInAdministrationView, long? cb2scOid) + { + throw new NotImplementedException(); + } + + IList IOperationsService.InsertNewAiPromptbausteine(IEnumerable aiPromptbausteine) + { + throw new NotImplementedException(); + } + + void IOperationsService.UpdateAiPromptbausteine(List aiPrompotBausteine) + { + throw new NotImplementedException(); + } } } diff --git a/Shared/BeWoEntityEnums.cs b/Shared/BeWoEntityEnums.cs index 91a4f9feb..ffbab26c6 100644 --- a/Shared/BeWoEntityEnums.cs +++ b/Shared/BeWoEntityEnums.cs @@ -189,7 +189,8 @@ namespace BS.Shared AiModel = 179, AiConversationMessage = 180, AiContext2BeWoObject = 181, - AiConfig = 182 + AiConfig = 182, + AiPromptbaustein = 183 } public enum SystemEntryID diff --git a/Shared/DataContracts/AiPromptbausteinDC.cs b/Shared/DataContracts/AiPromptbausteinDC.cs new file mode 100644 index 000000000..29f2daf4f --- /dev/null +++ b/Shared/DataContracts/AiPromptbausteinDC.cs @@ -0,0 +1,43 @@ +using System.Runtime.Serialization; + +using BS.Shared.DataContracts.Compact; + +namespace BS.Shared.DataContracts +{ + [DataContract] + public partial class AiPromptbausteinDC : IDataContract + { + [DataMember] + public ActivationTypeId ActivationType { get; set; } + + [DataMember] + public long? Oid { get; set; } + + [DataMember] + public long? Version { get; set; } + + [DataMember] + public string Text { get; set; } + + [DataMember] + public int Position { get; set; } + + [DataMember] + public string Name { get; set; } + + [DataMember] + public CompactEmployeeDC Employee { get; set; } + + [DataMember] + public bool IsOnlyForEmployee { get; set; } + + [DataMember] + public bool IsParent { get; set; } + + [DataMember] + public AiPromptbausteinDC Parent { get; set; } + + [DataMember] + public bool IsExpanded { get; set; } + } +} diff --git a/Shared/Shared.csproj b/Shared/Shared.csproj index 997612400..aa83bd9a5 100644 --- a/Shared/Shared.csproj +++ b/Shared/Shared.csproj @@ -321,6 +321,7 @@ +