From f90618e722df6e0085b899964e710d183d7b349a Mon Sep 17 00:00:00 2001 From: Floke Date: Thu, 28 Aug 2025 17:34:52 +0000 Subject: [PATCH] sync_manager.py aktualisiert --- sync_manager.py | 81 ++++++++++++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 32 deletions(-) diff --git a/sync_manager.py b/sync_manager.py index dddb24ab..2ef83651 100644 --- a/sync_manager.py +++ b/sync_manager.py @@ -253,10 +253,11 @@ class SyncManager: self.logger.info("Synchronisation erfolgreich abgeschlossen.") - def debug_sync(self): + def debug_sync(self, debug_id=None): """ - Führt eine reine Analyse des Sync-Prozesses durch, ohne Daten zu schreiben. - Gibt detaillierte Debug-Informationen im Log aus. + Führt eine Analyse des Sync-Prozesses durch. Ohne debug_id wird eine + allgemeine Statistik ausgegeben. Mit debug_id wird eine Tiefenanalyse + für einen einzelnen Datensatz durchgeführt. """ self.logger.info("========== START SYNC-DEBUG-MODUS ==========") @@ -264,38 +265,54 @@ class SyncManager: self.logger.error("Debug abgebrochen, da das Laden der Daten fehlschlug.") return - # 1. Analyse des D365 DataFrames - self.logger.info("\n--- D365 DataFrame Analyse ---") - d365_ids_series = self.d365_df['CRM ID'].dropna() - d365_ids = set(d365_ids_series) - self.logger.info(f"Anzahl Zeilen im D365 DataFrame: {len(self.d365_df)}") - self.logger.info(f"Anzahl nicht-leerer GUIDs in D365: {len(d365_ids)}") - self.logger.info(f"Erste 5 D365 GUIDs:\n{d365_ids_series.head().to_string()}") - self.logger.info(f"Letzte 5 D365 GUIDs:\n{d365_ids_series.tail().to_string()}") + if not debug_id: + self.logger.info("Keine spezifische ID angegeben. Führe allgemeine Statistik-Analyse durch.") + d365_ids = set(self.d365_df['CRM ID']) + gsheet_ids = set(self.gsheet_df[self.gsheet_df['CRM ID'] != '']['CRM ID'].dropna()) + self.logger.info("\n--- Set-Analyse (Vergleich) ---") + self.logger.info(f"Anzahl neuer IDs: {len(d365_ids - gsheet_ids)}") + self.logger.info(f"Anzahl zu archivierender IDs: {len(gsheet_ids - d365_ids)}") + self.logger.info(f"Größe der Schnittmenge: {len(d365_ids.intersection(gsheet_ids))}") + self.logger.info("========== ENDE SYNC-DEBUG-MODUS ==========") + return - # 2. Analyse des Google Sheet DataFrames - self.logger.info("\n--- Google Sheet DataFrame Analyse ---") - gsheet_ids_series = self.gsheet_df[self.gsheet_df['CRM ID'] != '']['CRM ID'].dropna() - gsheet_ids = set(gsheet_ids_series) - self.logger.info(f"Anzahl Zeilen im GSheet DataFrame: {len(self.gsheet_df)}") - self.logger.info(f"Anzahl nicht-leerer GUIDs im GSheet: {len(gsheet_ids)}") - self.logger.info(f"Erste 5 GSheet GUIDs:\n{gsheet_ids_series.head().to_string()}") - self.logger.info(f"Letzte 5 GSheet GUIDs:\n{gsheet_ids_series.tail().to_string()}") + # --- TIEFENANALYSE FÜR EINE SPEZIFISCHE ID --- + self.logger.info(f"\n--- Tiefenanalyse für CRM ID: {debug_id} ---") + debug_id = debug_id.lower().strip() - # 3. Analyse der Set-Operationen - self.logger.info("\n--- Set-Analyse (Vergleich) ---") - new_ids = d365_ids - gsheet_ids - deleted_ids = gsheet_ids - d365_ids - existing_ids = d365_ids.intersection(gsheet_ids) + # 1. Daten aus D365 suchen + d365_row = self.d365_df[self.d365_df['CRM ID'] == debug_id] + if d365_row.empty: + self.logger.warning("ID in D365-Export nicht gefunden.") + else: + self.logger.info("Datensatz aus D365-Export:") + # .to_dict('records')[0] wandelt die Zeile in ein lesbares Dictionary um + self.logger.info(d365_row.to_dict('records')[0]) - self.logger.info(f"Anzahl neuer IDs (in D365, nicht in GSheet): {len(new_ids)}") - self.logger.info(f"Anzahl zu archivierender IDs (in GSheet, nicht in D365): {len(deleted_ids)}") - self.logger.info(f"Größe der Schnittmenge (in beiden vorhanden): {len(existing_ids)}") + # 2. Daten aus GSheet suchen + gsheet_row = self.gsheet_df[self.gsheet_df['CRM ID'] == debug_id] + if gsheet_row.empty: + self.logger.warning("ID im Google Sheet nicht gefunden.") + else: + self.logger.info("\nDatensatz aus Google Sheet:") + self.logger.info(gsheet_row.to_dict('records')[0]) - if len(existing_ids) < 90 and len(d365_ids) > 90: - self.logger.warning("WARNUNG: Die Schnittmenge ist unerwartet klein. Dies bestätigt den Verdacht eines Matching-Problems!") - # Zeige ein paar IDs, die hätten übereinstimmen sollen - if gsheet_ids: - self.logger.info(f"Beispiel-GUID aus GSheet, die nicht gefunden wurde: {next(iter(gsheet_ids))}") + # 3. Direkter Vergleich des kritischen Feldes + if not d365_row.empty and not gsheet_row.empty: + self.logger.info("\n--- Direkter Feld-Vergleich: CRM Anzahl Techniker ---") + d365_val = d365_row.iloc[0]['CRM Anzahl Techniker'] + gsheet_val = gsheet_row.iloc[0]['CRM Anzahl Techniker'] + + self.logger.info(f"Wert aus D365: '{d365_val}' (Typ: {type(d365_val)})") + self.logger.info(f"Wert aus GSheet: '{gsheet_val}' (Typ: {type(gsheet_val)})") + + # Simuliere die Vergleichslogik + d365_val_str = str(d365_val).strip() + gsheet_val_str = str(gsheet_val).strip() + + if d365_val_str != gsheet_val_str: + self.logger.info("--> Ergebnis nach String-Konvertierung: Werte sind UNTERSCHIEDLICH.") + else: + self.logger.info("--> Ergebnis nach String-Konvertierung: Werte sind IDENTISCH.") self.logger.info("========== ENDE SYNC-DEBUG-MODUS ==========") \ No newline at end of file