Add tests for Kommunikation Sync implementation and verification scripts
- Implemented comprehensive tests for the Kommunikation Sync functionality, covering base64 encoding, marker parsing, creation, type detection, and integration scenarios. - Added a verification script to check for unique IDs in Advoware communications, ensuring stability and integrity of the IDs. - Created utility scripts for code validation, notification testing, and PUT response detail analysis to enhance development and testing processes. - Updated README with details on new tools and their usage.
This commit is contained in:
@@ -0,0 +1,202 @@
|
||||
"""
|
||||
Detail-Analyse: emailAddressData und phoneNumberData Struktur
|
||||
|
||||
Erkenntnisse:
|
||||
- CKommunikation Entity existiert NICHT in EspoCRM
|
||||
- CBeteiligte hat phoneNumberData und emailAddressData Arrays
|
||||
- PhoneNumber und EmailAddress Entities existieren (aber 403 Forbidden - nur intern)
|
||||
|
||||
Jetzt: Analysiere die Data-Arrays im Detail
|
||||
"""
|
||||
|
||||
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): print(f"[DEBUG] {msg}")
|
||||
|
||||
def __init__(self):
|
||||
self.logger = self.Logger()
|
||||
|
||||
|
||||
def print_section(title):
|
||||
print("\n" + "="*70)
|
||||
print(title)
|
||||
print("="*70)
|
||||
|
||||
|
||||
async def analyze_communication_data():
|
||||
"""Detaillierte Analyse der Communication-Data Felder"""
|
||||
|
||||
print_section("DETAIL-ANALYSE: emailAddressData und phoneNumberData")
|
||||
|
||||
context = SimpleContext()
|
||||
espo = EspoCRMAPI(context)
|
||||
|
||||
# Hole Beteiligten
|
||||
entity = await espo.get_entity('CBeteiligte', TEST_BETEILIGTE_ID)
|
||||
|
||||
print(f"\n✅ Beteiligter: {entity.get('name')}")
|
||||
print(f" ID: {entity.get('id')}")
|
||||
|
||||
# emailAddressData
|
||||
print("\n" + "="*50)
|
||||
print("emailAddressData")
|
||||
print("="*50)
|
||||
|
||||
email_data = entity.get('emailAddressData', [])
|
||||
|
||||
if email_data:
|
||||
print(f"\n📧 {len(email_data)} Email-Adresse(n):\n")
|
||||
|
||||
for i, email in enumerate(email_data):
|
||||
print(f"[{i+1}] {json.dumps(email, indent=2, ensure_ascii=False)}")
|
||||
|
||||
# Analysiere Struktur
|
||||
if i == 0:
|
||||
print(f"\n📊 Feld-Struktur:")
|
||||
for key, value in email.items():
|
||||
print(f" • {key:20s}: {type(value).__name__:10s} = {value}")
|
||||
else:
|
||||
print("\n❌ Keine Email-Adressen vorhanden")
|
||||
|
||||
# phoneNumberData
|
||||
print("\n" + "="*50)
|
||||
print("phoneNumberData")
|
||||
print("="*50)
|
||||
|
||||
phone_data = entity.get('phoneNumberData', [])
|
||||
|
||||
if phone_data:
|
||||
print(f"\n📞 {len(phone_data)} Telefonnummer(n):\n")
|
||||
|
||||
for i, phone in enumerate(phone_data):
|
||||
print(f"[{i+1}] {json.dumps(phone, indent=2, ensure_ascii=False)}")
|
||||
|
||||
# Analysiere Struktur
|
||||
if i == 0:
|
||||
print(f"\n📊 Feld-Struktur:")
|
||||
for key, value in phone.items():
|
||||
print(f" • {key:20s}: {type(value).__name__:10s} = {value}")
|
||||
else:
|
||||
print("\n❌ Keine Telefonnummern vorhanden")
|
||||
|
||||
# Prüfe andere Beteiligten mit mehr Kommunikationsdaten
|
||||
print_section("SUCHE: Beteiligter mit mehr Kommunikationsdaten")
|
||||
|
||||
print("\n🔍 Liste erste 20 Beteiligte und prüfe Kommunikationsdaten...\n")
|
||||
|
||||
beteiligte_list = await espo.list_entities('CBeteiligte', max_size=20)
|
||||
|
||||
best_example = None
|
||||
max_comm_count = 0
|
||||
|
||||
for bet in beteiligte_list:
|
||||
# list_entities kann Strings oder Dicts zurückgeben
|
||||
if isinstance(bet, str):
|
||||
continue
|
||||
|
||||
email_count = len(bet.get('emailAddressData', []))
|
||||
phone_count = len(bet.get('phoneNumberData', []))
|
||||
total = email_count + phone_count
|
||||
|
||||
if total > 0:
|
||||
print(f"• {bet.get('name', 'N/A')[:40]:40s} | "
|
||||
f"Email: {email_count} | Phone: {phone_count}")
|
||||
|
||||
if total > max_comm_count:
|
||||
max_comm_count = total
|
||||
best_example = bet
|
||||
|
||||
if best_example and max_comm_count > 0:
|
||||
print(f"\n✅ Bester Beispiel-Beteiligter: {best_example.get('name')}")
|
||||
print(f" Gesamt: {max_comm_count} Kommunikationseinträge")
|
||||
|
||||
print("\n📧 emailAddressData:")
|
||||
for i, email in enumerate(best_example.get('emailAddressData', [])):
|
||||
print(f"\n [{i+1}] {json.dumps(email, indent=6, ensure_ascii=False)}")
|
||||
|
||||
print("\n📞 phoneNumberData:")
|
||||
for i, phone in enumerate(best_example.get('phoneNumberData', [])):
|
||||
print(f"\n [{i+1}] {json.dumps(phone, indent=6, ensure_ascii=False)}")
|
||||
|
||||
return entity, email_data, phone_data, best_example
|
||||
|
||||
|
||||
async def main():
|
||||
print("\n" + "="*70)
|
||||
print("ESPOCRM KOMMUNIKATION - DETAIL-ANALYSE")
|
||||
print("="*70)
|
||||
print("\nZiel: Verstehe die Struktur von emailAddressData und phoneNumberData")
|
||||
print("Frage: Haben diese Arrays IDs für Matching mit Advoware?\n")
|
||||
|
||||
try:
|
||||
entity, emails, phones, best = await analyze_communication_data()
|
||||
|
||||
print_section("ZUSAMMENFASSUNG")
|
||||
|
||||
print("\n📊 Erkenntnisse:")
|
||||
|
||||
print("\n1️⃣ EspoCRM Standard-Struktur:")
|
||||
print(" • emailAddressData: Array von Email-Objekten")
|
||||
print(" • phoneNumberData: Array von Telefon-Objekten")
|
||||
print(" • Keine separate CKommunikation Entity")
|
||||
|
||||
if emails:
|
||||
print("\n2️⃣ emailAddressData Felder:")
|
||||
sample = emails[0]
|
||||
for key in sample.keys():
|
||||
print(f" • {key}")
|
||||
|
||||
if 'id' in sample:
|
||||
print("\n ✅ Hat 'id' Feld → Kann für Matching verwendet werden!")
|
||||
else:
|
||||
print("\n ❌ Kein 'id' Feld → Matching via Wert (emailAddress)")
|
||||
|
||||
if phones:
|
||||
print("\n3️⃣ phoneNumberData Felder:")
|
||||
sample = phones[0]
|
||||
for key in sample.keys():
|
||||
print(f" • {key}")
|
||||
|
||||
if 'id' in sample:
|
||||
print("\n ✅ Hat 'id' Feld → Kann für Matching verwendet werden!")
|
||||
else:
|
||||
print("\n ❌ Kein 'id' Feld → Matching via Wert (phoneNumber)")
|
||||
|
||||
print("\n💡 Sync-Strategie:")
|
||||
print("\n Option A: Kommunikation als Teil von Beteiligte-Sync")
|
||||
print(" ────────────────────────────────────────────────────")
|
||||
print(" • emailAddressData → Advoware Kommunikation (kommKz=4)")
|
||||
print(" • phoneNumberData → Advoware Kommunikation (kommKz=1)")
|
||||
print(" • Sync innerhalb von beteiligte_sync.py")
|
||||
print(" • Kein separates Entity in EspoCRM nötig")
|
||||
|
||||
print("\n Option B: Custom CKommunikation Entity erstellen")
|
||||
print(" ────────────────────────────────────────────────────")
|
||||
print(" • Neues Custom Entity in EspoCRM anlegen")
|
||||
print(" • Many-to-One Beziehung zu CBeteiligte")
|
||||
print(" • Separater kommunikation_sync.py")
|
||||
print(" • Ermöglicht mehr Flexibilität (Fax, BeA, etc.)")
|
||||
|
||||
print("\n ⚠️ WICHTIG:")
|
||||
print(" • Standard EspoCRM hat NUR Email und Phone")
|
||||
print(" • Advoware hat 12 verschiedene Kommunikationstypen")
|
||||
print(" • Für vollständigen Sync → Custom Entity empfohlen")
|
||||
|
||||
except Exception as e:
|
||||
print(f"\n❌ Fehler: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
asyncio.run(main())
|
||||
Reference in New Issue
Block a user