using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Web.Mvc; using BeWoPlanerMobil.Models; using BeWoPlanerMobil.Service; using BeWoPlanerMobil.Util; using BS.Shared; using BS.Shared.DataContracts; using BS.Shared.DataContracts.Compact; using BS.Shared.Extensions; using DevExpress.XtraScheduler; using DevExpress.XtraScheduler.Compatibility; using Newtonsoft.Json; using static BeWoPlanerMobil.Util.MobileUtils; using RecurrenceInformation = BS.Shared.Core.RecurrenceInformation; namespace BeWoPlanerMobil.Controllers { public class SchedulerController : AbstractBaseController { private SchedulerModel _Model; public SchedulerModel Model { get { if (!MobileSessionFacade.IsUserLoggedIn()) { Logout(); return null; } if (((SchedulerModel) Session[ModelSessionConstants.SchedulerModelKey])?.Employee is null) { _Model = new SchedulerModel { Employee = MobileSessionFacade.LoggedInEmployee }; Session[ModelSessionConstants.SchedulerModelKey] = _Model; } else { _Model = (SchedulerModel) Session[ModelSessionConstants.SchedulerModelKey]; } return _Model; } } [Authorize] public ActionResult Scheduler() { if(Model is null || !MobileSessionFacade.IsUserLoggedIn() || Request.Browser.Browser.Equals("InternetExplorer") || !AbstractModel.IsAllowedToSeeScheduler) { return Logout(); } if(AbstractModel.HasRightToInsertRessourceAppointments || AbstractModel.HasRightToViewAllResourceAppointments) { var allResources = KalenderService.GetAllResources().OrderBy(r => r.Name).ToList(); var categories2Resources = new Dictionary>(); foreach(var category in allResources.Select(resource => resource.ResourceCategory)) { categories2Resources.AddOrUpdateValueInDictionary(category, allResources.Where(resource => resource.ResourceCategory.Equals(category)).OrderBy(r => r.Name).ToList()); } Model.ResourceCategories2Resources = categories2Resources.OrderBy(kvp => kvp.Key.DisplayName).ToDictionary(kvp => kvp.Key, kvp => kvp.Value); } if(Model?.Employee?.EmployeeOid.HasValue ?? false) { var compactEmployee = EmployeeService.GetActiveCompactEmployeeWithOid(Model.Employee.EmployeeOid.Value); Model.MyTeamEmployees = EmployeeService.GetAllTeamMember(compactEmployee).OrderBy(employee => employee.LastName).ToList(); } else if(!(Model is null)) { Model.MyTeamEmployees = new List(); } if(AbstractModel.HasRightToViewTeams && (Model?.Employee?.EmployeeOid.HasValue ?? false)) { Model.MyTeams = EmployeeService.GetAllActiveCompactTeamsForEmployee(Model.Employee.EmployeeOid.Value).OrderBy(team => team.Name).ToList(); } if(!(Model is null)) { Model.TeamMemberCustomerOids = EmployeeService.LoadTeamsRelatedCustomerOids(MobileSessionFacade.LoggedInCompactEmployee.EmployeeOid); } LoadAppointmentsForDate(); return View(Model); } private void LoadAppointmentsForDate() { if(Model?.Employee.EmployeeOid is null) { return; } var date = Model.SelectedDate; var monday = date.GetInSameCalendarWeek(DayOfWeek.Monday); var sunday = monday.Date.AddDays(6); var start = date; var end = date.AddDays(1); if(Model.SelectedSchedulerView == "5") { start = monday; end = monday.AddDays(4); } else if(Model.SelectedSchedulerView == "7") { start = monday; end = sunday; } var selectedCustomers = Model.SelectedCustomersForFiltering?.Select(s => s.CustomerOid).ToList() ?? new List(); var selectedEmployees = Model.SelectedEmployeesForFiltering?.Select(s => s.EmployeeOid).ToList() ?? new List(); var selectedResources = Model.SelectedResourcesForFiltering?.Where(w => w.ResourceOid.HasValue).Select(s => s.ResourceOid.Value).ToList() ?? new List(); var appointments = KalenderService.LoadFilteredAppointmentsMitAufgaben(AbstractModel.HasRightToViewEmployeeAppointments, Model.Employee.EmployeeOid.Value, start.Date, end, selectedEmployees, selectedCustomers, selectedResources, false, false, false, false, true, true).ToList(); // Private Termine foreach(var appointment in appointments.Where(a => a.IsPrivate)) { if(appointment.Originator.Equals(MobileSessionFacade.LoggedInCompactEmployee) || appointment.EmployeeList.Any(e2a => e2a.Employee.Equals(MobileSessionFacade.LoggedInCompactEmployee))) { continue; } appointment.CanBeEdited = false; appointment.Description = "Privater Termin"; appointment.Subject = $"Privat ({appointment.Originator})"; } // Unerledigte Aufgaben var tasks = appointments.Where(w => w.IsTask && w.CompletedDate is null).ToList(); // Nur eigene Kliententermine ansehen if(!AbstractModel.HasRightToViewCustomerAppointments) { appointments = appointments.Where(a => a.CustomerList.All(c => MobileSessionFacade.LoggedInEmployee.RelatedCustomers.Any(rc => rc.Customer.Equals(c)))).ToList(); } if(!AbstractModel.HasRightToViewAllResourceAppointments) { appointments = appointments.Where(a => a.ResourceList.Count == 0).ToList(); } if(!AbstractModel.IsAllowedToSeeCustomers) { appointments = appointments.Where(a => a.CustomerList.Count == 0).ToList(); } // Wenn es ein ganztägiger Termin ist, eine Sekunde abziehen und beim Speichern wieder draufaddieren? foreach(var app in appointments.Where(a => a.AllDay)) { if(app.EndDate is null) { continue; } app.EndDate = app.EndDate.Value.AddMinutes(-1); } var holySweetFlyingFuck = appointments.Where(w => w.IsTask == false && // Aufgaben ausschließen w.StartDate.HasValue && w.EndDate.HasValue && // Datumsangaben haben einen Wert (date.InBetween(w.StartDate.Value, w.EndDate.Value, false) || date.CompareShortDates(w.StartDate.Value)) // Einzeltermine oder Ausnahmen und gelöschte Ausnahmen && (w.RecurrenceInfo is null || w.RecurrenceInfo != null && (w.Type == 3 || w.Type == 4)) ).ToList(); var deletedOccurrences = holySweetFlyingFuck.Where(w => w.Type == 4).Select(s => BS.Shared.Core.Utils.GetOccurrenceId(s.RecurrenceInfo)).ToList(); var changedOccurrences = holySweetFlyingFuck.Where(w => w.Type == 3).Select(s => BS.Shared.Core.Utils.GetOccurrenceId(s.RecurrenceInfo)).ToList(); holySweetFlyingFuck = holySweetFlyingFuck.Where(w => w.Type != 4).ToList(); holySweetFlyingFuck.AddRangeIfElementsNotIn(CalculateRecurrences(appointments, start, end, changedOccurrences, deletedOccurrences)); holySweetFlyingFuck.AddRange(tasks); Model.Appointments = Model.ShouldLoadTasks ? holySweetFlyingFuck.OrderByDescending(appointment => appointment.IsTask).ThenBy(appointment => appointment.StartDate).ToList() : holySweetFlyingFuck.Where(w => w.IsTask is false).OrderBy(appointment => appointment.StartDate).ToList(); Model.WeekViewObject = new WeekViewObject(Model.Appointments, Model.SelectedDate.GetInSameCalendarWeek(DayOfWeek.Monday), Model.Employee); if(AbstractModel.HasRightToViewCustomerSelectionInScheduler) { //Model.AllCustomers = EmployeeService.GetActiveCompactCustomersForEmployee(Model.Employee.EmployeeOid).OrderBy(o => o.DetailDescription).ToList(); Model.AllCustomers = CustomerService.GetAllActiveCompactCustomers().OrderBy(customer => customer.LastName).ToList(); } if(AbstractModel.HasRightToViewEmployeeAppointments) { //Model.AllEmployees = EmployeeService.GetActiveCompactEmployeesForEmployee(Model.Employee.EmployeeOid.Value).OrderBy(o => o.DetailDescription).ToList(); Model.AllEmployees = EmployeeService.GetAllActiveEmployeesCompact().OrderBy(employee => employee.LastName).ToList(); } } private static IEnumerable CalculateRecurrences(IEnumerable appointments, DateTime start, DateTime end, IReadOnlyCollection changedOccurrences, IReadOnlyCollection deletedOccurrences) { var result = new List(); var interval = new TimeInterval(start, end); foreach (var appointment in appointments.Where(app => app.RecurrenceInfo != null && app.Type == 1)) { var recurrenceInfo = new RecurrenceInfo(); recurrenceInfo.FromXml(appointment.RecurrenceInfo); var occurrenceCalculator = OccurrenceCalculator.CreateInstance(recurrenceInfo); var pattern = StaticAppointmentFactory.CreateAppointment(AppointmentType.Pattern); pattern.RecurrenceInfo.FromXml(appointment.RecurrenceInfo); pattern.Start = pattern.RecurrenceInfo.Start; pattern.End = pattern.RecurrenceInfo.End; var patternId = pattern.RecurrenceInfo.Id.ToString(); var occurrences = occurrenceCalculator.CalcOccurrences(interval, pattern); if(occurrences.Count > 0) { foreach(var app in occurrences.GetAppointments(interval)) { var index = app.RecurrenceIndex; var duration = (appointment.EndDate.Value - appointment.StartDate.Value).TotalMinutes; var isOutOfInterval = app.Start.GetShortDateTime().AreInBetweenDates(app.Start.AddMinutes(duration), start, end) == false; var isChangedOccurrence = changedOccurrences.Any(a => a.PatternId.Equals(patternId) && a.Index == index); var isDeletedOccurrence = deletedOccurrences.Any(a => a.PatternId.Equals(patternId) && a.Index == index); if(isOutOfInterval || isChangedOccurrence || isDeletedOccurrence) { continue; } var recurringAppointment = new SchedulerAppointmentDC { AllDay = appointment.AllDay, CustomerList = appointment.CustomerList, Description = appointment.Description?.RemoveUppercaseEsszett(), EmployeeList = appointment.EmployeeList, EndDate = app.Start.AddMinutes(duration), FormerBookingSequenceOid = appointment.FormerBookingSequenceOid, IsPrivate = appointment.IsPrivate, LabelKey = appointment.LabelKey, Location = appointment.Location?.RemoveUppercaseEsszett(), Originator = appointment.Originator, RecurrenceInfo = app.RecurrenceInfo.ToXml(), RecurrenceIndex = index, ReminderInfo = appointment.ReminderInfo, ResourceList = appointment.ResourceList, StartDate = app.Start, Subject = appointment.Subject?.RemoveUppercaseEsszett() ?? "", Type = (int) app.Type, ServiceRecordList = appointment.ServiceRecordList, SupportConceptList = appointment.SupportConceptList }; result.AddIfNotIn(recurringAppointment); } } } // Es wird bei ganztägigen Serienterminen eine Minute abgezogen, damit die nicht als zweitägig angezeigt werden. Bearbeiten kann man Serientermin im MoK noch nicht. foreach(var app in result.Where(w => w.AllDay && w.EndDate.HasValue)) { app.EndDate = app.EndDate.Value.AddMinutes(-1); } return result; } [Authorize] [HttpPost] public ActionResult InsertOrUpdateAppointment(FormCollection formCollection) { try { if(Model is null) { TempData[TempDataConstants.DoLogoutKey] = true; return Logout(); } var rawStartDate = formCollection[FormCollectionConstants.AppointmentStartDateKey]; var rawEndDate = formCollection[FormCollectionConstants.AppointmentEndDateKey]; var rawStartTime = formCollection[FormCollectionConstants.AppointmentStartTimeKey]; var rawEndTime = formCollection[FormCollectionConstants.AppointmentEndTimeKey]; var subject = formCollection[FormCollectionConstants.AppointmentSubjectKey]; var location = formCollection[FormCollectionConstants.AppointmentLocationKey]; var notice = formCollection[FormCollectionConstants.AppointmentNoticeKey]; subject = subject.RemoveUppercaseEsszett(); location = location.RemoveUppercaseEsszett(); notice = notice.RemoveUppercaseEsszett(); var isPrivate = formCollection[FormCollectionConstants.AppointmentIsPrivateKey] == "true,false"; var allDay = formCollection[FormCollectionConstants.AppointmentIsAllDayKey] == "true,false"; var isSuccessfulStartTime = DateTime.TryParseExact(rawStartTime, "HH:mm", null, DateTimeStyles.None, out var startTime); var isSuccessfulEndTime = DateTime.TryParseExact(rawEndTime, "HH:mm", null, DateTimeStyles.None, out var endTime); if(rawStartTime is null) { rawStartTime = "00:00"; } if(rawEndTime is null) { rawEndTime = "00:00"; } var startAndEnd = ConvertStringDatesToDateTimes($"{rawStartDate} {rawStartTime}", $"{rawEndDate} {rawEndTime}"); var startDate = startAndEnd.StartDate; var endDate = startAndEnd.EndDate; if(!allDay && isSuccessfulStartTime && isSuccessfulEndTime || allDay) { startDate = startDate.MergeDatesByDate(startTime); endDate = endDate.MergeDatesByDate(endTime); var appointmentToInsert = Model.SelectedAppointment ?? new SchedulerAppointmentDC(); var isNew = !appointmentToInsert.SchedulerAppointmentOid.HasValue; var appointmentEmployeeList = new List(); if(Model.SelectedEmployees?.Any() ?? false) { foreach(var employee in Model.SelectedEmployees) { var employee2Appointment = new Employee2SchedulerAppointmentDC { Employee = employee, }; appointmentEmployeeList.Add(employee2Appointment); } } if(allDay) { startDate = startDate.Date; endDate = endDate.AddDays(1); } appointmentToInsert.EmployeeList = appointmentEmployeeList; appointmentToInsert.CustomerList = Model.SelectedCustomers; appointmentToInsert.ResourceList = Model.SelectedResources ?? new List(); appointmentToInsert.SupportConceptList = isNew ? new List() : appointmentToInsert.SupportConceptList; appointmentToInsert.ServiceRecordList = isNew ? new List() : appointmentToInsert.ServiceRecordList; appointmentToInsert.EndDate = endDate; appointmentToInsert.StartDate = startDate; appointmentToInsert.Subject = subject; appointmentToInsert.Description = notice; appointmentToInsert.Originator = MobileSessionFacade.LoggedInCompactEmployee; appointmentToInsert.Location = location; appointmentToInsert.ActivationType = ActivationTypeId.Active; appointmentToInsert.IsPrivate = isPrivate; appointmentToInsert.AllDay = allDay; // Eine Minute addieren, wenn die Uhrzeit eines ganztägigen Termins nicht exakt 00:00 ist. // ToDo: Wird beim SelectAppointmentToEdit gemacht, damit die Formularanzeige korrekt ist! if(allDay && endDate.Hour == 23 && endDate.Minute == 59) { appointmentToInsert.EndDate = endDate.AddMinutes(1); } // ToDo: Rechte beachten! if(appointmentToInsert.CanBeEdited) { if(!isNew) { KalenderService.UpdateSchedulerAppointments(new List {appointmentToInsert}); } else { KalenderService.InsertSchedulerAppointments(new List {appointmentToInsert}); } } } } catch(Exception exception) { Log.Error(exception.Message, exception); } finally { if(Model != null) { Model.IsAllDay = false; Model.SelectedAppointment = null; Model.SelectedResources?.Clear(); Model.SelectedCustomers?.Clear(); Model.SelectedEmployees?.Clear(); } } return RedirectToActionPermanent("Scheduler"); } [Authorize] [HttpPost] public ActionResult NavigateToPreviousDate() { if (Model is null) { TempData[TempDataConstants.DoLogoutKey] = true; return Logout(); } Model.SelectedDate = Model.SelectedDate.AddDays(-1); if(Model != null) { Model.SelectedAppointment = null; //Model.SelectedResources.Clear(); } return RedirectToActionPermanent("Scheduler"); } [Authorize] [HttpPost] public ActionResult NavigateToNextDate() { if(Model is null) { TempData[TempDataConstants.DoLogoutKey] = true; return Logout(); } Model.SelectedDate = Model.SelectedDate.AddDays(1); if(!(Model is null)) { Model.SelectedAppointment = null; //Model.SelectedResources.Clear(); } return RedirectToActionPermanent("Scheduler"); } [Authorize] [HttpPost] public ActionResult SelectSchedulerDate(FormCollection formCollection) { if(Model is null) { TempData[TempDataConstants.DoLogoutKey] = true; return Logout(); } var rawSchedulerDate = formCollection[FormCollectionConstants.AppointmentSchedulerDateKey]; var schedulerDate = DateTime.ParseExact(rawSchedulerDate, "dd.MM.yyyy", null); Model.SelectedDate = schedulerDate; Model.SelectedAppointment = null; Model.SelectedResources.Clear(); return RedirectToActionPermanent("Scheduler"); } [Authorize] [HttpPost] public ActionResult SelectAppointmentToEdit(FormCollection formCollection) { if(Model is null) { TempData[TempDataConstants.DoLogoutKey] = true; #if DEBUG TempData[TempDataConstants.ErrorMessageKey] = "Model war null"; #endif return Logout(); } var rawOid = formCollection[FormCollectionConstants.AppointmentSchedulerOidHolderKey]; var isSuccessful = long.TryParse(rawOid, out var appointmentOid); if(!isSuccessful) { return RedirectToActionPermanent("Scheduler"); } Model.SelectedAppointment = Model.Appointments.FirstOrDefault(app => app.SchedulerAppointmentOid.HasValue && app.SchedulerAppointmentOid.Value == appointmentOid); if(Model.SelectedAppointment != null) { if(Model.SelectedAppointment.AllDay && Model.SelectedAppointment.EndDate.HasValue) { Model.SelectedAppointment.EndDate = Model.SelectedAppointment.EndDate.Value.AddMinutes(1).AddDays(-1); } Model.IsAllDay = Model.SelectedAppointment.AllDay; Model.IsPrivate = Model.SelectedAppointment.IsPrivate; Model.SelectedResources = Model.SelectedAppointment?.ResourceList ?? new List(); Model.SelectedEmployees = Model.SelectedAppointment?.EmployeeList.Select(e2a => e2a.Employee).ToList() ?? new List(); Model.SelectedCustomers = Model.SelectedAppointment?.CustomerList ?? new List(); } return RedirectToActionPermanent("Scheduler"); } [Authorize] public JsonResult ResetSelectedAppointment() { if(Model != null) { Model.SelectedAppointment = null; Model.SelectedResources.Clear(); Model.SelectedEmployees.Clear(); Model.SelectedCustomers.Clear(); Model.IsAllDay = false; Model.IsPrivate = false; } return Json(null, JsonRequestBehavior.AllowGet); } [Authorize] public JsonResult CheckForOverlappingAppointments(string startDateRaw, string endDateRaw, string startTimeRaw, string endTimeRaw) { if (Model is null) { Logout(); return null; } var isOverlapping = false; var oid = Model.SelectedAppointment?.SchedulerAppointmentOid; var isSuccessfulStartDate = DateTime.TryParseExact(startDateRaw, "dd.MM.yyyy", null, DateTimeStyles.None, out var startDate); var isSuccessfulStartTime = DateTime.TryParseExact(startTimeRaw, "HH:mm", null, DateTimeStyles.None, out var startTime); var isSuccessfulEndDate = DateTime.TryParseExact(endDateRaw, "dd.MM.yyyy", null, DateTimeStyles.None, out var endDate); var isSuccessfulEndTime = DateTime.TryParseExact(endTimeRaw, "HH:mm", null, DateTimeStyles.None, out var endTime); if (isSuccessfulStartDate && isSuccessfulStartTime && isSuccessfulEndDate && isSuccessfulEndTime) { startDate = startDate.MergeDatesByDate(startTime); endDate = endDate.MergeDatesByDate(endTime); var customerOidList = Model.SelectedAppointment?.CustomerList?.Select(customer => customer.CustomerOid).ToList() ?? new List(); var employeeOidList = Model.SelectedAppointment?.EmployeeList?.Select(employee2Appointment => employee2Appointment.Employee.EmployeeOid).ToList() ?? new List(); var resourceOidList = Model.SelectedResources.Where(resource => resource.ResourceOid.HasValue).Select(resource => resource.ResourceOid.Value).ToList() ?? new List(); var originator = Model.SelectedAppointment?.Originator ?? MobileSessionFacade.LoggedInCompactEmployee; var recurrenceId = Model.SelectedAppointment?.RecurrenceId ?? string.Empty; var recurrenceIndex = Model.SelectedAppointment?.RecurrenceIndex ?? 0; isOverlapping = KalenderService.OverlappingAppointmentsExist(startDate, endDate, employeeOidList, customerOidList, resourceOidList, originator.EmployeeOid, oid, recurrenceId, recurrenceIndex); // TODO: Serientermine überprüfen if(Model.Appointments != null) { foreach(var appointment in Model.Appointments.Where(app => app.SchedulerAppointmentOid is null && app.IsTask == false)) { } } } return Json(isOverlapping, JsonRequestBehavior.AllowGet); } [Authorize] public string SelectResourcesForAppointment(string resourceOids) { if(Model is null) { Logout(); return LeerzeichenFuerGetMethoden; } var oidList = ConvertOidStringToList(resourceOids); var list = new List(); Model.ResourceCategories2Resources.Values.DoForEach(l => l.DoForEach(s => list.AddIfNotIn(s))); Model.SelectedResources = list.Where(resource => resource.ResourceOid.HasValue && oidList.Contains(resource.ResourceOid.Value)).ToList(); return JsonConvert.SerializeObject(Model.SelectedResources); } [Authorize] public string SelectEmployeesForAppointment(string oidString) { if (Model is null) { Logout(); return LeerzeichenFuerGetMethoden; } var oidList = ConvertOidStringToList(oidString); Model.SelectedEmployees = Model.AllEmployees.Where(employee => oidList.Contains(employee.EmployeeOid)).ToList(); return JsonConvert.SerializeObject(Model.SelectedEmployees.OrderBy(o => o.DetailDescription)); } [Authorize] public string SelectCustomersForAppointment(string oidString) { if (Model is null) { Logout(); return LeerzeichenFuerGetMethoden; } var oidList = ConvertOidStringToList(oidString); Model.SelectedCustomers = Model.AllCustomers.Where(customer => oidList.Contains(customer.CustomerOid)).ToList(); return JsonConvert.SerializeObject(Model.SelectedCustomers.OrderBy(o => o.LastNameFirstName)); } [Authorize] public string CheckResourcesAvailability(string start, string end, string resourceOids, bool allDay) { if(string.IsNullOrWhiteSpace(start) || string.IsNullOrWhiteSpace(end) || string.IsNullOrWhiteSpace(resourceOids) || Model is null) { return LeerzeichenFuerGetMethoden; } if(!AbstractModel.HasRightToInsertRessourceAppointments) { return "Fehler! Sie haben nicht das Recht, Termine mit Ressourcen anzulegen!"; } var oidList = ConvertOidStringToList(resourceOids); foreach(var oid in oidList) { if(!Model.ResourceCategories2Resources.Any(a => a.Value.All(b => b.ResourceOid != oid))) { return LeerzeichenFuerGetMethoden; } } var dateTimes = ConvertStringDatesToDateTimes(start, end); if(allDay) { dateTimes.EndDate = dateTimes.EndDate.AddDays(1); } var info = KalenderService.CheckResourceAvailabilityWithEmployeeInformation(dateTimes.StartDate, dateTimes.EndDate, oidList, Model.SelectedAppointment?.SchedulerAppointmentOid, null); var result = string.Empty; foreach(var kvp in info) { result += $"Die Ressource \"{kvp.Key}\" ist im ausgewählten Zeitraum {start} bis {end} bereits gebucht"; if(!kvp.Value.All(string.IsNullOrWhiteSpace)) { result += ":

"; } foreach(var interval in kvp.Value) { result += $"{interval}
"; } } return result; } [Authorize] public string HasSelectedAppointment() { return JsonConvert.SerializeObject(Model?.SelectedAppointment != null); } [Authorize] [HttpPost] public ActionResult ChangeSchedulerView(FormCollection formCollection) { if(Model is null) { TempData[TempDataConstants.DoLogoutKey] = true; return Logout(); } var selectedSchedulerView = formCollection["SelectedSchedulerView"]; Model.SelectedSchedulerView = selectedSchedulerView; return RedirectToActionPermanent("Scheduler"); } [Authorize] [HttpPost] public ActionResult FindFreeIntervals(FormCollection formCollection) { if(Model is null) { TempData[TempDataConstants.DoLogoutKey] = true; return Logout(); } var durationString = formCollection["Duration"]; var intervalStartDateString = formCollection["IntervalStart"].Substring(0, 10); var intervalStartTimeString = formCollection["IntervalStartTime"]; var intervalEndDateString = formCollection["IntervalEnd"].Substring(0, 10); var intervalEndTimeString = formCollection["IntervalEndTime"]; if(int.TryParse(durationString, out var intervalDuration) && DateTime.TryParse($"{intervalStartDateString} {intervalStartTimeString}", out var intervalStart) && DateTime.TryParse($"{intervalEndDateString} {intervalEndTimeString}", out var intervalEnd) && Model.Employee.EmployeeOid.HasValue) { var customerOids = Model.SelectedCustomersForIntervalFinder.Select(customer => customer.CustomerOid).ToList(); var employeeOids = Model.SelectedEmployeesForIntervalFinder.Select(employee => employee.EmployeeOid).ToList(); var resourceOids = Model.SelectedResourcesForIntervalFinder.Where(resource => resource.ResourceOid.HasValue).Select(r => r.ResourceOid.Value).ToList(); Model.FreeIntervals = KalenderService.FindAppointmentsInRangeForIntervalFinder(intervalDuration, intervalStart, intervalEnd, resourceOids, customerOids, employeeOids, Model.Employee.EmployeeOid.Value); Model.IntervalStartDate = intervalStart; Model.IntervalEndDate = intervalEnd; Model.IntervalDuration = intervalDuration; } return RedirectToActionPermanent("Scheduler"); } [Authorize] public string SelectEmployeesForIntervalFinder(string oidString) { if (Model is null) { Logout(); return LeerzeichenFuerGetMethoden; } var employeeOids = ConvertOidStringToList(oidString); Model.SelectedEmployeesForIntervalFinder = Model.AllEmployees.Where(employee => employeeOids.Contains(employee.EmployeeOid)).ToList(); return JsonConvert.SerializeObject(Model.SelectedEmployeesForIntervalFinder.OrderBy(o => o.DetailDescription)); } [Authorize] public string SelectCustomersForIntervalFinder(string oidString) { if (Model is null) { Logout(); return LeerzeichenFuerGetMethoden; } var customerOids = ConvertOidStringToList(oidString); Model.SelectedCustomersForIntervalFinder = Model.AllCustomers.Where(customer => customerOids.Contains(customer.CustomerOid)).ToList(); return JsonConvert.SerializeObject(Model.SelectedCustomersForIntervalFinder.OrderBy(o => o.LastNameFirstName)); } [Authorize] public string SelectResourcesForIntervalFinder(string resourceOids) { if(Model is null) { Logout(); return LeerzeichenFuerGetMethoden; } var resourceOidList = ConvertOidStringToList(resourceOids); var list = new List(); Model.ResourceCategories2Resources.Values.DoForEach(l => l.DoForEach(s => list.AddIfNotIn(s))); Model.SelectedResourcesForIntervalFinder = list.Where(resource => resource.ResourceOid.HasValue && resourceOidList.Contains(resource.ResourceOid.Value)).ToList(); return JsonConvert.SerializeObject(Model.SelectedResourcesForIntervalFinder); } [Authorize] [HttpPost] public ActionResult SetIsInIntervalFinderMode(FormCollection formCollection) { if(Model is null) { TempData[TempDataConstants.DoLogoutKey] = true; return Logout(); } var newValue = !Model.IsInIntervalFinderMode; Model.IsInIntervalFinderMode = newValue; if(!newValue) { Model.SelectedEmployeesForIntervalFinder.Clear(); Model.SelectedCustomersForIntervalFinder.Clear(); Model.SelectedResourcesForIntervalFinder.Clear(); } return RedirectToActionPermanent("Scheduler"); } [Authorize] [HttpPost] public ActionResult SelectIntervalForForm(FormCollection formCollection) { if(Model is null) { TempData[TempDataConstants.DoLogoutKey] = true; return Logout(); } var startStr = formCollection["startDate"]; var endStr = formCollection["endDate"]; if(DateTime.TryParse(startStr, out var startDate) && DateTime.TryParse(endStr, out var endDate)) { Model.IsInIntervalFinderMode = false; var employees2Appointment = new List(); Model.SelectedEmployeesForIntervalFinder.DoForEach(employee => { employees2Appointment.Add(new Employee2SchedulerAppointmentDC { Employee = employee }); }); Model.SelectedAppointment = new SchedulerAppointmentDC() { ActivationType = ActivationTypeId.Active, IsTask = false, IsPrivate = false, Originator = MobileSessionFacade.LoggedInCompactEmployee, StartDate = startDate, EndDate = endDate }; Model.SelectedCustomers = Model.SelectedCustomersForIntervalFinder.Clone(); Model.SelectedEmployees = Model.SelectedEmployeesForIntervalFinder.Clone(); Model.SelectedResources = Model.SelectedResourcesForIntervalFinder.Clone(); Model.SelectedCustomersForIntervalFinder.Clear(); Model.SelectedEmployeesForIntervalFinder.Clear(); Model.SelectedResourcesForIntervalFinder.Clear(); Model.IntervalStartDate = null; Model.IntervalEndDate = null; } return RedirectToActionPermanent("Scheduler"); } [Authorize] public string ResetIntervalFinder() { if(Model is null) { return LeerzeichenFuerGetMethoden; } Model.SelectedCustomersForIntervalFinder.Clear(); Model.SelectedEmployeesForIntervalFinder.Clear(); Model.SelectedResourcesForIntervalFinder.Clear(); return LeerzeichenFuerGetMethoden; } [Authorize] public ActionResult FetchAppointments() { if(Model is null) { TempData[TempDataConstants.DoLogoutKey] = true; return PartialView("OneDaySchedulerPartial"); } LoadAppointmentsForDate(); return PartialView("OneDaySchedulerPartial", Model); } [Authorize] public string SelectResourcesForAppointmentFiltering(string resourceOids) { if(Model is null) { Logout(); return LeerzeichenFuerGetMethoden; } var oidList = ConvertOidStringToList(resourceOids); var list = new List(); Model.ResourceCategories2Resources.Values.DoForEach(l => l.DoForEach(s => list.AddIfNotIn(s))); Model.SelectedResourcesForFiltering = list.Where(resource => resource.ResourceOid.HasValue && oidList.Contains(resource.ResourceOid.Value)).ToList(); return JsonConvert.SerializeObject(Model.SelectedResourcesForFiltering); } [Authorize] public string SelectEmployeesForAppointmentFiltering(string oidString) { if(Model is null) { Logout(); return LeerzeichenFuerGetMethoden; } var oidList = ConvertOidStringToList(oidString); Model.SelectedEmployeesForFiltering = Model.AllEmployees.Where(employee => oidList.Contains(employee.EmployeeOid)).ToList(); return Model.SelectedEmployeesForFiltering.Count.ToString(); } [Authorize] public string SelectCustomersForAppointmentFiltering(string oidString) { if(Model is null) { Logout(); return LeerzeichenFuerGetMethoden; } var oidList = ConvertOidStringToList(oidString); Model.SelectedCustomersForFiltering = Model.AllCustomers.Where(customer => oidList.Contains(customer.CustomerOid)).ToList(); return Model.SelectedCustomersForFiltering.Count.ToString(); } [Authorize] public ActionResult FetchSelectedEmployeesForPopup() { if(Model is null) { TempData[TempDataConstants.DoLogoutKey] = true; } return PartialView("EmployeeForFilteringPartial", Model); } [Authorize] public ActionResult FetchEmployeeFilteringModalBody() { if(Model is null) { TempData[TempDataConstants.DoLogoutKey] = true; } return PartialView("EmployeeFilteringModalContentPartial", Model); } [Authorize] public string SelectTeamForFiltering(string teamOidString) { if(Model?.Employee?.EmployeeOid is null) { Logout(); return LeerzeichenFuerGetMethoden; } if(long.TryParse(teamOidString, out var teamOid)) { var team = EmployeeService.FindTeamByOid(teamOid, Model.Employee.EmployeeOid.Value); if(!(team is null)) { Model.SelectedEmployeesForFiltering.AddRangeIfElementsNotIn(team.Member); } } return LeerzeichenFuerGetMethoden; } [Authorize] public string SelectTeamForAppointment(string teamOidString) { if(Model?.Employee?.EmployeeOid is null) { Logout(); return LeerzeichenFuerGetMethoden; } var teamMemberOids = new List(); if(long.TryParse(teamOidString, out var teamOid)) { var team = EmployeeService.FindTeamByOid(teamOid, Model.Employee.EmployeeOid.Value); if(!(team is null)) { Model.SelectedEmployees.AddRangeIfElementsNotIn(team.Member); teamMemberOids.AddRangeIfElementsNotIn(team.Member.Select(member => member.EmployeeOid)); } } return JsonConvert.SerializeObject(teamMemberOids); } [Authorize] public ActionResult FetchCustomersForFiltering() { if(Model is null) { TempData[TempDataConstants.DoLogoutKey] = true; } return PartialView("CustomerFilterSelectionPartial", Model); } [Authorize] public ActionResult FetchCustomerFilteringModalBody() { if(Model is null) { TempData[TempDataConstants.DoLogoutKey] = true; } return PartialView("CustomerFilteringModalContentPartial", Model); } [Authorize] public string SetShouldLoadTasks(bool isChecked) { try { if(Model is null) { Logout(); return LeerzeichenFuerGetMethoden; } Model.ShouldLoadTasks = isChecked; return LeerzeichenFuerGetMethoden; } catch(Exception exception) { Log.Error(exception.Message, exception); } return LeerzeichenFuerGetMethoden; } [Authorize] public string DeleteAppointment(string appointmentIdentifier, bool deleteSeries) { if(Model?.Employee?.EmployeeOid is null) { Logout(); return LeerzeichenFuerGetMethoden; } if(!Guid.TryParse(appointmentIdentifier, out var identifier)) { return LeerzeichenFuerGetMethoden; } var schedulerAppointment = Model.AppointmentListItems.FirstOrDefault(app => app.Identifier.Equals(identifier))?.SchedulerAppointment; if(schedulerAppointment is null) { return LeerzeichenFuerGetMethoden; } if(schedulerAppointment.SchedulerAppointmentOid is null && !(schedulerAppointment.RecurrenceInfo is null)) { var recurrenceInfo = new RecurrenceInfo(); recurrenceInfo.FromXml(schedulerAppointment.RecurrenceInfo); var pattern = StaticAppointmentFactory.CreateAppointment(AppointmentType.Pattern); pattern.RecurrenceInfo.FromXml(schedulerAppointment.RecurrenceInfo); pattern.Start = pattern.RecurrenceInfo.Start; pattern.End = pattern.RecurrenceInfo.End; var exception = pattern.CreateException(AppointmentType.DeletedOccurrence, schedulerAppointment.RecurrenceIndex); var recurrenceId = exception.RecurrenceInfo.Id.ToString(); schedulerAppointment = deleteSeries ? KalenderService.FindRootAppointmentByRecurrenceId(recurrenceId) : CloneAppointment(schedulerAppointment, $"", (int)exception.Type); } if(schedulerAppointment is null) { return LeerzeichenFuerGetMethoden; } var teamMemberCustomerOids = EmployeeService.LoadTeamsRelatedCustomerOids(Model.Employee.EmployeeOid.Value); var customerList = schedulerAppointment.CustomerList; var employeeList = schedulerAppointment.EmployeeList; var resourceList = schedulerAppointment.ResourceList; var originator = schedulerAppointment.Originator; var isNew = schedulerAppointment.SchedulerAppointmentOid is null; var loggedOnUser = MobileSessionFacade.LoggedInUserDC; var isAllowedToDelete = BS.Shared.Core.Utils.CheckSchedulerRights(customerList, resourceList, employeeList, originator, isNew, SchedulerRightsCheckType.Edit, loggedOnUser, teamMemberCustomerOids); if(isAllowedToDelete) { if(schedulerAppointment.SchedulerAppointmentOid.HasValue && schedulerAppointment.NewSchedulerAppointmentVersion.HasValue) { var oid2Version = new Dictionary { { schedulerAppointment.SchedulerAppointmentOid.Value, schedulerAppointment.NewSchedulerAppointmentVersion.Value } }; KalenderService.DeactivateSchedulerAppointments(oid2Version); } // DeletedOccurrence if(schedulerAppointment.Type == 4 && !deleteSeries) { KalenderService.InsertSchedulerAppointments(new List { schedulerAppointment }); } } return LeerzeichenFuerGetMethoden; } [Authorize] public static SchedulerAppointmentDC CloneAppointment(SchedulerAppointmentDC schedulerAppointment, string recurrenceInfo, int type) { return new SchedulerAppointmentDC { StartDate = schedulerAppointment.StartDate, EndDate = schedulerAppointment.EndDate, ServiceRecordList = schedulerAppointment.ServiceRecordList ?? new List(), EmployeeList = schedulerAppointment.EmployeeList ?? new List(), ActivationType = ActivationTypeId.Active, AllDay = schedulerAppointment.AllDay, CanBeEdited = schedulerAppointment.CanBeEdited, CompletedDate = schedulerAppointment.CompletedDate, CompletedNotice = schedulerAppointment.CompletedNotice, CompletedUser = schedulerAppointment.CompletedUser, CustomerList = schedulerAppointment.CustomerList ?? new List(), Description = schedulerAppointment.Description?.RemoveUppercaseEsszett(), DueDate = schedulerAppointment.DueDate, FormerBookingSequenceOid = schedulerAppointment.FormerBookingSequenceOid, FormerTaskOid = schedulerAppointment.FormerTaskOid, HasServiceRecordEntry = schedulerAppointment.HasServiceRecordEntry, IsPrivate = schedulerAppointment.IsPrivate, IsTask = schedulerAppointment.IsTask, IsTeilnahmeBestaetigung = schedulerAppointment.IsTeilnahmeBestaetigung, LabelKey = schedulerAppointment.LabelKey, Location = schedulerAppointment.Location?.RemoveUppercaseEsszett(), Originator = schedulerAppointment.Originator, RecurrenceInfo = recurrenceInfo, ReminderInfo = schedulerAppointment.ReminderInfo, ResourceList = schedulerAppointment.ResourceList ?? new List(), Status = schedulerAppointment.Status, Subject = schedulerAppointment.Subject?.RemoveUppercaseEsszett() ?? string.Empty, SupportConceptList = schedulerAppointment.SupportConceptList ?? new List(), TaskDescription = schedulerAppointment.TaskDescription, Type = type }; } [Authorize] public string SelectTeamForIntervalFinder(string teamOidString) { if(Model?.Employee?.EmployeeOid is null) { Logout(); return LeerzeichenFuerGetMethoden; } if(long.TryParse(teamOidString, out var teamOid)) { var team = EmployeeService.FindTeamByOid(teamOid, Model.Employee.EmployeeOid.Value); if(!(team is null)) { var memberOids = team.Member.Select(member => member.EmployeeOid).ToList(); return JsonConvert.SerializeObject(memberOids); } } return LeerzeichenFuerGetMethoden; } [Authorize] [HttpPost] public ActionResult TransformAppointmentToServiceRecord(FormCollection formCollection) { if(Model is null) { TempData[TempDataConstants.DoLogoutKey] = true; return Logout(); } if(!Guid.TryParse(formCollection[FormCollectionConstants.AppointmentIdInputKey], out var identifier)) { return RedirectToActionPermanent("PrepareServiceRecordInsert", "Main"); } var appointmentListItem = Model.AppointmentListItems.FirstOrDefault(f => f.Identifier.Equals(identifier)); if(appointmentListItem is null) { return RedirectToActionPermanent("PrepareServiceRecordInsert", "Main"); } var appointment = appointmentListItem.SchedulerAppointment; var employeeOids = appointment.EmployeeList.Select(employee2Appointment => employee2Appointment.Employee.EmployeeOid).ToList(); if(employeeOids.Count == 0) { employeeOids.Add(appointment.Originator.EmployeeOid); } TempData[TempDataConstants.AppointmentListItemKey] = appointmentListItem; return RedirectToActionPermanent("PrepareServiceRecordInsert", "Main"); } } }