v1.7.4: Spalte für Branchen-KI-Konfidenz hinzugefügt
- Neue Spalte "Chat Branche Konfidenz" (AI) in COLUMN_MAP und alignment_demo eingefügt. - Nachfolgende Spaltenindizes angepasst. - Ziel: Speicherung des Konfidenz-Scores der Branchen-KI. - Prompt für evaluate_branche_chatgpt angepasst, um Konfidenz (Hoch/Mittel/Niedrig) zu erfragen. - Antwortformat-Anweisung im Prompt um Konfidenz erweitert. - Parsing-Logik in evaluate_branche_chatgpt erweitert, um Konfidenz zu extrahieren. - Rückgabewert von evaluate_branche_chatgpt um 'confidence'-Schlüssel erweitert. - DataProcessor._process_single_row angepasst, um den Branchen-KI-Konfidenz-Score zu speichern. - Logik zum Berechnen und Speichern von "Finaler Umsatz (Wiki>CRM)" und "Finaler Mitarbeiter (Wiki>CRM)" in _process_single_row integriert.
This commit is contained in:
@@ -8,7 +8,7 @@ von Unternehmensdaten, primär aus einem Google Sheet, ergänzt durch Web Scrapi
|
||||
Wikipedia, OpenAI (ChatGPT) und SerpAPI (Google Search, LinkedIn).
|
||||
|
||||
Autor: Christian Godelmann
|
||||
Version: v1.7.3
|
||||
Version: v1.7.4
|
||||
|
||||
Hinweis zur Struktur:
|
||||
Dieser Code wird in logischen Bloecken uebermittelt. Fuegen Sie die Bloecke
|
||||
@@ -107,7 +107,7 @@ PATTERNS_FILE_JSON = "technician_patterns.json" # Neu (Empfohlen)
|
||||
# --- Globale Konfiguration Klasse ---
|
||||
class Config:
|
||||
"""Zentrale Konfigurationseinstellungen."""
|
||||
VERSION = "v1.7.3"
|
||||
VERSION = "v1.7.4"
|
||||
LANG = "de" # Sprache fuer Wikipedia etc.
|
||||
# ACHTUNG: SHEET_URL ist hier ein Platzhalter. Ersetzen Sie ihn durch Ihre tatsaechliche URL.
|
||||
SHEET_URL = "https://docs.google.com/spreadsheets/d/1u_gHr9JUfmV1-iviRzbSe3575QEp7KLhK5jFV_gJcgo" # <<< ERSETZEN SIE DIES!
|
||||
@@ -185,7 +185,7 @@ class Config:
|
||||
|
||||
# --- Globale Spalten-Mapping (WICHTIG: MUSS ZU IHREM SHEET PASSEN!) ---
|
||||
# --- Globale Spalten-Mapping (WICHTIG: MUSS ZU IHREM SHEET PASSEN!) ---
|
||||
# Version 1.7.3 - 56 Spalten (A-BD)
|
||||
# Version 1.7.4 - 57 Spalten (A-BE)
|
||||
COLUMN_MAP = {
|
||||
# ReEval Flag & CRM-Daten (A-M)
|
||||
"ReEval Flag": 0, # A
|
||||
@@ -193,9 +193,9 @@ COLUMN_MAP = {
|
||||
"CRM Kurzform": 2, # C
|
||||
"CRM Website": 3, # D
|
||||
"CRM Ort": 4, # E
|
||||
"CRM Land": 5, # F (NEU)
|
||||
"CRM Land": 5, # F
|
||||
"CRM Beschreibung": 6, # G
|
||||
"CRM Branche": 7, # H
|
||||
"CRM Branche": 7, # H (Jetzt 1:1 zum Zielschema)
|
||||
"CRM Beschreibung Branche extern": 8, # I
|
||||
"CRM Anzahl Techniker": 9, # J
|
||||
"CRM Umsatz": 10, # K
|
||||
@@ -204,58 +204,60 @@ COLUMN_MAP = {
|
||||
|
||||
# Wikipedia-Daten & -Status (N-AB)
|
||||
"Wiki URL": 13, # N
|
||||
"Wiki Sitz Stadt": 14, # O (NEU)
|
||||
"Wiki Sitz Land": 15, # P (NEU)
|
||||
"Wiki Sitz Stadt": 14, # O
|
||||
"Wiki Sitz Land": 15, # P
|
||||
"Wiki Absatz": 16, # Q
|
||||
"Wiki Branche": 17, # R
|
||||
"Wiki Umsatz": 18, # S
|
||||
"Wiki Mitarbeiter": 19, # T
|
||||
"Wiki Kategorien": 20, # U
|
||||
"Wikipedia Timestamp": 21, # V (vorher AN)
|
||||
"Wiki Verif. Timestamp": 22, # W (vorher AX)
|
||||
"SerpAPI Wiki Search Timestamp": 23, # X (vorher AY)
|
||||
"Chat Wiki Konsistenzpruefung": 24, # Y (vorher S)
|
||||
"Chat Begruendung Wiki Inkonsistenz": 25, # Z (vorher T)
|
||||
"Chat Vorschlag Wiki Artikel": 26, # AA (vorher U)
|
||||
"Begruendung bei Abweichung": 27, # AB (vorher V)
|
||||
"Wikipedia Timestamp": 21, # V
|
||||
"Wiki Verif. Timestamp": 22, # W
|
||||
"SerpAPI Wiki Search Timestamp": 23, # X
|
||||
"Chat Wiki Konsistenzpruefung": 24, # Y
|
||||
"Chat Begruendung Wiki Inkonsistenz": 25, # Z
|
||||
"Chat Vorschlag Wiki Artikel": 26, # AA
|
||||
"Begruendung bei Abweichung": 27, # AB
|
||||
|
||||
# Website-Daten (AC-AG)
|
||||
"Website Rohtext": 28, # AC (vorher AR)
|
||||
"Website Zusammenfassung": 29, # AD (vorher AS)
|
||||
"Website Meta-Details": 30, # AE (NEU)
|
||||
"Website Scrape Timestamp": 31, # AF (vorher AT)
|
||||
"URL Prüfstatus": 32, # AG (NEU für URL_CHECK_NEEDED etc.)
|
||||
"Website Rohtext": 28, # AC
|
||||
"Website Zusammenfassung": 29, # AD
|
||||
"Website Meta-Details": 30, # AE
|
||||
"Website Scrape Timestamp": 31, # AF
|
||||
"URL Prüfstatus": 32, # AG
|
||||
|
||||
# ChatGPT Branchen- & weitere Schätzungen (AH-AT)
|
||||
"Chat Vorschlag Branche": 33, # AH (vorher W)
|
||||
"Chat Konsistenz Branche": 34, # AI (vorher X)
|
||||
"Chat Begruendung Abweichung Branche": 35, # AJ (vorher Y)
|
||||
"Chat Pruefung FSM Relevanz": 36, # AK (vorher Z)
|
||||
"Chat Begruendung für FSM Relevanz": 37, # AL (vorher AA)
|
||||
"Chat Schaetzung Anzahl Mitarbeiter": 38, # AM (vorher AB)
|
||||
"Chat Konsistenzprüfung Mitarbeiterzahl": 39, # AN (vorher AC)
|
||||
"Chat Begruendung Abweichung Mitarbeiterzahl": 40, # AO (vorher AD)
|
||||
"Chat Einschätzung Anzahl Servicetechniker": 41, # AP (vorher AE)
|
||||
"Chat Begruendung Abweichung Anzahl Servicetechniker": 42, # AQ (vorher AF)
|
||||
"Chat Schätzung Umsatz": 43, # AR (vorher AG)
|
||||
"Chat Begruendung Abweichung Umsatz": 44, # AS (vorher AH)
|
||||
# ChatGPT Branchen- & weitere Schätzungen (AH-AU) - VORHER AH-AS
|
||||
"Chat Vorschlag Branche": 33, # AH
|
||||
"Chat Branche Konfidenz": 34, # AI (NEU)
|
||||
"Chat Konsistenz Branche": 35, # AJ (vorher AI)
|
||||
"Chat Begruendung Abweichung Branche": 36, # AK (vorher AJ)
|
||||
"Chat Pruefung FSM Relevanz": 37, # AL (vorher AK)
|
||||
"Chat Begruendung für FSM Relevanz": 38, # AM (vorher AL)
|
||||
"Chat Schaetzung Anzahl Mitarbeiter": 39, # AN (vorher AM)
|
||||
"Chat Konsistenzprüfung Mitarbeiterzahl": 40, # AO (vorher AN)
|
||||
"Chat Begruendung Abweichung Mitarbeiterzahl": 41, # AP (vorher AO)
|
||||
"Chat Einschätzung Anzahl Servicetechniker": 42, # AQ (vorher AP)
|
||||
"Chat Begruendung Abweichung Anzahl Servicetechniker": 43, # AR (vorher AQ)
|
||||
"Chat Schätzung Umsatz": 44, # AS (vorher AR)
|
||||
"Chat Begruendung Abweichung Umsatz": 45, # AT (vorher AS)
|
||||
# Spalte AU ist jetzt leer, war vorher "Linked Serviceleiter gefunden"
|
||||
|
||||
# LinkedIn-Kontakte (AT-AW)
|
||||
"Linked Serviceleiter gefunden": 45, # AT (vorher AI)
|
||||
"Linked It-Leiter gefunden": 46, # AU (vorher AJ)
|
||||
"Linked Management gefunden": 47, # AV (vorher AK)
|
||||
"Linked Disponent gefunden": 48, # AW (vorher AL)
|
||||
# LinkedIn-Kontakte (AU-AX) - VORHER AT-AW
|
||||
"Linked Serviceleiter gefunden": 46, # AU (vorher AT)
|
||||
"Linked It-Leiter gefunden": 47, # AV (vorher AU)
|
||||
"Linked Management gefunden": 48, # AW (vorher AV)
|
||||
"Linked Disponent gefunden": 49, # AX (vorher AW)
|
||||
|
||||
# Konsolidierte Werte & ML (AX-AZ)
|
||||
"Finaler Umsatz (Wiki>CRM)": 49, # AX (vorher AV)
|
||||
"Finaler Mitarbeiter (Wiki>CRM)": 50, # AY (vorher AW)
|
||||
"Geschaetzter Techniker Bucket": 51, # AZ (vorher AU)
|
||||
# Konsolidierte Werte & ML (AY-BA) - VORHER AX-AZ
|
||||
"Finaler Umsatz (Wiki>CRM)": 50, # AY (vorher AX)
|
||||
"Finaler Mitarbeiter (Wiki>CRM)": 51, # AZ (vorher AY)
|
||||
"Geschaetzter Techniker Bucket": 52, # BA (vorher AZ)
|
||||
|
||||
# Timestamps (Rest) & System (BA-BD)
|
||||
"Contact Search Timestamp": 52, # BA (vorher AM)
|
||||
"Timestamp letzte Pruefung": 53, # BB (vorher AO, ChatGPT-bezogen)
|
||||
"Version": 54, # BC (vorher AP)
|
||||
"Tokens": 55, # BD (vorher AQ)
|
||||
# Timestamps (Rest) & System (BB-BE) - VORHER BA-BD
|
||||
"Contact Search Timestamp": 53, # BB (vorher BA)
|
||||
"Timestamp letzte Pruefung": 54, # BC (vorher BB)
|
||||
"Version": 55, # BD (vorher BC)
|
||||
"Tokens": 56, # BE (vorher BD)
|
||||
}
|
||||
|
||||
# --- Globale Variablen fuer Branch Mapping (werden von load_target_schema() befuellt) ---
|
||||
@@ -1107,6 +1109,8 @@ def load_target_schema(csv_filepath=BRANCH_MAPPING_FILE):
|
||||
schema_lines.append("\nBitte ordne das Unternehmen ausschliesslich in einen dieser Bereiche ein. Gib NUR den exakten Kurznamen der Branche zurueck (keine Praefixe oder zusaetzliche Erklaerungen ausser im 'Begruendung'-Feld).")
|
||||
schema_lines.append("Antworte ausschliesslich im folgenden Format (keine Einleitung, kein Schlusssatz):")
|
||||
schema_lines.append("Branche: <Exakter Kurzname der Branche aus der Liste>")
|
||||
# NEU: Konfidenz hier ins Antwortformat aufnehmen
|
||||
schema_lines.append("Konfidenz: <Hoch, Mittel oder Niedrig>")
|
||||
schema_lines.append("Uebereinstimmung: <ok oder X (Vergleich deines Vorschlags mit der extrahierten Kurzform der CRM-Referenz)>")
|
||||
schema_lines.append("Begruendung: <Sehr kurze Begruendung fuer deinen Branchenvorschlag>")
|
||||
TARGET_SCHEMA_STRING = "\n".join(schema_lines)
|
||||
@@ -1473,21 +1477,45 @@ def evaluate_branche_chatgpt(crm_branche, beschreibung, wiki_branche, wiki_kateg
|
||||
|
||||
if not ALLOWED_TARGET_BRANCHES:
|
||||
logger.critical("FEHLER in evaluate_branche_chatgpt: Ziel-Branchenschema nicht geladen.")
|
||||
return {"branch": "FEHLER - SCHEMA FEHLT", "consistency": "error_schema_missing", "justification": "Fehler: Ziel-Schema nicht geladen"}
|
||||
return {
|
||||
"branch": "FEHLER - SCHEMA FEHLT",
|
||||
"confidence": "N/A", # NEU: Konfidenz auch bei Fehler
|
||||
"consistency": "error_schema_missing",
|
||||
"justification": "Fehler: Ziel-Schema nicht geladen"
|
||||
}
|
||||
|
||||
allowed_branches_lookup = {b.lower(): b for b in ALLOWED_TARGET_BRANCHES}
|
||||
|
||||
# --- Prompt für ChatGPT erstellen ---
|
||||
# Beginnt mit den Regeln und der Liste der gueltigen Kurzformen (TARGET_SCHEMA_STRING)
|
||||
# Fügt dann den Hinweis auf Fokusbranchen hinzu (FOCUS_BRANCHES_PROMPT_PART)
|
||||
prompt_parts = [TARGET_SCHEMA_STRING, FOCUS_BRANCHES_PROMPT_PART] # <<< HIER FOCUS_BRANCHES_PROMPT_PART EINFÜGEN
|
||||
prompt_parts.append("\nOrdne das Unternehmen anhand folgender Angaben exakt einer Branche des Ziel-Branchenschemas (Kurzformen) zu:")
|
||||
|
||||
# ANPASSUNG: Antwortformat im TARGET_SCHEMA_STRING anpassen (dies geschieht in load_target_schema, aber der Effekt ist hier relevant)
|
||||
# Der TARGET_SCHEMA_STRING wird in load_target_schema() aufgebaut.
|
||||
# Wir müssen sicherstellen, dass die Anweisung für das Antwortformat dort auch "Konfidenz:" enthält.
|
||||
# Temporäre Anpassung hier, um den Logikfluss zu zeigen - idealerweise wird TARGET_SCHEMA_STRING direkt korrekt in load_target_schema generiert.
|
||||
|
||||
# Neuer Prompt-Teil für das Antwortformat (wird in TARGET_SCHEMA_STRING integriert)
|
||||
# Dies ist nur zur Illustration, wie TARGET_SCHEMA_STRING aussehen sollte.
|
||||
# Die eigentliche Änderung für TARGET_SCHEMA_STRING muss in der Funktion load_target_schema erfolgen.
|
||||
# TARGET_SCHEMA_STRING sollte so aussehen (Auszug für Antwortformat):
|
||||
# "...
|
||||
# Antworte ausschliesslich im folgenden Format (keine Einleitung, kein Schlusssatz):
|
||||
# Branche: <Exakter Kurzname der Branche aus der Liste>
|
||||
# Konfidenz: <Hoch, Mittel oder Niedrig>
|
||||
# Uebereinstimmung: <ok oder X (Vergleich deines Vorschlags mit der extrahierten Kurzform der CRM-Referenz)>
|
||||
# Begruendung: <Sehr kurze Begruendung fuer deinen Branchenvorschlag>
|
||||
# ..."
|
||||
|
||||
prompt_parts = [TARGET_SCHEMA_STRING, FOCUS_BRANCHES_PROMPT_PART]
|
||||
prompt_parts.append("\nOrdne das Unternehmen anhand folgender Angaben exakt einer Branche des Ziel-Branchenschemas (Kurzformen) zu.")
|
||||
# NEU: Anweisung zur Konfidenz explizit hinzufügen, falls nicht schon im TARGET_SCHEMA_STRING enthalten
|
||||
prompt_parts.append("Gib zusätzlich eine Konfidenz für deine Branchenwahl an (Hoch, Mittel oder Niedrig).")
|
||||
|
||||
|
||||
# Informationen hinzufügen (unverändert)
|
||||
if crm_branche and str(crm_branche).strip() and str(crm_branche).strip().lower() != "k.a.": prompt_parts.append(f"- CRM-Branche (Referenz): {str(crm_branche).strip()}")
|
||||
# Fallback-Logik für beschreibung vs. website_summary (basierend auf Ihrer alten Funktion)
|
||||
if wiki_branche and str(wiki_branche).strip() and str(wiki_branche).strip().lower() != "k.a.":
|
||||
# Wenn Wiki-Daten vorhanden sind, nutzen wir die CRM-Beschreibung als Hauptbeschreibung
|
||||
if beschreibung and str(beschreibung).strip() and str(beschreibung).strip().lower() != "k.a.":
|
||||
prompt_parts.append(f"- Beschreibung (CRM): {str(beschreibung).strip()[:500]}...")
|
||||
if website_summary and str(website_summary).strip() and str(website_summary).strip().lower() != "k.a." and not str(website_summary).strip().startswith("k.A. (Fehler"):
|
||||
@@ -1495,62 +1523,82 @@ def evaluate_branche_chatgpt(crm_branche, beschreibung, wiki_branche, wiki_kateg
|
||||
prompt_parts.append(f"- Wikipedia-Branche: {str(wiki_branche).strip()[:300]}...")
|
||||
if wiki_kategorien and str(wiki_kategorien).strip() and str(wiki_kategorien).strip().lower() != "k.a.":
|
||||
prompt_parts.append(f"- Wikipedia-Kategorien: {str(wiki_kategorien).strip()[:500]}...")
|
||||
else: # Keine validen Wiki-Daten
|
||||
else:
|
||||
logger.debug("evaluate_branche_chatgpt: Keine validen Wiki-Daten, nutze Website-Zusammenfassung als primäre Beschreibung (falls vorhanden).")
|
||||
if website_summary and str(website_summary).strip() and str(website_summary).strip().lower() != "k.a." and not str(website_summary).strip().startswith("k.A. (Fehler"):
|
||||
prompt_parts.append(f"- Website-Zusammenfassung (als Hauptbeschreibung): {str(website_summary).strip()[:800]}...") # Ggf. länger, da Hauptinfo
|
||||
elif beschreibung and str(beschreibung).strip() and str(beschreibung).strip().lower() != "k.a.": # Fallback auf CRM Beschreibung
|
||||
prompt_parts.append(f"- Website-Zusammenfassung (als Hauptbeschreibung): {str(website_summary).strip()[:800]}...")
|
||||
elif beschreibung and str(beschreibung).strip() and str(beschreibung).strip().lower() != "k.a.":
|
||||
prompt_parts.append(f"- Beschreibung (CRM, als Hauptbeschreibung): {str(beschreibung).strip()[:800]}...")
|
||||
|
||||
|
||||
if len(prompt_parts) < (3 + (1 if FOCUS_BRANCHES_PROMPT_PART else 0)): # Mind. TARGET_SCHEMA + FOCUS_PART (falls vorhanden) + Instruktion + 1 Infoquelle
|
||||
if len(prompt_parts) < (3 + (1 if FOCUS_BRANCHES_PROMPT_PART else 0)):
|
||||
logger.warning("Warnung in evaluate_branche_chatgpt: Zu wenige Informationen für Branchenevaluierung.")
|
||||
crm_short_branch_for_fallback = "k.A."
|
||||
if crm_branche and isinstance(crm_branche, str):
|
||||
parts = crm_branche.split(">", 1)
|
||||
crm_short_branch_for_fallback = parts[1].strip() if len(parts) > 1 else crm_branche.strip()
|
||||
return {"branch": crm_short_branch_for_fallback if crm_short_branch_for_fallback.lower() != "k.a." else "FEHLER",
|
||||
"consistency": "error_no_info",
|
||||
"justification": "Fehler: Zu wenige Informationen fuer eine Einschaetzung"}
|
||||
if crm_branche and isinstance(crm_branche, str) and crm_branche.strip().lower() != "k.a.":
|
||||
# Da Spalte H jetzt 1:1 ist, können wir sie direkt nehmen
|
||||
crm_short_branch_for_fallback = crm_branche.strip()
|
||||
|
||||
return {
|
||||
"branch": crm_short_branch_for_fallback if crm_short_branch_for_fallback.lower() != "k.a." else "FEHLER",
|
||||
"confidence": "N/A", # NEU
|
||||
"consistency": "error_no_info",
|
||||
"justification": "Fehler: Zu wenige Informationen fuer eine Einschaetzung"
|
||||
}
|
||||
|
||||
prompt = "\n".join(filter(None, prompt_parts)) # filter(None, ...) um leere Strings aus FOCUS_BRANCHES_PROMPT_PART zu entfernen
|
||||
# logger.debug(f"Erstellter Prompt fuer Branchenevaluierung:\n---\n{prompt}\n---")
|
||||
|
||||
# --- ChatGPT aufrufen (Rest der Funktion bleibt wie in Block 10/20) ---
|
||||
# ... (ChatGPT Call, Parsing, Validierung, Fallback-Logik) ...
|
||||
# Wichtig: Die API-Key Ladung und der openai-Import sollten jetzt global (Block 1) erfolgen
|
||||
# und nicht mehr innerhalb dieser Funktion.
|
||||
# Ihre alte Funktion hat api_key.txt gelesen, das ist jetzt Teil von Config.load_api_keys().
|
||||
prompt = "\n".join(filter(None, prompt_parts))
|
||||
# logger.debug(f"Erstellter Prompt fuer Branchenevaluierung:\n---\n{prompt}\n---") # Kann bei Bedarf aktiviert werden
|
||||
|
||||
chat_response = None
|
||||
try:
|
||||
chat_response = call_openai_chat(prompt, temperature=0.0) # Nutzt globale Funktion
|
||||
chat_response = call_openai_chat(prompt, temperature=0.0)
|
||||
if not chat_response:
|
||||
logger.error("call_openai_chat gab unerwarteterweise None/leer zurueck fuer Branchenevaluation.")
|
||||
raise APIError("Keine Antwort von OpenAI erhalten fuer Branchenevaluation.")
|
||||
# Hier wird eine Exception vom Typ openai.error.APIError erwartet, die vom @retry_on_failure gefangen wird.
|
||||
# Wenn es hierher kommt, ist es ein unerwarteter Zustand.
|
||||
raise APIError("Keine Antwort von OpenAI erhalten fuer Branchenevaluation.") # Import APIError from openai.error
|
||||
except Exception as e:
|
||||
logger.error(f"Endgueltiger FEHLER beim OpenAI-Aufruf fuer Branchenevaluation: {e}")
|
||||
crm_short_branch_for_fallback = "k.A."
|
||||
if crm_branche and isinstance(crm_branche, str):
|
||||
parts = crm_branche.split(">", 1)
|
||||
crm_short_branch_for_fallback = parts[1].strip() if len(parts) > 1 else crm_branche.strip()
|
||||
return {"branch": crm_short_branch_for_fallback if crm_short_branch_for_fallback.lower() != "k.a." else "FEHLER API",
|
||||
"consistency": "error_api_failed",
|
||||
"justification": f"Fehler API: {str(e)[:100]}"}
|
||||
if crm_branche and isinstance(crm_branche, str) and crm_branche.strip().lower() != "k.a.":
|
||||
crm_short_branch_for_fallback = crm_branche.strip()
|
||||
|
||||
return {
|
||||
"branch": crm_short_branch_for_fallback if crm_short_branch_for_fallback.lower() != "k.a." else "FEHLER API",
|
||||
"confidence": "N/A", # NEU
|
||||
"consistency": "error_api_failed",
|
||||
"justification": f"Fehler API: {str(e)[:100]}"
|
||||
}
|
||||
|
||||
# --- Antwort parsen (wie gehabt) ---
|
||||
# --- Antwort parsen ---
|
||||
lines = chat_response.strip().split("\n")
|
||||
result = {"branch": None, "consistency": None, "justification": ""}
|
||||
result = {
|
||||
"branch": None,
|
||||
"confidence": "N/A", # NEU: Initialwert
|
||||
"consistency": None,
|
||||
"justification": ""
|
||||
}
|
||||
suggested_branch = ""
|
||||
parsed_branch = False
|
||||
parsed_confidence = False # NEU
|
||||
|
||||
for line in lines:
|
||||
line_lower = line.lower(); line_stripped = line.strip()
|
||||
if line_lower.startswith("branche:"):
|
||||
suggested_branch = line_stripped.split(":", 1)[1].strip().strip('"\'')
|
||||
parsed_branch = True
|
||||
elif line_lower.startswith("konfidenz:"): # NEU
|
||||
confidence_text = line_stripped.split(":", 1)[1].strip().strip('"\'')
|
||||
# Validierung des Konfidenzwertes
|
||||
valid_confidences = ["hoch", "mittel", "niedrig"]
|
||||
if confidence_text.lower() in valid_confidences:
|
||||
result["confidence"] = confidence_text.capitalize() # Speichere mit großem Anfangsbuchstaben
|
||||
else:
|
||||
logger.warning(f"Ungueltiger Konfidenzwert '{confidence_text}' von ChatGPT erhalten. Setze auf 'N/A'.")
|
||||
result["confidence"] = "N/A (Ungueltig)"
|
||||
parsed_confidence = True
|
||||
elif line_lower.startswith("uebereinstimmung:") or line_lower.startswith("ubereinstimmung:"):
|
||||
pass
|
||||
elif line_lower.startswith("begruendung:") or line_lower.startswith("begruendung:"):
|
||||
pass # Wird spaeter basierend auf 'branch' und 'crm_branche' gesetzt
|
||||
elif line_lower.startswith("begruendung:") or line_lower.startswith("begruendung:"): # KORREKTUR: war "begruendung:"
|
||||
justification_text = line_stripped.split(":", 1)[1].strip()
|
||||
if result["justification"]: result["justification"] += " " + justification_text
|
||||
else: result["justification"] = justification_text
|
||||
@@ -1558,27 +1606,34 @@ def evaluate_branche_chatgpt(crm_branche, beschreibung, wiki_branche, wiki_kateg
|
||||
if not parsed_branch or not suggested_branch or suggested_branch.lower() in ["k.a.", "n/a"]:
|
||||
logger.error(f"Fehler in evaluate_branche_chatgpt: Konnte 'Branche:' nicht oder nur leer/k.A. aus Antwort parsen: {chat_response[:500]}...")
|
||||
crm_short_branch_for_fallback = "k.A."
|
||||
if crm_branche and isinstance(crm_branche, str):
|
||||
parts = crm_branche.split(">", 1)
|
||||
crm_short_branch_for_fallback = parts[1].strip() if len(parts) > 1 else crm_branche.strip()
|
||||
return {"branch": crm_short_branch_for_fallback if crm_short_branch_for_fallback.lower() != "k.a." else "FEHLER PARSING",
|
||||
"consistency": "error_parsing",
|
||||
"justification": f"Fehler Parsing: Antwortformat unerwartet."}
|
||||
if crm_branche and isinstance(crm_branche, str) and crm_branche.strip().lower() != "k.a.":
|
||||
crm_short_branch_for_fallback = crm_branche.strip()
|
||||
|
||||
return {
|
||||
"branch": crm_short_branch_for_fallback if crm_short_branch_for_fallback.lower() != "k.a." else "FEHLER PARSING",
|
||||
"confidence": result.get("confidence", "N/A"), # NEU: Konfidenz auch bei Parsing-Fehler der Branche
|
||||
"consistency": "error_parsing",
|
||||
"justification": f"Fehler Parsing: Antwortformat unerwartet."
|
||||
}
|
||||
|
||||
# Wenn Konfidenz nicht explizit geparst wurde, aber Branche schon
|
||||
if not parsed_confidence:
|
||||
logger.warning("Konnte 'Konfidenz:' nicht aus ChatGPT-Antwort parsen. Setze auf 'N/A'.")
|
||||
result["confidence"] = "N/A (Nicht geparst)"
|
||||
|
||||
# --- Validierung und Fallback (wie gehabt) ---
|
||||
|
||||
# --- Validierung und Fallback (wie gehabt, aber mit CRM-Branche direkt) ---
|
||||
final_branch = None
|
||||
suggested_branch_lower = suggested_branch.lower()
|
||||
|
||||
if suggested_branch_lower in allowed_branches_lookup:
|
||||
final_branch = allowed_branches_lookup[suggested_branch_lower]
|
||||
logger.debug(f"ChatGPT-Branchenvorschlag '{suggested_branch}' ist gueltig ('{final_branch}').")
|
||||
result["consistency"] = "pending_comparison"
|
||||
result["consistency"] = "pending_comparison"
|
||||
else:
|
||||
logger.debug(f"ChatGPT-Branchenvorschlag '{suggested_branch}' ist NICHT im Ziel-Schema. Starte Fallback...")
|
||||
crm_short_branch = "k.A."
|
||||
if crm_branche and isinstance(crm_branche, str):
|
||||
parts = crm_branche.split(">", 1)
|
||||
crm_short_branch = parts[1].strip() if len(parts) > 1 else crm_branche.strip()
|
||||
# CRM Branche ist jetzt direkt die Kurzform
|
||||
crm_short_branch = crm_branche.strip() if crm_branche and isinstance(crm_branche, str) else "k.A."
|
||||
|
||||
crm_short_branch_lower = crm_short_branch.lower()
|
||||
if crm_short_branch != "k.A." and crm_short_branch_lower in allowed_branches_lookup:
|
||||
@@ -1587,33 +1642,34 @@ def evaluate_branche_chatgpt(crm_branche, beschreibung, wiki_branche, wiki_kateg
|
||||
fallback_reason = f"Fallback: Ungueltiger ChatGPT-Vorschlag ('{suggested_branch}'). Gueltige CRM-Kurzform '{final_branch}' verwendet."
|
||||
result["justification"] = f"{fallback_reason} (ChatGPT Begruendung war: {result.get('justification', 'Keine')})"
|
||||
logger.info(f"Fallback auf gueltige CRM-Kurzform erfolgreich: '{final_branch}'")
|
||||
result["confidence"] = "N/A (Fallback)" # Konfidenz ist nicht relevant bei Fallback auf CRM
|
||||
else:
|
||||
final_branch = suggested_branch # Behalte ungueltigen Vorschlag für Info, wird aber als Fehler markiert
|
||||
final_branch = suggested_branch
|
||||
result["consistency"] = "fallback_invalid"
|
||||
error_reason = f"Fehler: Ungueltiger ChatGPT-Vorschlag ('{suggested_branch}') und keine gueltige CRM-Kurzform ('{crm_short_branch}') als Fallback."
|
||||
result["justification"] = f"{error_reason} (ChatGPT Begruendung war: {result.get('justification', 'Keine')})"
|
||||
logger.warning(f"Fallback fehlgeschlagen. Ungueltiger Vorschlag: '{final_branch}', Ungueltige CRM-Kurzform: '{crm_short_branch}'")
|
||||
final_branch = "FEHLER - UNGUELTIGE ZUWEISUNG" # Expliziter Fehlerwert
|
||||
final_branch = "FEHLER - UNGUELTIGE ZUWEISUNG"
|
||||
result["confidence"] = "N/A (Fehler)" # Konfidenz nicht relevant bei Fehler
|
||||
|
||||
result["branch"] = final_branch if final_branch else "FEHLER"
|
||||
|
||||
crm_short_to_compare = "k.A."
|
||||
if crm_branche and isinstance(crm_branche, str):
|
||||
parts = crm_branche.split(">", 1)
|
||||
crm_short_to_compare = parts[1].strip() if len(parts) > 1 else crm_branche.strip()
|
||||
|
||||
# Konsistenzprüfung: ok oder X
|
||||
crm_branch_to_compare = crm_branche.strip() if crm_branche and isinstance(crm_branche, str) else "k.A."
|
||||
# Nur prüfen, wenn kein Fallback auf CRM oder Fehler vorliegt
|
||||
if result["consistency"] == "pending_comparison" and result["branch"] != "FEHLER" and not result["branch"].startswith("FEHLER"):
|
||||
if result["branch"].lower() == crm_short_to_compare.lower():
|
||||
if result["branch"].lower() == crm_branch_to_compare.lower(): # Direktvergleich, da CRM Spalte H angepasst wurde
|
||||
result["consistency"] = "ok"
|
||||
else:
|
||||
result["consistency"] = "X"
|
||||
|
||||
if result["consistency"] == "pending_comparison":
|
||||
result["consistency"] = "error_comparison_failed"
|
||||
elif result["consistency"] is None:
|
||||
# Sicherstellen, dass consistency immer einen Wert hat
|
||||
if result["consistency"] == "pending_comparison": # Sollte nach obiger Logik nicht mehr der Fall sein
|
||||
result["consistency"] = "error_comparison_failed"
|
||||
elif result["consistency"] is None: # Fallback, falls etwas schiefgelaufen ist
|
||||
result["consistency"] = "error_unknown_state"
|
||||
|
||||
logger.debug(f"Finale Branch-Evaluation Ergebnis: Branch='{result.get('branch')}', Consistency='{result.get('consistency')}', Justification='{result.get('justification', '')[:100]}...'")
|
||||
logger.debug(f"Finale Branch-Evaluation Ergebnis: Branch='{result.get('branch')}', Confidence='{result.get('confidence')}', Consistency='{result.get('consistency')}', Justification='{result.get('justification', '')[:100]}...'")
|
||||
return result
|
||||
|
||||
|
||||
@@ -2444,7 +2500,7 @@ def alignment_demo(sheet):
|
||||
"ReEval Flag", "CRM Name", "CRM Kurzform", "CRM Website", "CRM Ort", "CRM Land", "CRM Beschreibung", "CRM Branche", "CRM Beschreibung Branche extern", "CRM Anzahl Techniker", "CRM Umsatz", "CRM Anzahl Mitarbeiter", "CRM Vorschlag Wiki URL",
|
||||
"Wiki URL", "Wiki Sitz Stadt", "Wiki Sitz Land", "Wiki Absatz", "Wiki Branche", "Wiki Umsatz", "Wiki Mitarbeiter", "Wiki Kategorien", "Wikipedia Timestamp", "Wiki Verif. Timestamp", "SerpAPI Wiki Search Timestamp", "Chat Wiki Konsistenzpruefung", "Chat Begründung Wiki Inkonsistenz", "Chat Vorschlag Wiki Artikel", "Begründung bei Abweichung",
|
||||
"Website Rohtext", "Website Zusammenfassung", "Website Meta-Details", "Website Scrape Timestamp", "URL Prüfstatus",
|
||||
"Chat Vorschlag Branche", "Chat Konsistenz Branche", "Chat Begruendung Abweichung Branche", "Chat Prüfung FSM Relevanz", "Chat Begründung für FSM Relevanz", "Chat Schätzung Anzahl Mitarbeiter", "Chat Konsistenzprüfung Mitarbeiterzahl", "Chat Begründung Abweichung Mitarbeiterzahl", "Chat Einschätzung Anzahl Servicetechniker", "Chat Begründung Abweichung Anzahl Servicetechniker", "Chat Schätzung Umsatz", "Chat Begründung Abweichung Umsatz",
|
||||
"Chat Vorschlag Branche", "Chat Branche Konfidenz", "Chat Konsistenz Branche", "Chat Begruendung Abweichung Branche", "Chat Prüfung FSM Relevanz", "Chat Begründung für FSM Relevanz", "Chat Schätzung Anzahl Mitarbeiter", "Chat Konsistenzprüfung Mitarbeiterzahl", "Chat Begründung Abweichung Mitarbeiterzahl", "Chat Einschätzung Anzahl Servicetechniker", "Chat Begründung Abweichung Anzahl Servicetechniker", "Chat Schätzung Umsatz", "Chat Begründung Abweichung Umsatz",
|
||||
"Linked Serviceleiter gefunden", "Linked It-Leiter gefunden", "Linked Management gefunden", "Linked Disponent gefunden",
|
||||
"Finaler Umsatz (Wiki>CRM)", "Finaler Mitarbeiter (Wiki>CRM)", "Geschaetzter Techniker Bucket",
|
||||
"Contact Search Timestamp", "Timestamp letzte Prüfung", "Version", "Tokens"
|
||||
@@ -2453,7 +2509,7 @@ def alignment_demo(sheet):
|
||||
"CRM", "CRM", "CRM", "CRM", "CRM", "CRM/Manuell", "CRM", "CRM", "CRM", "CRM", "CRM", "CRM", "CRM",
|
||||
"Wikipediascraper/SerpAPI/ChatGPT/Manuell", "Wikipediascraper", "Wikipediascraper", "Wikipediascraper", "Wikipediascraper", "Wikipediascraper", "Wikipediascraper", "Wikipediascraper", "System", "System", "System", "ChatGPT API", "ChatGPT API", "ChatGPT API", "System/Manuell",
|
||||
"Web Scraper", "ChatGPT API", "Web Scraper", "System", "System/Web Scraper",
|
||||
"ChatGPT API", "System/ChatGPT API", "ChatGPT API", "ChatGPT API", "ChatGPT API", "ChatGPT API", "System/ChatGPT API", "ChatGPT API", "ChatGPT API", "ChatGPT API", "ChatGPT API", "ChatGPT API",
|
||||
"ChatGPT API", "ChatGPT API", "System/ChatGPT API", "ChatGPT API", "ChatGPT API", "ChatGPT API", "ChatGPT API", "System/ChatGPT API", "ChatGPT API", "ChatGPT API", "ChatGPT API", "ChatGPT API", "ChatGPT API",
|
||||
"LinkedIn (via SerpApi)", "LinkedIn (via SerpApi)", "LinkedIn (via SerpApi)", "LinkedIn (via SerpApi)",
|
||||
"Skript (Wiki/CRM Logik)", "Skript (Wiki/CRM Logik)", "ML Modell / Skript",
|
||||
"System", "System", "System", "System"
|
||||
@@ -2462,7 +2518,7 @@ def alignment_demo(sheet):
|
||||
"Prozess", "Firmenname", "Firmenname", "Website", "Ort", "Land", "Beschreibung (Text)", "Branche", "Branche", "Anzahl Servicetechniker", "Umsatz", "Anzahl Mitarbeiter", "Wikipedia Artikel URL",
|
||||
"Wikipedia Artikel URL", "Ort", "Land", "Beschreibung (Text)", "Branche", "Umsatz", "Anzahl Mitarbeiter", "Kategorien (Text)", "Timestamp", "Timestamp", "Timestamp", "Verifizierung Wiki-Artikel", "Begründung Verifizierung", "Wikipedia Artikel URL (Vorschlag)", "Begründung URL-Abweichung",
|
||||
"Website-Content", "Website-Content (Zusammenfassung)", "Website-Content (Meta)", "Timestamp", "Prozess-Status",
|
||||
"Branche (Vorschlag KI)", "Branche (Konsistenz)", "Branche (Begründung KI)", "FSM Relevanz (KI)", "FSM Relevanz (Begründung KI)", "Anzahl Mitarbeiter (KI)", "Anzahl Mitarbeiter (Konsistenz KI)", "Anzahl Mitarbeiter (Begründung KI)", "Anzahl Servicetechniker (KI)", "Anzahl Servicetechniker (Begründung KI)", "Umsatz (KI)", "Umsatz (Begründung KI)",
|
||||
"Branche (Vorschlag KI)", "Branche (Konfidenz KI)", "Branche (Konsistenz)", "Branche (Begründung KI)", "FSM Relevanz (KI)", "FSM Relevanz (Begründung KI)", "Anzahl Mitarbeiter (KI)", "Anzahl Mitarbeiter (Konsistenz KI)", "Anzahl Mitarbeiter (Begründung KI)", "Anzahl Servicetechniker (KI)", "Anzahl Servicetechniker (Begründung KI)", "Umsatz (KI)", "Umsatz (Begründung KI)",
|
||||
"Kontakte (Anzahl)", "Kontakte (Anzahl)", "Kontakte (Anzahl)", "Kontakte (Anzahl)",
|
||||
"Umsatz (Konsolidiert)", "Anzahl Mitarbeiter (Konsolidiert)", "Anzahl Servicetechniker (Bucket ML)",
|
||||
"Timestamp", "Timestamp", "Skript Version", "API Tokens"
|
||||
@@ -2473,7 +2529,7 @@ def alignment_demo(sheet):
|
||||
"Enthält eine manuell gepflegte (normalisierte) Kurzform des Firmennamens...", #C
|
||||
"Von uns ermittelte Website des Unternehmens. Kann durch 'website_lookup' oder 'check_urls' aktualisiert werden.", #D
|
||||
"Von uns ermittelter Ort des Unternehmens.", #E
|
||||
"Land des Unternehmenssitzes laut CRM (manuell zu pflegen).", #F NEU
|
||||
"Land des Unternehmenssitzes laut CRM (manuell zu pflegen).", #F
|
||||
"Kurze Beschreibung des Unternehmens aus CRM.", #G
|
||||
"Aktuelle Branchenzuweisung entsprechend unserem Ziel-Branchenschema (manuell oder aus Altsystem).", #H
|
||||
"Von Dealfront gelieferte externe Beschreibung der Branche...", #I
|
||||
@@ -2482,8 +2538,8 @@ def alignment_demo(sheet):
|
||||
"Von uns recherchierte Anzahl der Mitarbeiter (aus CRM).", #L
|
||||
"Enthält aus einer alten Recherche Vorschläge für die Wikipedia URL zum Unternehmen...", #M
|
||||
"Finale Wikipedia URL des Unternehmens.", #N
|
||||
"Aus Wikipedia-Infobox extrahierte Stadt des Unternehmenssitzes.", #O NEU
|
||||
"Aus Wikipedia-Infobox extrahiertes Land des Unternehmenssitzes.", #P NEU
|
||||
"Aus Wikipedia-Infobox extrahierte Stadt des Unternehmenssitzes.", #O
|
||||
"Aus Wikipedia-Infobox extrahiertes Land des Unternehmenssitzes.", #P
|
||||
"Erster aussagekräftiger Absatz des Wikipedia-Artikels (N).", #Q
|
||||
"Aus der Wikipedia-Infobox extrahierte Branche(n).", #R
|
||||
"Aus der Wikipedia-Infobox extrahierter Umsatz (normalisiert in Mio. €).", #S
|
||||
@@ -2498,32 +2554,33 @@ def alignment_demo(sheet):
|
||||
"Wird derzeit primär geleert. Ursprünglich für Begründung bei Abweichung CRM Vorschlag Wiki URL (M alt) vs. gefundener Wiki-URL (N).", #AB
|
||||
"Roh extrahierter Textinhalt der Website. Basis für Zusammenfassung. Kann auch Fehlermeldungen oder Marker enthalten.", #AC
|
||||
"KI-generierte Zusammenfassung des Website-Rohtextes (AC).", #AD
|
||||
"Extrahierte Meta-Daten der Website: Title, Meta-Description, H1-H3 Überschriften.", #AE NEU
|
||||
"Extrahierte Meta-Daten der Website: Title, Meta-Description, H1-H3 Überschriften.", #AE
|
||||
"Zeitstempel des letzten Website-Scraping/Summarization-Versuchs (für AC, AD).", #AF
|
||||
"Status der URL-Prüfung (z.B. 'URL_CHECK_NEEDED', 'URL_OK').", #AG NEU
|
||||
"Status der URL-Prüfung (z.B. 'URL_CHECK_NEEDED', 'URL_OK').", #AG
|
||||
"Branchenvorschlag von ChatGPT basierend auf allen verfügbaren Informationen.", #AH
|
||||
"Konsistenzprüfung: 'ok', wenn ChatGPT-Vorschlag (AH) mit CRM-Branche (H) übereinstimmt.", #AI
|
||||
"Von ChatGPT generierte Begründung für den Branchenvorschlag (AH).", #AJ
|
||||
"Bewertung der FSM-Relevanz durch ChatGPT. (Platzhalter)", #AK
|
||||
"Von ChatGPT generierte Begründung für die Einschätzung der FSM-Relevanz. (Platzhalter)", #AL
|
||||
"Von ChatGPT geschätzte Anzahl der Mitarbeiter. (Platzhalter)", #AM
|
||||
"Konsistenzprüfung der von ChatGPT geschätzten Mitarbeiterzahl (AM). (Platzhalter)", #AN
|
||||
"Von ChatGPT generierte Begründung bei signifikanter Abweichung der geschätzten Mitarbeiterzahl. (Platzhalter)", #AO
|
||||
"Von ChatGPT geschätzte Anzahl der Servicetechniker. (Platzhalter)", #AP
|
||||
"Von ChatGPT generierte Begründung für die Einschätzung der Servicetechniker-Anzahl. (Platzhalter)", #AQ
|
||||
"Von ChatGPT geschätzter Umsatz. (Platzhalter)", #AR
|
||||
"Von ChatGPT generierte Begründung bei signifikanter Abweichung der geschätzten Umsatzzahlen. (Platzhalter)", #AS
|
||||
"Anzahl der via SerpAPI gefundenen LinkedIn-Kontakte für die Kategorie 'Serviceleiter'.", #AT
|
||||
"Anzahl der via SerpAPI gefundenen LinkedIn-Kontakte für die Kategorie 'IT-Leiter'.", #AU
|
||||
"Anzahl der via SerpAPI gefundenen LinkedIn-Kontakte für die Kategorie 'Management'.", #AV
|
||||
"Anzahl der via SerpAPI gefundenen LinkedIn-Kontakte für die Kategorie 'Disponent'.", #AW
|
||||
"Konsolidierter Umsatzwert in Mio. €. Priorisiert Wiki (S) > CRM (K).", #AX
|
||||
"Konsolidierte Mitarbeiterzahl. Priorisiert Wiki (T) > CRM (L).", #AY
|
||||
"Ergebnis der Schätzung durch das trainierte Machine-Learning-Modell.", #AZ
|
||||
"Zeitstempel der letzten Kontaktsuche via SerpAPI für diese Zeile.", #BA
|
||||
"Zeitstempel der letzten übergreifenden Prüfung/Bewertung durch ChatGPT (z.B. Branchenevaluation AH-AS).", #BB
|
||||
"Version des Skripts, die diese Zeile zuletzt signifikant bearbeitet hat.", #BC
|
||||
"Verbrauchte Tokens für OpenAI API-Aufrufe für diese Zeile." #BD
|
||||
"Konfidenz des ChatGPT-Branchenvorschlags (AH), z.B. Hoch/Mittel/Niedrig.", #AI (NEU)
|
||||
"Konsistenzprüfung: 'ok', wenn ChatGPT-Vorschlag (AH) mit CRM-Branche (H) übereinstimmt.", #AJ
|
||||
"Von ChatGPT generierte Begründung für den Branchenvorschlag (AH).", #AK
|
||||
"Bewertung der FSM-Relevanz durch ChatGPT. (Platzhalter)", #AL
|
||||
"Von ChatGPT generierte Begründung für die Einschätzung der FSM-Relevanz. (Platzhalter)", #AM
|
||||
"Von ChatGPT geschätzte Anzahl der Mitarbeiter. (Platzhalter)", #AN
|
||||
"Konsistenzprüfung der von ChatGPT geschätzten Mitarbeiterzahl (AM). (Platzhalter)", #AO
|
||||
"Von ChatGPT generierte Begründung bei signifikanter Abweichung der geschätzten Mitarbeiterzahl. (Platzhalter)", #AP
|
||||
"Von ChatGPT geschätzte Anzahl der Servicetechniker. (Platzhalter)", #AQ
|
||||
"Von ChatGPT generierte Begründung für die Einschätzung der Servicetechniker-Anzahl. (Platzhalter)", #AR
|
||||
"Von ChatGPT geschätzter Umsatz. (Platzhalter)", #AS
|
||||
"Von ChatGPT generierte Begründung bei signifikanter Abweichung der geschätzten Umsatzzahlen. (Platzhalter)", #AT
|
||||
"Anzahl der via SerpAPI gefundenen LinkedIn-Kontakte für die Kategorie 'Serviceleiter'.", #AU
|
||||
"Anzahl der via SerpAPI gefundenen LinkedIn-Kontakte für die Kategorie 'IT-Leiter'.", #AV
|
||||
"Anzahl der via SerpAPI gefundenen LinkedIn-Kontakte für die Kategorie 'Management'.", #AW
|
||||
"Anzahl der via SerpAPI gefundenen LinkedIn-Kontakte für die Kategorie 'Disponent'.", #AX
|
||||
"Konsolidierter Umsatzwert in Mio. €. Priorisiert Wiki (S) > CRM (K).", #AY
|
||||
"Konsolidierte Mitarbeiterzahl. Priorisiert Wiki (T) > CRM (L).", #AZ
|
||||
"Ergebnis der Schätzung durch das trainierte Machine-Learning-Modell.", #BA
|
||||
"Zeitstempel der letzten Kontaktsuche via SerpAPI für diese Zeile.", #BB
|
||||
"Zeitstempel der letzten übergreifenden Prüfung/Bewertung durch ChatGPT (z.B. Branchenevaluation AH-AT).", #BC
|
||||
"Version des Skripts, die diese Zeile zuletzt signifikant bearbeitet hat.", #BD
|
||||
"Verbrauchte Tokens für OpenAI API-Aufrufe für diese Zeile." #BE
|
||||
],
|
||||
[ # Zeile 5: Aufgabe / Funktion
|
||||
"Datenquelle/Prozesssteuerung: 'x' markiert Zeile für Re-Evaluation in Modus 'reeval'.", #A
|
||||
@@ -2531,7 +2588,7 @@ def alignment_demo(sheet):
|
||||
"Datenquelle: Manuell gepflegte Kurzform des Firmennamens, primär für API-Suchen (LinkedIn, SerpAPI) genutzt.", #C
|
||||
"Datenquelle/Ziel: Website des Unternehmens. Kann durch 'website_lookup' oder 'check_urls' aktualisiert werden.", #D
|
||||
"Datenquelle: Ort des Unternehmens aus CRM.", #E
|
||||
"Datenquelle: Land des Unternehmenssitzes laut CRM (manuell pflegen). Wichtig für DACH-Region-Analyse.", #F NEU
|
||||
"Datenquelle: Land des Unternehmenssitzes laut CRM (manuell pflegen). Wichtig für DACH-Region-Analyse.", #F
|
||||
"Datenquelle: Beschreibung aus CRM. Input für KI-Analysen.", #G
|
||||
"Datenquelle: Branchenkategorie aus CRM. Referenz für KI-Branchenbewertung.", #H
|
||||
"Datenquelle: Externe Branchenbeschreibung (z.B. Dealfront). Input für KI-Branchenbewertung.", #I
|
||||
@@ -2540,8 +2597,8 @@ def alignment_demo(sheet):
|
||||
"Datenquelle: Mitarbeiterzahl aus CRM. Input für Konsolidierung und ML.", #L
|
||||
"Datenquelle: Alte/vorgeschlagene Wiki-URL aus CRM. Dient als initialer Input für Wiki-Prozess.", #M
|
||||
"Ziel/Quelle: Finale, als relevant erachtete Wikipedia-URL. Quelle: Wikipedia-Scraper (Suche/Extraktion), SerpAPI (Neusuche), ChatGPT (Vorschlag AA nach Prüfung), oder manuelle Eingabe.", #N
|
||||
"Quelle: Aus Wikipedia-Infobox extrahierte Stadt des Unternehmenssitzes. Ziel: Geografische Analyse.", #O NEU
|
||||
"Quelle: Aus Wikipedia-Infobox extrahiertes Land des Unternehmenssitzes. Ziel: Geografische Analyse (DACH).", #P NEU
|
||||
"Quelle: Aus Wikipedia-Infobox extrahierte Stadt des Unternehmenssitzes. Ziel: Geografische Analyse.", #O
|
||||
"Quelle: Aus Wikipedia-Infobox extrahiertes Land des Unternehmenssitzes. Ziel: Geografische Analyse (DACH).", #P
|
||||
"Quelle: Erster aussagekräftiger Absatz des Wikipedia-Artikels (N). Input für KI-Analysen, z.B. Wiki-Verifizierung.", #Q
|
||||
"Quelle: Aus der Wikipedia-Infobox extrahierte Branche(n). Input für KI-Branchenbewertung.", #R
|
||||
"Quelle: Aus der Wikipedia-Infobox extrahierter Umsatz. Input für Konsolidierung und ML.", #S
|
||||
@@ -2556,32 +2613,33 @@ def alignment_demo(sheet):
|
||||
"Ziel/Info: Wird aktuell primär geleert. Kann für spezifische Begründungen bei URL-Abweichungen genutzt werden.", #AB
|
||||
"Ziel: Rohtext der Website. Input für Zusammenfassung (AD).", #AC
|
||||
"Ziel: KI-generierte Zusammenfassung des Website-Rohtextes (AC). Input für Branchenbewertung (AH).", #AD
|
||||
"Ziel: Strukturierte Meta-Daten der Website (Title, Description, H-Tags). Für schnelle Analyse & Validierung.", #AE NEU
|
||||
"Ziel: Strukturierte Meta-Daten der Website (Title, Description, H-Tags). Für schnelle Analyse & Validierung.", #AE
|
||||
"System: Timestamp des letzten Website-Scraping/Summarization-Versuchs (für AC, AD, AE). Steuert Wiederholung.", #AF
|
||||
"System/Ziel: Status der URL-Prüfung. 'URL_CHECK_NEEDED' triggert Neusuche im Modus 'check_urls'. Wird dort aktualisiert.", #AG NEU
|
||||
"System/Ziel: Status der URL-Prüfung. 'URL_CHECK_NEEDED' triggert Neusuche im Modus 'check_urls'. Wird dort aktualisiert.", #AG
|
||||
"Ziel: Von ChatGPT final vorgeschlagene Branche gemäß Zielschema. Hauptziel der Branchenklassifizierung.", #AH
|
||||
"Ziel: Ergebnis des Abgleichs zwischen KI-Branchenvorschlag (AH) und CRM-Branche (H).", #AI
|
||||
"Ziel: Von ChatGPT generierte Begründung für den Branchenvorschlag (AH).", #AJ
|
||||
"Ziel: Ergebnis der FSM-Relevanzprüfung durch ChatGPT. (Platzhalter)", #AK
|
||||
"Ziel: Begründung von ChatGPT für die FSM-Relevanz. (Platzhalter)", #AL
|
||||
"Ziel: Von ChatGPT geschätzte Mitarbeiterzahl. (Platzhalter)", #AM
|
||||
"Ziel: Konsistenzprüfung der KI-Mitarbeiterschätzung. (Platzhalter)", #AN
|
||||
"Ziel: Begründung von ChatGPT bei Abweichung der Mitarbeiterschätzung. (Platzhalter)", #AO
|
||||
"Ziel: Von ChatGPT geschätzte Anzahl Servicetechniker. (Platzhalter)", #AP
|
||||
"Ziel: Begründung von ChatGPT bei Abweichung der Technikerzahl-Schätzung. (Platzhalter)", #AQ
|
||||
"Ziel: Von ChatGPT geschätzter Umsatz. (Platzhalter)", #AR
|
||||
"Ziel: Begründung von ChatGPT bei Abweichung der Umsatzschätzung. (Platzhalter)", #AS
|
||||
"Ziel: Anzahl gefundener LinkedIn-Kontakte (Serviceleiter) via SerpAPI.", #AT
|
||||
"Ziel: Anzahl gefundener LinkedIn-Kontakte (IT-Leiter) via SerpAPI.", #AU
|
||||
"Ziel: Anzahl gefundener LinkedIn-Kontakte (Management) via SerpAPI.", #AV
|
||||
"Ziel: Anzahl gefundener LinkedIn-Kontakte (Disponent) via SerpAPI.", #AW
|
||||
"Ziel: Konsolidierter Umsatz (Wiki-Wert (S) > CRM-Wert (K)). Input für ML-Modell.", #AX
|
||||
"Ziel: Konsolidierte Mitarbeiterzahl (Wiki-Wert (T) > CRM-Wert (L)). Input für ML-Modell.", #AY
|
||||
"Ziel: Vom ML-Modell vorhergesagter Bucket für die Anzahl der Servicetechniker.", #AZ
|
||||
"System: Timestamp der letzten Kontaktsuche (Modus 'contacts'). Steuert Wiederholung.", #BA
|
||||
"System: Timestamp der letzten übergreifenden ChatGPT-Evaluation (Branchen, FSM etc.). Steuert Wiederholung.", #BB
|
||||
"System: Skriptversion, die die Zeile zuletzt signifikant bearbeitet hat.", #BC
|
||||
"System: Verbrauchte Tokens für OpenAI API-Aufrufe für diese Zeile." #BD
|
||||
"Ziel: Von ChatGPT eingeschätzte Konfidenz (Hoch/Mittel/Niedrig) für den Branchenvorschlag (AH).", #AI (NEU)
|
||||
"Ziel: Ergebnis des Abgleichs zwischen KI-Branchenvorschlag (AH) und CRM-Branche (H).", #AJ
|
||||
"Ziel: Von ChatGPT generierte Begründung für den Branchenvorschlag (AH).", #AK
|
||||
"Ziel: Ergebnis der FSM-Relevanzprüfung durch ChatGPT. (Platzhalter)", #AL
|
||||
"Ziel: Begründung von ChatGPT für die FSM-Relevanz. (Platzhalter)", #AM
|
||||
"Ziel: Von ChatGPT geschätzte Mitarbeiterzahl. (Platzhalter)", #AN
|
||||
"Ziel: Konsistenzprüfung der KI-Mitarbeiterschätzung. (Platzhalter)", #AO
|
||||
"Ziel: Begründung von ChatGPT bei Abweichung der Mitarbeiterschätzung. (Platzhalter)", #AP
|
||||
"Ziel: Von ChatGPT geschätzte Anzahl Servicetechniker. (Platzhalter)", #AQ
|
||||
"Ziel: Begründung von ChatGPT bei Abweichung der Technikerzahl-Schätzung. (Platzhalter)", #AR
|
||||
"Ziel: Von ChatGPT geschätzter Umsatz. (Platzhalter)", #AS
|
||||
"Ziel: Begründung von ChatGPT bei Abweichung der Umsatzschätzung. (Platzhalter)", #AT
|
||||
"Ziel: Anzahl gefundener LinkedIn-Kontakte (Serviceleiter) via SerpAPI.", #AU
|
||||
"Ziel: Anzahl gefundener LinkedIn-Kontakte (IT-Leiter) via SerpAPI.", #AV
|
||||
"Ziel: Anzahl gefundener LinkedIn-Kontakte (Management) via SerpAPI.", #AW
|
||||
"Ziel: Anzahl gefundener LinkedIn-Kontakte (Disponent) via SerpAPI.", #AX
|
||||
"Ziel: Konsolidierter Umsatz (Wiki-Wert (S) > CRM-Wert (K)). Input für ML-Modell.", #AY
|
||||
"Ziel: Konsolidierte Mitarbeiterzahl (Wiki-Wert (T) > CRM-Wert (L)). Input für ML-Modell.", #AZ
|
||||
"Ziel: Vom ML-Modell vorhergesagter Bucket für die Anzahl der Servicetechniker.", #BA
|
||||
"System: Timestamp der letzten Kontaktsuche (Modus 'contacts'). Steuert Wiederholung.", #BB
|
||||
"System: Timestamp der letzten übergreifenden ChatGPT-Evaluation (Branchen, FSM etc.). Steuert Wiederholung.", #BC
|
||||
"System: Skriptversion, die die Zeile zuletzt signifikant bearbeitet hat.", #BD
|
||||
"System: Verbrauchte Tokens für OpenAI API-Aufrufe für diese Zeile." #BE
|
||||
]
|
||||
]
|
||||
|
||||
@@ -4239,192 +4297,102 @@ class DataProcessor:
|
||||
# --- 3. ChatGPT Evaluationen (Branch, FSM, Emp, Umsatz Schaetzungen etc.) ---
|
||||
# Dieser Schritt wird ausgefuehrt, wenn 'chat' in steps_to_run enthalten ist UND
|
||||
# (_needs_chat_evaluations True ist ODER force_reeval True ist).
|
||||
# _needs_chat_evaluations prueft AO oder ob Wiki-Daten in diesem Lauf gerade aktualisiert wurden.
|
||||
# _needs_chat_evaluations prueft BC (alt AO) oder ob Wiki-Daten in diesem Lauf gerade aktualisiert wurden.
|
||||
# Nutzt interne Helfer: _get_cell_value_safe, _needs_chat_evaluations.
|
||||
# Nutzt globale Helfer: COLUMN_MAP, logger, datetime, time,
|
||||
# evaluate_branche_chatgpt (Block 10),
|
||||
# get_numeric_filter_value (Block 5) <- ERSETZT get_valid_numeric.
|
||||
# (Optional: evaluate_fsm_suitability, evaluate_employee_chatgpt, evaluate_umsatz_chatgpt - muessen implementiert werden).
|
||||
# get_numeric_filter_value (Block 5).
|
||||
# Nutzt lokale Variablen: crm_branche, crm_beschreibung, final_wiki_data, website_summary, wiki_data_updated_in_this_run.
|
||||
|
||||
# Pruefen Sie, ob die Chat-Schritte im aktuellen Lauf angefordert wurden
|
||||
run_chat_step = 'chat' in steps_to_run
|
||||
# Pruefen Sie, ob die Chat-Schritte laut Status, Re-Eval oder Wiki-Update noetig sind.
|
||||
# wiki_data_just_updated_in_this_run ist ein Flag aus dem vorherigen Wiki-Schritt (Block 19).
|
||||
chat_processing_needed_based_on_status = self._needs_chat_evaluations(row_data, force_reeval, wiki_data_updated_in_this_run)
|
||||
|
||||
|
||||
# Wenn die Chat-Schritte angefordert wurden UND laut Status/Re-Eval noetig sind
|
||||
if run_chat_step and chat_processing_needed_based_on_status:
|
||||
any_processing_done = True # Markiere, dass in dieser Zeile etwas getan wird
|
||||
|
||||
# Setzen Sie das Flag, dass Chat-Evaluationen liefen (koennte ML ausloesen Block 23)
|
||||
any_processing_done = True
|
||||
chat_eval_just_ran = True
|
||||
|
||||
# Bestimme den Grund fuer die Ausfuehrung dieses Schritts fuer das Logging
|
||||
grund_message_parts = []
|
||||
if force_reeval: grund_message_parts.append('Re-Eval')
|
||||
# Pruefe, ob der Timestamp AO leer ist (nutzt interne Helfer)
|
||||
if not self._get_cell_value_safe(row_data, "Timestamp letzte Pruefung").strip(): grund_message_parts.append('AO leer')
|
||||
# Pruefe, ob Wiki-Daten gerade aktualisiert wurden (Flag aus Block 19)
|
||||
if not self._get_cell_value_safe(row_data, "Timestamp letzte Pruefung").strip(): grund_message_parts.append('BC (Timestamp letzte Pruefung) leer') # Neuer Schlüssel BC
|
||||
if wiki_data_updated_in_this_run: grund_message_parts.append('Wiki Daten gerade aktualisiert')
|
||||
grund_message = ", ".join(grund_message_parts)
|
||||
grund_message = ", ".join(filter(None, grund_message_parts)) or "Unbekannter Grund"
|
||||
|
||||
self.logger.info(f"Zeile {row_num_in_sheet}: Fuehre CHATGPT Evaluationen aus (Grund: {grund_message})...") # <<< GEÄNDERT
|
||||
self.logger.info(f"Zeile {row_num_in_sheet}: Fuehre CHATGPT Evaluationen aus (Grund: {grund_message})...")
|
||||
|
||||
# Hole die notwendigen Daten fuer die ChatGPT-Calls.
|
||||
# Nutzt die initial geladenen CRM-Daten und die finalen Daten aus den vorherigen Schritten (Wiki, Website).
|
||||
# crm_branche, crm_beschreibung wurden initial geladen (Block 17).
|
||||
# final_wiki_data wurde im Wiki-Schritt (Block 19) aktualisiert oder behaelt alte Werte.
|
||||
# website_summary wurde im Website-Schritt (Block 18) aktualisiert oder behaelt alte Werte.
|
||||
|
||||
# --- 3a. Branchen-Einstufung (W, X, Y) ---
|
||||
self.logger.debug(" -> Starte Branchen-Einstufung ueber ChatGPT...") # <<< GEÄNDERT
|
||||
# --- 3a. Branchen-Einstufung (AH, AI, AJ, AK) --- NEUE SPALTENBUCHSTABEN BEACHTEN!
|
||||
self.logger.debug(" -> Starte Branchen-Einstufung ueber ChatGPT...")
|
||||
try:
|
||||
# Annahme: evaluate_branche_chatgpt global definiert (Block 10) und nutzt logging/retry
|
||||
# evaluate_branche_chatgpt braucht Zugriff auf globale ALLOWED_TARGET_BRANCHES und TARGET_SCHEMA_STRING (Block 6)
|
||||
# Der Aufruf ist mit retry_on_failure dekoriert und wirft bei endgueltigem Fehler eine Exception.
|
||||
branch_result = evaluate_branche_chatgpt( # Nutzt globalen Helfer (Block 10)
|
||||
crm_branche, # Nutzt initial geladenen CRM Wert
|
||||
crm_beschreibung, # Nutzt initial geladenen CRM Wert
|
||||
final_wiki_data.get('branche', 'k.A.'), # Nutzt ggf. neue Wiki-Branche aus Block 19
|
||||
final_wiki_data.get('categories', 'k.A.'), # Nutzt ggf. neue Wiki-Kategorien aus Block 19
|
||||
website_summary # Nutzt ggf. neue Website-Zusammenfassung aus Block 18
|
||||
branch_result = evaluate_branche_chatgpt(
|
||||
crm_branche,
|
||||
crm_beschreibung,
|
||||
final_wiki_data.get('branche', 'k.A.'),
|
||||
final_wiki_data.get('categories', 'k.A.'),
|
||||
website_summary
|
||||
)
|
||||
# Sammle Updates fuer die Branchen-Spalten (W, X, Y) (nutzt interne Helfer)
|
||||
# Stellen Sie sicher, dass die Schluessel im Ergebnis-Dict vorhanden sind, Fallback auf Standard-Fehlerwerte.
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Vorschlag Branche"] + 1)}{row_num_in_sheet}', 'values': [[branch_result.get("branch", "FEHLER")]]}) # Block 1 Column Map
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Konsistenz Branche"] + 1)}{row_num_in_sheet}', 'values': [[branch_result.get("consistency", "error")]]}) # Block 1 Column Map
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Begruendung Abweichung Branche"] + 1)}{row_num_in_sheet}', 'values': [[branch_result.get("justification", "Keine Begruendung")]]}) # Block 1 Column Map
|
||||
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Vorschlag Branche"] + 1)}{row_num_in_sheet}', 'values': [[branch_result.get("branch", "FEHLER")]]})
|
||||
# NEU: Konfidenz-Score speichern
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Branche Konfidenz"] + 1)}{row_num_in_sheet}', 'values': [[branch_result.get("confidence", "N/A")]]})
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Konsistenz Branche"] + 1)}{row_num_in_sheet}', 'values': [[branch_result.get("consistency", "error")]]})
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Begruendung Abweichung Branche"] + 1)}{row_num_in_sheet}', 'values': [[branch_result.get("justification", "Keine Begruendung")]]})
|
||||
|
||||
except Exception as e_branch_eval:
|
||||
# Wenn evaluate_branche_chatgpt eine Exception wirft (nach Retries)
|
||||
# Der Fehler wird bereits vom retry_on_failure Decorator oder evaluate_branche_chatgpt geloggt.
|
||||
self.logger.error(f"FEHLER bei Branchen-Einstufung ueber ChatGPT fuer Zeile {row_num_in_sheet}: {e_branch_eval}") # <<< GEÄNDERT
|
||||
# Logge den Traceback fuer detailliertere Fehlerinformationen
|
||||
self.logger.debug(traceback.format_exc()) # <<< GEÄNDERT
|
||||
# Fuegen Sie Updates mit Fehlerwerten hinzu, um den Fehler im Sheet zu dokumentieren.
|
||||
error_msg = f"Fehler: {str(e_branch_eval)[:100]}..." # Kuerze Fehlermeldung
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Vorschlag Branche"] + 1)}{row_num_in_sheet}', 'values': [['FEHLER']]}) # Block 1 Column Map
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Konsistenz Branche"] + 1)}{row_num_in_sheet}', 'values': [['error']]}) # Block 1 Column Map
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Begruendung Abweichung Branche"] + 1)}{row_num_in_sheet}', 'values': [[error_msg]]}) # Block 1 Column Map
|
||||
pass # Fahren Sie fort mit den naechsten Schritten, auch wenn Branchenevaluation fehlschlug
|
||||
self.logger.error(f"FEHLER bei Branchen-Einstufung ueber ChatGPT fuer Zeile {row_num_in_sheet}: {e_branch_eval}")
|
||||
self.logger.debug(traceback.format_exc())
|
||||
error_msg = f"Fehler: {str(e_branch_eval)[:100]}..."
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Vorschlag Branche"] + 1)}{row_num_in_sheet}', 'values': [['FEHLER']]})
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Branche Konfidenz"] + 1)}{row_num_in_sheet}', 'values': [['N/A']]}) # NEU
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Konsistenz Branche"] + 1)}{row_num_in_sheet}', 'values': [['error']]})
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Begruendung Abweichung Branche"] + 1)}{row_num_in_sheet}', 'values': [[error_msg]]})
|
||||
pass
|
||||
|
||||
# --- 3b. FSM Relevanz Bewertung (AL, AM) --- (Platzhalter wie gehabt)
|
||||
self.logger.debug(" -> Starte FSM Relevanz Bewertung (Platzhalter)...")
|
||||
# ... (Ihr Platzhalter-Code für FSM) ...
|
||||
|
||||
# --- 3b. FSM Relevanz Bewertung (Z, AA) ---
|
||||
# TODO: Implementieren Sie die Logik und den Aufruf der Funktion evaluate_fsm_suitability
|
||||
self.logger.debug(" -> Starte FSM Relevanz Bewertung (Platzhalter)...") # <<< GEÄNDERT
|
||||
# Beispielaufruf (angenommen, evaluate_fsm_suitability existiert global):
|
||||
# try:
|
||||
# fsm_result = evaluate_fsm_suitability(
|
||||
# company_name, # Nutzt initial geladenen CRM Namen
|
||||
# {'crm_desc': crm_beschreibung, 'wiki_paragraph': final_wiki_data.get('first_paragraph', 'k.A.'), 'web_summary': website_summary}
|
||||
# )
|
||||
# # Sammle Updates fuer FSM Spalten (Z, AA) (nutzt interne Helfer)
|
||||
# updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Pruefung FSM Relevanz"] + 1)}{row_num_in_sheet}', 'values': [[fsm_result.get('suitability', 'k.A.')]]}) # Block 1 Column Map
|
||||
# updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Begruendung fuer FSM Relevanz"] + 1)}{row_num_in_sheet}', 'values': [[fsm_result.get('justification', 'k.A.')]]}) # Block 1 Column Map
|
||||
# except Exception as e_fsm_eval:
|
||||
# self.logger.error(f"FEHLER bei FSM Relevanz Bewertung fuer Zeile {row_num_in_sheet}: {e_fsm_eval}") # <<< GEÄNDERT
|
||||
# # Fuege Fehler-Updates hinzu
|
||||
# updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Pruefung FSM Relevanz"] + 1)}{row_num_in_sheet}', 'values': [['FEHLER']]}) # Block 1 Column Map
|
||||
# updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Begruendung fuer FSM Relevanz"] + 1)}{row_num_in_sheet}', 'values': [[f'Fehler: {str(e_fsm_eval)[:100]}...']]}) # Block 1 Column Map
|
||||
# pass # Faert fort
|
||||
# --- 3c. Mitarbeiterzahl Schaetzung (AN, AO, AP) --- (Platzhalter wie gehabt)
|
||||
self.logger.debug(" -> Starte Mitarbeiterzahl Schaetzung (Platzhalter)...")
|
||||
# ... (Ihr Platzhalter-Code für Mitarbeiter) ...
|
||||
|
||||
# --- 3d. Umsatz Schaetzung (AS, AT) --- (Platzhalter wie gehabt)
|
||||
self.logger.debug(" -> Starte Umsatz Schaetzung (Platzhalter)...")
|
||||
# ... (Ihr Platzhalter-Code für Umsatz) ...
|
||||
|
||||
# --- 3c. Mitarbeiterzahl Schaetzung (AB, AC, AD) ---
|
||||
# TODO: Implementieren Sie die Logik und den Aufruf der Funktion evaluate_employee_chatgpt
|
||||
self.logger.debug(" -> Starte Mitarbeiterzahl Schaetzung (Platzhalter)...") # <<< GEÄNDERT
|
||||
# Beispielaufruf (angenommen, evaluate_employee_chatgpt existiert global):
|
||||
# try:
|
||||
# emp_estimate_result = evaluate_employee_chatgpt(
|
||||
# company_name, # Nutzt initial geladenen CRM Namen
|
||||
# {'crm_emp': self._get_cell_value_safe(row_data, "CRM Anzahl Mitarbeiter"), 'wiki_emp': final_wiki_data.get('mitarbeiter', 'k.A.'), 'wiki_paragraph': final_wiki_data.get('first_paragraph', 'k.A.'), 'web_summary': website_summary}
|
||||
# )
|
||||
# # Sammle Updates fuer Mitarbeiter Schaetzspalten (AB, AC, AD) (nutzt interne Helfer)
|
||||
# updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Schaetzung Anzahl Mitarbeiter"] + 1)}{row_num_in_sheet}', 'values': [[emp_estimate_result.get('estimate', 'k.A.')]]}) # Block 1 Column Map
|
||||
# updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Konsistenzpruefung Mitarbeiterzahl"] + 1)}{row_num_in_sheet}', 'values': [[emp_estimate_result.get('consistency', 'k.A.')]]}) # Block 1 Column Map
|
||||
# updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Begruendung Abweichung Mitarbeiterzahl"] + 1)}{row_num_in_sheet}', 'values': [[emp_estimate_result.get('justification', 'k.A.')]]}) # Block 1 Column Map
|
||||
# except Exception as e_emp_eval:
|
||||
# self.logger.error(f"FEHLER bei Mitarbeiterzahl Schaetzung fuer Zeile {row_num_in_sheet}: {e_emp_eval}") # <<< GEÄNDERT
|
||||
# # Fuege Fehler-Updates hinzu
|
||||
# updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Schaetzung Anzahl Mitarbeiter"] + 1)}{row_num_in_sheet}', 'values': [['FEHLER']]}) # Block 1 Column Map
|
||||
# updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Konsistenzpruefung Mitarbeiterzahl"] + 1)}{row_num_in_sheet}', 'values': [['error']]}) # Block 1 Column Map
|
||||
# updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Begruendung Abweichung Mitarbeiterzahl"] + 1)}{row_num_in_sheet}', 'values': [[f'Fehler: {str(e_emp_eval)[:100]}...']]}) # Block 1 Column Map
|
||||
# pass # Faert fort
|
||||
|
||||
|
||||
# --- 3d. Umsatz Schaetzung (AG, AH) ---
|
||||
# TODO: Implementieren Sie die Logik und den Aufruf der Funktion evaluate_umsatz_chatgpt
|
||||
self.logger.debug(" -> Starte Umsatz Schaetzung (Platzhalter)...") # <<< GEÄNDERT
|
||||
# Beispielaufruf (angenommen, evaluate_umsatz_chatgpt existiert global):
|
||||
# try:
|
||||
# umsatz_estimate_result = evaluate_umsatz_chatgpt(
|
||||
# company_name, # Nutzt initial geladenen CRM Namen
|
||||
# {'crm_umsatz': self._get_cell_value_safe(row_data, "CRM Umsatz"), 'wiki_umsatz': final_wiki_data.get('umsatz', 'k.A.'), 'wiki_paragraph': final_wiki_data.get('first_paragraph', 'k.A.'), 'web_summary': website_summary}
|
||||
# )
|
||||
# # Sammle Updates fuer Umsatz Schaetzspalten (AG, AH) (nutzt interne Helfer)
|
||||
# updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Schaetzung Umsatz"] + 1)}{row_num_in_sheet}', 'values': [[umsatz_estimate_result.get('estimate', 'k.A.')]]}) # Block 1 Column Map
|
||||
# updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Begruendung Abweichung Umsatz"] + 1)}{row_num_in_sheet}', 'values': [[umsatz_estimate_result.get('justification', 'k.A.')]]}) # Block 1 Column Map
|
||||
# except Exception as e_umsatz_eval:
|
||||
# self.logger.error(f"FEHLER bei Umsatz Schaetzung fuer Zeile {row_num_in_sheet}: {e_umsatz_eval}") # <<< GEÄNDERT
|
||||
# # Fuege Fehler-Updates hinzu
|
||||
# updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Schaetzung Umsatz"] + 1)}{row_num_in_sheet}', 'values': [['FEHLER']]}) # Block 1 Column Map
|
||||
# updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Begruendung Abweichung Umsatz"] + 1)}{row_num_in_sheet}', 'values': [[f'Fehler: {str(e_umsatz_eval)[:100]}...']]}) # Block 1 Column Map
|
||||
# pass # Faert fort
|
||||
|
||||
|
||||
# --- 3e. Konsolidierung Umsatz/Mitarbeiter (AV, AW) ---
|
||||
# Diese Logik wurde bisher in prepare_data_for_modeling (Block 31) verwendet,
|
||||
# kann aber auch hier nach jeder Zeilenverarbeitung durchgefuehrt und
|
||||
# ins Sheet geschrieben werden, um die konsolidierten Werte aktuell zu halten.
|
||||
self.logger.debug(" -> Konsolidiere Umsatz (AV) und Mitarbeiter (AW) (Wiki > CRM Logik)...") # <<< GEÄNDERT
|
||||
# --- 3e. Konsolidierung Umsatz/Mitarbeiter (AY, AZ) --- NEUE SPALTENBUCHSTABEN!
|
||||
# Diese Logik wird jetzt direkt hier ausgeführt.
|
||||
self.logger.debug(" -> Konsolidiere Umsatz (AY) und Mitarbeiter (AZ) (Wiki > CRM Logik)...")
|
||||
try:
|
||||
# Nutzt globale Funktion get_numeric_filter_value (Block 5) - ERSETZT get_valid_numeric
|
||||
# Hole die Werte aus den entsprechenden Spalten (CRM und finale Wiki-Daten)
|
||||
crm_umsatz_val = self._get_cell_value_safe(row_data, "CRM Umsatz") # Block 1 Column Map
|
||||
wiki_umsatz_val = final_wiki_data.get('umsatz', 'k.A.') # Nutzt finalen Wiki-Wert aus Block 19
|
||||
crm_umsatz_val = self._get_cell_value_safe(row_data, "CRM Umsatz")
|
||||
wiki_umsatz_val = final_wiki_data.get('umsatz', 'k.A.')
|
||||
|
||||
crm_ma_val = self._get_cell_value_safe(row_data, "CRM Anzahl Mitarbeiter") # Block 1 Column Map
|
||||
wiki_ma_val = final_wiki_data.get('mitarbeiter', 'k.A.') # Nutzt finalen Wiki-Wert aus Block 19
|
||||
crm_ma_val = self._get_cell_value_safe(row_data, "CRM Anzahl Mitarbeiter")
|
||||
wiki_ma_val = final_wiki_data.get('mitarbeiter', 'k.A.')
|
||||
|
||||
# Konvertiere die Werte zu Numerisch (Float/Int oder 0) mit get_numeric_filter_value
|
||||
num_crm_umsatz = get_numeric_filter_value(crm_umsatz_val, is_umsatz=True)
|
||||
num_wiki_umsatz = get_numeric_filter_value(wiki_umsatz_val, is_umsatz=True)
|
||||
|
||||
num_crm_ma = get_numeric_filter_value(crm_ma_val, is_umsatz=False)
|
||||
num_wiki_ma = get_numeric_filter_value(wiki_ma_val, is_umsatz=False)
|
||||
|
||||
# Konsolidierung: Wiki hat Prioritaet vor CRM. Wenn Wiki ungueltig (0), nehme CRM.
|
||||
# WICHTIG: 0 ist hier das Kennzeichen fuer ungueltig/nicht parsebar/k.A. in get_numeric_filter_value
|
||||
final_num_umsatz = num_wiki_umsatz if num_wiki_umsatz > 0 else num_crm_umsatz
|
||||
final_num_ma = num_wiki_ma if num_wiki_ma > 0 else num_crm_ma
|
||||
|
||||
# Konvertiere das finale numerische Ergebnis zurueck zu einem String ("Zahl" oder "k.A.")
|
||||
# Runden Sie Umsatz auf ganze Millionen und Mitarbeiter auf ganze Zahlen.
|
||||
# Stellen Sie sicher, dass nur positive Werte als Zahl ausgegeben werden, sonst "k.A.".
|
||||
final_umsatz_str = str(int(round(final_num_umsatz))) if final_num_umsatz > 0 else 'k.A.'
|
||||
final_ma_str = str(int(round(final_num_ma))) if final_num_ma > 0 else 'k.A.'
|
||||
|
||||
|
||||
# Sammle Updates fuer die Konsolidierungsspalten (AV, AW) (nutzt interne Helfer)
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Finaler Umsatz (Wiki>CRM)"] + 1)}{row_num_in_sheet}', 'values': [[final_umsatz_str]]}) # Block 1 Column Map
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Finaler Mitarbeiter (Wiki>CRM)"] + 1)}{row_num_in_sheet}', 'values': [[final_ma_str]]}) # Block 1 Column Map
|
||||
self.logger.debug(f" -> Konsolidiert: Umsatz={final_umsatz_str}, MA={final_ma_str}") # <<< GEÄNDERT
|
||||
|
||||
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Finaler Umsatz (Wiki>CRM)"] + 1)}{row_num_in_sheet}', 'values': [[final_umsatz_str]]})
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Finaler Mitarbeiter (Wiki>CRM)"] + 1)}{row_num_in_sheet}', 'values': [[final_ma_str]]})
|
||||
self.logger.debug(f" -> Konsolidiert: Umsatz={final_umsatz_str}, MA={final_ma_str}")
|
||||
|
||||
except Exception as e_consolidate:
|
||||
# Fange Fehler bei der Konsolidierung ab und logge sie
|
||||
self.logger.error(f"FEHLER bei Konsolidierung Umsatz/Mitarbeiter fuer Zeile {row_num_in_sheet}: {e_consolidate}") # <<< GEÄNDERT
|
||||
# Logge den Traceback
|
||||
self.logger.debug(traceback.format_exc()) # <<< GEÄNDERT
|
||||
# Fuege Fehler-Updates hinzu, um den Fehler im Sheet zu dokumentieren
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Finaler Umsatz (Wiki>CRM)"] + 1)}{row_num_in_sheet}', 'values': [['FEHLER']]}) # Block 1 Column Map
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Finaler Mitarbeiter (Wiki>CRM)"] + 1)}{row_num_in_sheet}', 'values': [['FEHLER']]}) # Block 1 Column Map
|
||||
pass # Faert fort
|
||||
self.logger.error(f"FEHLER bei Konsolidierung Umsatz/Mitarbeiter fuer Zeile {row_num_in_sheet}: {e_consolidate}")
|
||||
self.logger.debug(traceback.format_exc())
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Finaler Umsatz (Wiki>CRM)"] + 1)}{row_num_in_sheet}', 'values': [['FEHLER']]})
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Finaler Mitarbeiter (Wiki>CRM)"] + 1)}{row_num_in_sheet}', 'values': [['FEHLER']]})
|
||||
pass
|
||||
|
||||
|
||||
# Setze den Timestamp letzte Pruefung (AO), da die ChatGPT-Evaluationen liefen (auch wenn fehlerhaft)
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Timestamp letzte Pruefung"] + 1)}{row_num_in_sheet}', 'values': [[now_timestamp]]}) # Block 1 Column Map
|
||||
# Setze den Timestamp letzte Pruefung (BC - vorher BB), da die ChatGPT-Evaluationen liefen
|
||||
updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Timestamp letzte Pruefung"] + 1)}{row_num_in_sheet}', 'values': [[now_timestamp]]})
|
||||
|
||||
|
||||
# else if run_chat_step:
|
||||
|
||||
Reference in New Issue
Block a user