From 6b48aef90b358114b556cea1dc887ae4111c75f8 Mon Sep 17 00:00:00 2001 From: Lyndon Date: Wed, 5 Nov 2025 10:40:48 +0100 Subject: [PATCH] =?UTF-8?q?Warnung=20bei=20Zielpflicht,=20wenn=20keins=20a?= =?UTF-8?q?usgew=C3=A4hlt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BeWoPlanerMobil/Controllers/MainController.cs | 8 ++++ BeWoPlanerMobil/Models/AbstractModel.cs | 2 +- .../utils/service-record-time-calc.js | 20 ++++++--- .../ownSoft-Scripts/view-scripts/main.js | 39 ++++++++++------ .../Views/Main/GoalTreePartial.cshtml | 24 +++++++++- BeWoPlanerMobil/Views/Main/Main.cshtml | 6 ++- .../RestoreServiceRecordInputsPartial.cshtml | 45 ++++++++++++------- BeWoPlanerMobil/Views/Shared/_Layout.cshtml | 2 +- Service/Plugins/PluginLoader.cs | 2 +- 9 files changed, 107 insertions(+), 41 deletions(-) diff --git a/BeWoPlanerMobil/Controllers/MainController.cs b/BeWoPlanerMobil/Controllers/MainController.cs index bc0ae5458..10ff8a8d4 100644 --- a/BeWoPlanerMobil/Controllers/MainController.cs +++ b/BeWoPlanerMobil/Controllers/MainController.cs @@ -17,6 +17,7 @@ using DevExpress.XtraScheduler.Compatibility; using Newtonsoft.Json; using System; using System.Collections.Generic; +using System.Diagnostics; using System.Drawing; using System.Linq; using System.Net; @@ -344,6 +345,8 @@ namespace BeWoPlanerMobil.Controllers Model.IsServiceRecordNoticeMandatory = settingsValue is null || !settingsValue.Equals("0"); + Model.IsServiceRecordGoalMandatory = UserSettingsUtils.GetSettingValueAsBool(Model.Mandator.Settings, SettingsKeys.IsServiceRecordGoalMandatory); + //User Settings var user = LoggedInUser; var userSettings = user?.Settings.FirstOrDefault(f => f.Type.Equals(SettingsType.ApplicationSettings))?.Value; @@ -2985,6 +2988,8 @@ namespace BeWoPlanerMobil.Controllers break; } + Debug.WriteLine($"---->ValidationResult: {vr.ResultType}"); + switch(vr.ResultType) { case ServiceRecordOverlapping: @@ -3093,6 +3098,9 @@ namespace BeWoPlanerMobil.Controllers exitLoop = false; newResult.KannTrotzdemGespeichertWerden = true; break; + default: + Debug.WriteLine($"---->ValidationResult: {vr.ResultType}"); + break; } } } diff --git a/BeWoPlanerMobil/Models/AbstractModel.cs b/BeWoPlanerMobil/Models/AbstractModel.cs index 9ed527393..af362507d 100644 --- a/BeWoPlanerMobil/Models/AbstractModel.cs +++ b/BeWoPlanerMobil/Models/AbstractModel.cs @@ -268,6 +268,6 @@ namespace BeWoPlanerMobil.Models public bool ShowBetrag { get; set; } - + public bool IsServiceRecordGoalMandatory { get; set; } } } \ No newline at end of file diff --git a/BeWoPlanerMobil/Scripts/ownSoft-Scripts/utils/service-record-time-calc.js b/BeWoPlanerMobil/Scripts/ownSoft-Scripts/utils/service-record-time-calc.js index bc91b72fd..54ac54b28 100644 --- a/BeWoPlanerMobil/Scripts/ownSoft-Scripts/utils/service-record-time-calc.js +++ b/BeWoPlanerMobil/Scripts/ownSoft-Scripts/utils/service-record-time-calc.js @@ -32,12 +32,19 @@ let start = new Date(startDateValue); let end = hasEndDate ? new Date(endDateValue) : start; + // Von und Bis haben gültige Werte und es wurde nicht durch den Dauereinheitsbutton ausgelöst if(true === isStartTimeValid && true === isEndTimeValid && false === isFormatChange) { start = combineDateAndTime(start, startTimeValue); end = combineDateAndTime(end, endTimeValue); let dauer = (end.getTime() - start.getTime()) / 60000; + // Trägt man einen Termin ein, der + if(dauer < 0) { + end.setDate(end.getDate() + 1); + dauer = (end.getTime() - start.getTime()) / 60000; + } + if(duration > 0 && start >= end) { dauer = (false === isInMin ? duration * 60 : duration); @@ -130,6 +137,8 @@ function formatDuration(isInMin, durationAsNumber) { function calcTimeWithDuration(timeAsString, timeElement, start, duration, isFormatChange, isInMin) { start = combineDateAndTime(start, timeAsString); + logInfo3(`calcTimeWithDuration(timeAsString: ${timeAsString}, timeElement: ${timeElement}, start: ${start}, duration: ${duration}, isFormatChange: ${isFormatChange}, isInMin: ${isInMin})`); + const x = new Date(start.getTime() + duration * 60000); const timeString = `${x.getHours().toString().padStart(2, "0")}:${x.getMinutes().toString().padStart(2, "0")}`; timeElement.val(timeString); @@ -137,7 +146,6 @@ function calcTimeWithDuration(timeAsString, timeElement, start, duration, isForm } function beiDaueraenderung(idPrefix) { - logInfo2(`${idPrefix}-Dauer geändert`); const hoursMinutesDropdown = $(`#${idPrefix}-hours-minutes-dropdown-btn`); const startTimeInput = $(`#${idPrefix}-start-time-input`); @@ -151,8 +159,8 @@ function beiDaueraenderung(idPrefix) { const isInMin = (false === hasMinutesHoursDropdown && false === durationLabel.text().includes("(h)")) || hasMinutesHoursDropdown === true && hoursMinutesBtn.text().replaceAll(/\s/g, "") === "Minuten"; - const startTimeCondition = startTimeInput.val().length > 0; - const endTimeCondition = endTimeInput.val().length > 0; + const isStartTimeValid = startTimeInput.val().length > 0; + const isEndTimeValid = endTimeInput.val().length > 0; var dauerString = durationInput.val(); @@ -163,9 +171,9 @@ function beiDaueraenderung(idPrefix) { let duration = parseFloat(dauerString.replace(",", ".")); - const durationCondition = false === isNaN(duration); + const isDurationValid = false === isNaN(duration); - if((false === startTimeCondition && false === endTimeCondition) || false === durationCondition) { + if((false === isStartTimeValid && false === isEndTimeValid) || false === isDurationValid) { return; } @@ -185,7 +193,7 @@ function beiDaueraenderung(idPrefix) { end = new Date(endDateInput.val()); } - if(true === startTimeCondition) { + if(true === isStartTimeValid) { const startDateAndTimeCombined = combineDateAndTime(start, startTimeInput.val()); end = new Date(startDateAndTimeCombined.getTime() + duration * 60000); diff --git a/BeWoPlanerMobil/Scripts/ownSoft-Scripts/view-scripts/main.js b/BeWoPlanerMobil/Scripts/ownSoft-Scripts/view-scripts/main.js index c9c476b47..504689a15 100644 --- a/BeWoPlanerMobil/Scripts/ownSoft-Scripts/view-scripts/main.js +++ b/BeWoPlanerMobil/Scripts/ownSoft-Scripts/view-scripts/main.js @@ -196,12 +196,29 @@ function validateForm(form, prefix) { prefix = ""; } - var errorMessage = ""; - var isNoticeMandatory = window.getIsDocumentationMandatory(); - var numberOfNoticeTextareas = window.getNumberOfDokutypes(); + let errorMessage = ""; + const isNoticeMandatory = window.getIsDocumentationMandatory(); + const isServiceRecordGoalMandatory = window.getIsServiceRecordGoalMandatory(); + const numberOfNoticeTextareas = window.getNumberOfDokutypes(); var isValid = true; - + + if(isServiceRecordGoalMandatory) { + const selectedGoalOids = window.getCheckedGoalsAsArray(); + + if(selectedGoalOids.length === 0) { + hideSpinner(); + + showAlertMessageBox("Fehler", + "Sie müssen mindestens ein Ziel auswählen, bevor Sie speichern können.", + function() { + $("#messagePopup .modal-body").html(); + }, + true); + return; + } + } + if(isNoticeMandatory) { if(numberOfNoticeTextareas === 0) { var doku = $(`#${prefix}-doku-textarea-5`).val(); @@ -255,10 +272,8 @@ function validateForm(form, prefix) { if(startAndEndDates !== null && isValid) { var [start, end] = startAndEndDates; - if(end.getTime() < start.getTime()) { - showAlertMessageBox("Fehler", "Der Start muss vor dem Ende liegen!", null, false); - hideSpinner(); - return; + if(end.getTime() < start.getTime() || end.getTime() === start.getTime()) { + end.setDate(end.getDate() + 1); } var [doku1, doku2, doku3, doku4, doku5] = getDokuTexte(prefix); @@ -384,16 +399,12 @@ function getStartAndEndDate(prefix) { const endDateInput = $(`#${prefix}-end-date-input`); const startTimeInput = $(`#${prefix}-start-time-input`); const endTimeInput = $(`#${prefix}-end-time-input`); - logInfo(`Prefix: ${prefix}`); + return validateStartAndEndInputs(startDateInput, startTimeInput, endDateInput, endTimeInput, true); } function validateStartAndEndInputs(startDateInput, startTimeInput, endDateInput, endTimeInput, isServiceRecord) { - if(isServiceRecord === undefined || isServiceRecord === null) { - isServiceRecord = false; - } - - logInfo2(`Startdatum: ${startDateInput.prop("id")}`); + isServiceRecord = isServiceRecord ?? false; const startDate = new Date(startDateInput.val()); const startTime = startTimeInput.val(); diff --git a/BeWoPlanerMobil/Views/Main/GoalTreePartial.cshtml b/BeWoPlanerMobil/Views/Main/GoalTreePartial.cshtml index 38a189599..e74fdf29b 100644 --- a/BeWoPlanerMobil/Views/Main/GoalTreePartial.cshtml +++ b/BeWoPlanerMobil/Views/Main/GoalTreePartial.cshtml @@ -72,7 +72,7 @@ try { const rootElement = $("#goals-tree"); const checkboxes = rootElement.find("input"); - + var selectedGoals = ""; $.each(checkboxes, function(index, checkbox) { @@ -93,6 +93,28 @@ } } + function getCheckedGoalsAsArray() { + try { + const rootElement = $("#goals-tree"); + const checkboxes = rootElement.find("input"); + const oids = []; + + $.each(checkboxes, function(index, checkbox) { + const box = $(checkbox); + const id = box.attr("id").split("-")[2]; + + if(box.prop("checked") === true && !id.includes("goal")) { + oids.push(id); + } + }); + + return oids; + } catch(error) { + showErrorPopup(error); + return null; + } + } + function updateSelectedGoals() { try { const selectedGoals = getCheckedGoals(); diff --git a/BeWoPlanerMobil/Views/Main/Main.cshtml b/BeWoPlanerMobil/Views/Main/Main.cshtml index 6e2ce4270..fad3b8207 100644 --- a/BeWoPlanerMobil/Views/Main/Main.cshtml +++ b/BeWoPlanerMobil/Views/Main/Main.cshtml @@ -281,7 +281,11 @@ } function getIsDocumentationMandatory() { - return @(Model != null && Model.IsServiceRecordNoticeMandatory ? "true" : "false"); + return @(Model is { IsServiceRecordNoticeMandatory: true } ? "true" : "false"); + } + + function getIsServiceRecordGoalMandatory() { + return @(Model is { IsServiceRecordGoalMandatory: true } ? "true" : "false"); } function getSelectedGoalOids() { diff --git a/BeWoPlanerMobil/Views/Main/RestoreServiceRecordInputsPartial.cshtml b/BeWoPlanerMobil/Views/Main/RestoreServiceRecordInputsPartial.cshtml index f196293ff..817b441c5 100644 --- a/BeWoPlanerMobil/Views/Main/RestoreServiceRecordInputsPartial.cshtml +++ b/BeWoPlanerMobil/Views/Main/RestoreServiceRecordInputsPartial.cshtml @@ -20,7 +20,7 @@ const categoryOid = $("#sb-category-select option:selected").val(); const descriptionOid = $("#sb-leistung-select option:selected").val(); - updateCbScRelOids("sb", cb2ScRelOid); + updateCbScRelOids("sb", cb2ScRelOid); updateEmployeeOids("sb", eOid); updateCategory("sb", categoryOid); updateServiceDescription("sb", descriptionOid); @@ -150,7 +150,7 @@ function updateCbScRelOids(prefix, csv) { if(csv === null || csv === undefined || csv.length === 0) { - logInfo2(`csv ist leer: ${csv}; Entferne @MobileSessionFacade.LocalStorageKey-${firstCharToUpperCase(prefix)}Cb2ScRelOid${(prefix === "sb" ? "" : "s")}`); + logInfo2(`csv ist leer: ${csv}; Entferne @MobileSessionFacade.LocalStorageKey-${firstCharToUpperCase(prefix)}Cb2ScRelOid${(prefix === "sb" ? "" : "s")}`); localStorage.removeItem(`@MobileSessionFacade.LocalStorageKey-${firstCharToUpperCase(prefix)}Cb2ScRelOid${(prefix === "sb" ? "" : "s")}`); return; } @@ -233,12 +233,12 @@ function clearLocalBeWoStorage(prefix) { - const keyArray = []; + const keyArray = []; for(let i = 0; i < localStorage.length; i++) { const key = localStorage.key(i); - if(key.startsWith(`@MobileSessionFacade.LocalStorageKey-${firstCharToUpperCase(prefix)}`)) { + if(key.startsWith(`@MobileSessionFacade.LocalStorageKey-${firstCharToUpperCase(prefix)}`)) { keyArray.push(key); } } @@ -391,16 +391,14 @@ function readWholeLocalStorage() { logInfo3(`Es wurden ${localStorage.length} lokale gespeicherte Werte gefunden:`); - for(let i = 0; i < localStorage.length; i++) { - const key = localStorage.key(i); + for(let i = 0; i < localStorage.length; i++) { + const key = localStorage.key(i); logInfo3(`${key}: ${localStorage.getItem(key)}`); - } - } + } + } -@* ToDo: Sofern die Option gewählt wurde, muss der Von-Wert nach dem Speichern auf den gespeicherten Bis-Wert gesetzt werden! *@ - @using(Html.BeginForm("RestoreServiceRecordForm", "Main", FormMethod.Post, new { id = "restore-service-record-form" })) { @@ -447,12 +445,27 @@ if(Html.IsInDebugMode()) { - - +
+ + + + +
+ } } diff --git a/BeWoPlanerMobil/Views/Shared/_Layout.cshtml b/BeWoPlanerMobil/Views/Shared/_Layout.cshtml index 299292175..71bcdd7d4 100644 --- a/BeWoPlanerMobil/Views/Shared/_Layout.cshtml +++ b/BeWoPlanerMobil/Views/Shared/_Layout.cshtml @@ -55,7 +55,7 @@ - + diff --git a/Service/Plugins/PluginLoader.cs b/Service/Plugins/PluginLoader.cs index cadb90e0d..05cfb1283 100644 --- a/Service/Plugins/PluginLoader.cs +++ b/Service/Plugins/PluginLoader.cs @@ -407,7 +407,7 @@ namespace BeWo.Service.Plugins //t = "6203102637"; // BeWo Neuss-Lauth u. Lauth GbR //t = "7060431533"; // Arche Tecklenburg e.V. //t = "1159580198"; // Wendepunkt Velbert gGmbH - t = "5094575560"; // Christopherus Haus MID + //t = "5094575560"; // Christopherus Haus MID //t = "5261046426"; // SelbstWerk EN / Bettina Heckrodt //t = "6652893693"; // Claudia Heizmann //t = "5850903700"; // Alzey (Verein für Integration und Teilhabe am Leben e.V.)