1148 lines
61 KiB
Plaintext
1148 lines
61 KiB
Plaintext
@using BeWoPlanerMobil.Models
|
||
@using BeWoPlanerMobil.Util
|
||
@using BS.Shared
|
||
@using BS.Shared.Extensions
|
||
@model MainModel
|
||
|
||
@{
|
||
if(TempData[TempDataConstants.DoLogoutKey] is true)
|
||
{
|
||
<text>
|
||
<script type="text/javascript">
|
||
$("#second-logout-form").submit();
|
||
</script>
|
||
</text>
|
||
}
|
||
}
|
||
|
||
<script type="text/javascript">
|
||
window.addEventListener("load", function() {
|
||
@if(TempData[TempDataConstants.SupportConceptRelSelectedKey] is true)
|
||
{
|
||
<text>
|
||
window.updateCategory("@Model.BookingModePrefix", @Model.SelectedServiceCategoryOid);
|
||
window.updateServiceDescription("@Model.BookingModePrefix", @Model.SelectedServiceDescriptionOid);
|
||
window.updateEmployeeOids("@Model.BookingModePrefix", $("#sb-employee-input").val());
|
||
window.updateStartDate("@Model.BookingModePrefix", $(`#@Model.BookingModePrefix-start-date-input`).val());
|
||
window.updateStartTime("@Model.BookingModePrefix", $(`#@Model.BookingModePrefix-start-time-input`).val());
|
||
window.updateEndDate("@Model.BookingModePrefix", $(`#@Model.BookingModePrefix-end-date-input`).val());
|
||
window.updateEndTime("@Model.BookingModePrefix", $(`#@Model.BookingModePrefix-end-time-input`).val());
|
||
window.updateDurationUnit("sb", ($("#sb-hours-minutes-dropdown-btn").text().trim() === "Stunden" ? "h" : "m"));
|
||
</text>
|
||
}
|
||
});
|
||
|
||
$(document).ready(function() {
|
||
const dropdownBtn = $("#sb-hours-minutes-dropdown-btn");
|
||
|
||
dropdownBtn.on("click", function() {
|
||
dropdownBtn.data("text", dropdownBtn.text().replaceAll(/\s/g, ""));
|
||
});
|
||
|
||
$(".hours-minutes-link").on("click", function () {
|
||
const previousText = dropdownBtn.data("text");
|
||
const currentText = $(this).text().replaceAll(/\s/g, "");
|
||
|
||
if(previousText === currentText) {
|
||
return;
|
||
}
|
||
|
||
const buttonText = $(this).text();
|
||
dropdownBtn.text(buttonText);
|
||
|
||
window.setInputFilter();
|
||
|
||
window.updateDurationUnit("sb", (buttonText === "Stunden" ? "h" : "m"));
|
||
|
||
$.get('@Url.Action("ToggleDurationUnit")', { isInHoursMode: buttonText === "Stunden" });
|
||
|
||
calcDuration("sb", true, false, false);
|
||
});
|
||
|
||
@{
|
||
if(Model.SelectedSupportConcept != null || Model.SelectedCostBearerSupportConceptOid == -2)
|
||
{
|
||
<text>
|
||
initializeIntervalSelection();
|
||
</text>
|
||
}
|
||
}
|
||
|
||
window.calcPrependWidth();
|
||
});
|
||
|
||
function deleteSigntarue(signatureOid, serviceRecordOid, customerName, dateOfRecord) {
|
||
showMessagePopupWithCallback("Unterschrift löschen",
|
||
`Sind Sie sicher, dass Sie die Unterschrift von ${customerName} vom ${dateOfRecord} löschen möchten?`,
|
||
function () {
|
||
$("#sr-signature-to-del-oid-input").val(signatureOid);
|
||
$("#sr-sig-to-del-record-oid-input").val(serviceRecordOid);
|
||
showSpinner();
|
||
$("#delete-signature-form").submit();
|
||
},
|
||
false);
|
||
}
|
||
|
||
function resetSingleBookingForm() {
|
||
showSpinner();
|
||
$("#singleBookingForm").trigger("reset");
|
||
|
||
if($("#has-any-rating-types").val().toLowerCase() === "true") {
|
||
$(".goal-rating-badge").text("Bewerten");
|
||
} else {
|
||
$(".goal-rating-badge").text("");
|
||
}
|
||
|
||
$("#reset-single-booking-form-form").submit();
|
||
}
|
||
|
||
function setSelectedEmployeeForSingleBooking(selectedListElement, employeeOid) {
|
||
if(employeeOid !== null && employeeOid !== undefined && $.isNumeric(employeeOid) === true && employeeOid > 0) {
|
||
window.updateEmployeeOids('sb', employeeOid);
|
||
|
||
$.get("@Url.Action("SetServiceRecordEmployee")", {employeeOid: parseFloat(employeeOid)}, function (employeeName) {
|
||
$("#single-booking-employee-modal-popup").parent().find(".dropdown-toggle").text(employeeName);
|
||
$("#single-booking-employee-modal-popup").modal("hide");
|
||
|
||
window.loadServiceRecords();
|
||
});
|
||
}
|
||
}
|
||
|
||
function initializeIntervalSelection() {
|
||
const selectedOption = $("#timeFrameSelect option:selected").val();
|
||
|
||
switch (selectedOption) {
|
||
case "0":
|
||
$("#last-x-interval-container, #custom-interval-container, #month-interval-container").hide();
|
||
break;
|
||
case "1":
|
||
$("#last-x-interval-container, #custom-interval-container, #month-interval-container").hide();
|
||
break;
|
||
case "2":
|
||
$("#last-x-interval-container, #custom-interval-container, #month-interval-container").hide();
|
||
break;
|
||
case "3":
|
||
$("#last-x-interval-container, #custom-interval-container, #month-interval-container").hide();
|
||
break;
|
||
case "4":
|
||
$("#last-x-interval-container, #custom-interval-container, #month-interval-container").hide();
|
||
break;
|
||
case "5":
|
||
$("#last-x-interval-container").show();
|
||
$("#custom-interval-container, #month-interval-container").hide();
|
||
break;
|
||
case "6":
|
||
$("#custom-interval-container").show();
|
||
$("#last-x-interval-container, #month-interval-container").hide();
|
||
break;
|
||
case "7":
|
||
$("#month-interval-container").show();
|
||
$("#last-x-interval-container, #custom-interval-container").hide();
|
||
break;
|
||
}
|
||
}
|
||
|
||
function changeServiceRecordIntervalSelection(select) {
|
||
const selectedOption = $(select).val();
|
||
|
||
showSpinner();
|
||
|
||
if(["0", "1", "2", "3", "4"].includes(selectedOption)) {
|
||
$("#last-x-interval-container, #custom-interval-container, #month-interval-container").hide();
|
||
}
|
||
else if(selectedOption === "5") {
|
||
$("#last-x-interval-container").show();
|
||
$("#custom-interval-container, #month-interval-container").hide();
|
||
}
|
||
else if(selectedOption === "6") {
|
||
$("#custom-interval-container").show();
|
||
$("#last-x-interval-container, #month-interval-container").hide();
|
||
}
|
||
else if(selectedOption === "7") {
|
||
$("#month-interval-container").show();
|
||
$("#last-x-interval-container, #custom-interval-container").hide();
|
||
}
|
||
|
||
window.loadServiceRecords();
|
||
}
|
||
</script>
|
||
|
||
<script type="text/javascript">
|
||
var _externalCallPollingTimer = null;
|
||
|
||
// Zuletzt verwendeter Modus – wird aus der Session initialisiert
|
||
var _aiVoiceMode = '@Model.AiVoiceMode';
|
||
|
||
function startExternalCall() {
|
||
// Direkt starten mit dem gespeicherten Modus, keine Moduswahl anzeigen
|
||
if (_aiVoiceMode === '1') {
|
||
$('#external-call-status-text').text('Um die Aufnahme zu starten, klicken Sie auf den Link, den wir an Ihren ownChat Account gesendet haben.');
|
||
}
|
||
else {
|
||
$('#external-call-status-text').text('Bitte wechseln Sie zu ownChat um die Aufnahme zu starten.\nHINWEIS: Wenn ownChat auf diesem Gerät nicht installiert ist, ist die Spracheingabe nicht möglich.');
|
||
}
|
||
document.getElementById('external-call-overlay').style.display = 'flex';
|
||
|
||
$.ajax({
|
||
url: '@Url.Action("GetExternalCallUrl", "Main")',
|
||
type: 'GET',
|
||
success: function(result) {
|
||
if (result && result.success) {
|
||
// Custom URL Scheme (ownchat://) per temporärem Anchor-Element öffnen –
|
||
if (result.url && result.url.length > 0) {
|
||
var $a = $('<a>').attr('href', result.url).css('display', 'none').appendTo('body');
|
||
$a[0].click();
|
||
$a.remove();
|
||
}
|
||
// Polling starten - prüft regelmäßig ob der Callback aufgerufen wurde
|
||
_externalCallPollingTimer = setInterval(function() {
|
||
$.ajax({
|
||
url: '@Url.Action("CheckExternalCallStatus", "Main")',
|
||
type: 'GET',
|
||
success: function(pollResult) {
|
||
if (pollResult && pollResult.completed) {
|
||
stopExternalCallPolling();
|
||
onExternalCallCompleted(pollResult.data);
|
||
} else if (pollResult && pollResult.statusMessage) {
|
||
$('#external-call-status-text').text(pollResult.statusMessage);
|
||
}
|
||
},
|
||
error: function() {
|
||
// Bei Fehler weiter pollen
|
||
}
|
||
});
|
||
}, 3000);
|
||
} else {
|
||
document.getElementById('external-call-overlay').style.display = 'none';
|
||
var errorMsg = (result && result.message) ? result.message : 'Die externe URL konnte nicht ermittelt werden.';
|
||
showAlertMessageBox(errorMsg);
|
||
}
|
||
},
|
||
error: function() {
|
||
document.getElementById('external-call-overlay').style.display = 'none';
|
||
showAlertMessageBox('Fehler bei der Kommunikation mit dem Server.');
|
||
}
|
||
});
|
||
}
|
||
|
||
function openAiVoiceSettings() {
|
||
// Aktuellen Modus im Einstellungs-Overlay vorauswählen
|
||
$('input[name="aiVoiceMode"][value="' + _aiVoiceMode + '"]').prop('checked', true);
|
||
document.getElementById('aivoice-settings-overlay').style.display = 'flex';
|
||
}
|
||
|
||
function closeAiVoiceSettings() {
|
||
document.getElementById('aivoice-settings-overlay').style.display = 'none';
|
||
}
|
||
|
||
function saveAiVoiceMode() {
|
||
var selectedMode = $('input[name="aiVoiceMode"]:checked').val();
|
||
$.ajax({
|
||
url: '@Url.Action("SetAiVoiceMode", "Main")',
|
||
data: { mode: selectedMode },
|
||
type: 'POST',
|
||
success: function() {
|
||
_aiVoiceMode = selectedMode;
|
||
closeAiVoiceSettings();
|
||
cancelExternalCall();
|
||
showMessagePopup('Einstellungen gespeichert', 'Die Änderungen wurden übernommen. Bitte starten Sie die Aufnahme erneut.');
|
||
},
|
||
error: function() {
|
||
showAlertMessageBox('Fehler beim Speichern der Einstellung.');
|
||
}
|
||
});
|
||
}
|
||
|
||
function cancelExternalCall() {
|
||
stopExternalCallPolling();
|
||
// Server informieren, dass abgebrochen wurde – callId liegt serverseitig in der Session
|
||
$.ajax({
|
||
url: '@Url.Action("CancelExternalCall", "Main")',
|
||
type: 'POST'
|
||
});
|
||
}
|
||
|
||
function stopExternalCallPolling() {
|
||
if (_externalCallPollingTimer) {
|
||
clearInterval(_externalCallPollingTimer);
|
||
_externalCallPollingTimer = null;
|
||
}
|
||
document.getElementById('external-call-overlay').style.display = 'none';
|
||
}
|
||
|
||
function onExternalCallCompleted(data) {
|
||
var $target;
|
||
var targetIndex;
|
||
|
||
// Prüfen ob die Tab-Ansicht sichtbar ist (mehrere Dokutypes vorhanden)
|
||
var $activeTabTextarea = $('#dokufelderTab .tab-pane.active textarea');
|
||
if ($activeTabTextarea.length > 0) {
|
||
// Das aktive Tab-Textarea verwenden; Index aus der ID auslesen (sb-doku-textarea-{i})
|
||
$target = $activeTabTextarea;
|
||
targetIndex = parseInt($target.attr('id').replace('sb-doku-textarea-', ''), 10);
|
||
} else {
|
||
// Fallback: Einzelfeld Dokumentation6
|
||
$target = $('#sb-doku-textarea-5');
|
||
targetIndex = 5;
|
||
}
|
||
|
||
if ($target.length > 0) {
|
||
$target.val(data);
|
||
window.updateDokuText('sb', data, targetIndex);
|
||
}
|
||
}
|
||
</script>
|
||
|
||
@using(Html.BeginForm("ResetSingleBookingForm", "Main", FormMethod.Post, new { Id = "reset-single-booking-form-form" })) { }
|
||
|
||
<div class="row">
|
||
@* ----- Einzelbuchungsformular ----- *@
|
||
<div class="col col-12 col-md-5 booking-form-container">
|
||
@if (Model != null)
|
||
{
|
||
using (Html.BeginForm("SelectSupportConcept", "Main", FormMethod.Post, new { Id = "selectSupportConceptForm", onreset = "resetSingleBookingForm()" }))
|
||
{
|
||
var selectedSuportConceptTimeSpanColorClass = (Model.SelectedSupportConceptListObject?.IsAboutToExpire ?? false)
|
||
? "text-bewo-is-about-to-expire"
|
||
: (Model.SelectedSupportConceptListObject?.ExpiresInThreeMonthsOrLess ?? false)
|
||
? "text-bewo-expires-in-three-months"
|
||
: "text-light";
|
||
|
||
var isFormDisabled = Model.SelectedCostBearerSupportConceptOid.HasValue ? string.Empty : "disabled";
|
||
var nameAndDateOfBirth = Model.SelectedSupportConceptListObject?.NameAndDateOfBirth ?? string.Empty;
|
||
var supportConceptTimeSpan = Model.SelectedSupportConceptListObject?.SupportConceptTimeSpan ?? string.Empty;
|
||
|
||
<div>
|
||
<div class="container p-0">
|
||
<div class="row">
|
||
<div class="col mt-3">
|
||
<div class="list-group">
|
||
<a href="#" class="list-group-item flex-column align-items-start no-underline bg-bewo-task-red" data-toggle="modal" data-target="#supportConceptList">
|
||
<div class="d-flex">
|
||
<h5 class="mb-1 text-light text-left" id="selectedSupportConceptCustomerInfo">@nameAndDateOfBirth</h5>
|
||
</div>
|
||
@if(Model.SelectedCostBearerSupportConceptOid > 0)
|
||
{
|
||
<div class="dropdown-divider my-0 py-0"></div>
|
||
}
|
||
<p class="mb-1 text-left small @selectedSuportConceptTimeSpanColorClass" id="selectedSupportConceptInfo">
|
||
@supportConceptTimeSpan
|
||
</p>
|
||
</a>
|
||
</div>
|
||
</div>
|
||
@if(Model.SelectedCostBearerSupportConceptOid is > 0)
|
||
{
|
||
<div class="col-md-auto mt-3">
|
||
<button type="button" class="btn btn-outline-primary w-100 h-100" id="statistics-button" data-toggle="modal" data-target="#statistics-popup" onclick="showPieChart()">
|
||
<span class="d-md-none align-middle">Statistik</span>
|
||
<span class="fas fa-chart-pie align-middle" style="font-size: 2rem;"></span>
|
||
</button>
|
||
</div>
|
||
}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
@* Hilfeplanauswahlpopup *@
|
||
<div class="modal" role="dialog" tabindex="-1" id="supportConceptList">
|
||
<div class="modal-dialog text-center modal-dialog-scrollable" role="document">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h5 class="modal-title font-weight-bold">Hilfeplanauswahl</h5>
|
||
<button type="button" class="close" data-dismiss="modal" onclick="resetSupportConceptSearch()">
|
||
<span>×</span>
|
||
</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
@* Hilfeplansuche *@
|
||
<div class="input-group mb-3">
|
||
<input class="form-control w-100" autocomplete="on" type="text" placeholder="Suchen..." oninput="supportConceptSearchOnChange()" id="support-concept-search-input" />
|
||
<div class="input-group-append">
|
||
<button class="btn btn-outline-secondary" type="button" onclick="resetSupportConceptSearch()">
|
||
<span class="fas fa-times-circle"></span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<hr />
|
||
@* Hilfeplanliste *@
|
||
<div class="list-group">
|
||
@foreach (var supportConceptListObject in Model.SupportConceptListObjects)
|
||
{
|
||
var nameAndDoBColorClass = "text-dark";
|
||
|
||
var timeSpanColorClass = supportConceptListObject.IsAboutToExpire ?
|
||
"text-bewo-is-about-to-expire" :
|
||
supportConceptListObject.ExpiresInThreeMonthsOrLess ?
|
||
"text-bewo-expires-in-three-months" :
|
||
"text-dark";
|
||
|
||
if(supportConceptListObject.IsArchived)
|
||
{
|
||
timeSpanColorClass = "text-bewo-archived-sc";
|
||
nameAndDoBColorClass = timeSpanColorClass;
|
||
}
|
||
else if(supportConceptListObject.IsDeleted)
|
||
{
|
||
timeSpanColorClass = "text-bewo-deleted-sc";
|
||
nameAndDoBColorClass = timeSpanColorClass;
|
||
}
|
||
|
||
<a href="#" class="list-group-item flex-column align-items-start no-underline blubb-test" onclick="selectSupportConcept(@supportConceptListObject.CostBearer2SupportConceptOid)" data-dismiss="modal">
|
||
<div class="justify-content-between">
|
||
<h5 class="mb-1 text-dark text-left supportconcept-name-header @nameAndDoBColorClass">
|
||
@supportConceptListObject.NameAndDateOfBirth
|
||
</h5>
|
||
</div>
|
||
<p class="mb-1 text-left @timeSpanColorClass">
|
||
@supportConceptListObject.SupportConceptTimeSpan
|
||
</p>
|
||
</a>
|
||
}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
@* /Hilfeplanauswahlpopup *@
|
||
|
||
<input type="hidden" name="CostBearer2SupportConceptOid" id="sb-cb2ScRelOid" value="@Model.SelectedSupportConceptListObject.CostBearer2SupportConceptOid">
|
||
}
|
||
|
||
if(Model.IsCustomerAbsence)
|
||
{
|
||
<div class="container my-1 mb-0 mx-auto p-0 w-100 text-center">
|
||
<span>
|
||
<i class="fas fa-exclamation-triangle text-warning"></i>
|
||
<div class="text-danger d-inline">Klient ist abwesend</div>
|
||
<p class="text-danger mb-0 pb-0">@Model.CustomerAbsenceInfo</p>
|
||
</span>
|
||
</div>
|
||
}
|
||
|
||
using(Html.BeginForm("CreateOrUpdateServiceRecord", "Main", FormMethod.Post, new { id = "singleBookingForm" }))
|
||
{
|
||
<div>
|
||
@* ----- Einzelbuchung: Mitarbeiter ----- *@
|
||
<div class="form-row">
|
||
<div class="col-md">
|
||
<div class="mt-2" id="single-booking-employee-container">
|
||
@Html.PopupWithSearchForIFilterables(Model.Employees, "setSelectedEmployeeForSingleBooking", null, Model.SelectedEmployee?.DetailDescription, "single-booking-employee-modal-popup", false)
|
||
|
||
@{
|
||
var sbEmployeeInputValue = string.Empty;
|
||
|
||
if (Model.SelectedEmployee?.EmployeeOid is not null)
|
||
{
|
||
sbEmployeeInputValue = $"value=\"{Model.SelectedEmployee.EmployeeOid}\"";
|
||
}
|
||
}
|
||
|
||
<input type="hidden" id="sb-employee-input" onchange="window.updateEmployeeOids('sb', $(this).val())" @sbEmployeeInputValue />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
@* ----- Einzelbuchung: Ziele ----- *@
|
||
@if (Model.SelectedSupportConcept != null && Model.SelectedSupportConcept.Goals.Any())
|
||
{
|
||
<div class="form-row">
|
||
<div class="col-md mt-2">
|
||
<div class="card w-100">
|
||
<div class="card-header py-0" onclick="cardHeaderClick2(this)">
|
||
<div class="d-inline-flex">
|
||
<i class="fas @Html.GetCollapsibleChevron(Model, "goals-container") h-100 text-dark"></i>
|
||
</div>
|
||
<div class="d-inline-flex h-100">
|
||
<button type="button" class="btn btn-link text-dark">
|
||
Ziele
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<div class="collapse @Html.GetCollapsibleClass(Model.Collapsibles2IsShown, "goals-container")" id="goals-container">
|
||
<div class="card-body p-1">
|
||
<div class="input-group input-group-sm mb-1">
|
||
<input type="text" class="form-control" placeholder="Suchen ..." id="goal-search-input" oninput="goalTreeSearchOnChangeV2($(this))" />
|
||
<div class="input-group-append">
|
||
<button type="button" class="btn btn-outline-secondary" onclick="resetGoalTreeSearch()">
|
||
<span class="fas fa-times-circle"></span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<div class="btn-group btn-group-sm mb-1 w-100" role="group">
|
||
<button type="button" class="btn btn-outline-primary" onclick="window.showAllGoals()">Alle auf</button>
|
||
<button type="button" class="btn btn-outline-primary" onclick="window.hideAllGoals()">Alle zu</button>
|
||
</div>
|
||
<div class="container p-0 m-0" id="goals-tree">
|
||
@Html.Partial("GoalTreePartial", Model)
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
}
|
||
|
||
@* ----- Einzelbuchung: Kategorie & Leistung ----- *@
|
||
<div id="category-to-description-container">
|
||
@Html.Partial("Category2ServiceDescriptionPartial", Model)
|
||
</div>
|
||
|
||
@* ----- Marker ----- *@
|
||
@if (Model.ShowMarker)
|
||
{
|
||
var markerCheckedValue = Model.SelectedServiceRecord?.ServiceRecordType == ServiceRecordTypeId.Content ? "checked" : string.Empty;
|
||
|
||
<div class="form-row">
|
||
<div class="col-md mt-1">
|
||
<div class=" custom-control custom-checkbox custom-control-inline my-0">
|
||
<input type="checkbox" class="custom-control-input" onchange="window.updateMarker('sb', $(this).val());" name="@FormCollectionConstants.MarkerKey" id="sb-marker-cb" @markerCheckedValue />
|
||
<label class="custom-control-label" for="sb-marker-cb">Marker</label>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
}
|
||
|
||
@* ----- Betrag ----- *@
|
||
@if (Model.ShowBetrag)
|
||
{
|
||
var betrag = string.Empty;
|
||
if (Model.SelectedServiceRecord?.Betrag is > 0)
|
||
{
|
||
betrag = Model.SelectedServiceRecord.Betrag.Value.ToString("#.00");
|
||
}
|
||
|
||
<div class="form-row mt-1">
|
||
<div class="col-md">
|
||
<div class="form-group my-0">
|
||
<div class="input-group">
|
||
<div class="input-group-prepend">
|
||
<div class="input-group-text prepend-input-group-text">
|
||
Betrag
|
||
</div>
|
||
</div>
|
||
<input class="form-control" autocomplete="on" onchange="window.updateBetrag('sb', $(this).val())" type="text" id="sb-betrag" name="betrag" value="@betrag" />
|
||
<div class="input-group-append">
|
||
<div class="input-group-text">€</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
}
|
||
|
||
<hr class="mt-2 mb-0" />
|
||
|
||
@* ----- Einzelbuchung: Startdatum und gegebenenfalls Enddatum ----- *@
|
||
@{
|
||
var divisor = Model.SelectedDurationUnit == "Stunden" ? 60 : 1;
|
||
var durationValue = Model.DurationToEdit;
|
||
|
||
var afterValidationState = TempData[TempDataConstants.AfterValidationStateKey];
|
||
|
||
if (Model.SetStartTimeToEndTimeAfterSave && !Model.IsInEditingMode && afterValidationState is false)
|
||
{
|
||
durationValue = Model.NewDuration?.ToString();
|
||
if (Model.NewDuration.HasValue)
|
||
{
|
||
durationValue = (Model.NewDuration / divisor).ToString();
|
||
}
|
||
}
|
||
|
||
var columnWidth = Model.IsEndDateVisible ? "col-md-6" : "col";
|
||
}
|
||
|
||
<div class="form-row">
|
||
<div class="@columnWidth mt-2">
|
||
<div class="input-group">
|
||
<div class="input-group-prepend">
|
||
<span class="input-group-text prepend-input-group-text">
|
||
Startdatum
|
||
</span>
|
||
</div>
|
||
<input class="form-control" type="date" name="Datum" id="sb-start-date-input" onchange="calcDuration('sb', false, true, false); window.updateStartDate('sb', $(this).val());" value="@Model.StartDateToEditJSFormat" />
|
||
</div>
|
||
</div>
|
||
@if (Model.IsEndDateVisible)
|
||
{
|
||
<div class="col-md-6 mt-2">
|
||
<div class="input-group">
|
||
<div class="input-group-prepend">
|
||
<span class="input-group-text prepend-input-group-text">
|
||
Enddatum
|
||
</span>
|
||
</div>
|
||
<input class="form-control" type="date" name="Enddatum" id="sb-end-date-input" onchange="calcDuration('sb', false, false, true); window.updateEndDate('sb', $(this).val());" value="@Model.EndDateToEditJSFormat" />
|
||
</div>
|
||
</div>
|
||
}
|
||
</div>
|
||
<div class="form-row">
|
||
@{
|
||
var von = Model.IsInTransferMode || Model.IsInEditingMode || afterValidationState is true ? Model.StartTimeToEdit : Model.NewStartTime;
|
||
var bis = Model.IsInTransferMode || Model.IsInEditingMode || afterValidationState is true ? Model.EndTimeToEdit : Model.NewEndTime;
|
||
|
||
var x = von;
|
||
}
|
||
<div class="col mt-2">
|
||
<div class="input-group">
|
||
<div class="input-group-prepend">
|
||
<span class="input-group-text">
|
||
Von
|
||
</span>
|
||
</div>
|
||
<input class="form-control" type="time" name="Start" id="sb-start-time-input" onchange="calcDuration('sb', false, true, false);window.updateStartTime('sb', $(this).val());" value="@von" />
|
||
<span class="input-group-text rounded-0 border-left-0 border-right-0">
|
||
Bis
|
||
</span>
|
||
<input class="form-control" type="time" name="Ende" id="sb-end-time-input" onchange="calcDuration('sb', false, false, true);window.updateEndTime('sb', $(this).val());" value="@bis" />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
@* ----- Einzelbuchung: Dauer ----- *@
|
||
<div class="form-row mt-2">
|
||
<div class="col-md">
|
||
<div class="form-group my-0">
|
||
<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" id="sb-duration-label">
|
||
@labelText
|
||
</div>
|
||
</div>
|
||
<input type="text" class="form-control" id="sb-duration-input" name="Dauer" onchange="beiDaueraenderung('sb'); window.updateDuration('sb', $(this).val());" value="@durationValue">
|
||
@if (Model.IsZeiterfassungInStdMin)
|
||
{
|
||
<div class="input-group-append">
|
||
<button id="sb-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">
|
||
<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 mt-2">
|
||
<div class="col-md">
|
||
<div class="form-group my-0">
|
||
<div class="input-group">
|
||
<div class="input-group-prepend">
|
||
<div class="input-group-text">
|
||
Gefahrene Kilometer
|
||
</div>
|
||
</div>
|
||
<input class="form-control" autocomplete="on" id="sb-distance-input" name="Distanz" onchange="validateDistanceInput(); window.updateDistance('sb', $(this).val());" value="@Model.DistanceToEdit">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
}
|
||
|
||
@* ----- Einzelbuchung: Textbausteine ----- *@
|
||
@if (Model.HasRightToSeeTextModules)
|
||
{
|
||
<script type="text/javascript">
|
||
function textModuleButtonOnClick() {
|
||
$('#tree').load('@Url.Action("LoadUpToDateTextModules")');
|
||
}
|
||
</script>
|
||
<div class="form-row mt-2" id="textmodule-container">
|
||
<div class="col-md">
|
||
<button type="button" class="btn btn-primary form-control" data-toggle="modal" data-target="#textbausteine-popup" id="sb-textbausteine-btn" onclick="textModuleButtonOnClick()">Textbausteine</button>
|
||
</div>
|
||
</div>
|
||
}
|
||
@* ----- Einzelbuchung: KI Funktionen ----- *@
|
||
@if (Model.HasRightToSeeAiPromptsInZeiterfassung)
|
||
{
|
||
<script type="text/javascript">
|
||
|
||
</script>
|
||
<div class="form-row mt-2" id="aifunction-container">
|
||
<div class="col-md">
|
||
@if (Model.HasRightToUseAiVoice)
|
||
{
|
||
<button type="button" class="btn btn-primary float-right mr-1" id="aivoice-button" onclick="startExternalCall();" title="KI-Spracheingabe & Transkription" style="padding: 0 0.6em; overflow: hidden; line-height: 0;"><img src="@Url.Content("~/Content/images/Icon_Mikro_Weiss.png")" alt="KI-Spracheingabe & Transkription" style="height:2.25em; display: block;" /></button>
|
||
}
|
||
<button type="button" class="btn btn-primary float-right mr-1" id="aiprompt-btn" style="padding: 0 0.6em; overflow: hidden; line-height: 0;"><img src="@Url.Content("~/Content/images/Icon_KI_Funktion_Weiss+Gruen.png")" alt="KI-Promptbausteine auswählen" style="height:2.25em; display: block;" /></button>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
|
||
|
||
<!-- KI-Promptbausteine Modal -->
|
||
<div class="modal fade" id="aiprompt-modal" tabindex="-1" role="dialog" aria-labelledby="aiprompt-modal-title" aria-hidden="true">
|
||
<div class="modal-dialog modal-lg" role="document">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h5 class="modal-title" id="aiprompt-modal-title">KI-Promptbausteine auswählen</h5>
|
||
<button type="button" class="close" data-dismiss="modal" aria-label="Schließen">
|
||
<span aria-hidden="true">×</span>
|
||
</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="row" style="min-height: 350px;">
|
||
<div class="col-md-5 border-right" id="aiprompt-tree-col">
|
||
<div id="aiprompt-tree" style="overflow-y: auto; max-height: 400px;">
|
||
<div class="text-muted small p-2">Wird geladen…</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-7" id="aiprompt-prompts-col">
|
||
<div id="aiprompt-prompts-list">
|
||
<div class="text-muted small p-2">Bitte einen Ordner auswählen.</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn btn-secondary" data-dismiss="modal">Schließen</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script type="text/javascript">
|
||
(function () {
|
||
function buildTree(folders, container, level) {
|
||
folders.forEach(function (folder) {
|
||
var indent = level * 16;
|
||
var item = $('<div class="aiprompt-folder-item" style="cursor:pointer; padding: 4px 6px; border-radius:4px; margin-bottom:2px;">'
|
||
+ '<span style="display:inline-block; width:' + indent + 'px;"></span>'
|
||
+ '<span class="aiprompt-folder-toggle mr-1" style="display:inline-block; width:14px;">'
|
||
+ (folder.SubFolders && folder.SubFolders.length > 0 ? '▶' : ' ')
|
||
+ '</span>'
|
||
+ '<span class="aiprompt-folder-label"><strong>' + $('<div>').text(folder.Title).html() + '</strong></span>'
|
||
+ '</div>');
|
||
|
||
var subContainer = null;
|
||
if (folder.SubFolders && folder.SubFolders.length > 0) {
|
||
subContainer = $('<div class="aiprompt-subfolders" style="display:none;"></div>');
|
||
buildTree(folder.SubFolders, subContainer, level + 1);
|
||
}
|
||
|
||
item.on('click', function (e) {
|
||
e.stopPropagation();
|
||
$('.aiprompt-folder-item').removeClass('bg-primary text-white').css('color', '');
|
||
item.addClass('bg-primary text-white');
|
||
|
||
if (subContainer) {
|
||
var expanded = subContainer.is(':visible');
|
||
subContainer.toggle(!expanded);
|
||
item.find('.aiprompt-folder-toggle').html(expanded ? '▶' : '▼');
|
||
}
|
||
|
||
showPrompts(folder.SubPrompts || []);
|
||
});
|
||
|
||
container.append(item);
|
||
if (subContainer) container.append(subContainer);
|
||
});
|
||
}
|
||
|
||
function showPrompts(prompts) {
|
||
var list = $('#aiprompt-prompts-list').empty();
|
||
if (!prompts || prompts.length === 0) {
|
||
list.html('<div class="text-muted small p-2">Keine Prompts in diesem Ordner.</div>');
|
||
return;
|
||
}
|
||
prompts.forEach(function (p) {
|
||
var card = $('<div class="card mb-2" style="cursor:pointer;"></div>');
|
||
var body = $('<div class="card-body p-2"></div>');
|
||
body.append($('<h6 class="card-title mb-1"></h6>').text(p.Title));
|
||
if (p.Description) body.append($('<p class="card-text small text-muted mb-0"></p>').text(p.Description));
|
||
card.append(body);
|
||
card.on('click', function () {
|
||
if (p.Oid == null) return;
|
||
// Prompt server-seitig ausführen und Ergebnis ins Doku-Feld schreiben
|
||
var $card = $(this);
|
||
$('#aiprompt-prompts-list .card').css('pointer-events', 'none').css('opacity', '0.5');
|
||
$card.css('opacity', '1').append(
|
||
'<div class="aiprompt-loading text-muted small mt-1">'
|
||
+ '<span class="spinner-border spinner-border-sm mr-1"></span>Wird ausgeführt …</div>');
|
||
$.ajax({
|
||
url: '@Url.Action("StartPrompt", "Main")',
|
||
type: 'POST',
|
||
data: { promptOid: p.Oid },
|
||
success: function (resp) {
|
||
$('#aiprompt-modal').modal('hide');
|
||
var text = resp && resp.text ? resp.text : '';
|
||
var activeTextarea = $('textarea:visible:first[id^="sb-doku-textarea"]');
|
||
if (activeTextarea.length && text) {
|
||
var current = activeTextarea.val();
|
||
activeTextarea.val(current ? current + '\n' + text : text).trigger('change');
|
||
}
|
||
},
|
||
error: function (xhr) {
|
||
var msg = 'Fehler beim Ausführen des Prompts.';
|
||
try {
|
||
var r = JSON.parse(xhr.responseText);
|
||
if (r && r.message) msg += '\n' + r.message;
|
||
} catch (e) { }
|
||
console.error('StartPrompt Fehler:', xhr.status, xhr.responseText);
|
||
$('.aiprompt-loading').remove();
|
||
$('#aiprompt-prompts-list .card').css('pointer-events', '').css('opacity', '');
|
||
alert(msg);
|
||
}
|
||
});
|
||
});
|
||
list.append(card);
|
||
});
|
||
}
|
||
|
||
var dataLoaded = false;
|
||
|
||
$('#aiprompt-btn').on('click', function () {
|
||
$('#aiprompt-modal').modal('show');
|
||
if (dataLoaded) return;
|
||
$.ajax({
|
||
url: '@Url.Action("GetAiPromptbausteinFolder", "Main")',
|
||
type: 'GET',
|
||
success: function (data) {
|
||
dataLoaded = true;
|
||
var tree = $('#aiprompt-tree').empty();
|
||
if (!data || data.length === 0) {
|
||
tree.html('<div class="text-muted small p-2">Keine Ordner verfügbar.</div>');
|
||
return;
|
||
}
|
||
buildTree(data, tree, 0);
|
||
},
|
||
error: function (xhr, textStatus, errorThrown) {
|
||
var details = 'Status: ' + xhr.status + ' ' + (xhr.statusText || '')
|
||
+ '\ntextStatus: ' + textStatus
|
||
+ '\nerror: ' + errorThrown;
|
||
if (xhr.responseText) {
|
||
details += '\n\nAntwort:\n' + xhr.responseText.substring(0, 4000);
|
||
}
|
||
console.error('GetAiPromptbausteinFolder Fehler:', details);
|
||
$('#aiprompt-tree').html(
|
||
'<div class="text-danger small p-2">Fehler beim Laden der Promptbausteine.<br/>'
|
||
+ '<pre style="white-space:pre-wrap; font-size:11px; max-height:320px; overflow:auto;">'
|
||
+ $('<div>').text(details).html()
|
||
+ '</pre></div>');
|
||
}
|
||
});
|
||
});
|
||
})();
|
||
</script>
|
||
}
|
||
@* ----- Einzelbuchung: Dokumentation ----- *@
|
||
<div class="form-row">
|
||
<div class="col-md mt-3">
|
||
@if (Model.NumberOfDokuTypes == 0)
|
||
{
|
||
<div class="form-group my-0">
|
||
<label for="sb-doku-textarea-5">Dokumentation</label>
|
||
<textarea class="form-control" autocomplete="on" style="overflow: scroll;" onchange="window.updateDokuText('sb', $(this).val(), 5)" name="Dokumentation6" id="sb-doku-textarea-5">@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];
|
||
|
||
<li class="nav-item">
|
||
<a href="#sb-doku_@i" id="sb-doku_@i-tab" onchange="window.updateDokuText('sb', $(this).val(), @i)" data-toggle="tab" role="tab" class="nav-link@(i == 0 ? " active" : string.Empty)">
|
||
@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="sb-doku_@i" role="tabpanel">
|
||
<textarea class="form-control doku-form-control" onchange="window.updateDokuText('sb', $(this).val(), @i)" autocomplete="on" style="overflow: scroll;" id="sb-doku-textarea-@i" name="@textareaName">@Model.NoticeListToEdit[i]</textarea>
|
||
</div>
|
||
}
|
||
</div>
|
||
}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
}
|
||
|
||
<div class="w-100 mt-2">
|
||
<button type="button" class="btn btn-primary float-right ml-1" id="create-button" onclick="submitSingleBookingForm()">@Model.SubmitButtonValue</button>
|
||
|
||
@if (Model.IsInEditingMode)
|
||
{
|
||
using (Html.BeginForm("ResetEditingMode", "Main", FormMethod.Post))
|
||
{
|
||
<button type="submit" class="btn btn-primary float-right" onclick="showSpinner()">Abbrechen</button>
|
||
}
|
||
}
|
||
else if (Model.IsInTransferMode)
|
||
{
|
||
using (Html.BeginForm("ResetTransferMode", "Main", FormMethod.Post))
|
||
{
|
||
<button type="submit" class="btn btn-primary float-right" onclick="showSpinner()">Abbrechen</button>
|
||
}
|
||
}
|
||
else
|
||
{
|
||
<button type="button" class="btn btn-primary float-right" id="reset-button" onclick="resetSingleBookingForm();">Abbrechen</button>
|
||
}
|
||
|
||
|
||
|
||
@Html.Partial("RestoreServiceRecordInputsPartial", Model)
|
||
</div>
|
||
|
||
@* Warte-Overlay für externen Aufruf *@
|
||
<div id="external-call-overlay" style="display:none; position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.6); z-index:9999; justify-content:center; align-items:center;">
|
||
<div style="background:white; border-radius:8px; padding:30px; min-width:300px; text-align:center; box-shadow:0 4px 20px rgba(0,0,0,0.3);">
|
||
<div class="mb-3">
|
||
<i class="fa fa-spinner fa-spin fa-2x"></i>
|
||
</div>
|
||
<p class="mb-3" id="external-call-status-text" style="white-space: pre-line">Bitte warten...</p>
|
||
<button type="button" class="btn btn-secondary mr-2" onclick="openAiVoiceSettings();">
|
||
<i class="fa fa-cog mr-1"></i>Einstellungen
|
||
</button>
|
||
<button type="button" class="btn btn-danger" onclick="cancelExternalCall();">Abbrechen</button>
|
||
</div>
|
||
</div>
|
||
|
||
@* Einstellungs-Overlay für Moduswahl *@
|
||
<div id="aivoice-settings-overlay" style="display:none; position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.7); z-index:10000; justify-content:center; align-items:center;">
|
||
<div style="background:white; border-radius:8px; padding:30px; max-width:480px; box-shadow:0 4px 20px rgba(0,0,0,0.3);">
|
||
<h6 class="mb-3">Modus für Spracheingabe</h6>
|
||
<div class="form-group text-left mb-4">
|
||
<div class="form-check mb-3">
|
||
<input class="form-check-input" type="radio" name="aiVoiceMode" id="aiVoiceModeDirect" value="0" />
|
||
<label class="form-check-label font-weight-bold" for="aiVoiceModeDirect">
|
||
Spracheingabe direkt aus Mobilklient starten
|
||
</label>
|
||
<small class="form-text text-muted">Diese Option setzt voraus, dass Mobilklient und ownChat auf gleichem Endgerät genutzt werden</small>
|
||
</div>
|
||
<div class="form-check">
|
||
<input class="form-check-input" type="radio" name="aiVoiceMode" id="aiVoiceModePush" value="1" />
|
||
<label class="form-check-label font-weight-bold" for="aiVoiceModePush">
|
||
Spracheingabe per Push-Nachricht starten
|
||
</label>
|
||
<small class="form-text text-muted">Diese Option ermöglicht die Nutzung von Mobilklient und ownChat auf getrennten Endgeräten wie bei der Vollversion</small>
|
||
</div>
|
||
</div>
|
||
<div class="text-right">
|
||
<button type="button" class="btn btn-secondary mr-2" onclick="closeAiVoiceSettings();">Schließen</button>
|
||
<button type="button" class="btn btn-primary" onclick="saveAiVoiceMode();">Speichern</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
}
|
||
</div>
|
||
@* /Einzelbuchungsformular *@
|
||
|
||
@* ----- Liste mit den Einträgen und dem Auswahl-Select ----- *@
|
||
<div class="col col-12 col-md-7">
|
||
@if(Model != null)
|
||
{
|
||
if(Model.SelectedSupportConcept != null || Model.SelectedCostBearerSupportConceptOid == -2)
|
||
{
|
||
var defaultStartDate = DateTime.Now.GetFirstOfMonth().ToString("yyyy-MM-dd");
|
||
var defaultEndDate = DateTime.Today.ToString("yyyy-MM-dd");
|
||
|
||
if (Model.SelectedZeitraum != null && Model.SelectedZeitraum.StartDate.HasValue && Model.SelectedZeitraum.EndDate.HasValue)
|
||
{
|
||
defaultStartDate = Model.SelectedZeitraum.StartDate.Value.ToString("yyyy-MM-dd");
|
||
defaultEndDate = Model.SelectedZeitraum.EndDate.Value.ToString("yyyy-MM-dd");
|
||
}
|
||
<div class="container-fluid w-100 mt-3 p-0">
|
||
<div class="form-row">
|
||
<div class="col">
|
||
<div class="form-group">
|
||
<select name="Records" class="custom-select" onchange="changeServiceRecordIntervalSelection(this)" id="timeFrameSelect">
|
||
<option value="5"
|
||
@{if(Model.ServiceRecordTimeInterval == ServiceRecordTimeInterval.XTage) { @Html.Raw("selected") }}>
|
||
Letzten x Tage
|
||
</option>
|
||
<option value="0"
|
||
@{if(Model.ServiceRecordTimeInterval == ServiceRecordTimeInterval.LastWeek) { @Html.Raw("selected") }}>
|
||
Letzten 7 Tage
|
||
</option>
|
||
<option value="1"
|
||
@{if(Model.ServiceRecordTimeInterval == ServiceRecordTimeInterval.LastMonth) { @Html.Raw("selected") }}>
|
||
Letzten 30 Tage
|
||
</option>
|
||
<option value="2"
|
||
@{if(Model.ServiceRecordTimeInterval == ServiceRecordTimeInterval.Last3Month) { @Html.Raw("selected") }}>
|
||
Letzten 90 Tage
|
||
</option>
|
||
<option value="3"
|
||
@{if(Model.ServiceRecordTimeInterval == ServiceRecordTimeInterval.All) { @Html.Raw("selected") }}>
|
||
Alle
|
||
</option>
|
||
<option value="6"
|
||
@{if(Model.ServiceRecordTimeInterval == ServiceRecordTimeInterval.ZeitraumWaehlen) { @Html.Raw("selected") }}>
|
||
Zeitraum wählen
|
||
</option>
|
||
<option value="7"
|
||
@{if(Model.ServiceRecordTimeInterval == ServiceRecordTimeInterval.Monatsauswahl) { @Html.Raw("selected") }}>
|
||
Monat wählen
|
||
</option>
|
||
</select>
|
||
|
||
</div>
|
||
</div>
|
||
<div class="col-auto">
|
||
<button type="button" class="btn btn-success w-100" onclick="loadServiceRecords()">
|
||
<span class="fas fa-sync-alt"></span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
@*----- Anzahl Tage: [Nummern-Input] ----- *@
|
||
<div class="form-row" id="last-x-interval-container">
|
||
<div class="col-12">
|
||
<div class="form-group">
|
||
<div class="input-group">
|
||
<div class="input-group-prepend">
|
||
<span class="input-group-text">Anzahl Tage:</span>
|
||
</div>
|
||
<input class="form-control" id="day-count-number" type="number" name="day-count-number" min="0" value="@Model.LastSelectedServiceRecordTimeIntervalDays" />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
@*----- Zeitraum wählen: [Von-Datum] bis [Bis-Datum] erster des Monats bis aktuelles Datum ----- *@
|
||
<div class="form-row" id="custom-interval-container">
|
||
<div class="col-12">
|
||
<div class="form-group">
|
||
<div class="form-row">
|
||
<div class="col mt-2">
|
||
<div class="input-group">
|
||
<div class="input-group-prepend">
|
||
<span class="input-group-text">
|
||
Von
|
||
</span>
|
||
</div>
|
||
<input class="form-control" type="date" name="von" id="time-frame-start-date" onfocusout="loadServiceRecords()" value="@defaultStartDate"/>
|
||
<span class="input-group-text rounded-0 border-left-0 border-right-0">
|
||
Bis
|
||
</span>
|
||
<input class="form-control" type="date" name="bis" id="time-frame-end-date" onfocusout="loadServiceRecords()" value="@defaultEndDate"/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-row" id="month-interval-container">
|
||
<div class="col-6">
|
||
<div class="form-group">
|
||
<div class="input-group">
|
||
<div class="input-group-prepend">
|
||
<span class="input-group-text">Monat</span>
|
||
</div>
|
||
<select name="month-select" class="custom-select" id="month-select" onchange="loadServiceRecords()">
|
||
<option value="1"
|
||
@{if(Model.LastSelectedServiceRecordMonth.Month == 1) { @Html.Raw("selected") } }>
|
||
Januar
|
||
</option>
|
||
<option value="2"
|
||
@{if(Model.LastSelectedServiceRecordMonth.Month == 2) { @Html.Raw("selected") } }>
|
||
Februar
|
||
</option>
|
||
<option value="3"
|
||
@{ if(Model.LastSelectedServiceRecordMonth.Month == 3) { @Html.Raw("selected") } }>
|
||
März
|
||
</option>
|
||
<option value="4"
|
||
@{if(Model.LastSelectedServiceRecordMonth.Month == 4) { @Html.Raw("selected") }}>
|
||
April
|
||
</option>
|
||
<option value="5"
|
||
@{if(Model.LastSelectedServiceRecordMonth.Month == 5) { @Html.Raw("selected") }}>
|
||
Mai
|
||
</option>
|
||
<option value="6"
|
||
@{if(Model.LastSelectedServiceRecordMonth.Month == 6) { @Html.Raw("selected") }}>
|
||
Juni
|
||
</option>
|
||
<option value="7"
|
||
@{if(Model.LastSelectedServiceRecordMonth.Month == 7) { @Html.Raw("selected") }}>
|
||
Juli
|
||
</option>
|
||
<option value="8"
|
||
@{if(Model.LastSelectedServiceRecordMonth.Month == 8) { @Html.Raw("selected") }}>
|
||
August
|
||
</option>
|
||
<option value="9"
|
||
@{if(Model.LastSelectedServiceRecordMonth.Month == 9) { @Html.Raw("selected") }}>
|
||
September
|
||
</option>
|
||
<option value="10"
|
||
@{if(Model.LastSelectedServiceRecordMonth.Month == 10) { @Html.Raw("selected") }}>
|
||
Oktober
|
||
</option>
|
||
<option value="11"
|
||
@{if(Model.LastSelectedServiceRecordMonth.Month == 11) { @Html.Raw("selected") }}>
|
||
November
|
||
</option>
|
||
<option value="12"
|
||
@{if(Model.LastSelectedServiceRecordMonth.Month == 12) { @Html.Raw("selected") }}>
|
||
Dezember
|
||
</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-6">
|
||
<div class="form-group">
|
||
<div class="input-group">
|
||
<div class="input-group-prepend">
|
||
<span class="input-group-text">Jahr</span>
|
||
</div>
|
||
<select class="custom-select" name="year-select" id="year-select" onchange="loadServiceRecords()">
|
||
@{
|
||
var heuer = DateTime.Today.Year;
|
||
for(var year = heuer + 1; year >= heuer - 10; year--)
|
||
{
|
||
<option value="@year"
|
||
@{if(Model.LastSelectedServiceRecordMonth.Year == year) { @Html.Raw("selected") }}>
|
||
@year
|
||
</option>
|
||
}
|
||
}
|
||
</select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
}
|
||
|
||
<hr class="mt-2"/>
|
||
|
||
<div class="container-fluid mt-3" id="service-record-list-container">
|
||
@Html.Partial("ServiceRecordListPartial", Model)
|
||
</div>
|
||
}
|
||
</div>
|
||
@* ----- /Liste mit den Einträgen und dem Auswahl-Select ----- *@
|
||
</div>
|
||
|
||
@using(Html.BeginForm("DeleteSignature", "Main", FormMethod.Post, new { id = "delete-signature-form" }))
|
||
{
|
||
<input type="hidden" name="sr-signature-to-del-oid" id="sr-signature-to-del-oid-input" />
|
||
<input type="hidden" name="sr-sig-to-del-record-oid" id="sr-sig-to-del-record-oid-input" />
|
||
} |