From bacc7fcedd7967bb59b239b2d80c4b0e4fdc5b8c Mon Sep 17 00:00:00 2001 From: Lyndon Date: Mon, 13 Jul 2026 20:32:28 +0200 Subject: [PATCH] =?UTF-8?q?Verhindern,=20dass=20Ressourcen=20doppelt=20geb?= =?UTF-8?q?ucht=20werden=20mit=20Recht:=20ToDoOID=3D91266751=20Serientermi?= =?UTF-8?q?ne=20k=C3=B6nnen=20gel=C3=B6scht=20werden,=20aber=20es=20fehlt?= =?UTF-8?q?=20noch=20eine=20Abfrage,=20ob=20man=20wirklich=20l=C3=B6schen?= =?UTF-8?q?=20will=20bei=20normalen=20Terminen.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ViewModel/SchedulerAppointmentListVM.cs | 24 +++++++-- .../Controllers/AbstractBaseController.cs | 3 +- .../DevExpressSchedulerController.cs | 44 +++++++++------ .../Controllers/LoginController.cs | 3 +- BeWoPlanerMobil/Models/AppointmentModel.cs | 5 ++ .../DevExpressScheduler.cshtml | 53 ++++++++++++++++++- .../DevExpressScheduler/SchedulerHelper.cs | 2 + .../SchedulerPagePartial.cshtml | 3 +- BeWoPlanerMobil/Views/Login/Index.cshtml | 2 +- Data/Access/SearchDAO.cs | 4 +- Service/Plugins/ResourceService.cs | 1 - Shared/BeWoEntityEnums.cs | 26 ++++----- 12 files changed, 126 insertions(+), 44 deletions(-) diff --git a/BeWo/Scheduler/ViewModel/SchedulerAppointmentListVM.cs b/BeWo/Scheduler/ViewModel/SchedulerAppointmentListVM.cs index ab35d0705..205498419 100644 --- a/BeWo/Scheduler/ViewModel/SchedulerAppointmentListVM.cs +++ b/BeWo/Scheduler/ViewModel/SchedulerAppointmentListVM.cs @@ -198,11 +198,18 @@ namespace BeWo.Scheduler.ViewModel var message = string.Empty; - ServiceFacade.DoResourceServiceSync( s => message = s.ValidateSchedulerAppointment(start, end, employeeOids, customerOids, resourceOids, originatorOid, schedulerAppointmentOid, recurrenceInfoId, recurrenceIndex, shouldSkipResourceAvailablityCheck)); if(!string.IsNullOrWhiteSpace(message)) { + if(message.Contains("Die Ressource") && message.Contains("ist im ausgewählten Zeitraum") && message.Contains("bereits gebucht:") && BeWoApp.LoggedOnUser.HasRight(UserRightType.KalenderRessourcenDoppeltBuchen) is false) + { + message = message.Remove(message.Length - 31) + "Speichern nicht möglich."; + + MessageBox.Show(message, "Überschneidung", MessageBoxButton.OK, MessageBoxImage.Exclamation); + return; + } + var messageBoxResult = MessageBox.Show(message, "Überschneidung", MessageBoxButton.YesNo, MessageBoxImage.Exclamation); if(messageBoxResult.Equals(MessageBoxResult.No)) @@ -212,7 +219,7 @@ namespace BeWo.Scheduler.ViewModel } } - if (item.Type.Equals(AppointmentType.ChangedOccurrence) && _GeoeffneterTermin != null) + if(item.Type.Equals(AppointmentType.ChangedOccurrence) && _GeoeffneterTermin != null) { areEqual = _GeoeffneterTermin.Equals(item); } @@ -223,7 +230,7 @@ namespace BeWo.Scheduler.ViewModel } } - if (dcList.Count <= 0) + if(dcList.Count <= 0) { return; } @@ -305,6 +312,14 @@ namespace BeWo.Scheduler.ViewModel if(!string.IsNullOrWhiteSpace(message)) { + if(message.Contains("Die Ressource") && message.Contains("ist im ausgewählten Zeitraum") && message.Contains("bereits gebucht:") && BeWoApp.LoggedOnUser.HasRight(UserRightType.KalenderRessourcenDoppeltBuchen) is false) + { + message = message.Remove(message.Length - 31) + "Speichern nicht möglich."; + + MessageBox.Show(message, "Überschneidung", MessageBoxButton.OK, MessageBoxImage.Exclamation); + return; + } + var messageBoxResult = MessageBox.Show(message, "Überschneidung", MessageBoxButton.YesNo, MessageBoxImage.Exclamation); if(messageBoxResult.Equals(MessageBoxResult.No)) @@ -314,11 +329,10 @@ namespace BeWo.Scheduler.ViewModel } } - dcList.Add(vm.CommitToDataContract()); } - if (dcList.Count <= 0) + if(dcList.Count <= 0) { return; } diff --git a/BeWoPlanerMobil/Controllers/AbstractBaseController.cs b/BeWoPlanerMobil/Controllers/AbstractBaseController.cs index a7113251d..ac8c8ed41 100644 --- a/BeWoPlanerMobil/Controllers/AbstractBaseController.cs +++ b/BeWoPlanerMobil/Controllers/AbstractBaseController.cs @@ -43,13 +43,12 @@ namespace BeWoPlanerMobil.Controllers #if DEBUG Debug.WriteLine($"+++>Logout aufrufende Methode: {new StackTrace().GetFrame(1).GetMethod().Name}"); #endif - MobileSessionFacade.LogUserOut(); FormsAuthentication.SignOut(); AbstractModel.TimeOfLastAction = null; - return RedirectToActionPermanent("Index", "Login", new {tenant = MobileSessionFacade.Tenant}); + return RedirectToActionPermanent("Index", "Login", new {tenant = MobileSessionFacade.Tenant, message = ViewData[LoginController.LoginErrorIndex]?.ToString() }); } protected virtual void InitModel(AbstractModel model) diff --git a/BeWoPlanerMobil/Controllers/DevExpressSchedulerController.cs b/BeWoPlanerMobil/Controllers/DevExpressSchedulerController.cs index e75c88efe..10b7aca38 100644 --- a/BeWoPlanerMobil/Controllers/DevExpressSchedulerController.cs +++ b/BeWoPlanerMobil/Controllers/DevExpressSchedulerController.cs @@ -489,17 +489,24 @@ namespace BeWoPlanerMobil.Controllers foreach(var appointment in appointmentsToInsert) { - appointment.CustomerList = AppointmentModel.SelectedCustomers; - appointment.ResourceList = AppointmentModel.SelectedResources; - - appointment.EmployeeList = new List(); - - foreach(var selectedEmployee in AppointmentModel.SelectedEmployees ?? new List()) + if(appointment.Type != (int) AppointmentType.DeletedOccurrence) { - appointment.EmployeeList.Add(new Employee2SchedulerAppointmentDC { Employee = selectedEmployee }); - } + // Beim Löschen eines Serientermins wird hier ein Insert für die gelöschte Ausnahme erstellt + appointment.CustomerList = AppointmentModel.SelectedCustomers; + appointment.ResourceList = AppointmentModel.SelectedResources; + appointment.EmployeeList = new List(); - appointment.Originator = Model.LoggedInUser.Employee; + foreach(var selectedEmployee in AppointmentModel.SelectedEmployees ?? new List()) + { + appointment.EmployeeList.Add(new Employee2SchedulerAppointmentDC { Employee = selectedEmployee }); + } + + appointment.Originator = Model.LoggedInUser.Employee; + } + else + { + appointment.NewSchedulerAppointmentVersion = null; + } KalenderService.InsertSchedulerAppointment(appointment); ViewData["EditableAppointmentModel"] = appointment; @@ -532,10 +539,11 @@ namespace BeWoPlanerMobil.Controllers KalenderService.UpdateSchedulerAppointments(new List { appointment }); } - KalenderService.DeleteSchedulerAppointments( - appointmentsToRemove - .Where(appointment => appointment.SchedulerAppointmentOid.HasValue && appointment.NewSchedulerAppointmentVersion.HasValue) - .ToDictionary(k => k.SchedulerAppointmentOid.Value, v => v.NewSchedulerAppointmentVersion.Value)); + var oid2Version = appointmentsToRemove + .Where(appointment => appointment.SchedulerAppointmentOid.HasValue && appointment.NewSchedulerAppointmentVersion.HasValue) + .ToDictionary(k => k.SchedulerAppointmentOid.Value, v => v.NewSchedulerAppointmentVersion.Value); + + KalenderService.DeleteSchedulerAppointments(oid2Version); ReloadAppointments(); } @@ -1139,9 +1147,13 @@ namespace BeWoPlanerMobil.Controllers Model.ResourceCategories2Resources.Values.DoForEach(l => l.DoForEach(s => list.AddIfNotIn(s))); - Model.SelectedEmployees = Model.PossibleEmployees.Where(employee => Model.SelectedEmployeeOids.Contains(employee.EmployeeOid)).ToList(); - Model.SelectedCustomers = Model.PossibleCustomers.Where(customer => Model.SelectedCustomerOids.Contains(customer.CustomerOid)).ToList(); - Model.SelectedResources = list.Where(resource => resource.ResourceOid.HasValue && Model.SelectedResourceOids.Contains(resource.ResourceOid.Value)).ToList(); + //Model.SelectedEmployees = Model.PossibleEmployees.Where(employee => Model.SelectedEmployeeOids.Contains(employee.EmployeeOid)).ToList(); + //Model.SelectedCustomers = Model.PossibleCustomers.Where(customer => Model.SelectedCustomerOids.Contains(customer.CustomerOid)).ToList(); + //Model.SelectedResources = list.Where(resource => resource.ResourceOid.HasValue && Model.SelectedResourceOids.Contains(resource.ResourceOid.Value)).ToList(); + + AppointmentModel.SelectedEmployees = Model.PossibleEmployees.Where(employee => Model.SelectedEmployeeOids.Contains(employee.EmployeeOid)).ToList(); + AppointmentModel.SelectedCustomers = Model.PossibleCustomers.Where(customer => Model.SelectedCustomerOids.Contains(customer.CustomerOid)).ToList(); + AppointmentModel.SelectedResources = list.Where(resource => resource.ResourceOid.HasValue && Model.SelectedResourceOids.Contains(resource.ResourceOid.Value)).ToList(); Model.SelectedEmployeesForFiltering = Model.PossibleEmployees.Where(employee => Model.SelectedEmployeeOidsForFiltering.Contains(employee.EmployeeOid)).ToList(); Model.SelectedCustomersForFiltering = Model.PossibleCustomers.Where(customer => Model.SelectedCustomerOidsForFiltering.Contains(customer.CustomerOid)).ToList(); diff --git a/BeWoPlanerMobil/Controllers/LoginController.cs b/BeWoPlanerMobil/Controllers/LoginController.cs index 3a020a44b..241c6cff8 100644 --- a/BeWoPlanerMobil/Controllers/LoginController.cs +++ b/BeWoPlanerMobil/Controllers/LoginController.cs @@ -146,7 +146,7 @@ namespace BeWoPlanerMobil.Controllers } - public ActionResult Index(string tenant, string returnUrl) + public ActionResult Index(string tenant, string returnUrl, string message = null) { if(returnUrl != null) { @@ -184,6 +184,7 @@ namespace BeWoPlanerMobil.Controllers return Redirect(url); } + ViewData[LoginErrorIndex] = message; MobileSessionFacade.Tenant = tenant; return View("Index"); } diff --git a/BeWoPlanerMobil/Models/AppointmentModel.cs b/BeWoPlanerMobil/Models/AppointmentModel.cs index 3400664a0..d55f05301 100644 --- a/BeWoPlanerMobil/Models/AppointmentModel.cs +++ b/BeWoPlanerMobil/Models/AppointmentModel.cs @@ -36,6 +36,8 @@ namespace BeWoPlanerMobil.Models public int? RecurrenceIndex { get; set; } + public long? NewSchedulerAppointmentVersion { get; set; } + public bool ShowEmployeeColors { get; set; } public List ServiceRecordList { get; set; } @@ -214,6 +216,8 @@ namespace BeWoPlanerMobil.Models TaskDescription = appointment.TaskDescription; OriginatorOid = appointment.Originator.EmployeeOid; + + NewSchedulerAppointmentVersion = appointment.NewSchedulerAppointmentVersion; } public virtual void Assign(AppointmentModel source) @@ -252,6 +256,7 @@ namespace BeWoPlanerMobil.Models TaskDescription = source.TaskDescription; OriginatorOid = source.OriginatorOid; + NewSchedulerAppointmentVersion = source.NewSchedulerAppointmentVersion; } } } \ No newline at end of file diff --git a/BeWoPlanerMobil/Views/DevExpressScheduler/DevExpressScheduler.cshtml b/BeWoPlanerMobil/Views/DevExpressScheduler/DevExpressScheduler.cshtml index 1b3f27083..02f1e3359 100644 --- a/BeWoPlanerMobil/Views/DevExpressScheduler/DevExpressScheduler.cshtml +++ b/BeWoPlanerMobil/Views/DevExpressScheduler/DevExpressScheduler.cshtml @@ -13,6 +13,28 @@ newAptBtn.empty(); newAptBtn.append("Neuer Termin"); } + + const observer = new MutationObserver((mutations, obs) => { + const el0 = document.getElementById("appointmentRecurrenceForm_AptRecCtl_Monthly_WmeWeekOfMnth_DDD_L_LBI0T0"); + const el1 = document.getElementById("appointmentRecurrenceForm_AptRecCtl_Monthly_WmeWeekOfMnth_DDD_L_LBI1T0"); + const el2 = document.getElementById("appointmentRecurrenceForm_AptRecCtl_Monthly_WmeWeekOfMnth_DDD_L_LBI2T0"); + const el3 = document.getElementById("appointmentRecurrenceForm_AptRecCtl_Monthly_WmeWeekOfMnth_DDD_L_LBI3T0"); + const el4 = document.getElementById("appointmentRecurrenceForm_AptRecCtl_Monthly_WmeWeekOfMnth_DDD_L_LBI4T0"); + + const dropdown = document.getElementById("appointmentRecurrenceForm_AptRecCtl_Monthly_WmeWeekOfMnth_I"); + + if(el0 && el1 && el2 && el3 && el4 && dropdown) { + $(el0).text("Ersten"); + $(el1).text("Zweiten"); + $(el2).text("Dritten"); + $(el3).text("Vierten"); + $(el4).text("Letzten"); + + obs.disconnect(); + } + }); + + observer.observe(document.body, {childList: true, subtree: true}); }); function UpdateSchedulerHeight() { @@ -41,7 +63,7 @@ if(editFormPopup.css("top") !== undefined) { editFormPopup.css("top", "50px"); - const recurrence = $("#appointmentRecurrenceForm_AptRecCtl_mainDiv label:contains('Recurrence')"); + const recurrence = $("#appointmentRecurrenceForm_ChkRecurrence label:contains('Recurrence')"); const daily = $("#appointmentRecurrenceForm_AptRecCtl_mainDiv label:contains('Daily')"); const weekly = $("#appointmentRecurrenceForm_AptRecCtl_mainDiv label:contains('Weekly')"); const monthly = $("#appointmentRecurrenceForm_AptRecCtl_mainDiv label:contains('Monthly')"); @@ -52,6 +74,32 @@ weekly.text("Wöchentlich"); monthly.text("Monatlich"); yearly.text("Jährlich"); + + $("#appointmentRecurrenceForm_AptRecCtl_Daily_mainDiv label:contains('Every weekday')").text("Jeden Wochentag"); + $("#appointmentRecurrenceForm_AptRecCtl_Daily_mainDiv label:contains('Every')").text("Alle"); + $("#appointmentRecurrenceForm_AptRecCtl_Daily_mainDiv span:contains('day(s)')").text("Tage"); + + $("#appointmentRecurrenceForm_AptRecCtl_Weekly_mainDiv label:contains('Recur every')").text("Alle"); + $("#appointmentRecurrenceForm_AptRecCtl_Weekly_mainDiv span:contains('week(s) on:')").text("Wochen am:"); + + $("#appointmentRecurrenceForm_AptRecCtl_Monthly_mainDiv label:contains('Day')").text("Tag"); + $("#appointmentRecurrenceForm_AptRecCtl_Monthly_ctl02").text("im"); + $("#appointmentRecurrenceForm_AptRecCtl_Monthly_mainDiv span:contains('month(s)')").text("Monat"); + $("#appointmentRecurrenceForm_AptRecCtl_Monthly_mainDiv label:contains('The')").text("Am"); + $("#appointmentRecurrenceForm_AptRecCtl_Monthly_ctl04").text("jeden"); + $("#appointmentRecurrenceForm_AptRecCtl_Monthly_mainDiv span:contains('month(s)')").text("Monats"); + $("#appointmentRecurrenceForm_AptRecCtl_Monthly_WmeWeekOfMnth_DDD_L_LBI1T0").text("zweiten"); + + $("#appointmentRecurrenceForm_AptRecCtl_Yearly_mainDiv label:contains('Every')").text("Jeden"); + $("#appointmentRecurrenceForm_AptRecCtl_Yearly_mainDiv label:contains('The')").text("Am"); + $("#appointmentRecurrenceForm_AptRecCtl_Yearly_mainDiv label:contains('of')").text("im"); + + $("#appointmentRecurrenceForm_AptRecCtl_RangeCtl_mainDiv label:contains('No end date')").text("Ohne Enddatum"); + $("#appointmentRecurrenceForm_AptRecCtl_RangeCtl_mainDiv label:contains('End after:')").text("Endet nach:"); + $("#appointmentRecurrenceForm_AptRecCtl_RangeCtl_mainDiv span:contains('occurrences')").text("Wiederholungen"); + $("#appointmentRecurrenceForm_AptRecCtl_RangeCtl_mainDiv label:contains('End by:')").text("Endet am:"); + + } if(editFormPopup.outerWidth() !== undefined) { @@ -616,12 +664,13 @@ }
- @*@if(Html.IsInDebugMode()) + @*@if(Html.IsInDebugMode()) { }*@ +

diff --git a/BeWoPlanerMobil/Views/DevExpressScheduler/SchedulerHelper.cs b/BeWoPlanerMobil/Views/DevExpressScheduler/SchedulerHelper.cs index 38e2707ea..82840b150 100644 --- a/BeWoPlanerMobil/Views/DevExpressScheduler/SchedulerHelper.cs +++ b/BeWoPlanerMobil/Views/DevExpressScheduler/SchedulerHelper.cs @@ -58,6 +58,8 @@ namespace BeWoPlanerMobil.Views.DevExpressScheduler appointmentStorage.CustomFieldMappings.Add(new ASPxAppointmentCustomFieldMapping("CanBeViewed", "CanBeViewed")); appointmentStorage.CustomFieldMappings.Add(new ASPxAppointmentCustomFieldMapping("CanBeDeleted", "CanBeDeleted")); + appointmentStorage.CustomFieldMappings.Add(new ASPxAppointmentCustomFieldMapping("NewSchedulerAppointmentVersion", "NewSchedulerAppointmentVersion")); + return appointmentStorage; } diff --git a/BeWoPlanerMobil/Views/DevExpressScheduler/SchedulerPagePartial.cshtml b/BeWoPlanerMobil/Views/DevExpressScheduler/SchedulerPagePartial.cshtml index aa9564338..dbe6fbd62 100644 --- a/BeWoPlanerMobil/Views/DevExpressScheduler/SchedulerPagePartial.cshtml +++ b/BeWoPlanerMobil/Views/DevExpressScheduler/SchedulerPagePartial.cshtml @@ -380,7 +380,8 @@ CompletedDate = container.Appointment.CustomFields["CompletedDate"] is DateTime completedDate ? completedDate : null, OriginatorOid = (container.Appointment.CustomFields["Originator"] as CompactEmployeeDC)?.EmployeeOid, RecurrenceInfo = container.Appointment.RecurrenceInfo?.ToXml(), - RecurrenceIndex = container.Appointment.RecurrenceIndex + RecurrenceIndex = container.Appointment.RecurrenceIndex, + NewSchedulerAppointmentVersion = container.Appointment.CustomFields["NewSchedulerAppointmentVersion"] as long? }; var appointmentModel = ViewData["EditableAppointmentModel"] != null ? (AppointmentModel)ViewData["EditableAppointmentModel"] : newModel; diff --git a/BeWoPlanerMobil/Views/Login/Index.cshtml b/BeWoPlanerMobil/Views/Login/Index.cshtml index c11f74129..d2966303e 100644 --- a/BeWoPlanerMobil/Views/Login/Index.cshtml +++ b/BeWoPlanerMobil/Views/Login/Index.cshtml @@ -24,7 +24,7 @@