From 1469063ad772592fc34d6cd21a107675a99d24f2 Mon Sep 17 00:00:00 2001 From: Developer01 Date: Wed, 18 Mar 2026 15:31:59 +0100 Subject: [PATCH] Zu testen bei ewa --- .../Classes/ClassDocGrid.vb | 134 +++---- .../Classes/ClassHelper.vb | 178 +++++---- app/DD-Record-Organizer/Log_ewa.txt | Bin 0 -> 153702 bytes app/DD-Record-Organizer/OrgFlow.vbproj | 1 + app/DD-Record-Organizer/frmNodeNavigation.vb | 48 ++- app/DD-Record-Organizer/frmWM_IndexFile.resx | 114 ++++-- app/DD-Record-Organizer/frmWM_IndexFile.vb | 378 +++++++++++++++--- 7 files changed, 589 insertions(+), 264 deletions(-) create mode 100644 app/DD-Record-Organizer/Log_ewa.txt diff --git a/app/DD-Record-Organizer/Classes/ClassDocGrid.vb b/app/DD-Record-Organizer/Classes/ClassDocGrid.vb index 809cdf2..b1cff46 100644 --- a/app/DD-Record-Organizer/Classes/ClassDocGrid.vb +++ b/app/DD-Record-Organizer/Classes/ClassDocGrid.vb @@ -274,11 +274,20 @@ Public Class ClassDocGrid End If End If End Sub - Public Shared Sub FillColumns(pDocGridView As GridView, - DT_RESULT As DataTable, DT_WINDREAM_RESULTLIST As DataTable, DT_DOCRESULT_DROPDOWN_ITEMS As DataTable, - DropdownValueChangedHandler As EventHandler, DatepickerValueChangedHandler As EventHandler, TextValueChangedHandler As EventHandler, CheckValueChangedHandler As EventHandler, - SearchType As String, RECORD_ID As Integer) + DT_RESULT As DataTable, DT_WINDREAM_RESULTLIST As DataTable, DT_DOCRESULT_DROPDOWN_ITEMS As DataTable, + DropdownValueChangedHandler As EventHandler, DatepickerValueChangedHandler As EventHandler, TextValueChangedHandler As EventHandler, CheckValueChangedHandler As EventHandler, + SearchType As String, RECORD_ID As Integer) + + ' ── 1. KRITISCH: Event-Handler ENTFERNEN vor Neuregistrierung ─────────── + RemoveHandler pDocGridView.MasterRowExpanded, AddressOf gridView_MasterRowExpanded + RemoveHandler pDocGridView.CustomColumnDisplayText, AddressOf gridView_CustomColumnDisplayText + RemoveHandler pDocGridView.FocusedRowChanged, AddressOf GVDoc_Values_FocusedRowChanged + + ' ── 2. DATE_COLUMNS Listen leeren (verhindert Duplikate) ──────────────── + DATE_COLUMNS.Clear() + DATE_COLUMNS_CONFIG.Clear() + ' Handler speichern _dropdownValueChangedHandler = DropdownValueChangedHandler _datepickerValueChangedHandler = DatepickerValueChangedHandler @@ -299,7 +308,6 @@ Public Class ClassDocGrid Dim columnTitle As String = row.Item("HEADER_CAPTION") Dim type As Integer = row.Item("TYPE_ID") - If type = 3 And isConfig = False Then DATE_COLUMNS.Add(columnTitle) ElseIf type = 3 And isConfig = True Then @@ -329,13 +337,13 @@ Public Class ClassDocGrid DT_DETAIL_VALUES = ClassDataCache.GetOrLoad(cacheKey, Function() Dim sql = String.Format( - "SELECT T.[GUID],T.[DocID],T.[CONFIG_ID],T1.HEADER_CAPTION,T.[VALUE],T1.[LANGUAGE], " & - "T1.COLUMN_VIEW,T1.EDITABLE,T1.TYPE_ID,T1.VISIBLE,T.CHANGED_WHEN,T.CHANGED_WHO " & - "FROM TBPMO_DOC_VALUES T " & - "INNER JOIN TBPMO_STRUCTURE_NODES_USER_TEMP TTEMP ON T.RECORD_ID = TTEMP.RECORD_ID " & - "RIGHT JOIN TBPMO_DOCSEARCH_RESULTLIST_CONFIG T1 ON T.CONFIG_ID = T1.GUID " & - "WHERE T1.ENTITY_ID = {0} AND LANGUAGE = '{1}' AND T1.CONFIG_COLUMNS = 1", - CURRENT_ENTITY_ID, USER_LANGUAGE) + "SELECT T.[GUID],T.[DocID],T.[CONFIG_ID],T1.HEADER_CAPTION,T.[VALUE],T1.[LANGUAGE], " & + "T1.COLUMN_VIEW,T1.EDITABLE,T1.TYPE_ID,T1.VISIBLE,T.CHANGED_WHEN,T.CHANGED_WHO " & + "FROM TBPMO_DOC_VALUES T " & + "INNER JOIN TBPMO_STRUCTURE_NODES_USER_TEMP TTEMP ON T.RECORD_ID = TTEMP.RECORD_ID " & + "RIGHT JOIN TBPMO_DOCSEARCH_RESULTLIST_CONFIG T1 ON T.CONFIG_ID = T1.GUID " & + "WHERE T1.ENTITY_ID = {0} AND LANGUAGE = '{1}' AND T1.CONFIG_COLUMNS = 1", + CURRENT_ENTITY_ID, USER_LANGUAGE) Return MYDB_ECM.GetDatatable(sql) End Function, TimeSpan.FromMinutes(2)) @@ -344,12 +352,12 @@ Public Class ClassDocGrid DT_DETAIL_VALUES = ClassDataCache.GetOrLoad(cacheKey, Function() Dim sql = String.Format( - "SELECT T.[GUID],T.[DocID],T.[CONFIG_ID],T1.HEADER_CAPTION,T.[VALUE],T1.[LANGUAGE], " & - "T1.COLUMN_VIEW,T1.EDITABLE,T1.TYPE_ID,T1.VISIBLE,T.CHANGED_WHEN,T.CHANGED_WHO " & - "FROM TBPMO_DOC_VALUES T " & - "RIGHT JOIN TBPMO_DOCSEARCH_RESULTLIST_CONFIG T1 ON T.CONFIG_ID = T1.GUID " & - "WHERE T1.ENTITY_ID = {0} AND LANGUAGE = '{1}' AND T1.CONFIG_COLUMNS = 1 AND T.RECORD_ID = {2}", - CURRENT_ENTITY_ID, USER_LANGUAGE, RECORD_ID) + "SELECT T.[GUID],T.[DocID],T.[CONFIG_ID],T1.HEADER_CAPTION,T.[VALUE],T1.[LANGUAGE], " & + "T1.COLUMN_VIEW,T1.EDITABLE,T1.TYPE_ID,T1.VISIBLE,T.CHANGED_WHEN,T.CHANGED_WHO " & + "FROM TBPMO_DOC_VALUES T " & + "RIGHT JOIN TBPMO_DOCSEARCH_RESULTLIST_CONFIG T1 ON T.CONFIG_ID = T1.GUID " & + "WHERE T1.ENTITY_ID = {0} AND LANGUAGE = '{1}' AND T1.CONFIG_COLUMNS = 1 AND T.RECORD_ID = {2}", + CURRENT_ENTITY_ID, USER_LANGUAGE, RECORD_ID) Return MYDB_ECM.GetDatatable(sql) End Function, TimeSpan.FromMinutes(2)) End Select @@ -374,9 +382,6 @@ Public Class ClassDocGrid If oFlteredRows.Length > 0 Then value = oFlteredRows(0)("VALUE").ToString() End If - - - 'value = MYDB_ECM.GetScalarValue(String.Format("SELECT VALUE FROM TBPMO_DOC_VALUES WHERE CONFIG_ID = {0} AND DocID = {1} AND RECORD_ID = {2}", oConfigID, oDocID, RECORD_ID)) Catch ex As Exception LOGGER.Warn(String.Format("Attention: Could not get Value from TBPMO_DOC_VALUES for ConfigId[{0}], DocId[{1}]: ", oConfigID, oDocID) & ex.Message) End Try @@ -389,6 +394,7 @@ Public Class ClassDocGrid LOGGER.Warn($"Attention: Could not load values from TBPMO_DOC_VALUES: " & ex.Message & vbNewLine & $"SELECT VALUE FROM TBPMO_DOC_VALUES WHERE CONFIG_ID = {oConfigID} AND DocID = {oDocID} AND RECORD_ID = {RECORD_ID}") End Try LOGGER.Debug("Values loaded...") + Try ' Tabellen zum DataSet hinzufügen ds.Tables.Add(DT_RESULT) @@ -422,24 +428,26 @@ Public Class ClassDocGrid Dim gridControl As GridControl = pDocGridView.GridControl - - ' ── Performance-optimiertes DataSource-Setzen ───────────────────────── + ' ── 3. KRITISCH: Performance-optimiertes DataSource-Setzen ─────────── _isGridRefreshing = True ' Flag setzen VOR DataSource-Änderung Try pDocGridView.BeginDataUpdate() ' Events unterdrücken + pDocGridView.BeginUpdate() ' UI-Updates unterdrücken ' Datasource auf Master-Tabelle setzen gridControl.DataSource = ds.Tables(0) gridControl.ForceInitialize() - pDocGridView.EndDataUpdate() ' Events reaktivieren + pDocGridView.EndUpdate() ' UI-Updates reaktivieren + pDocGridView.EndDataUpdate() ' Events reaktivieren + Catch ex As Exception + LOGGER.Error($"Error setting DataSource: {ex.Message}") Finally - _isGridRefreshing = False ' Flag zurücksetzen + ' Flag NICHT hier zurücksetzen - erst NACH allen Grid-Operationen! End Try ' Detail View anlegen und der Relation `docIdDetails` zuweisen Dim GVDoc_Values As New GridView(gridControl) - 'grvwDetail.OptionsBehavior.Editable = False GVDoc_Values.OptionsView.ShowGroupPanel = False GVDoc_Values.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.Style3D GVDoc_Values.OptionsView.EnableAppearanceEvenRow = True @@ -447,18 +455,17 @@ Public Class ClassDocGrid GVDoc_Values.Appearance.HeaderPanel.BackColor = Color.Orange GVDoc_Values.Appearance.HeaderPanel.Options.UseBackColor = True - gridControl.LevelTree.Nodes.Add("docIdDetails", GVDoc_Values) Catch ex As Exception MsgBox("Error in FillColumns: " & vbNewLine & ex.Message, MsgBoxStyle.Critical) LOGGER.Warn("Attention: Could not load converted datatable DocSearch: " & ex.Message) End Try + ' ── 4. KRITISCH: Handler NACH DataSource-Setzen registrieren ───────────── AddHandler pDocGridView.MasterRowExpanded, AddressOf gridView_MasterRowExpanded AddHandler pDocGridView.CustomColumnDisplayText, AddressOf gridView_CustomColumnDisplayText AddHandler pDocGridView.FocusedRowChanged, AddressOf GVDoc_Values_FocusedRowChanged - For Each row As DataRow In DT_WINDREAM_RESULTLIST.Rows Dim col As GridColumn = pDocGridView.Columns(row.Item("HEADER_CAPTION")) Dim colCaption = row.Item("HEADER_CAPTION") @@ -501,18 +508,22 @@ Public Class ClassDocGrid oChangedColumn.DisplayFormat.FormatString = CURRENT_DATE_FORMAT & " HH:MM:ss" End If + ' ── 5. BestFitColumns mit gesetztem Flag ────────────────────────────────── If GridDocResult_BestFitColumns Then - _isGridRefreshing = True ' Auch hier Events unterdrücken + ' _isGridRefreshing ist bereits True Try pDocGridView.BeginUpdate() pDocGridView.OptionsView.BestFitMaxRowCount = -1 pDocGridView.BestFitColumns(True) pDocGridView.EndUpdate() - Finally - _isGridRefreshing = False + Catch ex As Exception + LOGGER.Error($"Error in BestFitColumns: {ex.Message}") End Try End If + ' ── 6. KRITISCH: Flag ERST JETZT zurücksetzen! ──────────────────────────── + _isGridRefreshing = False + ' Alle Spalten aus ReadOnly setzen, danach werden alle passenden auf nicht ReadOnly gesetzt For Each column As GridColumn In pDocGridView.Columns column.OptionsColumn.AllowEdit = False @@ -623,69 +634,54 @@ Public Class ClassDocGrid End If Dim fieldName As String = e.Column.FieldName + Dim valueString As String = e.Value.ToString() + + ' ── WICHTIG: Verhindere rekursive Aufrufe ──────────────────────────── + ' Wenn DisplayText bereits korrekt ist, nichts ändern + If e.DisplayText = valueString Then Return + Dim parsedDate As DateTime ' ── Datumskonvertierung für Standard-Datumsspalten ─────────────────── If DATE_COLUMNS IsNot Nothing AndAlso DATE_COLUMNS.Contains(fieldName) Then - ' Nur bei Verbose-Logging loggen - If EnableVerboseGridLogging Then - LOGGER.Debug($"gridView_CustomColumnDisplayText [Standard] [{fieldName}]") - End If - Try - ' Versuche direktes Parsen - If DateTime.TryParse(e.Value.ToString(), parsedDate) Then - e.DisplayText = parsedDate.ToString(CURRENT_DATE_FORMAT & " HH:mm:ss") - Else - ' Fallback: ParseExact - parsedDate = DateTime.ParseExact(e.Value.ToString(), - CURRENT_DATE_FORMAT & " HH:mm:ss", - System.Globalization.DateTimeFormatInfo.InvariantInfo) - e.DisplayText = parsedDate.ToString(CURRENT_DATE_FORMAT & " HH:mm:ss") + If DateTime.TryParse(valueString, parsedDate) Then + Dim formattedDate As String = parsedDate.ToString(CURRENT_DATE_FORMAT & " HH:mm:ss") + ' Nur setzen wenn unterschiedlich + If e.DisplayText <> formattedDate Then + e.DisplayText = formattedDate + End If End If Catch ex As FormatException - ' Bei Parsing-Fehler Original-Wert anzeigen - e.DisplayText = e.Value.ToString() + ' Bei Fehler Original-Wert belassen (NICHT setzen!) If EnableVerboseGridLogging Then - LOGGER.Debug($"Date parsing failed for [{fieldName}]: {e.Value}") + LOGGER.Debug($"Date parsing failed for [{fieldName}]: {valueString}") End If End Try - - Return ' Früher Exit - keine weitere Prüfung nötig + Return End If ' ── Datumskonvertierung für Config-Datumsspalten ────────────────────── If DATE_COLUMNS_CONFIG IsNot Nothing AndAlso DATE_COLUMNS_CONFIG.Contains(fieldName) Then - ' Nur bei Verbose-Logging loggen - If EnableVerboseGridLogging Then - LOGGER.Debug($"gridView_CustomColumnDisplayText [Config] [{fieldName}]") - End If - Try - ' Versuche direktes Parsen - If DateTime.TryParse(e.Value.ToString(), parsedDate) Then - e.DisplayText = parsedDate.ToString(CURRENT_DATE_FORMAT) - Else - ' Fallback: ParseExact - parsedDate = DateTime.ParseExact(e.Value.ToString(), - CURRENT_DATE_FORMAT, - System.Globalization.DateTimeFormatInfo.InvariantInfo) - e.DisplayText = parsedDate.ToString(CURRENT_DATE_FORMAT) + If DateTime.TryParse(valueString, parsedDate) Then + Dim formattedDate As String = parsedDate.ToString(CURRENT_DATE_FORMAT) + ' Nur setzen wenn unterschiedlich + If e.DisplayText <> formattedDate Then + e.DisplayText = formattedDate + End If End If Catch ex As FormatException - ' Bei Parsing-Fehler Original-Wert anzeigen - e.DisplayText = e.Value.ToString() + ' Bei Fehler Original-Wert belassen If EnableVerboseGridLogging Then - LOGGER.Debug($"Date parsing failed for [{fieldName}]: {e.Value}") + LOGGER.Debug($"Date parsing failed for [{fieldName}]: {valueString}") End If End Try End If Catch ex As Exception - ' Fehler IMMER loggen (aber nicht Debug) LOGGER.Error($"gridView_CustomColumnDisplayText Error [{e.Column?.FieldName}]: {ex.Message}") End Try - End Sub Public Shared Sub GVDoc_Values_FocusedRowChanged(sender As GridView, e As DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs) Try diff --git a/app/DD-Record-Organizer/Classes/ClassHelper.vb b/app/DD-Record-Organizer/Classes/ClassHelper.vb index 70000fb..dfc0534 100644 --- a/app/DD-Record-Organizer/Classes/ClassHelper.vb +++ b/app/DD-Record-Organizer/Classes/ClassHelper.vb @@ -301,68 +301,7 @@ Public Class ClassHelper End Try End Try End Sub - 'Private Shared Sub BWFileHandler_DoWork() - ' Try - ' Dim oOverrideRunPath As String = "" - ' Dim oExtension = Path.GetExtension(BW_DocPath).ToLower - ' For Each oROW As DataRow In CURRENT_TBFILE_EXTENSION_OVERRIDE.Rows - ' If oExtension.Replace(".", "") = oROW.Item("FILE_EXTENSION") Then - ' LOGGER.Debug($"Specific fileextension override for extension [{oExtension}] found! ") - ' oOverrideRunPath = oROW.Item("PROCESS") - ' End If - ' Next - ' Dim oMyProcess = New Process() - ' Dim oSql - ' Try - ' '###### - ' Dim startInfo As New ProcessStartInfo() - ' If oOverrideRunPath <> "" Then - ' startInfo.FileName = oOverrideRunPath - ' startInfo.Arguments = """" & BW_DocPath & """" - ' startInfo.UseShellExecute = True - ' startInfo.RedirectStandardOutput = False - ' Else - ' startInfo.FileName = BW_DocPath - ' startInfo.UseShellExecute = True - ' startInfo.RedirectStandardOutput = False - ' End If - ' '##### - ' oMyProcess.Start(startInfo) - ' Dim myViewerProcessID = oMyProcess.Id - ' oMyProcess.WaitForExit() - ' oExtension = Path.GetExtension(BW_DocPath).ToLower - ' LOGGER.Debug($"Checking oExtension [{oExtension}]...") - ' If FILE_FORMATS_CHANGE_DURING_EDIT.Contains(oExtension) Then - ' oSql = $"SELECT * FROM VWOF_DOCID_HANDLE WHERE dwParentID = {BW_ParentID} and [Filename] = '{BW_Filename}'" - ' Dim oDTNEWDoc As DataTable = MYDB_ECM.GetDatatable(oSql) - - ' If Not IsNothing(oDTNEWDoc) Then - ' If oDTNEWDoc.Rows.Count = 1 Then - - ' Dim oInsert = $"INSERT INTO TBPMO_DOC_ID_CHANGED (USER_ID,PROCESS_ID,VERSION_ID,OLD_DOC_ID,NEW_DOC_ID, DOC_PATH) VALUES ( - ' {USER_GUID},'{myViewerProcessID.ToString}',{oDTNEWDoc.Rows(0).Item("dwVersionID")},{BW_DocID},{oDTNEWDoc.Rows(0).Item("NewDocID")}, '{BW_DocPath}')" - ' MYDB_ECM.ExecuteNonQuery(oInsert) - ' End If - - - ' End If - ' End If - - ' Catch ex As Exception - ' LOGGER.Warn("Error in Process1.Start(): " & ex.Message & vBCrlf & " - Path: " & BW_DocPath & " - DocID: " & BW_DocID) - ' MsgBox("Error in OpenFile: " & ex.Message & vBCrlf & " - Path: " & BW_DocPath & " - DocID: " & BW_DocID, MsgBoxStyle.Exclamation) - ' Exit Sub - ' End Try - - ' Catch ex As Exception - ' LOGGER.Warn("Error in Process.Start(): " & ex.Message & vBCrlf & " - Path: " & BW_DocPath & " - DocID: " & BW_DocID) - ' Try - ' Process.Start(BW_DocPath) - ' Catch ex1 As Exception - ' LOGGER.Warn("Error in Process.Start(1): " & ex1.Message & vBCrlf & " - Path: " & BW_DocPath & " - DocID: " & BW_DocID) - ' End Try - ' End Try - 'End Sub + Private Shared Sub FOLDER_OPEN(PATH As Object, DocID As String) Try If PATH <> Nothing Then @@ -461,12 +400,35 @@ Public Class ClassHelper End Function Public Shared Sub REMOVE_OLD_DROP_FILES() Try + ' ✅ NEU: Pre-Check - welche Dateien sind betroffen? + Dim preCheckSQL = $"SELECT GUID, FILENAME_ONLY, ADDED_WHEN, DATEDIFF(MINUTE, ADDED_WHEN, GETDATE()) AS AGE_MINUTES " & + $"FROM TBPMO_FILES_USER " & + $"WHERE ADDED_WHEN < DATEADD(MINUTE, -15, GETDATE()) " & + $"AND WORKED = 0 AND USER_WORK = '{USER_USERNAME}'" + + Dim preCheckDT = MYDB_ECM.GetDatatable(preCheckSQL) + + If preCheckDT IsNot Nothing AndAlso preCheckDT.Rows.Count > 0 Then + LOGGER.Warn($"REMOVE_OLD_DROP_FILES: {preCheckDT.Rows.Count} Dateien werden als TIMEOUT markiert:") + For Each row As DataRow In preCheckDT.Rows + LOGGER.Warn($" - GUID={row("GUID")}, Datei={row("FILENAME_ONLY")}, Alter={row("AGE_MINUTES")} Minuten") + Next + Else + LOGGER.Debug($"REMOVE_OLD_DROP_FILES: Keine Dateien älter als 15 Minuten (User: {USER_USERNAME})") + End If + + ' ✅ Dann UPDATE Dim oDEL = String.Format("UPDATE [DD_ECM].[dbo].[TBPMO_FILES_USER] - SET [USER_WORK] = [USER_WORK] + '_TIMEOUT', - WORKED = 1 - WHERE ADDED_WHEN < DATEADD(MINUTE, -5, GETDATE()) - AND WORKED = 0 AND USER_WORK = '{0}' ;", USER_USERNAME) - MYDB_ECM.ExecuteNonQuery(oDEL) + SET [USER_WORK] = [USER_WORK] + '_TIMEOUT', + WORKED = 1 + WHERE ADDED_WHEN < DATEADD(MINUTE, -15, GETDATE()) + AND WORKED = 0 AND USER_WORK = '{0}' ;", USER_USERNAME) + + Dim rowsAffected = MYDB_ECM.ExecuteNonQuery(oDEL) + + If rowsAffected > 0 Then + LOGGER.Warn($"REMOVE_OLD_DROP_FILES: {rowsAffected} Dateien wurden als TIMEOUT markiert") + End If Catch ex As Exception MsgBox(ex.Message, MsgBoxStyle.Critical, "Unexpected error while REMOVE_OLD_DROP_FILES") End Try @@ -475,7 +437,19 @@ Public Class ClassHelper Try Dim sql = String.Format("SELECT *, CONVERT(BIT,0) AS DELETE_FILE FROM TBPMO_FILES_USER WHERE (USER_WORK = '{0}') AND WORKED = 0", USER_USERNAME) CURRENT_TBPMO_FILES_USER = MYDB_ECM.GetDatatable(sql) + ' ✅ NEU: Logging + If CURRENT_TBPMO_FILES_USER Is Nothing Then + LOGGER.Warn($"Create_USER_FILE_TABLE: GetDatatable gab Nothing zurück (User: {USER_USERNAME})") + Else + LOGGER.Debug($"Create_USER_FILE_TABLE: {CURRENT_TBPMO_FILES_USER.Rows.Count} Dateien geladen (User: {USER_USERNAME})") + + ' ✅ DEBUG: Zeige GUIDs der geladenen Dateien + For Each row As DataRow In CURRENT_TBPMO_FILES_USER.Rows + LOGGER.Debug($" - GUID={row("GUID")}, WORKED={row("WORKED")}, Datei={row("FILENAME2WORK")}") + Next + End If Catch ex As Exception + LOGGER.Error($"Create_USER_FILE_TABLE Exception: {ex.Message}") MsgBox(ex.Message, MsgBoxStyle.Critical, "Unexpected error while creating User_File_Table") End Try End Sub @@ -551,9 +525,11 @@ Public Class ClassHelper Else LOGGER.Warn($"File does not exist: [{pFilename}] - Cannot compute hash.") End If + Dim oSQL = $"SELECT Filename, ADDED_WHO, FORMAT(ADDED_WHEN, 'dd-MM-yyyy HH:mm') AS ADDED_WHEN_STRING FROM TBPMO_DOCRESULT_LIST WHERE FILE_HASH = '{CURRENT_FILE_HASH}' ORDER BY ADDED_WHEN DESC" LOGGER.Debug($"Inserting File - hash is [{CURRENT_FILE_HASH}]") Dim oDTCHECK As DataTable = MYDB_ECM.GetDatatable(oSQL) + If Not IsNothing(oDTCHECK) Then If oDTCHECK.Rows.Count >= 1 Then LOGGER.Info($"We got a file with the same hash [{CURRENT_FILE_HASH}]") @@ -561,34 +537,74 @@ Public Class ClassHelper Dim oUSER = oDTCHECK.Rows(0).Item(1) Dim oADDED_WHEN = oDTCHECK.Rows(0).Item(2) Dim oMSG As String + If USER_LANGUAGE <> "de-DE" Then oMSG = $"This file has already been imported into orgFLOW!" & vbCrLf & - $"File: [{oFilename}]" & vbCrLf & - $"Imported on: {oADDED_WHEN}" & vbCrLf & - $"Imported by: {oUSER}" & vbCrLf & - $"Total imports with identical content: {oDTCHECK.Rows.Count}" & vbCrLf & vbCrLf & - "Do you want to import this file again?" & vbCrLf & - "NO → Teh complete Import will be cancelled." + $"File: [{oFilename}]" & vbCrLf & + $"Imported on: {oADDED_WHEN}" & vbCrLf & + $"Imported by: {oUSER}" & vbCrLf & + $"Total imports with identical content: {oDTCHECK.Rows.Count}" & vbCrLf & vbCrLf & + "Do you want to import this file again?" & vbCrLf & + "NO → Teh complete Import will be cancelled." Else oMSG = $"Diese Datei wurde bereits in orgFLOW importiert!" & vbCrLf & - $"Datei: [{oFilename}]" & vbCrLf & - $"Importiert am: {oADDED_WHEN}" & vbCrLf & - $"Importiert von: {oUSER}" & vbCrLf & - $"Anzahl Importe mit identischem Inhalt: {oDTCHECK.Rows.Count}" & vbCrLf & vbCrLf & - "Möchten Sie die Datei dennoch erneut importieren?" & vbCrLf & - "NEIN → Der gesamte Import (alle folgenden) wird abgebrochen." + $"Datei: [{oFilename}]" & vbCrLf & + $"Importiert am: {oADDED_WHEN}" & vbCrLf & + $"Importiert von: {oUSER}" & vbCrLf & + $"Anzahl Importe mit identischem Inhalt: {oDTCHECK.Rows.Count}" & vbCrLf & vbCrLf & + "Möchten Sie die Datei dennoch erneut importieren?" & vbCrLf & + "NEIN → Der gesamte Import (alle folgenden) wird abgebrochen." End If + Dim result As MsgBoxResult result = MessageBox.Show(oMSG, CAPTION_CONFIRMATION, MessageBoxButtons.YesNo, MessageBoxIcon.Question) + If result = MsgBoxResult.No Then + LOGGER.Info($"User wählte NEIN bei Hash-Duplikat-Check für [{filename_only}] - Import abgebrochen") Return False + Else + LOGGER.Info($"User wählte JA bei Hash-Duplikat-Check für [{filename_only}] - fahre fort") End If End If End If - Dim ins As String = String.Format("INSERT INTO TBPMO_FILES_USER (FILENAME2WORK, USER_WORK,HANDLE_TYPE,FILENAME_ONLY,FILE_HASH) VALUES ('{0}','{1}','{2}','{3}','{4}')", pFilename, USER_USERNAME, handleType, filename_only, CURRENT_FILE_HASH) - Return MYDB_ECM.ExecuteNonQuery(ins) + ' ✅ NEU: Pre-Check - gibt es bereits einen Eintrag mit diesem Hash? + Dim preCheckSQL = $"SELECT GUID, USER_WORK, WORKED FROM TBPMO_FILES_USER WHERE FILE_HASH = '{CURRENT_FILE_HASH}' AND USER_WORK = '{USER_USERNAME}'" + Dim preCheckDT = MYDB_ECM.GetDatatable(preCheckSQL) + + If preCheckDT IsNot Nothing AndAlso preCheckDT.Rows.Count > 0 Then + LOGGER.Warn($"WARNUNG: Datei mit Hash [{CURRENT_FILE_HASH}] bereits in TBPMO_FILES_USER vorhanden:") + For Each row As DataRow In preCheckDT.Rows + LOGGER.Warn($" - GUID={row("GUID")}, USER_WORK={row("USER_WORK")}, WORKED={row("WORKED")}") + Next + End If + + ' ✅ INSERT mit explizitem Logging + Dim ins As String = String.Format("INSERT INTO TBPMO_FILES_USER (FILENAME2WORK, USER_WORK, HANDLE_TYPE, FILENAME_ONLY, FILE_HASH) VALUES ('{0}','{1}','{2}','{3}','{4}')", pFilename, USER_USERNAME, handleType, filename_only, CURRENT_FILE_HASH) + + LOGGER.Debug($"Führe INSERT aus: [{ins}]") + Dim insertResult = MYDB_ECM.ExecuteNonQuery(ins) + + If insertResult Then + ' ✅ VERIFY - wurde wirklich eingefügt? + Dim verifySQL = $"SELECT TOP 1 GUID, ADDED_WHEN FROM TBPMO_FILES_USER WHERE FILE_HASH = '{CURRENT_FILE_HASH}' AND USER_WORK = '{USER_USERNAME}' ORDER BY GUID DESC" + Dim verifyDT = MYDB_ECM.GetDatatable(verifySQL) + + If verifyDT IsNot Nothing AndAlso verifyDT.Rows.Count > 0 Then + Dim insertedGUID = verifyDT.Rows(0)("GUID") + Dim insertedADDED_WHEN = verifyDT.Rows(0)("ADDED_WHEN") + LOGGER.Info($"INSERT ERFOLGREICH: GUID={insertedGUID}, ADDED_WHEN={insertedADDED_WHEN}, Datei=[{filename_only}]") + Else + LOGGER.Error($"INSERT fehlgeschlagen (VERIFY)! Datei=[{filename_only}], Hash=[{CURRENT_FILE_HASH}]") + End If + Else + LOGGER.Error($"INSERT fehlgeschlagen (ExecuteNonQuery)! Datei=[{filename_only}]") + End If + + Return insertResult + Catch ex As Exception + LOGGER.Error($"Insert_USER_File Exception: {ex.Message}") MsgBox("Unexpected Error in Insert file for user (TBPMO_FILES_USER): " & ex.Message, MsgBoxStyle.Critical) Return False End Try diff --git a/app/DD-Record-Organizer/Log_ewa.txt b/app/DD-Record-Organizer/Log_ewa.txt new file mode 100644 index 0000000000000000000000000000000000000000..1c7a20fb21f7a39d59edecdd8c6caf6874069d92 GIT binary patch literal 153702 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 b>s!%&cl{xq-yJ(cCS`W|oS2zjO-BBI!b6!Y literal 0 HcmV?d00001 diff --git a/app/DD-Record-Organizer/OrgFlow.vbproj b/app/DD-Record-Organizer/OrgFlow.vbproj index 0267fb9..c7c1643 100644 --- a/app/DD-Record-Organizer/OrgFlow.vbproj +++ b/app/DD-Record-Organizer/OrgFlow.vbproj @@ -1717,6 +1717,7 @@ PreserveNewest + diff --git a/app/DD-Record-Organizer/frmNodeNavigation.vb b/app/DD-Record-Organizer/frmNodeNavigation.vb index b5e6aab..9d43d9b 100644 --- a/app/DD-Record-Organizer/frmNodeNavigation.vb +++ b/app/DD-Record-Organizer/frmNodeNavigation.vb @@ -2307,7 +2307,7 @@ Public Class frmNodeNavigation End If End If If CURRENT_RECORD_ID = 0 Then - ClassHelper.MSGBOX_Handler("INFO", "Attention", "Input missing: ", "Please choose a record.") + ClassHelper.MSGBOX_Handler("INFO", "Achtung", "Fokus unklar: ", "Bitte wählen Sie erneut einen Knoten aus!") Exit Sub End If If DROPPED_CHECKED = False Then @@ -2349,30 +2349,44 @@ Public Class frmNodeNavigation End If ClassHelper.REMOVE_OLD_DROP_FILES() ClassHelper.Create_USER_FILE_TABLE() - If Not IsNothing(CURRENT_TBPMO_FILES_USER) Then - If CURRENT_TBPMO_FILES_USER.Rows.Count > 0 Then - For Each Filerow As DataRow In CURRENT_TBPMO_FILES_USER.Rows - If CBool(Filerow.Item("WORKED")) = False Then - 'Dim datei = Str.ToString.Replace("@DROPFROMFSYSTEM@", "") - CURRENT_FILEID = Filerow.Item("GUID") - ' CURRENT_PARENT_ENTITY_ID = PARENT_ENTITYID - 'CURRENT_RECORD_ID = RECORD_ID - 'CURRENT_ENTITY_ID = ENTITY_ID - CURRENT_FORMVIEW_ID = FORMVIEW_ID - frmWM_IndexFile.ShowDialog() - Else + ' ✅ ENDLOS-SCHLEIFE: Solange Dateien vorhanden sind, Formular öffnen + Do While True + ' ✅ Prüfe, ob noch Dateien vorhanden sind + If CURRENT_TBPMO_FILES_USER Is Nothing OrElse CURRENT_TBPMO_FILES_USER.Rows.Count = 0 Then + NNLogger.Info("Keine weiteren Dateien zu verarbeiten - beende Check_Dropped_Files") + Exit Do + End If - End If - Next + ' ✅ Hole die ERSTE unverarbeitete Datei + Dim firstFile = CURRENT_TBPMO_FILES_USER.Rows.Cast(Of DataRow)() _ + .Where(Function(r) CBool(r("WORKED")) = False) _ + .FirstOrDefault() + + If firstFile Is Nothing Then + NNLogger.Info("Alle Dateien wurden verarbeitet - beende Check_Dropped_Files") + Exit Do End If - End If + + ' ✅ Setze globale Variablen + CURRENT_FILEID = CInt(firstFile("GUID")) + CURRENT_FORMVIEW_ID = FORMVIEW_ID + + NNLogger.Debug($"Öffne frmWM_IndexFile für FileId={CURRENT_FILEID}") + + ' ✅ Öffne Formular (kann Multi-Indexing ausführen!) + frmWM_IndexFile.ShowDialog() + + ' ✅ WICHTIG: Lade Dateiliste NEU aus Datenbank! + ClassHelper.Create_USER_FILE_TABLE() + + ' ✅ Schleife läuft weiter, prüft erneut ob Dateien vorhanden sind + Loop Catch ex As Exception NNLogger.Error(ex) ClassHelper.MSGBOX_Handler("ERROR", "Unexpected Error", "Error in Check_Dropped_Files: ", ex.Message) End Try - End Sub Private Async Sub GridControlDocSearch_DragDrop(sender As Object, e As DragEventArgs) Handles GridControlDocSearch.DragDrop Await Drag_Drop(e) diff --git a/app/DD-Record-Organizer/frmWM_IndexFile.resx b/app/DD-Record-Organizer/frmWM_IndexFile.resx index e46c40f..381dec3 100644 --- a/app/DD-Record-Organizer/frmWM_IndexFile.resx +++ b/app/DD-Record-Organizer/frmWM_IndexFile.resx @@ -126,10 +126,10 @@ - 6, 25 + 7, 33 - 62, 15 + 74, 20 5 @@ -160,10 +160,10 @@ True - 428, 25 + 489, 33 - 70, 15 + 86, 20 6 @@ -190,10 +190,10 @@ True - 6, 54 + 7, 72 - 73, 15 + 84, 20 8 @@ -217,10 +217,10 @@ True - 12, 9 + 14, 12 - 61, 15 + 79, 20 0 @@ -244,10 +244,13 @@ Top, Left, Right - 15, 27 + 17, 36 + + + 3, 4, 3, 4 - 574, 23 + 655, 27 1 @@ -271,10 +274,10 @@ Segoe UI Semibold, 9.75pt, style=Bold - 12, 58 + 14, 77 - 188, 17 + 238, 23 2 @@ -298,10 +301,13 @@ Segoe UI Semibold, 9.75pt, style=Bold - 15, 78 + 17, 104 + + + 3, 4, 3, 4 - 203, 25 + 231, 29 3 @@ -340,10 +346,13 @@ MiddleLeft - 431, 444 + 493, 592 + + + 3, 4, 3, 4 - 158, 28 + 181, 37 4 @@ -370,10 +379,13 @@ Top, Left, Right - 85, 22 + 97, 29 + + + 3, 4, 3, 4 - 281, 23 + 321, 27 6 @@ -394,10 +406,13 @@ Top, Left, Right - 85, 51 + 97, 68 + + + 3, 4, 3, 4 - 469, 23 + 535, 27 9 @@ -418,10 +433,13 @@ Top, Right - 504, 22 + 576, 29 + + + 3, 4, 3, 4 - 50, 23 + 57, 27 7 @@ -442,10 +460,16 @@ Segoe UI, 9pt, style=Italic - 15, 117 + 17, 156 + + + 3, 4, 3, 4 + + + 3, 4, 3, 4 - 560, 80 + 640, 107 7 @@ -475,10 +499,13 @@ Verdana, 9.75pt, style=Italic - 24, 450 + 27, 603 + + + 3, 4, 3, 4 - 177, 20 + 226, 24 8 @@ -511,10 +538,13 @@ Verdana, 9.75pt, style=Bold, Italic - 24, 476 + 27, 638 + + + 3, 4, 3, 4 - 519, 20 + 688, 24 9 @@ -547,10 +577,16 @@ Top, Bottom, Left, Right - 15, 203 + 17, 271 + + + 3, 4, 3, 4 + + + 3, 4, 3, 4 - 574, 191 + 656, 255 10 @@ -583,10 +619,10 @@ Segoe UI Semibold, 9pt, style=Bold, Italic - 21, 397 + 24, 529 - 134, 15 + 172, 20 11 @@ -616,10 +652,13 @@ Segoe UI Semibold, 9pt, style=Bold, Italic - 24, 415 + 27, 553 + + + 3, 4, 3, 4 - 551, 24 + 629, 28 12 @@ -643,10 +682,10 @@ True - 7, 15 + 8, 20 - 604, 513 + 690, 684 Segoe UI, 9pt @@ -1100,6 +1139,9 @@ wAH//wAA///AAf//AAD//8AB//8AAP//wAH//wAA///AD///AAD///H///8AAP///////wAA + + 3, 4, 3, 4 + Import nach windream: diff --git a/app/DD-Record-Organizer/frmWM_IndexFile.vb b/app/DD-Record-Organizer/frmWM_IndexFile.vb index 020e74b..235e704 100644 --- a/app/DD-Record-Organizer/frmWM_IndexFile.vb +++ b/app/DD-Record-Organizer/frmWM_IndexFile.vb @@ -41,11 +41,18 @@ Public Class frmWM_IndexFile Function WORK_FILE(ImportFilePath As String, VerzeichnisZiel As String, vDokart_ID As Integer, vDokart As String, multiindex As Boolean) 'Dim swWORK_FILE As New SW("WORK_FILE: " & DOCTYPE_IDTextBox.Text) Try + LOGGER.Debug($" WORK_FILE aufgerufen: CURRENT_FILEID={CURRENT_FILEID}, Datei={Me.txtFilepath.Text}") + LOGGER.Debug($"=== WORK_FILE START: multiindex={multiindex} ===") + LOGGER.Debug($" Datei: {ImportFilePath}") + LOGGER.Debug($" Flags: _multiIndexDecisionMade={_multiIndexDecisionMade}, _multiIndexOverwriteExisting={_multiIndexOverwriteExisting}") + CURRENT_DOC_ID = Nothing Dim odeleteRights As Boolean = True - Dim oSQL = $"SELECT GUID FROM TBPMO_FILES_USER WHERE FILENAME2WORK = '{ImportFilePath}' AND WORKED = 0 AND USER_WORK = '{Environment.UserName}'" - CURRENT_FILEID = MYDB_ECM.GetScalarValue(oSQL) + If CURRENT_FILEID = 0 OrElse CURRENT_FILEID = Nothing Then + LOGGER.Error("WORK_FILE: CURRENT_FILEID ist ungültig (0 oder Nothing)!") + Return False + End If CURRENT_DOKARTSTRING = vDokart Dim err As Boolean = False '################################################################# @@ -64,6 +71,7 @@ Public Class frmWM_IndexFile If multiindex = True Then If _multiIndexDecisionMade = False Then + LOGGER.Debug(" ZEIGE DIALOG für Multi-Index-Entscheidung") ' Erste Kollision → Benutzer fragen Dim msg As String If USER_LANGUAGE <> "de-DE" Then @@ -84,12 +92,16 @@ Public Class frmWM_IndexFile _multiIndexOverwriteExisting = (result = MsgBoxResult.Yes) _multiIndexDecisionMade = True - LOGGER.Info($"Multi-Indexing: User decision for file conflicts = {If(_multiIndexOverwriteExisting, "OVERWRITE", "VERSION")}") + LOGGER.Debug($" Benutzer-Entscheidung: {If(_multiIndexOverwriteExisting, "OVERWRITE", "VERSION")}") + LOGGER.Debug($" Flags NACH Dialog: _multiIndexDecisionMade={_multiIndexDecisionMade}, _multiIndexOverwriteExisting={_multiIndexOverwriteExisting}") + Else + LOGGER.Debug($" Verwende GESPEICHERTE Entscheidung: {If(_multiIndexOverwriteExisting, "OVERWRITE", "VERSION")}") End If shouldOverwrite = _multiIndexOverwriteExisting Else ' Einzeldatei → wie bisher + LOGGER.Debug(" Einzeldatei: Zeige Dialog") Dim msg As String If USER_LANGUAGE <> "de-DE" Then msg = "A file with the same name already exists!" & vbCrLf & @@ -104,10 +116,12 @@ Public Class frmWM_IndexFile Dim result As MsgBoxResult = MessageBox.Show(msg, "File already exists:", MessageBoxButtons.YesNo, MessageBoxIcon.Question) shouldOverwrite = (result = MsgBoxResult.Yes) + LOGGER.Debug($" Einzeldatei-Entscheidung: {If(shouldOverwrite, "OVERWRITE", "VERSION")}") End If ' ── Entscheidung ausführen ──────────────────────────────────── If shouldOverwrite Then + LOGGER.Debug(" Führe OVERWRITE aus") If WMMOD.RemoveFile(CURRENT_NEWFILENAME) = False Then Return False Else @@ -127,8 +141,12 @@ Public Class frmWM_IndexFile Next End If Else + LOGGER.Debug(" Führe VERSIONIERUNG aus") CURRENT_NEWFILENAME = ClassHelper.Versionierung_Datei(CURRENT_NEWFILENAME) + LOGGER.Debug($" Neuer Dateiname: {CURRENT_NEWFILENAME}") End If + Else + LOGGER.Debug(" Datei existiert NICHT, kein Konflikt") End If sw.Done() '################################################################# @@ -291,15 +309,23 @@ Public Class frmWM_IndexFile stg1 = "Success:" End If If multiindex = False Then CURRENT_NOTIFICATION_MSG = stg - MYDB_ECM.GetScalarValue("UPDATE TBPMO_FILES_USER SET WORKED = 1 WHERE GUID = " & CURRENT_FILEID) - For Each row As DataRow In CURRENT_TBPMO_FILES_USER.Rows - If row.Item("GUID") = CURRENT_FILEID Then - row.Item("WORKED") = 1 - If IsNothing(droptype) Then - droptype = row.Item("HANDLE_TYPE") - End If - End If - Next + + ' Neu - NUR wenn NICHT im Multi-Index-Modus: + If multiindex = False Then + MYDB_ECM.ExecuteNonQuery("UPDATE TBPMO_FILES_USER SET WORKED = 1 WHERE GUID = " & CURRENT_FILEID) + LOGGER.Debug($" Einzeldatei als WORKED markiert: GUID={CURRENT_FILEID}") + + ' ✅ DEBUG: Was steht JETZT in der DB? + Dim debugSQL = $"SELECT GUID, WORKED, FILENAME_ONLY FROM TBPMO_FILES_USER WHERE USER_WORK = '{USER_USERNAME}' ORDER BY GUID DESC" + Dim debugDT = MYDB_ECM.GetDatatable(debugSQL) + LOGGER.Debug($" ═══ DEBUG NACH UPDATE ═══") + LOGGER.Debug($" Anzahl Dateien in DB: {debugDT.Rows.Count}") + For Each row As DataRow In debugDT.Rows + LOGGER.Debug($" - GUID={row("GUID")}, WORKED={row("WORKED")}, Datei={row("FILENAME_ONLY")}") + Next + LOGGER.Debug($" ═══════════════════════") + End If + If IsNothing(CURRENT_DOC_ID) Then sw = New SW("GettingDocID") sql = String.Format("SELECT DocID FROM VWPMO_DOC_SYNC WHERE FULL_FILENAME = '{0}' AND CONVERT(DATE,Change_DateTime) = CONVERT(DATE,GETDATE())", CURRENT_FILEIN_WD) @@ -425,31 +451,70 @@ Public Class frmWM_IndexFile Me.Cursor = Cursors.WaitCursor SaveMySettingsValue("WD_IndexDeleteDocs", WD_IndexDeleteDocs, "ConfigMain") - ' ── Multi-Indexing-Flags zurücksetzen beim Start ────────────────── + LOGGER.Debug("=== HANDLE_FILE START ===") + LOGGER.Debug($" Flags VOR Reset: _multiIndexDecisionMade={_multiIndexDecisionMade}, _multiIndexOverwriteExisting={_multiIndexOverwriteExisting}") + _multiIndexDecisionMade = False _multiIndexOverwriteExisting = False + LOGGER.Debug($" Flags NACH Reset: _multiIndexDecisionMade={_multiIndexDecisionMade}, _multiIndexOverwriteExisting={_multiIndexOverwriteExisting}") + LOGGER.Debug($" chkMultiIndexer: Visible={chkMultiIndexer.Visible}, Checked={chkMultiIndexer.Checked}") + If chkMultiIndexer.Visible = True And chkMultiIndexer.Checked = True Then - ' ── Erste Datei: FILE_HASH sicherstellen ─────────────────────── + LOGGER.Debug("=== MULTI-INDEXING MODUS AKTIV ===") + + ' ── Erste Datei: FILE_HASH und CURRENT_FILEID sicherstellen ─── + Dim firstFileId As Integer = CURRENT_FILEID + Dim firstFileName As String = CURRENT_FILENAME + For Each oRow As DataRow In CURRENT_TBPMO_FILES_USER.Rows If oRow.Item("GUID") = CURRENT_FILEID Then FILE_HASH = oRow.Item("FILE_HASH") + firstFileName = oRow.Item("FILENAME2WORK") Exit For End If Next - If WORK_FILE(Me.txtFilepath.Text, Me.PATHTextBox.Text, doctype_id, My.Settings.WD_INDEXDOKART_SAVE, True) = False Then + LOGGER.Debug($" Verarbeite erste Datei (CURRENT_FILEID={firstFileId}): {firstFileName}") + + If WORK_FILE(firstFileName, Me.PATHTextBox.Text, doctype_id, My.Settings.WD_INDEXDOKART_SAVE, True) = False Then Me.Cursor = Cursors.Default + LOGGER.Warn(" Erste Datei fehlgeschlagen!") Return False End If - ' ── Erste Datei erfolgreich: GUID merken, Folgedateien laden ── - Dim firstFileId = CURRENT_FILEID - Dim DTFiles2Work As DataTable = MYDB_ECM.GetDatatable( - "SELECT * FROM TBPMO_FILES_USER WHERE WORKED = 0 " & - "AND GUID <> " & firstFileId & " AND USER_WORK = '" & USER_USERNAME & "'") + LOGGER.Debug(" Erste Datei erfolgreich verarbeitet") + + ' ── WICHTIG: Erste Datei als WORKED markieren UND DataTable neu laden ── + LOGGER.Debug($" Markiere erste Datei als WORKED: GUID={firstFileId}") + MYDB_ECM.ExecuteNonQuery($"UPDATE TBPMO_FILES_USER SET WORKED = 1 WHERE GUID = {firstFileId}") + + LOGGER.Debug(" Lade aktualisierte Dateiliste aus Datenbank...") + + ' ✅ SCHRITT 1: Prüfe mit COUNT(*), wie viele Dateien in der DB sind + Dim countSQL = $"SELECT COUNT(*) FROM TBPMO_FILES_USER WHERE USER_WORK = '{USER_USERNAME}' AND WORKED = 0" + Dim remainingCount = CInt(MYDB_ECM.GetScalarValue(countSQL)) + LOGGER.Debug($" SQL COUNT ergab: {remainingCount} verbleibende Dateien") + + ' ✅ SCHRITT 2: Nur wenn COUNT > 0, dann DataTable laden + If remainingCount > 0 Then + CURRENT_TBPMO_FILES_USER = MYDB_ECM.GetDatatable("SELECT *, CONVERT(BIT,0) AS DELETE_FILE FROM TBPMO_FILES_USER " & + "WHERE USER_WORK = '" & USER_USERNAME & "' AND WORKED = 0") + + If CURRENT_TBPMO_FILES_USER Is Nothing Then + LOGGER.Error(" WARNUNG: GetDatatable gab Nothing zurück, obwohl COUNT > 0!") + CURRENT_TBPMO_FILES_USER = New DataTable() + Else + LOGGER.Debug($" DataTable geladen: {CURRENT_TBPMO_FILES_USER.Rows.Count} Zeilen") + End If + Else + LOGGER.Info(" SQL COUNT ergab 0 Dateien") + CURRENT_TBPMO_FILES_USER = New DataTable() + End If - If DTFiles2Work Is Nothing OrElse DTFiles2Work.Rows.Count = 0 Then + ' ── Folgedateien aus aktualierter DataTable verarbeiten ── + If CURRENT_TBPMO_FILES_USER Is Nothing OrElse CURRENT_TBPMO_FILES_USER.Rows.Count = 0 Then + LOGGER.Info(" Keine weiteren Dateien vorhanden") NEW_FILES_ADDED = True FILE_WORKED = True Me.Cursor = Cursors.Default @@ -457,12 +522,24 @@ Public Class frmWM_IndexFile Return True End If + LOGGER.Debug($" Weitere Dateien gefunden: {CURRENT_TBPMO_FILES_USER.Rows.Count}") + LOGGER.Debug($" Flags VOR Schleife: _multiIndexDecisionMade={_multiIndexDecisionMade}, _multiIndexOverwriteExisting={_multiIndexOverwriteExisting}") + Dim err As Boolean = False - For Each filerow As DataRow In DTFiles2Work.Rows - CURRENT_FILEID = filerow.Item("GUID") - CURRENT_FILENAME = filerow.Item("FILENAME2WORK") - FILE_HASH = filerow.Item("FILE_HASH") - aktFiledropped = CURRENT_FILENAME + Dim fileCount As Integer = 0 + For Each filerow As DataRow In CURRENT_TBPMO_FILES_USER.Rows + fileCount += 1 + Dim currentFileId As Integer = filerow.Item("GUID") + Dim currentFileName As String = filerow.Item("FILENAME2WORK") + Dim currentFileHash As String = filerow.Item("FILE_HASH") + + CURRENT_FILEID = currentFileId + CURRENT_FILENAME = currentFileName + FILE_HASH = currentFileHash + aktFiledropped = currentFileName + + LOGGER.Debug($" [{fileCount}/{CURRENT_TBPMO_FILES_USER.Rows.Count}] Verarbeite Datei: {currentFileName}, FILEID={currentFileId}") + LOGGER.Debug($" Flags: _multiIndexDecisionMade={_multiIndexDecisionMade}, _multiIndexOverwriteExisting={_multiIndexOverwriteExisting}") Dim handleType As String = filerow.Item("HANDLE_TYPE") Select Case handleType @@ -476,10 +553,15 @@ Public Class frmWM_IndexFile droptype = handleType End Select - If WORK_FILE(CURRENT_FILENAME, Me.PATHTextBox.Text, doctype_id, My.Settings.WD_INDEXDOKART_SAVE, True) = False Then + If WORK_FILE(currentFileName, Me.PATHTextBox.Text, doctype_id, My.Settings.WD_INDEXDOKART_SAVE, True) = False Then err = True + LOGGER.Warn($" Datei fehlgeschlagen!") Exit For End If + + LOGGER.Debug($" Datei erfolgreich verarbeitet") + LOGGER.Debug($" Markiere Datei als WORKED: GUID={currentFileId}") + MYDB_ECM.ExecuteNonQuery($"UPDATE TBPMO_FILES_USER SET WORKED = 1 WHERE GUID = {currentFileId}") Next Me.Cursor = Cursors.Default @@ -493,6 +575,7 @@ Public Class frmWM_IndexFile stg = "All files were transferred via Multiindexing to windream" stg1 = "Success:" End If + LOGGER.Info("=== MULTI-INDEXING ERFOLGREICH ABGESCHLOSSEN ===") MsgBox(stg, MsgBoxStyle.Information, stg1) Me.Close() Return True @@ -501,25 +584,123 @@ Public Class frmWM_IndexFile Return False Else - ' ── Einzeldatei ─────────────────────────────────────────────── - If WORK_FILE(Me.txtFilepath.Text, Me.PATHTextBox.Text, doctype_id, My.Settings.WD_INDEXDOKART_SAVE, False) = True Then - NEW_FILES_ADDED = True - FILE_WORKED = True + ' ✅ EINZELDATEI MODUS + LOGGER.Debug("=== EINZELDATEI MODUS ===") + + ' ✅ WICHTIG: CURRENT_FILEID VOR WORK_FILE setzen! + For Each oRow As DataRow In CURRENT_TBPMO_FILES_USER.Rows + If oRow.Item("FILENAME2WORK") = Me.txtFilepath.Text Then + CURRENT_FILEID = CInt(oRow("GUID")) + FILE_HASH = oRow("FILE_HASH").ToString() + LOGGER.Debug($" Datei gefunden in CURRENT_TBPMO_FILES_USER: FILEID={CURRENT_FILEID}") + Exit For + End If + Next + + ' ✅ Validierung NACH Schleife + If CURRENT_FILEID = 0 Then + LOGGER.Error($" Datei nicht gefunden in CURRENT_TBPMO_FILES_USER: {Me.txtFilepath.Text}") Me.Cursor = Cursors.Default - Me.Close() - Return True - Else + MessageBox.Show("Die Datei konnte nicht in der Verarbeitungsliste gefunden werden!", + "Fehler:", MessageBoxButtons.OK, MessageBoxIcon.Error) + Return False + End If + + If WORK_FILE(Me.txtFilepath.Text, Me.PATHTextBox.Text, doctype_id, My.Settings.WD_INDEXDOKART_SAVE, False) = False Then Me.Cursor = Cursors.Default MessageBox.Show("Import to windream was not successful." & vbCrLf & - "Check the log for further information!", - "Unexpected Error in windream-Stream:", - MessageBoxButtons.OK, MessageBoxIcon.Error) + "Check the log for further information!", + "Unexpected Error in windream-Stream:", + MessageBoxButtons.OK, MessageBoxIcon.Error) Return False End If + + ' ── Datei erfolgreich verarbeitet ── + NEW_FILES_ADDED = True + FILE_WORKED = True + LOGGER.Debug(" Einzeldatei erfolgreich verarbeitet") + + ' ✅ Prüfen, ob weitere Dateien vorhanden sind + LOGGER.Debug(" Lade aktualisierte Dateiliste für Einzeldatei-Check...") + + ' ✅ SCHRITT 1: Prüfe mit COUNT(*), wie viele Dateien in der DB sind + Dim countSQL = $"SELECT COUNT(*) FROM TBPMO_FILES_USER WHERE USER_WORK = '{USER_USERNAME}' AND WORKED = 0" + Dim remainingCount = CInt(MYDB_ECM.GetScalarValue(countSQL)) + LOGGER.Debug($" ═══ SQL COUNT NACH WORK_FILE ═══") + LOGGER.Debug($" COUNT(*) ergab: {remainingCount} verbleibende Dateien") + + ' ✅ SCHRITT 2: Dateiliste laden UND vergleichen + ClassHelper.Create_USER_FILE_TABLE() + + If CURRENT_TBPMO_FILES_USER Is Nothing Then + LOGGER.Error($" ❌ KRITISCHER FEHLER: Create_USER_FILE_TABLE gab Nothing zurück!") + ElseIf CURRENT_TBPMO_FILES_USER.Rows.Count <> remainingCount Then + LOGGER.Error($" ❌ KRITISCHER FEHLER: COUNT ergab {remainingCount}, aber DataTable hat {CURRENT_TBPMO_FILES_USER.Rows.Count} Zeilen!") + LOGGER.Error($" ❌ VERDACHT: Race-Condition oder Transaction-Problem!") + Else + LOGGER.Debug($" ✅ OK: COUNT und DataTable stimmen überein ({remainingCount} Dateien)") + End If + LOGGER.Debug($" ═══════════════════════════════") + + If CURRENT_TBPMO_FILES_USER IsNot Nothing AndAlso CURRENT_TBPMO_FILES_USER.Rows.Count > 0 Then + LOGGER.Info($" Einzeldatei-Modus: Weitere {CURRENT_TBPMO_FILES_USER.Rows.Count} Dateien vorhanden - aktualisiere Formular") + + ' ── Lade ERSTE Datei aus der NEUEN Liste ── + Dim nextFile = CURRENT_TBPMO_FILES_USER.Rows(0) + CURRENT_FILEID = CInt(nextFile("GUID")) + CURRENT_FILENAME = nextFile("FILENAME2WORK").ToString() + FILE_HASH = nextFile("FILE_HASH").ToString() + aktFiledropped = CURRENT_FILENAME + txtFilepath.Text = CURRENT_FILENAME + + LOGGER.Debug($" Nächste Datei geladen: FILEID={CURRENT_FILEID}, Datei={CURRENT_FILENAME}") + + ' ── Update MULTIFILES-Anzeige ── + MULTIFILES = CURRENT_TBPMO_FILES_USER.Rows.Count - 1 + If MULTIFILES > 0 Then + chkMultiIndexer.Text = "Multi-Indexing - Alle nachfolgenden Dateien (" & MULTIFILES & ") identisch indexieren" + chkMultiIndexer.Visible = True + chkMultiIndexer.Checked = False + Else + chkMultiIndexer.Visible = False + End If + + ' ── Handle-Type setzen ── + Dim handleType As String = nextFile("HANDLE_TYPE").ToString() + Select Case handleType + Case "@DROPFROMFSYSTEM@" + droptype = "dragdrop file" + chkdelete_origin.Visible = True + Case "@OUTLOOK_ATTMNT@" + droptype = "dragdrop attachment" + chkdelete_origin.Visible = True + Case "@OUTLOOKMESSAGE@" + droptype = "dragdrop message" + chkdelete_origin.Visible = True + Case "SCAN" + droptype = "scan" + chkdelete_origin.Visible = False + Case Else + droptype = handleType + chkdelete_origin.Visible = False + End Select + + Me.Cursor = Cursors.Default + LOGGER.Debug(" Formular bleibt offen für nächste Datei") + Return True ' ← Formular bleibt offen! + + Else + ' ✅ Keine weiteren Dateien → Formular schließen + LOGGER.Info(" Einzeldatei-Modus: Keine weiteren Dateien - schließe Formular") + Me.Cursor = Cursors.Default + Me.Close() + Return True + End If End If Catch ex As Exception MsgBox("Error in Indexing_File:" & vbCrLf & ex.Message, MsgBoxStyle.Critical) + LOGGER.Error($"Handle_File Exception: {ex.Message}{vbCrLf}{ex.StackTrace}") Return False Finally Me.Cursor = Cursors.Default @@ -1113,37 +1294,63 @@ Public Class frmWM_IndexFile CURRENT_FILENAME = "" Me.VWDDINDEX_AUTOMTableAdapter.Connection.ConnectionString = MYDB_ECM.CurrentConnectionString chkMultiIndexer.Checked = False + + ' ── Multi-Indexing-Flags beim Formular-Load zurücksetzen ── + LOGGER.Debug("=== FORM LOAD: Flags zurücksetzen ===") + LOGGER.Debug($" VOR Reset: _multiIndexDecisionMade = {_multiIndexDecisionMade}, _multiIndexOverwriteExisting = {_multiIndexOverwriteExisting}") + + _multiIndexDecisionMade = False + _multiIndexOverwriteExisting = False + _processedFileIds.Clear() + + LOGGER.Debug($" NACH Reset: _multiIndexDecisionMade = {_multiIndexDecisionMade}, _multiIndexOverwriteExisting = {_multiIndexOverwriteExisting}") + LOGGER.Debug($" ProcessedFileIds Count: {_processedFileIds.Count}") + LOGGER.Debug("frmWD_Index_Dokart_Load") chkdelete_origin.Checked = False chkdelete_origin.Visible = False Dim oReconnect = WMMOD.SessionReconnect - '= New Windream(LOGCONFIG, False, WMDriveLetter, WMPATH_PREFIX, True, WM_SERVER, WM_USER, WM_USER_PW, WM_DOMAIN) + + ' ── WICHTIG: Prüfen, ob überhaupt Dateien vorhanden sind ── + If CURRENT_TBPMO_FILES_USER Is Nothing OrElse CURRENT_TBPMO_FILES_USER.Rows.Count = 0 Then + LOGGER.Info("frmWD_Index_Dokart_Load: Keine Dateien vorhanden - Formular wird geschlossen") + Me.Close() + Exit Sub + End If + Dim oHandleType As String For Each oRow As DataRow In CURRENT_TBPMO_FILES_USER.Rows If oRow.Item("GUID") = CURRENT_FILEID Then CURRENT_FILENAME = oRow.Item("FILENAME2WORK") oHandleType = oRow.Item("HANDLE_TYPE") FILE_HASH = oRow.Item("FILE_HASH") + Exit For ' ← Hinzugefügt: Schleife verlassen, wenn gefunden End If Next + If CURRENT_FILENAME = "" Then - MsgBox("Chekc the Temp Files Table, as it seems to be empty!", MsgBoxStyle.Exclamation) + LOGGER.Warn("Check the Temp Files Table, as it seems to be empty or CURRENT_FILEID not found!") + MsgBox("Check the Temp Files Table, as it seems to be empty!", MsgBoxStyle.Exclamation) + Me.Close() ' ← Formular schließen statt Exit Sub Exit Sub End If - MULTIFILES = 0 - For Each row As DataRow In CURRENT_TBPMO_FILES_USER.Rows - If row.Item("GUID") <> CURRENT_FILEID Then - MULTIFILES += 1 - End If - Next + + ' ── KORREKTUR: Zähle alle Dateien außer der aktuellen ── + MULTIFILES = CURRENT_TBPMO_FILES_USER.Rows.Count - 1 + LOGGER.Debug($" MULTIFILES berechnet: Gesamt={CURRENT_TBPMO_FILES_USER.Rows.Count}, MULTIFILES={MULTIFILES}") + If MULTIFILES > 0 Then chkMultiIndexer.Text = "Multi-Indexing - Alle nachfolgenden Dateien (" & MULTIFILES & ") identisch indexieren" chkMultiIndexer.Visible = True + LOGGER.Debug($" chkMultiIndexer: Visible=True, Text={chkMultiIndexer.Text}") Else chkMultiIndexer.Visible = False + LOGGER.Debug(" chkMultiIndexer: Visible=False (keine weiteren Dateien)") End If + aktFiledropped = CURRENT_FILENAME txtFilepath.Text = aktFiledropped + If oHandleType = "@DROPFROMFSYSTEM@" Then droptype = "dragdrop file" chkdelete_origin.Visible = True @@ -1159,21 +1366,19 @@ Public Class frmWM_IndexFile ElseIf oHandleType = "SCAM" Then droptype = "scan" End If + Dim sql = String.Format("SELECT FORMVIEW_ID, FORM_ID, FORM_TITLE, DOKUMENTTYPE_ID, DOKUMENTTYPE, PATH, SHORTNAME, OBJECT_TYPE, FW_DOCTYPE_ID FROM VWPMO_DOKUMENTTYPES WHERE (FORMVIEW_ID = {0}) " & - "ORDER BY SEQUENCE, DOKUMENTTYPE", CURRENT_FORMVIEW_ID) + "ORDER BY SEQUENCE, DOKUMENTTYPE", CURRENT_FORMVIEW_ID) DTVWPMO_DOKUMENTTYPES = MYDB_ECM.GetDatatable(sql) - 'VWPMO_DOKUMENTTYPESTableAdapter.Connection.ConnectionString = MYDB_ECM.CurrentConnectionString - 'Me.VWPMO_DOKUMENTTYPESTableAdapter.Fill(Me.DD_DMSDataSet.VWPMO_DOKUMENTTYPES, CURRENT_FORMVIEW_ID) - CURRENT_REDUNDANT_FORM_ID = 0 CURRENT_REDUNDANT_FORMVIEW_ID = 0 - If DTVWPMO_DOKUMENTTYPES.Rows.Count = 0 Then ' DD_DMSDataSet.VWPMO_DOKUMENTTYPES.Rows.Count = 0 Then + If DTVWPMO_DOKUMENTTYPES.Rows.Count = 0 Then If CURRENT_ENTITY_REDUNDANT_ID <> 0 Then Dim FVID = MYDB_ECM.GetScalarValue(String.Format("SELECT GUID FROM TBPMO_FORM_VIEW WHERE FORM_ID = {0} and SCREEN_ID = 1", CURRENT_ENTITY_REDUNDANT_ID), True) - 'Me.VWPMO_DOKUMENTTYPESTableAdapter.Fill(Me.DD_DMSDataSet.VWPMO_DOKUMENTTYPES, FVID) - If DTVWPMO_DOKUMENTTYPES.Rows.Count = 0 Then 'DD_DMSDataSet.VWPMO_DOKUMENTTYPES.Rows.Count = 0 Then + If DTVWPMO_DOKUMENTTYPES.Rows.Count = 0 Then MsgBox("No documenttypes for the redundant entity configured either! Indexing is not possible!" & vbCrLf & "Please check the configuration!", MsgBoxStyle.Exclamation) + Me.Close() Exit Sub Else LOGGER.Debug("Redundant EntityID: " & CURRENT_ENTITY_REDUNDANT_ID) @@ -1184,12 +1389,15 @@ Public Class frmWM_IndexFile End If Else MsgBox("No documenttypes for this entity configured! Indexing is not possible!" & vbCrLf & "Please check the configuration!", MsgBoxStyle.Exclamation) + Me.Close() Exit Sub End If - End If + Catch ex As Exception + LOGGER.Error($"Error in frmWD_Index_Dokart_Load: {ex.Message}") MsgBox("Error in frmWD_Index_Dokart_Load:" & vbCrLf & ex.Message, MsgBoxStyle.Critical) + Me.Close() End Try End Sub @@ -1242,19 +1450,63 @@ Public Class frmWM_IndexFile Private Sub frmWM_IndexFile_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing Try - ' Alle nicht-verarbeiteten Dateien löschen (außer den erfolgreichen) - Dim processedIds = String.Join(",", _processedFileIds) - Dim oDelete = $"DELETE FROM TBPMO_FILES_USER WHERE USER_WORK = '{USER_USERNAME}' AND WORKED = 0" - If _processedFileIds.Count > 0 Then - oDelete &= $" AND GUID NOT IN ({processedIds})" + ' ── Multi-Indexing-Flags zurücksetzen ── + _multiIndexDecisionMade = False + _multiIndexOverwriteExisting = False + + ' ✅ WICHTIG: Liste NEU LADEN, bevor wir zählen! + LOGGER.Debug("=== CLOSING: Lade aktuelle Dateiliste ===") + ClassHelper.Create_USER_FILE_TABLE() ' ← Lädt CURRENT_TBPMO_FILES_USER NEU! + + ' ── Prüfen, ob noch Dateien zu verarbeiten sind ── + If CURRENT_TBPMO_FILES_USER IsNot Nothing AndAlso CURRENT_TBPMO_FILES_USER.Rows.Count > 0 Then + ' Es gibt noch nicht verarbeitete Dateien → Benutzer fragen + LOGGER.Debug($"TBPMO_FILES_USER: Formular wird geschlossen, aber {CURRENT_TBPMO_FILES_USER.Rows.Count} Dateien sind noch vorhanden.") + + Dim msg As String + Dim title As String + If USER_LANGUAGE <> "de-DE" Then + msg = $"There are still {CURRENT_TBPMO_FILES_USER.Rows.Count} unprocessed file(s)!" & vbCrLf & vbCrLf & + "Do you really want to cancel the import?" & vbCrLf & vbCrLf & + "YES → Cancel import and delete all pending files" & vbCrLf & + "NO → Continue indexing" + title = "Cancel Import?" + Else + msg = $"Es sind noch {CURRENT_TBPMO_FILES_USER.Rows.Count} nicht verarbeitete Datei(en) vorhanden!" & vbCrLf & vbCrLf & + "Möchten Sie den Import wirklich abbrechen?" & vbCrLf & vbCrLf & + "JA → Import abbrechen und alle ausstehenden Dateien löschen" & vbCrLf & + "NEIN → Indexierung fortsetzen" + title = "Import abbrechen?" + End If + + Dim result As MsgBoxResult = MessageBox.Show(msg, title, MessageBoxButtons.YesNo, MessageBoxIcon.Warning) + + If result = MsgBoxResult.No Then + ' Benutzer will NICHT abbrechen → Formular-Schließen verhindern + LOGGER.Info("Benutzer hat Abbruch verhindert - Formular bleibt offen") + e.Cancel = True + Exit Sub + Else + ' Benutzer will abbrechen → Alle Dateien löschen + LOGGER.Info("Benutzer hat Abbruch bestätigt - Lösche alle ausstehenden Dateien") + Dim oDelete = $"DELETE FROM TBPMO_FILES_USER WHERE USER_WORK = '{USER_USERNAME}' AND WORKED = 0" + MYDB_ECM.ExecuteNonQuery(oDelete) + LOGGER.Info($"TBPMO_FILES_USER: {CURRENT_TBPMO_FILES_USER.Rows.Count} nicht-verarbeitete Einträge wurden gelöscht (User: {USER_USERNAME})") + + ' ── WICHTIG: DataTable leeren, damit Load-Event korrekt reagiert ── + CURRENT_TBPMO_FILES_USER.Clear() + LOGGER.Debug("CURRENT_TBPMO_FILES_USER wurde geleert") + End If + Else + ' Keine Dateien mehr vorhanden → Normal schließen, aufräumen + LOGGER.Debug("Keine ausstehenden Dateien mehr vorhanden ") + End If - MYDB_ECM.ExecuteNonQuery(oDelete) - LOGGER.Info($"TBPMO_FILES_USER: Nicht-verarbeitete Einträge bereinigt (User: {USER_USERNAME})") + Catch ex As Exception LOGGER.Warn($"Fehler beim Bereinigen von TBPMO_FILES_USER (Closing): {ex.Message}") End Try End Sub - Private Sub frmWM_IndexFile_Closed(sender As Object, e As EventArgs) Handles Me.Closed Try Cursor = Cursors.Default @@ -1262,4 +1514,8 @@ Public Class frmWM_IndexFile End Try End Sub + + Private Sub chkMultiIndexer_CheckedChanged(sender As Object, e As EventArgs) Handles chkMultiIndexer.CheckedChanged + LOGGER.Debug($"chkMultiIndexer.CheckedChanged: {chkMultiIndexer.Checked}") + End Sub End Class \ No newline at end of file