sync_manager.py aktualisiert
This commit is contained in:
109
sync_manager.py
109
sync_manager.py
@@ -465,3 +465,112 @@ class SyncManager:
|
|||||||
self.logger.info("--> Ergebnis: Werte sind IDENTISCH.")
|
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)
|
||||||
Reference in New Issue
Block a user