using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Web.Mvc; using BeWoPlanerMobil.Models; using BeWoPlanerMobil.Service; using BS.Shared.DataContracts; using BS.Shared.DataContracts.Compact; using BS.Shared.Extensions; using DevExpress.XtraScheduler; using DevExpress.XtraScheduler.Compatibility; using static BeWoPlanerMobil.Util.MobileUtils; namespace BeWoPlanerMobil.Controllers { public class SchedulerController : AbstractBaseController { private const string SchedulerModelSessionKey = "SchedulerModel"; private SchedulerModel _Model; public SchedulerModel Model { get { if (!MobileSessionFacade.IsUserLoggedIn()) { RedirectToActionPermanent("Index", "Login"); return null; } if (((SchedulerModel) Session[SchedulerModelSessionKey])?.Employee == null) { _Model = new SchedulerModel { Employee = MobileSessionFacade.LoggedInEmployee }; Session[SchedulerModelSessionKey] = _Model; } else { _Model = (SchedulerModel) Session[SchedulerModelSessionKey]; } return _Model; } } [Authorize] public ActionResult Scheduler() { if (!MobileSessionFacade.IsUserLoggedIn() || Request.Browser.Browser.Equals("InternetExplorer") || !AbstractModel.IsAllowedToSeeScheduler) { return RedirectToActionPermanent("Index", "Login"); } LoadAppointmentsForDate(); return View(Model); } private void LoadAppointmentsForDate() { if(Model?.Employee.EmployeeOid == null) { return; } var date = Model.SelectedDate; var appointments = KalenderService.LoadFilteredAppointmentsMitAufgaben(AbstractModel.HasRightToSeeAllEmployeeAppointments, Model.Employee.EmployeeOid.Value, date.Date, date.Date.AddDays(1), new List(), new List(), new List(), false, false, false, false, true, true).ToList(); var tasks = appointments.Where(w => w.IsTask).ToList(); var zuErledigen = tasks.Where(t => t.DueDate.HasValue && t.DueDate.Value.Date >= DateTime.Today); // Nur eigene Kliententermine ansehen if(!AbstractModel.HasRightToSeeAllCustomerAppointments) { appointments = appointments.Where(a => a.CustomerList.All(c => MobileSessionFacade.LoggedInEmployee.RelatedCustomers.Any(rc => rc.Customer.Equals(c)))).ToList(); } if(!AbstractModel.HasRightToSeeAllResourceAppointments) { appointments = appointments.Where(a => a.ResourceList.Count == 0).ToList(); } if(!AbstractModel.IsAllowedToSeeCustomers) { appointments = appointments.Where(a => a.CustomerList.Count == 0).ToList(); } var holySweetFlyingFuck = appointments.Where(w => w.StartDate.HasValue && w.EndDate.HasValue && ((date.InBetween(w.StartDate.Value, w.EndDate.Value, false) || date.CompareShortDates(w.StartDate.Value)) && w.RecurrenceInfo == null || w.RecurrenceInfo != null && (w.Type == 3 || w.Type == 4) && (date.InBetween(w.StartDate.Value, w.EndDate.Value, false) || date.CompareShortDates(w.StartDate.Value)))).ToList(); var deletedOccurrences = holySweetFlyingFuck.Where(w => w.Type == 4).Select(s => GetOccurrenceId(s.RecurrenceInfo)).ToList(); var changedOccurrences = holySweetFlyingFuck.Where(w => w.Type == 3).Select(s => GetOccurrenceId(s.RecurrenceInfo)).ToList(); holySweetFlyingFuck = holySweetFlyingFuck.Where(w => w.Type != 4).ToList(); foreach(var appointment in appointments) { if(appointment.RecurrenceInfo != null && appointment.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 interval = new TimeInterval(date, date.AddDays(1)); var occurrences = occurrenceCalculator.CalcOccurrences(interval, pattern); if(occurrences.Count > 0) { foreach(var termin in occurrences.GetAppointments(interval)) { var index = termin.RecurrenceIndex; var duration = (appointment.EndDate.Value - appointment.StartDate.Value).TotalMinutes; if(!date.InBetween(termin.Start.GetShortDateTime(), termin.Start.AddMinutes(duration), true) || changedOccurrences.Any(a => a.PatternId.Equals(patternId) && a.Index == index) || deletedOccurrences.Any(a => a.PatternId.Equals(patternId) && a.Index == index)) { continue; } holySweetFlyingFuck.AddIfNotIn(new SchedulerAppointmentDC { AllDay = appointment.AllDay, CustomerList = appointment.CustomerList, Description = appointment.Description, EmployeeList = appointment.EmployeeList, EndDate = termin.Start.AddMinutes(duration), FormerBookingSequenceOid = appointment.FormerBookingSequenceOid, IsPrivate = appointment.IsPrivate, LabelId = appointment.LabelId, Location = appointment.Location, Originator = appointment.Originator, RecurrenceInfo = termin.RecurrenceInfo.ToXml(), ReminderInfo = appointment.ReminderInfo, ResourceList = appointment.ResourceList, StartDate = termin.Start, Subject = appointment.Subject ?? "", Type = appointment.Type }); } } } } holySweetFlyingFuck.AddRange(zuErledigen); Model.Appointments = holySweetFlyingFuck; } [Authorize] [HttpPost] public ActionResult InsertOrUpdateAppointment(FormCollection formCollection) { try { if (Model == null) { RedirectToActionPermanent("Index", "Login"); } var rawStartDate = formCollection["StartDate"]; var rawEndDate = formCollection["EndDate"]; var rawStartTime = formCollection["StartTime"]; var rawEndTime = formCollection["EndTime"]; var subject = formCollection["Subject"]; var location = formCollection["Location"]; var notice = formCollection["Notice"]; var isSuccessfulStartDate = DateTime.TryParseExact(rawStartDate, "dd.MM.yyyy", null, DateTimeStyles.None, out var startDate); var isSuccessfulStartTime = DateTime.TryParseExact(rawStartTime, "HH:mm", null, DateTimeStyles.None, out var startTime); var isSuccessfulEndDate = DateTime.TryParseExact(rawEndDate, "dd.MM.yyyy", null, DateTimeStyles.None, out var endDate); var isSuccessfulEndTime = DateTime.TryParseExact(rawEndTime, "HH:mm", null, DateTimeStyles.None, out var endTime); if (isSuccessfulStartDate && isSuccessfulStartTime && isSuccessfulEndDate && isSuccessfulEndTime) { startDate = startDate.MergeDatesByDate(startTime); endDate = endDate.MergeDatesByDate(endTime); var appointmentToInsert = Model.SelectedAppointment ?? new SchedulerAppointmentDC(); appointmentToInsert.EmployeeList = new List(); appointmentToInsert.CustomerList = new List(); appointmentToInsert.ResourceList = new List(); appointmentToInsert.SupportConceptList = new List(); appointmentToInsert.EndDate = endDate; appointmentToInsert.StartDate = startDate; appointmentToInsert.Subject = subject; appointmentToInsert.Description = notice; appointmentToInsert.Originator = MobileSessionFacade.LoggedInCompactEmployee; appointmentToInsert.Location = location; if (appointmentToInsert.SchedulerAppointmentOid.HasValue) { KalenderService.UpdateSchedulerAppointments(new List {appointmentToInsert}); } else { KalenderService.InsertSchedulerAppointments(new List {appointmentToInsert}); } } } catch (Exception exception) { Log.Error(exception.Message, exception); } finally { if (Model != null) { Model.SelectedAppointment = null; } } return RedirectToActionPermanent("Scheduler"); } [Authorize] [HttpPost] public ActionResult NavigateToPreviousDate() { if (Model == null) { RedirectToActionPermanent("Index", "Login"); } Model.SelectedDate = Model.SelectedDate.AddDays(-1); if(Model != null) { Model.SelectedAppointment = null; } return RedirectToActionPermanent("Scheduler"); } [Authorize] [HttpPost] public ActionResult NavigateToNextDate() { if(Model == null) { RedirectToActionPermanent("Index", "Login"); } Model.SelectedDate = Model.SelectedDate.AddDays(1); if(Model != null) { Model.SelectedAppointment = null; } return RedirectToActionPermanent("Scheduler"); } [Authorize] [HttpPost] public ActionResult SelectSchedulerDate(FormCollection formCollection) { if (Model == null) { RedirectToActionPermanent("Index", "Login"); } var rawSchedulerDate = formCollection["SchedulerDate"]; var schedulerDate = DateTime.ParseExact(rawSchedulerDate, "dd.MM.yyyy", null); Model.SelectedDate = schedulerDate; if(Model != null) { Model.SelectedAppointment = null; } return RedirectToActionPermanent("Scheduler"); } [Authorize] [HttpPost] public ActionResult SelectAppointmentToEdit(FormCollection formCollection) { var rawOid = formCollection["scheduler-oid-holder"]; var isSuccessful = long.TryParse(rawOid, out var appointmentOid); if (isSuccessful) { Model.SelectedAppointment = Model.Appointments.FirstOrDefault(app => app.SchedulerAppointmentOid.HasValue && app.SchedulerAppointmentOid.Value == appointmentOid); } return RedirectToActionPermanent("Scheduler"); } [Authorize] public JsonResult ResetSelectedAppointment() { if (Model != null) { Model.SelectedAppointment = null; } return Json(null, JsonRequestBehavior.AllowGet); } [Authorize] public JsonResult CheckForOverlappingAppointments(string startDateRaw, string endDateRaw, string startTimeRaw, string endTimeRaw) { if (Model == null) { 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 customerList = Model.SelectedAppointment?.CustomerList?.Select(customer => customer.CustomerOid).ToList() ?? new List(); var employeeList = Model.SelectedAppointment?.EmployeeList?.Select(employee2Appointment => employee2Appointment.Employee.EmployeeOid).ToList() ?? new List(); var resourceList = Model.SelectedAppointment?.ResourceList?.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, employeeList, customerList, resourceList, originator.EmployeeOid, oid, recurrenceId, recurrenceIndex); } return Json(isOverlapping, JsonRequestBehavior.AllowGet); } } }