""" Test: Gibt es ID-Collections für EmailAddress/PhoneNumber? In EspoCRM gibt es bei Many-to-Many Beziehungen oft: - entityNameIds (Array von IDs) - entityNameNames (Dict ID → Name) Zum Beispiel: teamsIds, teamsNames Hypothese: Es könnte emailAddressesIds oder ähnlich geben """ import asyncio import json from services.espocrm import EspoCRMAPI TEST_BETEILIGTE_ID = '68e4af00172be7924' 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): pass def __init__(self): self.logger = self.Logger() def print_section(title): print("\n" + "="*70) print(title) print("="*70) async def search_for_id_fields(): """Suche nach allen ID-ähnlichen Feldern""" print_section("SUCHE: ID-Collections") context = SimpleContext() espo = EspoCRMAPI(context) entity = await espo.get_entity('CBeteiligte', TEST_BETEILIGTE_ID) print("\n🔍 Alle Felder die 'Ids' enthalten:") ids_fields = {k: v for k, v in entity.items() if 'Ids' in k} for key, value in sorted(ids_fields.items()): print(f" • {key:40s}: {value}") print("\n🔍 Alle Felder die 'Names' enthalten:") names_fields = {k: v for k, v in entity.items() if 'Names' in k} for key, value in sorted(names_fields.items()): print(f" • {key:40s}: {value}") print("\n🔍 Alle Felder mit 'email' oder 'phone' (case-insensitive):") comm_fields = {k: v for k, v in entity.items() if 'email' in k.lower() or 'phone' in k.lower()} for key, value in sorted(comm_fields.items()): value_str = str(value)[:80] if not isinstance(value, list) else f"[{len(value)} items]" print(f" • {key:40s}: {value_str}") async def test_specific_fields(): """Teste spezifische Feld-Namen die existieren könnten""" print_section("TEST: Spezifische Feld-Namen") context = SimpleContext() espo = EspoCRMAPI(context) potential_fields = [ 'emailAddressesIds', 'emailAddressIds', 'phoneNumbersIds', 'phoneNumberIds', 'emailIds', 'phoneIds', 'emailAddressesNames', 'phoneNumbersNames', ] print("\n📋 Teste mit select Parameter:\n") for field in potential_fields: try: result = await espo.api_call( f'CBeteiligte/{TEST_BETEILIGTE_ID}', params={'select': f'id,{field}'} ) if field in result and result[field] is not None: print(f" ✅ {field:30s}: {result[field]}") else: print(f" ⚠️ {field:30s}: Im Response aber None/leer") except Exception as e: print(f" ❌ {field:30s}: {str(e)[:60]}") async def test_with_loadAdditionalFields(): """EspoCRM unterstützt manchmal loadAdditionalFields Parameter""" print_section("TEST: loadAdditionalFields Parameter") context = SimpleContext() espo = EspoCRMAPI(context) params_to_test = [ {'loadAdditionalFields': 'true'}, {'loadAdditionalFields': '1'}, {'withLinks': 'true'}, {'withRelated': 'emailAddresses,phoneNumbers'}, ] for params in params_to_test: print(f"\n📋 Teste mit params: {params}") try: result = await espo.api_call( f'CBeteiligte/{TEST_BETEILIGTE_ID}', params=params ) # Suche nach neuen Feldern new_fields = {k: v for k, v in result.items() if ('email' in k.lower() or 'phone' in k.lower()) and 'Data' not in k} if new_fields: print(" ✅ Neue Felder gefunden:") for k, v in new_fields.items(): print(f" • {k}: {v}") else: print(" ⚠️ Keine neuen Felder") except Exception as e: print(f" ❌ Error: {e}") async def test_create_with_explicit_ids(): """ Was wenn wir bei CREATE/UPDATE explizite IDs für Email/Phone mitgeben? Vielleicht gibt EspoCRM dann IDs zurück? """ print_section("IDEE: Explizite IDs bei UPDATE mitgeben") print("\n💡 EspoCRM Standard-Verhalten:") print(" Bei Many-to-Many Beziehungen (z.B. Teams):") print(" - INPUT: teamsIds: ['id1', 'id2']") print(" - OUTPUT: teamsIds: ['id1', 'id2']") print(" ") print(" Könnte bei emailAddresses ähnlich funktionieren?") context = SimpleContext() espo = EspoCRMAPI(context) # Hole aktuelle Daten entity = await espo.get_entity('CBeteiligte', TEST_BETEILIGTE_ID) current_emails = entity.get('emailAddressData', []) print("\n📋 Aktuelle emailAddressData:") for e in current_emails: print(f" • {e.get('emailAddress')}") # Versuche ein Update mit hypothetischen emailAddressesIds print("\n🧪 Test: UPDATE mit emailAddressesIds Feld") print(" (DRY RUN - nicht wirklich ausgeführt)") # Generiere Test-IDs (EspoCRM IDs sind meist 17 Zeichen) test_ids = [f"test{str(i).zfill(13)}" for i in range(len(current_emails))] print(f"\n Würde senden:") print(f" emailAddressesIds: {test_ids}") print(f" emailAddressData: {[e['emailAddress'] for e in current_emails]}") print("\n ⚠️ Zu riskant ohne zu wissen was passiert") async def check_standard_contact_entity(): """ Prüfe wie es bei Standard Contact Entity funktioniert (als Referenz für Custom Entity) """ print_section("REFERENZ: Standard Contact Entity") context = SimpleContext() espo = EspoCRMAPI(context) print("\n📋 Hole ersten Contact als Referenz:") try: contacts = await espo.api_call('Contact', params={'maxSize': 1}) if contacts and contacts.get('list'): contact = contacts['list'][0] print(f"\n Contact: {contact.get('name')}") print(f"\n 🔍 Email/Phone-relevante Felder:") for key, value in sorted(contact.items()): if 'email' in key.lower() or 'phone' in key.lower(): value_str = str(value)[:80] if not isinstance(value, (list, dict)) else type(value).__name__ print(f" • {key:35s}: {value_str}") else: print(" ⚠️ Keine Contacts vorhanden") except Exception as e: print(f" ❌ Error: {e}") async def main(): print("\n" + "="*70) print("SUCHE: EMAIL/PHONE ID-COLLECTIONS") print("="*70) print("\nZiel: Finde ID-Arrays für EmailAddress/PhoneNumber Entities\n") try: await search_for_id_fields() await test_specific_fields() await test_with_loadAdditionalFields() await test_create_with_explicit_ids() await check_standard_contact_entity() print_section("FAZIT") print("\n🎯 Wenn KEINE ID-Collections existieren:") print("\n Option 1: Separate CKommunikation Entity ✅ BESTE LÖSUNG") print(" Struktur:") print(" {") print(" 'id': 'espocrm-generated-id',") print(" 'beteiligteId': '68e4af00...',") print(" 'typ': 'Email/Phone',") print(" 'wert': 'max@example.com',") print(" 'advowareId': 149331,") print(" 'advowareRowId': 'ABC...'") print(" }") print("\n Vorteile:") print(" • Eigene Entity-ID für jede Kommunikation") print(" • advowareId/advowareRowId als eigene Felder") print(" • Sauberes Datenmodell") print(" • Stabiles bidirektionales Matching") print("\n Option 2: One-Way Sync (Advoware → EspoCRM)") print(" • Matching via Wert (emailAddress/phoneNumber)") print(" • Nur Advoware-Änderungen werden synchronisiert") print(" • EspoCRM als Read-Only Viewer") except Exception as e: print(f"\n❌ Fehler: {e}") import traceback traceback.print_exc() if __name__ == "__main__": asyncio.run(main())