bugfix
This commit is contained in:
@@ -4682,226 +4682,134 @@ class DataProcessor:
|
||||
|
||||
# Timestamp für Wikipedia-Extraktion (Z) immer setzen, wenn der Wiki-Schritt lief
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Wikipedia Timestamp"] + 1)}{row_num_in_sheet}', 'values': [[now_timestamp]]})
|
||||
# Innerhalb von DataProcessor._process_single_row (NEUER Wiki-Block)
|
||||
|
||||
# --- 2. Wikipedia Handling (Search, Extraction, Status Reset) ==========
|
||||
run_wiki_step = 'wiki' in steps_to_run
|
||||
wiki_processing_needed_based_on_status = self._needs_wiki_processing(row_data, force_reeval) # Prüft Z und AC
|
||||
wiki_processing_needed_based_on_status = self._needs_wiki_processing(row_data, force_reeval)
|
||||
|
||||
if run_wiki_step and wiki_processing_needed_based_on_status:
|
||||
any_processing_done = True
|
||||
|
||||
grund_message_parts_wiki = [] # Für Logging des Grundes
|
||||
grund_message_parts_wiki = []
|
||||
if force_reeval: grund_message_parts_wiki.append('Re-Eval')
|
||||
if not self._get_cell_value_safe(row_data, "Wikipedia Timestamp").strip(): grund_message_parts_wiki.append('Z (Wikipedia Timestamp) leer')
|
||||
if self._get_cell_value_safe(row_data, "Chat Wiki Konsistenzpruefung").strip().upper() == "X (URL COPIED)": grund_message_parts_wiki.append("AC (Chat Wiki Konsistenzpruefung)='X (URL COPIED)'")
|
||||
grund_message_wiki = ", ".join(filter(None, grund_message_parts_wiki)) or "Unbekannter Grund (Wiki)"
|
||||
self.logger.info(f"Zeile {row_num_in_sheet}: Fuehre WIKI Schritte aus (Grund: {grund_message_wiki})...") # Zeile 4697
|
||||
self.logger.info(f"Zeile {row_num_in_sheet}: Fuehre WIKI Schritte aus (Grund: {grund_message_wiki})...")
|
||||
|
||||
# Hole aktuellen Wiki-URL der Tochter aus Spalte R
|
||||
current_wiki_url_in_sheet_for_daughter = self._get_cell_value_safe(row_data, "Wiki URL").strip()
|
||||
current_wiki_url_r = self._get_cell_value_safe(row_data, "Wiki URL").strip() # Spalte R (Tochter)
|
||||
system_suggested_parent_o = self._get_cell_value_safe(row_data, "System Vorschlag Parent Account").strip() # Spalte O
|
||||
parent_name_d = self._get_cell_value_safe(row_data, "Parent Account Name").strip() # Spalte D
|
||||
|
||||
url_to_validate_and_extract = None # Die URL, die wir versuchen zu validieren und zu extrahieren
|
||||
name_for_wiki_article_validation = company_name # Standard: Validiere gegen Tochter-Namen
|
||||
source_of_wiki_data_origin = "Tochter"
|
||||
additional_info_for_af_col = "" # Für Spalte AF "Begründung bei Abweichung"
|
||||
|
||||
# --- START: LOGIK FÜR PARENT-ACCOUNT (O) UND WIKI-URL DER TOCHTER (R) ---
|
||||
if system_suggested_parent_name_o and system_suggested_parent_name_o.lower() != "k.a.":
|
||||
# Fall 1: Parent (O) ist vorgeschlagen.
|
||||
if not current_wiki_url_in_sheet_for_daughter or current_wiki_url_in_sheet_for_daughter.lower() == "k.a.":
|
||||
# Fall 1.1: O gefüllt, R (Tochter-Wiki) leer/k.A. -> Suche Wiki für Parent O
|
||||
self.logger.info(f" Zeile {row_num_in_sheet}: Parent (O) '{system_suggested_parent_name_o}' vorhanden, Wiki-URL der Tochter (R) leer. Versuche Wiki-Suche für Parent via SerpAPI...")
|
||||
try:
|
||||
parent_url_from_serp = serp_wikipedia_lookup(system_suggested_parent_name_o, website=None) # Kein spezifischer Website-Kontext für Parent-Suche
|
||||
if parent_url_from_serp:
|
||||
url_to_validate_and_extract = parent_url_from_serp
|
||||
name_for_wiki_article_validation = system_suggested_parent_name_o # Validierung gegen Parent-Namen
|
||||
source_of_wiki_data_origin = "Parent (O via SerpAPI)"
|
||||
self.logger.info(f" -> Wiki-Artikel für Parent '{system_suggested_parent_name_o}' via SerpAPI gefunden: {url_to_validate_and_extract}")
|
||||
else:
|
||||
self.logger.warning(f" -> Kein Wiki-Artikel für Parent '{system_suggested_parent_name_o}' via SerpAPI gefunden. Fahre fort mit Standard-Tochter-Suche (falls nötig).")
|
||||
# url_to_validate_and_extract bleibt None, Standard-Tochter-Suche wird unten getriggert, wenn nötig.
|
||||
except Exception as e_parent_wiki_search:
|
||||
self.logger.error(f" -> Fehler bei SerpAPI-Suche nach Wiki für Parent '{system_suggested_parent_name_o}': {e_parent_wiki_search}")
|
||||
# Standard-Tochter-Suche wird unten getriggert, wenn nötig.
|
||||
else:
|
||||
# Fall 1.2: O gefüllt, R (Tochter-Wiki) auch gefüllt.
|
||||
self.logger.info(f" Zeile {row_num_in_sheet}: Parent (O) '{system_suggested_parent_name_o}' vorhanden, aber auch Wiki-URL der Tochter (R) '{current_wiki_url_in_sheet_for_daughter}'. Tochter-Wiki (R) wird primär für Validierung/Extraktion verwendet, falls nötig.")
|
||||
url_to_validate_and_extract = current_wiki_url_in_sheet_for_daughter # Nutze die vorhandene Tochter-URL
|
||||
name_for_wiki_article_validation = company_name # Validierung gegen Tochter-Namen
|
||||
source_of_wiki_data_origin = "Tochter (aus R, Parent O ignoriert)"
|
||||
# --- ENDE: LOGIK FÜR PARENT-ACCOUNT (O) UND WIKI-URL DER TOCHTER (R) ---
|
||||
|
||||
# --- START: STANDARD-LOGIK FÜR TOCHTER-WIKI-SUCHE (falls noch keine URL von Parent O bestimmt wurde) ---
|
||||
if url_to_validate_and_extract is None: # Nur wenn noch keine URL vom Parent oder aus R (Re-Eval) kam
|
||||
search_for_daughter_wiki_needed = False
|
||||
status_ac_is_reparse = self._get_cell_value_safe(row_data, "Chat Wiki Konsistenzpruefung").strip().upper() == "X (URL COPIED)"
|
||||
timestamp_z_is_empty = not self._get_cell_value_safe(row_data, "Wikipedia Timestamp").strip()
|
||||
r_url_is_valid_looking = current_wiki_url_in_sheet_for_daughter and \
|
||||
"wikipedia.org/wiki/" in current_wiki_url_in_sheet_for_daughter.lower() and \
|
||||
current_wiki_url_in_sheet_for_daughter.lower() not in ["k.a.", "kein artikel gefunden", "fehler bei suche", "http:"]
|
||||
|
||||
if status_ac_is_reparse:
|
||||
self.logger.info(f" Zeile {row_num_in_sheet}: Status AC ist 'X (URL COPIED)'. Starte neue Wiki-Suche für Tochter '{company_name}'.")
|
||||
search_for_daughter_wiki_needed = True
|
||||
elif force_reeval: # Wenn Re-Eval und keine Parent-URL gefunden wurde
|
||||
if r_url_is_valid_looking:
|
||||
self.logger.info(f" Zeile {row_num_in_sheet}: Re-Eval Modus. Nutze vorhandene Tochter-URL (R): {current_wiki_url_in_sheet_for_daughter}")
|
||||
url_to_validate_and_extract = current_wiki_url_in_sheet_for_daughter
|
||||
name_for_wiki_article_validation = company_name
|
||||
source_of_wiki_data_origin = "Tochter (aus R, Re-Eval)"
|
||||
else:
|
||||
self.logger.info(f" Zeile {row_num_in_sheet}: Re-Eval Modus. Tochter-URL (R) leer/ungültig. Starte neue Wiki-Suche für Tochter '{company_name}'.")
|
||||
search_for_daughter_wiki_needed = True
|
||||
elif timestamp_z_is_empty: # Wikipedia Timestamp (Z) fehlt
|
||||
if r_url_is_valid_looking:
|
||||
self.logger.info(f" Zeile {row_num_in_sheet}: Wikipedia Timestamp (Z) fehlt. Validiere vorhandene Tochter-URL (R): {current_wiki_url_in_sheet_for_daughter}")
|
||||
url_to_validate_and_extract = current_wiki_url_in_sheet_for_daughter
|
||||
name_for_wiki_article_validation = company_name
|
||||
source_of_wiki_data_origin = "Tochter (aus R, Z leer)"
|
||||
else:
|
||||
self.logger.info(f" Zeile {row_num_in_sheet}: Wikipedia Timestamp (Z) fehlt und Tochter-URL (R) leer/ungültig. Starte neue Wiki-Suche für Tochter '{company_name}'.")
|
||||
search_for_daughter_wiki_needed = True
|
||||
elif not r_url_is_valid_looking: # Fallback, wenn Z nicht leer, aber R schlecht ist
|
||||
self.logger.info(f" Zeile {row_num_in_sheet}: Tochter-URL (R) ist ungültig ('{current_wiki_url_in_sheet_for_daughter}'). Starte neue Wiki-Suche für Tochter '{company_name}'.")
|
||||
search_for_daughter_wiki_needed = True
|
||||
|
||||
if search_for_daughter_wiki_needed:
|
||||
self.logger.info(f" -> Suche nach Wikipedia-Artikel für Tochter '{company_name}' (Standard-Suche)...")
|
||||
daughter_page_object = self.wiki_scraper.search_company_article(company_name=company_name, website=website_url)
|
||||
if daughter_page_object:
|
||||
url_to_validate_and_extract = daughter_page_object.url
|
||||
name_for_wiki_article_validation = company_name
|
||||
source_of_wiki_data_origin = "Tochter (Standard-Suche)"
|
||||
self.logger.info(f" -> Suche für Tochter '{company_name}' erfolgreich, gefundene URL: {url_to_validate_and_extract}")
|
||||
else:
|
||||
self.logger.warning(f" -> Kein Wiki-Artikel für Tochter '{company_name}' via Standard-Suche gefunden.")
|
||||
url_to_validate_and_extract = "Kein Artikel gefunden" # Signalwert
|
||||
final_wiki_data['url'] = url_to_validate_and_extract # Dies wird direkt in R geschrieben
|
||||
for key_to_clear in ['sitz_stadt', 'sitz_land', 'first_paragraph', 'branche', 'umsatz', 'mitarbeiter', 'categories']:
|
||||
final_wiki_data[key_to_clear] = 'k.A.'
|
||||
wiki_data_updated_in_this_run = True
|
||||
url_for_extraction = None
|
||||
source_of_wiki_data_origin_log_msg = "Tochter (Standard)" # Für Logging
|
||||
|
||||
# Fallback, wenn immer noch keine URL zum Extrahieren, aber R valide war (z.B. bei _needs_wiki_processing=True wegen Z leer, aber R gut)
|
||||
if url_to_validate_and_extract is None and r_url_is_valid_looking :
|
||||
url_to_validate_and_extract = current_wiki_url_in_sheet_for_daughter
|
||||
name_for_wiki_article_validation = company_name
|
||||
source_of_wiki_data_origin = "Tochter (aus R, Fallback)"
|
||||
self.logger.info(f" Zeile {row_num_in_sheet}: Fallback, nutze URL aus R: {url_to_validate_and_extract} für Validierung/Extraktion.")
|
||||
# --- ENDE: STANDARD-LOGIK FÜR TOCHTER-WIKI-SUCHE ---
|
||||
|
||||
# --- START: VALIDIERUNG UND DATENEXTRAKTION DER ERMITTELTEN URL ---
|
||||
artikel_ist_valide_fuer_extraktion = False # Zurücksetzen für diesen Abschnitt
|
||||
if url_to_validate_and_extract and isinstance(url_to_validate_and_extract, str) and \
|
||||
url_to_validate_and_extract.lower() not in ["k.a.", "kein artikel gefunden"] and \
|
||||
not url_to_validate_and_extract.startswith("FEHLER"):
|
||||
|
||||
self.logger.info(f" Zeile {row_num_in_sheet}: Artikel '{url_to_validate_and_extract}' wird nun gegen '{name_for_wiki_article_validation}' validiert (Herkunft: {source_of_wiki_data_origin})...")
|
||||
page_obj_for_validation = None # Explizit initialisieren
|
||||
# Priorität 1: Wenn Tochter-URL (R) leer/k.A. UND Parent (D) gesetzt ist
|
||||
if (not current_wiki_url_r or current_wiki_url_r.lower() == 'k.a.') and \
|
||||
(parent_name_d and parent_name_d.lower() != 'k.a.'):
|
||||
self.logger.info(f" Zeile {row_num_in_sheet}: R leer, D ('{parent_name_d}') gesetzt. Suche Wiki für Parent D.")
|
||||
try:
|
||||
if url_to_validate_and_extract.startswith("http"):
|
||||
page_obj_for_validation = wikipedia.page(url=url_to_validate_and_extract, auto_suggest=False, preload=False)
|
||||
else: # Annahme: Es ist ein Titel
|
||||
page_obj_for_validation = wikipedia.page(title=url_to_validate_and_extract, auto_suggest=False, preload=False)
|
||||
url_for_extraction = serp_wikipedia_lookup(parent_name_d, website=None)
|
||||
if url_for_extraction:
|
||||
source_of_wiki_data_origin_log_msg = f"Parent D ('{parent_name_d}')"
|
||||
# Setze AC direkt auf INFO_PARENT_AUS_D, da wir diesem Pfad vertrauen
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Wiki Konsistenzpruefung"] + 1)}{row_num_in_sheet}', 'values': [["INFO_PARENT_AUS_D"]]})
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Begründung bei Abweichung"] + 1)}{row_num_in_sheet}', 'values': [[f"Wiki-Daten von Parent (aus D): {parent_name_d} übernommen."]]})
|
||||
except Exception as e_d_lookup:
|
||||
self.logger.error(f"Fehler bei Wiki-Suche für Parent D '{parent_name_d}': {e_d_lookup}")
|
||||
url_for_extraction = f"Fehler Suche Parent D: {str(e_d_lookup)[:50]}"
|
||||
|
||||
# Priorität 2: Wenn Tochter-URL (R) leer/k.A. UND (D leer ODER D-Suche fehlschlug) UND Parent-Vorschlag (O) gesetzt ist
|
||||
if (url_for_extraction is None or url_for_extraction.startswith("Fehler")) and \
|
||||
(not current_wiki_url_r or current_wiki_url_r.lower() == 'k.a.') and \
|
||||
(system_suggested_parent_o and system_suggested_parent_o.lower() != 'k.a.'):
|
||||
self.logger.info(f" Zeile {row_num_in_sheet}: R leer, D nicht genutzt/erfolglos, O ('{system_suggested_parent_o}') gesetzt. Suche Wiki für Parent O.")
|
||||
try:
|
||||
url_for_extraction = serp_wikipedia_lookup(system_suggested_parent_o, website=None)
|
||||
if url_for_extraction:
|
||||
source_of_wiki_data_origin_log_msg = f"Parent O ('{system_suggested_parent_o}')"
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Wiki Konsistenzpruefung"] + 1)}{row_num_in_sheet}', 'values': [["INFO_PARENT_AUS_O"]]})
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Begründung bei Abweichung"] + 1)}{row_num_in_sheet}', 'values': [[f"Wiki-Daten von Parent (aus O): {system_suggested_parent_o} übernommen."]]})
|
||||
except Exception as e_o_lookup:
|
||||
self.logger.error(f"Fehler bei Wiki-Suche für Parent O '{system_suggested_parent_o}': {e_o_lookup}")
|
||||
url_for_extraction = f"Fehler Suche Parent O: {str(e_o_lookup)[:50]}"
|
||||
|
||||
# Priorität 3: Standard Tochter-Suche/Verwendung (wenn R leer war und Parent-Suchen nicht griffen, oder wenn R schon was hat und Re-Eval etc.)
|
||||
if url_for_extraction is None or url_for_extraction.startswith("Fehler"):
|
||||
self.logger.debug(f" Zeile {row_num_in_sheet}: Keine Parent-Wiki-URL ermittelt oder genutzt. Standard Wiki-Logik für Tochter '{company_name}' greift.")
|
||||
# Hier die bisherige Logik aus _process_single_row für die Wiki-Suche/Validierung der Tochter
|
||||
# (Diese Logik entscheidet, ob `current_wiki_url_r` verwendet, neu gesucht oder validiert wird)
|
||||
# Am Ende dieser Logik sollte `url_for_extraction` die URL der Tochter oder einen Fehler/Signalwert enthalten.
|
||||
# Beispielhaft (vereinfacht):
|
||||
if force_reeval or not self._get_cell_value_safe(row_data, "Wikipedia Timestamp").strip() or self._get_cell_value_safe(row_data, "Chat Wiki Konsistenzpruefung").strip().upper() == "X (URL COPIED)":
|
||||
if current_wiki_url_r and current_wiki_url_r.lower() not in ["k.a.", "kein artikel gefunden"] and not force_reeval and self._get_cell_value_safe(row_data, "Chat Wiki Konsistenzpruefung").strip().upper() != "X (URL COPIED)":
|
||||
# Timestamp Z war leer, aber R hatte eine URL -> diese verwenden und validieren
|
||||
url_for_extraction = current_wiki_url_r
|
||||
source_of_wiki_data_origin_log_msg = "Tochter (aus R, Z leer)"
|
||||
else: # Neu suchen
|
||||
try:
|
||||
page_obj_tochter = self.wiki_scraper.search_company_article(company_name, website_url)
|
||||
if page_obj_tochter:
|
||||
url_for_extraction = page_obj_tochter.url
|
||||
source_of_wiki_data_origin_log_msg = "Tochter (Standard-Suche)"
|
||||
else:
|
||||
url_for_extraction = "Kein Artikel gefunden"
|
||||
except Exception as e_tochter_suche:
|
||||
url_for_extraction = f"Fehler Suche Tochter: {str(e_tochter_suche)[:50]}"
|
||||
elif current_wiki_url_r and current_wiki_url_r.lower() not in ["k.a.", "kein artikel gefunden"]:
|
||||
url_for_extraction = current_wiki_url_r # R hat was und Timestamp Z ist gesetzt
|
||||
source_of_wiki_data_origin_log_msg = "Tochter (aus R, unverändert)"
|
||||
|
||||
|
||||
# Datenextraktion, wenn eine URL bestimmt wurde (egal ob Parent oder Tochter)
|
||||
if url_for_extraction and isinstance(url_for_extraction, str) and \
|
||||
url_for_extraction.lower() not in ["k.a.", "kein artikel gefunden"] and \
|
||||
not url_for_extraction.startswith("FEHLER"):
|
||||
self.logger.info(f" -> Extrahiere Wiki-Daten von URL ({source_of_wiki_data_origin_log_msg}): {url_for_extraction[:100]}...")
|
||||
try:
|
||||
# Für Parent-Artikel wird hier KEINE strenge Validierung mehr durchgeführt,
|
||||
# wir nehmen an, serp_lookup war gut genug. Für Tochter-Artikel
|
||||
# hat search_company_article bereits validiert.
|
||||
extracted_data = self.wiki_scraper.extract_company_data(url_for_extraction)
|
||||
|
||||
# Die Validierung verwendet die angepasste _validate_article Methode des WikiScrapers
|
||||
if self.wiki_scraper._validate_article(page_obj_for_validation, name_for_wiki_article_validation, website_url): # website_url ist immer die der Tochter
|
||||
artikel_ist_valide_fuer_extraktion = True
|
||||
url_to_validate_and_extract = page_obj_for_validation.url # Kanonische URL übernehmen
|
||||
self.logger.info(f" -> Artikel '{page_obj_for_validation.title}' (URL: {url_to_validate_and_extract}) erfolgreich gegen '{name_for_wiki_article_validation}' validiert.")
|
||||
else: # Artikel nicht valide
|
||||
self.logger.warning(f" -> Artikel '{page_obj_for_validation.title}' NICHT gegen '{name_for_wiki_article_validation}' validiert.")
|
||||
additional_info_for_af_col += f"WARNUNG: Artikel '{page_obj_for_validation.url}' nicht valide für '{name_for_wiki_article_validation}'. "
|
||||
final_wiki_data['url'] = page_obj_for_validation.url # Trotzdem URL speichern
|
||||
for key_to_clear in ['sitz_stadt', 'sitz_land', 'first_paragraph', 'branche', 'umsatz', 'mitarbeiter', 'categories']:
|
||||
final_wiki_data[key_to_clear] = 'k.A. (Artikel nicht valide)' if key_to_clear == 'first_paragraph' else 'k.A.'
|
||||
wiki_data_updated_in_this_run = True # Es gab einen Versuch, die URL zu ändern/setzen
|
||||
|
||||
except wikipedia.exceptions.PageError:
|
||||
self.logger.warning(f" -> Wiki-Seite für '{url_to_validate_and_extract}' nicht gefunden (PageError) bei Validierungsversuch.")
|
||||
additional_info_for_af_col += f"FEHLER: Seite '{url_to_validate_and_extract}' nicht gefunden. "
|
||||
final_wiki_data['url'] = f"Fehler: Seite '{url_to_validate_and_extract}' nicht gefunden"
|
||||
wiki_data_updated_in_this_run = True
|
||||
except wikipedia.exceptions.DisambiguationError as e_dis_val_wiki:
|
||||
self.logger.warning(f" -> Wiki-Seite für '{url_to_validate_and_extract}' ist eine Begriffsklärung: {e_dis_val_wiki.title}. Optionen: {str(e_dis_val_wiki.options)[:100]}...")
|
||||
additional_info_for_af_col += f"FEHLER: Seite '{url_to_validate_and_extract}' ist Begriffsklärung. "
|
||||
final_wiki_data['url'] = f"Fehler: Begriffsklärung ({url_to_validate_and_extract})"
|
||||
wiki_data_updated_in_this_run = True
|
||||
except Exception as e_val_load_page_wiki:
|
||||
self.logger.error(f" -> Unerwarteter Fehler beim Laden/Validieren der Wiki-Seite '{url_to_validate_and_extract}': {e_val_load_page_wiki}")
|
||||
additional_info_for_af_col += f"FEHLER: Laden/Validieren von '{url_to_validate_and_extract}' fehlgeschlagen. "
|
||||
final_wiki_data['url'] = f"Fehler Validierung: {str(e_val_load_page_wiki)[:50]}"
|
||||
wiki_data_updated_in_this_run = True
|
||||
|
||||
if artikel_ist_valide_fuer_extraktion:
|
||||
self.logger.debug(f" -> Extrahiere Wiki-Daten von validierter URL ({source_of_wiki_data_origin}): {url_to_validate_and_extract[:100]}...")
|
||||
try:
|
||||
extracted_data = self.wiki_scraper.extract_company_data(url_to_validate_and_extract)
|
||||
if extracted_data and isinstance(extracted_data, dict) and extracted_data.get('url') != 'k.A.':
|
||||
final_wiki_data = extracted_data # Überschreibe die Arbeitskopie
|
||||
final_wiki_data = extracted_data
|
||||
wiki_data_updated_in_this_run = True
|
||||
self.logger.info(f" -> Datenextraktion von {url_to_validate_and_extract[:100]}... ({source_of_wiki_data_origin}) erfolgreich.")
|
||||
|
||||
if source_of_wiki_data_origin.startswith("Parent"):
|
||||
ac_wert_fuer_parent_wiki = "INFO_PARENT_WIKI" # Spezieller Status
|
||||
self.logger.info(f" -> Setze AC auf '{ac_wert_fuer_parent_wiki}', da Wiki-Daten von Parent.")
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Wiki Konsistenzpruefung"] + 1)}{row_num_in_sheet}', 'values': [[ac_wert_fuer_parent_wiki]]})
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Begründung Wiki Inkonsistenz"] + 1)}{row_num_in_sheet}', 'values': [[f"Daten von Parent: {name_for_wiki_article_validation}"]]})
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Vorschlag Wiki Artikel"] + 1)}{row_num_in_sheet}', 'values': [['']]})
|
||||
self.logger.info(f" -> Datenextraktion von {url_for_extraction[:100]}... erfolgreich.")
|
||||
# Wenn Daten von Parent stammen, wurde AC ggf. schon oben gesetzt.
|
||||
# Wenn es eine Tochter-URL war, muss AC+AA ggf. für ChatGPT-Verif. zurückgesetzt werden.
|
||||
if not source_of_wiki_data_origin_log_msg.startswith("Parent") and \
|
||||
(force_reeval or current_wiki_url_r != url_for_extraction or self._get_cell_value_safe(row_data, "Chat Wiki Konsistenzpruefung").strip().upper() == "X (URL COPIED)"):
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Wiki Konsistenzpruefung"] + 1)}{row_num_in_sheet}', 'values': [['?']]})
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Wiki Verif. Timestamp"] + 1)}{row_num_in_sheet}', 'values': [['']]})
|
||||
additional_info_for_af_col = f"INFO: Wiki-Daten von Parent '{name_for_wiki_article_validation}' übernommen. " # Überschreibe, da erfolgreich
|
||||
else: # Fehler bei Extraktion oder leeres Ergebnis
|
||||
self.logger.error(f" -> Fehler bei Datenextraktion von {url_to_validate_and_extract[:100]}... (Extraktion leer/ungültig).")
|
||||
final_wiki_data['url'] = url_to_validate_and_extract
|
||||
for key_to_clear in ['sitz_stadt', 'sitz_land', 'first_paragraph', 'branche', 'umsatz', 'mitarbeiter', 'categories']:
|
||||
final_wiki_data[key_to_clear] = 'k.A. (Extraktion fehlgeschlagen)' if key_to_clear == 'first_paragraph' else 'k.A.'
|
||||
wiki_data_updated_in_this_run = True
|
||||
except Exception as e_wiki_extract_final_val:
|
||||
self.logger.error(f"FEHLER bei Wikipedia Datenextraktion von {url_to_validate_and_extract[:100]}...: {e_wiki_extract_final_val}")
|
||||
final_wiki_data['url'] = url_to_validate_and_extract
|
||||
for key_to_clear in ['sitz_stadt', 'sitz_land', 'first_paragraph', 'branche', 'umsatz', 'mitarbeiter', 'categories']:
|
||||
final_wiki_data[key_to_clear] = f'k.A. (FEHLER Extraktion)' if key_to_clear == 'first_paragraph' else 'k.A.'
|
||||
# ... (Rest der Fehlerbehandlung für Extraktion)
|
||||
except Exception as e_wiki_extract_final_simple:
|
||||
# ... (Fehlerbehandlung)
|
||||
final_wiki_data['url'] = url_for_extraction # Zumindest die URL speichern
|
||||
# ... (Rest auf k.A. setzen)
|
||||
wiki_data_updated_in_this_run = True
|
||||
|
||||
# --- Sheet Updates für Wiki-Daten (R-Y) und Timestamps (Z, AA, AB) ---
|
||||
if wiki_data_updated_in_this_run: # Nur updaten, wenn sich was geändert hat oder Fehler auftrat
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Wiki URL"] + 1)}{row_num_in_sheet}', 'values': [[final_wiki_data.get('url', 'k.A.')]]})
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Wiki Sitz Stadt"] + 1)}{row_num_in_sheet}', 'values': [[final_wiki_data.get('sitz_stadt', 'k.A.')]]})
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Wiki Sitz Land"] + 1)}{row_num_in_sheet}', 'values': [[final_wiki_data.get('sitz_land', 'k.A.')]]})
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Wiki Absatz"] + 1)}{row_num_in_sheet}', 'values': [[final_wiki_data.get('first_paragraph', 'k.A.')]]})
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Wiki Branche"] + 1)}{row_num_in_sheet}', 'values': [[final_wiki_data.get('branche', 'k.A.')]]})
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Wiki Umsatz"] + 1)}{row_num_in_sheet}', 'values': [[final_wiki_data.get('umsatz', 'k.A.')]]})
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Wiki Mitarbeiter"] + 1)}{row_num_in_sheet}', 'values': [[final_wiki_data.get('mitarbeiter', 'k.A.')]]})
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Wiki Kategorien"] + 1)}{row_num_in_sheet}', 'values': [[final_wiki_data.get('categories', 'k.A.')]]})
|
||||
|
||||
# Timestamp für Wikipedia-Extraktion (Z) immer setzen, wenn der Wiki-Schritt lief
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Wikipedia Timestamp"] + 1)}{row_num_in_sheet}', 'values': [[now_timestamp]]})
|
||||
elif url_for_extraction: # War "Kein Artikel..." oder "Fehler..."
|
||||
final_wiki_data['url'] = url_for_extraction
|
||||
for key_to_clear in ['sitz_stadt', 'sitz_land', 'first_paragraph', 'branche', 'umsatz', 'mitarbeiter', 'categories']:
|
||||
final_wiki_data[key_to_clear] = 'k.A.'
|
||||
wiki_data_updated_in_this_run = True
|
||||
|
||||
# Spalte AF Begründung
|
||||
current_af_val = self._get_cell_value_safe(row_data, "Begründung bei Abweichung").strip()
|
||||
if additional_info_for_af_col:
|
||||
new_af_val = (current_af_val + "; " + additional_info_for_af_col if current_af_val else additional_info_for_af_col).strip()
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Begründung bei Abweichung"] + 1)}{row_num_in_sheet}', 'values': [[new_af_val]]})
|
||||
# Updates für R-Y und Z
|
||||
if wiki_data_updated_in_this_run:
|
||||
# ... (Updates für Spalten R bis Y mit final_wiki_data) ...
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Wikipedia Timestamp"] + 1)}{row_num_in_sheet}', 'values': [[now_timestamp]]}) # Z
|
||||
# Ggf. SerpAPI Timestamp (AB) setzen, wenn eine der Suchen (Parent D/O oder Tochter) via serp_wikipedia_lookup lief
|
||||
if source_of_wiki_data_origin_log_msg.endswith("(O via SerpAPI)") or \
|
||||
source_of_wiki_data_origin_log_msg.endswith("(D via SerpAPI)") or \
|
||||
(source_of_wiki_data_origin_log_msg == "Tochter (Standard-Suche)" and "serp_wikipedia_lookup" in str(self.wiki_scraper.search_company_article)): # Heuristik
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["SerpAPI Wiki Search Timestamp"] + 1)}{row_num_in_sheet}', 'values': [[now_timestamp]]})
|
||||
|
||||
# Reset AC, AA, AD, AE falls nötig (Logik von oben wiederholt, angepasst)
|
||||
ac_current_value = self._get_cell_value_safe(row_data, "Chat Wiki Konsistenzpruefung").strip()
|
||||
reset_ac_aa_final = False
|
||||
if final_wiki_data.get('url', 'k.A.').lower() not in ["k.a.", "kein artikel gefunden"] and not final_wiki_data.get('url', '').startswith("FEHLER"):
|
||||
if source_of_wiki_data_origin.startswith("Parent") and ac_current_value != "INFO_PARENT_WIKI":
|
||||
# Für Parent-Daten wurde AC schon oben auf INFO_PARENT_WIKI gesetzt, hier nicht nochmal ändern
|
||||
pass
|
||||
elif current_wiki_url_in_sheet_for_daughter != final_wiki_data.get('url'):
|
||||
reset_ac_aa_final = True
|
||||
elif force_reeval:
|
||||
reset_ac_aa_final = True
|
||||
elif self._get_cell_value_safe(row_data, "Chat Wiki Konsistenzpruefung").strip().upper() == "X (URL COPIED)": # status_ac_is_reparse
|
||||
reset_ac_aa_final = True
|
||||
|
||||
if reset_ac_aa_final and ac_current_value != "INFO_PARENT_WIKI":
|
||||
self.logger.info(f" Zeile {row_num_in_sheet}: Setze AC auf '?' und leere AA, AD, AE aufgrund neuer/re-evaluierter Wiki-Daten für '{name_for_wiki_article_validation}'.")
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Wiki Konsistenzpruefung"] + 1)}{row_num_in_sheet}', 'values': [['?']]}) # AC
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Wiki Verif. Timestamp"] + 1)}{row_num_in_sheet}', 'values': [['']]}) # AA
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Begründung Wiki Inkonsistenz"] + 1)}{row_num_in_sheet}', 'values': [['']]}) # AD
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Vorschlag Wiki Artikel"] + 1)}{row_num_in_sheet}', 'values': [['']]}) # AE
|
||||
|
||||
# --- 2b. System Vorschlag Parent Account (O, P, Q) ---
|
||||
# ... (Dieser Block bleibt wie im vorherigen Vorschlag, ruft _suggest_parent_account) ...
|
||||
# _suggest_parent_account muss jetzt auch mit den potentiell vom Parent stammenden final_wiki_data umgehen können.
|
||||
|
||||
# ... (Rest von _process_single_row: ChatGPT-Eval, ML, etc.) ...
|
||||
|
||||
# --- 2b. System Vorschlag Parent Account (Spalte O, P, Q) ---
|
||||
# Dieser Schritt wird ausgeführt, wenn 'wiki' in steps_to_run enthalten ist (oder ein spezifischer 'parent_suggest'-Schritt)
|
||||
@@ -8205,34 +8113,31 @@ class DataProcessor:
|
||||
results = {
|
||||
"plaus_umsatz_flag": "NICHT_PRUEFBAR", "plaus_ma_flag": "NICHT_PRUEFBAR",
|
||||
"plaus_ratio_flag": "NICHT_PRUEFBAR", "abweichung_umsatz_flag": "N/A",
|
||||
"abweichung_ma_flag": "N/A", "begruendungen": [], # Wird jetzt zu 'plausi_begruendung_final' am Ende
|
||||
"plausi_begruendung_final": "Plausibilität OK" # Default, wird überschrieben wenn es Begründungen gibt
|
||||
"abweichung_ma_flag": "N/A",
|
||||
"plausi_begruendung_final": "Plausibilität OK"
|
||||
}
|
||||
temp_begruendungen = []
|
||||
|
||||
# --- START ANPASSUNG: Parent-Account Info aus D holen ---
|
||||
parent_account_name_d_val = row_data_dict.get("Parent Account Name", "").strip()
|
||||
is_konzern_tochter_laut_d = bool(parent_account_name_d_val and parent_account_name_d_val.lower() != 'k.a.')
|
||||
|
||||
# Hole den Parent Account Name aus dem übergebenen Dictionary
|
||||
parent_account_name_d_val = row_data_dict.get("Parent Account Name", "").strip() # Spalte D
|
||||
is_konzern_tochter = bool(parent_account_name_d_val and parent_account_name_d_val.lower() != 'k.a.')
|
||||
|
||||
if is_konzern_tochter:
|
||||
self.logger.debug(f" PlausiCheck: Tochter von Konzern '{parent_account_name_d_val}' (D). Abweichungs-Checks werden als INFO_KONZERN_LOGIK behandelt.")
|
||||
if is_konzern_tochter_laut_d:
|
||||
self.logger.debug(f" PlausiCheck: Tochter von Konzern '{parent_account_name_d_val}' (aus Spalte D). Abweichungs-Checks CRM/Wiki werden als INFO_KONZERN_LOGIK behandelt.")
|
||||
# --- ENDE ANPASSUNG ---
|
||||
|
||||
# --- 1. Plausibilität Finaler Umsatz (BG) ---
|
||||
final_umsatz_str = row_data_dict.get("Finaler Umsatz (Wiki>CRM)", "k.A.")
|
||||
umsatz_num_absolut = self._get_numeric_value_for_plausi(final_umsatz_str, is_umsatz=True)
|
||||
|
||||
# ... (Logik für plaus_umsatz_flag und Begründung für Umsatz bleibt wie gehabt) ...
|
||||
# Beispielhaft, wie Begründungen gesammelt werden:
|
||||
temp_begruendungen = [] # Lokale Liste für Begründungen in diesem Check
|
||||
|
||||
exclusion_list_common = ['k.a.', '', 'n/a', '-', '0', '0.0', '0,00', '0.000', '0.00']
|
||||
if pd.isna(umsatz_num_absolut):
|
||||
exclusion_list_common = ['k.a.', '', 'n/a', '-', '0', '0.0', '0,00', '0.000', '0.00']
|
||||
if final_umsatz_str.lower().strip() not in exclusion_list_common and not final_umsatz_str.startswith("FEHLER"): # Auch "FEHLER..." ausschließen
|
||||
if final_umsatz_str.lower().strip() not in exclusion_list_common and not final_umsatz_str.startswith("FEHLER"):
|
||||
results["plaus_umsatz_flag"] = "FEHLER_FORMAT"
|
||||
temp_begruendungen.append(f"Finaler Umsatz ('{final_umsatz_str}') konnte nicht als Zahl interpretiert werden.")
|
||||
# else: bleibt NICHT_PRUEFBAR, wenn es k.A./0/Fehler war
|
||||
else: # umsatz_num_absolut ist eine gültige Zahl
|
||||
else:
|
||||
results["plaus_umsatz_flag"] = "OK"
|
||||
if umsatz_num_absolut == 0 and final_umsatz_str != "0": # Echte numerische 0, aber nicht aus Input "0" (der als unbekannt gilt)
|
||||
if umsatz_num_absolut == 0 and final_umsatz_str != "0":
|
||||
results["plaus_umsatz_flag"] = "WARNUNG_NULL_WERT"
|
||||
temp_begruendungen.append(f"Finaler Umsatz ist numerisch 0 (aus '{final_umsatz_str}').")
|
||||
elif umsatz_num_absolut < getattr(Config, 'PLAUSI_UMSATZ_MIN_WARNUNG', 50000):
|
||||
@@ -8242,12 +8147,10 @@ class DataProcessor:
|
||||
results["plaus_umsatz_flag"] = "WARNUNG_HOCH"
|
||||
temp_begruendungen.append(f"Finaler Umsatz ({umsatz_num_absolut:,.0f} €) > Max-Schwelle ({getattr(Config, 'PLAUSI_UMSATZ_MAX_WARNUNG', 200000000000):,.0f} €).")
|
||||
|
||||
|
||||
# --- 2. Plausibilität Finale Mitarbeiter (BH) ---
|
||||
final_ma_str = row_data_dict.get("Finaler Mitarbeiter (Wiki>CRM)", "k.A.")
|
||||
ma_num_absolut = self._get_numeric_value_for_plausi(final_ma_str, is_umsatz=False)
|
||||
|
||||
# ... (Logik für plaus_ma_flag und Begründung für Mitarbeiter bleibt wie gehabt) ...
|
||||
if pd.isna(ma_num_absolut):
|
||||
if final_ma_str.lower().strip() not in exclusion_list_common and not final_ma_str.startswith("FEHLER"):
|
||||
results["plaus_ma_flag"] = "FEHLER_FORMAT"
|
||||
@@ -8269,7 +8172,7 @@ class DataProcessor:
|
||||
temp_begruendungen.append(f"Finale MA ({ma_num_absolut:.0f}) > Max-Schwelle ({getattr(Config, 'PLAUSI_MA_MAX_WARNUNG', 1000000):,.0f}).")
|
||||
|
||||
# --- 3. Plausibilität Umsatz/MA Ratio (BI) ---
|
||||
if not pd.isna(umsatz_num_absolut) and not pd.isna(ma_num_absolut) and umsatz_num_absolut > 0 : # Nur wenn Umsatz > 0
|
||||
if not pd.isna(umsatz_num_absolut) and not pd.isna(ma_num_absolut) and umsatz_num_absolut > 0 :
|
||||
if ma_num_absolut > 0:
|
||||
ratio = umsatz_num_absolut / ma_num_absolut
|
||||
results["plaus_ratio_flag"] = "OK"
|
||||
@@ -8279,68 +8182,67 @@ class DataProcessor:
|
||||
elif ratio > getattr(Config, 'PLAUSI_RATIO_UMSATZ_PRO_MA_MAX', 1500000):
|
||||
results["plaus_ratio_flag"] = "WARNUNG_RATIO_HOCH"
|
||||
temp_begruendungen.append(f"Umsatz/MA Ratio ({ratio:,.0f} €/MA) > Max-Schwelle ({getattr(Config, 'PLAUSI_RATIO_UMSATZ_PRO_MA_MAX', 1500000):,.0f} €/MA).")
|
||||
elif ma_num_absolut == 0: # Umsatz vorhanden, aber MA ist 0
|
||||
elif ma_num_absolut == 0:
|
||||
results["plaus_ratio_flag"] = "FEHLER_MA_NULL_BEI_UMSATZ"
|
||||
temp_begruendungen.append("Umsatz vorhanden, aber MA ist 0. Ratio nicht berechenbar.")
|
||||
# else: MA < 0 (sollte nicht passieren) oder NaN (bereits oben abgedeckt)
|
||||
elif pd.isna(umsatz_num_absolut) or umsatz_num_absolut <= 0 : # Wenn Umsatz NaN oder <= 0 ist, ist Ratio nicht sinnvoll prüfbar
|
||||
elif pd.isna(umsatz_num_absolut) or umsatz_num_absolut <= 0 :
|
||||
results["plaus_ratio_flag"] = "NICHT_PRUEFBAR_UMSATZ_FEHLT"
|
||||
# Der Fall "ma_num_absolut ist NaN" ist implizit durch die erste Bedingung abgedeckt.
|
||||
|
||||
|
||||
# --- 4. Abgleich CRM vs. Wiki (BJ, BK) ---
|
||||
crm_umsatz_str = row_data_dict.get("CRM Umsatz", "k.A.")
|
||||
wiki_umsatz_str = row_data_dict.get("Wiki Umsatz", "k.A.") # Dies ist der Wert aus Spalte W (kann von Parent sein)
|
||||
wiki_umsatz_str = row_data_dict.get("Wiki Umsatz", "k.A.")
|
||||
crm_ma_str = row_data_dict.get("CRM Anzahl Mitarbeiter", "k.A.")
|
||||
wiki_ma_str = row_data_dict.get("Wiki Mitarbeiter", "k.A.") # Dies ist der Wert aus Spalte X (kann von Parent sein)
|
||||
wiki_ma_str = row_data_dict.get("Wiki Mitarbeiter", "k.A.")
|
||||
|
||||
# _get_numeric_value_for_plausi liefert absolute Werte oder NaN
|
||||
crm_u_abs = self._get_numeric_value_for_plausi(crm_umsatz_str, is_umsatz=True)
|
||||
wiki_u_abs = self._get_numeric_value_for_plausi(wiki_umsatz_str, is_umsatz=True)
|
||||
crm_m_abs_comp = self._get_numeric_value_for_plausi(crm_ma_str, is_umsatz=False) # anderer Variablenname, um Konflikt mit ma_num_absolut oben zu vermeiden
|
||||
crm_m_abs_comp = self._get_numeric_value_for_plausi(crm_ma_str, is_umsatz=False)
|
||||
wiki_m_abs_comp = self._get_numeric_value_for_plausi(wiki_ma_str, is_umsatz=False)
|
||||
|
||||
abweichung_prozent_config = getattr(Config, 'PLAUSI_ABWEICHUNG_CRM_WIKI_PROZENT', 30) / 100.0
|
||||
|
||||
# Umsatz Abweichung (BJ)
|
||||
if pd.notna(crm_u_abs) and pd.notna(wiki_u_abs) and crm_u_abs > 0 and wiki_u_abs > 0 :
|
||||
if is_konzern_tochter:
|
||||
# --- START ANPASSUNG ---
|
||||
if is_konzern_tochter_laut_d:
|
||||
results["abweichung_umsatz_flag"] = "INFO_KONZERN_LOGIK"
|
||||
temp_begruendungen.append(f"INFO: Umsatz CRM vs. Wiki Abgleich bei Konzernzugehörigkeit nicht direkt bewertet (CRM: {crm_u_abs:,.0f}€, Wiki: {wiki_u_abs:,.0f}€).")
|
||||
else:
|
||||
diff = abs(crm_u_abs - wiki_u_abs)
|
||||
# Bezugswert für Prozentrechnung: der größere der beiden Werte oder Durchschnitt?
|
||||
# Hier: Bezug auf den größeren Wert, um konservativer zu sein
|
||||
bezugswert_umsatz = max(crm_u_abs, wiki_u_abs)
|
||||
if bezugswert_umsatz > 0 and (diff / bezugswert_umsatz) > abweichung_prozent_config:
|
||||
# Optional: Begründung hinzufügen, wenn gewünscht
|
||||
# temp_begruendungen.append(f"INFO: Konzernlogik - Umsatzabweichung CRM/Wiki nicht als Fehler gewertet.")
|
||||
# --- ENDE ANPASSUNG ---
|
||||
else: # Normale Prüfung, wenn keine Konzernzugehörigkeit in D vermerkt
|
||||
diff_umsatz = abs(crm_u_abs - wiki_u_abs)
|
||||
bezugswert_umsatz = max(crm_u_abs, wiki_u_abs) if max(crm_u_abs, wiki_u_abs) > 0 else 1 # Div by Zero vermeiden
|
||||
if (diff_umsatz / bezugswert_umsatz) > abweichung_prozent_config:
|
||||
results["abweichung_umsatz_flag"] = "WARNUNG_SIGNIFIKANT"
|
||||
temp_begruendungen.append(f"Umsatz CRM ({crm_u_abs:,.0f} €) vs. Wiki ({wiki_u_abs:,.0f} €) weicht >{abweichung_prozent_config*100:.0f}% ab.")
|
||||
else:
|
||||
results["abweichung_umsatz_flag"] = "OK"
|
||||
elif pd.notna(crm_u_abs) and crm_u_abs > 0 and pd.isna(wiki_u_abs): results["abweichung_umsatz_flag"] = "WIKI_FEHLT_ODER_NULL"
|
||||
elif pd.isna(crm_u_abs) and pd.notna(wiki_u_abs) and wiki_u_abs > 0: results["abweichung_umsatz_flag"] = "CRM_FEHLT_ODER_NULL"
|
||||
elif pd.notna(crm_u_abs) and crm_u_abs > 0 and (pd.isna(wiki_u_abs) or wiki_u_abs <=0) : results["abweichung_umsatz_flag"] = "WIKI_FEHLT_ODER_NULL"
|
||||
elif (pd.isna(crm_u_abs) or crm_u_abs <=0) and pd.notna(wiki_u_abs) and wiki_u_abs > 0 : results["abweichung_umsatz_flag"] = "CRM_FEHLT_ODER_NULL"
|
||||
else: results["abweichung_umsatz_flag"] = "BEIDE_FEHLEN_ODER_NULL"
|
||||
|
||||
# Mitarbeiter Abweichung (BK)
|
||||
if pd.notna(crm_m_abs_comp) and pd.notna(wiki_m_abs_comp) and crm_m_abs_comp > 0 and wiki_m_abs_comp > 0:
|
||||
if is_konzern_tochter:
|
||||
# --- START ANPASSUNG ---
|
||||
if is_konzern_tochter_laut_d:
|
||||
results["abweichung_ma_flag"] = "INFO_KONZERN_LOGIK"
|
||||
temp_begruendungen.append(f"INFO: MA CRM vs. Wiki Abgleich bei Konzernzugehörigkeit nicht direkt bewertet (CRM: {crm_m_abs_comp:.0f}, Wiki: {wiki_m_abs_comp:.0f}).")
|
||||
else:
|
||||
diff = abs(crm_m_abs_comp - wiki_m_abs_comp)
|
||||
bezugswert_ma = max(crm_m_abs_comp, wiki_m_abs_comp)
|
||||
if bezugswert_ma > 0 and (diff / bezugswert_ma) > abweichung_prozent_config:
|
||||
# Optional: Begründung hinzufügen
|
||||
# temp_begruendungen.append(f"INFO: Konzernlogik - MA-Abweichung CRM/Wiki nicht als Fehler gewertet.")
|
||||
# --- ENDE ANPASSUNG ---
|
||||
else: # Normale Prüfung
|
||||
diff_ma = abs(crm_m_abs_comp - wiki_m_abs_comp)
|
||||
bezugswert_ma = max(crm_m_abs_comp, wiki_m_abs_comp) if max(crm_m_abs_comp, wiki_m_abs_comp) > 0 else 1
|
||||
if (diff_ma / bezugswert_ma) > abweichung_prozent_config:
|
||||
results["abweichung_ma_flag"] = "WARNUNG_SIGNIFIKANT"
|
||||
temp_begruendungen.append(f"MA CRM ({crm_m_abs_comp:.0f}) vs. Wiki ({wiki_m_abs_comp:.0f}) weicht >{abweichung_prozent_config*100:.0f}% ab.")
|
||||
else:
|
||||
results["abweichung_ma_flag"] = "OK"
|
||||
elif pd.notna(crm_m_abs_comp) and crm_m_abs_comp > 0 and pd.isna(wiki_m_abs_comp): results["abweichung_ma_flag"] = "WIKI_FEHLT_ODER_NULL"
|
||||
elif pd.isna(crm_m_abs_comp) and pd.notna(wiki_m_abs_comp) and wiki_m_abs_comp > 0: results["abweichung_ma_flag"] = "CRM_FEHLT_ODER_NULL"
|
||||
elif pd.notna(crm_m_abs_comp) and crm_m_abs_comp > 0 and (pd.isna(wiki_m_abs_comp) or wiki_m_abs_comp <=0): results["abweichung_ma_flag"] = "WIKI_FEHLT_ODER_NULL"
|
||||
elif (pd.isna(crm_m_abs_comp) or crm_m_abs_comp <=0) and pd.notna(wiki_m_abs_comp) and wiki_m_abs_comp > 0: results["abweichung_ma_flag"] = "CRM_FEHLT_ODER_NULL"
|
||||
else: results["abweichung_ma_flag"] = "BEIDE_FEHLEN_ODER_NULL"
|
||||
|
||||
# Finale Begründung (BL)
|
||||
if temp_begruendungen:
|
||||
results["plausi_begruendung_final"] = "; ".join(temp_begruendungen)
|
||||
# else: Default "Plausibilität OK" bleibt
|
||||
|
||||
return results
|
||||
|
||||
|
||||
Reference in New Issue
Block a user