diff --git a/BeWoPlanerMobil/Controllers/CustomerController.cs b/BeWoPlanerMobil/Controllers/CustomerController.cs index 07f60b221..8066b5d75 100644 --- a/BeWoPlanerMobil/Controllers/CustomerController.cs +++ b/BeWoPlanerMobil/Controllers/CustomerController.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Web.Mvc; -using BeWo.Report.DefaultReports; +using BeWo.Report.DefaultReports; using BeWo.View.Navigation.Filter; using BeWoPlanerMobil.Models; using BeWoPlanerMobil.Service; @@ -15,6 +9,13 @@ using BS.Shared.DataContracts; using BS.Shared.DataContracts.Compact; using BS.Shared.Extensions; using DevExpress.XtraReports.UI; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Web.Mvc; namespace BeWoPlanerMobil.Controllers { @@ -1409,6 +1410,46 @@ namespace BeWoPlanerMobil.Controllers { return SaveCollapsibleStatusToModel(Model, isOpen, identifier); } + + [Authorize] + public string CheckForOverlappingAbsenceTimes(string startStr, string endStr, long oid) + { + if(false == DateTime.TryParse(startStr, out var start)) + { + start = DateTime.MinValue; + } + + if(false == DateTime.TryParse(endStr, out var end)) + { + end = DateTime.MaxValue; + } + + var messages = new List(); + + var hasOverlappingAbsenceTimes = false; + + foreach(var absenceTime in Model.SelectedCustomer.AbsenceTimes) + { + var alpha = absenceTime.Start ?? DateTime.MinValue; + var omega = absenceTime.End ?? DateTime.MaxValue; + + if(start >= alpha && start <= omega || + alpha >= start && alpha <= end || + end >= alpha && end <= omega || + omega >= start && omega <= end) + { + hasOverlappingAbsenceTimes = true; + break; + } + } + + if(hasOverlappingAbsenceTimes) + { + messages.Add("Die Abwesenheit überschneidet sich mit mindestens einer bereits vorhandenen Abwesenheit.

Möchten Sie trotzdem fortfahren?"); + } + + return JsonConvert.SerializeObject(messages); + } } public enum CustomerReportType diff --git a/BeWoPlanerMobil/Controllers/DevExpressSchedulerController.cs b/BeWoPlanerMobil/Controllers/DevExpressSchedulerController.cs index 5d024e086..2b2c6bed8 100644 --- a/BeWoPlanerMobil/Controllers/DevExpressSchedulerController.cs +++ b/BeWoPlanerMobil/Controllers/DevExpressSchedulerController.cs @@ -339,6 +339,19 @@ namespace BeWoPlanerMobil.Controllers return PartialView("SchedulerPagePartial", Model); } + [Authorize] + public string GetAppointmentType(long oid) + { + var appointment = Model.GetAppointmentByOid(oid); + + var showMenuItem = false; + + //var isTask = appointment.IsTask; + //var isAbsenceTime = appointment. + + return JsonConvert.SerializeObject(showMenuItem); + } + [Authorize] public ActionResult CheckEmployeeAvailability(string startString, string endString) { diff --git a/BeWoPlanerMobil/Controllers/EmployeeController.cs b/BeWoPlanerMobil/Controllers/EmployeeController.cs index 1b9e5f0ec..6313b2734 100644 --- a/BeWoPlanerMobil/Controllers/EmployeeController.cs +++ b/BeWoPlanerMobil/Controllers/EmployeeController.cs @@ -1,12 +1,14 @@ using System; -using System.Diagnostics; +using System.Collections.Generic; using System.Linq; using System.Web.Mvc; using BeWoPlanerMobil.Models; using BeWoPlanerMobil.Service; using BeWoPlanerMobil.Util; +using Bogus.DataSets; using BS.Shared; using BS.Shared.DataContracts; +using Newtonsoft.Json; namespace BeWoPlanerMobil.Controllers { @@ -276,5 +278,59 @@ namespace BeWoPlanerMobil.Controllers return PartialView("AbsenceTimePartial", Model); } + + [Authorize] + public string CheckForOverlappingAbsenceTimes(string startStr, string endStr, long oid) + { + var hasNoEnd = false; + + if(false == DateTime.TryParse(startStr, out var start)) + { + start = DateTime.MinValue; + } + + if(false == DateTime.TryParse(endStr, out var end)) + { + hasNoEnd = true; + + end = DateTime.MaxValue; + } + + var messages = new List(); + + var hasOverlappingAbsenceTimes = false; + + foreach(var absenceTime in Model.SelectedEmployee.AbsenceTimes) + { + var alpha = absenceTime.Start ?? DateTime.MinValue; + var omega = absenceTime.End ?? DateTime.MaxValue; + + if(start >= alpha && start <= omega || + alpha >= start && alpha <= end || + end >= alpha && end <= omega || + omega >= start && omega <= end) + { + hasOverlappingAbsenceTimes = true; + break; + } + } + + if(hasOverlappingAbsenceTimes) + { + messages.Add($"Die Abwesenheit überschneidet sich mit mindestens einer bereits vorhandenen Abwesenheit.{(hasNoEnd ? "

" : "
")}"); + } + + if(hasNoEnd) + { + messages.Add("Die Abwesenheit hat kein Enddatum.
Beachten Sie, dass Abwesenheiten ohne Enddatum unbegrenzt weiterlaufen und es dadurch zu Fehlberechnungen im Stunden- und Urlaubskonto kommen kann."); + } + + if(messages.Any()) + { + messages.Add("

Möchten Sie trotzdem fortfahren?
"); + } + + return JsonConvert.SerializeObject(messages); + } } } \ No newline at end of file diff --git a/BeWoPlanerMobil/Controllers/IAbsenceTimeController.cs b/BeWoPlanerMobil/Controllers/IAbsenceTimeController.cs index 231451d84..0d82c79d9 100644 --- a/BeWoPlanerMobil/Controllers/IAbsenceTimeController.cs +++ b/BeWoPlanerMobil/Controllers/IAbsenceTimeController.cs @@ -23,5 +23,8 @@ namespace BeWoPlanerMobil.Controllers [Authorize] ActionResult DeleteAbsenceTime(long absenceTimeOid); + + [Authorize] + string CheckForOverlappingAbsenceTimes(string startStr, string endStr, long oid); } } diff --git a/BeWoPlanerMobil/Controllers/MainController.cs b/BeWoPlanerMobil/Controllers/MainController.cs index 8d2386b2c..7c42446ea 100644 --- a/BeWoPlanerMobil/Controllers/MainController.cs +++ b/BeWoPlanerMobil/Controllers/MainController.cs @@ -4250,7 +4250,10 @@ namespace BeWoPlanerMobil.Controllers Model.TransferringAppointmentOid = TempData[TempDataConstants.AppointmentOidKey] as long?; - var isSerientermin = TempData[TempDataConstants.AppointmentIsSerienterminKey] is true; + var recurrenceIndex = (int?) TempData[TempDataConstants.AppointmentRecurrenceIndexKey]; + + var isSerientermin = recurrenceIndex.HasValue; + //TempData[TempDataConstants.AppointmentIsSerienterminKey] is true; if((false == Model.TransferringAppointmentOid.HasValue && false == isSerientermin) || false == Model.LoggedInEmployee.EmployeeOid.HasValue) { @@ -4437,7 +4440,9 @@ namespace BeWoPlanerMobil.Controllers var pattern = StaticAppointmentFactory.CreateAppointment(AppointmentType.Pattern); pattern.RecurrenceInfo.FromXml(recurrenceInfo); - var apt = pattern.CreateException(AppointmentType.ChangedOccurrence, appointment.RecurrenceIndex); + var apt = pattern.CreateException(AppointmentType.ChangedOccurrence, recurrenceIndex.Value); + + var changedOccurrence = SchedulerAppointmentDC.RecurringExceptionFromDevExpressAppointment(apt, appointment); var x = apt.RecurrenceIndex; } diff --git a/BeWoPlanerMobil/Controllers/SchedulerController.cs b/BeWoPlanerMobil/Controllers/SchedulerController.cs index 844fff7f9..2a3b710ff 100644 --- a/BeWoPlanerMobil/Controllers/SchedulerController.cs +++ b/BeWoPlanerMobil/Controllers/SchedulerController.cs @@ -1431,6 +1431,11 @@ namespace BeWoPlanerMobil.Controllers TempData[TempDataConstants.AppointmentOidKey] = appointment?.SchedulerAppointmentOid; + if(appointment?.RecurrenceInfo != null) + { + TempData[TempDataConstants.AppointmentRecurrenceIndexKey] = appointment?.RecurrenceIndex; + } + TempData[TempDataConstants.AppointmentStartKey] = appointment?.StartDate; TempData[TempDataConstants.AppointmentEndKey] = appointment?.EndDate; TempData[TempDataConstants.AppointmentSubjectKey] = appointment?.Subject; diff --git a/BeWoPlanerMobil/Models/CustomerModel.cs b/BeWoPlanerMobil/Models/CustomerModel.cs index 1bb2b35c4..b9683e832 100644 --- a/BeWoPlanerMobil/Models/CustomerModel.cs +++ b/BeWoPlanerMobil/Models/CustomerModel.cs @@ -16,6 +16,7 @@ namespace BeWoPlanerMobil.Models public long? ObjectOid => SelectedCustomerOid; public TableID ObjectTid => TableID.Customer; public string HtmlPrefix => "customer"; + public long? AbsenteeOid => SelectedCustomerOid; public IAbsenceTime AbsenceTimeObject { diff --git a/BeWoPlanerMobil/Models/EmployeeModel.cs b/BeWoPlanerMobil/Models/EmployeeModel.cs index f7563e13c..9bb3547b7 100644 --- a/BeWoPlanerMobil/Models/EmployeeModel.cs +++ b/BeWoPlanerMobil/Models/EmployeeModel.cs @@ -28,6 +28,7 @@ namespace BeWoPlanerMobil.Models set => EmployeeSessionModel.SelectedAbsenceTimeObjectOid = value; } + public long? AbsenteeOid => SelectedEmployeeOid; public EmployeeModel() { SessionModel = new EmployeeSessionModel(); diff --git a/BeWoPlanerMobil/Models/IAbsenceTimeModel.cs b/BeWoPlanerMobil/Models/IAbsenceTimeModel.cs index 19ed5f6ea..ef1969be4 100644 --- a/BeWoPlanerMobil/Models/IAbsenceTimeModel.cs +++ b/BeWoPlanerMobil/Models/IAbsenceTimeModel.cs @@ -13,5 +13,6 @@ namespace BeWoPlanerMobil.Models IAbsenceTime AbsenceTimeObject { get; set; } Dictionary Collapsibles2IsShown { get; set; } List AbsenceReasonItems { get; } + long? AbsenteeOid { get; } } } diff --git a/BeWoPlanerMobil/Scripts/ownSoft-Scripts/mobileUtils.js b/BeWoPlanerMobil/Scripts/ownSoft-Scripts/mobileUtils.js index f1acec2eb..6d462638c 100644 --- a/BeWoPlanerMobil/Scripts/ownSoft-Scripts/mobileUtils.js +++ b/BeWoPlanerMobil/Scripts/ownSoft-Scripts/mobileUtils.js @@ -552,4 +552,48 @@ function getTimeStamp(dateObject, showSeconds, showMilliseconds) { } else { return `${dd}.${MM}.${yyyy} ${HH}:${mm}`; } -} \ No newline at end of file +} + +function getUnixTimeStamp(dateObject, showSeconds) { + const dd = String(dateObject.getDate()).padStart(2, "0"); + const MM = String(dateObject.getMonth() + 1).padStart(2, "0"); + const yyyy = dateObject.getFullYear(); + const HH = String(dateObject.getHours()).padStart(2, "0"); + const mm = String(dateObject.getMinutes()).padStart(2, "0"); + const ss = String(dateObject.getSeconds()).padStart(2, "0"); + const ms = String(dateObject.getMilliseconds()).padStart(2, "0"); + + return showSeconds ? `${yyyy}-${MM}-${dd} ${HH}:${mm}:${ss}` : `${yyyy}-${MM}-${dd} ${HH}:${mm}`; +} + + function showMessagePopupWithHtmlAndCallbacks(title, messageAsHtml, callback, cancelBtnCallback) { + $("#popupTitle").text(title); + + if(messageAsHtml !== null) { + $("#modal-body").html("

"); + } + + $("#popupMessage").html(messageAsHtml); + + $("#message-popup-ok-btn").off("click"); + + if(typeof callback === "function") { + $("#message-popup-ok-btn").on("click", function() { + callback(); + }); + } + + if(typeof cancelBtnCallback === "function") { + $("#message-popup-close-btn").off("click"); + $("#message-popup-close-btn").on("click", function() { + cancelBtnCallback(); + }); + } + + $("#messagePopup").modal( + { + backdrop: "static", + keyboard: false + } + ); + } \ No newline at end of file diff --git a/BeWoPlanerMobil/Util/MobileUtils.cs b/BeWoPlanerMobil/Util/MobileUtils.cs index a7bd9e74e..201718bbb 100644 --- a/BeWoPlanerMobil/Util/MobileUtils.cs +++ b/BeWoPlanerMobil/Util/MobileUtils.cs @@ -625,5 +625,12 @@ namespace BeWoPlanerMobil.Util return "5px solid #C0FFD0"; } + + public static string GetCssRightValue(DevExpress.XtraScheduler.Appointment appointment) + { + var serviceRecords = appointment.CustomFields[nameof(SchedulerAppointmentDC.ServiceRecordList)] as List ?? new List(); + + return serviceRecords.Any() ? "40px" : "23px"; + } } } \ No newline at end of file diff --git a/BeWoPlanerMobil/Views/Customer/Customer.cshtml b/BeWoPlanerMobil/Views/Customer/Customer.cshtml index 5d5e46c7a..c96a8f8bb 100644 --- a/BeWoPlanerMobil/Views/Customer/Customer.cshtml +++ b/BeWoPlanerMobil/Views/Customer/Customer.cshtml @@ -1079,7 +1079,7 @@ } -@if(Model.HasRightToViewCustomerAbsenceTimes) +@if(Model.HasRightToViewCustomerAbsenceTimes && Model.SelectedCustomer != null) {