feat: Add test notification system for EspoCRM integration
This commit is contained in:
252
bitbylaw/scripts/test_notification.py
Normal file
252
bitbylaw/scripts/test_notification.py
Normal file
@@ -0,0 +1,252 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Test: Notification System
|
||||||
|
==========================
|
||||||
|
|
||||||
|
Sendet testweise Notifications an EspoCRM:
|
||||||
|
1. Task-Erstellung
|
||||||
|
2. In-App Notification
|
||||||
|
3. READ-ONLY Field Conflict
|
||||||
|
"""
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
||||||
|
|
||||||
|
from services.notification_utils import NotificationManager
|
||||||
|
from services.espocrm import EspoCRMAPI
|
||||||
|
|
||||||
|
BOLD = '\033[1m'
|
||||||
|
GREEN = '\033[92m'
|
||||||
|
RED = '\033[91m'
|
||||||
|
YELLOW = '\033[93m'
|
||||||
|
BLUE = '\033[94m'
|
||||||
|
RESET = '\033[0m'
|
||||||
|
|
||||||
|
def print_success(text):
|
||||||
|
print(f"{GREEN}✓ {text}{RESET}")
|
||||||
|
|
||||||
|
def print_error(text):
|
||||||
|
print(f"{RED}✗ {text}{RESET}")
|
||||||
|
|
||||||
|
def print_info(text):
|
||||||
|
print(f"{BLUE}ℹ {text}{RESET}")
|
||||||
|
|
||||||
|
def print_section(title):
|
||||||
|
print(f"\n{BOLD}{'='*70}{RESET}")
|
||||||
|
print(f"{BOLD}{title}{RESET}")
|
||||||
|
print(f"{BOLD}{'='*70}{RESET}\n")
|
||||||
|
|
||||||
|
|
||||||
|
class SimpleLogger:
|
||||||
|
def debug(self, msg): pass
|
||||||
|
def info(self, msg): print(f"[INFO] {msg}")
|
||||||
|
def warning(self, msg): print(f"{YELLOW}[WARN] {msg}{RESET}")
|
||||||
|
def error(self, msg): print(f"{RED}[ERROR] {msg}{RESET}")
|
||||||
|
|
||||||
|
class SimpleContext:
|
||||||
|
def __init__(self):
|
||||||
|
self.logger = SimpleLogger()
|
||||||
|
|
||||||
|
|
||||||
|
async def main():
|
||||||
|
print_section("TEST: Notification System")
|
||||||
|
|
||||||
|
context = SimpleContext()
|
||||||
|
espo = EspoCRMAPI(context=context)
|
||||||
|
notification_mgr = NotificationManager(espocrm_api=espo, context=context)
|
||||||
|
|
||||||
|
# Finde echte Test-Adresse
|
||||||
|
print_info("Suche Test-Adresse in EspoCRM...")
|
||||||
|
|
||||||
|
import json
|
||||||
|
addresses = await espo.list_entities(
|
||||||
|
'CAdressen',
|
||||||
|
where=json.dumps([{
|
||||||
|
'type': 'contains',
|
||||||
|
'attribute': 'name',
|
||||||
|
'value': 'SYNC-TEST'
|
||||||
|
}]),
|
||||||
|
max_size=1
|
||||||
|
)
|
||||||
|
|
||||||
|
if not addresses.get('list'):
|
||||||
|
print_error("Keine SYNC-TEST Adresse gefunden - erstelle eine...")
|
||||||
|
|
||||||
|
# Hole Beteiligten
|
||||||
|
beteiligte = await espo.list_entities(
|
||||||
|
'CBeteiligte',
|
||||||
|
where=json.dumps([{
|
||||||
|
'type': 'equals',
|
||||||
|
'attribute': 'betNr',
|
||||||
|
'value': '104860'
|
||||||
|
}]),
|
||||||
|
max_size=1
|
||||||
|
)
|
||||||
|
|
||||||
|
if not beteiligte.get('list'):
|
||||||
|
print_error("Beteiligter nicht gefunden!")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Erstelle Test-Adresse
|
||||||
|
import datetime as dt
|
||||||
|
test_addr = await espo.create_entity('CAdressen', {
|
||||||
|
'name': f'NOTIFICATION-TEST {dt.datetime.now().strftime("%H:%M:%S")}',
|
||||||
|
'adresseStreet': 'Notification Test Str. 999',
|
||||||
|
'adresseCity': 'Teststadt',
|
||||||
|
'adressePostalCode': '12345',
|
||||||
|
'beteiligteId': beteiligte['list'][0]['id']
|
||||||
|
})
|
||||||
|
|
||||||
|
TEST_ENTITY_ID = test_addr['id']
|
||||||
|
print_success(f"Test-Adresse erstellt: {TEST_ENTITY_ID}")
|
||||||
|
else:
|
||||||
|
TEST_ENTITY_ID = addresses['list'][0]['id']
|
||||||
|
print_success(f"Test-Adresse gefunden: {TEST_ENTITY_ID}")
|
||||||
|
|
||||||
|
# 1. Test: Address Delete Required
|
||||||
|
print_section("1. Test: Address Delete Notification")
|
||||||
|
|
||||||
|
print_info("Sende DELETE-Notification...")
|
||||||
|
|
||||||
|
result = await notification_mgr.notify_manual_action_required(
|
||||||
|
entity_type='CAdressen',
|
||||||
|
entity_id=TEST_ENTITY_ID,
|
||||||
|
action_type='address_delete_required',
|
||||||
|
details={
|
||||||
|
'message': 'TEST: Adresse in Advoware löschen',
|
||||||
|
'description': (
|
||||||
|
'TEST-Notification:\n'
|
||||||
|
'Diese Adresse wurde in EspoCRM gelöscht:\n'
|
||||||
|
'Teststraße 123\n'
|
||||||
|
'10115 Berlin\n\n'
|
||||||
|
'Bitte manuell in Advoware löschen:\n'
|
||||||
|
'1. Öffne Beteiligten 104860 in Advoware\n'
|
||||||
|
'2. Gehe zu Adressen-Tab\n'
|
||||||
|
'3. Lösche Adresse (Index 1)\n'
|
||||||
|
'4. Speichern'
|
||||||
|
),
|
||||||
|
'advowareIndex': 1,
|
||||||
|
'betnr': 104860,
|
||||||
|
'address': 'Teststraße 123, Berlin',
|
||||||
|
'priority': 'Medium'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if result:
|
||||||
|
print_success("✓ DELETE-Notification gesendet!")
|
||||||
|
if result.get('task_id'):
|
||||||
|
print(f" Task ID: {result['task_id']}")
|
||||||
|
if result.get('notification_id'):
|
||||||
|
print(f" Notification ID: {result['notification_id']}")
|
||||||
|
else:
|
||||||
|
print_error("✗ DELETE-Notification fehlgeschlagen!")
|
||||||
|
|
||||||
|
# 2. Test: READ-ONLY Field Conflict
|
||||||
|
print_section("2. Test: READ-ONLY Field Conflict Notification")
|
||||||
|
|
||||||
|
print_info("Sende READ-ONLY Conflict Notification...")
|
||||||
|
|
||||||
|
changes = [
|
||||||
|
{
|
||||||
|
'field': 'Hauptadresse',
|
||||||
|
'espoField': 'isPrimary',
|
||||||
|
'advoField': 'standardAnschrift',
|
||||||
|
'espoCRM_value': True,
|
||||||
|
'advoware_value': False
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'field': 'Land',
|
||||||
|
'espoField': 'adresseCountry',
|
||||||
|
'advoField': 'land',
|
||||||
|
'espoCRM_value': 'AT',
|
||||||
|
'advoware_value': 'DE'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
change_details = '\n'.join([
|
||||||
|
f"- {c['field']}: EspoCRM='{c['espoCRM_value']}' → "
|
||||||
|
f"Advoware='{c['advoware_value']}'"
|
||||||
|
for c in changes
|
||||||
|
])
|
||||||
|
|
||||||
|
result2 = await notification_mgr.notify_manual_action_required(
|
||||||
|
entity_type='CAdressen',
|
||||||
|
entity_id=TEST_ENTITY_ID,
|
||||||
|
action_type='readonly_field_conflict',
|
||||||
|
details={
|
||||||
|
'message': f'TEST: {len(changes)} READ-ONLY Feld(er) geändert',
|
||||||
|
'description': (
|
||||||
|
f'TEST-Notification:\n'
|
||||||
|
f'Folgende Felder wurden in EspoCRM geändert, sind aber '
|
||||||
|
f'READ-ONLY in Advoware und können nicht automatisch '
|
||||||
|
f'synchronisiert werden:\n\n{change_details}\n\n'
|
||||||
|
f'Bitte manuell in Advoware anpassen:\n'
|
||||||
|
f'1. Öffne Beteiligten 104860 in Advoware\n'
|
||||||
|
f'2. Gehe zu Adressen-Tab\n'
|
||||||
|
f'3. Passe die Felder manuell an\n'
|
||||||
|
f'4. Speichern'
|
||||||
|
),
|
||||||
|
'changes': changes,
|
||||||
|
'address': 'Teststraße 123, Berlin',
|
||||||
|
'betnr': 104860,
|
||||||
|
'priority': 'High'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if result2:
|
||||||
|
print_success("✓ READ-ONLY Conflict Notification gesendet!")
|
||||||
|
if result2.get('task_id'):
|
||||||
|
print(f" Task ID: {result2['task_id']}")
|
||||||
|
if result2.get('notification_id'):
|
||||||
|
print(f" Notification ID: {result2['notification_id']}")
|
||||||
|
else:
|
||||||
|
print_error("✗ READ-ONLY Conflict Notification fehlgeschlagen!")
|
||||||
|
|
||||||
|
# 3. Test: General Manual Action
|
||||||
|
print_section("3. Test: General Manual Action Notification")
|
||||||
|
|
||||||
|
print_info("Sende allgemeine Notification...")
|
||||||
|
|
||||||
|
result3 = await notification_mgr.notify_manual_action_required(
|
||||||
|
entity_type='CBeteiligte',
|
||||||
|
entity_id='6987b30a9bbbfefd0',
|
||||||
|
action_type='general_manual_action',
|
||||||
|
details={
|
||||||
|
'message': 'TEST: Allgemeine manuelle Aktion erforderlich',
|
||||||
|
'description': (
|
||||||
|
'TEST-Notification:\n\n'
|
||||||
|
'Dies ist eine Test-Notification für das Notification-System.\n'
|
||||||
|
'Sie dient nur zu Testzwecken und kann ignoriert werden.\n\n'
|
||||||
|
f'Erstellt am: {datetime.now().strftime("%d.%m.%Y %H:%M:%S")}'
|
||||||
|
),
|
||||||
|
'priority': 'Low'
|
||||||
|
},
|
||||||
|
create_task=False # Kein Task für diesen Test
|
||||||
|
)
|
||||||
|
|
||||||
|
if result3:
|
||||||
|
print_success("✓ General Notification gesendet!")
|
||||||
|
if result3.get('task_id'):
|
||||||
|
print(f" Task ID: {result3['task_id']}")
|
||||||
|
if result3.get('notification_id'):
|
||||||
|
print(f" Notification ID: {result3['notification_id']}")
|
||||||
|
else:
|
||||||
|
print_error("✗ General Notification fehlgeschlagen!")
|
||||||
|
|
||||||
|
print_section("ZUSAMMENFASSUNG")
|
||||||
|
|
||||||
|
print_info("Prüfe EspoCRM:")
|
||||||
|
print(" 1. Öffne Tasks-Modul")
|
||||||
|
print(" 2. Suche nach 'TEST:'")
|
||||||
|
print(" 3. Prüfe Notifications (Glocken-Icon)")
|
||||||
|
print()
|
||||||
|
print_success("✓ 3 Test-Notifications versendet!")
|
||||||
|
print_info("⚠ Bitte manuell in EspoCRM löschen nach dem Test")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
asyncio.run(main())
|
||||||
Reference in New Issue
Block a user