Der Intervallfinder im alten Kalendermodul funktoniert wieder korrekt.

This commit is contained in:
2026-04-15 11:29:51 +02:00
parent acdb064f4a
commit 9abba8ca6b
22 changed files with 630 additions and 310 deletions

View File

@@ -347,6 +347,7 @@
<Compile Include="Models\ReportModel.cs" />
<Compile Include="Models\ReportViewerModel.cs" />
<Compile Include="Models\SchedulerModel.cs" />
<Compile Include="Util\Constants\DevExpressSchedulerConstants.cs" />
<Compile Include="Util\Constants\ViewDataConstants.cs" />
<Compile Include="Util\DcToMokMapper.cs" />
<Compile Include="Util\ISignable.cs" />
@@ -719,6 +720,7 @@
<Content Include="Views\DevExpressScheduler\AptFltEmployeePopupListPartial.cshtml" />
<Content Include="Views\DevExpressScheduler\AptFltCustomerPopupListPartial.cshtml" />
<Content Include="Views\DevExpressScheduler\AptFltResourcePopupListPartial.cshtml" />
<Content Include="Views\DevExpressScheduler\SchedulerNotificationPartial.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="packages.config" />

View File

@@ -1,4 +1,11 @@
@charset "UTF-8";
a.disabled {
pointer-events: none;
cursor: default;
opacity: 0.5;
color: gray;
}
textarea {
min-height: 150px !important;
}

File diff suppressed because one or more lines are too long

View File

@@ -24,6 +24,13 @@ $theme-colors:
"bewo-report": #995E3B
);
a.disabled {
pointer-events: none;
cursor: default;
opacity: 0.5;
color: gray;
}
textarea {
min-height: 150px !important;
}

View File

@@ -99,8 +99,15 @@ namespace BeWoPlanerMobil.Controllers
return;
}
var x = Model.SelectedEmployeeOidsForFiltering;
var userSettings = LoggedInUser?.Settings.FirstOrDefault(f => f.Type.Equals(SettingsType.ApplicationSettings))?.Value;
Model.ShowOnlyMyOwnAppointments = UserSettingsUtils.GetSettingValueAsBool(userSettings, SettingsKeys.ZeigeNurMeineTermine);
if(Model.ShowOnlyMyOwnAppointments && LoggedInUser != null)
{
Model.SelectedEmployeeOidsForFiltering = new List<long> { LoggedInUser.Employee.EmployeeOid };
}
Model.PossibleEmployees = EmployeeService.GetAllAuthorizedCompactEmployees();
Model.PossibleCustomers = CustomerService.GetAllAuthorizedCompactCustomers();
Model.PossibleResources = KalenderService.GetAllResources();
@@ -175,7 +182,7 @@ namespace BeWoPlanerMobil.Controllers
Model.ShowOnlyEmployees,
Model.ShowOnlyCustomers,
Model.ShowOnlyResources,
Model.ShowOnlyMyOwnAppointments,
Model.ShowOnlyPrivateAppointments,
Model.ShowOnlyMyOwnAppointments,
Model.ShowTasks
);
@@ -186,13 +193,33 @@ namespace BeWoPlanerMobil.Controllers
var customerAbsenceTimes = KalenderService.GetAllActiveCustomersAbsenceTimesInInterval(intervalStart, intervalEnd, employeeOid, selectedCustomerOids);
var employeeAbsenceTimes = KalenderService.GetAllActiveEmployeeAbsenceTimesInInterval(intervalStart, intervalEnd, employeeOid, selectedEmployeeOids);
var allAbsenceTimes = new List<AbsenceTimeDC>();
allAbsenceTimes.AddRange(customerAbsenceTimes);
allAbsenceTimes.AddRange(employeeAbsenceTimes);
if(Model.ShowAbsenceTimes)
{
var allAbsenceTimes = new List<AbsenceTimeDC>();
allAbsenceTimes.AddRange(customerAbsenceTimes);
allAbsenceTimes.AddRange(employeeAbsenceTimes);
appointments.AddRange(ConvertAbsenceTimesToAppointments(allAbsenceTimes, Model.PossibleCustomers, Model.PossibleEmployees));
appointments.AddRange(ConvertAbsenceTimesToAppointments(allAbsenceTimes, Model.PossibleCustomers, Model.PossibleEmployees));
}
Model.Appointments = appointments;
LoadNotificationCount();
}
[Authorize]
public ActionResult GetNotifications()
{
LoadNotificationCount();
return PartialView("SchedulerNotificationPartial", Model);
}
private int LoadNotificationCount()
{
Model.OpenAppointments = KalenderService.GetAllOpenAppointmentsForEmployee(LoggedInUser.Employee.EmployeeOid);
return Model.NotificationCount;
}
private List<SchedulerAppointmentDC> ConvertAbsenceTimesToAppointments(List<AbsenceTimeDC> absenceTimes, List<CompactCustomerDC> allCustomers, List<CompactEmployeeDC> allEmployees)
@@ -247,7 +274,8 @@ namespace BeWoPlanerMobil.Controllers
FormerAbsenceTimeOid = absenceTime.AbsenceTimeOid,
Originator = originator,
Subject = subject,
Krankheitsmeldung = absenceTime.KrankheitsMeldung
Krankheitsmeldung = absenceTime.KrankheitsMeldung,
IsAbsenceTime = true
};
if(false == customer is null && employee is null)
@@ -412,50 +440,69 @@ namespace BeWoPlanerMobil.Controllers
return LeerzeichenFuerGetMethoden;
}
/// <summary>
/// Hier laufen Custom-Aufrufe drüber ab. Im JavaScript mit scheduler.PerformCallback(...) aufrufen.
/// </summary>
/// <param name="apptID">Etwaige Id des Termin-Objekts</param>
/// <param name="actionId">Die Id der auszuführenden Methode</param>
/// <param name="args">Etwaige Parameter für die auszuführende Methode</param>
/// <returns>Entweder das Scheduler-Partial oder ein anderer Seitenaufruf.</returns>
[Authorize]
public ActionResult CustomCallbackAction(string apptID, string actionId, string[] args)
{
if(actionId == "ToServiceRecord")
switch(actionId)
{
long? selectedAppointmentOid;
var isRecurring = false;
// Serientermin
if(apptID.Contains("_"))
{
var splitApptId = apptID.Split('_');
selectedAppointmentOid = long.Parse(splitApptId[0]);
var recurrenceIndex = int.Parse(splitApptId[1]);
TempData[TempDataConstants.AppointmentRecurrenceIndexKey] = recurrenceIndex;
}
else
{
selectedAppointmentOid = long.Parse(apptID);
}
var appointment = selectedAppointmentOid.HasValue ? Model.GetAppointmentByOid(selectedAppointmentOid.Value) : null;
TempData[TempDataConstants.AppointmentOidKey] = appointment?.SchedulerAppointmentOid;
TempData[TempDataConstants.AppointmentStartKey] = appointment?.StartDate;
TempData[TempDataConstants.AppointmentEndKey] = appointment?.EndDate;
TempData[TempDataConstants.AppointmentSubjectKey] = appointment?.Subject;
TempData[TempDataConstants.AppointmentIsAllDayKey] = appointment?.AllDay ?? false;
TempData[TempDataConstants.AppointmentCustomerOidsKey] = string.Join(",", appointment?.CustomerList.Select(s => s.CustomerOid) ?? new List<long>());
TempData[TempDataConstants.AppointmentEmployeeOidsKey] = string.Join(",", appointment?.EmployeeList.Select(s => s.Employee.EmployeeOid) ?? new List<long>());
TempData[TempDataConstants.AppointmentIsSerienterminKey] = appointment != null && selectedAppointmentOid is null && appointment.RecurrenceInfo is string;
return RedirectToActionPermanent("PrepareServiceRecordInsert", "Main");
case "ToServiceRecord":
return ToServiceRecord(apptID, actionId, args);
case "FilterAppointments":
return FilterAppointments(args.Length >= 1 ? args[0] : null);
case "Reload":
ReloadAppointments();
break;
}
return PartialView("SchedulerPagePartial", Model);
}
[Authorize]
private ActionResult ToServiceRecord(string apptID, string actionId, string[] args)
{
long? selectedAppointmentOid;
var isRecurring = false;
// Serientermin
if(apptID.Contains("_"))
{
var splitApptId = apptID.Split('_');
selectedAppointmentOid = long.Parse(splitApptId[0]);
var recurrenceIndex = int.Parse(splitApptId[1]);
TempData[TempDataConstants.AppointmentRecurrenceIndexKey] = recurrenceIndex;
}
else
{
selectedAppointmentOid = long.Parse(apptID);
}
var appointment = selectedAppointmentOid.HasValue ? Model.GetAppointmentByOid(selectedAppointmentOid.Value) : null;
TempData[TempDataConstants.AppointmentOidKey] = appointment?.SchedulerAppointmentOid;
TempData[TempDataConstants.AppointmentStartKey] = appointment?.StartDate;
TempData[TempDataConstants.AppointmentEndKey] = appointment?.EndDate;
TempData[TempDataConstants.AppointmentSubjectKey] = appointment?.Subject;
TempData[TempDataConstants.AppointmentIsAllDayKey] = appointment?.AllDay ?? false;
TempData[TempDataConstants.AppointmentCustomerOidsKey] = string.Join(",", appointment?.CustomerList.Select(s => s.CustomerOid) ?? new List<long>());
TempData[TempDataConstants.AppointmentEmployeeOidsKey] = string.Join(",", appointment?.EmployeeList.Select(s => s.Employee.EmployeeOid) ?? new List<long>());
TempData[TempDataConstants.AppointmentIsSerienterminKey] = appointment != null && selectedAppointmentOid is null && appointment.RecurrenceInfo is string;
return RedirectToActionPermanent("PrepareServiceRecordInsert", "Main");
}
[Authorize]
public string GetAppointmentType(long oid)
{
@@ -670,5 +717,50 @@ namespace BeWoPlanerMobil.Controllers
{
return JsonConvert.SerializeObject(Model.SelectedResourceOidsForFiltering.Count);
}
private ActionResult FilterAppointments(string filters)
{
var filterPairs = filters?.Split(';') ?? Array.Empty<string>();
foreach(var pair in filterPairs)
{
var id2Checked = pair.Split("_");
var isChecked = id2Checked[1] == "on";
var id = id2Checked[0];
switch(id)
{
case "only-my-own-appointments-cb2":
Model.ShowOnlyMyOwnAppointments = isChecked;
UpdateUserSettingsWithoutReload(SettingsKeys.ZeigeNurMeineTermine, isChecked.ToString());
break;
case "only-private-appointments-cb2":
Model.ShowOnlyPrivateAppointments = isChecked;
break;
case "employee-colors-cb2":
Model.ShowEmployeeColors = isChecked;
break;
case "absence-times-cb2":
Model.ShowAbsenceTimes = isChecked;
break;
case "tasks-cb2":
Model.ShowTasks = isChecked;
break;
case "only-employees-cb2":
Model.ShowOnlyEmployees = isChecked;
break;
case "only-customers-cb2":
Model.ShowOnlyCustomers = isChecked;
break;
case "only-resources-cb2":
Model.ShowOnlyResources = isChecked;
break;
}
}
ReloadAppointments();
return PartialView("SchedulerPagePartial", Model);
}
}
}

View File

@@ -1521,11 +1521,7 @@ namespace BeWoPlanerMobil.Controllers
if(Model.NewServiceRecord.CostBearer != null && Model.ShowSignature && (Model.NewServiceRecord.ServiceDescription.Category.IsBillable || Model.NewServiceRecord.ServiceDescription.Category.BillableAmount > 0m || Model.NewServiceRecord.ServiceDescription.BillableAmount > 0m))
{
var valRes = OperationsService.ValidateServiceRecord(Model.NewServiceRecord, null, 0, null, null);
bool doppelt = false;
if(valRes.Count > 0 && valRes.FirstOrDefault(v => v.ResultType == ServiceRecordValidationResult.DoppelterEintrag) != null)
{
doppelt = true;
}
var doppelt = valRes.Count > 0 && valRes.FirstOrDefault(v => v.ResultType == DoppelterEintrag) != null;
if(!doppelt)
{

View File

@@ -1,12 +1,4 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web.Mvc;
using BeWoPlanerMobil.Models;
using BeWoPlanerMobil.Models;
using BeWoPlanerMobil.Service;
using BeWoPlanerMobil.Util;
using BS.Shared;
@@ -16,6 +8,13 @@ using BS.Shared.Extensions;
using DevExpress.XtraScheduler;
using DevExpress.XtraScheduler.Compatibility;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web.Mvc;
using static BeWoPlanerMobil.Util.MobileUtils;
using RecurrenceInformation = BS.Shared.Core.RecurrenceInformation;
@@ -28,30 +27,19 @@ namespace BeWoPlanerMobil.Controllers
{
get
{
if (!MobileSessionFacade.IsUserLoggedIn())
if(false == MobileSessionFacade.IsUserLoggedIn())
{
Logout();
return null;
}
if (_Model == null)
if(_Model is null)
{
_Model = new SchedulerModel();
InitModel(_Model);
InitViewModel();
}
//if (((SchedulerModel) Session[ModelSessionConstants.SchedulerModelKey])?.LoggedInEmployee is null)
//{
// _Model = new SchedulerModel();
// InitModel(_Model);
// Session[ModelSessionConstants.SchedulerModelKey] = _Model;
//}
//else
//{
// _Model = (SchedulerModel) Session[ModelSessionConstants.SchedulerModelKey];
//}
return _Model;
}
}
@@ -161,11 +149,19 @@ namespace BeWoPlanerMobil.Controllers
[Authorize]
public ActionResult Scheduler()
{
if(!MobileSessionFacade.IsUserLoggedIn() || Request.Browser.Browser.Equals("InternetExplorer") || !Model.IsAllowedToSeeScheduler)
if(false == MobileSessionFacade.IsUserLoggedIn() || Request.Browser.Browser.Equals("InternetExplorer") || false == Model.IsAllowedToSeeScheduler)
{
return Logout();
}
if(Model.IsInIntervalFinderMode && Model.IntervalStartDate.HasValue && Model.IntervalEndDate.HasValue && Model.IntervalDuration.HasValue)
{
var customerOids = Model.SelectedCustomerOidsForIntervalFinder.Clone();
var employeeOids = Model.SelectedEmployeeOidsForIntervalFinder.Clone();
var resourceOids = Model.SelectedResourceOidsForIntervalFinder.Clone();
Model.FreeIntervals = KalenderService.FindAppointmentsInRangeForIntervalFinder(Model.IntervalDuration.Value, Model.IntervalStartDate.Value, Model.IntervalEndDate.Value, resourceOids, customerOids, employeeOids, Model.LoggedInUser.Employee.EmployeeOid);
}
return View(Model);
}
@@ -748,7 +744,37 @@ namespace BeWoPlanerMobil.Controllers
Model.IntervalDuration = intervalDuration;
}
return RedirectToActionPermanent("Scheduler");
return RedirectToActionPermanent("Scheduler", Model);
}
[Authorize]
public ActionResult FindFreeIntervalsGet(int duration, string startStr, string endStr)
{
if(Model is null)
{
TempData[TempDataConstants.DoLogoutKey] = true;
return PartialView("AppointmentIntervalFinderResultPartial");
}
var startDateStr = startStr.Substring(0, 10);
var startTimeStr = startStr.Substring(11, 5);
var endDateStr = endStr.Substring(0, 10);
var endTimeStr = endStr.Substring(11, 5);
if(DateTime.TryParse($"{startDateStr} {startTimeStr}", out var intervalStart) && DateTime.TryParse($"{endDateStr} {endTimeStr}", out var intervalEnd))
{
var customerOids = Model.SelectedCustomerOidsForIntervalFinder.Clone();
var employeeOids = Model.SelectedEmployeeOidsForIntervalFinder.Clone();
var resourceOids = Model.SelectedResourceOidsForIntervalFinder.Clone();
Model.FreeIntervals = KalenderService.FindAppointmentsInRangeForIntervalFinder(duration, intervalStart, intervalEnd, resourceOids, customerOids, employeeOids, Model.LoggedInUser.Employee.EmployeeOid);
Model.IntervalStartDate = intervalStart;
Model.IntervalEndDate = intervalEnd;
Model.IntervalDuration = duration;
}
return PartialView("AppointmentIntervalFinderResultPartial", Model);
}
[Authorize]

View File

@@ -100,6 +100,8 @@ namespace BeWoPlanerMobil.Models
public List<CompactCustomerDC> SelectedCustomersForIntervalFinder { get; set; }
public List<ResourceDC> SelectedResourcesForIntervalFinder { get; set; }
public List<long> SelectedEmployeeOidsForIntervalFinder
{
get => DevExpressSchedulerSessionModel.SelectedEmployeeOidsForIntervalFinder;
@@ -165,5 +167,20 @@ namespace BeWoPlanerMobil.Models
get => DevExpressSchedulerSessionModel.ShowOnlyMyOwnAppointments;
set => DevExpressSchedulerSessionModel.ShowOnlyMyOwnAppointments = value;
}
#region Benachrichtigungen
public List<SchedulerAppointmentDC> OpenAppointments { get; set; }
public List<long> OpenAppointmentOids
{
get => DevExpressSchedulerSessionModel.OpenAppointmentOids;
set => DevExpressSchedulerSessionModel.OpenAppointmentOids = value;
}
public int NotificationCount => OpenAppointmentOids?.Count ?? 0;
#endregion
}
}

View File

@@ -18,6 +18,8 @@ namespace BeWoPlanerMobil.Models
public List<long> SelectedCustomerOidsForIntervalFinder { get; set; }
public List<long> SelectedResourceOidsForIntervalFinder { get; set; }
public List<long> OpenAppointmentOids { get; set; }
public bool ShowTasks { get; set; }
public bool ShowOnlyPrivateAppointments { get; set; }
public bool ShowOnlyEmployees { get; set; }
@@ -27,6 +29,8 @@ namespace BeWoPlanerMobil.Models
public bool ShowEmployeeColors { get; set; }
public bool ShowOnlyMyOwnAppointments { get; set; }
public int NotificationCount { get; set; }
public override void ResetValues()
{
base.ResetValues();
@@ -43,6 +47,8 @@ namespace BeWoPlanerMobil.Models
SelectedCustomerOidsForIntervalFinder = new List<long>();
SelectedResourceOidsForIntervalFinder = new List<long>();
OpenAppointmentOids = new List<long>();
ShowTasks = false;
ShowOnlyPrivateAppointments = false;
ShowOnlyEmployees = false;
@@ -51,6 +57,8 @@ namespace BeWoPlanerMobil.Models
ShowAbsenceTimes = false;
ShowEmployeeColors = false;
ShowOnlyMyOwnAppointments = false;
NotificationCount = 0;
}
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace BeWoPlanerMobil.Util.Constants
{
public static class DevExpressSchedulerConstants
{
// Dictionary?
// MyOwnAppointmentsOnly -> only-my-own-appointments-cb2
//public static List<string>
}
}

View File

@@ -602,6 +602,11 @@ namespace BeWoPlanerMobil.Util
public static string GetAppointmentRightBackground(DevExpress.XtraScheduler.Appointment appointment)
{
if(appointment.CustomFields["IsTask"] is true)
{
return GetAppointmentRightGradient(false, new List<string> { "#993B3B" }, 1);
}
var hasCustomers = appointment.CustomFields["Customers"] is List<CompactCustomerDC> customerList && customerList.Any();
var customFieldValue = appointment.CustomFields["Resources"];
@@ -624,6 +629,11 @@ namespace BeWoPlanerMobil.Util
return $"5px solid #{GetColorAsHex(color)}";
}
if(appointment.CustomFields["IsTask"] is true)
{
return "5px solid #993B3B";
}
return "5px solid #C0FFD0";
}

View File

@@ -1,4 +1,5 @@
@model BeWoPlanerMobil.Models.DevExpressSchedulerModel
@using BeWoPlanerMobil.Util
@model BeWoPlanerMobil.Models.DevExpressSchedulerModel
@{
ViewBag.Title = "DevExpressScheduler";
@@ -137,32 +138,87 @@
}
function OnAppointmentMenuPopup(s, e) {
const selectedAppointment = scheduler.GetAppointmentById(scheduler.GetSelectedAppointmentIds()[0]);
console.log(selectedAppointment);
const id = scheduler.GetSelectedAppointmentIds()[0];
const selectedAppointment = scheduler.GetAppointmentById(id);
const isAbsenceTime = selectedAppointment.IsAbsenceTime;
const isTask = selectedAppointment.IsTask;
for(let i = 0; i < e.item.items.length; i++) {
const currentItem = e.item.items[i];
if(currentItem.name === "ToServiceRecord") {
const isTask = selectedAppointment.customField("IsTask");
const isAbsenceTime = selectedAppointment.customField("IsAbsenceTime");
if(isTask === true || isAbsenceTime === true) {
currentItem.SetVisible(false);
}
switch(currentItem.name) {
case "ToServiceRecord":
if(isAbsenceTime || isTask) {
currentItem.SetVisible(false);
}
break;
}
}
}
function filterAppointments() {
const checkedBoxes = $("#filter-menu input[type='checkbox']");
var selectedBoxes = "";
for(let i = 0; i < checkedBoxes.length; i++) {
const box = $(checkedBoxes[i]);
const boxId = box.prop("id");
const boxValue = box.prop("checked") ? "on" : "off";
selectedBoxes += `${boxId}_${boxValue}`;
if(i !== checkedBoxes.length - 1) {
selectedBoxes += ";";
}
}
scheduler.PerformCallback({
apptID: "",
actionId: "FilterAppointments",
args: [selectedBoxes]
});
}
function updateNotificationInfo() {
$("#scheduler-notification-container").load("@Url.Action("GetNotifications")");
}
</script>
<div class="dropdown">
<div class="dropdown show">
@{
var isOnlyOwnAptsChecked = Model.ShowOnlyMyOwnAppointments ? "checked" : string.Empty;
var isOnlyPrivateAptsChecked = Model.ShowOnlyPrivateAppointments ? "checked" : string.Empty;
var isEmployeeColorsChecked = Model.ShowEmployeeColors ? "checked" : string.Empty;
var isAbsenceTimesChecked = Model.ShowAbsenceTimes ? "checked" : string.Empty;
var isTasksChecked = Model.ShowTasks ? "checked" : string.Empty;
var isOnlyEmployeesChecked = Model.ShowOnlyEmployees ? "checked" : string.Empty;
var isOnlyCustomersChecked = Model.ShowOnlyCustomers ? "checked" : string.Empty;
var isOnlyResourcesChecked = Model.ShowOnlyResources ? "checked" : string.Empty;
}
<button class="btn btn-primary dropdown-toggle m-1" type="button" data-toggle="dropdown">
Filtern
</button>
<div class="dropdown-menu">
<button class="btn btn-success m-1 ml-0" type="button" onclick="scheduler.PerformCallback({ apptID: '', actionId: 'Reload' })">
<i class="fas fa-sync-alt"></i>
</button>
@if(Model.NotificationCount == 0)
{
<a href="#" class="disabled" style="text-decoration: underline;">keine Benachrichtigungen</a>
}
<div id="scheduler-notification-container" class="m-1" style="margin: 0 auto;">
@Html.Partial("SchedulerNotificationPartial", Model);
</div>
<div class="dropdown-menu show" id="filter-menu">
<div class="dropdown-item">
<form class="form-inline">
<div class="form-group form-check">
<input type="checkbox" class="form-check-input" id="only-my-own-appointments-cb2">
<input type="checkbox" class="form-check-input" id="only-my-own-appointments-cb2" @isOnlyOwnAptsChecked onclick="filterAppointments()">
<label class="form-check-label" for="only-my-own-appointments-cb2">Nur meine Termine</label>
</div>
</form>
@@ -170,7 +226,7 @@
<div class="dropdown-item">
<form class="form-inline">
<div class="form-group form-check">
<input type="checkbox" class="form-check-input" id="only-private-appointments-cb2">
<input type="checkbox" class="form-check-input" id="only-private-appointments-cb2" @isOnlyPrivateAptsChecked onclick="filterAppointments()">
<label class="form-check-label" for="only-private-appointments-cb2">Nur private Termine</label>
</div>
</form>
@@ -179,7 +235,7 @@
<div class="dropdown-item">
<form class="form-inline">
<div class="form-group form-check">
<input type="checkbox" class="form-check-input" id="employee-colors-cb2">
<input type="checkbox" class="form-check-input" id="employee-colors-cb2" @isEmployeeColorsChecked onclick="filterAppointments()">
<label class="form-check-label" for="employee-colors-cb2">Mitarbeiterfarben</label>
</div>
</form>
@@ -187,7 +243,7 @@
<div class="dropdown-item">
<form class="form-inline">
<div class="form-group form-check">
<input type="checkbox" class="form-check-input" id="absence-times-cb2">
<input type="checkbox" class="form-check-input" id="absence-times-cb2" @isAbsenceTimesChecked onclick="filterAppointments()">
<label class="form-check-label" for="absence-times-cb2">Abwesenheiten</label>
</div>
</form>
@@ -195,7 +251,7 @@
<div class="dropdown-item">
<form class="form-inline">
<div class="form-group form-check">
<input type="checkbox" class="form-check-input" id="tasks-cb2">
<input type="checkbox" class="form-check-input" id="tasks-cb2" @isTasksChecked onclick="filterAppointments()">
<label class="form-check-label" for="tasks-cb2">Aufgaben</label>
</div>
</form>
@@ -204,7 +260,7 @@
<div class="dropdown-item">
<form class="form-inline">
<div class="form-group form-check">
<input type="checkbox" class="form-check-input" id="only-employees-cb2">
<input type="checkbox" class="form-check-input" id="only-employees-cb2" @isOnlyEmployeesChecked onclick="filterAppointments()">
<label class="form-check-label" for="only-employees-cb2">Nur Mitarbeiter</label>
</div>
</form>
@@ -212,7 +268,7 @@
<div class="dropdown-item">
<form class="form-inline">
<div class="form-group form-check">
<input type="checkbox" class="form-check-input" id="only-customers-cb2">
<input type="checkbox" class="form-check-input" id="only-customers-cb2" @isOnlyCustomersChecked onclick="filterAppointments()">
<label class="form-check-label" for="only-customers-cb2">Nur Klienten</label>
</div>
</form>
@@ -220,7 +276,7 @@
<div class="dropdown-item">
<form class="form-inline">
<div class="form-group form-check">
<input type="checkbox" class="form-check-input" id="only-resources-cb2">
<input type="checkbox" class="form-check-input" id="only-resources-cb2" @isOnlyResourcesChecked onclick="filterAppointments()">
<label class="form-check-label" for="only-resources-cb2">Nur Ressourcen</label>
</div>
</form>
@@ -251,8 +307,8 @@
</div>
}
@Html.Partial("AptFltEmployeesPartial")
@Html.Partial("AptFltEmployeesPartial", Model)
@Html.Partial("AptFltCustomersPartial")
@Html.Partial("AptFltCustomersPartial", Model)
@Html.Partial("AptFltResourcesPartial")
@Html.Partial("AptFltResourcesPartial", Model)

View File

@@ -29,7 +29,6 @@
white-space: nowrap;
overflow: hidden;
font: 10pt 'Signika Negative';
color: #37414D;
display: block;
}
@@ -52,8 +51,12 @@
}
</style>
<div class="horizontal-appointment-template-div" style="border-left: @MobileUtils.GetLeftAppointmentBorder(Model);background: @MobileUtils.GetAppointmentRightBackground(Model) right / 5px 100% no-repeat, #C0FFD0;">
<div class="horizontal-appointment-info">
@{
var background = Model.CustomFields["IsTask"] is true ? "#993B3B" : "#C0FFD0";
var color = Model.CustomFields["IsTask"] is true ? "#FFFFFF" : "#37414D";
}
<div class="horizontal-appointment-template-div" style="border-left: @MobileUtils.GetLeftAppointmentBorder(Model);background: @MobileUtils.GetAppointmentRightBackground(Model) right / 5px 100% no-repeat, @background;">
<div class="horizontal-appointment-info" style="color: @color;">
<label class="horizontal-appointment-label">
@GetHeaderTime() <span style="font-weight: bold;">@GetSubjectAndLocation()</span>
</label>

View File

@@ -0,0 +1,18 @@
@model BeWoPlanerMobil.Models.DevExpressSchedulerModel
@functions
{
string GetNotificationInfo()
{
return $"{Model.NotificationCount} Benachrichtigung{(Model.NotificationCount == 1 ? string.Empty : "en")}";
}
}
@if(Model.NotificationCount == 0)
{
<a href="#" class="disabled" style="text-decoration: underline;">keine Benachrichtigungen</a>
}
else
{
<a href="#">@GetNotificationInfo()</a>
}

View File

@@ -162,7 +162,13 @@
settings.OptionsToolTips.ShowSelectionToolTip = false;
settings.ClientSideEvents.ActiveViewChanging = "onActiveViewChanged";
settings.ClientSideEvents.MenuItemClicked = "onMenuItemClicked";
settings.InitClientAppointment = (send, evargs) =>
{
evargs.Properties.Add("IsAbsenceTime", evargs.Appointment.CustomFields["IsAbsenceTime"]);
evargs.Properties.Add("IsTask", evargs.Appointment.CustomFields["IsTask"]);
};
settings.PopupMenuShowing = PopupMenuShowing;
settings.Storage.Appointments.Assign(SchedulerHelper.DefaultAppointmentStorage);
@@ -188,19 +194,29 @@
}
};
settings.Views.WeekView.SetHorizontalAppointmentTemplateContent(c => { Html.RenderPartial("HorizontalAppointmentTemplatePartial", c.AppointmentViewInfo); });
settings.Views.AgendaView.Enabled = false;
settings.Views.MonthView.SetHorizontalAppointmentTemplateContent(c => { Html.RenderPartial("HorizontalAppointmentTemplatePartial", c.AppointmentViewInfo); });
settings.Views.WeekView.SetHorizontalAppointmentTemplateContent(appointmentTemplateContainer => { Html.RenderPartial("HorizontalAppointmentTemplatePartial", appointmentTemplateContainer.AppointmentViewInfo.Appointment); });
settings.Views.WeekView.SetHorizontalSameDayAppointmentTemplateContent(appointmentTemplateContainer => { Html.RenderPartial("HorizontalAppointmentTemplatePartial", appointmentTemplateContainer.AppointmentViewInfo.Appointment); });
settings.Views.DayView.SetVerticalAppointmentTemplateContent(c => { Html.RenderPartial("VerticalAppointmentTemplatePartial", c.AppointmentViewInfo); });
settings.Views.DayView.SetHorizontalAppointmentTemplateContent(c => { Html.RenderPartial("HorizontalAppointmentTemplatePartial", c.AppointmentViewInfo); });
settings.Views.FullWeekView.SetVerticalAppointmentTemplateContent(appointmentTemplateContainer => { Html.RenderPartial("VerticalAppointmentTemplatePartial", appointmentTemplateContainer.AppointmentViewInfo); });
settings.Views.FullWeekView.SetHorizontalAppointmentTemplateContent(appointmentTemplateContainer => { Html.RenderPartial("HorizontalAppointmentTemplatePartial", appointmentTemplateContainer.AppointmentViewInfo.Appointment); });
settings.Views.WorkWeekView.SetVerticalAppointmentTemplateContent(c => { Html.RenderPartial("VerticalAppointmentTemplatePartial", c.AppointmentViewInfo); });
settings.Views.WorkWeekView.SetHorizontalAppointmentTemplateContent(c => { Html.RenderPartial("HorizontalAppointmentTemplatePartial", c.AppointmentViewInfo.Appointment); });
settings.Views.MonthView.SetHorizontalAppointmentTemplateContent(appointmentTemplateContainer => { Html.RenderPartial("HorizontalAppointmentTemplatePartial", appointmentTemplateContainer.AppointmentViewInfo.Appointment); });
settings.Views.MonthView.SetHorizontalSameDayAppointmentTemplateContent(appointmentTemplateContainer => { Html.RenderPartial("HorizontalAppointmentTemplatePartial", appointmentTemplateContainer.AppointmentViewInfo.Appointment); });
settings.OptionsForms.SetAppointmentFormTemplateContent(c =>
settings.Views.DayView.SetVerticalAppointmentTemplateContent(appointmentTemplateContainer => { Html.RenderPartial("VerticalAppointmentTemplatePartial", appointmentTemplateContainer.AppointmentViewInfo); });
settings.Views.DayView.SetHorizontalAppointmentTemplateContent(appointmentTemplateContainer => { Html.RenderPartial("HorizontalAppointmentTemplatePartial", appointmentTemplateContainer.AppointmentViewInfo.Appointment); });
settings.Views.WorkWeekView.SetVerticalAppointmentTemplateContent(appointmentTemplateContainer => { Html.RenderPartial("VerticalAppointmentTemplatePartial", appointmentTemplateContainer.AppointmentViewInfo); });
settings.Views.WorkWeekView.SetHorizontalAppointmentTemplateContent(appointmentTemplateContainer => { Html.RenderPartial("HorizontalAppointmentTemplatePartial", appointmentTemplateContainer.AppointmentViewInfo.Appointment); });
settings.Views.TimelineView.SetHorizontalSameDayAppointmentTemplateContent(appointmentTemplateContainer => { Html.RenderPartial("HorizontalAppointmentTemplatePartial", appointmentTemplateContainer.AppointmentViewInfo); });
settings.Views.TimelineView.SetHorizontalAppointmentTemplateContent(appointmentTemplateContainer => { Html.RenderPartial("HorizontalAppointmentTemplatePartial", appointmentTemplateContainer.AppointmentViewInfo.Appointment); });
settings.OptionsForms.SetAppointmentFormTemplateContent(appointmentFormTemplateContainer =>
{
var container = (CustomAppointmentTemplateContainer) c;
var container = (CustomAppointmentTemplateContainer) appointmentFormTemplateContainer;
var oid = (long?) container.Appointment.Id;

View File

@@ -40,7 +40,20 @@
if(isValid === false) {
hideSpinner();
} else {
$("#hidden-submit-btn").click();
// ToDo: Durch get ersetzen!
//$("#hidden-submit-btn").click();
$("#interval-finder-result-container")
.load(
"@Url.Action("FindFreeIntervalsGet")",
{
duration: $("#interval-duration").val(),
startStr: $("#scheduler-interval-start").val(),
endStr: $("#scheduler-interval-end").val()
},
() => {
hideSpinner();
}
);
}
} catch(error) {
window.showErrorPopup(error);
@@ -148,188 +161,185 @@
<div id="interval-form-container">
<div class="alert alert-danger collapse" role="alert" id="interval-finder-validation-alert"></div>
@using(Html.BeginForm("FindFreeIntervals", "Scheduler", FormMethod.Post, new { id = "find-appointment-intervals-form", @class = "needs-validation", novalidate = true }))
{
<div>
<div class="form-row mt-1">
<div class="col-md">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text prepend-text">
Von
</span>
</div>
<input class="form-control" type="datetime-local" id="scheduler-interval-start" name="IntervalStart" value="@Model.IntervalStartDateStr"/>
</div>
</div>
</div>
<div class="form-row mt-1">
<div class="col-md">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text prepend-text">
Bis
</span>
</div>
<input class="form-control" type="datetime-local" id="scheduler-interval-end" name="IntervalEnd" value="@Model.IntervalEndDateStr"/>
</div>
</div>
</div>
<div class="form-row mt-1">
<div class="col-md">
<div class="form-group mb-1">
<div class="input-group">
<div class="input-group-prepend">
<div class="input-group-text prepend-text px-2">
Dauer
</div>
</div>
<input value="@Model.IntervalDurationStr" type="number" autocomplete="on" min="10" id="interval-duration" name="Duration" class="form-control"/>
</div>
</div>
</div>
</div>
@if(Model.HasResourcesEmployeesOrCustomers)
{
<!-- Hinzufügen-Buttons -->
<div class="form-row">
@if(Model.HasRightToViewEmployeeAppointments)
{
<div class="col-md">
<div class="form-group my-1">
<button type="button" class="btn btn-bewo-employee w-100" data-toggle="modal" data-target="#employees-interval-finder-popup">Mitarbeiter</button>
</div>
</div>
}
@if(Model.HasRightToViewCustomerAppointments)
{
<div class="col-md">
<div class="form-group my-1">
<button type="button" class="btn btn-bewo-customers w-100" data-toggle="modal" data-target="#customers-interval-finder-popup">Klienten</button>
</div>
</div>
}
@if(Model.HasRightToViewAllResourceAppointments && Model.ResourceCategories2Resources.Any())
{
<div class="col-md">
<div class="form-group my-1">
<button type="button" class="btn btn-bewo-resource w-100" data-toggle="modal" data-target="#resources-interval-finder-popup">Ressourcen</button>
</div>
</div>
}
</div>
<div class="form-row">
@if(Model.HasRightToViewEmployeeAppointments)
{
<div class="col-12">
<div class="form-group my-1">
<div class="list-group" id="selected-employees-interval-finder-list">
@foreach(var selectedEmployee in Model.SelectedEmployeesForIntervalFinder)
{
<div class="list-group-item my-auto" id="related-employee-interval-finder-@selectedEmployee.EmployeeOid">
<div class="row">
<div class="input-group">
<div class="input-group-prepend">
<i class="fas fa-user text-bewo-employee h-100"></i>
</div>
<p class="form-control border-0 bg-transparent text-truncate">
@selectedEmployee.DetailDescription
</p>
<div class="input-group-append">
@{
var url = Url.Action("SelectEmployeesForIntervalFinder", "Scheduler");
var oid = selectedEmployee.EmployeeOid;
var filterAppointmentsUrl = Url.Action("FetchAppointments", "Scheduler");
var onClickParams = $"{oid}, '-interval-finder-checkbox', false, '{url}', 'employees-interval-finder-popup', 'employees-interval-finder-popup', 'related-employee-interval-finder-', '{filterAppointmentsUrl}'";
}
<button type="button" class="btn btn-primary" onclick="removeSelectedItem(@onClickParams)">
<span class="fas fa-times-circle"></span>
</button>
</div>
</div>
</div>
</div>
}
</div>
</div>
</div>
}
@if(Model.HasRightToViewCustomerAppointments)
{
<div class="col-12">
<div class="form-group my-1">
<div class="list-group" id="selected-customers-interval-finder-list">
@foreach(var selectedCustomer in Model.SelectedCustomersForIntervalFinder)
{
<div class="list-group-item my-auto" id="related-customer-interval-finder-@selectedCustomer.CustomerOid">
<div class="row">
<div class="input-group">
<div class="input-group-prepend">
<i class="fas fa-user text-bewo-customers h-100"></i>
</div>
<p class="form-control border-0 bg-transparent text-truncate">
@selectedCustomer.DetailDescription
</p>
<div class="input-group-append">
@{
var url = Url.Action("SelectCustomersForIntervalFinder", "Scheduler");
var oid = selectedCustomer.CustomerOid;
var filterAppointmentsUrl = Url.Action("FetchAppointments", "Scheduler");
var onClickParams = $"{oid}, '-interval-finder-checkbox', false, '{url}', 'customers-interval-finder-popup', 'customers-interval-finder-popup', 'related-customer-interval-finder-', '{filterAppointmentsUrl}'";
}
<button type="button" class="btn btn-primary" onclick="removeSelectedItem(@onClickParams)">
<span class="fas fa-times-circle"></span>
</button>
</div>
</div>
</div>
</div>
}
</div>
</div>
</div>
}
@if(Model.HasRightToViewAllResourceAppointments && Model.ResourceCategories2Resources.Any())
{
<div class="col-12">
<div class="form-group my-1">
<div class="list-group" id="selected-resources-interval-finder-list">
@foreach(var selectedResource in Model.SelectedResourcesForIntervalFinder)
{
<div class="list-group-item my-auto" id="related-resource-interval-finder-item-@selectedResource.ResourceOid">
<div class="row">
<div class="input-group">
<div class="input-group-prepend">
<i class="fas fa-cubes text-bewo-resource h-100"></i>
</div>
<p class="form-control border-0 bg-transparent text-truncate">
@selectedResource.Name
</p>
<div class="input-group-append">
<button type="button" class="btn btn-primary" onclick="removeSelectedResource('related-resource-interval-finder-item-@selectedResource.ResourceOid', 'resource-@selectedResource.ResourceOid-interval-finder-checkbox', 'resources-interval-finder-popup', '@Url.Action("SelectResourcesForIntervalFinder", "Scheduler")', 'selected-resources-interval-finder-list', '@Url.Action("FetchAppointments", "Scheduler")', 'related-resource-interval-finder-item-', '-interval-finder-checkbox', 'all-resources-for-interval-finder-checkbox')">
<span class="fas fa-times-circle"></span>
</button>
</div>
</div>
</div>
</div>
}
</div>
</div>
</div>
}
</div>
}
<div>
<div class="form-row mt-1">
<div class="col-md">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text prepend-text">
Von
</span>
</div>
<input class="form-control" type="datetime-local" id="scheduler-interval-start" name="IntervalStart" value="@Model.IntervalStartDateStr" />
</div>
</div>
</div>
<button type="submit" class="d-none" id="hidden-submit-btn"></button>
}
<div class="form-row mt-1">
<div class="col-md">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text prepend-text">
Bis
</span>
</div>
<input class="form-control" type="datetime-local" id="scheduler-interval-end" name="IntervalEnd" value="@Model.IntervalEndDateStr" />
</div>
</div>
</div>
<div class="form-row mt-1">
<div class="col-md">
<div class="form-group mb-1">
<div class="input-group">
<div class="input-group-prepend">
<div class="input-group-text prepend-text px-2">
Dauer
</div>
</div>
<input value="@Model.IntervalDurationStr" type="number" autocomplete="on" min="10" id="interval-duration" name="Duration" class="form-control" />
</div>
</div>
</div>
</div>
@if(Model.HasResourcesEmployeesOrCustomers)
{
<!-- Hinzufügen-Buttons -->
<div class="form-row">
@if(Model.HasRightToViewEmployeeAppointments)
{
<div class="col-md">
<div class="form-group my-1">
<button type="button" class="btn btn-bewo-employee w-100" data-toggle="modal" data-target="#employees-interval-finder-popup">Mitarbeiter</button>
</div>
</div>
}
@if(Model.HasRightToViewCustomerAppointments)
{
<div class="col-md">
<div class="form-group my-1">
<button type="button" class="btn btn-bewo-customers w-100" data-toggle="modal" data-target="#customers-interval-finder-popup">Klienten</button>
</div>
</div>
}
@if(Model.HasRightToViewAllResourceAppointments && Model.ResourceCategories2Resources.Any())
{
<div class="col-md">
<div class="form-group my-1">
<button type="button" class="btn btn-bewo-resource w-100" data-toggle="modal" data-target="#resources-interval-finder-popup">Ressourcen</button>
</div>
</div>
}
</div>
<div class="form-row">
@if(Model.HasRightToViewEmployeeAppointments)
{
<div class="col-12">
<div class="form-group my-1">
<div class="list-group" id="selected-employees-interval-finder-list">
@foreach(var selectedEmployee in Model.SelectedEmployeesForIntervalFinder)
{
<div class="list-group-item my-auto" id="related-employee-interval-finder-@selectedEmployee.EmployeeOid">
<div class="row">
<div class="input-group">
<div class="input-group-prepend">
<i class="fas fa-user text-bewo-employee h-100"></i>
</div>
<p class="form-control border-0 bg-transparent text-truncate">
@selectedEmployee.DetailDescription
</p>
<div class="input-group-append">
@{
var url = Url.Action("SelectEmployeesForIntervalFinder", "Scheduler");
var oid = selectedEmployee.EmployeeOid;
var filterAppointmentsUrl = Url.Action("FetchAppointments", "Scheduler");
var onClickParams = $"{oid}, '-interval-finder-checkbox', false, '{url}', 'employees-interval-finder-popup', 'employees-interval-finder-popup', 'related-employee-interval-finder-', '{filterAppointmentsUrl}'";
}
<button type="button" class="btn btn-primary" onclick="removeSelectedItem(@onClickParams)">
<span class="fas fa-times-circle"></span>
</button>
</div>
</div>
</div>
</div>
}
</div>
</div>
</div>
}
@if(Model.HasRightToViewCustomerAppointments)
{
<div class="col-12">
<div class="form-group my-1">
<div class="list-group" id="selected-customers-interval-finder-list">
@foreach(var selectedCustomer in Model.SelectedCustomersForIntervalFinder)
{
<div class="list-group-item my-auto" id="related-customer-interval-finder-@selectedCustomer.CustomerOid">
<div class="row">
<div class="input-group">
<div class="input-group-prepend">
<i class="fas fa-user text-bewo-customers h-100"></i>
</div>
<p class="form-control border-0 bg-transparent text-truncate">
@selectedCustomer.DetailDescription
</p>
<div class="input-group-append">
@{
var url = Url.Action("SelectCustomersForIntervalFinder", "Scheduler");
var oid = selectedCustomer.CustomerOid;
var filterAppointmentsUrl = Url.Action("FetchAppointments", "Scheduler");
var onClickParams = $"{oid}, '-interval-finder-checkbox', false, '{url}', 'customers-interval-finder-popup', 'customers-interval-finder-popup', 'related-customer-interval-finder-', '{filterAppointmentsUrl}'";
}
<button type="button" class="btn btn-primary" onclick="removeSelectedItem(@onClickParams)">
<span class="fas fa-times-circle"></span>
</button>
</div>
</div>
</div>
</div>
}
</div>
</div>
</div>
}
@if(Model.HasRightToViewAllResourceAppointments && Model.ResourceCategories2Resources.Any())
{
<div class="col-12">
<div class="form-group my-1">
<div class="list-group" id="selected-resources-interval-finder-list">
@foreach(var selectedResource in Model.SelectedResourcesForIntervalFinder)
{
<div class="list-group-item my-auto" id="related-resource-interval-finder-item-@selectedResource.ResourceOid">
<div class="row">
<div class="input-group">
<div class="input-group-prepend">
<i class="fas fa-cubes text-bewo-resource h-100"></i>
</div>
<p class="form-control border-0 bg-transparent text-truncate">
@selectedResource.Name
</p>
<div class="input-group-append">
<button type="button" class="btn btn-primary" onclick="removeSelectedResource('related-resource-interval-finder-item-@selectedResource.ResourceOid', 'resource-@selectedResource.ResourceOid-interval-finder-checkbox', 'resources-interval-finder-popup', '@Url.Action("SelectResourcesForIntervalFinder", "Scheduler")', 'selected-resources-interval-finder-list', '@Url.Action("FetchAppointments", "Scheduler")', 'related-resource-interval-finder-item-', '-interval-finder-checkbox', 'all-resources-for-interval-finder-checkbox')">
<span class="fas fa-times-circle"></span>
</button>
</div>
</div>
</div>
</div>
}
</div>
</div>
</div>
}
</div>
}
</div>
<div class="d-flex bd-highlight mt-3">
<div class="mr-auto bd-highlight">
@using(Html.BeginForm("SetIsInIntervalFinderMode", "Scheduler", FormMethod.Post))

View File

@@ -2,7 +2,7 @@
@model BeWoPlanerMobil.Models.SchedulerModel
@{
if(TempData[TempDataConstants.DoLogoutKey] is bool doLogout && doLogout)
if(TempData[TempDataConstants.DoLogoutKey] is true)
{
<text>
<script type="text/javascript">
@@ -12,10 +12,23 @@
}
}
@functions
{
string GetIntervalStart()
{
return $"{Model.IntervalStartDate:dd.MM.yyyy HH:mm}";
}
string GetIntervalEnd()
{
return $"{Model.IntervalEndDate:dd.MM.yyyy HH:mm}";
}
}
@if(Model.FreeIntervals.Any())
{
<div class="table-responsive overflow-auto" style="max-width: 1200px; max-height: 80vh;">
<table class="table table-striped small table-bordered overflow-auto" style="width: fit-content; max-height: 80vh;">
<table class="table table-striped table-sm small table-bordered overflow-auto" style="width: fit-content; max-height: 80vh;">
<thead>
<th scope="col">Zeit</th>
@foreach(var date in Model.FreeIntervalDays)
@@ -62,7 +75,7 @@ else if(Model.IntervalStartDate.HasValue && Model.IntervalEndDate.HasValue)
{
<div class="container-fluid mx-0 px-0">
<div class="alert alert-warning" role="alert" id="interval-finder-validation-alert">
Im ausgewählten Zeitraum zwischen dem @Model.IntervalStartDateStr @Model.IntervalStartTimeStr Uhr und dem @Model.IntervalEndDateStr @Model.IntervalEndTimeStr Uhr wurden keine freien Intervalle gefunden.
Im ausgewählten Zeitraum zwischen dem @GetIntervalStart() Uhr und dem @GetIntervalEnd() Uhr wurden keine freien Intervalle gefunden.
</div>
</div>
}

View File

@@ -236,7 +236,9 @@
@* TODO: VORERST NICHT LÖSCHEN! *@
@if(Model?.IsInIntervalFinderMode ?? false)
{
@Html.Partial("AppointmentIntervalFinderResultPartial", Model)
<div id="interval-finder-result-container">
@Html.Partial("AppointmentIntervalFinderResultPartial", Model)
</div>
}
else
{

View File

@@ -59,7 +59,7 @@
</logger>
<logger name="NHibernate.SQL">
<level value="WARN" />
<level value="DEBUG" />
</logger>
<logger name="NHibernate.Search">

View File

@@ -5156,13 +5156,13 @@ WHERE sc.Billable = 1 and sr.StartDate >= '{0:yyyy-MM-dd}' and sr.StartDate < '{
var freeIntervals = new List<DateTimeSpan>();
if (intervals.Count > 0)
if(intervals.Count > 0)
{
if (result.Count > 0)
if(result.Count > 0)
{
foreach (var interval in intervals)
foreach(var interval in intervals)
{
if (!result.Any(a => a.StartDate.HasValue && a.EndDate.HasValue && a.StartDate.Value.IsInInterval(a.EndDate.Value, interval.StartDate, interval.EndDate)))
if(false == result.Any(a => a.StartDate.HasValue && a.EndDate.HasValue && a.StartDate.Value.IsInInterval(a.EndDate.Value, interval.StartDate, interval.EndDate)))
{
freeIntervals.Add(interval);
}
@@ -5181,7 +5181,7 @@ WHERE sc.Billable = 1 and sr.StartDate >= '{0:yyyy-MM-dd}' and sr.StartDate < '{
{
var result = new List<SchedulerAppointment>();
if (intervalStart < intervalEnd)
if(intervalStart < intervalEnd)
{
var intervals = IntervalFinderHelper.GenerateIntervalsForCriteria(intervalStart, intervalEnd, skipWeekends);
@@ -5192,13 +5192,13 @@ WHERE sc.Billable = 1 and sr.StartDate >= '{0:yyyy-MM-dd}' and sr.StartDate < '{
var criteria = CreateCriteriaIsActiveWithAlias<SchedulerAppointment>("sa")
.Add(Restrictions.Not(Restrictions.Eq(nameof(SchedulerAppointment.IsTask), true)));
if (intervals.Count > 0)
if(intervals.Count > 0)
{
if (intervals.Count > 1)
if(intervals.Count > 1)
{
var criterionList = new List<ICriterion>();
foreach (var dts in intervals)
foreach(var dts in intervals)
{
criterionList.AddIfNotIn(
Restrictions.Or(
@@ -5217,7 +5217,7 @@ WHERE sc.Billable = 1 and sr.StartDate >= '{0:yyyy-MM-dd}' and sr.StartDate < '{
{
var dts = intervals.FirstOrDefault();
if (dts != null)
if(dts != null)
{
var cri = Restrictions.Or(
Restrictions.Between(nameof(SchedulerAppointment.StartDate), dts.StartDate, dts.EndDate),
@@ -5236,7 +5236,7 @@ WHERE sc.Billable = 1 and sr.StartDate >= '{0:yyyy-MM-dd}' and sr.StartDate < '{
ICriterion resourceCriterion = null;
ICriterion customerCriterion = null;
if (employeeOids.Count == 0)
if(employeeOids.Count == 0)
{
employeeOids.Add(loggedInEmployeeOid);
}
@@ -5244,6 +5244,7 @@ WHERE sc.Billable = 1 and sr.StartDate >= '{0:yyyy-MM-dd}' and sr.StartDate < '{
var detachedCriteria1 = DetachedCriteria.For<Employee2SchedulerAppointment>()
.Add(Restrictions.In(nameof(Employee2SchedulerAppointment.Employee) + ".Oid", employeeOids))
.SetProjection(Projections.Property(nameof(Employee2SchedulerAppointment.SchedulerAppointmentOid)));
var employee2SchedCrit = Subqueries.PropertyIn(nameof(BeWoEntityBase.Oid), detachedCriteria1);
var originatorCrit = Restrictions.In(nameof(SchedulerAppointment.Originator), employeeOids);
@@ -5258,13 +5259,13 @@ WHERE sc.Billable = 1 and sr.StartDate >= '{0:yyyy-MM-dd}' and sr.StartDate < '{
var employeeCriterion = Restrictions.Or(employee2SchedCrit, and);
if (customerOids?.Count > 0)
if(customerOids?.Count > 0)
{
var customerSql = $"{BeWoEntityBase.PropertyName_Oid} IN (SELECT newschappoid FROM customer2newschapp WHERE customeroid IN ({customerOids.ToSeparatedString(",")}))";
customerCriterion = Expression.Sql(customerSql);
}
if (resourceOids?.Count > 0)
if(resourceOids?.Count > 0)
{
var resourceSql = $"{BeWoEntityBase.PropertyName_Oid} IN (SELECT newschappoid FROM resource2newschapp WHERE resourceoid IN ({resourceOids.ToSeparatedString(",")}))";
resourceCriterion = Expression.Sql(resourceSql);
@@ -5277,17 +5278,17 @@ WHERE sc.Billable = 1 and sr.StartDate >= '{0:yyyy-MM-dd}' and sr.StartDate < '{
resourceCriterion
};
if (listOfCriterias.Count > 0)
if(listOfCriterias.Count > 0)
{
var orCriteria = CreateOrCriteria(listOfCriterias);
if (orCriteria != null)
if(orCriteria != null)
{
criteria.Add(orCriteria);
}
}
var criteriaAsString = criteria.ToString();
var criteriaAsString = GetGeneratedSql(criteria);
var appointments = criteria.List<SchedulerAppointment>().ToList();

View File

@@ -1499,4 +1499,24 @@ namespace BS.Shared
Asa, //Aufsuchendes Angebot? o.ä.
Tgv //Tagesgeldverwaltung
}
public enum BeWoAppointmentType
{
Appointment,
Task,
AbsenceTime
}
public enum AppointmentFilter
{
Default,
MyOwnAppointmentsOnly,
PrivateAppointmentsOnly,
EmployeeColors,
AbsenceTimes,
Tasks,
EmployeesOnly,
CustomersOnly,
ResourcesOnly
}
}

View File

@@ -165,6 +165,7 @@ namespace BS.Shared.DataContracts
public long? FormerAbsenceTimeOid { get; set; }
public DateTime? Krankheitsmeldung { get; set; }
public AbsenceReasonDC AbsenceReason { get; set; }
public bool IsAbsenceTime { get; set; }
public override bool Equals(object obj)
{