Files
motia/bitbylaw/scripts/analysis/compare_entities_104860.py
bitbylaw 7856dd1d68 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.
2026-02-08 23:05:56 +00:00

234 lines
8.0 KiB
Python
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""
Vergleicht Advoware Entity (betNr 104860) mit EspoCRM Entity (68e3e7eab49f09adb)
um zu prüfen ob sie synchron sind.
"""
import asyncio
import sys
import json
from pathlib import Path
# Add parent directory to path
sys.path.insert(0, str(Path(__file__).parent.parent))
from services.advoware import AdvowareAPI
from services.advoware_service import AdvowareService
from services.espocrm import EspoCRMAPI
from services.espocrm_mapper import BeteiligteMapper
from services.beteiligte_sync_utils import BeteiligteSync
import hashlib
class SimpleContext:
"""Minimal context for logging"""
class Logger:
def info(self, msg): print(f" {msg}")
def debug(self, msg): print(f"🔍 {msg}")
def warn(self, msg): print(f"⚠️ {msg}")
def warning(self, msg): print(f"⚠️ {msg}")
def error(self, msg): print(f"{msg}")
def __init__(self):
self.logger = self.Logger()
def calculate_komm_hash(kommunikationen):
"""Berechnet Hash wie im Code"""
komm_rowids = sorted([k.get('rowId', '') for k in kommunikationen if k.get('rowId')])
return hashlib.md5(''.join(komm_rowids).encode()).hexdigest()[:16]
async def compare_entities():
context = SimpleContext()
# IDs
betnr = 104860
espo_id = "68e3e7eab49f09adb"
print(f"\n{'='*80}")
print(f"ENTITY COMPARISON")
print(f"{'='*80}")
print(f"Advoware betNr: {betnr}")
print(f"EspoCRM ID: {espo_id}")
print(f"{'='*80}\n")
# Initialize APIs
advoware_api = AdvowareAPI(context)
advoware_service = AdvowareService(context)
espocrm = EspoCRMAPI(context)
mapper = BeteiligteMapper()
sync_utils = BeteiligteSync(espocrm, None, context)
# ========== FETCH ADVOWARE ==========
print("\n📥 Fetching Advoware Entity...")
try:
advo_result = await advoware_api.api_call(
f'api/v1/advonet/Beteiligte/{betnr}',
method='GET'
)
if isinstance(advo_result, list):
advo_entity = advo_result[0] if advo_result else None
else:
advo_entity = advo_result
if not advo_entity:
print("❌ Advoware Entity nicht gefunden!")
return
print(f"✅ Advoware Entity geladen")
print(f" - Name: {advo_entity.get('name')}")
print(f" - rowId: {advo_entity.get('rowId', 'N/A')[:40]}...")
print(f" - geaendertAm: {advo_entity.get('geaendertAm')}")
print(f" - Kommunikationen: {len(advo_entity.get('kommunikation', []))}")
except Exception as e:
print(f"❌ Fehler beim Laden von Advoware: {e}")
import traceback
traceback.print_exc()
return
# ========== FETCH ESPOCRM ==========
print("\n📥 Fetching EspoCRM Entity...")
try:
espo_entity = await espocrm.get_entity('CBeteiligte', espo_id)
if not espo_entity:
print("❌ EspoCRM Entity nicht gefunden!")
return
print(f"✅ EspoCRM Entity geladen")
print(f" - Name: {espo_entity.get('name')}")
print(f" - betnr: {espo_entity.get('betnr')}")
print(f" - modifiedAt: {espo_entity.get('modifiedAt')}")
print(f" - syncStatus: {espo_entity.get('syncStatus')}")
print(f" - advowareLastSync: {espo_entity.get('advowareLastSync')}")
print(f" - advowareRowId: {espo_entity.get('advowareRowId', 'N/A')[:40]}...")
print(f" - kommunikationHash: {espo_entity.get('kommunikationHash')}")
print(f" - emailAddressData: {len(espo_entity.get('emailAddressData', []))}")
print(f" - phoneNumberData: {len(espo_entity.get('phoneNumberData', []))}")
except Exception as e:
print(f"❌ Fehler beim Laden von EspoCRM: {e}")
import traceback
traceback.print_exc()
return
# ========== COMPARISON ==========
print(f"\n{'='*80}")
print("STAMMDATEN VERGLEICH")
print(f"{'='*80}\n")
# Timestamp comparison
comparison = sync_utils.compare_entities(espo_entity, advo_entity)
print(f"🔍 Timestamp-Vergleich: {comparison}")
# Field-by-field comparison
print("\n📊 Feld-für-Feld Vergleich (Stammdaten):\n")
# Map Advoware → EspoCRM für Vergleich
advo_mapped = mapper.map_advoware_to_cbeteiligte(advo_entity)
fields_to_compare = [
'name', 'rechtsform', 'geburtsdatum', 'anrede',
'handelsregister', 'geschlecht', 'titel'
]
differences = []
for field in fields_to_compare:
espo_val = espo_entity.get(field)
advo_val = advo_mapped.get(field)
match = "" if espo_val == advo_val else ""
print(f"{match} {field:20} | EspoCRM: {str(espo_val)[:40]:40} | Advoware: {str(advo_val)[:40]:40}")
if espo_val != advo_val:
differences.append({
'field': field,
'espocrm': espo_val,
'advoware': advo_val
})
# ========== KOMMUNIKATION COMPARISON ==========
print(f"\n{'='*80}")
print("KOMMUNIKATION VERGLEICH")
print(f"{'='*80}\n")
advo_kommunikationen = advo_entity.get('kommunikation', [])
espo_emails = espo_entity.get('emailAddressData', [])
espo_phones = espo_entity.get('phoneNumberData', [])
# Hash Vergleich
current_hash = calculate_komm_hash(advo_kommunikationen)
stored_hash = espo_entity.get('kommunikationHash')
print(f"📊 Kommunikations-Hash:")
print(f" - Gespeichert in EspoCRM: {stored_hash}")
print(f" - Aktuell in Advoware: {current_hash}")
print(f" - Match: {'✅ JA' if current_hash == stored_hash else '❌ NEIN'}")
# Advoware Kommunikationen im Detail
print(f"\n📞 Advoware Kommunikationen ({len(advo_kommunikationen)}):")
for i, komm in enumerate(advo_kommunikationen, 1):
tlf = (komm.get('tlf') or '').strip()
kommkz = komm.get('kommKz', 0)
bemerkung = komm.get('bemerkung', '')[:50]
online = komm.get('online', False)
rowid = komm.get('rowId', 'N/A')[:20]
print(f" {i}. {tlf:30} | kommKz={kommkz:2} | online={online} | rowId={rowid}...")
if bemerkung:
print(f" Bemerkung: {bemerkung}...")
# EspoCRM Emails
print(f"\n📧 EspoCRM Emails ({len(espo_emails)}):")
for i, email in enumerate(espo_emails, 1):
addr = email.get('emailAddress', '')
primary = email.get('primary', False)
print(f" {i}. {addr:40} | primary={primary}")
# EspoCRM Phones
print(f"\n📱 EspoCRM Phones ({len(espo_phones)}):")
for i, phone in enumerate(espo_phones, 1):
num = phone.get('phoneNumber', '')
typ = phone.get('type', 'N/A')
primary = phone.get('primary', False)
print(f" {i}. {num:30} | type={typ:10} | primary={primary}")
# ========== SUMMARY ==========
print(f"\n{'='*80}")
print("ZUSAMMENFASSUNG")
print(f"{'='*80}\n")
if differences:
print(f"❌ STAMMDATEN NICHT SYNCHRON! {len(differences)} Unterschiede gefunden:")
for diff in differences:
print(f" - {diff['field']}: EspoCRM='{diff['espocrm']}' ≠ Advoware='{diff['advoware']}'")
else:
print("✅ Stammdaten sind synchron")
print()
if current_hash != stored_hash:
print(f"❌ KOMMUNIKATION NICHT SYNCHRON! Hash stimmt nicht überein")
else:
print("✅ Kommunikation-Hash stimmt überein (aber könnte trotzdem Unterschiede geben)")
print()
# Total count check
total_espo_komm = len(espo_emails) + len(espo_phones)
total_advo_komm = len([k for k in advo_kommunikationen if (k.get('tlf') or '').strip()])
if total_espo_komm != total_advo_komm:
print(f"⚠️ Anzahl-Unterschied: EspoCRM={total_espo_komm} ≠ Advoware={total_advo_komm}")
else:
print(f"✅ Anzahl stimmt überein: {total_espo_komm} Kommunikationen")
print(f"\n{'='*80}\n")
if __name__ == '__main__':
asyncio.run(compare_entities())