Files
motia/bitbylaw/scripts/test_kommunikation_readonly.py
bitbylaw ebbbf419ee feat: Implement bidirectional synchronization utilities for Advoware and EspoCRM communications
- Added KommunikationSyncManager class to handle synchronization logic.
- Implemented methods for loading data, computing diffs, and applying changes between Advoware and EspoCRM.
- Introduced 3-way diffing mechanism to intelligently resolve conflicts.
- Added helper methods for creating empty slots and detecting changes in communications.
- Enhanced logging for better traceability during synchronization processes.
2026-02-08 19:53:40 +00:00

351 lines
11 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.
"""
Detaillierte Analyse: Welche Felder sind bei PUT änderbar?
Basierend auf ersten Tests:
- POST funktioniert (alle 4 Felder)
- PUT funktioniert TEILWEISE
- DELETE = 403 Forbidden (wie bei Adressen/Bankverbindungen)
Felder laut Swagger:
- tlf (string, nullable)
- bemerkung (string, nullable)
- kommKz (enum/int)
- online (boolean)
Response enthält zusätzlich:
- id (int) - Kommunikations-ID
- betNr (int) - Beteiligten-ID
- kommArt (int) - Scheint von kommKz generiert zu werden
- rowId (string) - Änderungserkennung
"""
import asyncio
import json
from services.advoware import AdvowareAPI
TEST_BETNR = 104860
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_field_mutability():
"""Teste welche Felder bei PUT änderbar sind"""
context = SimpleContext()
advo = AdvowareAPI(context)
# STEP 1: Erstelle Test-Kommunikation
print_section("STEP 1: Erstelle Test-Kommunikation")
create_data = {
'kommKz': 1, # TelGesch
'tlf': '+49 511 000000-00',
'bemerkung': 'TEST-READONLY: Initial',
'online': False
}
print(f"📤 POST Data: {json.dumps(create_data, indent=2)}")
result = await advo.api_call(
f'api/v1/advonet/Beteiligte/{TEST_BETNR}/Kommunikationen',
method='POST',
data=create_data
)
if isinstance(result, list) and len(result) > 0:
created = result[0]
else:
created = result
komm_id = created['id']
original_rowid = created['rowId']
print(f"\n✅ Erstellt:")
print(f" ID: {komm_id}")
print(f" rowId: {original_rowid}")
print(f" kommArt: {created['kommArt']}")
print(f"\n📋 Vollständige Response:")
print(json.dumps(created, indent=2, ensure_ascii=False))
# STEP 2: Teste jedes Feld einzeln
print_section("STEP 2: Teste Feld-Änderbarkeit")
test_results = {}
# Test 1: tlf
print("\n🔬 Test 1/4: tlf (Telefonnummer/Email)")
print(" Änderung: '+49 511 000000-00''+49 511 111111-11'")
test_data = {
'kommKz': created['kommKz'],
'tlf': '+49 511 111111-11', # GEÄNDERT
'bemerkung': created['bemerkung'],
'online': created['online']
}
try:
result = await advo.api_call(
f'api/v1/advonet/Beteiligte/{TEST_BETNR}/Kommunikationen/{komm_id}',
method='PUT',
data=test_data
)
new_rowid = result['rowId']
rowid_changed = (new_rowid != original_rowid)
value_changed = (result['tlf'] == '+49 511 111111-11')
print(f" ✅ PUT erfolgreich")
print(f" 📊 Wert geändert: {value_changed}")
print(f" 📊 rowId geändert: {rowid_changed}")
print(f" Alt: {original_rowid}")
print(f" Neu: {new_rowid}")
test_results['tlf'] = {
'writable': value_changed,
'rowid_changed': rowid_changed,
'status': 'WRITABLE' if value_changed else 'READ-ONLY'
}
original_rowid = new_rowid # Update für nächsten Test
except Exception as e:
print(f" ❌ FEHLER: {e}")
test_results['tlf'] = {'writable': False, 'status': 'ERROR', 'error': str(e)}
# Test 2: bemerkung
print("\n🔬 Test 2/4: bemerkung")
print(" Änderung: 'TEST-READONLY: Initial''TEST-READONLY: Modified'")
test_data = {
'kommKz': created['kommKz'],
'tlf': result['tlf'], # Aktueller Wert
'bemerkung': 'TEST-READONLY: Modified', # GEÄNDERT
'online': result['online']
}
try:
result = await advo.api_call(
f'api/v1/advonet/Beteiligte/{TEST_BETNR}/Kommunikationen/{komm_id}',
method='PUT',
data=test_data
)
new_rowid = result['rowId']
rowid_changed = (new_rowid != original_rowid)
value_changed = (result['bemerkung'] == 'TEST-READONLY: Modified')
print(f" ✅ PUT erfolgreich")
print(f" 📊 Wert geändert: {value_changed}")
print(f" 📊 rowId geändert: {rowid_changed}")
test_results['bemerkung'] = {
'writable': value_changed,
'rowid_changed': rowid_changed,
'status': 'WRITABLE' if value_changed else 'READ-ONLY'
}
original_rowid = new_rowid
except Exception as e:
print(f" ❌ FEHLER: {e}")
test_results['bemerkung'] = {'writable': False, 'status': 'ERROR', 'error': str(e)}
# Test 3: kommKz
print("\n🔬 Test 3/4: kommKz (Kommunikationstyp)")
original_kommkz = result['kommKz']
target_kommkz = 6
print(f" Änderung: {original_kommkz} (TelGesch) → {target_kommkz} (TelPrivat)")
test_data = {
'kommKz': target_kommkz, # GEÄNDERT
'tlf': result['tlf'],
'bemerkung': f"TEST-READONLY: Versuch kommKz {original_kommkz}{target_kommkz}",
'online': result['online']
}
try:
result = await advo.api_call(
f'api/v1/advonet/Beteiligte/{TEST_BETNR}/Kommunikationen/{komm_id}',
method='PUT',
data=test_data
)
new_rowid = result['rowId']
rowid_changed = (new_rowid != original_rowid)
value_changed = (result['kommKz'] == target_kommkz)
print(f" ✅ PUT erfolgreich")
print(f" 📊 PUT Response kommKz: {result['kommKz']}")
print(f" 📊 PUT Response kommArt: {result['kommArt']}")
print(f" 📊 rowId geändert: {rowid_changed}")
# WICHTIG: Nachfolgender GET zur Verifizierung
print(f"\n 🔍 Verifizierung via GET...")
beteiligte_get = await advo.api_call(
f'api/v1/advonet/Beteiligte/{TEST_BETNR}',
method='GET'
)
if isinstance(beteiligte_get, list):
beteiligte_get = beteiligte_get[0]
kommunikationen_get = beteiligte_get.get('kommunikation', [])
verify_komm = next((k for k in kommunikationen_get if k['id'] == komm_id), None)
if verify_komm:
print(f" 📋 GET Response kommKz: {verify_komm['kommKz']}")
print(f" 📋 GET Response kommArt: {verify_komm['kommArt']}")
print(f" 📋 GET Response bemerkung: {verify_komm['bemerkung']}")
# Finale Bewertung basierend auf GET
actual_value_changed = (verify_komm['kommKz'] == target_kommkz)
if actual_value_changed:
print(f" ✅ BESTÄTIGT: kommKz wurde geändert auf {target_kommkz}")
else:
print(f" ❌ BESTÄTIGT: kommKz blieb bei {verify_komm['kommKz']} (nicht geändert!)")
test_results['kommKz'] = {
'writable': actual_value_changed,
'rowid_changed': rowid_changed,
'status': 'WRITABLE' if actual_value_changed else 'READ-ONLY',
'requested_value': target_kommkz,
'put_response_value': result['kommKz'],
'get_response_value': verify_komm['kommKz'],
'note': f"PUT sagte: {result['kommKz']}, GET sagte: {verify_komm['kommKz']}"
}
else:
print(f" ⚠️ Kommunikation nicht in GET gefunden")
test_results['kommKz'] = {
'writable': False,
'status': 'ERROR',
'error': 'Not found in GET'
}
original_rowid = new_rowid
except Exception as e:
print(f" ❌ FEHLER: {e}")
test_results['kommKz'] = {'writable': False, 'status': 'ERROR', 'error': str(e)}
# Test 4: online
print("\n🔬 Test 4/4: online (Boolean Flag)")
print(" Änderung: False → True")
test_data = {
'kommKz': result['kommKz'],
'tlf': result['tlf'],
'bemerkung': result['bemerkung'],
'online': True # GEÄNDERT
}
try:
result = await advo.api_call(
f'api/v1/advonet/Beteiligte/{TEST_BETNR}/Kommunikationen/{komm_id}',
method='PUT',
data=test_data
)
new_rowid = result['rowId']
rowid_changed = (new_rowid != original_rowid)
value_changed = (result['online'] == True)
print(f" ✅ PUT erfolgreich")
print(f" 📊 Wert geändert: {value_changed}")
print(f" 📊 rowId geändert: {rowid_changed}")
test_results['online'] = {
'writable': value_changed,
'rowid_changed': rowid_changed,
'status': 'WRITABLE' if value_changed else 'READ-ONLY'
}
except Exception as e:
print(f" ❌ FEHLER: {e}")
test_results['online'] = {'writable': False, 'status': 'ERROR', 'error': str(e)}
# ZUSAMMENFASSUNG
print_section("ZUSAMMENFASSUNG: Feld-Status")
print("\n📊 Ergebnisse:\n")
for field, result in test_results.items():
status = result['status']
icon = "" if status == "WRITABLE" else "" if status == "READ-ONLY" else "⚠️"
print(f" {icon} {field:15s}{status}")
if result.get('note'):
print(f" {result['note']}")
if result.get('error'):
print(f" ⚠️ {result['error']}")
# Count
writable = sum(1 for r in test_results.values() if r['status'] == 'WRITABLE')
readonly = sum(1 for r in test_results.values() if r['status'] == 'READ-ONLY')
print(f"\n📈 Statistik:")
print(f" WRITABLE: {writable}/{len(test_results)} Felder")
print(f" READ-ONLY: {readonly}/{len(test_results)} Felder")
print(f"\n⚠️ Test-Kommunikation {komm_id} manuell löschen!")
print(f" BetNr: {TEST_BETNR}")
return test_results
async def main():
print("\n" + "="*70)
print("KOMMUNIKATION API - FELDANALYSE")
print("="*70)
print("\nZiel: Herausfinden welche Felder bei PUT änderbar sind")
print("Methode: Einzelne Feldänderungen + rowId-Tracking\n")
try:
results = await test_field_mutability()
print_section("EMPFEHLUNG FÜR MAPPER")
writable_fields = [f for f, r in results.items() if r['status'] == 'WRITABLE']
readonly_fields = [f for f, r in results.items() if r['status'] == 'READ-ONLY']
if writable_fields:
print("\n✅ Für UPDATE (PUT) verwenden:")
for field in writable_fields:
print(f" - {field}")
if readonly_fields:
print("\n❌ NUR bei CREATE (POST) verwenden:")
for field in readonly_fields:
print(f" - {field}")
print("\n💡 Sync-Strategie:")
print(" - CREATE: Alle Felder")
print(" - UPDATE: Nur WRITABLE Felder")
print(" - DELETE: Notification (403 Forbidden)")
except Exception as e:
print(f"\n❌ Fehler: {e}")
import traceback
traceback.print_exc()
if __name__ == '__main__':
asyncio.run(main())