diff --git a/BeWoPlanerMobil/BeWoPlanerMobil.csproj b/BeWoPlanerMobil/BeWoPlanerMobil.csproj index 82f38c36a..1a2ce855a 100644 --- a/BeWoPlanerMobil/BeWoPlanerMobil.csproj +++ b/BeWoPlanerMobil/BeWoPlanerMobil.csproj @@ -675,6 +675,7 @@ + diff --git a/BeWoPlanerMobil/Controllers/MainController.cs b/BeWoPlanerMobil/Controllers/MainController.cs index b2911ebe8..b525780bd 100644 --- a/BeWoPlanerMobil/Controllers/MainController.cs +++ b/BeWoPlanerMobil/Controllers/MainController.cs @@ -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 diff --git a/BeWoPlanerMobil/Controllers/SchedulerController.cs b/BeWoPlanerMobil/Controllers/SchedulerController.cs index 4cb90f93e..f43d57cf4 100644 --- a/BeWoPlanerMobil/Controllers/SchedulerController.cs +++ b/BeWoPlanerMobil/Controllers/SchedulerController.cs @@ -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; diff --git a/BeWoPlanerMobil/Models/MainModel.cs b/BeWoPlanerMobil/Models/MainModel.cs index 3610906be..5f58abc99 100644 --- a/BeWoPlanerMobil/Models/MainModel.cs +++ b/BeWoPlanerMobil/Models/MainModel.cs @@ -841,6 +841,19 @@ namespace BeWoPlanerMobil.Models return SelectedServiceDescription; } + public BookingMode CurrentBookingMode + { + get + { + if(IsInGroupBookingMode) + { + return BookingMode.GroupBookingMode; + } + + return IsInMultiBookingMode ? BookingMode.MultiBookingMode : BookingMode.SingleBookingMode; + } + } + } diff --git a/BeWoPlanerMobil/Scripts/ownSoft-Scripts/signature.js b/BeWoPlanerMobil/Scripts/ownSoft-Scripts/signature.js index 534fd64c1..d43611854 100644 --- a/BeWoPlanerMobil/Scripts/ownSoft-Scripts/signature.js +++ b/BeWoPlanerMobil/Scripts/ownSoft-Scripts/signature.js @@ -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; diff --git a/BeWoPlanerMobil/Scripts/ownSoft-Scripts/view-scripts/main.js b/BeWoPlanerMobil/Scripts/ownSoft-Scripts/view-scripts/main.js index f27b11e50..3b8a3b232 100644 --- a/BeWoPlanerMobil/Scripts/ownSoft-Scripts/view-scripts/main.js +++ b/BeWoPlanerMobil/Scripts/ownSoft-Scripts/view-scripts/main.js @@ -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(); diff --git a/BeWoPlanerMobil/Util/FormCollectionConstants.cs b/BeWoPlanerMobil/Util/FormCollectionConstants.cs index 69cbaca95..4c88ddf31 100644 --- a/BeWoPlanerMobil/Util/FormCollectionConstants.cs +++ b/BeWoPlanerMobil/Util/FormCollectionConstants.cs @@ -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"; } } \ No newline at end of file diff --git a/BeWoPlanerMobil/Views/Main/Category2ServiceDescriptionPartial.cshtml b/BeWoPlanerMobil/Views/Main/Category2ServiceDescriptionPartial.cshtml index a420ff17c..f19446770 100644 --- a/BeWoPlanerMobil/Views/Main/Category2ServiceDescriptionPartial.cshtml +++ b/BeWoPlanerMobil/Views/Main/Category2ServiceDescriptionPartial.cshtml @@ -1,4 +1,5 @@ @using BeWoPlanerMobil.Util +@using BS.Shared @model BeWoPlanerMobil.Models.MainModel @{ @@ -10,6 +11,26 @@ } + + 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; + } } -@{ - var selectedServiceDescription = Model.GetSelectedOrFirstServiceDescription(); - var selectedCategory = selectedServiceDescription?.Category; -} + @@ -45,17 +69,17 @@ Kategorie - + @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; @category.Name } @@ -75,7 +99,7 @@ Leistung - + @if(selectedCategory != null && Model.Categories2Descriptions.ContainsKey(selectedCategory)) { foreach(var serviceDescription in Model.Categories2Descriptions[selectedCategory]) diff --git a/BeWoPlanerMobil/Views/Main/GoalTreePartial.cshtml b/BeWoPlanerMobil/Views/Main/GoalTreePartial.cshtml index 4c1438c08..075ade629 100644 --- a/BeWoPlanerMobil/Views/Main/GoalTreePartial.cshtml +++ b/BeWoPlanerMobil/Views/Main/GoalTreePartial.cshtml @@ -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 ${numberOfSelectedGoals}`); }); } catch(error) { @@ -128,11 +128,6 @@ } -@* - 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"; diff --git a/BeWoPlanerMobil/Views/Main/GroupBookingFormPartial.cshtml b/BeWoPlanerMobil/Views/Main/GroupBookingFormPartial.cshtml index 8f2a16604..f31c69117 100644 --- a/BeWoPlanerMobil/Views/Main/GroupBookingFormPartial.cshtml +++ b/BeWoPlanerMobil/Views/Main/GroupBookingFormPartial.cshtml @@ -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)); + } @if(Model != null) @@ -85,7 +110,7 @@ @* Hilfepläne und Mitarbeiter *@ - + @Html.Partial("GroupBookingSelectionPartial", Model) @@ -301,26 +326,27 @@ } - - @submitButtonText - - @if(Model.IsInTransferMode) - { - using(Html.BeginForm("ResetTransferMode", "Main", FormMethod.Post)) - { - Abbrechen - } - } - else - { - using(Html.BeginForm("ResetEditingMode", "Main", FormMethod.Post)) - { - Abbrechen - } - } + + @submitButtonText - @* - - *@ - + @if(Model.IsInTransferMode) + { + using(Html.BeginForm("ResetTransferMode", "Main", FormMethod.Post)) + { + Abbrechen + } + } + else + { + using(Html.BeginForm("ResetEditingMode", "Main", FormMethod.Post)) + { + Abbrechen + } + } + + @if(Html.IsInDebugMode()) + { + @Html.Partial("RestoreServiceRecordInputsPartial", Model) + } + } \ No newline at end of file diff --git a/BeWoPlanerMobil/Views/Main/GroupBookingPartial.cshtml b/BeWoPlanerMobil/Views/Main/GroupBookingPartial.cshtml index 089a52782..68bc68b3a 100644 --- a/BeWoPlanerMobil/Views/Main/GroupBookingPartial.cshtml +++ b/BeWoPlanerMobil/Views/Main/GroupBookingPartial.cshtml @@ -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 @@ - Hilfepläne - Gruppen + Hilfepläne + Gruppen - + @Html.Partial("GroupBookingScCbRelList", Model) @@ -113,7 +116,7 @@ @* ----- (Gruppenbuchung) Mitarbeiterauswahl Popup ----- *@ - + @@ -131,16 +134,17 @@ + + @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; - - - - @employee.DetailDescription - - } + + + @employee.DetailDescription + + } + diff --git a/BeWoPlanerMobil/Views/Main/GroupBookingScCbRelList.cshtml b/BeWoPlanerMobil/Views/Main/GroupBookingScCbRelList.cshtml index d54562a15..f6c26cbc0 100644 --- a/BeWoPlanerMobil/Views/Main/GroupBookingScCbRelList.cshtml +++ b/BeWoPlanerMobil/Views/Main/GroupBookingScCbRelList.cshtml @@ -12,7 +12,7 @@ } } - + @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); - } - + class="custom-control-input cb2sc-input" id="gb-cb2sc-checkbox-@cb2Sc.CostBearer2SupportConceptOid" onchange="addScCbRelsToGroupBooking()" name="cb2sc-checkbox-@cb2Sc.CostBearer2SupportConceptOid" value="@cb2Sc.CostBearer2SupportConceptOid"> + @cb2Sc.NameAndDateOfBirth @@ -43,7 +41,7 @@ } - + @foreach(var group in Model.GroupOfPeopleListItems) { diff --git a/BeWoPlanerMobil/Views/Main/GroupBookingSelectionPartial.cshtml b/BeWoPlanerMobil/Views/Main/GroupBookingSelectionPartial.cshtml index c401995bd..46866dbb3 100644 --- a/BeWoPlanerMobil/Views/Main/GroupBookingSelectionPartial.cshtml +++ b/BeWoPlanerMobil/Views/Main/GroupBookingSelectionPartial.cshtml @@ -57,7 +57,7 @@ - + Mitarbeiter hinzufügen @Model.GroupBookingSelectedEmployees.Count diff --git a/BeWoPlanerMobil/Views/Main/Main.cshtml b/BeWoPlanerMobil/Views/Main/Main.cshtml index c13f46adc..3d82b8554 100644 --- a/BeWoPlanerMobil/Views/Main/Main.cshtml +++ b/BeWoPlanerMobil/Views/Main/Main.cshtml @@ -133,7 +133,7 @@ } - 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) { - loadServiceRecords(); + loadServiceRecords(); } + + + + + // 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); } diff --git a/BeWoPlanerMobil/Views/Main/MultiBookingFormPartial.cshtml b/BeWoPlanerMobil/Views/Main/MultiBookingFormPartial.cshtml index 3916ca3ef..3faa0c224 100644 --- a/BeWoPlanerMobil/Views/Main/MultiBookingFormPartial.cshtml +++ b/BeWoPlanerMobil/Views/Main/MultiBookingFormPartial.cshtml @@ -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)); } @@ -284,16 +306,17 @@ } - - Anlegen + + Anlegen - @using(Html.BeginForm("ResetMultiBookingForm", "Main", FormMethod.Post)) - { - Abbrechen - } - - @* - - *@ - + @using(Html.BeginForm("ResetMultiBookingForm", "Main", FormMethod.Post)) + { + Abbrechen + } + + @if(Html.IsInDebugMode()) + { + @Html.Partial("RestoreServiceRecordInputsPartial", Model) + } + } \ No newline at end of file diff --git a/BeWoPlanerMobil/Views/Main/MultiBookingPartial.cshtml b/BeWoPlanerMobil/Views/Main/MultiBookingPartial.cshtml index 5dcb8e666..05a48d2e4 100644 --- a/BeWoPlanerMobil/Views/Main/MultiBookingPartial.cshtml +++ b/BeWoPlanerMobil/Views/Main/MultiBookingPartial.cshtml @@ -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 @@ @* (Mehrfachbuchung) Hilfeplan- und Gruppenauswahl Popup *@ - + @@ -123,10 +126,10 @@ - Hilfepläne - Gruppen + Hilfepläne + Gruppen - + @Html.Partial("MultiBookingScCbRelList", Model) @@ -135,7 +138,7 @@ @* (Mehrfachbuchung) Mitarbeiterauswahl Popup *@ - + @@ -153,16 +156,17 @@ + + @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; - - - - @employee.DetailDescription - - } + + + @employee.DetailDescription + + } + diff --git a/BeWoPlanerMobil/Views/Main/MultiBookingScCbRelList.cshtml b/BeWoPlanerMobil/Views/Main/MultiBookingScCbRelList.cshtml index 7b12bd741..2eb7aad90 100644 --- a/BeWoPlanerMobil/Views/Main/MultiBookingScCbRelList.cshtml +++ b/BeWoPlanerMobil/Views/Main/MultiBookingScCbRelList.cshtml @@ -12,7 +12,7 @@ } } - + @foreach(var cb2Sc in Model.SupportConceptListObjectsForGroupBooking) { @@ -41,7 +41,7 @@ } - + @foreach(var group in Model.GroupOfPeopleListItems) { diff --git a/BeWoPlanerMobil/Views/Main/MultiBookingSelectionPartial.cshtml b/BeWoPlanerMobil/Views/Main/MultiBookingSelectionPartial.cshtml index de52093b3..baddcc70b 100644 --- a/BeWoPlanerMobil/Views/Main/MultiBookingSelectionPartial.cshtml +++ b/BeWoPlanerMobil/Views/Main/MultiBookingSelectionPartial.cshtml @@ -15,7 +15,7 @@ @* (Mehrfachbuchung) Hilfeplanauswahl-Button *@ - Hilfepläne und Gruppen hinzufügen + Hilfepläne und Gruppen hinzufügen @@ -57,8 +57,8 @@ - - Mitarbeiter hinzufügen @Model.GroupBookingSelectedEmployees.Count + + Mitarbeiter hinzufügen @Model.GroupBookingSelectedEmployees.Count diff --git a/BeWoPlanerMobil/Views/Main/RestoreServiceRecordInputsPartial.cshtml b/BeWoPlanerMobil/Views/Main/RestoreServiceRecordInputsPartial.cshtml new file mode 100644 index 000000000..a1565f9ab --- /dev/null +++ b/BeWoPlanerMobil/Views/Main/RestoreServiceRecordInputsPartial.cshtml @@ -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) +{ + + + +} + + + +@using(Html.BeginForm("RestoreServiceRecordForm", "Main", FormMethod.Post, new {id="restore-service-record-form"})) +{ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/BeWoPlanerMobil/Views/Main/SingleBookingPartial.cshtml b/BeWoPlanerMobil/Views/Main/SingleBookingPartial.cshtml index 7856a464e..7ee552ecb 100644 --- a/BeWoPlanerMobil/Views/Main/SingleBookingPartial.cshtml +++ b/BeWoPlanerMobil/Views/Main/SingleBookingPartial.cshtml @@ -5,7 +5,7 @@ @model MainModel @{ - if(TempData[TempDataConstants.DoLogoutKey] is bool doLogout && doLogout) + if(TempData[TempDataConstants.DoLogoutKey] is bool and true) { - - @@ -100,98 +98,6 @@ diff --git a/ReportImp/PariSozialGzMigranten/Reporting/Reports/SettlementReport2.Designer.cs b/ReportImp/PariSozialGzMigranten/Reporting/Reports/SettlementReport2.Designer.cs index c7bc05871..017e1b8da 100644 --- a/ReportImp/PariSozialGzMigranten/Reporting/Reports/SettlementReport2.Designer.cs +++ b/ReportImp/PariSozialGzMigranten/Reporting/Reports/SettlementReport2.Designer.cs @@ -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; } } \ No newline at end of file diff --git a/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater.sln b/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater.sln new file mode 100644 index 000000000..681783e94 --- /dev/null +++ b/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater.sln @@ -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 diff --git a/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater/App.config b/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater/App.config new file mode 100644 index 000000000..128152c7a --- /dev/null +++ b/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater/App.config @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater/BeWoDatabaseUpdater.csproj b/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater/BeWoDatabaseUpdater.csproj new file mode 100644 index 000000000..01232a757 --- /dev/null +++ b/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater/BeWoDatabaseUpdater.csproj @@ -0,0 +1,134 @@ + + + + + Debug + AnyCPU + {C9F91B7A-0317-44C5-A747-05E3E3ED540B} + Exe + BeWoDatabaseUpdater + BeWoDatabaseUpdater + v4.8.1 + 512 + true + true + 13 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + x64 + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\BouncyCastle.Cryptography.2.6.1\lib\net461\BouncyCastle.Cryptography.dll + + + ..\packages\Google.Protobuf.3.31.1\lib\net45\Google.Protobuf.dll + + + ..\packages\K4os.Compression.LZ4.1.3.8\lib\net462\K4os.Compression.LZ4.dll + + + ..\packages\K4os.Compression.LZ4.Streams.1.3.8\lib\net462\K4os.Compression.LZ4.Streams.dll + + + ..\packages\K4os.Hash.xxHash.1.0.8\lib\net462\K4os.Hash.xxHash.dll + + + ..\packages\Microsoft.Bcl.AsyncInterfaces.9.0.6\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll + + + ..\packages\MySql.Data.9.3.0\lib\net48\MySql.Data.dll + + + + ..\packages\System.Buffers.4.6.1\lib\net462\System.Buffers.dll + + + + ..\packages\System.Configuration.ConfigurationManager.9.0.6\lib\net462\System.Configuration.ConfigurationManager.dll + + + + ..\packages\System.Diagnostics.DiagnosticSource.9.0.6\lib\net462\System.Diagnostics.DiagnosticSource.dll + + + ..\packages\System.IO.Pipelines.9.0.6\lib\net462\System.IO.Pipelines.dll + + + ..\packages\System.Memory.4.6.3\lib\net462\System.Memory.dll + + + + ..\packages\System.Numerics.Vectors.4.6.1\lib\net462\System.Numerics.Vectors.dll + + + ..\packages\System.Runtime.CompilerServices.Unsafe.6.1.2\lib\net462\System.Runtime.CompilerServices.Unsafe.dll + + + ..\packages\System.Threading.Tasks.Extensions.4.6.3\lib\net462\System.Threading.Tasks.Extensions.dll + + + + + + ..\packages\ZstdSharp.Port.0.8.5\lib\net462\ZstdSharp.dll + + + + + + + + + + + + + + + + + + False + Microsoft .NET Framework 4.8.1 %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + + + + \ No newline at end of file diff --git a/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater/Extensions/DictionaryExtensions.cs b/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater/Extensions/DictionaryExtensions.cs new file mode 100644 index 000000000..d0bd48728 --- /dev/null +++ b/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater/Extensions/DictionaryExtensions.cs @@ -0,0 +1,61 @@ +using System.Collections.Generic; +using System.Linq; + +namespace BeWoDatabaseUpdater.Extensions +{ + public static class DictionaryExtensions + { + public static IDictionary> AddOrUpdateValueInDictionary(this IDictionary> dictionary, T key, List value) + { + if(false == dictionary.ContainsKey(key)) + { + dictionary.Add(key, value); + } + else + { + dictionary[key] = dictionary[key].Union(value).ToList(); + } + + return dictionary; + } + + public static IDictionary> AddOrUpdateValueInDictionary(this IDictionary> 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(this IDictionary dictionary, T key, U value) + { + if(dictionary.ContainsKey(key)) + { + return; + } + + dictionary.Add(key, value); + } + + public static void AddAndIgnoreDuplicates(this IDictionary dictionary, IEnumerable> dictionary2Add) + { + dictionary2Add.Where(kvp => false == dictionary.ContainsKey(kvp.Key)).DoForEach(dictionary.Add); + } + + public static bool ContainsValueAtKey(this IDictionary> dictionary, T key, U value) + { + return dictionary.ContainsKey(key) && (dictionary[key]?.Contains(value) ?? false); + } + + public static void AddOrUpdate(this IDictionary dictionary, T key, U value) + { + dictionary[key] = value; + } + } +} diff --git a/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater/Extensions/EnumerableTExtensions.cs b/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater/Extensions/EnumerableTExtensions.cs new file mode 100644 index 000000000..364a4e1a7 --- /dev/null +++ b/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater/Extensions/EnumerableTExtensions.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace BeWoDatabaseUpdater.Extensions +{ + public static class EnumerableTExtensions + { + public static IEnumerable DoForEach(this IEnumerable enumerable, Action action) + { + var list = enumerable as IList ?? enumerable.ToList(); + + foreach(var item in list) + { + action(item); + } + + return list; + } + + public static int IndexOf(this IEnumerable list, T item) + { + var counter = 0; + + foreach(var listItem in list) + { + if(listItem.Equals(item)) + { + return counter; + } + + counter++; + } + + return -1; + } + } +} diff --git a/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater/Extensions/ListTExtensions.cs b/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater/Extensions/ListTExtensions.cs new file mode 100644 index 000000000..e2f7cf3c1 --- /dev/null +++ b/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater/Extensions/ListTExtensions.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace BeWoDatabaseUpdater.Extensions +{ + public static class ListTExtensions + { + public static void AddIfNotIn(this IList list, T item) + { + if(list.Contains(item)) + { + return; + } + + list.Add(item); + } + + public static void AddRange(this IList list, IEnumerable items) + { + foreach(var item in items) + { + list.Add(item); + } + } + + public static void AddRangeIfNotIn(this IList list, IEnumerable items) + { + foreach(var item in items) + { + list.AddIfNotIn(item); + } + } + + public static bool Exists(this IList list, Predicate match) + { + return list.Any(item => match(item)); + } + + public static void RemoveRange(this IList list, IEnumerable items) + { + foreach(var item in items.ToList()) + { + list.Remove(item); + } + } + + public static void RemoveRange(this IList list, Predicate match) + { + var items = list.Where(t => match(t)).ToList(); + + list.RemoveRange(items); + } + } +} diff --git a/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater/Extensions/TimeSpanExtensions.cs b/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater/Extensions/TimeSpanExtensions.cs new file mode 100644 index 000000000..0b115d3e2 --- /dev/null +++ b/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater/Extensions/TimeSpanExtensions.cs @@ -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}"; + } + } +} diff --git a/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater/Program.cs b/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater/Program.cs new file mode 100644 index 000000000..059914446 --- /dev/null +++ b/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater/Program.cs @@ -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 _FilePaths2Sql = []; + private static List _FilePaths = []; + private static List _BeWoSchemaNames = []; + private static readonly List _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(); + + 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(); + + 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 commands) + { + public string FilePath { get; set; } = filePath; + public List Commands { get; set; } = commands ?? []; + } + + public class MySqlHelper + { + public string ConnectionString { get; set; } + + private readonly MySqlConnection _Connection; + + public async Task> LoadBeWoDatabaseNames() + { + var connection = new MySqlConnection(ConnectionString); + + var result = new List(); + + 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 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); + } + } + } +} diff --git a/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater/Properties/AssemblyInfo.cs b/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..b0471a979 --- /dev/null +++ b/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater/Properties/AssemblyInfo.cs @@ -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")] diff --git a/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater/Utils.cs b/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater/Utils.cs new file mode 100644 index 000000000..d6a1459dd --- /dev/null +++ b/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater/Utils.cs @@ -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; + } + } +} diff --git a/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater/packages.config b/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater/packages.config new file mode 100644 index 000000000..f968922a7 --- /dev/null +++ b/Tools/BeWoDatabaseUpdater/BeWoDatabaseUpdater/packages.config @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file