diff --git a/BeWoPlanerMobil/BeWoPlanerMobil.csproj b/BeWoPlanerMobil/BeWoPlanerMobil.csproj index 5c7de565b..19c62cd72 100644 --- a/BeWoPlanerMobil/BeWoPlanerMobil.csproj +++ b/BeWoPlanerMobil/BeWoPlanerMobil.csproj @@ -186,7 +186,8 @@ ..\packages\EntityFramework.6.5.1\lib\net45\EntityFramework.SqlServer.dll - ..\packages\log4net.3.1.0\lib\net462\log4net.dll + False + ..\Lib\log4net.dll ..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.4.1.0\lib\net472\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll @@ -237,7 +238,7 @@ ..\packages\System.Numerics.Vectors.4.6.1\lib\net462\System.Numerics.Vectors.dll - + False ..\Lib\System.Runtime.CompilerServices.Unsafe.dll diff --git a/BeWoPlanerMobil/Content/images/Icon_KI_Funktion_Weiss+Gruen.png b/BeWoPlanerMobil/Content/images/Icon_KI_Funktion_Weiss+Gruen.png new file mode 100644 index 000000000..597cdace2 Binary files /dev/null and b/BeWoPlanerMobil/Content/images/Icon_KI_Funktion_Weiss+Gruen.png differ diff --git a/BeWoPlanerMobil/Content/images/Icon_KI_Funktion_Weiss.png b/BeWoPlanerMobil/Content/images/Icon_KI_Funktion_Weiss.png new file mode 100644 index 000000000..fce0f9288 Binary files /dev/null and b/BeWoPlanerMobil/Content/images/Icon_KI_Funktion_Weiss.png differ diff --git a/BeWoPlanerMobil/Controllers/AbstractBaseController.cs b/BeWoPlanerMobil/Controllers/AbstractBaseController.cs index 83b106271..a7113251d 100644 --- a/BeWoPlanerMobil/Controllers/AbstractBaseController.cs +++ b/BeWoPlanerMobil/Controllers/AbstractBaseController.cs @@ -1,23 +1,24 @@ -using System; -using System.Diagnostics; -using System.Web.Mvc; -using System.Web.Security; -using BeWo.Data.Access; +using BeWo.Data.Access; using BeWo.Data.Entities; using BeWo.Service.DCEntityMapper; using BeWo.Service.ServiceContracts; +using BeWo.Service.ServiceContracts.Enhanced; using BeWoPlanerMobil.Models; using BeWoPlanerMobil.Service; using BS.Shared; using BS.Shared.Core; using BS.Shared.DataContracts; using ReportingService.ServiceContracts; +using System; +using System.Diagnostics; +using System.Web.Mvc; +using System.Web.Security; namespace BeWoPlanerMobil.Controllers { public abstract class AbstractBaseController : Controller - { - protected readonly ICustomerService CustomerService = new MobileSessionFacade().CustomerService; + { + protected readonly ICustomerService CustomerService = new MobileSessionFacade().CustomerService; protected readonly IOperationsService OperationsService = new MobileSessionFacade().OperationsService; protected readonly IEmployeeService EmployeeService = new MobileSessionFacade().EmployeeService; protected readonly IValueListService ValueListService = new MobileSessionFacade().ValueListService; @@ -26,7 +27,8 @@ namespace BeWoPlanerMobil.Controllers protected readonly IDownloadService DownloadService = new MobileSessionFacade().DownloadService; protected readonly IReportService ReportService = new MobileSessionFacade().ReportService; protected readonly IQueryService QueryService = new MobileSessionFacade().QueryService; - + protected readonly IAiEnhancedService AiService = new MobileSessionFacade().AiService; + protected const string LeerzeichenFuerGetMethoden = " "; protected static readonly log4net.ILog Log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); diff --git a/BeWoPlanerMobil/Controllers/MainController.cs b/BeWoPlanerMobil/Controllers/MainController.cs index 303bbeb93..c0de2bbf8 100644 --- a/BeWoPlanerMobil/Controllers/MainController.cs +++ b/BeWoPlanerMobil/Controllers/MainController.cs @@ -11,6 +11,7 @@ using BS.Shared; using BS.Shared.Core; using BS.Shared.DataContracts; using BS.Shared.DataContracts.Compact; +using BS.Shared.DataContracts.Feature.AI; using BS.Shared.Extensions; using BS.Shared.Services; using DevExpress.Utils.Extensions; @@ -316,8 +317,163 @@ namespace BeWoPlanerMobil.Controllers } } + [HttpGet] + [Authorize] + public ActionResult GetAiPromptbausteinFolder() + { + try + { + var folders = AiService.GetAiPromptbausteinFolder(AiActionType.ServiceRecordDocumentation).ToList(); + AddFavoriten(folders); + var projected = ProjectAiFolders(folders); + + return new JsonResult + { + Data = projected, + JsonRequestBehavior = JsonRequestBehavior.AllowGet, + MaxJsonLength = int.MaxValue + }; + } + catch (Exception ex) + { + Response.StatusCode = 500; + Response.TrySkipIisCustomErrors = true; + return Json(new + { + error = ex.GetType().Name, + message = ex.Message, + inner = ex.InnerException?.Message, + stack = ex.StackTrace + }, JsonRequestBehavior.AllowGet); + } + } + + [HttpPost] + [Authorize] + public ActionResult StartPrompt(long promptOid) + { + try + { + var conv = new AiConversationDC + { + Created = DateTime.Now, + Updated = DateTime.Now, + ActionType = AiActionType.ServiceRecordDocumentation + }; + + AiViewContextDC viewContext = CreateViewContext(); + + conv = AiService.CreateAiConversation(conv, viewContext); + + var messages = AiService.ExecuteAiConversationWithPrompt(conv.Oid.Value, viewContext, promptOid); + + // Die generierte Dokumentation ist die letzte Assistent-Nachricht. + var resultMessage = (messages ?? new AiConversationMessageDC[0]) + .LastOrDefault(m => m.Role == AiConversationMessageRole.Assistent) + ?? (messages ?? new AiConversationMessageDC[0]).LastOrDefault(); + + return Json(new + { + success = true, + text = resultMessage?.Message ?? string.Empty + }); + } + catch (Exception ex) + { + Log.Error("StartPrompt fehlgeschlagen", ex); + Response.StatusCode = 500; + Response.TrySkipIisCustomErrors = true; + return Json(new + { + success = false, + error = ex.GetType().Name, + message = ex.Message, + inner = ex.InnerException?.Message + }); + } + } + + /// + /// Baut den AI-Kontext für die aktuell bearbeitete Einzelbuchung auf: + /// Primary = ausgewähltes Betreuungskonzept, Secondary = aktueller Dokumentationstext. + /// + private AiViewContextDC CreateViewContext() + { + return new AiViewContextDC + { + Primary = Model.SelectedSupportConceptOid, + Secondary = Model.NoticeToEdit + }; + } + + private void AddFavoriten(List folders) + { + var favoriten = new AiPromptbausteinFolderDC() + { + Oid = -5, + Title = "Favoriten", + Description = "Eigene Favoriten", + SubPrompts = new List() + }; + + AddFavoritenPrompts(folders, favoriten); + + folders.Insert(0, favoriten); + + } + + private void AddFavoritenPrompts(List folders, AiPromptbausteinFolderDC favoriten) + { + foreach (var folder in folders) + { + + if (folder.SubFolders?.Any() ?? false) + AddFavoritenPrompts(folder.SubFolders, favoriten); + + foreach (var prompt in folder.SubPrompts) + { + if (prompt.IsFavorite) + favoriten.SubPrompts.Add(prompt); + } + + //foreach (var routine in folder.SubRoutines.VMList) + //{ + // if (routine.IsFavorite) + // favoriten.SubRoutines.VMList.Add(routine); + //} + } + } + + /// + /// Projiziert die AiPromptbausteinFolderDC-Baumstruktur auf ein schlankes, + /// zirkelbezugsfreies Objekt für die JSON-Serialisierung an das UI. + /// + private List ProjectAiFolders(List folders) + { + if (folders == null) + { + return new List(); + } + + return folders.Select(f => (object)new + { + f.Title, + f.Description, + SubFolders = ProjectAiFolders(f.SubFolders), + SubPrompts = (f.SubPrompts ?? new List()) + .Select(p => new + { + p.Oid, + p.Title, + p.Description, + p.Prompt + }).ToList() + }).ToList(); + } + private void InitSettings() { + //Mandator Settings Model.ShowBetrag = UserSettingsUtils.GetSettingValueAsBool(Model.Mandator.Settings, SettingsKeys.ShowBetrag); Model.ShowMarker = UserSettingsUtils.GetSettingValueAsBool(Model.Mandator.Settings, SettingsKeys.ShowMarker); diff --git a/BeWoPlanerMobil/Models/AbstractModel.cs b/BeWoPlanerMobil/Models/AbstractModel.cs index 519a69624..941e2d2e8 100644 --- a/BeWoPlanerMobil/Models/AbstractModel.cs +++ b/BeWoPlanerMobil/Models/AbstractModel.cs @@ -60,6 +60,8 @@ namespace BeWoPlanerMobil.Models public bool HasRightToInsertRessourceAppointments => CheckRight(UserRightType.KalenderRessourcentermineAnlegen) || CheckRight(UserRightType.CreateAll); + public bool HasRightToSeeAiPromptsInZeiterfassung => CheckRight(UserRightType.AiModulePromptbausteineView) && CheckRight(UserRightType.AiModuleServiceRecordDocu); + public bool HasRightToUseAiVoice { get diff --git a/BeWoPlanerMobil/Service/MobileSessionFacade.cs b/BeWoPlanerMobil/Service/MobileSessionFacade.cs index 50ff3d2c9..cd27e8d2a 100644 --- a/BeWoPlanerMobil/Service/MobileSessionFacade.cs +++ b/BeWoPlanerMobil/Service/MobileSessionFacade.cs @@ -1,9 +1,11 @@ -using System.Web; -using BeWo.Service.ServiceContracts; +using BeWo.Service.ServiceContracts; +using BeWo.Service.ServiceContracts.Enhanced; using BeWo.Service.ServiceImplementations; +using BeWo.Service.ServiceImplementations.Enhanced; using BeWoPlanerMobil.Models; using ReportingService.ServiceContracts; using ReportingService.ServiceImplementations; +using System.Web; namespace BeWoPlanerMobil.Service { @@ -21,6 +23,7 @@ namespace BeWoPlanerMobil.Service DownloadService = new DownloadServiceImp(); ReportService = new ReportServiceImp(); QueryService = new QueryServiceImp(); + AiService = new AiEnhancedServiceImp(); } public ICustomerService CustomerService { get; } @@ -33,6 +36,7 @@ namespace BeWoPlanerMobil.Service public IDownloadService DownloadService { get; } public IReportService ReportService { get; } public IQueryService QueryService { get; } + public IAiEnhancedService AiService { get; } public static long? LoggedInUserOid { diff --git a/BeWoPlanerMobil/Web.config b/BeWoPlanerMobil/Web.config index 43f171232..35b21d985 100644 --- a/BeWoPlanerMobil/Web.config +++ b/BeWoPlanerMobil/Web.config @@ -170,6 +170,8 @@ + +