MoK:
Mitarbeiterstundenkonto: Rechte werden wie im FaC beachtet Ressourcenverfügbarkeitsprüfung zeigt jetzt Intervalle, in denen die ausgewählten Ressourcen bereits gebucht sind an und von wem, sofern man diesen Mitarbeiter sehen darf. FaC: Ressourcenverfügbarkeitsprüfung zeigt jetzt Intervalle, in denen die ausgewählten Ressourcen bereits gebucht sind an und von wem, sofern man diesen Mitarbeiter sehen darf.
This commit is contained in:
@@ -538,7 +538,7 @@ namespace BeWo
|
||||
showBetrag = true;
|
||||
showPivotGrid = true;
|
||||
showArbeitszeiten = true;
|
||||
showMarker = true;
|
||||
//showMarker = true;
|
||||
showUrlaubsplanung = true;
|
||||
showDienstplanung = true;
|
||||
showHilfeplanBezeichnung = true;
|
||||
|
||||
@@ -696,7 +696,7 @@ namespace BeWo
|
||||
|
||||
public bool DoSaveCheck()
|
||||
{
|
||||
return _CurrentDetailView == null || _CurrentDetailView.DoSaveCheck();
|
||||
return _CurrentDetailView is null || _CurrentDetailView.DoSaveCheck();
|
||||
}
|
||||
|
||||
private void InitCommandBindings()
|
||||
@@ -706,7 +706,7 @@ namespace BeWo
|
||||
ApplicationCommands.Save,
|
||||
(s, e) =>
|
||||
{
|
||||
if (_CurrentModalPopup == null)
|
||||
if (_CurrentModalPopup is null)
|
||||
{
|
||||
_CurrentDetailView.SaveData();
|
||||
}
|
||||
@@ -717,13 +717,13 @@ namespace BeWo
|
||||
},
|
||||
(s, e) =>
|
||||
{
|
||||
if (_CurrentModalPopup == null)
|
||||
if (_CurrentModalPopup is null)
|
||||
{
|
||||
e.CanExecute = _CurrentDetailView != null ? _CurrentDetailView.IsDirty : false;
|
||||
e.CanExecute = _CurrentDetailView?.IsDirty ?? false;
|
||||
}
|
||||
else
|
||||
{
|
||||
e.CanExecute = _CurrentDetailView != null && (_CurrentModalPopup is BeWoView && ((BeWoView) _CurrentModalPopup).IsDirty);
|
||||
e.CanExecute = _CurrentDetailView != null && (_CurrentModalPopup is BeWoView view && view.IsDirty);
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ namespace BeWo.View.Master
|
||||
}
|
||||
|
||||
// Mitarbeiterstundenkonto
|
||||
if (BeWoApp.Tenant == "3010479871" || (!BeWoApp.LoggedOnUser.HasRight(UserRightType.Mitarbeiterstundenkonto_ViewAll) && !BeWoApp.LoggedOnUser.HasRight(UserRightType.Mitarbeiterstundenkonto_ViewSelf) && !BeWoApp.LoggedOnUser.HasRight(UserRightType.Mitarbeiterstundenkonto_ViewTeams)))
|
||||
if(BeWoApp.Tenant == "3010479871" || (!BeWoApp.LoggedOnUser.HasRight(UserRightType.Mitarbeiterstundenkonto_ViewAll) && !BeWoApp.LoggedOnUser.HasRight(UserRightType.Mitarbeiterstundenkonto_ViewSelf) && !BeWoApp.LoggedOnUser.HasRight(UserRightType.Mitarbeiterstundenkonto_ViewTeams)))
|
||||
{
|
||||
//Aachener Verein
|
||||
tabitem_makonto.Visibility = Visibility.Collapsed;
|
||||
|
||||
@@ -126,6 +126,8 @@ namespace BeWoPlanerMobil.Controllers
|
||||
TempData["show_pw_change_popup"] = tempDataValue;
|
||||
}
|
||||
}
|
||||
|
||||
Model.ShowMarker = UserSettingsUtils.GetSettingValueAsBool(Model.Mandator.Settings, SettingsKeys.ShowMarker);
|
||||
}
|
||||
|
||||
var mandatorSettings = Model.Mandator.Settings;
|
||||
@@ -270,7 +272,6 @@ namespace BeWoPlanerMobil.Controllers
|
||||
Log.Info($"Model.SupportConceptListObjects Oids = {sb}");
|
||||
|
||||
}
|
||||
//Log.Info(String.Format("Main() Set CostBearer2SupportConceptOid = -1: Model.SelectedSupportConceptListObject is null {0}, isInList {1}", Model.SelectedSupportConceptListObject is null, isInList));
|
||||
|
||||
Model.SelectedSupportConceptListObject = Model.SupportConceptListObjects.FirstOrDefault(f => f.CostBearer2SupportConceptOid == "-1") ?? Model.SupportConceptListObjects.First();
|
||||
Model.CostBearer2SupportConceptOid = -1;
|
||||
@@ -926,6 +927,7 @@ namespace BeWoPlanerMobil.Controllers
|
||||
appointmentListItemPrototype = appointmentListItem;
|
||||
}
|
||||
|
||||
var marker = "on" == collection[FormCollectionConstants.MarkerKey];
|
||||
string doku1;
|
||||
|
||||
if(Model.Dokutypes != null && Model.Dokutypes.Length > 0)
|
||||
@@ -1035,7 +1037,10 @@ namespace BeWoPlanerMobil.Controllers
|
||||
Model.NewServiceRecord.Goals = Model.SelectedGoals;
|
||||
Model.NewServiceRecord.Start = zeitenFeld[0];
|
||||
Model.NewServiceRecord.End = zeitenFeld[1];
|
||||
|
||||
if(marker)
|
||||
{
|
||||
Model.NewServiceRecord.ServiceRecordType = ServiceRecordTypeId.Content;
|
||||
}
|
||||
Model.NewServiceRecord.DistanceInMeterDecimal = distanceInMeters;
|
||||
|
||||
if(Model.Employee.EmployeeOid.HasValue)
|
||||
@@ -2287,9 +2292,6 @@ namespace BeWoPlanerMobil.Controllers
|
||||
var newResult = new ValidationResult();
|
||||
var exitLoop = false;
|
||||
|
||||
// ToDo: Prüfen, ob eine Monatsunterschrift mit dem ServiceRecord verbunden ist und, ob die Zeiten geändert wurden.
|
||||
// ToDo: Ist dem so, dann eine Warnung anzeigen, dass die damit verknpüpfte Unterschrift ungültig oder gelöscht wird, und so nicht mehr auf dem QB angezeigt wird.
|
||||
|
||||
if(Model.SelectedSupportConcept != null && Model.SelectedSupportConcept.Goals.Any() && Model.SelectedGoals.Count == 0)
|
||||
{
|
||||
newResult.Message += "Es wurden keine Ziele zugeordnet.<br/><br/>";
|
||||
@@ -3037,6 +3039,8 @@ namespace BeWoPlanerMobil.Controllers
|
||||
return View("Main", Model);
|
||||
}
|
||||
|
||||
var marker = "on" == formCollection[FormCollectionConstants.MarkerKey];
|
||||
|
||||
var distanz = formCollection[FormCollectionConstants.DistanceKey];
|
||||
decimal? distanceInMeters = null;
|
||||
|
||||
@@ -3126,6 +3130,11 @@ namespace BeWoPlanerMobil.Controllers
|
||||
Model.NewServiceRecord.Start = zeitenFeld[0];
|
||||
Model.NewServiceRecord.End = zeitenFeld[1];
|
||||
|
||||
if(marker)
|
||||
{
|
||||
Model.NewServiceRecord.ServiceRecordType = ServiceRecordTypeId.Content;
|
||||
}
|
||||
|
||||
Model.NewServiceRecord.DistanceInMeterDecimal = distanceInMeters;
|
||||
|
||||
if(Model.Employee.EmployeeOid.HasValue)
|
||||
@@ -3545,6 +3554,8 @@ namespace BeWoPlanerMobil.Controllers
|
||||
return View("Main", Model);
|
||||
}
|
||||
|
||||
var marker = "on" == formCollection[FormCollectionConstants.MarkerKey];
|
||||
|
||||
var distanz = formCollection[FormCollectionConstants.DistanceKey];
|
||||
decimal? distanceInMeters = null;
|
||||
|
||||
@@ -3664,6 +3675,11 @@ namespace BeWoPlanerMobil.Controllers
|
||||
ServiceDescription = OperationsService.GetServiceDescription(Model.SelectedServiceDescriptionOid.Value)
|
||||
};
|
||||
|
||||
if(marker)
|
||||
{
|
||||
newServiceRecord.ServiceRecordType = ServiceRecordTypeId.Content;
|
||||
}
|
||||
|
||||
if(Model.IsEndDateVisible)
|
||||
{
|
||||
newServiceRecord.ServiceRecordFormat = ServiceRecordFormate.ZeiterfassungMitEndDatum;
|
||||
|
||||
@@ -56,23 +56,23 @@ namespace BeWoPlanerMobil.Controllers
|
||||
|
||||
if(AbstractModel.HasRightToInsertRessourceAppointments)
|
||||
{
|
||||
var allResources = KalenderService.GetAllResources().ToList();
|
||||
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)).ToList());
|
||||
categories2Resources.AddOrUpdateValueInDictionary(category, allResources.Where(resource => resource.ResourceCategory.Equals(category)).OrderBy(r => r.Name).ToList());
|
||||
}
|
||||
|
||||
Model.ResourceCategories2Resources = categories2Resources;
|
||||
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);
|
||||
Model.MyTeamEmployees = EmployeeService.GetAllTeamMember(compactEmployee).OrderBy(employee => employee.LastName).ToList();
|
||||
}
|
||||
else if(!(Model is null))
|
||||
{
|
||||
@@ -81,7 +81,7 @@ namespace BeWoPlanerMobil.Controllers
|
||||
|
||||
if(AbstractModel.HasRightToViewTeams && (Model?.Employee?.EmployeeOid.HasValue ?? false))
|
||||
{
|
||||
Model.MyTeams = EmployeeService.GetAllActiveCompactTeamsForEmployee(Model.Employee.EmployeeOid.Value);
|
||||
Model.MyTeams = EmployeeService.GetAllActiveCompactTeamsForEmployee(Model.Employee.EmployeeOid.Value).OrderBy(team => team.Name).ToList();
|
||||
}
|
||||
|
||||
if(!(Model is null))
|
||||
@@ -175,13 +175,13 @@ namespace BeWoPlanerMobil.Controllers
|
||||
if(AbstractModel.HasRightToViewCustomerSelectionInScheduler)
|
||||
{
|
||||
//Model.AllCustomers = EmployeeService.GetActiveCompactCustomersForEmployee(Model.Employee.EmployeeOid).OrderBy(o => o.DetailDescription).ToList();
|
||||
Model.AllCustomers = CustomerService.GetAllActiveCompactCustomers();
|
||||
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();
|
||||
Model.AllEmployees = EmployeeService.GetAllActiveEmployeesCompact().OrderBy(employee => employee.LastName).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -610,59 +610,61 @@ namespace BeWoPlanerMobil.Controllers
|
||||
return LeerzeichenFuerGetMethoden;
|
||||
}
|
||||
|
||||
var oidList = ConvertOidStringToList(resourceOids);
|
||||
|
||||
foreach(var oid in oidList)
|
||||
{
|
||||
if(!Model.ResourceCategories2Resources.Any(a => a.Value.All(b => b.ResourceOid != oid)))
|
||||
{
|
||||
return JsonConvert.SerializeObject(new List<ResourceDC>());
|
||||
}
|
||||
}
|
||||
|
||||
var dateTimes = ConvertStringDatesToDateTimes(start, end);
|
||||
|
||||
var unavailableResources = KalenderService.CheckResourceAvailability(dateTimes.StartDate, dateTimes.EndDate, oidList, Model.SelectedAppointment?.SchedulerAppointmentOid);
|
||||
|
||||
return JsonConvert.SerializeObject(unavailableResources);
|
||||
|
||||
// ToDo: Wieder einchecken
|
||||
// ALT!
|
||||
//var oidList = ConvertOidStringToList(resourceOids);
|
||||
|
||||
//foreach(var oid in oidList)
|
||||
//{
|
||||
// if(!Model.ResourceCategories2Resources.Any(a => a.Value.All(b => b.ResourceOid != oid)))
|
||||
// {
|
||||
// return LeerzeichenFuerGetMethoden;
|
||||
// return JsonConvert.SerializeObject(new List<ResourceDC>());
|
||||
// }
|
||||
//}
|
||||
|
||||
//var dateTimes = ConvertStringDatesToDateTimes(start, end);
|
||||
|
||||
//if(allDay)
|
||||
//{
|
||||
// dateTimes.EndDate = dateTimes.EndDate.AddDays(1);
|
||||
//}
|
||||
//var unavailableResources = KalenderService.CheckResourceAvailability(dateTimes.StartDate, dateTimes.EndDate, oidList, Model.SelectedAppointment?.SchedulerAppointmentOid);
|
||||
|
||||
//var info = KalenderService.CheckResourceAvailabilityWithEmployeeInformation(dateTimes.StartDate, dateTimes.EndDate, oidList, Model.SelectedAppointment?.SchedulerAppointmentOid);
|
||||
//return JsonConvert.SerializeObject(unavailableResources);
|
||||
|
||||
//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 />";
|
||||
// }
|
||||
var oidList = ConvertOidStringToList(resourceOids);
|
||||
|
||||
// foreach(var interval in kvp.Value)
|
||||
// {
|
||||
// result += $"{interval}<br />";
|
||||
// }
|
||||
//}
|
||||
foreach(var oid in oidList)
|
||||
{
|
||||
if(!Model.ResourceCategories2Resources.Any(a => a.Value.All(b => b.ResourceOid != oid)))
|
||||
{
|
||||
return LeerzeichenFuerGetMethoden;
|
||||
}
|
||||
}
|
||||
|
||||
//return result;
|
||||
var dateTimes = ConvertStringDatesToDateTimes(start, end);
|
||||
|
||||
if(allDay)
|
||||
{
|
||||
dateTimes.EndDate = dateTimes.EndDate.AddDays(1);
|
||||
}
|
||||
|
||||
var recurrenceId = Model.SelectedAppointment.RecurrenceId;
|
||||
var recurrenceIndex = Model.SelectedAppointment.RecurrenceIndex;
|
||||
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]
|
||||
|
||||
@@ -155,7 +155,28 @@ namespace BeWoPlanerMobil.Models
|
||||
public static bool HasRightMitarbeiterstundenkontoViewTeams => CheckRight(UserRightType.Mitarbeiterstundenkonto_ViewTeams);
|
||||
public static bool HasRightMitarbeiterstundenkontoViewSelf => CheckRight(UserRightType.Mitarbeiterstundenkonto_ViewSelf);
|
||||
|
||||
public static bool HasRightToViewReports => CheckRight(UserRightType.QueryView_View);
|
||||
public static bool HasRightToViewReports => CheckForAtLeastOneRight(new UserRightType[]
|
||||
{
|
||||
UserRightType.ViewAll,
|
||||
UserRightType.QueryView_View,
|
||||
UserRightType.Analysis_ServiceOverview_View,
|
||||
UserRightType.Analysis_Auslastung_View,
|
||||
UserRightType.Analysis_AuslastungAllEmployee_View,
|
||||
UserRightType.Analysis_AuslastungTeam_View,
|
||||
UserRightType.Kilometerauswertung_View,
|
||||
UserRightType.KilometerauswertungEigene_View,
|
||||
UserRightType.BewertungAuswertung_View,
|
||||
UserRightType.PivotTabelleAnsehen,
|
||||
UserRightType.DienstplanungAnsehen,
|
||||
UserRightType.AbwesenheitsPlanungAnsehen,
|
||||
UserRightType.Mitarbeiterstundenkonto_ViewAll,
|
||||
UserRightType.Mitarbeiterstundenkonto_ViewSelf,
|
||||
UserRightType.Mitarbeiterstundenkonto_ViewTeams,
|
||||
UserRightType.Jahresbericht,
|
||||
UserRightType.Auswertungen_BerichteAnsehen,
|
||||
UserRightType.Auswertungen_StundenuebersichtAnsehen,
|
||||
UserRightType.Auswertungen_HilfeplanuebersichtAnsehen
|
||||
});
|
||||
|
||||
public static bool HasRightToViewMitarbeiterstundenkonto
|
||||
{
|
||||
|
||||
@@ -729,6 +729,8 @@ namespace BeWoPlanerMobil.Models
|
||||
public MandatorDC Mandator { get; set; }
|
||||
|
||||
public bool IsPasswordSecurityEnabled { get; set; }
|
||||
|
||||
public bool ShowMarker { get; set; }
|
||||
}
|
||||
|
||||
public class CustomSelectListItem
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace BeWoPlanerMobil.Models
|
||||
allResources.AddRangeIfElementsNotIn(cat2res.Value);
|
||||
}
|
||||
|
||||
return allResources;
|
||||
return allResources.OrderBy(resource => resource.Name).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -100,11 +100,11 @@ function submitGroupBookingForm() {
|
||||
}
|
||||
|
||||
function deactivateGroupBookingForm() {
|
||||
$("#employees-button, #category-select, #leistung-select, #start-date, #end-date, #start-time, #end-time, #duration, #distance, textarea, #reset-button, #create-button, #textbausteine-button, #hours-minutes-dropdown-btn").prop("disabled", true);
|
||||
$("#employees-button, #category-select, #leistung-select, #start-date, #end-date, #start-time, #end-time, #duration, #distance, textarea, #reset-button, #create-button, #textbausteine-button, #hours-minutes-dropdown-btn, #gb-marker-cb").prop("disabled", true);
|
||||
}
|
||||
|
||||
function activateGroupBookingForm() {
|
||||
$("#employees-button, #category-select, #leistung-select, #start-date, #end-date, #start-time, #end-time, #duration, #distance, textarea, #reset-button, #create-button, #textbausteine-button, #hours-minutes-dropdown-btn").prop("disabled", false);
|
||||
$("#employees-button, #category-select, #leistung-select, #start-date, #end-date, #start-time, #end-time, #duration, #distance, textarea, #reset-button, #create-button, #textbausteine-button, #hours-minutes-dropdown-btn, #gb-marker-cb").prop("disabled", false);
|
||||
}
|
||||
|
||||
function deleteServiceRecord(serviceRecordOid) {
|
||||
|
||||
@@ -121,57 +121,56 @@ function validateAppointmentForm() {
|
||||
$.get(getCheckResourcesAvailabilityUrl(), { start: startDate.format("DD.MM.YYYY HH:mm"), end: endDate.format("DD.MM.YYYY HH:mm"), resourceOids: oidString, allDay: isAllDay }).done(function(result) {
|
||||
if (result.length > 1) {
|
||||
try {
|
||||
// ToDo: Wieder einchecken! (24.07.2023)
|
||||
//hideSpinner();
|
||||
|
||||
//if (result.includes("Fehler!")) {
|
||||
// showErrorMessagePopup(result.substring(7));
|
||||
// return;
|
||||
//} else {
|
||||
// showMessagePopupWithHtml("Überschneidung",
|
||||
// result,
|
||||
// function() {
|
||||
// $("#messagePopup .modal-body").html();
|
||||
// showSpinner();
|
||||
// insertOrUpdateAppointment(startDate.format("DD.MM.YYYY"), endDate.format("DD.MM.YYYY"), startDate.format("HH:mm"), endDate.format("HH:mm"));
|
||||
// },
|
||||
// false);
|
||||
//}
|
||||
|
||||
|
||||
var unavailableResources = $.parseJSON(result);
|
||||
var resourceCount = 0;
|
||||
var names = "";
|
||||
|
||||
$.each(unavailableResources, function(index, resource) {
|
||||
if (names.length > 1) {
|
||||
names += ", ";
|
||||
}
|
||||
|
||||
resourceCount++;
|
||||
|
||||
names += resource.Name;
|
||||
});
|
||||
|
||||
var unavailableResourcesMessage;
|
||||
|
||||
if(resourceCount > 0) {
|
||||
if(resourceCount > 1) {
|
||||
unavailableResourcesMessage = "Einige der ausgewählten Ressourcen (" + names + ") sind zum gewählten Zeitpunkt nicht verfügbar.";
|
||||
} else {
|
||||
unavailableResourcesMessage = "Eine der ausgewählten Ressourcen (" + names + ") ist zum gewählten Zeitpunkt nicht verfügbar.";
|
||||
}
|
||||
|
||||
hideSpinner();
|
||||
|
||||
showWarningMessageBox("Überschneidung", unavailableResourcesMessage, function() {
|
||||
$("#messagePopup .modal-body").html();
|
||||
showSpinner();
|
||||
insertOrUpdateAppointment(startDate.format("DD.MM.YYYY"), endDate.format("DD.MM.YYYY"), startDate.format("HH:mm"), endDate.format("HH:mm"));
|
||||
}, false);
|
||||
hideSpinner();
|
||||
|
||||
if (result.includes("Fehler!")) {
|
||||
showErrorMessagePopup(result.substring(7));
|
||||
return;
|
||||
} else {
|
||||
showMessagePopupWithHtml("Überschneidung",
|
||||
result,
|
||||
function() {
|
||||
$("#messagePopup .modal-body").html();
|
||||
showSpinner();
|
||||
insertOrUpdateAppointment(startDate.format("DD.MM.YYYY"), endDate.format("DD.MM.YYYY"), startDate.format("HH:mm"), endDate.format("HH:mm"));
|
||||
},
|
||||
false);
|
||||
}
|
||||
|
||||
// ALT!
|
||||
//var unavailableResources = $.parseJSON(result);
|
||||
//var resourceCount = 0;
|
||||
//var names = "";
|
||||
|
||||
//$.each(unavailableResources, function(index, resource) {
|
||||
// if (names.length > 1) {
|
||||
// names += ", ";
|
||||
// }
|
||||
|
||||
// resourceCount++;
|
||||
|
||||
// names += resource.Name;
|
||||
//});
|
||||
|
||||
//var unavailableResourcesMessage;
|
||||
|
||||
//if(resourceCount > 0) {
|
||||
// if(resourceCount > 1) {
|
||||
// unavailableResourcesMessage = "Einige der ausgewählten Ressourcen (" + names + ") sind zum gewählten Zeitpunkt nicht verfügbar.";
|
||||
// } else {
|
||||
// unavailableResourcesMessage = "Eine der ausgewählten Ressourcen (" + names + ") ist zum gewählten Zeitpunkt nicht verfügbar.";
|
||||
// }
|
||||
|
||||
// hideSpinner();
|
||||
|
||||
// showWarningMessageBox("Überschneidung", unavailableResourcesMessage, function() {
|
||||
// $("#messagePopup .modal-body").html();
|
||||
// showSpinner();
|
||||
// insertOrUpdateAppointment(startDate.format("DD.MM.YYYY"), endDate.format("DD.MM.YYYY"), startDate.format("HH:mm"), endDate.format("HH:mm"));
|
||||
// }, false);
|
||||
|
||||
// return;
|
||||
//}
|
||||
} catch (error) {
|
||||
showErrorPopup(error);
|
||||
return;
|
||||
|
||||
@@ -24,10 +24,9 @@
|
||||
public static string RecordsKey => "Records";
|
||||
public static string ServiceRecordOidHolder2Key => "service-record-oid-holder";
|
||||
public static string IsInGroupBookingModeKey => "IsInGroupBookingMode";
|
||||
|
||||
public static string IsInMultiBookingModeKey => "IsInMultiBookingMode";
|
||||
|
||||
public static string DurationInMinutesKey => "DurationInMinutes";
|
||||
public static string MarkerKey => "marker-cb";
|
||||
|
||||
// Kalender
|
||||
public static string AppointmentStartDateKey => "StartDate";
|
||||
|
||||
@@ -146,6 +146,25 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Marker -->
|
||||
@if(Model.ShowMarker)
|
||||
{
|
||||
<div class="form-row">
|
||||
<div class="col-md">
|
||||
<div class="custom-control custom-checkbox custom-control-inline">
|
||||
<input type="checkbox" class="custom-control-input" name="marker-cb" id="gb-marker-cb" />
|
||||
<label class="custom-control-label" for="gb-marker-cb">Marker</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="form-row">
|
||||
<div class="col-md">
|
||||
<hr/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Start- und Enddatum -->
|
||||
<div class="form-row">
|
||||
|
||||
@@ -235,14 +235,14 @@
|
||||
$("#employeesDropDown, #category-select, #leistung-select, " +
|
||||
"#start-date, #end-date, #start-time, #end-time, #duration, " +
|
||||
"#distance, #textbausteine-button, #goals-button, textarea, #reset-button, " +
|
||||
"#create-button, #statistics-button, #timeFrameSelect, #hours-minutes-dropdown-btn").prop("disabled", (isSupportConceptSelected ? false : true));
|
||||
"#create-button, #statistics-button, #timeFrameSelect, #hours-minutes-dropdown-btn, #marker-cb").prop("disabled", (isSupportConceptSelected ? false : true));
|
||||
|
||||
if("@Model.IsInGroupBookingMode".toLowerCase() === "true") {
|
||||
var hasSelectedSupportConcepts = "@Model.SelectedConceptCostBearerRelations.Any()".toLowerCase() === "true";
|
||||
|
||||
$("#employees-button, #category-select, #leistung-select, " +
|
||||
"#start-date, #end-date, #start-time, #end-time, #duration, " +
|
||||
"#distance, textarea, #reset-button, #create-button, #textbausteine-button, #hours-minutes-dropdown-btn").prop("disabled", (hasSelectedSupportConcepts ? false : true));
|
||||
"#distance, textarea, #reset-button, #create-button, #textbausteine-button, #hours-minutes-dropdown-btn, #gb-marker-cb").prop("disabled", (hasSelectedSupportConcepts ? false : true));
|
||||
}
|
||||
|
||||
$("#fehlerdetail-textarea").prop("disabled", false);
|
||||
|
||||
@@ -204,7 +204,7 @@
|
||||
|
||||
function deactivateMultiBookingForm() {
|
||||
try {
|
||||
$("#multi-booking-employees-button, #mb-category-select, #mb-leistung-select, #mb-start-date, #mb-end-date, #mb-start-time, #mb-end-time, #mb-duration, #mb-distance, textarea, #mb-reset-button, #mb-create-button, #mb-textbausteine-button, #mb-hours-minutes-dropdown-btn").prop("disabled", true);
|
||||
$("#multi-booking-employees-button, #mb-category-select, #mb-leistung-select, #mb-start-date, #mb-end-date, #mb-start-time, #mb-end-time, #mb-duration, #mb-distance, textarea, #mb-reset-button, #mb-create-button, #mb-textbausteine-button, #mb-hours-minutes-dropdown-btn, #mb-marker-cb").prop("disabled", true);
|
||||
} catch (error) {
|
||||
showErrorPopup(error);
|
||||
}
|
||||
@@ -212,7 +212,7 @@
|
||||
|
||||
function activateMultiBookingForm() {
|
||||
try {
|
||||
$("#multi-booking-employees-button, #mb-category-select, #mb-leistung-select, #mb-start-date, #mb-end-date, #mb-start-time, #mb-end-time, #mb-duration, #mb-distance, textarea, #mb-reset-button, #mb-create-button, #mb-textbausteine-button, #mb-hours-minutes-dropdown-btn").prop("disabled", false);
|
||||
$("#multi-booking-employees-button, #mb-category-select, #mb-leistung-select, #mb-start-date, #mb-end-date, #mb-start-time, #mb-end-time, #mb-duration, #mb-distance, textarea, #mb-reset-button, #mb-create-button, #mb-textbausteine-button, #mb-hours-minutes-dropdown-btn, #mb-marker-cb").prop("disabled", false);
|
||||
} catch (error) {
|
||||
showErrorPopup(error);
|
||||
}
|
||||
@@ -339,6 +339,25 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Marker -->
|
||||
@if(Model.ShowMarker)
|
||||
{
|
||||
<div class="form-row">
|
||||
<div class="col-md">
|
||||
<div class="custom-control custom-checkbox custom-control-inline">
|
||||
<input type="checkbox" class="custom-control-input" name="marker-cb" id="mb-marker-cb" />
|
||||
<label class="custom-control-label" for="mb-marker-cb">Marker</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="form-row">
|
||||
<div class="col-md">
|
||||
<hr/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Start- und Enddatum -->
|
||||
<div class="form-row">
|
||||
|
||||
@@ -133,81 +133,121 @@
|
||||
|
||||
using(Html.BeginForm("CreateOrUpdateServiceRecord", "Main", FormMethod.Post, new { onreset = "serviceDescriptionSelectOnReset('category-select', 'leistung-select', 'textmodule-container', 'tree')", id = "singleBookingForm" }))
|
||||
{
|
||||
<div class="mt-3">
|
||||
<!-- Einzelbuchung: Mitarbeiter -->
|
||||
<div class="mt-3">
|
||||
<!-- Einzelbuchung: Mitarbeiter -->
|
||||
<div class="form-row">
|
||||
<div class="col-md">
|
||||
<div class="form-group my-2">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text prepend-input-group-text">Mitarbeiter</div>
|
||||
</div>
|
||||
@Html.DropDownListFor(m => m.SelectedEmployeeOid, Model.EmployeeListItems, new { id = "employeesDropDown", @class = "custom-select", onchange = "setSelectedEmployee()" })
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@if(Model.SelectedSupportConcept != null && Model.SelectedSupportConcept.Goals.Any())
|
||||
{
|
||||
<!-- Einzelbuchung: Ziele -->
|
||||
<div class="form-row">
|
||||
<div class="col-md">
|
||||
<div class="form-group my-2">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text prepend-input-group-text">Mitarbeiter</div>
|
||||
<button type="button" class="btn btn-primary form-control my-3" data-toggle="modal" data-target="#goal-popup" id="goals-button">Ziele</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="col-md">
|
||||
<div class="collapse w-100 mt-1 max-vw-50" id="goals-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
}
|
||||
|
||||
<!-- Einzelbuchung: Leistungskategorie -->
|
||||
<div class="form-row">
|
||||
<div class="col-md">
|
||||
<div class="form-group my-2">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text prepend-input-group-text">
|
||||
Kategorie
|
||||
</div>
|
||||
</div>
|
||||
@Html.DropDownListFor(m => m.SelectedServiceCategoryOid, Model.ServiceCategoryListItems, new { onchange = "loadServiceDescriptions('category-select', 'leistung-select', 'textmodule-container', 'tree')", @class = "custom-select", Id = "category-select" })
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Einzelbuchung: Leistung -->
|
||||
<div class="form-row">
|
||||
<div class="col-md">
|
||||
<div class="form-group my-2">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text prepend-input-group-text">
|
||||
Leistung
|
||||
</div>
|
||||
</div>
|
||||
<select class="custom-select" id="leistung-select" name="ServiceDescription" onchange="setServiceDescription('leistung-select')">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Marker -->
|
||||
@if(Model.ShowMarker)
|
||||
{
|
||||
<div class="form-row">
|
||||
<div class="col-md">
|
||||
<div class="custom-control custom-checkbox custom-control-inline">
|
||||
<input type="checkbox" class="custom-control-input" name="marker-cb" id="marker-cb" />
|
||||
<label class="custom-control-label" for="marker-cb">Marker</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="form-row">
|
||||
<div class="col-md">
|
||||
<hr />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Einzelbuchung: Startdatum -->
|
||||
<div class="form-row">
|
||||
<div class="col-md">
|
||||
<div class="form-group my-2">
|
||||
<div class="input-group date" id="start-date-picker" data-target-input="nearest">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text prepend-input-group-text">
|
||||
Startdatum
|
||||
</div>
|
||||
</div>
|
||||
<input type="text" id="start-date" name="Datum" class="form-control datetimepicker-input" data-target="#start-date-picker" data-toggle="datetimepicker" value="@Model.StartDateToEdit" />
|
||||
<div class="input-group-append" data-target="#start-date-picker" data-toggle="datetimepicker">
|
||||
<div class="input-group-text px-2">
|
||||
<i class="fas fa-calendar-alt"></i>
|
||||
</div>
|
||||
@Html.DropDownListFor(m => m.SelectedEmployeeOid, Model.EmployeeListItems, new { id = "employeesDropDown", @class = "custom-select", onchange = "setSelectedEmployee()" })
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@if(Model.SelectedSupportConcept != null && Model.SelectedSupportConcept.Goals.Any())
|
||||
<!-- Einzelbuchung: Enddatum -->
|
||||
@if(Model.IsEndDateVisible)
|
||||
{
|
||||
<!-- Einzelbuchung: Ziele -->
|
||||
<div class="form-row">
|
||||
<div class="col-md">
|
||||
<button type="button" class="btn btn-primary form-control my-3" data-toggle="modal" data-target="#goal-popup" id="goals-button">Ziele</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="col-md">
|
||||
<div class="collapse w-100 mt-1 max-vw-50" id="goals-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
}
|
||||
|
||||
<!-- Einzelbuchung: Leistungskategorie -->
|
||||
<div class="form-row">
|
||||
<div class="col-md">
|
||||
<div class="form-group my-2">
|
||||
<div class="input-group">
|
||||
<div class="input-group date" id="end-date-picker" data-target-input="nearest">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text prepend-input-group-text">
|
||||
Kategorie
|
||||
Enddatum
|
||||
</div>
|
||||
</div>
|
||||
@Html.DropDownListFor(m => m.SelectedServiceCategoryOid, Model.ServiceCategoryListItems, new { onchange = "loadServiceDescriptions('category-select', 'leistung-select', 'textmodule-container', 'tree')", @class = "custom-select", Id = "category-select" })
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Einzelbuchung: Leistung -->
|
||||
<div class="form-row">
|
||||
<div class="col-md">
|
||||
<div class="form-group my-2">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text prepend-input-group-text">
|
||||
Leistung
|
||||
</div>
|
||||
</div>
|
||||
<select class="custom-select" id="leistung-select" name="ServiceDescription" onchange="setServiceDescription('leistung-select')">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Einzelbuchung: Startdatum -->
|
||||
<div class="form-row">
|
||||
<div class="col-md">
|
||||
<div class="form-group my-2">
|
||||
<div class="input-group date" id="start-date-picker" data-target-input="nearest">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text prepend-input-group-text">
|
||||
Startdatum
|
||||
</div>
|
||||
</div>
|
||||
<input type="text" id="start-date" name="Datum" class="form-control datetimepicker-input" data-target="#start-date-picker" data-toggle="datetimepicker" value="@Model.StartDateToEdit" />
|
||||
<div class="input-group-append" data-target="#start-date-picker" data-toggle="datetimepicker">
|
||||
<input type="text" id="end-date" name="Enddatum" class="form-control datetimepicker-input" data-target="#end-date-picker" data-toggle="datetimepicker" value="@Model.EndDateToEdit" />
|
||||
<div class="input-group-append" data-target="#end-date-picker" data-toggle="datetimepicker">
|
||||
<div class="input-group-text px-2">
|
||||
<i class="fas fa-calendar-alt"></i>
|
||||
</div>
|
||||
@@ -215,182 +255,162 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Einzelbuchung: Enddatum -->
|
||||
@if(Model.IsEndDateVisible)
|
||||
{
|
||||
<div class="col-md">
|
||||
<div class="form-group my-2">
|
||||
<div class="input-group date" id="end-date-picker" data-target-input="nearest">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text prepend-input-group-text">
|
||||
Enddatum
|
||||
</div>
|
||||
</div>
|
||||
<input type="text" id="end-date" name="Enddatum" class="form-control datetimepicker-input" data-target="#end-date-picker" data-toggle="datetimepicker" value="@Model.EndDateToEdit" />
|
||||
<div class="input-group-append" data-target="#end-date-picker" data-toggle="datetimepicker">
|
||||
<div class="input-group-text px-2">
|
||||
<i class="fas fa-calendar-alt"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<!-- Einzelbuchung: Von -->
|
||||
<div class="form-row">
|
||||
@{
|
||||
var startTimeValue = Model.StartTimeToEdit;
|
||||
var endTimeValue = Model.EndTimeToEdit;
|
||||
var divisor = Model.SelectedDurationUnit == "Stunden" ? 60 : 1;
|
||||
var durationValue = Model.DurationToEdit;
|
||||
}
|
||||
</div>
|
||||
<!-- Einzelbuchung: Von -->
|
||||
<div class="form-row">
|
||||
@{
|
||||
var startTimeValue = Model.StartTimeToEdit;
|
||||
var endTimeValue = Model.EndTimeToEdit;
|
||||
var divisor = Model.SelectedDurationUnit == "Stunden" ? 60 : 1;
|
||||
var durationValue = Model.DurationToEdit;
|
||||
|
||||
if(Model.SetStartTimeToEndTimeAfterSave && !Model.IsInEditingMode)
|
||||
if(Model.SetStartTimeToEndTimeAfterSave && !Model.IsInEditingMode)
|
||||
{
|
||||
startTimeValue = Model.NewStartTime;
|
||||
endTimeValue = Model.NewEndTime;
|
||||
durationValue = Model.NewDuration?.ToString();
|
||||
if(Model.NewDuration.HasValue)
|
||||
{
|
||||
startTimeValue = Model.NewStartTime;
|
||||
endTimeValue = Model.NewEndTime;
|
||||
durationValue = Model.NewDuration?.ToString();
|
||||
if(Model.NewDuration.HasValue)
|
||||
{
|
||||
durationValue = (Model.NewDuration / divisor).ToString();
|
||||
}
|
||||
durationValue = (Model.NewDuration / divisor).ToString();
|
||||
}
|
||||
}
|
||||
<div class="col-md">
|
||||
<div class="form-group my-2">
|
||||
<div class="input-group date" id="start-time-picker" data-target-input="nearest">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text sm-prepend-input-group-text px-2">
|
||||
Von
|
||||
</div>
|
||||
</div>
|
||||
<input type="text" id="start-time" name="Start" class="form-control datetimepicker-input" data-target="#start-time-picker" value="@startTimeValue" />
|
||||
<div class="input-group-append" data-target="#start-time-picker" data-toggle="datetimepicker">
|
||||
<div class="input-group-text px-2">
|
||||
<i class="fas fa-clock"></i>
|
||||
</div>
|
||||
}
|
||||
<div class="col-md">
|
||||
<div class="form-group my-2">
|
||||
<div class="input-group date" id="start-time-picker" data-target-input="nearest">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text sm-prepend-input-group-text px-2">
|
||||
Von
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Einzelbuchung: Bis -->
|
||||
<div class="col-md">
|
||||
<div class="form-group my-2">
|
||||
<div class="input-group date" id="end-time-picker" data-target-input="nearest">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text sm-prepend-input-group-text px-2">
|
||||
Bis
|
||||
</div>
|
||||
</div>
|
||||
<input type="text" id="end-time" name="Ende" class="form-control datetimepicker-input" data-target="#end-time-picker" value="@endTimeValue" />
|
||||
<div class="input-group-append" data-target="#end-time-picker" data-toggle="datetimepicker">
|
||||
<div class="input-group-text px-2">
|
||||
<i class="fas fa-clock"></i>
|
||||
</div>
|
||||
<input type="text" id="start-time" name="Start" class="form-control datetimepicker-input" data-target="#start-time-picker" value="@startTimeValue" />
|
||||
<div class="input-group-append" data-target="#start-time-picker" data-toggle="datetimepicker">
|
||||
<div class="input-group-text px-2">
|
||||
<i class="fas fa-clock"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Einzelbuchung: Dauer -->
|
||||
<!-- Einzelbuchung: Bis -->
|
||||
<div class="col-md">
|
||||
<div class="form-group my-2">
|
||||
<div class="input-group date" id="end-time-picker" data-target-input="nearest">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text sm-prepend-input-group-text px-2">
|
||||
Bis
|
||||
</div>
|
||||
</div>
|
||||
<input type="text" id="end-time" name="Ende" class="form-control datetimepicker-input" data-target="#end-time-picker" value="@endTimeValue" />
|
||||
<div class="input-group-append" data-target="#end-time-picker" data-toggle="datetimepicker">
|
||||
<div class="input-group-text px-2">
|
||||
<i class="fas fa-clock"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Einzelbuchung: Dauer -->
|
||||
<div class="form-row">
|
||||
<div class="col-md">
|
||||
<div class="form-group my-2">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
@{
|
||||
var labelText = Model.EinheitZeiterfassung == 1 ? "Dauer (h)" : "Dauer";
|
||||
}
|
||||
<div class="input-group-text prepend-input-group-text">
|
||||
@labelText
|
||||
</div>
|
||||
</div>
|
||||
<input type="text" class="form-control" id="duration" name="Dauer" onchange="onDurationChange('start-time', 'end-time', 'start-date', 'end-date', 'duration', 'hours-minutes-dropdown-btn', 'start-date-picker', 'end-date-picker')" value="@durationValue">
|
||||
@if(Model.IsZeiterfassungInStdMin)
|
||||
{
|
||||
<div class="input-group-append">
|
||||
<button id="hours-minutes-dropdown-btn" class="btn btn-outline-primary dropdown-toggle w-100" type="button" data-toggle="dropdown">
|
||||
@Model.SelectedDurationUnit
|
||||
</button>
|
||||
<div class="dropdown-menu w-100">
|
||||
<a class="dropdown-item hours-minutes-link" href="#">Minuten</a>
|
||||
<a class="dropdown-item hours-minutes-link" href="#">Stunden</a>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Einzelbuchung: Distanz -->
|
||||
@if(Model.ShowDistanceField)
|
||||
{
|
||||
<div class="form-row">
|
||||
<div class="col-md">
|
||||
<div class="form-group my-2">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
@{
|
||||
var labelText = Model.EinheitZeiterfassung == 1 ? "Dauer (h)" : "Dauer";
|
||||
}
|
||||
<div class="input-group-text prepend-input-group-text">
|
||||
@labelText
|
||||
<div class="input-group-text">
|
||||
Gefahrene Kilometer
|
||||
</div>
|
||||
</div>
|
||||
<input type="text" class="form-control" id="duration" name="Dauer" onchange="onDurationChange('start-time', 'end-time', 'start-date', 'end-date', 'duration', 'hours-minutes-dropdown-btn', 'start-date-picker', 'end-date-picker')" value="@durationValue">
|
||||
@if(Model.IsZeiterfassungInStdMin)
|
||||
{
|
||||
<div class="input-group-append">
|
||||
<button id="hours-minutes-dropdown-btn" class="btn btn-outline-primary dropdown-toggle w-100" type="button" data-toggle="dropdown">
|
||||
@Model.SelectedDurationUnit
|
||||
</button>
|
||||
<div class="dropdown-menu w-100">
|
||||
<a class="dropdown-item hours-minutes-link" href="#">Minuten</a>
|
||||
<a class="dropdown-item hours-minutes-link" href="#">Stunden</a>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<input class="form-control" id="distance" name="Distanz" onchange="validateDistanceInput()" value="@Model.DistanceToEdit">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Einzelbuchung: Distanz -->
|
||||
@if(Model.ShowDistanceField)
|
||||
{
|
||||
<div class="form-row">
|
||||
<div class="col-md">
|
||||
<div class="form-group my-2">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text">
|
||||
Gefahrene Kilometer
|
||||
</div>
|
||||
</div>
|
||||
<input class="form-control" id="distance" name="Distanz" onchange="validateDistanceInput()" value="@Model.DistanceToEdit">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@if(AbstractModel.HasRightToSeeTextModules)
|
||||
{
|
||||
<script>
|
||||
}
|
||||
@if(AbstractModel.HasRightToSeeTextModules)
|
||||
{
|
||||
<script>
|
||||
function textModuleButtonOnClick() {
|
||||
$('#tree').load('@Url.Action("LoadUpToDateTextModules")');
|
||||
}
|
||||
</script>
|
||||
<!-- Einzelbuchung: Textbausteine -->
|
||||
<div class="form-row" id="textmodule-container">
|
||||
<div class="col-md">
|
||||
<button type="button" class="btn btn-primary form-control mt-3" data-toggle="modal" data-target="#textbausteine-popup" id="textbausteine-button" onclick="textModuleButtonOnClick()">Textbausteine</button>
|
||||
</script>
|
||||
<!-- Einzelbuchung: Textbausteine -->
|
||||
<div class="form-row" id="textmodule-container">
|
||||
<div class="col-md">
|
||||
<button type="button" class="btn btn-primary form-control mt-3" data-toggle="modal" data-target="#textbausteine-popup" id="textbausteine-button" onclick="textModuleButtonOnClick()">Textbausteine</button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div class="form-row">
|
||||
<div class="col-md mt-3">
|
||||
@if(Model.NumberOfDokuTypes == 0)
|
||||
{
|
||||
<div class="form-group">
|
||||
<label for="dokufeld">Dokumentation</label>
|
||||
<textarea class="form-control" name="Dokumentation6" id="dokufeld">@Model.NoticeToEdit</textarea>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div class="form-row">
|
||||
<div class="col-md mt-3">
|
||||
@if(Model.NumberOfDokuTypes == 0)
|
||||
{
|
||||
<div class="form-group">
|
||||
<label for="dokufeld">Dokumentation</label>
|
||||
<textarea class="form-control" name="Dokumentation6" id="dokufeld">@Model.NoticeToEdit</textarea>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<ul class="nav nav-tabs" role="tab-list">
|
||||
@for(var i = 0; i < Model.Dokutypes.Length; i++)
|
||||
{
|
||||
var currentDokuType = Model.Dokutypes[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
<ul class="nav nav-tabs" role="tab-list">
|
||||
@for(var i = 0; i < Model.Dokutypes.Length; i++)
|
||||
{
|
||||
var currentDokuType = Model.Dokutypes[i];
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="#doku_@i" id="doku_@i-tab" data-toggle="tab" role="tab" aria-controls="doku_@i" class="nav-link@(i == 0 ? " active" : string.Empty)" aria-selected="true">
|
||||
@currentDokuType.DisplayName
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
<div class="tab-content" id="dokufelderTab">
|
||||
@for(var i = 0; i < Model.Dokutypes.Length; i++)
|
||||
{
|
||||
var textareaName = i + 1 < 1 ? "Dokumentation" : "Dokumentation" + (i + 1);
|
||||
<li class="nav-item">
|
||||
<a href="#doku_@i" id="doku_@i-tab" data-toggle="tab" role="tab" aria-controls="doku_@i" class="nav-link@(i == 0 ? " active" : string.Empty)" aria-selected="true">
|
||||
@currentDokuType.DisplayName
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
<div class="tab-content" id="dokufelderTab">
|
||||
@for(var i = 0; i < Model.Dokutypes.Length; i++)
|
||||
{
|
||||
var textareaName = i + 1 < 1 ? "Dokumentation" : "Dokumentation" + (i + 1);
|
||||
|
||||
<div class="tab-pane show@(i == 0 ? " active" : string.Empty)" id="doku_@i" role="tabpanel" aria-labelledby="doku_@i-tab">
|
||||
<textarea class="form-control doku-form-control" id="doku-textarea-@i" name="@textareaName">@Model.NoticeListToEdit[i]</textarea>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane show@(i == 0 ? " active" : string.Empty)" id="doku_@i" role="tabpanel" aria-labelledby="doku_@i-tab">
|
||||
<textarea class="form-control doku-form-control" id="doku-textarea-@i" name="@textareaName">@Model.NoticeListToEdit[i]</textarea>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="d-flex bd-highlight mt-3">
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
@if(Model.HasResourcesEmployeesOrCustomers)
|
||||
{
|
||||
<div class="form-row">
|
||||
@if(AbstractModel.HasRightToViewEmployeeAppointments)
|
||||
@if(AbstractModel.HasRightToViewEmployeeAppointments && AbstractModel.HasRightToInsertEmployeeAppointments)
|
||||
{
|
||||
<div class="col-md">
|
||||
<div class="form-group my-1">
|
||||
@@ -121,7 +121,7 @@
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@if(AbstractModel.HasRightToViewCustomerSelectionInScheduler)
|
||||
@if(AbstractModel.HasRightToViewCustomerSelectionInScheduler && AbstractModel.HasRightToInsertCustomerAppointments)
|
||||
{
|
||||
<div class="col-md">
|
||||
<div class="form-group my-1">
|
||||
@@ -129,7 +129,7 @@
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@if(AbstractModel.HasRightToViewAllResourceAppointments && Model.ResourceCategories2Resources.Any())
|
||||
@if(AbstractModel.HasRightToViewAllResourceAppointments && AbstractModel.HasRightToInsertRessourceAppointments && Model.ResourceCategories2Resources.Any())
|
||||
{
|
||||
<div class="col-md">
|
||||
<div class="form-group my-1">
|
||||
@@ -140,7 +140,7 @@
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
@if(AbstractModel.HasRightToViewEmployeeAppointments)
|
||||
@if(AbstractModel.HasRightToViewEmployeeAppointments && AbstractModel.HasRightToInsertEmployeeAppointments)
|
||||
{
|
||||
<div class="col-12">
|
||||
<div class="form-group my-1">
|
||||
@@ -169,7 +169,7 @@
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@if(AbstractModel.HasRightToViewCustomerSelectionInScheduler)
|
||||
@if(AbstractModel.HasRightToViewCustomerSelectionInScheduler && AbstractModel.HasRightToInsertCustomerAppointments)
|
||||
{
|
||||
<div class="col-12">
|
||||
<div class="form-group my-1">
|
||||
@@ -207,7 +207,7 @@
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@if(AbstractModel.HasRightToViewAllResourceAppointments)
|
||||
@if(AbstractModel.HasRightToViewAllResourceAppointments && AbstractModel.HasRightToInsertRessourceAppointments)
|
||||
{
|
||||
<div class="col-12">
|
||||
<div class="form-group my-1">
|
||||
@@ -293,7 +293,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if(AbstractModel.HasRightToViewAllResourceAppointments && Model.ResourceCategories2Resources.Any())
|
||||
@if(AbstractModel.HasRightToViewAllResourceAppointments && AbstractModel.HasRightToInsertRessourceAppointments && Model.ResourceCategories2Resources.Any())
|
||||
{
|
||||
<div class="modal" tabindex="-1" role="dialog" id="resources-popup">
|
||||
<div class="modal-dialog modal-dialog-scrollable" role="document">
|
||||
@@ -363,7 +363,7 @@
|
||||
</div>
|
||||
}
|
||||
|
||||
@if(AbstractModel.HasRightToViewEmployeeAppointments && Model.AllEmployees.Any())
|
||||
@if(AbstractModel.HasRightToViewEmployeeAppointments && AbstractModel.HasRightToInsertEmployeeAppointments && Model.AllEmployees.Any())
|
||||
{
|
||||
<script type="text/javascript">
|
||||
function resetEmployeeSearch() {
|
||||
@@ -583,7 +583,7 @@
|
||||
</div>
|
||||
}
|
||||
|
||||
@if(AbstractModel.HasRightToViewCustomerSelectionInScheduler && Model.AllCustomers.Any())
|
||||
@if(AbstractModel.HasRightToViewCustomerSelectionInScheduler && AbstractModel.HasRightToInsertCustomerAppointments && Model.AllCustomers.Any())
|
||||
{
|
||||
<div class="modal" tabindex="-1" role="dialog" id="customers-popup">
|
||||
<div class="modal-dialog modal-dialog-scrollable" role="document">
|
||||
|
||||
@@ -358,6 +358,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@if(AbstractModel.HasRightToViewQuittierungsbelege)
|
||||
{
|
||||
using(Html.BeginForm("RedirectToReportView", "Main", FormMethod.Post))
|
||||
@@ -373,6 +374,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@*ToDo: Wie im FaC machen!*@
|
||||
@if(AbstractModel.HasRightToViewReports && AbstractModel.HasRightToViewMitarbeiterstundenkonto)
|
||||
{
|
||||
using(Html.BeginForm("RedirectToReportViewer", "Main", FormMethod.Post))
|
||||
|
||||
@@ -1359,22 +1359,22 @@ namespace BeWo.Data.Access
|
||||
|
||||
public bool OverlappingAppointmentsExist(DateTime start, DateTime end, IEnumerable<long> employees, IEnumerable<long> customers, IEnumerable<long> resources, long originator, long? appointmentOid, string recurrenceId = "", int occurrenceIndex = 0)
|
||||
{
|
||||
if(employees == null)
|
||||
if(employees is null)
|
||||
{
|
||||
employees = new List<long>();
|
||||
}
|
||||
|
||||
if(customers == null)
|
||||
if(customers is null)
|
||||
{
|
||||
customers = new List<long>();
|
||||
}
|
||||
|
||||
if(resources == null)
|
||||
if(resources is null)
|
||||
{
|
||||
resources = new List<long>();
|
||||
}
|
||||
|
||||
var isRecurrenceException = appointmentOid == null;
|
||||
var isRecurrenceException = appointmentOid is null;
|
||||
var isBeingUpdatedToNormalAppointment = false;
|
||||
Guid? recurrenceIdToIgnore = null;
|
||||
|
||||
@@ -1414,7 +1414,7 @@ namespace BeWo.Data.Access
|
||||
|
||||
var appointments = appTmp.Where(a =>
|
||||
{
|
||||
if(a.RecurrenceInfo == null)
|
||||
if(a.RecurrenceInfo is null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -1440,30 +1440,24 @@ namespace BeWo.Data.Access
|
||||
{
|
||||
var recId = root.GetRecurrenceId();
|
||||
|
||||
if(recId != null && recurrenceIdToIgnore != null)
|
||||
if(recId is null || recurrenceIdToIgnore is null)
|
||||
{
|
||||
if(recId.Equals(recurrenceIdToIgnore))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
return !recId.Equals(recurrenceIdToIgnore);
|
||||
}).ToList();
|
||||
|
||||
schedulerAppointments = schedulerAppointments.Where(root =>
|
||||
{
|
||||
var recId = root.GetRecurrenceId();
|
||||
|
||||
if(recId != null && recurrenceIdToIgnore != null)
|
||||
if(recId is null || recurrenceIdToIgnore is null)
|
||||
{
|
||||
if(recId.Equals(recurrenceIdToIgnore))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
return !recId.Equals(recurrenceIdToIgnore);
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
@@ -1477,7 +1471,7 @@ namespace BeWo.Data.Access
|
||||
// Das Muster für die Terminserie wird berechnet
|
||||
var pattern = StaticAppointmentFactory.CreateAppointment(AppointmentType.Pattern);
|
||||
|
||||
if(pattern == null)
|
||||
if(pattern is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -1496,7 +1490,7 @@ namespace BeWo.Data.Access
|
||||
|
||||
foreach(var occurrence in occurrences.GetAppointments(interval))
|
||||
{
|
||||
if(appointment.EndDate == null || appointment.StartDate == null)
|
||||
if(appointment.EndDate is null || appointment.StartDate is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -1576,21 +1570,21 @@ namespace BeWo.Data.Access
|
||||
|
||||
var recurringAppointment = new SchedulerAppointment
|
||||
{
|
||||
AllDay = occurrence.AllDay,
|
||||
CustomerList = appointment.CustomerList,
|
||||
Notice = appointment.Notice,
|
||||
EmployeeList = appointment.EmployeeList,
|
||||
EndDate = occurrence.Start.AddMinutes(duration),
|
||||
AllDay = occurrence.AllDay,
|
||||
CustomerList = appointment.CustomerList,
|
||||
Notice = appointment.Notice,
|
||||
EmployeeList = appointment.EmployeeList,
|
||||
EndDate = occurrence.Start.AddMinutes(duration),
|
||||
FormerBookingSequenceOid = appointment.FormerBookingSequenceOid,
|
||||
IsPrivate = appointment.IsPrivate,
|
||||
Location = appointment.Location,
|
||||
Originator = appointment.Originator,
|
||||
RecurrenceInfo = occurrence.RecurrenceInfo.ToXml(),
|
||||
ReminderInfo = appointment.ReminderInfo,
|
||||
ResourceList = appointment.ResourceList,
|
||||
StartDate = occurrence.Start,
|
||||
Subject = appointment.Subject ?? "",
|
||||
Type = appointment.Type
|
||||
IsPrivate = appointment.IsPrivate,
|
||||
Location = appointment.Location,
|
||||
Originator = appointment.Originator,
|
||||
RecurrenceInfo = occurrence.RecurrenceInfo.ToXml(),
|
||||
ReminderInfo = appointment.ReminderInfo,
|
||||
ResourceList = appointment.ResourceList,
|
||||
StartDate = occurrence.Start,
|
||||
Subject = appointment.Subject ?? "",
|
||||
Type = appointment.Type
|
||||
};
|
||||
|
||||
schedulerAppointments.AddIfNotIn(recurringAppointment);
|
||||
@@ -1608,7 +1602,7 @@ namespace BeWo.Data.Access
|
||||
}
|
||||
}
|
||||
|
||||
var oidList = new List<long>();
|
||||
var employeeOidList = new List<long>();
|
||||
|
||||
schedulerAppointments = schedulerAppointments.Where(appointment => appointment.Type != 4).ToList();
|
||||
|
||||
@@ -1622,10 +1616,10 @@ namespace BeWo.Data.Access
|
||||
}
|
||||
}
|
||||
|
||||
oidList.AddRange(appointment.EmployeeList.Select(rel => rel.ParticipationAnswer != ParticipationAnswer.Absage && rel.Employee.Oid != null ? rel.Employee.Oid.Value : 0));
|
||||
employeeOidList.AddRange(appointment.EmployeeList.Select(rel => rel.ParticipationAnswer != ParticipationAnswer.Absage && rel.Employee.Oid != null ? rel.Employee.Oid.Value : 0));
|
||||
}
|
||||
|
||||
var hasOverlappingEmployeeAppointments = oidList.Intersect(employees).Any();
|
||||
var hasOverlappingEmployeeAppointments = employeeOidList.Intersect(employees).Any();
|
||||
var hasOverlappingCustomerAppointments = schedulerAppointments.Any(app => { return ShouldDoAppointmentOverlappingCheck(app, recurrenceGuid) && app.CustomerList.Select(c => c.Oid ?? 0).Intersect(customers).Any(); });
|
||||
|
||||
var hasOverlappingResourceAppointments = schedulerAppointments.Any(app => { return ShouldDoAppointmentOverlappingCheck(app, recurrenceGuid) && app.ResourceList.Select(r => r.Oid ?? 0).Intersect(resources).Any(); });
|
||||
@@ -1644,23 +1638,22 @@ namespace BeWo.Data.Access
|
||||
|
||||
return hasOverlappingEmployeeAppointments || hasOverlappingCustomerAppointments || hasOverlappingResourceAppointments || hasOverlappingOriginatorAppointments;
|
||||
}
|
||||
|
||||
|
||||
private static bool ShouldDoAppointmentOverlappingCheck(SchedulerAppointment appointment, Guid? recurrenceId)
|
||||
{
|
||||
if(appointment.Oid.HasValue && recurrenceId.HasValue)
|
||||
if(!appointment.Oid.HasValue || !recurrenceId.HasValue)
|
||||
{
|
||||
var recId = appointment.GetRecurrenceIdAndIndex(out var recIndex);
|
||||
|
||||
if(appointment.RecurrenceInfo != null && recId != null)
|
||||
{
|
||||
if(recId.Equals(recurrenceId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
var recId = appointment.GetRecurrenceIdAndIndex(out var recIndex);
|
||||
|
||||
if(appointment.RecurrenceInfo is null || recId is null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return !recId.Equals(recurrenceId);
|
||||
}
|
||||
|
||||
public IEnumerable<SchedulerAppointment> GetAllActiveAppointmentsForEmployeeInInterval(DateTime start, DateTime end, long pEmployeeOid)
|
||||
@@ -4216,32 +4209,28 @@ namespace BeWo.Data.Access
|
||||
{
|
||||
var isOverlapping = OverlappingAppointmentsExist(start, end, employees, customers, resources, originator, appointmentOid, recurrenceId?.ToString() ?? "", occurrenceIndex);
|
||||
|
||||
var unavailableResources = shouldSkipResourceAvailability ? new List<Resource>() : CheckAvailabilityOfResources(resources.ToList(), start, end, appointmentOid, recurrenceId, occurrenceIndex);
|
||||
// Die Ressourcen werden auf Verfügbarkeit im ausgewählten Zeitraum geprüft
|
||||
var info = shouldSkipResourceAvailability ? new Dictionary<string, List<string>>() : CheckResourceAvailabilityWithEmployeeInformation(start, end, resources, appointmentOid, recurrenceId, occurrenceIndex);
|
||||
|
||||
var stringBuilder = new StringBuilder();
|
||||
|
||||
if(unavailableResources.Any())
|
||||
foreach(var resourceName2Intervals in info)
|
||||
{
|
||||
var names = string.Empty;
|
||||
stringBuilder.AppendLine($"Die Ressource \"{resourceName2Intervals.Key}\" ist im ausgewählten Zeitraum {start:dd.MM.yyyy HH:mm} bis {end:dd.MM.yyyy HH:mm} bereits gebucht:");
|
||||
if(!resourceName2Intervals.Value.All(IsNullOrWhiteSpace))
|
||||
{
|
||||
stringBuilder.Append("\r\n\r\n");
|
||||
}
|
||||
|
||||
unavailableResources.DoForEach(resource => names += resource.Name + ", ");
|
||||
|
||||
names = names.TrimEnd(' ').TrimEnd(',');
|
||||
|
||||
var resourceCount = resources.Count();
|
||||
|
||||
var suffix = (resourceCount > 1 ? "n" : string.Empty);
|
||||
|
||||
var ressourceWarningMessage = resourceCount > 1 ? $"Ein{(resourceCount > 1 ? "ige" : "e")} der ausgewählten Ressourcen ({names}) sind" : $"{(resourceCount > 1 ? "Eine der" : "Die")} ausgewählte{suffix} Ressource{suffix} ({names}) ist";
|
||||
|
||||
ressourceWarningMessage += $" zum gewählten Zeitpunkt ({start.GetDateString(end)}) nicht verfügbar.";
|
||||
|
||||
stringBuilder.Append(ressourceWarningMessage);
|
||||
foreach(var interval in resourceName2Intervals.Value)
|
||||
{
|
||||
stringBuilder.AppendLine($"{interval}");
|
||||
}
|
||||
}
|
||||
|
||||
if(isOverlapping)
|
||||
{
|
||||
if(unavailableResources.Any())
|
||||
if(info.Any())
|
||||
{
|
||||
stringBuilder.Append("\n\n");
|
||||
}
|
||||
@@ -4249,7 +4238,7 @@ namespace BeWo.Data.Access
|
||||
stringBuilder.Append("Dieser Termin überschneidet sich mit einem anderen bereits existierenden Termin.");
|
||||
}
|
||||
|
||||
if(unavailableResources.Any() || isOverlapping)
|
||||
if(info.Any() || isOverlapping)
|
||||
{
|
||||
stringBuilder.Append("\n\nMöchten Sie trotzdem speichern?");
|
||||
}
|
||||
@@ -4259,7 +4248,7 @@ namespace BeWo.Data.Access
|
||||
|
||||
public virtual IList FindFileattachmentOids(string text)
|
||||
{
|
||||
var q = Session.CreateSQLQuery(Format("SELECT Oid, bewofolderoid, objectoid, objecttid, path FROM FileAttachment WHERE Path like '%{0}%'", text));
|
||||
var q = Session.CreateSQLQuery($"SELECT Oid, bewofolderoid, objectoid, objecttid, path FROM FileAttachment WHERE Path like '%{text}%'");
|
||||
|
||||
return q.List();
|
||||
}
|
||||
@@ -5183,8 +5172,6 @@ namespace BeWo.Data.Access
|
||||
return signature.Count == 1;
|
||||
}
|
||||
|
||||
// ToDo: FALSCHE METHODE! SUCHT NUR NACH SERIENTERMINEN, DIE SO NICHT IN DER DATENBANK SIND!
|
||||
// ToDo: SQL BEARBEITEN, DAMIT DIE SCHEDULERAPPOINTMENT-OBJEKTE ZURÜCKGEGEBEN WERDEN UND NICHT DIE GEBUCHTEN RESSOURCEN!
|
||||
/// <summary>
|
||||
/// Prüft anhand der Oids von Ressourcen deren Verfügbarkeit in einem Zeitraum.
|
||||
/// Gibt die nicht verfügbaren Ressourcen und Mitarbeiter, die sie gebucht aben zurück für eine detaillierte Fehlermeldung.
|
||||
@@ -5198,24 +5185,12 @@ namespace BeWo.Data.Access
|
||||
/// <returns>Die im angegebenen Zeitraum belegten Ressourcen mit den Mitarbeitern, die sie gebucht haben</returns>
|
||||
public List<SchedulerAppointment> FindAppointmentsByResourcesInInterval(List<long> resourceOids, DateTime start, DateTime end, long? selectedAppointmentOid, Guid? recurrenceId = null, int? occurrenceIndex = null)
|
||||
{
|
||||
//var c = CreateCriteria<Resource>("r").Add(Restrictions.Eq(nameof(BeWoEntityBase.IsActive), ActivationTypeId.Active)).Add(Restrictions.In(nameof(BeWoEntityBase.Oid), resourceOids));
|
||||
|
||||
//var excludingSelectedAppointment = selectedAppointmentOid.HasValue ? $"Oid <> {selectedAppointmentOid} AND " : "";
|
||||
|
||||
//var sql = "Oid IN " +
|
||||
// "(SELECT ResourceOid FROM resource2newschapp r2n WHERE r2n.NewSchAppOid IN " +
|
||||
// $"(SELECT Oid FROM newschedulerappointment WHERE IsActive = 1 AND Type <> 4 AND {excludingSelectedAppointment}('{start:yyyy-MM-dd HH:mm:ss}' > StartDate OR '{end:yyyy-MM-dd HH:mm:ss}' > StartDate) AND ('{start:yyyy-MM-dd HH:mm:ss}' < EndDate OR '{end:yyyy-MM-dd HH:mm:ss}' < EndDate)))";
|
||||
|
||||
//var criterion = Expression.Sql(sql);
|
||||
|
||||
//c.Add(criterion);
|
||||
|
||||
//var resources = c.List<Resource>().ToList();
|
||||
|
||||
var betweenCriterion = CreateBetweenDateTimesCriterion(start, end, "StartDate", "EndDate");
|
||||
|
||||
var c2 = CreateCriteriaIsActive<SchedulerAppointment>()
|
||||
.Add(Restrictions.Not(Restrictions.Eq(nameof(SchedulerAppointment.Type), 4)))
|
||||
.Add(Expression.Sql($"'{start:yyyy-MM-dd HH:mm:ss}' BETWEEN StartDate AND EndDate OR '{end:yyyy-MM-dd HH:mm:ss}' BETWEEN StartDate AND EndDate OR StartDate BETWEEN '{start:yyyy-MM-dd HH:mm:ss}' AND '{end:yyyy-MM-dd HH:mm:ss}' OR EndDate BETWEEN '{start:yyyy-MM-dd HH:mm:ss}' AND '{end:yyyy-MM-dd HH:mm:ss}'"));
|
||||
//.Add(Restrictions.Not(Restrictions.Eq(nameof(SchedulerAppointment.Type), 4)))
|
||||
.Add(betweenCriterion);
|
||||
|
||||
|
||||
if(!(selectedAppointmentOid is null))
|
||||
{
|
||||
@@ -5225,161 +5200,191 @@ namespace BeWo.Data.Access
|
||||
c2.CreateAlias(nameof(SchedulerAppointment.ResourceList), "resources", JoinType.InnerJoin)
|
||||
.Add(Restrictions.In($"resources.{nameof(BeWoEntityBase.Oid)}", resourceOids));
|
||||
|
||||
var appointments = c2.List<SchedulerAppointment>().ToList();
|
||||
|
||||
var tempAppointments = c2.List<SchedulerAppointment>().ToList();
|
||||
|
||||
var isBeingUpdatedToNormalAppointment = false;
|
||||
Guid? recurrenceIdToIgnore = null;
|
||||
if(selectedAppointmentOid.HasValue)
|
||||
{
|
||||
// Das Pattern wird geladen, bzw. mit der Ausnahme mit Index 0 verglichen
|
||||
// Wird die Serie in einen Einzeltermin geändert und es existiert eine Ausnahme mit Index 0, sollte die Ausnahme behalten werden und nicht der Root-Termin
|
||||
var original = DAOFactory.GenericDAO.LoadByID<SchedulerAppointment>(selectedAppointmentOid.Value);
|
||||
var originalRecurrenceId = original?.GetRecurrenceId();
|
||||
|
||||
if(!(originalRecurrenceId is null) && IsNullOrWhiteSpace(recurrenceId?.ToString()))
|
||||
{
|
||||
isBeingUpdatedToNormalAppointment = true;
|
||||
recurrenceIdToIgnore = originalRecurrenceId;
|
||||
}
|
||||
}
|
||||
|
||||
var appointments = tempAppointments.Where(appointment =>
|
||||
{
|
||||
if(appointment.RecurrenceInfo is null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var recId2 = appointment.GetRecurrenceIdAndIndex(out var index);
|
||||
return !((recurrenceId?.Equals(recId2) ?? false) && occurrenceIndex == index);
|
||||
}).ToList();
|
||||
|
||||
|
||||
var deletedOccurrences = appointments.Where(app => app.Type == 4).Select(app => BS.Shared.Core.Utils.GetOccurrenceId(app.RecurrenceInfo)).ToList();
|
||||
var changedOccurrences = appointments.Where(app => app.Type == 3).Select(app => BS.Shared.Core.Utils.GetOccurrenceId(app.RecurrenceInfo)).ToList();
|
||||
|
||||
var recurringAppointmentsCriteria = CreateRecurrenceCriteria(start, end).Add(Restrictions.Eq(nameof(SchedulerAppointment.Type), 1));
|
||||
|
||||
var recurringAppointments = recurringAppointmentsCriteria.List<SchedulerAppointment>().ToList();
|
||||
|
||||
if(isBeingUpdatedToNormalAppointment)
|
||||
{
|
||||
recurringAppointments = recurringAppointments.Where(root => FilterRootAppointment(root, recurrenceIdToIgnore)).ToList();
|
||||
|
||||
appointments = appointments.Where(root => FilterRootAppointment(root, recurrenceIdToIgnore)).ToList();
|
||||
}
|
||||
|
||||
recurringAppointments = recurringAppointments.Where(s => s.ResourceList.Any(r => r.Oid.HasValue && resourceOids.Contains(r.Oid.Value))).ToList();
|
||||
|
||||
// ToDo: Wieso wird das gemacht?
|
||||
if(recurringAppointments.Count == 0)
|
||||
{
|
||||
//return new List<SchedulerAppointment>();
|
||||
}
|
||||
|
||||
var changedOccurrencesCriteria = CreateCriteriaIsActive<SchedulerAppointment>().Add(Restrictions.Eq(nameof(SchedulerAppointment.Type), 3));
|
||||
var deletedOccurrencesCriteria = CreateCriteria<SchedulerAppointment>().Add(Restrictions.Eq(nameof(SchedulerAppointment.Type), 4));
|
||||
|
||||
var inBetween = CreateBetweenDateTimesCriterion(start, end, nameof(SchedulerAppointment.StartDate), nameof(SchedulerAppointment.EndDate));
|
||||
|
||||
changedOccurrencesCriteria.Add(inBetween);
|
||||
deletedOccurrencesCriteria.Add(inBetween);
|
||||
|
||||
//var appointments = new List<SchedulerAppointment>();
|
||||
|
||||
if(selectedAppointmentOid.HasValue)
|
||||
{
|
||||
changedOccurrencesCriteria.Add(Restrictions.Not(Restrictions.Eq(nameof(BeWoEntityBase.Oid), selectedAppointmentOid.Value)));
|
||||
deletedOccurrencesCriteria.Add(Restrictions.Not(Restrictions.Eq(nameof(BeWoEntityBase.Oid), selectedAppointmentOid.Value)));
|
||||
}
|
||||
|
||||
var changedOccurrences = new List<SchedulerAppointment>();
|
||||
|
||||
var recurrenceIds = string.Empty;
|
||||
recurringAppointments.DoForEach(appointment => recurrenceIds += $"'{appointment.GetRecurrenceId()}',");
|
||||
recurrenceIds = recurrenceIds.Trim(',');
|
||||
|
||||
if(recurrenceIds.Any())
|
||||
{
|
||||
var changedCriteria = CreateCriteriaIsActive<SchedulerAppointment>()
|
||||
.Add(Restrictions.Eq(nameof(SchedulerAppointment.Type), 3))
|
||||
.Add(Expression.Sql($"RecurrenceInfo IS NOT NULL AND RecurrenceInfo LIKE '%Id%' AND SUBSTRING(RecurrenceInfo, LOCATE('Id', RecurrenceInfo) + 4, 36) IN ({recurrenceIds})"));
|
||||
|
||||
changedOccurrences = changedCriteria.List<SchedulerAppointment>().ToList();
|
||||
}
|
||||
|
||||
//var changedOccurrences = changedOccurrencesCriteria.List<SchedulerAppointment>().Where(a => a.ResourceList.Any(r => r.Oid.HasValue && resourceOids.Contains(r.Oid.Value))).ToList();
|
||||
var deletedOccurrences = deletedOccurrencesCriteria.List<SchedulerAppointment>().Where(a => a.ResourceList.Any(r => r.Oid.HasValue && resourceOids.Contains(r.Oid.Value))).ToList();
|
||||
|
||||
// Sich wiederholende Termine erzeugen und dabei die Ausnahmen und gelöschten Ausnahmen ignorieren
|
||||
var interval = new TimeInterval(start, end);
|
||||
foreach(var recurringAppointment in recurringAppointments)
|
||||
foreach(var appointment in recurringAppointments)
|
||||
{
|
||||
var recurrenceInfo = new RecurrenceInfo();
|
||||
recurrenceInfo.FromXml(recurringAppointment.RecurrenceInfo);
|
||||
recurrenceInfo.FromXml(appointment.RecurrenceInfo);
|
||||
|
||||
var occurenceCalculator = OccurrenceCalculator.CreateInstance(recurrenceInfo);
|
||||
var occurrenceCalculator = OccurrenceCalculator.CreateInstance(recurrenceInfo);
|
||||
|
||||
// Das Muster für die Terminserie wird berechnet
|
||||
var pattern = StaticAppointmentFactory.CreateAppointment(AppointmentType.Pattern);
|
||||
pattern.RecurrenceInfo.FromXml(recurringAppointment.RecurrenceInfo);
|
||||
pattern.Start = pattern.RecurrenceInfo.Start;
|
||||
pattern.End = pattern.RecurrenceInfo.End;
|
||||
|
||||
if(!Guid.TryParse(pattern.RecurrenceInfo.Id.ToString(), out var patternId))
|
||||
if(pattern is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Die Serientermine werden berechnet (ausnahmslos, d.h. es werden auch bearbeitete und gelöschte Termine erstellt, die herausgefiltert werden müssen).
|
||||
var occurrences = occurenceCalculator.CalcOccurrences(interval, pattern);
|
||||
pattern.RecurrenceInfo.FromXml(appointment.RecurrenceInfo);
|
||||
pattern.Start = pattern.RecurrenceInfo.Start;
|
||||
pattern.End = appointment.EndDate.Value;
|
||||
|
||||
var occurrenceAppointments = occurrences.GetAppointments(interval);
|
||||
var patternId = pattern.RecurrenceInfo.Id.ToString();
|
||||
|
||||
foreach(var occurrence in occurrenceAppointments)
|
||||
var interval = new TimeInterval(start, end);
|
||||
|
||||
var occurrences = occurrenceCalculator.CalcOccurrences(interval, pattern);
|
||||
|
||||
foreach(var occurrence in occurrences.GetAppointments(interval))
|
||||
{
|
||||
if(recurringAppointment.EndDate is null || recurringAppointment.StartDate is null)
|
||||
if(appointment.EndDate is null || appointment.StartDate is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Sicher machen
|
||||
// Terminindex in der Serie
|
||||
var index = occurrence.RecurrenceIndex;
|
||||
|
||||
var isDeletedOrChanged = changedOccurrences.Any(a =>
|
||||
{
|
||||
var guid = a.GetRecurrenceIdAndIndex(out var i);
|
||||
// Das Ende ist offen, da die Terminserie kein Ende hat. Deshalb wird das Ende berechnet.
|
||||
var duration = (appointment.EndDate.Value - appointment.StartDate.Value).TotalMinutes;
|
||||
|
||||
if(guid is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var guidParsingSuccessful = Guid.TryParse(occurrence.RecurrenceInfo?.Id?.ToString(), out var occurrenceGuid);
|
||||
|
||||
return guid.Value.Equals(patternId) && index == i;
|
||||
}) || deletedOccurrences.Any(a =>
|
||||
{
|
||||
var guid = a.GetRecurrenceIdAndIndex(out var i);
|
||||
|
||||
if(guid is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return guid.Value.Equals(patternId) && index == i;
|
||||
});
|
||||
|
||||
if(isDeletedOrChanged)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var duration = (recurringAppointment.EndDate.Value - recurringAppointment.StartDate.Value).TotalMinutes;
|
||||
// Der generierte Serientermin muss sich zeitlich mit dem neuen Termin überschneiden
|
||||
// und darf nicht in der Liste der geänderten Serientermine oder der Liste der gelöschten Serientermine sein.
|
||||
var isInIntervalTest = start.IsInInterval(end, occurrence.Start, occurrence.Start.AddMinutes(duration));
|
||||
|
||||
if(!isInIntervalTest)
|
||||
if(!isInIntervalTest ||
|
||||
changedOccurrences.Any(changedOccurence => changedOccurence.PatternId.Equals(patternId) && changedOccurence.Index == index) ||
|
||||
deletedOccurrences.Any(deletedOccurence => deletedOccurence.PatternId.Equals(patternId) && deletedOccurence.Index == index) ||
|
||||
index == occurrenceIndex && guidParsingSuccessful && recurrenceId != null && recurrenceId.Equals(occurrenceGuid))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var occurrenceAppointment = new SchedulerAppointment
|
||||
// Prüfen, ob es eine Ausnahme an dem Tag gibt, die zu dem Pattern gehört, um das Pattern auszuschließen
|
||||
var relatedAppointments = FindAppointmentsByRecurrenceId(new List<string> { recurrenceInfo.Id.ToString() }, true);
|
||||
var relatedAppointmentsInInterval = relatedAppointments.Where(a =>
|
||||
{
|
||||
AllDay = occurrence.AllDay,
|
||||
CustomerList = recurringAppointment.CustomerList,
|
||||
Notice = recurringAppointment.Notice,
|
||||
EmployeeList = recurringAppointment.EmployeeList,
|
||||
EndDate = occurrence.Start.AddMinutes(duration),
|
||||
FormerBookingSequenceOid = recurringAppointment.FormerBookingSequenceOid,
|
||||
IsPrivate = recurringAppointment.IsPrivate,
|
||||
Location = recurringAppointment.Location,
|
||||
Originator = recurringAppointment.Originator,
|
||||
RecurrenceInfo = occurrence.RecurrenceInfo.ToXml(),
|
||||
ReminderInfo = recurringAppointment.ReminderInfo,
|
||||
ResourceList = recurringAppointment.ResourceList,
|
||||
StartDate = occurrence.Start,
|
||||
Subject = recurringAppointment.Subject ?? Empty,
|
||||
Type = recurringAppointment.Type
|
||||
};
|
||||
|
||||
if(!(recurrenceId is null) && occurrenceIndex.HasValue)
|
||||
{
|
||||
var recId = occurrenceAppointment.GetRecurrenceId();
|
||||
|
||||
if((recId?.Equals(recurrenceId.Value) ?? false) && index.Equals(occurrenceIndex.Value))
|
||||
if(a.StartDate == null || a.EndDate == null)
|
||||
{
|
||||
continue;
|
||||
return false;
|
||||
}
|
||||
|
||||
var myStart = a.StartDate.Value.Date;
|
||||
var myEnd = a.EndDate.Value.Date;
|
||||
|
||||
var isInInterval = start.Date.InBetween(myStart.GetShortDateTime(), myEnd, true);
|
||||
|
||||
return isInInterval && a.Type != 4;
|
||||
}).ToList();
|
||||
|
||||
var hasToStop = false;
|
||||
|
||||
// Prüfen, ob es sich bei dem Termin für den Überschneidungen gesucht werden, um zu unterscheiden, ob ein Serientermin in einen normalen geändert wird.
|
||||
var root = FindRootAppointmentByRecurrenceId(recurrenceInfo.Id.ToString());
|
||||
if(root.Oid != null && selectedAppointmentOid != null && root.Oid == selectedAppointmentOid && root.RecurrenceInfo != null && IsNullOrWhiteSpace(recurrenceId?.ToString()))
|
||||
{
|
||||
hasToStop = true;
|
||||
}
|
||||
|
||||
// Indices und Ids der RecurrenceInfo vergleichen. Stimmen sie überein, dann wird das generiert Serienelement ignoriert.
|
||||
if(occurrence.RecurrenceInfo?.Id != null && !hasToStop)
|
||||
{
|
||||
if(Guid.TryParse(occurrence.RecurrenceInfo.Id.ToString(), out var guid))
|
||||
{
|
||||
foreach(var relatedAppointment in relatedAppointmentsInInterval)
|
||||
{
|
||||
var relatedAppointmentRecurrenceId = relatedAppointment.GetRecurrenceIdAndIndex(out var relatedAppointmentRecurrenceIndex);
|
||||
|
||||
if(relatedAppointmentRecurrenceId != null)
|
||||
{
|
||||
if(guid.Equals(relatedAppointmentRecurrenceId) && relatedAppointmentRecurrenceIndex.Equals(occurrence.RecurrenceIndex))
|
||||
{
|
||||
hasToStop = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
appointments.AddIfNotIn(occurrenceAppointment);
|
||||
if(hasToStop)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var recurringAppointment = new SchedulerAppointment
|
||||
{
|
||||
AllDay = occurrence.AllDay,
|
||||
CustomerList = appointment.CustomerList,
|
||||
Notice = appointment.Notice,
|
||||
EmployeeList = appointment.EmployeeList,
|
||||
EndDate = occurrence.Start.AddMinutes(duration),
|
||||
FormerBookingSequenceOid = appointment.FormerBookingSequenceOid,
|
||||
IsPrivate = appointment.IsPrivate,
|
||||
Location = appointment.Location,
|
||||
Originator = appointment.Originator,
|
||||
RecurrenceInfo = occurrence.RecurrenceInfo.ToXml(),
|
||||
ReminderInfo = appointment.ReminderInfo,
|
||||
ResourceList = appointment.ResourceList,
|
||||
StartDate = occurrence.Start,
|
||||
Subject = appointment.Subject ?? "",
|
||||
Type = appointment.Type
|
||||
};
|
||||
|
||||
appointments.AddIfNotIn(recurringAppointment);
|
||||
}
|
||||
}
|
||||
|
||||
return appointments.ToList();
|
||||
return appointments.Where(appointment => appointment.Type != 4).OrderBy(appointment => appointment.StartDate).ToList();
|
||||
}
|
||||
|
||||
private static bool FilterRootAppointment(SchedulerAppointment root, Guid? recurrenceIdToIgnore)
|
||||
{
|
||||
var recId = root.GetRecurrenceId();
|
||||
|
||||
if(recId is null || recurrenceIdToIgnore is null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return !recId.Equals(recurrenceIdToIgnore);
|
||||
}
|
||||
|
||||
public List<ConfirmationReceiptSignature> LoadAllConfirmationReceiptSignaturesByServiceRecordOids(IList<long> serviceRecordOids)
|
||||
@@ -5395,5 +5400,78 @@ namespace BeWo.Data.Access
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Dictionary<string, List<string>> CheckResourceAvailabilityWithEmployeeInformation(DateTime start, DateTime end, List<long> resourceOids, long? selectedAppointmentOid, Guid? recurrenceId = null, int occurrenceIndex = 0)
|
||||
{
|
||||
var appointments = FindAppointmentsByResourcesInInterval(resourceOids, start, end, selectedAppointmentOid, recurrenceId, occurrenceIndex);
|
||||
|
||||
var user = LoggedInUserOperationContextExt.Current?.User ?? SessionFacade.LoggedInUser;
|
||||
|
||||
var result = new Dictionary<string, List<string>>();
|
||||
|
||||
if(user is null)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
var loggedInEmployee = user.Employee;
|
||||
|
||||
var hasRightToViewEmployeeAppointments = user.CheckForRight(UserRightType.KalenderMitarbeitertermineAnsehen);
|
||||
var hasRightToViewResourceAppointments = user.CheckForRight(UserRightType.KalenderRessourcentermineAnsehen);
|
||||
|
||||
var dictionary = new Dictionary<Resource, List<SchedulerAppointment>>();
|
||||
|
||||
foreach(var appointment in appointments)
|
||||
{
|
||||
foreach(var resource in appointment.ResourceList)
|
||||
{
|
||||
dictionary.AddOrUpdateValueInDictionary(resource, appointment);
|
||||
}
|
||||
}
|
||||
|
||||
foreach(var resource2Appointments in dictionary)
|
||||
{
|
||||
foreach(var appointment in resource2Appointments.Value)
|
||||
{
|
||||
var originator = appointment.Originator;
|
||||
var employee2Appointments = appointment.EmployeeList;
|
||||
|
||||
var isOwnAppointment = (originator?.Equals(loggedInEmployee) ?? false) || employee2Appointments.ToList().Any(e2a => e2a.Employee.Equals(loggedInEmployee));
|
||||
|
||||
// Wenn isOwnAppointment true ist, darf der Benutzer die Uhrzeiten und die Mitarbeiter sehen. Ansonsten müssen die Rechte geprüft werden.
|
||||
if(isOwnAppointment || hasRightToViewEmployeeAppointments) // Es werden Zeit und Mitarbeiter angezeigt
|
||||
{
|
||||
result.AddOrUpdateValueInDictionary(resource2Appointments.Key.Name, $"{CreateDateTimeInfoFromAppointment(appointment.StartDate, appointment.EndDate, appointment.AllDay)} von {originator}");
|
||||
}
|
||||
else if(hasRightToViewResourceAppointments && !hasRightToViewEmployeeAppointments) // Nur die Uhrzeit anzeigen
|
||||
{
|
||||
result.AddOrUpdateValueInDictionary(resource2Appointments.Key.Name, $"{CreateDateTimeInfoFromAppointment(appointment.StartDate, appointment.EndDate, appointment.AllDay)}");
|
||||
}
|
||||
else if(!hasRightToViewEmployeeAppointments) // Es werden weder Zeit noch Mitarbeiter angezeigt
|
||||
{
|
||||
result.AddOrUpdateValueInDictionary(resource2Appointments.Key.Name, string.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static string CreateDateTimeInfoFromAppointment(DateTime? start, DateTime? end, bool allDay)
|
||||
{
|
||||
if(start.HasValue && end.HasValue && allDay == false)
|
||||
{
|
||||
return start.Value.Date == end.Value.Date ?
|
||||
$"{start.Value.ToShortTimeString()} - {end.Value.ToShortTimeString()} " :
|
||||
$"{start.Value:dd.MM.yyyy HH:mm} - {end.Value:dd.MM.yyyy HH:mm} ";
|
||||
}
|
||||
|
||||
if(allDay && start.HasValue && end.HasValue)
|
||||
{
|
||||
return start.Value.Date == end.Value.Date ? " " : $"{start.Value.ToShortDateString()} - {end.Value.ToShortDateString()} ";
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<NameOfLastUsedPublishProfile>BeWo2.0</NameOfLastUsedPublishProfile>
|
||||
<UseIISExpress>true</UseIISExpress>
|
||||
<LastActiveSolutionConfig>Release|Any CPU</LastActiveSolutionConfig>
|
||||
<LastActiveSolutionConfig>Debug|Any CPU</LastActiveSolutionConfig>
|
||||
<Use64BitIISExpress>false</Use64BitIISExpress>
|
||||
<IISExpressSSLPort />
|
||||
<IISExpressAnonymousAuthentication />
|
||||
|
||||
@@ -117,7 +117,7 @@ namespace BeWo.Service.Plugins
|
||||
//t = "4271389563"; // Komm Mit
|
||||
//t = "5430005891"; // Marienhospital Eickel
|
||||
//t = "3265049248"; // Gerdas Pflegedienst
|
||||
t = "1549622397"; // Kontakt und Krisenhilfe
|
||||
//t = "1549622397"; // Kontakt und Krisenhilfe
|
||||
//t = "4782194565"; // Skm Rheydt
|
||||
//t = "7535795843"; // Sozialwerk Dürener Christen
|
||||
//t = "6388340414"; // Weitblick
|
||||
@@ -195,7 +195,7 @@ namespace BeWo.Service.Plugins
|
||||
//t = "9556218062"; // Diakonie Landshut
|
||||
//t = "2279593936"; // Diakonie Mülheim
|
||||
//t = "3623837005"; // Betreuwo Wesel
|
||||
t = "8407321888"; // AWO Wesel
|
||||
//t = "8407321888"; // AWO Wesel
|
||||
//t = "8454426692"; // Mit-Menschen Wuppertal
|
||||
//t = "0629004412"; // BeWo-Colonia Basaran (Projekt
|
||||
//t = "7668701607"; // Wohnstätten Essen
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BeWo.Data;
|
||||
using BeWo.Data.Access;
|
||||
using BeWo.Data.Entities;
|
||||
using BeWo.Service.DCEntityMapper;
|
||||
using BS.Shared;
|
||||
using BS.Shared.Core;
|
||||
using BS.Shared.DataContracts;
|
||||
using BS.Shared.Extensions;
|
||||
using NHibernate.Util;
|
||||
|
||||
namespace BeWo.Service.Plugins
|
||||
{
|
||||
@@ -34,77 +29,9 @@ namespace BeWo.Service.Plugins
|
||||
return list;
|
||||
}
|
||||
|
||||
public virtual Dictionary<string, List<string>> CheckResourceAvailabilityWithBookingEmployees(DateTime start, DateTime end, List<long> resourceOids, long? selectedAppointmentOid)
|
||||
public virtual Dictionary<string, List<string>> CheckResourceAvailabilityWithBookingEmployees(DateTime start, DateTime end, List<long> resourceOids, long? selectedAppointmentOid, Guid? recurrenceId, int occurrenceIndex = 0, bool shouldSkipResourceAvailability = false)
|
||||
{
|
||||
var appointments = DAOFactory.SearchDAO.FindAppointmentsByResourcesInInterval(resourceOids, start, end, selectedAppointmentOid);
|
||||
|
||||
var user = LoggedInUserOperationContextExt.Current?.User ?? SessionFacade.LoggedInUser;
|
||||
|
||||
var result = new Dictionary<string, List<string>>();
|
||||
|
||||
if(user is null)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
var loggedInEmployee = user.Employee;
|
||||
|
||||
var hasRightToViewEmployeeAppointments = user.CheckForRight(UserRightType.KalenderMitarbeitertermineAnsehen);
|
||||
var hasRightToViewResourceAppointments = user.CheckForRight(UserRightType.KalenderRessourcentermineAnsehen);
|
||||
|
||||
var dictionary = new Dictionary<Resource, List<SchedulerAppointment>>();
|
||||
|
||||
foreach(var appointment in appointments)
|
||||
{
|
||||
foreach(var resource in appointment.ResourceList)
|
||||
{
|
||||
dictionary.AddOrUpdateValueInDictionary(resource, appointment);
|
||||
}
|
||||
}
|
||||
|
||||
foreach(var resource2Appointments in dictionary)
|
||||
{
|
||||
foreach(var appointment in resource2Appointments.Value)
|
||||
{
|
||||
var originator = appointment.Originator;
|
||||
var employee2Appointments = appointment.EmployeeList;
|
||||
|
||||
var isOwnAppointment = (originator?.Equals(loggedInEmployee) ?? false) || employee2Appointments.ToList().Any(e2a => e2a.Employee.Equals(loggedInEmployee));
|
||||
|
||||
// Wenn isOwnAppointment true ist, darf der Benutzer die Uhrzeiten und die Mitarbeiter sehen. Ansonsten müssen die Rechte geprüft werden.
|
||||
if(isOwnAppointment || hasRightToViewEmployeeAppointments) // Es werden Zeit und Mitarbeiter angezeigt
|
||||
{
|
||||
result.AddOrUpdateValueInDictionary(resource2Appointments.Key.Name, $"{CreateDateTimeInfoFromAppointment(appointment.StartDate, appointment.EndDate, appointment.AllDay)} von {originator}");
|
||||
}
|
||||
else if(hasRightToViewResourceAppointments && !hasRightToViewEmployeeAppointments) // Nur die Uhrzeit anzeigen
|
||||
{
|
||||
result.AddOrUpdateValueInDictionary(resource2Appointments.Key.Name, $"{CreateDateTimeInfoFromAppointment(appointment.StartDate, appointment.EndDate, appointment.AllDay)}");
|
||||
}
|
||||
else if(!hasRightToViewEmployeeAppointments) // Es werden weder Zeit noch Mitarbeiter angezeigt
|
||||
{
|
||||
result.AddOrUpdateValueInDictionary(resource2Appointments.Key.Name, string.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private string CreateDateTimeInfoFromAppointment(DateTime? start, DateTime? end, bool allDay)
|
||||
{
|
||||
if(start.HasValue && end.HasValue)
|
||||
{
|
||||
return start.Value.Date == end.Value.Date ?
|
||||
$"{start.Value.ToShortTimeString()} - {end.Value.ToShortTimeString()} " :
|
||||
$"{start.Value:dd.MM.yyyy HH:mm} - {end.Value:dd.MM.yyyy HH:mm} ";
|
||||
}
|
||||
|
||||
if(allDay && start.HasValue && end.HasValue)
|
||||
{
|
||||
return start.Value.Date == end.Value.Date ? " " : $"{start.Value.ToShortDateString()} - {end.Value.ToShortDateString()} ";
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
return DAOFactory.SearchDAO.CheckResourceAvailabilityWithEmployeeInformation(start, end, resourceOids, selectedAppointmentOid, recurrenceId, occurrenceIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,6 +243,6 @@ namespace BeWo.Service.ServiceContracts
|
||||
|
||||
[FaultContract(typeof(BeWoFault))]
|
||||
[OperationContract]
|
||||
Dictionary<string, List<string>> CheckResourceAvailabilityWithEmployeeInformation(DateTime start, DateTime end, List<long> resourceOids, long? selectedAppointmentOid);
|
||||
Dictionary<string, List<string>> CheckResourceAvailabilityWithEmployeeInformation(DateTime start, DateTime end, List<long> resourceOids, long? selectedAppointmentOid, Guid? recurrenceId, int occurrenceIndex = 0, bool shouldSkipResourceAvailability = false);
|
||||
}
|
||||
}
|
||||
@@ -2712,13 +2712,13 @@ namespace BeWo.Service.ServiceImplementations
|
||||
}
|
||||
}
|
||||
|
||||
public Dictionary<string, List<string>> CheckResourceAvailabilityWithEmployeeInformation(DateTime start, DateTime end, List<long> resourceOids, long? selectedAppointmentOid)
|
||||
public Dictionary<string, List<string>> CheckResourceAvailabilityWithEmployeeInformation(DateTime start, DateTime end, List<long> resourceOids, long? selectedAppointmentOid, Guid? recurrenceId, int occurrenceIndex = 0, bool shouldSkipResourceAvailability = false)
|
||||
{
|
||||
try
|
||||
{
|
||||
var s = PluginLoader.FindClass<ResourceService>();
|
||||
|
||||
return s.CheckResourceAvailabilityWithBookingEmployees(start, end, resourceOids, selectedAppointmentOid);
|
||||
return s.CheckResourceAvailabilityWithBookingEmployees(start, end, resourceOids, selectedAppointmentOid, recurrenceId, occurrenceIndex, shouldSkipResourceAvailability);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user