sync_manager.py aktualisiert

This commit is contained in:
2025-08-29 06:12:03 +00:00
parent 4f9ed10c96
commit 4a3e35cee2

View File

@@ -464,4 +464,113 @@ class SyncManager:
else:
self.logger.info("--> Ergebnis: Werte sind IDENTISCH.")
self.logger.info("========== ENDE SYNC-DEBUG-MODUS ==========")
self.logger.info("========== ENDE SYNC-DEBUG-MODUS ==========")
def simulate_sync(self):
"""
Führt eine reine "Trockenlauf"-Analyse des Sync-Prozesses durch, ohne Daten zu schreiben.
Gibt einen detaillierten Bericht über alle potenziellen Änderungen aus.
"""
self.logger.info("========== START SYNC-SIMULATION ==========")
if not self._load_data():
self.logger.error("Simulation abgebrochen, da das Laden der Daten fehlschlug.")
return
# Die Analyse-Logik ist identisch zum echten Lauf
d365_ids = set(self.d365_df['CRM ID'].dropna())
gsheet_ids = set(self.gsheet_df['CRM ID'].dropna())
new_ids = d365_ids - gsheet_ids
existing_ids = d365_ids.intersection(gsheet_ids)
simulation_results = defaultdict(list)
# 1. Bestehende Accounts analysieren
if existing_ids:
d365_indexed = self.d365_df.set_index('CRM ID')
gsheet_to_update_df = self.gsheet_df[self.gsheet_df['CRM ID'].isin(existing_ids)]
for _, gsheet_row in gsheet_to_update_df.iterrows():
crm_id = gsheet_row['CRM ID']
d365_row = d365_indexed.loc[crm_id]
changes = []
conflicts = []
needs_reeval = False
for gsheet_col in self.d365_wins_cols:
d365_val = str(d365_row[gsheet_col]).strip()
gsheet_val = str(gsheet_row[gsheet_col]).strip()
trigger_update = False
if gsheet_col == 'CRM Land':
d365_code_lower, gsheet_val_lower = d365_val.lower(), gsheet_val.lower()
d365_translated = Config.COUNTRY_CODE_MAP.get(d365_code_lower, d365_code_lower).lower()
if gsheet_val_lower != d365_code_lower and gsheet_val_lower != d365_translated:
trigger_update = True
elif gsheet_col == 'CRM Anzahl Techniker':
semantically_empty = ['', '0', '-1']
if d365_val in semantically_empty and gsheet_val in semantically_empty: pass
elif d365_val != gsheet_val: trigger_update = True
elif gsheet_col == 'CRM Branche':
if gsheet_row['Chat Vorschlag Branche'] == '' and d365_val != gsheet_val:
trigger_update = True
elif gsheet_col == 'CRM Umsatz':
if gsheet_row['Wiki Umsatz'] == '' and d365_val != gsheet_val:
trigger_update = True
elif gsheet_col == 'CRM Anzahl Mitarbeiter':
if gsheet_row['Wiki Mitarbeiter'] == '' and d365_val != gsheet_val:
trigger_update = True
elif gsheet_col == 'CRM Beschreibung':
if gsheet_row['Website Zusammenfassung'] == '' and d365_val != gsheet_val:
trigger_update = True
else:
if d365_val != gsheet_val: trigger_update = True
if trigger_update:
changes.append(f"UPDATE: {gsheet_col} von '{gsheet_val}' zu '{d365_val}'")
needs_reeval = True
for gsheet_col in self.smart_merge_cols:
d365_val = str(d365_row.get(gsheet_col, '')).strip()
gsheet_val = str(gsheet_row.get(gsheet_col, '')).strip()
if d365_val and gsheet_val and d365_val != gsheet_val:
conflicts.append(f"CONFLICT: {gsheet_col} (D365='{d365_val}' vs GSheet='{gsheet_val}')")
if changes or conflicts:
account_name = d365_row.get('CRM Name', 'Unbekannt')
key = f"ACCOUNT: {crm_id} ({account_name})"
simulation_results[key].extend(changes)
simulation_results[key].extend(conflicts)
if needs_reeval:
simulation_results[key].append("AKTION: ReEval Flag würde gesetzt werden.")
# 2. Den Bericht generieren und ausgeben
self.logger.info("\n\n" + "="*80)
self.logger.info(" S Y N C S I M U L A T I O N S B E R I C H T")
self.logger.info("="*80)
self.logger.info(f"\n--- ZUSAMMENFASSUNG ---")
self.logger.info(f"Accounts im D365-Export: {len(d365_ids)}")
self.logger.info(f"Accounts im Google Sheet: {len(gsheet_ids)}")
self.logger.info(f"--> {len(new_ids)} NEUE Accounts würden hinzugefügt.")
self.logger.info(f"--> {len(simulation_results)} BESTEHENDE Accounts würden geändert.")
self.logger.info(f"--> {len(existing_ids) - len(simulation_results)} bestehende Accounts bleiben UNVERÄNDERT.")
self.logger.info("-" * 80)
if new_ids:
self.logger.info(f"\n--- {len(new_ids)} NEUE ACCOUNTS ---")
new_accounts_df = self.d365_df[self.d365_df['CRM ID'].isin(new_ids)]
for _, row in new_accounts_df.head(20).iterrows(): # Zeige maximal die ersten 20
self.logger.info(f" - NEU: {row['CRM ID']} ({row['CRM Name']})")
if len(new_ids) > 20: self.logger.info(" - ... und weitere.")
if simulation_results:
self.logger.info(f"\n--- {len(simulation_results)} ZU AKTUALISIERENDE ACCOUNTS ---")
for account, details in simulation_results.items():
self.logger.info(account)
for detail in details:
self.logger.info(f" - {detail}")
self.logger.info("\n" + "="*80)
self.logger.info(" S I M U L A T I O N B E E N D E T")
self.logger.info("="*80)