""" Test: EspoCRM Kommunikation - Wie werden Kontaktdaten gespeichert? Prüfe: 1. Gibt es ein separates CKommunikation Entity? 2. Wie sind Telefon/Email/Fax in CBeteiligte gespeichert? 3. Sind es Arrays oder einzelne Felder? """ import asyncio import json from services.espocrm import EspoCRMAPI # Test-Beteiligter mit Kommunikationsdaten TEST_BETEILIGTE_ID = '68e4af00172be7924' # Angela Mustermanns class SimpleContext: class Logger: def info(self, msg): print(f"[INFO] {msg}") def error(self, msg): print(f"[ERROR] {msg}") def warning(self, msg): print(f"[WARN] {msg}") def debug(self, msg): print(f"[DEBUG] {msg}") def __init__(self): self.logger = self.Logger() def print_section(title): print("\n" + "="*70) print(title) print("="*70) async def test_cbeteiligte_structure(): """Analysiere CBeteiligte Kommunikationsfelder""" print_section("TEST 1: CBeteiligte Entity Struktur") context = SimpleContext() espo = EspoCRMAPI(context) # Hole Beteiligten entity = await espo.get_entity('CBeteiligte', TEST_BETEILIGTE_ID) print(f"\n✅ Beteiligter geladen: {entity.get('name')}") print(f" ID: {entity.get('id')}") print(f" betNr: {entity.get('betnr')}") # Suche nach Kommunikationsfeldern print("\n📊 Kommunikations-relevante Felder:") comm_fields = [ 'phoneNumber', 'phoneNumberData', 'emailAddress', 'emailAddressData', 'fax', 'faxData', 'mobile', 'mobileData', 'website', # Plural Varianten 'phoneNumbers', 'emailAddresses', 'faxNumbers', # Link-Felder 'kommunikationIds', 'kommunikationNames', 'kommunikationenIds', 'kommunikationenNames', 'ckommunikationIds', 'ckommunikationNames' ] found_fields = {} for field in comm_fields: if field in entity: value = entity[field] found_fields[field] = value print(f"\n ✓ {field}:") print(f" Typ: {type(value).__name__}") if isinstance(value, list): print(f" Anzahl: {len(value)}") if len(value) > 0: print(f" Beispiel: {json.dumps(value[0], indent=6, ensure_ascii=False)}") elif isinstance(value, dict): print(f" Keys: {list(value.keys())}") print(f" Content: {json.dumps(value, indent=6, ensure_ascii=False)}") else: print(f" Wert: {value}") if not found_fields: print("\n ⚠️ Keine Standard-Kommunikationsfelder gefunden") # Zeige alle Felder die "comm", "phone", "email", "fax", "tel" enthalten print("\n📋 Alle Felder mit Kommunikations-Keywords:") keywords = ['comm', 'phone', 'email', 'fax', 'tel', 'mobil', 'kontakt'] matching_fields = {} for key, value in entity.items(): key_lower = key.lower() if any(kw in key_lower for kw in keywords): matching_fields[key] = value print(f" • {key}: {type(value).__name__}") if isinstance(value, (str, int, bool)) and value: print(f" = {value}") return entity, found_fields async def test_ckommunikation_entity(): """Prüfe ob CKommunikation Entity existiert""" print_section("TEST 2: CKommunikation Entity") context = SimpleContext() espo = EspoCRMAPI(context) # Versuche CKommunikation zu listen try: result = await espo.list_entities('CKommunikation', max_size=5) print(f"✅ CKommunikation Entity existiert!") print(f" Anzahl gefunden: {len(result)}") if result: print(f"\n📋 Beispiel-Kommunikation:") print(json.dumps(result[0], indent=2, ensure_ascii=False)) return True, result except Exception as e: if '404' in str(e) or 'not found' in str(e).lower(): print(f"❌ CKommunikation Entity existiert NICHT") print(f" Fehler: {e}") return False, None else: print(f"⚠️ Fehler beim Abrufen: {e}") return None, None async def test_entity_metadata(): """Hole Entity-Metadaten von CBeteiligte""" print_section("TEST 3: CBeteiligte Metadaten") context = SimpleContext() espo = EspoCRMAPI(context) # Hole Metadaten (falls API das unterstützt) try: # Versuche Entity-Defs zu holen metadata = await espo.api_call('/Metadata', method='GET') if 'entityDefs' in metadata and 'CBeteiligte' in metadata['entityDefs']: beteiligte_def = metadata['entityDefs']['CBeteiligte'] print("✅ Metadaten verfügbar") if 'fields' in beteiligte_def: fields = beteiligte_def['fields'] print(f"\n📊 Kommunikations-Felder in Definition:") for field_name, field_def in fields.items(): field_lower = field_name.lower() if any(kw in field_lower for kw in ['comm', 'phone', 'email', 'fax', 'tel']): print(f"\n • {field_name}:") print(f" type: {field_def.get('type')}") if 'entity' in field_def: print(f" entity: {field_def.get('entity')}") if 'link' in field_def: print(f" link: {field_def.get('link')}") return metadata except Exception as e: print(f"⚠️ Metadaten nicht verfügbar: {e}") return None async def test_list_all_entities(): """Liste alle verfügbaren Entities""" print_section("TEST 4: Alle verfügbaren Entities") context = SimpleContext() espo = EspoCRMAPI(context) # Häufige Entity-Namen die mit Kommunikation zu tun haben könnten test_entities = [ 'CKommunikation', 'Kommunikation', 'Communication', 'PhoneNumber', 'EmailAddress', 'CPhoneNumber', 'CEmailAddress', 'CPhone', 'CEmail', 'CContact', 'ContactData' ] print("\n🔍 Teste verschiedene Entity-Namen:\n") existing = [] for entity_name in test_entities: try: result = await espo.list_entities(entity_name, max_size=1) print(f" ✅ {entity_name} - existiert ({len(result)} gefunden)") existing.append(entity_name) except Exception as e: if '404' in str(e) or 'not found' in str(e).lower(): print(f" ❌ {entity_name} - existiert nicht") else: print(f" ⚠️ {entity_name} - Fehler: {str(e)[:50]}") return existing async def main(): print("\n" + "="*70) print("ESPOCRM KOMMUNIKATION ANALYSE") print("="*70) print("\nZiel: Verstehen wie Kommunikationsdaten in EspoCRM gespeichert sind") print("Frage: Gibt es separate Kommunikations-Entities oder nur Felder?\n") try: # Test 1: CBeteiligte Struktur entity, comm_fields = await test_cbeteiligte_structure() # Test 2: CKommunikation Entity ckommunikation_exists, ckommunikation_data = await test_ckommunikation_entity() # Test 3: Metadaten # metadata = await test_entity_metadata() # Test 4: Liste entities existing_entities = await test_list_all_entities() # Zusammenfassung print_section("ZUSAMMENFASSUNG") print("\n📊 Erkenntnisse:") if comm_fields: print(f"\n✅ CBeteiligte hat Kommunikationsfelder:") for field, value in comm_fields.items(): vtype = type(value).__name__ print(f" • {field} ({vtype})") if ckommunikation_exists: print(f"\n✅ CKommunikation Entity existiert") print(f" → Separate Kommunikations-Entities möglich") elif ckommunikation_exists == False: print(f"\n❌ CKommunikation Entity existiert NICHT") print(f" → Kommunikation nur als Felder in CBeteiligte") if existing_entities: print(f"\n📋 Gefundene Kommunikations-Entities:") for ename in existing_entities: print(f" • {ename}") print("\n💡 Empfehlung:") if not comm_fields and not ckommunikation_exists: print(" ⚠️ Keine Kommunikationsstruktur gefunden") print(" → Eventuell müssen Custom Fields erst angelegt werden") elif comm_fields and not ckommunikation_exists: print(" → Verwende vorhandene Felder in CBeteiligte (phoneNumber, emailAddress, etc.)") print(" → Sync als Teil des Beteiligte-Syncs (nicht separat)") elif ckommunikation_exists: print(" → Verwende CKommunikation Entity für separaten Kommunikations-Sync") print(" → Ermöglicht mehrere Kommunikationseinträge pro Beteiligten") except Exception as e: print(f"\n❌ Fehler: {e}") import traceback traceback.print_exc() if __name__ == '__main__': asyncio.run(main())