Merge branch 'master' of ssh://float.ownsoft.de/git/beyondSoft/BeWo

This commit is contained in:
2025-08-11 12:18:29 +02:00
34 changed files with 1623 additions and 433 deletions

View File

@@ -675,6 +675,7 @@
<Content Include="Views\DevTools\DevToolsSettingsPartial.cshtml" />
<Content Include="Views\DevTools\DevToolsUserRightsPartial.cshtml" />
<Content Include="Views\DevTools\DevToolsDataGenerationPartial.cshtml" />
<Content Include="Views\Main\RestoreServiceRecordInputsPartial.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="packages.config" />

View File

@@ -1308,17 +1308,18 @@ namespace BeWoPlanerMobil.Controllers
appointmentPrototype = MapperFactory.SchedulerAppointmentDCSchedulerAppointment.MapToNewDC(app);
}
var marker = "on" == collection[FormCollectionConstants.MarkerKey];
string doku1;
var d1 = collection[FormCollectionConstants.Dokumentation1Key];
var d2 = collection[FormCollectionConstants.Dokumentation2Key];
var d3 = collection[FormCollectionConstants.Dokumentation3Key];
var d4 = collection[FormCollectionConstants.Dokumentation4Key];
var d5 = collection[FormCollectionConstants.Dokumentation5Key];
var d6 = collection[FormCollectionConstants.Dokumentation6Key];
if(Model.Dokutypes != null && Model.Dokutypes.Length > 0)
{
doku1 = collection[FormCollectionConstants.Dokumentation1Key];
}
else
{
doku1 = collection[FormCollectionConstants.Dokumentation6Key];
}
var marker = "on" == collection[FormCollectionConstants.MarkerKey];
var doku1 = Model.Dokutypes?.Length > 0 ?
collection[FormCollectionConstants.Dokumentation1Key] :
collection[FormCollectionConstants.Dokumentation6Key];
decimal? betrag = null;
var betragAsString = collection[FormCollectionConstants.BetragKey]?.Replace('.', ',');
@@ -5105,6 +5106,44 @@ namespace BeWoPlanerMobil.Controllers
return LeerzeichenFuerGetMethoden;
}
[Authorize]
[HttpPost]
public ActionResult RestoreServiceRecordForm(FormCollection formCollection)
{
// Neuen ServiceRecord bauen, als wenn der Nutzer das normal gemacht hätte?
// Geht das auch bei Gruppen- und Mehrfachbuchungen? Ja, siehe Bearbeiten!
var dateInputValue = formCollection[FormCollectionConstants.DateKey];
var startTimeInputValue = formCollection[FormCollectionConstants.StartKey];
var endTimeInputValue = formCollection[FormCollectionConstants.EndKey];
var endDateInputValue = formCollection[FormCollectionConstants.EndDateKey];
var doku1 = formCollection[FormCollectionConstants.Dokumentation1Key];
var doku2 = formCollection[FormCollectionConstants.Dokumentation2Key];
var doku3 = formCollection[FormCollectionConstants.Dokumentation3Key];
var doku4 = formCollection[FormCollectionConstants.Dokumentation4Key];
var doku5 = formCollection[FormCollectionConstants.Dokumentation5Key];
var doku6 = formCollection[FormCollectionConstants.Dokumentation6Key];
var distanceInputValue = formCollection[FormCollectionConstants.DistanceKey];
var markerInputValue = formCollection[FormCollectionConstants.MarkerKey];
var serviceDescriptionOidInputValue = formCollection[FormCollectionConstants.ServiceDescriptionKey];
var durationInputValue = formCollection[FormCollectionConstants.DurationKey];
var betragInputValue = formCollection[FormCollectionConstants.BetragKey];
var selectedGroupBookingCb2ScOidsInputValue = formCollection[FormCollectionConstants.GroupBookingSelectedCb2ScOidsKey];
var selectedMultiBookingCb2ScOidsInputValue = formCollection[FormCollectionConstants.MultiBookingSelectedCb2ScOidsKey];
var selectedSingleBookingEmployeeOidInputValue = formCollection[FormCollectionConstants.SingleBookingEmployeeOidKey];
var selectedGroupBookingEmployeeOidsInputValue = formCollection[FormCollectionConstants.GroupBookingSelectedEmployeeOidsKey];
var selectedMultiBookingEmployeeOidsInputValue = formCollection[FormCollectionConstants.MultiBookingSelectedEmployeeOidsKey];
var selectedGoalOidsInputValue = formCollection[FormCollectionConstants.SelectedGoalOids];
DateTime.TryParse(dateInputValue, out var date);
DateTime.TryParse(endDateInputValue, out var endDate);
decimal.TryParse(distanceInputValue, out var distance);
TempData[TempDataConstants.AfterRestoreKey] = true;
return View("Main", Model);
}
}
public class ServiceRecord2Monatsunterschrift

View File

@@ -527,7 +527,7 @@ namespace BeWoPlanerMobil.Controllers
var rawSchedulerDate = formCollection[FormCollectionConstants.AppointmentSchedulerDateKey];
var schedulerDate = DateTime.ParseExact(rawSchedulerDate, "dd.MM.yyyy", null);
var schedulerDate = DateTime.ParseExact(rawSchedulerDate, "yyyy-MM-dd", null);
Model.SelectedDate = schedulerDate;

View File

@@ -841,6 +841,19 @@ namespace BeWoPlanerMobil.Models
return SelectedServiceDescription;
}
public BookingMode CurrentBookingMode
{
get
{
if(IsInGroupBookingMode)
{
return BookingMode.GroupBookingMode;
}
return IsInMultiBookingMode ? BookingMode.MultiBookingMode : BookingMode.SingleBookingMode;
}
}
}

View File

@@ -11,7 +11,7 @@ function updateCanvasSize(canvasJQueryElement) {
const rowWidth = canvasJQueryElement.parent().parent().innerWidth();
const sourceCanvas = document.getElementById(canvasJQueryElement.attr("id"));
const sourceCanvas = document.getElementById(canvasJQueryElement.prop("id"));
const canvasWidth = sourceCanvas.scrollWidth;
@@ -22,13 +22,13 @@ function updateCanvasSize(canvasJQueryElement) {
let isMinDifferenceMet = false;
if (parsedCanvasWidth > parsedNewWidth) {
if(parsedCanvasWidth > parsedNewWidth) {
isMinDifferenceMet = parsedCanvasWidth - parsedNewWidth > 4;
} else {
isMinDifferenceMet = parsedNewWidth - parsedCanvasWidth > 4;
}
if (isMinDifferenceMet) {
if(isMinDifferenceMet) {
var trimmedCanvas = trimCanvas(cloneCanvas(sourceCanvas));
var canvasContext = sourceCanvas.getContext("2d", { willReadFrequently: true });
@@ -39,10 +39,10 @@ function updateCanvasSize(canvasJQueryElement) {
return;
}
var img = new Image;
var img = new Image();
img.onload = function () {
if (trimmedCanvas.width > parsedNewWidth) {
if(trimmedCanvas.width > parsedNewWidth) {
const factor = trimmedCanvas.height / trimmedCanvas.width;
const newHeight = parsedNewWidth * factor;

View File

@@ -1,16 +1,22 @@
function selectSupportConcept(cb2ScOid) {
showSpinner();
$("#CostBearer2SupportConceptOid").val(cb2ScOid);
$("#sb-cb2ScRelOid").val(cb2ScOid);
window.saveItemValueLocally(document.getElementById("sb-cb2ScRelOid"));
$("#selectSupportConceptForm").submit();
}
function setSelectedEmployee() {
const employeeOid = parseInt($("#employeesDropDown").find(":selected").val());
if (isNaN(employeeOid)) {
if(isNaN(employeeOid)) {
return;
}
$("#sb-employee-input").val(employeeOid);
window.saveItemValueLocally($("#sb-employee-input").val());
$.get(window.getSetServiceRecordEmployeeUrl(), { employeeOid: employeeOid });
}
@@ -67,9 +73,9 @@ function toggleGroupBookingForm() {
function changeMultiBookingFormEnableState(enableState) {
$(
"#multi-booking-employees-button, " +
"#category-select, " +
"#leistung-select, " +
"#mb-employees-button, " +
"#mb-category-select, " +
"#mb-leistung-select, " +
"#mb-start-date-input, " +
"#mb-end-date-input, " +
"#mb-start-time-input, " +
@@ -82,15 +88,15 @@ function changeMultiBookingFormEnableState(enableState) {
"#mb-betrag," +
"#mb-textbausteine-btn, " +
"#mb-hours-minutes-dropdown-btn, " +
"#mb-marker-cb, " +
".bewo-restore-btn").prop("disabled", enableState);
"#mb-marker-cb"
).prop("disabled", enableState);
}
function changeGroupBookingFormEnableState(enableState) {
$(
"#employees-button, " +
"#category-select, " +
"#leistung-select, " +
"#gb-category-select, " +
"#gb-leistung-select, " +
"#gb-start-date-input, " +
"#gb-end-date-input, " +
"#gb-start-time-input, " +
@@ -103,16 +109,15 @@ function changeGroupBookingFormEnableState(enableState) {
"#gb-textbausteine-btn, " +
"#gb-hours-minutes-dropdown-btn, " +
"#gb-marker-cb, " +
"#gb-betrag, " +
".bewo-restore-btn"
"#gb-betrag"
).prop("disabled", enableState);
}
function changeSingleBookingFormEnableState(enableState) {
$(
"#employeesDropDown, " +
"#category-select, " +
"#leistung-select, " +
"#sb-category-select, " +
"#sb-leistung-select, " +
"#sb-start-date-input, " +
"#sb-end-date-input, " +
"#sb-start-time-input, " +
@@ -128,8 +133,7 @@ function changeSingleBookingFormEnableState(enableState) {
"#statistics-button, " +
"#timeFrameSelect, " +
"#sb-marker-cb, " +
"#sb-betrag, " +
".bewo-restore-btn"
"#sb-betrag"
).prop("disabled", enableState);
}
@@ -213,7 +217,7 @@ function validateForm(form, prefix) {
if(isNoticeMandatory) {
if(numberOfNoticeTextareas === 0) {
var doku = $(`#${prefix}-dokufeld-textarea`).val();
var doku = $(`#${prefix}-doku-textarea`).val();
if(doku === undefined || doku === null) {
doku = "";
@@ -291,7 +295,9 @@ function validateForm(form, prefix) {
$("#srv-service-description").val($(`#${prefix}-leistung-select`).find(":selected").val());
$("#srv-duration").val($(`#${prefix}-duration-input`).val());
$("#srv-betrag").val($(`#${prefix}-betrag`).val());
// ToDo: Hier lokal speichern?
showSpinner();
$("#service-record-validation-form").submit();
}
@@ -301,7 +307,7 @@ function getDokuTexte(prefix) {
const noticeList = [null, null, null, null, null];
try {
const hasMultipleDokufelder = $(`#${prefix}-dokufeld-textarea`).length === 0;
const hasMultipleDokufelder = $(`#${prefix}-doku-textarea`).length === 0;
let dokufeldCounter = 0;
@@ -315,7 +321,7 @@ function getDokuTexte(prefix) {
}
}
} else {
noticeList[0] = $(`#${prefix}-dokufeld-textarea`).val();
noticeList[0] = $(`#${prefix}-doku-textarea`).val();
dokufeldCounter = 1;
}
@@ -351,8 +357,6 @@ function hideGoalRatingPopup() {
}
}
function checkChildNodes(parentOid) {
const rootElement = $(`#c-${parentOid}`);
const checkboxes = rootElement.find("input");
@@ -369,10 +373,6 @@ function checkChildNodes(parentOid) {
});
}
function validateDistanceInput() {
checkNumberInput("distance");
}
@@ -434,7 +434,6 @@ function validateStartAndEndInputs(startDateInput, startTimeInput, endDateInput,
return [combineDateAndTime(startDate, startTime), combineDateAndTime(endDate, endTime)];
}
function supportConceptSearchOnChange() {
try {
var text = $("#support-concept-search-input").val().toLowerCase();

View File

@@ -32,6 +32,15 @@
public static string ServiceRecordSignatureBlobKey => "service-record-signature-blob";
public static string ServiceRecordSignatureDateKey => "service-record-signature-date";
public static string ServiceRecordSignatureRecordOidKey => "service-record-signature-record-oid";
public static string GroupBookingSelectedCb2ScOidsKey => "service-record-group-booking-cb2sc-oids";
public static string GroupBookingSelectedEmployeeOidsKey => "service-record-group-booking-employee-oids";
public static string MultiBookingSelectedCb2ScOidsKey => "service-record-multi-booking-cb2sc-oids";
public static string MultiBookingSelectedEmployeeOidsKey => "service-record-multi-booking-employee-oids";
public static string SingleBookingEmployeeOidKey => "service-record-single-booking-employee-oid";
public static string SelectedGoalOids => "service-record-selected-goal-oids";
public static string GroupBookingSelectedGroupOidsKey => "service-record-group-booking-employee-oids";
public static string MultiBookingSelectedGroupOidsKey => "service-record-multi-booking-employee-oids";
// Kalender
public static string AppointmentStartDateKey => "StartDate";
@@ -84,5 +93,7 @@
public static string InfoMessageKey => "InfoMessage";
public static string ReportMessageKey => "ReportMessage";
public static string AppointmentOidKey => "AppointmentOid";
public static string AfterRestoreKey => "AfterRestore";
public static string SaveSupportConceptDependenciesKey => "SaveSupportConceptDependencies";
}
}

View File

@@ -1,4 +1,5 @@
@using BeWoPlanerMobil.Util
@using BS.Shared
@model BeWoPlanerMobil.Models.MainModel
@{
@@ -10,6 +11,26 @@
</script>
</text>
}
var selectedServiceDescription = Model.GetSelectedOrFirstServiceDescription();
var selectedCategory = selectedServiceDescription?.Category;
var bookingMode = Model.CurrentBookingMode;
string prefix;
switch(bookingMode)
{
case BookingMode.GroupBookingMode:
prefix = "gb";
break;
case BookingMode.MultiBookingMode:
prefix = "mb";
break;
default:
prefix = "sb";
break;
}
}
<script type="text/javascript">
@@ -18,7 +39,7 @@
}
function setSelectedServiceCategory() {
const selectedCategoryOid = $("#category-select").find(":selected").val();
const selectedCategoryOid = $("#@prefix-category-select").find(":selected").val();
$("#category-to-description-container").load("@Url.Action("SetSelectedServiceCategory")", {categoryOidStr: selectedCategoryOid}, function() {
$("#tree").load("@Url.Action("LoadUpToDateTextModules")");
@@ -26,14 +47,17 @@
}
$(document).ready(function() {
window.calcPrependWidth();
window.calcPrependWidth();
window.addEventListener("load", function() {
$("#@prefix-category-select, #@prefix-leistung-select").on("change", function() {
saveItemValueLocally(this);
});
});
});
</script>
@{
var selectedServiceDescription = Model.GetSelectedOrFirstServiceDescription();
var selectedCategory = selectedServiceDescription?.Category;
}
<!-- Kategorie -->
<div class="form-row">
@@ -45,17 +69,17 @@
Kategorie
</div>
</div>
<select id="category-select" class="custom-select" onchange="setSelectedServiceCategory()">
<select id="@prefix-category-select" class="custom-select" onchange="setSelectedServiceCategory()">
@foreach(var serviceCategory2ServiceDescriptions in Model.Categories2Descriptions)
{
var category = serviceCategory2ServiceDescriptions.Key;
{
var category = serviceCategory2ServiceDescriptions.Key;
if(category is null)
{
continue;
}
if(category is null)
{
continue;
}
var selected = selectedCategory != null && selectedCategory.Equals(category) ? " selected" : string.Empty;
var selected = selectedCategory != null && selectedCategory.Equals(category) ? " selected" : string.Empty;
<option value="@category.ServiceCategoryOid"@selected>@category.Name</option>
}
@@ -75,7 +99,7 @@
Leistung
</div>
</div>
<select class="custom-select" id="leistung-select" name="ServiceDescription" onchange="setServiceDescription('leistung-select')">
<select class="custom-select" id="@prefix-leistung-select" name="ServiceDescription" onchange="setServiceDescription('@prefix-leistung-select')">
@if(selectedCategory != null && Model.Categories2Descriptions.ContainsKey(selectedCategory))
{
foreach(var serviceDescription in Model.Categories2Descriptions[selectedCategory])

View File

@@ -32,18 +32,18 @@
$(".goal-card, .goal-text").hide();
var goalLabels = $(".goal-name-label");
const goalLabels = $(".goal-name-label");
$.each(goalLabels, function (index, item) {
var label = $(item);
const label = $(item);
var goalText = $.trim(label.text());
const goalText = $.trim(label.text());
if (false === goalText.toLowerCase().includes(text)) {
return;
}
var parents = label.parents(".goal-card, .goal-text");
const parents = label.parents(".goal-card, .goal-text");
parents.show();
});
} catch(error) {
@@ -55,9 +55,9 @@
try {
$("#goal-search-input").val("");
var entries = $(".goal-text");
var treeCard = $(".goal-card");
var collapsable = treeCard.find(".collapse");
const entries = $(".goal-text");
const treeCard = $(".goal-card");
const collapsable = treeCard.find(".collapse");
entries.show();
treeCard.show();
@@ -70,14 +70,14 @@
function getCheckedGoals() {
try {
var rootElement = $("#goals-tree");
var checkboxes = rootElement.find("input");
const rootElement = $("#goals-tree");
const checkboxes = rootElement.find("input");
var selectedGoals = "";
$.each(checkboxes, function(index, checkbox) {
var box = $(checkbox);
var id = box.attr("id").split("-")[2];
const box = $(checkbox);
const id = box.attr("id").split("-")[2];
if(box.prop("checked") === true && !id.includes("goal")) {
selectedGoals += id + ";";
@@ -92,9 +92,9 @@
function updateSelectedGoals() {
try {
var selectedGoals = getCheckedGoals();
const selectedGoals = getCheckedGoals();
$.get("@Url.Action("UpdateGoals")", {pGoalOids: selectedGoals}, function (numberOfSelectedGoals) {
$.get("@Url.Action("UpdateGoals")", {pGoalOids: selectedGoals}, function (numberOfSelectedGoals) {
$("#goals-button").html(`Ziele <span class='badge badge-light text-primary'>${numberOfSelectedGoals}</span>`);
});
} catch(error) {
@@ -128,11 +128,6 @@
}
</script>
@*
ToDo für Montag, 15.07.2024: Bis 30 Ziele/Maßnahmen standardmäßig alles ausklappen, ansonsten einklappen
ToDo: Alles/Nichts auswählen implementieren
*@
@helper BuildGoalTreeBranch(GoalTreeItem goalTreeItem)
{
var collapseClass = Model.GoalTree.Count <= 30 ? "collapse show" : "collapse";

View File

@@ -19,16 +19,18 @@
var selectedGroups = [];
var selectedSupportConcepts = [];
$("#group-booking-supportconcepts input:checked").each(function () {
$("#gb-supportconcepts input:checked").each(function () {
selectedSupportConcepts.push($(this).attr("value"));
});
$("#group-booking-groups input:checked").each(function () {
$("#gb-groups input:checked").each(function () {
selectedGroups.push($(this).attr("value"));
});
$("#group-booking-sc-cb-rel-tab-content").load("@Url.Action("AddScCbRelsToGroupBooking")", {relOids: selectedSupportConcepts, groupOids: selectedGroups}, function() {
$("#groupbooking-selection-container").load("@Url.Action("ReloadGroupBookingForm")", function () {
updateLocallyStoredGroupBookingCb2ScRelOids();
$("#gb-sc-cb-rel-tab-content").load("@Url.Action("AddScCbRelsToGroupBooking")", {relOids: selectedSupportConcepts, groupOids: selectedGroups}, function() {
$("#gb-selection-container").load("@Url.Action("ReloadGroupBookingForm")", function () {
toggleGroupBookingForm();
$("#goals-tree").load("@Url.Action("ReloadGoals")", function() {
@@ -39,9 +41,11 @@
}
function removeSupportConceptCostBearerRel(relOid) {
$(`#cb2sc-checkbox-${relOid}`).prop("checked", false);
$(`#gb-cb2sc-checkbox-${relOid}`).prop("checked", false);
$("#groupbooking-selection-container").load("@Url.Action("RemoveSupportConceptCostbearerRel")", {relOid: relOid}
updateLocallyStoredGroupBookingCb2ScRelOids();
$("#gb-selection-container").load("@Url.Action("RemoveSupportConceptCostbearerRel")", {relOid: relOid}
, function () {
$("#goals-tree").load("@Url.Action("ReloadGoals")"
, function () {
@@ -50,7 +54,28 @@
$("#tree").load("@Url.Action("LoadUpToDateTextModules")");
});
});
}
}
function updateLocallyStoredGroupBookingCb2ScRelOids() {
let cb2ScOidString = "";
const storage = window.getBeWoStorage();
$("#gb-supportconcepts input:checked").each(function () {
cb2ScOidString += `${$(this).attr("value")},`;
});
storage.updateGroupBookingSelectedCb2ScRelOids(cb2ScOidString.slice(0, -1));
}
function updateLocallyStoredGroupOids() {
let groupOidString = "";
const storage = window.getBeWoStorage();
$("#gb-supportconcepts input:checked").each(function () {
groupOidString += `${$(this).attr("value")},`;
});
storage.updateGroupBookingSelectedGroupOids(groupOidString.slice(0, -1));
}
</script>
@if(Model != null)
@@ -85,7 +110,7 @@
</div>
</div>
@* Hilfepläne und Mitarbeiter *@
<div id="groupbooking-selection-container">
<div id="gb-selection-container">
@Html.Partial("GroupBookingSelectionPartial", Model)
</div>
@@ -301,26 +326,27 @@
</div>
}
<div class="w-100 mt-2">
<button type="button" class="btn btn-primary float-right ml-1" id="create-button" onclick="submitGroupBookingForm()">@submitButtonText</button>
@if(Model.IsInTransferMode)
{
using(Html.BeginForm("ResetTransferMode", "Main", FormMethod.Post))
{
<button type="submit" id="reset-button" class="btn btn-primary float-right" onclick="showSpinner()">Abbrechen</button>
}
}
else
{
using(Html.BeginForm("ResetEditingMode", "Main", FormMethod.Post))
{
<button type="submit" id="reset-button" class="btn btn-primary float-right" onclick="showSpinner()">Abbrechen</button>
}
}
<div class="w-100 mt-2">
<button type="button" class="btn btn-primary float-right ml-1" id="create-button" onclick="submitGroupBookingForm()">@submitButtonText</button>
@*<button type="button" class="btn btn-bewo-dev bewo-restore-btn" onclick="window.restoreAllFields()">
<i class="fas fa-recycle"></i>
</button>*@
</div>
@if(Model.IsInTransferMode)
{
using(Html.BeginForm("ResetTransferMode", "Main", FormMethod.Post))
{
<button type="submit" id="reset-button" class="btn btn-primary float-right" onclick="showSpinner()">Abbrechen</button>
}
}
else
{
using(Html.BeginForm("ResetEditingMode", "Main", FormMethod.Post))
{
<button type="submit" id="reset-button" class="btn btn-primary float-right" onclick="showSpinner()">Abbrechen</button>
}
}
@if(Html.IsInDebugMode())
{
@Html.Partial("RestoreServiceRecordInputsPartial", Model)
}
</div>
}

View File

@@ -53,7 +53,7 @@
var oidString = "";
$("#group-booking-employee-selection-popup input:checked").each(function() {
$("#gb-employee-selection-popup input:checked").each(function() {
const oid = $(this).val();
selectedEmployees.push(oid);
@@ -67,6 +67,9 @@
}
}
const storage = window.getBeWoStorage();
storage.updateGroupBookingSelectedEmployeeOids(oidString);
$.get("@Url.Action("AddEmployeesToGroupBooking")", { pEmployeeOids: oidString }).done(function(numberOfSelectedEmployees) {
$("#selected-employees-count-badge").text(numberOfSelectedEmployees);
@@ -101,10 +104,10 @@
</div>
<div class="modal-body">
<nav class="nav nav-pills nav-fill">
<a class="nav-item nav-link active" href="#group-booking-supportconcepts" data-toggle="tab" role="tab">Hilfepläne</a>
<a class="nav-item nav-link" href="#group-booking-groups" data-toggle="tab" role="tab">Gruppen</a>
<a class="nav-item nav-link active" href="#gb-supportconcepts" data-toggle="tab" role="tab">Hilfepläne</a>
<a class="nav-item nav-link" href="#gb-groups" data-toggle="tab" role="tab">Gruppen</a>
</nav>
<div class="tab-content" id="group-booking-sc-cb-rel-tab-content">
<div class="tab-content" id="gb-sc-cb-rel-tab-content">
@Html.Partial("GroupBookingScCbRelList", Model)
</div>
</div>
@@ -113,7 +116,7 @@
</div>
@* ----- (Gruppenbuchung) Mitarbeiterauswahl Popup ----- *@
<div class="modal" tabindex="-1" role="dialog" id="group-booking-employee-selection-popup">
<div class="modal" tabindex="-1" role="dialog" id="gb-employee-selection-popup">
<div class="modal-dialog modal-dialog-scrollable" role="document">
<div class="modal-content">
<div class="modal-header">
@@ -131,16 +134,17 @@
</button>
</div>
</div>
<div id="gb-employee-selection-list">
@foreach(var employee in Model.EmployeesForGroupAndMultiBooking)
{
var checkedValue = Model.GroupBookingSelectedEmployees.Contains(employee) ? "checked=\"checked\"" : string.Empty;
@foreach(var employee in Model.EmployeesForGroupAndMultiBooking)
{
var checkedValue = Model.GroupBookingSelectedEmployees.Contains(employee) ? "checked=\"checked\"" : string.Empty;
<div class="custom-control custom-checkbox employee-text">
<input type="checkbox" @checkedValue class="custom-control-input" id="group-employee-@employee.EmployeeOid" onchange="addEmployeeToGroupBooking()" value="@employee.EmployeeOid" />
<label for="group-employee-@employee.EmployeeOid" class="custom-control-label employee-name-label">@employee.DetailDescription</label>
</div>
}
<div class="custom-control custom-checkbox employee-text">
<input type="checkbox" @checkedValue class="custom-control-input" id="group-employee-@employee.EmployeeOid" onchange="addEmployeeToGroupBooking()" value="@employee.EmployeeOid" />
<label for="group-employee-@employee.EmployeeOid" class="custom-control-label employee-name-label">@employee.DetailDescription</label>
</div>
}
</div>
</div>
</div>
</div>

View File

@@ -12,7 +12,7 @@
}
}
<div class="tab-pane show active" role="tabpanel" id="group-booking-supportconcepts">
<div class="tab-pane show active" role="tabpanel" id="gb-supportconcepts">
<ul class="list-group">
@foreach(var cb2Sc in Model.SupportConceptListObjectsForGroupBooking)
{
@@ -20,16 +20,14 @@
@{
var timeSpanColorClass2 = cb2Sc.IsAboutToExpire ? "text-bewo-is-about-to-expire" : cb2Sc.ExpiresInThreeMonthsOrLess ? "text-bewo-expires-in-three-months" : "text-dark";
var checkedValue = Model.GroupBookingSelectedCostBearerSupportConceptOids.Any(a => a == cb2Sc.CostBearer2SupportConceptOid);
}
<div class="custom-control custom-checkbox custom-control-inline">
<input type="checkbox"
@{ if(checkedValue) { @Html.Raw("checked=\"checked\"") } }
class="custom-control-input cb2sc-input" id="cb2sc-checkbox-@cb2Sc.CostBearer2SupportConceptOid" onchange="addScCbRelsToGroupBooking()" name="cb2sc-checkbox-@cb2Sc.CostBearer2SupportConceptOid" value="@cb2Sc.CostBearer2SupportConceptOid">
<label for="cb2sc-checkbox-@cb2Sc.CostBearer2SupportConceptOid" class="custom-control-label">
class="custom-control-input cb2sc-input" id="gb-cb2sc-checkbox-@cb2Sc.CostBearer2SupportConceptOid" onchange="addScCbRelsToGroupBooking()" name="cb2sc-checkbox-@cb2Sc.CostBearer2SupportConceptOid" value="@cb2Sc.CostBearer2SupportConceptOid">
<label for="gb-cb2sc-checkbox-@cb2Sc.CostBearer2SupportConceptOid" class="custom-control-label">
<span class="justify-content-between mb-1 text-dark text-left">
@cb2Sc.NameAndDateOfBirth
</span>
@@ -43,7 +41,7 @@
}
</ul>
</div>
<div class="tab-pane show" role="tabpanel" id="group-booking-groups">
<div class="tab-pane show" role="tabpanel" id="gb-groups">
<ul class="list-group">
@foreach(var group in Model.GroupOfPeopleListItems)
{

View File

@@ -57,7 +57,7 @@
<div class="form-row">
<div class="col-md">
<div class="form-group my-0">
<button type="button" class="btn btn-bewo-employee btn-block mt-2" data-toggle="modal" data-target="#group-booking-employee-selection-popup" id="employees-button">
<button type="button" class="btn btn-bewo-employee btn-block mt-2" data-toggle="modal" data-target="#gb-employee-selection-popup" id="employees-button">
Mitarbeiter hinzufügen <span class="badge badge-light text-primary" id="selected-employees-count-badge">@Model.GroupBookingSelectedEmployees.Count</span>
</button>
</div>

View File

@@ -133,7 +133,7 @@
</text>
}
const supportConceptOid = parseInt($("#CostBearer2SupportConceptOid").val());
const supportConceptOid = parseInt($("#sb-cb2ScRelOid").val());
const isSupportConceptSelected = supportConceptOid !== -1;
@@ -196,9 +196,18 @@
@if(TempData[TempDataConstants.AppointmentOidKey] is long && false == Model.IsInGroupBookingMode && false == Model.IsInMultiBookingMode)
{
<text>
loadServiceRecords();
loadServiceRecords();
</text>
}
// ToDo: Falls ein Hilfeplan im Einzelbuchungsformular ausgewählt ist, auch die davon abhängigen Dinge lokal speichern
if("@Model.CurrentBookingMode".toLowerCase() === "0") {
alert("EINZELBUCHUNGSMODUS");
}
} catch(error) {
window.showErrorPopup(error);
}

View File

@@ -18,15 +18,15 @@
var selectedGroups = [];
var selectedSupportConcepts = [];
$("#multi-booking-supportconcepts input:checked").each(function () {
$("#mb-supportconcepts input:checked").each(function () {
selectedSupportConcepts.push($(this).attr("value"));
});
$("#multi-booking-groups input:checked").each(function () {
$("#mb-groups input:checked").each(function () {
selectedGroups.push($(this).attr("value"));
});
$("#multi-booking-sc-cb-rel-tab-content").load("@Url.Action("AddScCbRelsToMultiBooking")", {relOids: selectedSupportConcepts, groupOids: selectedGroups}, function() {
$("#mb-sc-cb-rel-tab-content").load("@Url.Action("AddScCbRelsToMultiBooking")", {relOids: selectedSupportConcepts, groupOids: selectedGroups}, function() {
$("#multibooking-selection-container").load("@Url.Action("ReloadMultiBookingForm")", function () {
changeMultiBookingFormEnableState($(".mb-cb2sc-input:checkbox:checked").length > 0 ? false : true);
@@ -49,6 +49,28 @@
);
}
);
}
function updateLocallyStoredMultiBookingCb2ScRelOids() {
let cb2ScOidString = "";
const storage = window.getBeWoStorage();
$("#mb-supportconcepts input:checked").each(function () {
cb2ScOidString += `${$(this).attr("value")},`;
});
storage.updateGroupBookingSelectedCb2ScRelOids(cb2ScOidString.slice(0, -1));
}
function updateLocallyStoredMultiBookingGroupOids() {
let groupOidString = "";
const storage = window.getBeWoStorage();
$("#mb-supportconcepts input:checked").each(function () {
groupOidString += `${$(this).attr("value")},`;
});
storage.updateGroupBookingSelectedGroupOids(groupOidString.slice(0, -1));
}
</script>
@@ -284,16 +306,17 @@
</div>
}
<div class="w-100 mt-2">
<button type="button" class="btn btn-primary float-right ml-1" id="mb-create-btn" onclick="window.submitMultiBookingForm()">Anlegen</button>
<div class="w-100 mt-2">
<button type="button" class="btn btn-primary float-right ml-1" id="mb-create-btn" onclick="window.submitMultiBookingForm()">Anlegen</button>
@using(Html.BeginForm("ResetMultiBookingForm", "Main", FormMethod.Post))
{
<button type="submit" id="mb-reset-btn" class="btn btn-primary float-right" onclick="showSpinner()">Abbrechen</button>
}
@*<button type="button" class="btn btn-bewo-dev bewo-restore-btn" onclick="window.restoreAllFields()">
<i class="fas fa-recycle"></i>
</button>*@
</div>
@using(Html.BeginForm("ResetMultiBookingForm", "Main", FormMethod.Post))
{
<button type="submit" id="mb-reset-btn" class="btn btn-primary float-right" onclick="showSpinner()">Abbrechen</button>
}
@if(Html.IsInDebugMode())
{
@Html.Partial("RestoreServiceRecordInputsPartial", Model)
}
</div>
}

View File

@@ -44,7 +44,7 @@
let oidString = "";
$("#multi-booking-employee-selection-popup input:checked").each(function() {
$("#mb-employee-selection-popup input:checked").each(function() {
selectedEmployees.push($(this).val());
});
@@ -56,10 +56,13 @@
}
}
$.get("@Url.Action("AddEmployeesToMultiBooking")", { pEmployeeOids: oidString }).done(function(numberOfSelectedEmployees) {
$("#multi-booking-selected-employees-count-badge").text(numberOfSelectedEmployees);
const storage = window.getBeWoStorage();
storage.updateMultiBookingSelectedEmployeeOids(oidString);
$("#multi-booking-create-button").prop("disabled", numberOfSelectedEmployees === "0" ? true : false);
$.get("@Url.Action("AddEmployeesToMultiBooking")", { pEmployeeOids: oidString }).done(function(numberOfSelectedEmployees) {
$("#mb-selected-employees-count-badge").text(numberOfSelectedEmployees);
$("#mb-create-btn").prop("disabled", numberOfSelectedEmployees === "0" ? true : false);
});
}
@@ -112,7 +115,7 @@
</div>
@* (Mehrfachbuchung) Hilfeplan- und Gruppenauswahl Popup *@
<div class="modal" data-backdrop="static" tabindex="-1" role="dialog" id="multi-booking-popup">
<div class="modal" data-backdrop="static" tabindex="-1" role="dialog" id="mb-sc-cb-rel-popup">
<div class="modal-dialog modal-dialog-scrollable" role="document">
<div class="modal-content">
<div class="modal-header">
@@ -123,10 +126,10 @@
</div>
<div class="modal-body">
<nav class="nav nav-pills nav-fill">
<a class="nav-item nav-link active" href="#multi-booking-supportconcepts" data-toggle="tab" role="tab">Hilfepläne</a>
<a class="nav-item nav-link" href="#multi-booking-groups" data-toggle="tab" role="tab">Gruppen</a>
<a class="nav-item nav-link active" href="#mb-supportconcepts" data-toggle="tab" role="tab">Hilfepläne</a>
<a class="nav-item nav-link" href="#mb-groups" data-toggle="tab" role="tab">Gruppen</a>
</nav>
<div class="tab-content" id="multi-booking-sc-cb-rel-tab-content">
<div class="tab-content" id="mb-sc-cb-rel-tab-content">
@Html.Partial("MultiBookingScCbRelList", Model)
</div>
</div>
@@ -135,7 +138,7 @@
</div>
@* (Mehrfachbuchung) Mitarbeiterauswahl Popup *@
<div class="modal" tabindex="-1" role="dialog" id="multi-booking-employee-selection-popup">
<div class="modal" tabindex="-1" role="dialog" id="mb-employee-selection-popup">
<div class="modal-dialog modal-dialog-scrollable" role="document">
<div class="modal-content">
<div class="modal-header">
@@ -153,16 +156,17 @@
</button>
</div>
</div>
<div id="mb-employee-selection-list">
@foreach(var employee in Model.EmployeesForGroupAndMultiBooking)
{
var checkedValue = Model.GroupBookingSelectedEmployees.Contains(employee) ? "checked=\"checked\"" : string.Empty;
@foreach(var employee in Model.EmployeesForGroupAndMultiBooking)
{
var checkedValue = Model.GroupBookingSelectedEmployees.Contains(employee) ? "checked=\"checked\"" : string.Empty;
<div class="custom-control custom-checkbox employee-text">
<input type="checkbox" @checkedValue class="custom-control-input" id="multi-employee-@employee.EmployeeOid" onchange="addEmployeeToMultiBooking()" value="@employee.EmployeeOid" />
<label for="multi-employee-@employee.EmployeeOid" class="custom-control-label employee-name-label">@employee.DetailDescription</label>
</div>
}
<div class="custom-control custom-checkbox employee-text">
<input type="checkbox" @checkedValue class="custom-control-input" id="mb-employee-@employee.EmployeeOid" onchange="addEmployeeToMultiBooking()" value="@employee.EmployeeOid" />
<label for="mb-employee-@employee.EmployeeOid" class="custom-control-label employee-name-label">@employee.DetailDescription</label>
</div>
}
</div>
</div>
</div>
</div>

View File

@@ -12,7 +12,7 @@
}
}
<div class="tab-pane show active" role="tabpanel" id="multi-booking-supportconcepts">
<div class="tab-pane show active" role="tabpanel" id="mb-supportconcepts">
<ul class="list-group">
@foreach(var cb2Sc in Model.SupportConceptListObjectsForGroupBooking)
{
@@ -41,7 +41,7 @@
}
</ul>
</div>
<div class="tab-pane show" role="tabpanel" id="multi-booking-groups">
<div class="tab-pane show" role="tabpanel" id="mb-groups">
<ul class="list-group">
@foreach(var group in Model.GroupOfPeopleListItems)
{

View File

@@ -15,7 +15,7 @@
@* (Mehrfachbuchung) Hilfeplanauswahl-Button *@
<div class="form-row">
<div class="col-md">
<button type="button" class="btn btn-bewo-task-red btn-block" data-toggle="modal" data-target="#multi-booking-popup" id="support-concepts-and-groups-button">Hilfepläne und Gruppen hinzufügen</button>
<button type="button" class="btn btn-bewo-task-red btn-block" data-toggle="modal" data-target="#mb-sc-cb-rel-popup" id="support-concepts-and-groups-button">Hilfepläne und Gruppen hinzufügen</button>
</div>
</div>
@@ -57,8 +57,8 @@
<div class="form-row">
<div class="col-md">
<div class="form-group my-0">
<button type="button" class="btn btn-bewo-employee btn-block mt-2" data-toggle="modal" data-target="#multi-booking-employee-selection-popup" id="multi-booking-employees-button">
Mitarbeiter hinzufügen <span class="badge badge-light text-primary" id="multi-booking-selected-employees-count-badge">@Model.GroupBookingSelectedEmployees.Count</span>
<button type="button" class="btn btn-bewo-employee btn-block mt-2" data-toggle="modal" data-target="#mb-employee-selection-popup" id="mb-employees-button">
Mitarbeiter hinzufügen <span class="badge badge-light text-primary" id="mb-selected-employees-count-badge">@Model.GroupBookingSelectedEmployees.Count</span>
</button>
</div>
</div>

View File

@@ -0,0 +1,390 @@
@using BeWoPlanerMobil.Service
@using BeWoPlanerMobil.Util
@model BeWoPlanerMobil.Models.MainModel
@*
ToDo: Bei Hilfeplan schauen, ob die Ziele/Maßnahmen, Kategorie/Leistung, Textbausteines korrekt sind.
*@
@if(TempData[TempDataConstants.AfterRestoreKey] is bool and true)
{
<text>
<script type="text/javascript">
</script>
</text>
}
<script type="text/javascript">
class LocalBeWoStorage {
id;
inputList;
groupBookingCb2ScRelOids;
multiBookingCb2ScRelOids;
groupBookingGroupOids;
multiBookingGroupOids;
groupBookingEmployeeOids;
multiBookingEmployeeOids;
constructor(id, inputList) {
this.id = id;
this.inputList = inputList;
this.groupBookingCb2ScRelOids = [];
this.groupBookingGroupOids = [];
this.groupBookingEmployeeOids = [];
this.multiBookingCb2ScRelOids = [];
this.multiBookingGroupOids = [];
this.multiBookingEmployeeOids = [];
}
clearInputList() {
if (this.inputList === null || this.inputList === undefined) {
this.inputList = [];
}
this.inputList.length = 0;
localStorage.setItem(this.id, JSON.stringify(this));
}
removeItemById(id) {
const newInputList = [];
for (let i = 0; i < this.inputList.length; i++) {
const input = this.inputList[i];
if (input.inputId !== id) {
newInputList.push(input);
}
}
this.inputList = newInputList;
localStorage.setItem(this.id, JSON.stringify(this));
}
removeItemByName(name) {
const newInputList = [];
for (let i = 0; i < this.inputList.length; i++) {
const input = this.inputList[i];
if (input.inputName !== name) {
newInputList.push(input);
}
}
this.inputList = newInputList;
localStorage.setItem(this.id, JSON.stringify(this));
}
addInputValue(inputId, inputName, inputType, inputValue, timeStamp) {
if (inputType === "radio") {
this.removeItemByName(inputName);
}
const obj = {
inputId: inputId,
inputName: inputName,
inputType: inputType,
inputValue: inputValue,
timeStamp: timeStamp
};
this.removeItemById(inputId);
this.inputList.push(obj);
localStorage.setItem(this.id, JSON.stringify(this));
}
getItemById(id) {
const item = this.inputList.find((element) => element.inputId === id);
return item;
}
getItemsByName(name) {
const result = [];
this.inputList.map((item) => {
if (item.inputName === name) {
result.push(item);
}
});
return result;
}
updateGroupBookingSelectedCb2ScRelOids(commaSeparatedOidString) {
if(commaSeparatedOidString === null || commaSeparatedOidString === undefined) {
commaSeparatedOidString = "";
}
const strArr = commaSeparatedOidString.split(",");
for(let i = 0; i < strArr.length; i++) {
if($.isNumeric(strArr[i])) {
this.groupBookingCb2ScRelOids.push(parseInt(strArr[i]));
}
}
localStorage.setItem(this.id, JSON.stringify(this));
}
updateGroupBookingSelectedGroupOids(commaSeparatedOidString) {
if(commaSeparatedOidString === null || commaSeparatedOidString === undefined) {
commaSeparatedOidString = "";
}
const strArr = commaSeparatedOidString.split(",");
for(let i = 0; i < strArr.length; i++) {
if($.isNumeric(strArr[i])) {
this.groupBookingGroupOids.push(parseInt(strArr[i]));
}
}
localStorage.setItem(this.id, JSON.stringify(this));
}
getGroupBookingSelectedCb2ScRelOids() {
return this.groupBookingCb2ScRelOids;
}
getGroupBookingSelectedGroupOids() {
return this.groupBookingGroupOids;
}
updateGroupBookingSelectedEmployeeOids(commaSeparatedOidString) {
if(commaSeparatedOidString === null || commaSeparatedOidString === undefined) {
commaSeparatedOidString = "";
}
const strArr = commaSeparatedOidString.split(",");
for(let i = 0; i < strArr.length; i++) {
if($.isNumeric(strArr[i])) {
this.groupBookingEmployeeOids.push(parseInt(strArr[i]));
}
}
localStorage.setItem(this.id, JSON.stringify(this));
}
getMultiBookingSelectedCb2ScRelOids() {
return this.multiBookingCb2ScRelOids;
}
getMultiBookingSelectedGroupOids() {
return this.multiBookingGroupOids;
}
updateMultiBookingSelectedCb2ScRelOids(commaSeparatedOidString) {
if(commaSeparatedOidString === null || commaSeparatedOidString === undefined) {
commaSeparatedOidString = "";
}
const strArr = commaSeparatedOidString.split(",");
for(let i = 0; i < strArr.length; i++) {
if($.isNumeric(strArr[i])) {
this.multiBookingCb2ScRelOids.push(parseInt(strArr[i]));
}
}
localStorage.setItem(this.id, JSON.stringify(this));
}
updateMultiBookingSelectedGroupOids(commaSeparatedOidString) {
if(commaSeparatedOidString === null || commaSeparatedOidString === undefined) {
commaSeparatedOidString = "";
}
const strArr = commaSeparatedOidString.split(",");
for(let i = 0; i < strArr.length; i++) {
if($.isNumeric(strArr[i])) {
this.multiBookingGroupOids.push(parseInt(strArr[i]));
}
}
localStorage.setItem(this.id, JSON.stringify(this));
}
updateMultiBookingSelectedEmployeeOids(commaSeparatedOidString) {
if(commaSeparatedOidString === null || commaSeparatedOidString === undefined) {
commaSeparatedOidString = "";
}
const strArr = commaSeparatedOidString.split(",");
for(let i = 0; i < strArr.length; i++) {
if($.isNumeric(strArr[i])) {
this.multiBookingEmployeeOids.push(parseInt(strArr[i]));
}
}
localStorage.setItem(this.id, JSON.stringify(this));
}
}
function getLocalStorageKey() {
return "@MobileSessionFacade.LocalStorageKey";
}
function getBeWoStorage() {
const localStorageKey = getLocalStorageKey();
const unparsedLocalStorageJson = localStorage.getItem(localStorageKey);
let beWoStorage = new LocalBeWoStorage(localStorageKey, []);
if(unparsedLocalStorageJson === null || unparsedLocalStorageJson === undefined || unparsedLocalStorageJson.length === 0) {
localStorage.setItem(localStorageKey, JSON.stringify(beWoStorage));
} else {
const parsedJson = JSON.parse(unparsedLocalStorageJson);
beWoStorage = new LocalBeWoStorage(localStorageKey, parsedJson.inputList);
}
return beWoStorage;
}
function clearLocalBeWoStorage() {
const beWoStorage = getBeWoStorage();
beWoStorage.clearInputList();
}
function getRestoreButtonState() {
const beWoStorage = getBeWoStorage();
return beWoStorage.inputList.length > 0;
}
window.addEventListener("load", function() {
$(".booking-form-container, #goals-tree").find("textarea, select, input").on("change", function() { saveItemValueLocally(this); });
$("#IsInGroupBookingMode, #IsInMultiBookingMode").on("change", function() { saveItemValueLocally(this); });
});
function restoreField(id) {
const beWoStorage = getBeWoStorage();
const inputObj = beWoStorage.getItemById(id);
if(inputObj === undefined || inputObj === null) {
return;
}
$(`#${id}`).val(inputObj.inputValue);
$(`#${id}`).trigger("change");
}
function saveItemValueLocally(htmlElement) {
const item = $(htmlElement);
const id = item.attr("id");
const type = item.prop("type");
const value = type === "checkbox" ? item.is(":checked").toString() : item.val();
if((value === null || value === undefined) || value.length === 0) {
return;
}
const name = item.prop("name");
const beWoStorage = getBeWoStorage();
beWoStorage.addInputValue(id, name, type, value, new Date());
toggleRestoreButton();
}
function restoreAllFields() {
const beWoStorage = getBeWoStorage();
$.each(beWoStorage.inputList, (index, item) => {
logInfo3(`Id: ${item.inputId}; Wert: ${item.inputValue};`);
});
// ToDo: die versteckten Felder ausfüllen und das Formular an den Server schicken, wo ein neues ServiceRecord-Objekt mithilfe des versteckten Formulars erzeugt wird.
$("#srr-gb-cb2sc-oids").val(beWoStorage.groupBookingCb2ScRelOids);
$("#srr-gb-group-oids").val(beWoStorage.groupBookingGroupOids);
$("#srr-gb-emp-oids").val(beWoStorage.groupBookingEmployeeOids);
$("#srr-mb-cb2sc-oids").val(beWoStorage.multiBookingCb2ScRelOids);
$("#srr-mb-group-oids").val(beWoStorage.multiBookingGroupOids);
$("#srr-mb-emp-oids").val(beWoStorage.multiBookingEmployeeOids);
$.each(beWoStorage.inputList, (index, item) => {
if (item.inputType === "checkbox") {
$(`#${item.inputId}`).prop("checked", item.inputValue);
} else {
$(`#${item.inputId}`).val(item.inputValue);
}
let inputId = item.inputId;
if(item.inputId.startsWith("sb-") || item.inputId.startsWith("gb-") || item.inputId.startsWith("mb-")) {
inputId = item.inputId.slice(3);
}
if(inputId === "doku-textarea") {
inputId += "-6";
}
logInfo(`Id: ${inputId}; Wert: ${item.inputValue};`);
//$(`#srr-${inputId}`).val(item.inputValue);
//$(`#${item.inputId}`).trigger("change");
});
$("#restore-service-record-form").submit();
}
$(window).ready(function() {
const sbDate = $("#sb-start-date-input").val();
const gbDate = $("#gb-start-date-input").val();
const mbDate = $("#mb-start-date-input").val();
logInfo(`Einzelbuchung: ${sbDate}\r\nGruppenbuchung: ${gbDate}\r\nMehrfachbuchung: ${mbDate}`);
});
</script>
@using(Html.BeginForm("RestoreServiceRecordForm", "Main", FormMethod.Post, new {id="restore-service-record-form"}))
{
<input type="hidden" id="srr-start-time-input" name="@FormCollectionConstants.DateKey" />
<input type="hidden" id="srr-end-time-input" name="@FormCollectionConstants.EndKey" />
<input type="hidden" id="srr-start-date-input" name="@FormCollectionConstants.StartKey" />
<input type="hidden" id="srr-end-date-input" name="@FormCollectionConstants.EndDateKey" />
<input type="hidden" id="srr-doku-textarea-1" name="@FormCollectionConstants.Dokumentation1Key" />
<input type="hidden" id="srr-doku-textarea-2" name="@FormCollectionConstants.Dokumentation2Key" />
<input type="hidden" id="srr-doku-textarea-3" name="@FormCollectionConstants.Dokumentation3Key" />
<input type="hidden" id="srr-doku-textarea-4" name="@FormCollectionConstants.Dokumentation4Key" />
<input type="hidden" id="srr-doku-textarea-5" name="@FormCollectionConstants.Dokumentation5Key" />
<input type="hidden" id="srr-doku-textarea-6" name="@FormCollectionConstants.Dokumentation6Key" />
<input type="hidden" id="srr-distance-input" name="@FormCollectionConstants.DistanceKey" />
<input type="hidden" id="srr-form-id" name="@FormCollectionConstants.FormIdKey" />
<input type="hidden" id="srr-marker-cb" name="@FormCollectionConstants.MarkerKey" />
<input type="hidden" id="srr-leistung-select" name="@FormCollectionConstants.ServiceDescriptionKey" />
<input type="hidden" id="srr-duration-input" name="@FormCollectionConstants.DurationKey" />
<input type="hidden" id="srr-betrag" name="@FormCollectionConstants.BetragKey" />
<input type="hidden" id="srr-sb-emp-oid" name="@FormCollectionConstants.SingleBookingEmployeeOidKey" />
<input type="hidden" id="srr-gb-cb2sc-oids" name="@FormCollectionConstants.GroupBookingSelectedCb2ScOidsKey" />
<input type="hidden" id="srr-gb-emp-oids" name="@FormCollectionConstants.GroupBookingSelectedEmployeeOidsKey" />
<input type="hidden" id="srr-gb-group-oids" name="@FormCollectionConstants.GroupBookingSelectedGroupOidsKey" />
<input type="hidden" id="srr-mb-cb2sc-oids" name="@FormCollectionConstants.MultiBookingSelectedCb2ScOidsKey" />
<input type="hidden" id="srr-mb-emp-oids" name="@FormCollectionConstants.MultiBookingSelectedEmployeeOidsKey" />
<input type="hidden" id="srr-mb-group-oids" name="@FormCollectionConstants.MultiBookingSelectedGroupOidsKey" />
<button type="button" class="btn btn-bewo-dev bewo-restore-btn" onclick="window.restoreAllFields()">
<i class="fas fa-recycle"></i>
</button>
}

View File

@@ -5,7 +5,7 @@
@model MainModel
@{
if(TempData[TempDataConstants.DoLogoutKey] is bool doLogout && doLogout)
if(TempData[TempDataConstants.DoLogoutKey] is bool and true)
{
<text>
<script type="text/javascript">
@@ -242,7 +242,7 @@
</div>
@* /Hilfeplanauswahlpopup *@
<input type="hidden" name="CostBearer2SupportConceptOid" id="CostBearer2SupportConceptOid" value="@Model.SelectedSupportConceptListObject.CostBearer2SupportConceptOid">
<input type="hidden" name="CostBearer2SupportConceptOid" id="sb-cb2ScRelOid" value="@Model.SelectedSupportConceptListObject.CostBearer2SupportConceptOid">
}
if(Model.IsCustomerAbsence)
@@ -264,6 +264,17 @@
<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.SelectedEmployeeOid.HasValue)
{
sbEmployeeInputValue = $"value=\"{Model.SelectedEmployeeOid.Value}\"";
}
}
<input type="hidden" id="sb-employee-input" @sbEmployeeInputValue />
</div>
</div>
</div>
@@ -468,8 +479,8 @@
@if(Model.NumberOfDokuTypes == 0)
{
<div class="form-group my-0">
<label for="sb-dokufeld-textarea">Dokumentation</label>
<textarea class="form-control" autocomplete="on" style="overflow: scroll;" name="Dokumentation6" id="sb-dokufeld-textarea">@Model.NoticeToEdit</textarea>
<label for="sb-doku-textarea">Dokumentation</label>
<textarea class="form-control" autocomplete="on" style="overflow: scroll;" name="Dokumentation6" id="sb-doku-textarea">@Model.NoticeToEdit</textarea>
</div>
}
else
@@ -521,12 +532,13 @@
}
else
{
<button type="button" class="btn btn-primary float-right" id="reset-button" onclick="window.restoreAllFields(); resetSingleBookingForm();">Abbrechen</button>
}
<button type="button" class="btn btn-primary float-right" id="reset-button" onclick="resetSingleBookingForm();">Abbrechen</button>
}
@*<button type="button" class="btn btn-bewo-dev bewo-restore-btn" onclick="window.restoreAllFields()">
<i class="fas fa-recycle"></i>
</button>*@
@if(Html.IsInDebugMode())
{
@Html.Partial("RestoreServiceRecordInputsPartial", Model)
}
</div>
}
</div>

View File

@@ -130,7 +130,7 @@
<div class="col col-md-auto justify-content-center mx-1 px-0">
@using(Html.BeginForm("SelectSchedulerDate", "Scheduler", FormMethod.Post, new { id = "scheduler-date-form" }))
{
<input class="form-control" type="date" id="start-date" name="SchedulerDate" value="@Model.SelectedDate.ToString("yyyy-MM-dd")" />
<input class="form-control" type="date" id="start-date" name="SchedulerDate" onchange="submitSchedulerDateForm()" value="@Model.SelectedDate.ToString("yyyy-MM-dd")" />
}
</div>
<div class="col-auto justify-content-center mx-1 px-0">

View File

@@ -45,13 +45,11 @@
<script type="text/javascript" src="@Scripts.Url("~/Scripts/devexpress-dependencies/ace/ace.min.js")"></script>
<link type="text/css" rel="stylesheet" href="@Url.Content("~/Content/style.css")" />
<link type="text/css" rel="stylesheet" href="@Url.Content("~/Content/tempusdominus-bootstrap-4.min.css")" />
<script type="text/javascript" src="@Scripts.Url("~/Scripts/ownSoft-Scripts/utils/dateUtils.js?v=1.4")"></script>
<script type="text/javascript" src="@Scripts.Url("~/Scripts/moment/moment.min.js")"></script>
<script type="text/javascript" src="@Scripts.Url("~/Scripts/moment/locale/de.js")"></script>
<script type="text/javascript" src="@Scripts.Url("~/Scripts/tempusdominus-boostrap-4.min.js")"></script>
<script type="text/javascript" src="@Scripts.Url("~/Scripts/ownSoft-Scripts/mobileUtils.js?v=1.4")"></script>
<script type="text/javascript" src="@Scripts.Url("~/Scripts/ownSoft-Scripts/view-scripts/main.js?v=1.6")"></script>
@@ -100,98 +98,6 @@
</style>
<script type="text/javascript">
class LocalBeWoStorage {
id;
inputList;
constructor(id, inputList) {
this.id = id;
this.inputList = inputList;
}
clearInputList() {
if(this.inputList === null || this.inputList === undefined) {
this.inputList = [];
}
this.inputList.length = 0;
localStorage.setItem(this.id, JSON.stringify(this));
}
removeItemById(id) {
const newInputList = [];
for(let i = 0; i < this.inputList.length; i++) {
const input = this.inputList[i];
if(input.inputId !== id) {
newInputList.push(input);
}
}
this.inputList = newInputList;
localStorage.setItem(this.id, JSON.stringify(this));
}
removeItemByName(name) {
const newInputList = [];
for(let i = 0; i < this.inputList.length; i++) {
const input = this.inputList[i];
if(input.inputName !== name) {
newInputList.push(input);
}
}
this.inputList = newInputList;
localStorage.setItem(this.id, JSON.stringify(this));
}
addInputValue(inputId, inputName, inputType, inputValue, timeStamp) {
if(inputType === "radio") {
this.removeItemByName(inputName);
}
const obj = {
inputId: inputId,
inputName: inputName,
inputType: inputType,
inputValue: inputValue,
timeStamp: timeStamp
};
this.removeItemById(inputId);
this.inputList.push(obj);
localStorage.setItem(this.id, JSON.stringify(this));
}
getItemById(id) {
const item = this.inputList.find((element) => element.inputId === id);
logInfo3(`Element: ${id}; Wert: ${item.inputValue}; Typ: ${item.inputType}`);
return item;
}
getItemsByName(name) {
const result = [];
this.inputList.map((item) => {
if (item.inputName === name) {
result.push(item);
}
});
return result;
}
}
function saveCollapsibleState(id, url) {
const isShown = $(`#${id}`).hasClass("show");
$.get(url, { isOpen: isShown, identifier: id });
@@ -446,98 +352,6 @@
function getMaxElementHeight(elementClassName) {
return Math.max.apply(Math, $(`.${elementClassName}`).map(function () { return $(this).height(); }).get());
}
@* Eingabenwiederherstellung *@
function getLocalStorageKey() {
return "@MobileSessionFacade.LocalStorageKey";
}
function getBeWoStorage() {
const localStorageKey = getLocalStorageKey();
const unparsedLocalStorageJson = localStorage.getItem(localStorageKey);
let beWoStorage = new LocalBeWoStorage(localStorageKey, []);
if(unparsedLocalStorageJson === null || unparsedLocalStorageJson === undefined || unparsedLocalStorageJson.length === 0) {
localStorage.setItem(localStorageKey, JSON.stringify(beWoStorage));
} else {
const parsedJson = JSON.parse(unparsedLocalStorageJson);
beWoStorage = new LocalBeWoStorage(localStorageKey, parsedJson.inputList);
}
return beWoStorage;
}
function clearLocalBeWoStorage() {
const beWoStorage = getBeWoStorage();
beWoStorage.clearInputList();
}
function getRestoreButtonState() {
const beWoStorage = getBeWoStorage();
return beWoStorage.inputList.length > 0;
}
window.addEventListener("load", function() {
$(".booking-form-container").find("textarea, select, input").on("change", function() {
const item = $(this);
const id = item.attr("id");
const type = item.prop("type");
const value = type === "checkbox" ? item.is(":checked").toString() : item.val();
if((value === null || value === undefined) || value.length === 0) {
logInfo2(`Element mit Id "${id}" hat ${(value !== null ? "einen leeren" : " keinen")} Wert.`);
return;
}
logInfo3(`${id}: ${value}`);
const name = item.prop("name");
const beWoStorage = getBeWoStorage();
beWoStorage.addInputValue(id, name, type, value, new Date());
// ToDo: Auch Hilfeplan- und Mitarbeiterauswahl berücksichtigen
// ToDo: 28.07.2025: Hilefplan einbauen und dabei dann ein Flag setzen in TempData und dann gegebenenfalls alle anderen Felder wiederherstellen
toggleRestoreButton();
});
});
function restoreField(id) {
const beWoStorage = getBeWoStorage();
const inputObj = beWoStorage.getItemById(id);
if(inputObj === undefined || inputObj === null) {
return;
}
$(`#${id}`).val(inputObj.inputValue);
$(`#${id}`).trigger("change");
}
function restoreAllFields() {
const beWoStorage = getBeWoStorage();
$.each(beWoStorage.inputList, (index, item) => {
if (item.inputType === "checkbox") {
$(`#${item.inputId}`).prop("checked", item.inputValue);
} else {
$(`#${item.inputId}`).val(item.inputValue);
}
$(`#${item.inputId}`).trigger("change");
});
}
@* /Eingabenwiederherstellung *@
</script>
</head>
<body>

View File

@@ -56,6 +56,12 @@ namespace PariSozialGzMigranten.Reporting.Reports
this.xrTableCell2 = new DevExpress.XtraReports.UI.XRTableCell();
this.xrTableRow8 = new DevExpress.XtraReports.UI.XRTableRow();
this.xrTableCell5 = new DevExpress.XtraReports.UI.XRTableCell();
this.xrTableRow13 = new DevExpress.XtraReports.UI.XRTableRow();
this.xrTableCell15 = new DevExpress.XtraReports.UI.XRTableCell();
this.xrTableRow14 = new DevExpress.XtraReports.UI.XRTableRow();
this.xrTableCell17 = new DevExpress.XtraReports.UI.XRTableCell();
this.xrTableRow15 = new DevExpress.XtraReports.UI.XRTableRow();
this.xrTableCell19 = new DevExpress.XtraReports.UI.XRTableCell();
this.RecipientPostCodeAndTown = new DevExpress.XtraReports.UI.XRLabel();
this.xrLabel_RecipientStreet = new DevExpress.XtraReports.UI.XRLabel();
this.xrLabel_RecipientDivision = new DevExpress.XtraReports.UI.XRLabel();
@@ -84,6 +90,7 @@ namespace PariSozialGzMigranten.Reporting.Reports
this.xrRichText1 = new DevExpress.XtraReports.UI.XRRichText();
this.xrLabel5 = new DevExpress.XtraReports.UI.XRLabel();
this.GroupHeader1 = new DevExpress.XtraReports.UI.GroupHeaderBand();
this.xrLabel13 = new DevExpress.XtraReports.UI.XRLabel();
this.xrLabel7 = new DevExpress.XtraReports.UI.XRLabel();
this.fieldApprovedFLSWithFactor = new DevExpress.XtraReports.UI.CalculatedField();
this.DetailReport = new DevExpress.XtraReports.UI.DetailReportBand();
@@ -105,13 +112,8 @@ namespace PariSozialGzMigranten.Reporting.Reports
this.xrTableRow37 = new DevExpress.XtraReports.UI.XRTableRow();
this.xrTableCell59 = new DevExpress.XtraReports.UI.XRTableCell();
this.xrTableCell60 = new DevExpress.XtraReports.UI.XRTableCell();
this.xrTableRow13 = new DevExpress.XtraReports.UI.XRTableRow();
this.xrTableCell15 = new DevExpress.XtraReports.UI.XRTableCell();
this.xrTableRow14 = new DevExpress.XtraReports.UI.XRTableRow();
this.xrTableCell17 = new DevExpress.XtraReports.UI.XRTableCell();
this.xrTableRow15 = new DevExpress.XtraReports.UI.XRTableRow();
this.xrTableCell19 = new DevExpress.XtraReports.UI.XRTableCell();
this.xrLabel13 = new DevExpress.XtraReports.UI.XRLabel();
this.xrLabel9 = new DevExpress.XtraReports.UI.XRLabel();
this.xrLabel11 = new DevExpress.XtraReports.UI.XRLabel();
this.bindingSource1 = new System.Windows.Forms.BindingSource(this.components);
((System.ComponentModel.ISupportInitialize)(this.xrTable2)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.xrTable3)).BeginInit();
@@ -367,6 +369,50 @@ namespace PariSozialGzMigranten.Reporting.Reports
this.xrTableCell5.Text = "0221 / 420 398 55";
this.xrTableCell5.Weight = 1D;
//
// xrTableRow13
//
this.xrTableRow13.Cells.AddRange(new DevExpress.XtraReports.UI.XRTableCell[] {
this.xrTableCell15});
this.xrTableRow13.Name = "xrTableRow13";
this.xrTableRow13.Weight = 0.092715231788079389D;
//
// xrTableCell15
//
this.xrTableCell15.Multiline = true;
this.xrTableCell15.Name = "xrTableCell15";
this.xrTableCell15.Padding = new DevExpress.XtraPrinting.PaddingInfo(2, 2, 0, 0, 100F);
this.xrTableCell15.Weight = 1D;
//
// xrTableRow14
//
this.xrTableRow14.Cells.AddRange(new DevExpress.XtraReports.UI.XRTableCell[] {
this.xrTableCell17});
this.xrTableRow14.Name = "xrTableRow14";
this.xrTableRow14.Weight = 0.092715231788079389D;
//
// xrTableCell17
//
this.xrTableCell17.Multiline = true;
this.xrTableCell17.Name = "xrTableCell17";
this.xrTableCell17.Padding = new DevExpress.XtraPrinting.PaddingInfo(2, 2, 0, 0, 100F);
this.xrTableCell17.Text = "E-mail:";
this.xrTableCell17.Weight = 1D;
//
// xrTableRow15
//
this.xrTableRow15.Cells.AddRange(new DevExpress.XtraReports.UI.XRTableCell[] {
this.xrTableCell19});
this.xrTableRow15.Name = "xrTableRow15";
this.xrTableRow15.Weight = 0.092715231788079389D;
//
// xrTableCell19
//
this.xrTableCell19.Multiline = true;
this.xrTableCell19.Name = "xrTableCell19";
this.xrTableCell19.Padding = new DevExpress.XtraPrinting.PaddingInfo(2, 2, 0, 0, 100F);
this.xrTableCell19.Text = "gesundheitszentrum@parisozial-koeln.de";
this.xrTableCell19.Weight = 1D;
//
// RecipientPostCodeAndTown
//
this.RecipientPostCodeAndTown.CanShrink = true;
@@ -430,10 +476,12 @@ namespace PariSozialGzMigranten.Reporting.Reports
// ReportFooter
//
this.ReportFooter.Controls.AddRange(new DevExpress.XtraReports.UI.XRControl[] {
this.xrLabel11,
this.xrLabel9,
this.xrLabel10,
this.xrTable3});
this.ReportFooter.Font = new DevExpress.Drawing.DXFont("Verdana", 10F);
this.ReportFooter.HeightF = 161.6249F;
this.ReportFooter.HeightF = 225.3749F;
this.ReportFooter.KeepTogether = true;
this.ReportFooter.Name = "ReportFooter";
this.ReportFooter.StylePriority.UseFont = false;
@@ -638,6 +686,20 @@ namespace PariSozialGzMigranten.Reporting.Reports
this.GroupHeader1.Name = "GroupHeader1";
this.GroupHeader1.StylePriority.UseFont = false;
//
// xrLabel13
//
this.xrLabel13.DataBindings.AddRange(new DevExpress.XtraReports.UI.XRBinding[] {
new DevExpress.XtraReports.UI.XRBinding("Text", null, "BusinessPartnerId")});
this.xrLabel13.Font = new DevExpress.Drawing.DXFont("Calibri", 11F);
this.xrLabel13.LocationFloat = new DevExpress.Utils.PointFloat(519.7917F, 176.3749F);
this.xrLabel13.Name = "xrLabel13";
this.xrLabel13.Padding = new DevExpress.XtraPrinting.PaddingInfo(2, 2, 0, 0, 100F);
this.xrLabel13.SizeF = new System.Drawing.SizeF(263.2083F, 23F);
this.xrLabel13.StylePriority.UseFont = false;
this.xrLabel13.StylePriority.UseTextAlignment = false;
this.xrLabel13.TextAlignment = DevExpress.XtraPrinting.TextAlignment.TopLeft;
this.xrLabel13.TextFormatString = "GP.: {0}";
//
// xrLabel7
//
this.xrLabel7.CanShrink = true;
@@ -700,7 +762,7 @@ namespace PariSozialGzMigranten.Reporting.Reports
// xrTableCell52
//
this.xrTableCell52.BorderColor = System.Drawing.SystemColors.ControlLight;
this.xrTableCell52.Borders = ((DevExpress.XtraPrinting.BorderSide)((DevExpress.XtraPrinting.BorderSide.Left | DevExpress.XtraPrinting.BorderSide.Bottom)));
this.xrTableCell52.Borders = ((DevExpress.XtraPrinting.BorderSide)((DevExpress.XtraPrinting.BorderSide.Left | DevExpress.XtraPrinting.BorderSide.Top)));
this.xrTableCell52.DataBindings.AddRange(new DevExpress.XtraReports.UI.XRBinding[] {
new DevExpress.XtraReports.UI.XRBinding("Text", null, "InvoiceItems.AbrechnungsText")});
this.xrTableCell52.Font = new DevExpress.Drawing.DXFont("arial", 10F);
@@ -715,8 +777,8 @@ namespace PariSozialGzMigranten.Reporting.Reports
// xrTableCell53
//
this.xrTableCell53.BorderColor = System.Drawing.SystemColors.ControlLight;
this.xrTableCell53.Borders = ((DevExpress.XtraPrinting.BorderSide)(((DevExpress.XtraPrinting.BorderSide.Left | DevExpress.XtraPrinting.BorderSide.Right)
| DevExpress.XtraPrinting.BorderSide.Bottom)));
this.xrTableCell53.Borders = ((DevExpress.XtraPrinting.BorderSide)(((DevExpress.XtraPrinting.BorderSide.Left | DevExpress.XtraPrinting.BorderSide.Top)
| DevExpress.XtraPrinting.BorderSide.Right)));
this.xrTableCell53.DataBindings.AddRange(new DevExpress.XtraReports.UI.XRBinding[] {
new DevExpress.XtraReports.UI.XRBinding("Text", null, "InvoiceItems.GrossAmountTotal", "{0:c}")});
this.xrTableCell53.Font = new DevExpress.Drawing.DXFont("arial", 10F);
@@ -769,7 +831,7 @@ namespace PariSozialGzMigranten.Reporting.Reports
// xrTableCell9
//
this.xrTableCell9.BorderColor = System.Drawing.SystemColors.ControlLight;
this.xrTableCell9.Borders = ((DevExpress.XtraPrinting.BorderSide)((DevExpress.XtraPrinting.BorderSide.Left | DevExpress.XtraPrinting.BorderSide.Bottom)));
this.xrTableCell9.Borders = ((DevExpress.XtraPrinting.BorderSide)((DevExpress.XtraPrinting.BorderSide.Left | DevExpress.XtraPrinting.BorderSide.Top)));
this.xrTableCell9.Font = new DevExpress.Drawing.DXFont("arial", 10F);
this.xrTableCell9.Name = "xrTableCell9";
this.xrTableCell9.Padding = new DevExpress.XtraPrinting.PaddingInfo(2, 2, 0, 0, 100F);
@@ -783,7 +845,8 @@ namespace PariSozialGzMigranten.Reporting.Reports
// xrTableCell10
//
this.xrTableCell10.BorderColor = System.Drawing.SystemColors.ControlLight;
this.xrTableCell10.Borders = ((DevExpress.XtraPrinting.BorderSide)(((DevExpress.XtraPrinting.BorderSide.Left | DevExpress.XtraPrinting.BorderSide.Right)
this.xrTableCell10.Borders = ((DevExpress.XtraPrinting.BorderSide)((((DevExpress.XtraPrinting.BorderSide.Left | DevExpress.XtraPrinting.BorderSide.Top)
| DevExpress.XtraPrinting.BorderSide.Right)
| DevExpress.XtraPrinting.BorderSide.Bottom)));
this.xrTableCell10.DataBindings.AddRange(new DevExpress.XtraReports.UI.XRBinding[] {
new DevExpress.XtraReports.UI.XRBinding("Text", null, "InvoiceItems.GrossAmountTotal")});
@@ -811,8 +874,8 @@ namespace PariSozialGzMigranten.Reporting.Reports
// xrTableCell7
//
this.xrTableCell7.BorderColor = System.Drawing.SystemColors.ControlLight;
this.xrTableCell7.Borders = ((DevExpress.XtraPrinting.BorderSide)(((DevExpress.XtraPrinting.BorderSide.Left | DevExpress.XtraPrinting.BorderSide.Right)
| DevExpress.XtraPrinting.BorderSide.Bottom)));
this.xrTableCell7.Borders = ((DevExpress.XtraPrinting.BorderSide)(((DevExpress.XtraPrinting.BorderSide.Left | DevExpress.XtraPrinting.BorderSide.Top)
| DevExpress.XtraPrinting.BorderSide.Right)));
this.xrTableCell7.Font = new DevExpress.Drawing.DXFont("Verdana", 9.75F, DevExpress.Drawing.DXFontStyle.Regular, DevExpress.Drawing.DXGraphicsUnit.Point, new DevExpress.Drawing.DXFontAdditionalProperty[] {
new DevExpress.Drawing.DXFontAdditionalProperty("GdiCharSet", ((byte)(0)))});
this.xrTableCell7.Name = "xrTableCell7";
@@ -829,7 +892,7 @@ namespace PariSozialGzMigranten.Reporting.Reports
this.xrTable5});
this.GroupFooter1.Font = new DevExpress.Drawing.DXFont("Verdana", 9.75F, DevExpress.Drawing.DXFontStyle.Regular, DevExpress.Drawing.DXGraphicsUnit.Point, new DevExpress.Drawing.DXFontAdditionalProperty[] {
new DevExpress.Drawing.DXFontAdditionalProperty("GdiCharSet", ((byte)(0)))});
this.GroupFooter1.HeightF = 46.25006F;
this.GroupFooter1.HeightF = 30F;
this.GroupFooter1.Name = "GroupFooter1";
this.GroupFooter1.StylePriority.UseFont = false;
//
@@ -856,7 +919,8 @@ namespace PariSozialGzMigranten.Reporting.Reports
// xrTableCell59
//
this.xrTableCell59.BorderColor = System.Drawing.SystemColors.ControlLight;
this.xrTableCell59.Borders = ((DevExpress.XtraPrinting.BorderSide)((DevExpress.XtraPrinting.BorderSide.Left | DevExpress.XtraPrinting.BorderSide.Bottom)));
this.xrTableCell59.Borders = ((DevExpress.XtraPrinting.BorderSide)(((DevExpress.XtraPrinting.BorderSide.Left | DevExpress.XtraPrinting.BorderSide.Top)
| DevExpress.XtraPrinting.BorderSide.Bottom)));
this.xrTableCell59.Font = new DevExpress.Drawing.DXFont("Arial", 10F, DevExpress.Drawing.DXFontStyle.Bold);
this.xrTableCell59.Name = "xrTableCell59";
this.xrTableCell59.Padding = new DevExpress.XtraPrinting.PaddingInfo(2, 2, 0, 0, 100F);
@@ -868,7 +932,8 @@ namespace PariSozialGzMigranten.Reporting.Reports
//
// xrTableCell60
//
this.xrTableCell60.Borders = ((DevExpress.XtraPrinting.BorderSide)(((DevExpress.XtraPrinting.BorderSide.Left | DevExpress.XtraPrinting.BorderSide.Right)
this.xrTableCell60.Borders = ((DevExpress.XtraPrinting.BorderSide)((((DevExpress.XtraPrinting.BorderSide.Left | DevExpress.XtraPrinting.BorderSide.Top)
| DevExpress.XtraPrinting.BorderSide.Right)
| DevExpress.XtraPrinting.BorderSide.Bottom)));
this.xrTableCell60.DataBindings.AddRange(new DevExpress.XtraReports.UI.XRBinding[] {
new DevExpress.XtraReports.UI.XRBinding("Text", null, "Claim", "{0:c}")});
@@ -883,63 +948,29 @@ namespace PariSozialGzMigranten.Reporting.Reports
this.xrTableCell60.TextAlignment = DevExpress.XtraPrinting.TextAlignment.TopRight;
this.xrTableCell60.Weight = 0.16397432767427886D;
//
// xrTableRow13
// xrLabel9
//
this.xrTableRow13.Cells.AddRange(new DevExpress.XtraReports.UI.XRTableCell[] {
this.xrTableCell15});
this.xrTableRow13.Name = "xrTableRow13";
this.xrTableRow13.Weight = 0.092715231788079389D;
this.xrLabel9.Font = new DevExpress.Drawing.DXFont("Arial", 10F);
this.xrLabel9.LocationFloat = new DevExpress.Utils.PointFloat(52.04137F, 185.6251F);
this.xrLabel9.Name = "xrLabel9";
this.xrLabel9.Padding = new DevExpress.XtraPrinting.PaddingInfo(2, 2, 0, 0, 100F);
this.xrLabel9.SizeF = new System.Drawing.SizeF(91.66667F, 17.00002F);
this.xrLabel9.StylePriority.UseFont = false;
this.xrLabel9.StylePriority.UseTextAlignment = false;
this.xrLabel9.Text = "Musa Deli";
this.xrLabel9.TextAlignment = DevExpress.XtraPrinting.TextAlignment.TopCenter;
//
// xrTableCell15
// xrLabel11
//
this.xrTableCell15.Multiline = true;
this.xrTableCell15.Name = "xrTableCell15";
this.xrTableCell15.Padding = new DevExpress.XtraPrinting.PaddingInfo(2, 2, 0, 0, 100F);
this.xrTableCell15.Weight = 1D;
//
// xrTableRow14
//
this.xrTableRow14.Cells.AddRange(new DevExpress.XtraReports.UI.XRTableCell[] {
this.xrTableCell17});
this.xrTableRow14.Name = "xrTableRow14";
this.xrTableRow14.Weight = 0.092715231788079389D;
//
// xrTableCell17
//
this.xrTableCell17.Multiline = true;
this.xrTableCell17.Name = "xrTableCell17";
this.xrTableCell17.Padding = new DevExpress.XtraPrinting.PaddingInfo(2, 2, 0, 0, 100F);
this.xrTableCell17.Text = "E-mail:";
this.xrTableCell17.Weight = 1D;
//
// xrTableRow15
//
this.xrTableRow15.Cells.AddRange(new DevExpress.XtraReports.UI.XRTableCell[] {
this.xrTableCell19});
this.xrTableRow15.Name = "xrTableRow15";
this.xrTableRow15.Weight = 0.092715231788079389D;
//
// xrTableCell19
//
this.xrTableCell19.Multiline = true;
this.xrTableCell19.Name = "xrTableCell19";
this.xrTableCell19.Padding = new DevExpress.XtraPrinting.PaddingInfo(2, 2, 0, 0, 100F);
this.xrTableCell19.Text = "gesundheitszentrum@parisozial-koeln.de";
this.xrTableCell19.Weight = 1D;
//
// xrLabel13
//
this.xrLabel13.DataBindings.AddRange(new DevExpress.XtraReports.UI.XRBinding[] {
new DevExpress.XtraReports.UI.XRBinding("Text", null, "BusinessPartnerId")});
this.xrLabel13.Font = new DevExpress.Drawing.DXFont("Calibri", 11F);
this.xrLabel13.LocationFloat = new DevExpress.Utils.PointFloat(519.7917F, 176.3749F);
this.xrLabel13.Name = "xrLabel13";
this.xrLabel13.Padding = new DevExpress.XtraPrinting.PaddingInfo(2, 2, 0, 0, 100F);
this.xrLabel13.SizeF = new System.Drawing.SizeF(263.2083F, 23F);
this.xrLabel13.StylePriority.UseFont = false;
this.xrLabel13.StylePriority.UseTextAlignment = false;
this.xrLabel13.TextAlignment = DevExpress.XtraPrinting.TextAlignment.TopLeft;
this.xrLabel13.TextFormatString = "GP.: {0}";
this.xrLabel11.Font = new DevExpress.Drawing.DXFont("Arial", 10F);
this.xrLabel11.LocationFloat = new DevExpress.Utils.PointFloat(52.04137F, 202.6252F);
this.xrLabel11.Name = "xrLabel11";
this.xrLabel11.Padding = new DevExpress.XtraPrinting.PaddingInfo(2, 2, 0, 0, 100F);
this.xrLabel11.SizeF = new System.Drawing.SizeF(91.66667F, 17.00002F);
this.xrLabel11.StylePriority.UseFont = false;
this.xrLabel11.StylePriority.UseTextAlignment = false;
this.xrLabel11.Text = "- Leitung -";
this.xrLabel11.TextAlignment = DevExpress.XtraPrinting.TextAlignment.TopCenter;
//
// bindingSource1
//
@@ -961,7 +992,7 @@ namespace PariSozialGzMigranten.Reporting.Reports
this.ExportOptions.PrintPreview.DefaultFileName = "Spitzabrechnung";
this.FormattingRuleSheet.AddRange(new DevExpress.XtraReports.UI.FormattingRule[] {
this.ruleRateFactorNull});
this.Margins = new DevExpress.Drawing.DXMargins(0F, 44F, 154.1666F, 163.2084F);
this.Margins = new DevExpress.Drawing.DXMargins(0F, 43F, 154.1666F, 163.2084F);
this.PageHeight = 1169;
this.PageWidth = 827;
this.PaperKind = DevExpress.Drawing.Printing.DXPaperKind.A4;
@@ -1061,5 +1092,7 @@ namespace PariSozialGzMigranten.Reporting.Reports
private DevExpress.XtraReports.UI.XRTableRow xrTableRow15;
private DevExpress.XtraReports.UI.XRTableCell xrTableCell19;
private DevExpress.XtraReports.UI.XRLabel xrLabel13;
private DevExpress.XtraReports.UI.XRLabel xrLabel11;
private DevExpress.XtraReports.UI.XRLabel xrLabel9;
}
}

View File

@@ -0,0 +1,25 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.14.36203.30 d17.14
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BeWoDatabaseUpdater", "BeWoDatabaseUpdater\BeWoDatabaseUpdater.csproj", "{C9F91B7A-0317-44C5-A747-05E3E3ED540B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C9F91B7A-0317-44C5-A747-05E3E3ED540B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C9F91B7A-0317-44C5-A747-05E3E3ED540B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C9F91B7A-0317-44C5-A747-05E3E3ED540B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C9F91B7A-0317-44C5-A747-05E3E3ED540B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {EF9037FE-3443-42CE-BFD7-F3CBE9FB1071}
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8.1" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.3.0" newVersion="6.0.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.5.0" newVersion="4.0.5.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.5.0" newVersion="4.0.5.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.IO.Pipelines" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.6" newVersion="9.0.0.6" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.4.0" newVersion="4.2.4.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Google.Protobuf" publicKeyToken="a7d26565bac4d604" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.31.1.0" newVersion="3.31.1.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@@ -0,0 +1,134 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{C9F91B7A-0317-44C5-A747-05E3E3ED540B}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>BeWoDatabaseUpdater</RootNamespace>
<AssemblyName>BeWoDatabaseUpdater</AssemblyName>
<TargetFrameworkVersion>v4.8.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
<LangVersion>13</LangVersion>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>x64</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="BouncyCastle.Cryptography, Version=2.0.0.0, Culture=neutral, PublicKeyToken=072edcf4a5328938, processorArchitecture=MSIL">
<HintPath>..\packages\BouncyCastle.Cryptography.2.6.1\lib\net461\BouncyCastle.Cryptography.dll</HintPath>
</Reference>
<Reference Include="Google.Protobuf, Version=3.31.1.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
<HintPath>..\packages\Google.Protobuf.3.31.1\lib\net45\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="K4os.Compression.LZ4, Version=1.3.8.0, Culture=neutral, PublicKeyToken=2186fa9121ef231d, processorArchitecture=MSIL">
<HintPath>..\packages\K4os.Compression.LZ4.1.3.8\lib\net462\K4os.Compression.LZ4.dll</HintPath>
</Reference>
<Reference Include="K4os.Compression.LZ4.Streams, Version=1.3.8.0, Culture=neutral, PublicKeyToken=2186fa9121ef231d, processorArchitecture=MSIL">
<HintPath>..\packages\K4os.Compression.LZ4.Streams.1.3.8\lib\net462\K4os.Compression.LZ4.Streams.dll</HintPath>
</Reference>
<Reference Include="K4os.Hash.xxHash, Version=1.0.8.0, Culture=neutral, PublicKeyToken=32cd54395057cec3, processorArchitecture=MSIL">
<HintPath>..\packages\K4os.Hash.xxHash.1.0.8\lib\net462\K4os.Hash.xxHash.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=9.0.0.6, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.9.0.6\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
</Reference>
<Reference Include="MySql.Data, Version=9.3.0.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
<HintPath>..\packages\MySql.Data.9.3.0\lib\net48\MySql.Data.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Buffers, Version=4.0.5.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.6.1\lib\net462\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.Configuration" />
<Reference Include="System.Configuration.ConfigurationManager, Version=9.0.0.6, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Configuration.ConfigurationManager.9.0.6\lib\net462\System.Configuration.ConfigurationManager.dll</HintPath>
</Reference>
<Reference Include="System.Core" />
<Reference Include="System.Diagnostics.DiagnosticSource, Version=9.0.0.6, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Diagnostics.DiagnosticSource.9.0.6\lib\net462\System.Diagnostics.DiagnosticSource.dll</HintPath>
</Reference>
<Reference Include="System.IO.Pipelines, Version=9.0.0.6, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.IO.Pipelines.9.0.6\lib\net462\System.IO.Pipelines.dll</HintPath>
</Reference>
<Reference Include="System.Memory, Version=4.0.5.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Memory.4.6.3\lib\net462\System.Memory.dll</HintPath>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Numerics.Vectors, Version=4.1.6.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Numerics.Vectors.4.6.1\lib\net462\System.Numerics.Vectors.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.6.1.2\lib\net462\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.4.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.6.3\lib\net462\System.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.Transactions" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="ZstdSharp, Version=0.8.5.0, Culture=neutral, PublicKeyToken=8d151af33a4ad5cf, processorArchitecture=MSIL">
<HintPath>..\packages\ZstdSharp.Port.0.8.5\lib\net462\ZstdSharp.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Extensions\DictionaryExtensions.cs" />
<Compile Include="Extensions\EnumerableTExtensions.cs" />
<Compile Include="Extensions\ListTExtensions.cs" />
<Compile Include="Extensions\TimeSpanExtensions.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Utils.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.8.1">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4.8.1 %28x86 and x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -0,0 +1,61 @@
using System.Collections.Generic;
using System.Linq;
namespace BeWoDatabaseUpdater.Extensions
{
public static class DictionaryExtensions
{
public static IDictionary<T, List<U>> AddOrUpdateValueInDictionary<T, U>(this IDictionary<T, List<U>> dictionary, T key, List<U> value)
{
if(false == dictionary.ContainsKey(key))
{
dictionary.Add(key, value);
}
else
{
dictionary[key] = dictionary[key].Union(value).ToList();
}
return dictionary;
}
public static IDictionary<T, List<U>> AddOrUpdateValueInDictionary<T, U>(this IDictionary<T, List<U>> dictionary, T key, U value)
{
if(false == dictionary.ContainsKey(key))
{
dictionary.Add(key, [value]);
}
else
{
dictionary[key].AddIfNotIn(value);
}
return dictionary;
}
public static void AddAndIgnoreDuplicates<T, U>(this IDictionary<T, U> dictionary, T key, U value)
{
if(dictionary.ContainsKey(key))
{
return;
}
dictionary.Add(key, value);
}
public static void AddAndIgnoreDuplicates<T, U>(this IDictionary<T, U> dictionary, IEnumerable<KeyValuePair<T, U>> dictionary2Add)
{
dictionary2Add.Where(kvp => false == dictionary.ContainsKey(kvp.Key)).DoForEach(dictionary.Add);
}
public static bool ContainsValueAtKey<T, U>(this IDictionary<T, List<U>> dictionary, T key, U value)
{
return dictionary.ContainsKey(key) && (dictionary[key]?.Contains(value) ?? false);
}
public static void AddOrUpdate<T, U>(this IDictionary<T, U> dictionary, T key, U value)
{
dictionary[key] = value;
}
}
}

View File

@@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace BeWoDatabaseUpdater.Extensions
{
public static class EnumerableTExtensions
{
public static IEnumerable<T> DoForEach<T>(this IEnumerable<T> enumerable, Action<T> action)
{
var list = enumerable as IList<T> ?? enumerable.ToList();
foreach(var item in list)
{
action(item);
}
return list;
}
public static int IndexOf<T>(this IEnumerable<T> list, T item)
{
var counter = 0;
foreach(var listItem in list)
{
if(listItem.Equals(item))
{
return counter;
}
counter++;
}
return -1;
}
}
}

View File

@@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace BeWoDatabaseUpdater.Extensions
{
public static class ListTExtensions
{
public static void AddIfNotIn<T>(this IList<T> list, T item)
{
if(list.Contains(item))
{
return;
}
list.Add(item);
}
public static void AddRange<T>(this IList<T> list, IEnumerable<T> items)
{
foreach(var item in items)
{
list.Add(item);
}
}
public static void AddRangeIfNotIn<T>(this IList<T> list, IEnumerable<T> items)
{
foreach(var item in items)
{
list.AddIfNotIn(item);
}
}
public static bool Exists<T>(this IList<T> list, Predicate<T> match)
{
return list.Any(item => match(item));
}
public static void RemoveRange<T>(this IList<T> list, IEnumerable<T> items)
{
foreach(var item in items.ToList())
{
list.Remove(item);
}
}
public static void RemoveRange<T>(this IList<T> list, Predicate<T> match)
{
var items = list.Where(t => match(t)).ToList();
list.RemoveRange(items);
}
}
}

View File

@@ -0,0 +1,12 @@
using System;
namespace BeWoDatabaseUpdater.Extensions
{
public static class TimeSpanExtensions
{
public static string ToShortString(this TimeSpan timeSpan)
{
return $"{(int) timeSpan.TotalMinutes:D2}:{timeSpan.Seconds:D2}.{timeSpan.Milliseconds:D2}";
}
}
}

View File

@@ -0,0 +1,363 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using BeWoDatabaseUpdater.Extensions;
using MySql.Data.MySqlClient;
namespace BeWoDatabaseUpdater
{
// ToDo: bestimmte Fehlermeldungen ignorieren oder prüfen, ob es die Spalten bereits gibt etc.
internal class Program
{
private const int CutoffYear = 2001;
private static string _ConnectionString;
private static string _ModelPath;
private static DateTime? _LastAccessTime;
private const string UpdaterSettingsFilePath = "bewo-database-updater-settings.txt";
public const string FailedSqlCommandsFilePath = "bewo-database-updater-failed-sql-commands.txt";
private static readonly List<FilePath2MySqlCommands> _FilePaths2Sql = [];
private static List<string> _FilePaths = [];
private static List<string> _BeWoSchemaNames = [];
private static readonly List<DateTime> _LastAccessTimes = [];
private static readonly Stopwatch _Stopwatch = new();
private static async Task Main(string[] args)
{
var settingsFilePath = Path.Combine(AppContext.BaseDirectory, UpdaterSettingsFilePath);
// Falls die Settings-Datei noch nicht existiert:
if(false == File.Exists(settingsFilePath))
{
using var fileStream = File.Create(settingsFilePath);
}
// Falls es noch keine Datei mit Sql-Fehler gibt, wird eine erstellt, in die die Fehler geschrieben werden:
if(false == File.Exists(FailedSqlCommandsFilePath))
{
using var fileStream = File.Create(FailedSqlCommandsFilePath);
}
// Die Settingsdatei mit Pfad zum "Model"-Verzeichnis, MySql-Connection-String und dem letzten Ausführdatum auslesen
ReadSettingsFile(settingsFilePath);
if(string.IsNullOrWhiteSpace(_ConnectionString))
{
Console.WriteLine();
Console.Write("Connection String: ");
_ConnectionString = Console.ReadLine();
}
// Den Pfad zum Model-Verzeichnis im BeWoPlaner-Projekt ermitteln
DetermineModelPath();
// Die Dateien mit den Sql-Skripten auflisten
_Stopwatch.Start();
GetTextAndSqlFiles();
Console.WriteLine($"{DateTime.Now:dd.MM.yyyy HH:mm:ss.fff}: Führe Updates durch ...{Environment.NewLine}");
var helper = new MySqlHelper(_ConnectionString);
_BeWoSchemaNames = await helper.LoadBeWoDatabaseNames() ?? [];
LoadSqlScriptsFromFilesToMemory(() =>
{
var commandCount = 0;
var fileCount = 0;
_FilePaths2Sql.DoForEach(path2Commands =>
{
commandCount += path2Commands.Commands.Count;
fileCount++;
});
var message = $"{DateTime.Now:dd.MM.yyyy HH:mm:ss.fff}: {commandCount} MySQL-Abfragen in {fileCount} Dateien und {_BeWoSchemaNames.Count} BeWoPlaner-Datenbanken ({_BeWoSchemaNames.Count * commandCount} Transaktionen gesamt):{Environment.NewLine}";
var sb = new StringBuilder();
for(var i = 0; i < message.Length; i++)
{
sb.Append('-');
}
Console.WriteLine($"{message}{sb}");
if(commandCount == 0)
{
OnAllThreadsCompleted();
return;
}
helper.OpenSession();
// Ein Thread pro Sql-Kommando
var threads = new List<Thread>();
foreach(var schemaName in _BeWoSchemaNames)
{
foreach(var path2Commands in _FilePaths2Sql)
{
_LastAccessTimes.Add(new FileInfo(path2Commands.FilePath).LastAccessTime);
foreach(var command in path2Commands.Commands)
{
var thread = new Thread( () =>
{
var sql = $"USE `{schemaName}`; {command}";
helper.ExecuteUpdateOrCreate(sql, path2Commands.FilePath);
});
thread.Start();
threads.Add(thread);
}
}
}
threads.DoForEach(thread =>
{
thread.Join();
helper.CloseSession();
OnAllThreadsCompleted();
});
});
if(MySqlHelper.DistinctErrors.Any())
{
Console.Read();
}
}
private static void OnAllThreadsCompleted()
{
_LastAccessTime = _LastAccessTimes.Any() ? _LastAccessTimes.Max() : DateTime.Now;
_Stopwatch.Stop();
File.WriteAllText(UpdaterSettingsFilePath,
$"ConnectionString={_ConnectionString}{Environment.NewLine}" +
$"LastScriptAccessTime={_LastAccessTime}{Environment.NewLine}" +
$"ModelPath={_ModelPath}"
);
var timeSpan = TimeSpan.FromTicks(_Stopwatch.ElapsedTicks);
Console.WriteLine($"{DateTime.Now:dd.MM.yyyy HH:mm:ss.fff}: Dauer: {timeSpan.ToShortString()}{Environment.NewLine}");
Console.WriteLine($"{MySqlHelper.DistinctErrors.Count} Fehler{(MySqlHelper.DistinctErrors.Any() ? ":" : "")}");
MySqlHelper.DistinctErrors.DoForEach(number2Message => Console.WriteLine($"{number2Message.Key}: {number2Message.Value}"));
}
private static void GetTextAndSqlFiles()
{
_FilePaths = Directory.GetFiles(_ModelPath).Where(file =>
{
var extension = Path.GetExtension(file);
var fileInfo = new FileInfo(file);
var name = fileInfo.Name.ToLower();
if(false == name.StartsWith("changes_"))
{
return false;
}
int.TryParse(name.Split('_')[1], out var year);
if(year == 0)
{
year = DateTime.Today.Year;
}
return (extension.EndsWith("txt") || extension.EndsWith("sql")) && year >= CutoffYear && fileInfo.LastAccessTime > _LastAccessTime;
}).ToList();
}
private static void ReadSettingsFile(string settingsFilePath)
{
var allLines = File.ReadAllLines(settingsFilePath);
foreach(var line in allLines)
{
var settingsName2Value = line.Split('=');
if(settingsName2Value.Length < 2)
{
continue;
}
var settingsName = settingsName2Value[0];
var indexOfFirstEquals = line.IndexOf('=');
var settingsValue = line.Substring(indexOfFirstEquals + 1);
switch(settingsName)
{
case "ConnectionString":
_ConnectionString = settingsValue;
break;
case "LastScriptAccessTime":
if(DateTime.TryParse(settingsValue, out var parsedNewestScriptCreationTime))
{
_LastAccessTime = parsedNewestScriptCreationTime;
}
break;
case "ModelPath":
_ModelPath = settingsValue;
break;
}
}
}
private static void DetermineModelPath()
{
while(string.IsNullOrWhiteSpace(_ModelPath) || false == Directory.Exists(_ModelPath))
{
Console.WriteLine();
if(false == string.IsNullOrWhiteSpace(_ModelPath) && false == Directory.Exists(_ModelPath))
{
Console.WriteLine($"Der Pfad '{_ModelPath}' ist ungültig!");
}
Console.Write("Pfad zum Model-Verzeichnis: ");
_ModelPath = Console.ReadLine();
}
}
private static void LoadSqlScriptsFromFilesToMemory(Action callback)
{
var threads = new List<Thread>();
foreach(var filePath in _FilePaths)
{
var thread = new Thread(() =>
{
var fileInfo = new FileInfo(filePath);
if(_LastAccessTime.HasValue && _LastAccessTime >= fileInfo.CreationTime)
{
return;
}
_FilePaths2Sql.Add(new FilePath2MySqlCommands(filePath, File.ReadAllText(filePath).Split(';').ToList()));
});
thread.Start();
threads.Add(thread);
}
Task.Run(() =>
{
threads.DoForEach(thread => thread.Join());
callback?.Invoke();
});
}
}
public class FilePath2MySqlCommands(string filePath, List<string> commands)
{
public string FilePath { get; set; } = filePath;
public List<string> Commands { get; set; } = commands ?? [];
}
public class MySqlHelper
{
public string ConnectionString { get; set; }
private readonly MySqlConnection _Connection;
public async Task<List<string>> LoadBeWoDatabaseNames()
{
var connection = new MySqlConnection(ConnectionString);
var result = new List<string>();
try
{
await connection.OpenAsync();
var command = new MySqlCommand("SELECT TABLE_SCHEMA FROM INFORMATION_SCHEMA.TABLES tables WHERE tables.TABLE_NAME = 'bewofile';") {Connection = connection};
await using var dataReader = command.ExecuteReader();
while(await dataReader.ReadAsync())
{
var schemaName = dataReader["TABLE_SCHEMA"]?.ToString();
if(schemaName is not null)
{
result.AddIfNotIn(schemaName);
}
}
}
catch(Exception exception)
{
Console.WriteLine(exception);
}
finally
{
if(connection.State is ConnectionState.Open or ConnectionState.Executing)
{
await connection.CloseAsync();
}
}
return result;
}
public MySqlHelper(string connectionString)
{
ConnectionString = connectionString;
_Connection = new MySqlConnection(ConnectionString);
}
public static Dictionary<int, string> DistinctErrors = [];
public void OpenSession()
{
_Connection.Open();
}
public void CloseSession()
{
_Connection.Close();
WriteSqlErrorsToFile();
}
public void WriteSqlErrorsToFile()
{
File.WriteAllLines(Program.FailedSqlCommandsFilePath, DistinctErrors.Values);
}
public async Task ExecuteUpdateOrCreate(string sql, string filePath)
{
try
{
await new MySqlCommand(sql) { Connection = _Connection }.ExecuteNonQueryAsync();
}
catch(MySqlException exception)
{
var errorMessage = $"{exception.Number} {new FileInfo(filePath).Name}: {exception.Message}";
DistinctErrors.AddAndIgnoreDuplicates(exception.Number, errorMessage);
}
}
}
}

View File

@@ -0,0 +1,33 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("BeWoDatabaseUpdater")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BeWoDatabaseUpdater")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("c9f91b7a-0317-44c5-a747-05e3e3ed540b")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,21 @@
using System;
namespace BeWoDatabaseUpdater
{
public static class Utils
{
public static void ConsoleWriteException(Exception exception)
{
ConsoleWriteError(exception.ToString());
}
public static void ConsoleWriteError(string errorMessage)
{
Console.BackgroundColor = ConsoleColor.Black;
Console.ForegroundColor = ConsoleColor.DarkRed;
Console.WriteLine(errorMessage);
Console.BackgroundColor = ConsoleColor.Black;
Console.ForegroundColor = ConsoleColor.White;
}
}
}

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="BouncyCastle.Cryptography" version="2.6.1" targetFramework="net481" />
<package id="Google.Protobuf" version="3.31.1" targetFramework="net481" />
<package id="K4os.Compression.LZ4" version="1.3.8" targetFramework="net481" />
<package id="K4os.Compression.LZ4.Streams" version="1.3.8" targetFramework="net481" />
<package id="K4os.Hash.xxHash" version="1.0.8" targetFramework="net481" />
<package id="Microsoft.Bcl.AsyncInterfaces" version="9.0.6" targetFramework="net481" />
<package id="MySql.Data" version="9.3.0" targetFramework="net481" />
<package id="System.Buffers" version="4.6.1" targetFramework="net481" />
<package id="System.Configuration.ConfigurationManager" version="9.0.6" targetFramework="net481" />
<package id="System.Diagnostics.DiagnosticSource" version="9.0.6" targetFramework="net481" />
<package id="System.IO.Pipelines" version="9.0.6" targetFramework="net481" />
<package id="System.Memory" version="4.6.3" targetFramework="net481" />
<package id="System.Numerics.Vectors" version="4.6.1" targetFramework="net481" />
<package id="System.Runtime.CompilerServices.Unsafe" version="6.1.2" targetFramework="net481" />
<package id="System.Threading.Tasks.Extensions" version="4.6.3" targetFramework="net481" />
<package id="ZstdSharp.Port" version="0.8.5" targetFramework="net481" />
</packages>