Files
BeWoPlaner/BeWoPlanerMobil/Controllers/SchedulerController.cs
Lyndon Jetten 3ca4ec5323 Das Gruppenbuchungsformular hat jetzt die Summe der Ziele aller ausgewählten Hilfepläne und die Schnittmenge deren Leistungen und Kategorien.
Das Mehrfachbuchungsformular hat ebenfalls die Schnittmenge der Leistungen und Kategorien von den ausgewählten Hilfeplänen.

Das Caching ist wieder aktiviert. Und lädt pro Post-Aufruf nur noch einmal 13 MB und danach nur noch 300 kb herunter.

Überall konsequent geprüft, ob das Model nicht null ist und falls dem so ist, wird ausgeloggt, damit es zu keinen Fehlern mehr kommt.
2024-06-26 12:29:22 +02:00

1209 lines
49 KiB
C#

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)
{
var allResources = KalenderService.GetAllResources().OrderBy(r => r.Name).ToList();
var categories2Resources = new Dictionary<ValueListEntryDC, List<ResourceDC>>();
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<CompactEmployeeDC>();
}
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<long>();
var selectedEmployees = Model.SelectedEmployeesForFiltering?.Select(s => s.EmployeeOid).ToList() ?? new List<long>();
var selectedResources = Model.SelectedResourcesForFiltering?.Where(w => w.ResourceOid.HasValue).Select(s => s.ResourceOid.Value).ToList() ?? new List<long>();
var appointments = KalenderService.LoadFilteredAppointmentsMitAufgaben(AbstractModel.HasRightToViewEmployeeAppointments, Model.Employee.EmployeeOid.Value, start.Date, end, selectedEmployees, selectedCustomers, selectedResources, false, false, false, false, true, true).ToList();
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))
{
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 = holySweetFlyingFuck.Where(w => w.IsTask == Model.ShouldLoadTasks).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<SchedulerAppointmentDC> CalculateRecurrences(IEnumerable<SchedulerAppointmentDC> appointments, DateTime start, DateTime end, IReadOnlyCollection<RecurrenceInformation> changedOccurrences, IReadOnlyCollection<RecurrenceInformation> deletedOccurrences)
{
var result = new List<SchedulerAppointmentDC>();
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<Employee2SchedulerAppointmentDC>();
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<ResourceDC>();
appointmentToInsert.SupportConceptList = isNew ? new List<CompactSupportConceptDC>() : appointmentToInsert.SupportConceptList;
appointmentToInsert.ServiceRecordList = isNew ? new List<ServiceRecordDC>() : 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<SchedulerAppointmentDC> {appointmentToInsert});
}
else
{
KalenderService.InsertSchedulerAppointments(new List<SchedulerAppointmentDC> {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<ResourceDC>();
Model.SelectedEmployees = Model.SelectedAppointment?.EmployeeList.Select(e2a => e2a.Employee).ToList() ?? new List<CompactEmployeeDC>();
Model.SelectedCustomers = Model.SelectedAppointment?.CustomerList ?? new List<CompactCustomerDC>();
}
return RedirectToActionPermanent("Scheduler");
}
[Authorize]
public JsonResult ResetSelectedAppointment()
{
if (Model != null)
{
Model.SelectedAppointment = null;
Model.SelectedResources.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<long>();
var employeeOidList = Model.SelectedAppointment?.EmployeeList?.Select(employee2Appointment => employee2Appointment.Employee.EmployeeOid).ToList() ?? new List<long>();
var resourceOidList = Model.SelectedResources.Where(resource => resource.ResourceOid.HasValue).Select(resource => resource.ResourceOid.Value).ToList() ?? new List<long>();
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<ResourceDC>();
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 += ":<br /><br />";
}
foreach(var interval in kvp.Value)
{
result += $"{interval}<br />";
}
}
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 d = formCollection["Duration"];
var s = formCollection["IntervalStart"].Substring(0, 10);
var st = formCollection["IntervalStartTime"];
var e = formCollection["IntervalEnd"].Substring(0, 10);
var et = formCollection["IntervalEndTime"];
if (int.TryParse(d, out var duration) && DateTime.TryParse($"{s} {st}", out var start) && DateTime.TryParse($"{e} {et}", out var end) && Model.Employee.EmployeeOid.HasValue)
{
var customerOids = Model.SelectedCustomersForIntervalFinder.Select(c => c.CustomerOid).ToList();
var employeeOids = Model.SelectedEmployeesForIntervalFinder.Select(m => m.EmployeeOid).ToList();
var resourceOids = Model.SelectedResourcesForIntervalFinder.Where(w => w.ResourceOid.HasValue).Select(r => r.ResourceOid.Value).ToList();
Model.FreeIntervals = KalenderService.FindAppointmentsInRange(duration, start, end, resourceOids, customerOids, employeeOids, Model.Employee.EmployeeOid.Value);
Model.IntervalStartDate = start;
Model.IntervalEndDate = end;
Model.IntervalDuration = duration;
}
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<ResourceDC>();
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<Employee2SchedulerAppointmentDC>();
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<ResourceDC>();
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<long>();
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, $"<RecurrenceInfo Id=\"{recurrenceId}\" Index=\"{schedulerAppointment.RecurrenceIndex}\" />", (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<long, long> { { schedulerAppointment.SchedulerAppointmentOid.Value, schedulerAppointment.NewSchedulerAppointmentVersion.Value } };
KalenderService.DeactivateSchedulerAppointments(oid2Version);
}
// DeletedOccurrence
if(schedulerAppointment.Type == 4 && !deleteSeries)
{
KalenderService.InsertSchedulerAppointments(new List<SchedulerAppointmentDC> { 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<ServiceRecordDC>(),
EmployeeList = schedulerAppointment.EmployeeList ?? new List<Employee2SchedulerAppointmentDC>(),
ActivationType = ActivationTypeId.Active,
AllDay = schedulerAppointment.AllDay,
CanBeEdited = schedulerAppointment.CanBeEdited,
CompletedDate = schedulerAppointment.CompletedDate,
CompletedNotice = schedulerAppointment.CompletedNotice,
CompletedUser = schedulerAppointment.CompletedUser,
CustomerList = schedulerAppointment.CustomerList ?? new List<CompactCustomerDC>(),
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<ResourceDC>(),
Status = schedulerAppointment.Status,
Subject = schedulerAppointment.Subject?.RemoveUppercaseEsszett() ?? string.Empty,
SupportConceptList = schedulerAppointment.SupportConceptList ?? new List<CompactSupportConceptDC>(),
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");
}
}
}