feat(sync): Optimize matching and updating of communication entries in bidirectional sync
This commit is contained in:
@@ -594,13 +594,68 @@ class KommunikationSyncManager:
|
|||||||
try:
|
try:
|
||||||
advo_kommunikationen = advo_bet.get('kommunikation', [])
|
advo_kommunikationen = advo_bet.get('kommunikation', [])
|
||||||
|
|
||||||
# Var2: In EspoCRM gelöscht → Empty Slot in Advoware
|
# OPTIMIERUNG: Matche Var2 (Delete) + Var1 (New) mit gleichem kommKz
|
||||||
|
# → Direkt UPDATE statt DELETE+RELOAD+CREATE
|
||||||
|
var2_by_kommkz = {} # kommKz → [komm, ...]
|
||||||
|
var1_by_kommkz = {} # kommKz → [(value, espo_item), ...]
|
||||||
|
|
||||||
|
# Gruppiere Var2 nach kommKz
|
||||||
|
for komm in diff['espo_deleted']:
|
||||||
|
bemerkung = komm.get('bemerkung') or ''
|
||||||
|
marker = parse_marker(bemerkung)
|
||||||
|
if marker:
|
||||||
|
kommkz = marker['kommKz']
|
||||||
|
if kommkz not in var2_by_kommkz:
|
||||||
|
var2_by_kommkz[kommkz] = []
|
||||||
|
var2_by_kommkz[kommkz].append(komm)
|
||||||
|
|
||||||
|
# Gruppiere Var1 nach kommKz
|
||||||
|
for value, espo_item in diff['espo_new']:
|
||||||
|
espo_type = espo_item.get('type', 'email' if '@' in value else None)
|
||||||
|
kommkz = detect_kommkz(value, advo_bet, espo_type=espo_type)
|
||||||
|
if kommkz not in var1_by_kommkz:
|
||||||
|
var1_by_kommkz[kommkz] = []
|
||||||
|
var1_by_kommkz[kommkz].append((value, espo_item))
|
||||||
|
|
||||||
|
# Matche und führe direkte Updates aus
|
||||||
|
matched_var2_ids = set()
|
||||||
|
matched_var1_indices = {} # kommkz → set of matched indices
|
||||||
|
|
||||||
|
for kommkz in var2_by_kommkz.keys():
|
||||||
|
if kommkz in var1_by_kommkz:
|
||||||
|
var2_list = var2_by_kommkz[kommkz]
|
||||||
|
var1_list = var1_by_kommkz[kommkz]
|
||||||
|
|
||||||
|
# Matche paarweise
|
||||||
|
for i, (value, espo_item) in enumerate(var1_list):
|
||||||
|
if i < len(var2_list):
|
||||||
|
komm = var2_list[i]
|
||||||
|
komm_id = komm['id']
|
||||||
|
|
||||||
|
self.logger.info(f"[KOMM] 🔄 Var2+Var1 Match: kommKz={kommkz}, updating slot {komm_id} with '{value[:30]}...'")
|
||||||
|
|
||||||
|
# Direktes UPDATE statt DELETE+CREATE
|
||||||
|
await self.advoware.update_kommunikation(betnr, komm_id, {
|
||||||
|
'tlf': value,
|
||||||
|
'online': espo_item['primary'],
|
||||||
|
'bemerkung': create_marker(value, kommkz)
|
||||||
|
})
|
||||||
|
|
||||||
|
matched_var2_ids.add(komm_id)
|
||||||
|
if kommkz not in matched_var1_indices:
|
||||||
|
matched_var1_indices[kommkz] = set()
|
||||||
|
matched_var1_indices[kommkz].add(i)
|
||||||
|
|
||||||
|
result['created'] += 1
|
||||||
|
self.logger.info(f"[KOMM] ✅ Slot updated (optimized merge)")
|
||||||
|
|
||||||
|
# Unmatched Var2: Erstelle Empty Slots
|
||||||
for komm in diff['espo_deleted']:
|
for komm in diff['espo_deleted']:
|
||||||
komm_id = komm.get('id')
|
komm_id = komm.get('id')
|
||||||
tlf = (komm.get('tlf') or '').strip()
|
if komm_id not in matched_var2_ids:
|
||||||
self.logger.info(f"[KOMM] 🗑️ Var2: Deleted in EspoCRM - komm_id={komm_id}, value='{tlf[:30]}...'")
|
synced_value = komm.get('_synced_value', '')
|
||||||
await self._create_empty_slot(betnr, komm)
|
self.logger.info(f"[KOMM] 🗑️ Var2: Deleted in EspoCRM - komm_id={komm_id}, synced_value='{synced_value[:30]}...'")
|
||||||
self.logger.info(f"[KOMM] ✅ Empty slot created for komm_id={komm_id}")
|
await self._create_empty_slot(betnr, komm, synced_value=synced_value)
|
||||||
result['deleted'] += 1
|
result['deleted'] += 1
|
||||||
|
|
||||||
# Var5: In EspoCRM geändert (z.B. primary Flag)
|
# Var5: In EspoCRM geändert (z.B. primary Flag)
|
||||||
@@ -630,12 +685,16 @@ class KommunikationSyncManager:
|
|||||||
result['updated'] += 1
|
result['updated'] += 1
|
||||||
|
|
||||||
# Var1: Neu in EspoCRM → Create oder reuse Slot in Advoware
|
# Var1: Neu in EspoCRM → Create oder reuse Slot in Advoware
|
||||||
for value, espo_item in diff['espo_new']:
|
# Überspringe bereits gematchte Einträge (Var2+Var1 merged)
|
||||||
self.logger.info(f"[KOMM] ➕ Var1: New in EspoCRM '{value[:30]}...', type={espo_item.get('type')}")
|
for idx, (value, espo_item) in enumerate(diff['espo_new']):
|
||||||
|
|
||||||
# Erkenne kommKz mit espo_type
|
|
||||||
espo_type = espo_item.get('type', 'email' if '@' in value else None)
|
espo_type = espo_item.get('type', 'email' if '@' in value else None)
|
||||||
kommkz = detect_kommkz(value, advo_bet, espo_type=espo_type)
|
kommkz = detect_kommkz(value, advo_bet, espo_type=espo_type)
|
||||||
|
|
||||||
|
# Skip wenn bereits als Var2+Var1 Match verarbeitet
|
||||||
|
if kommkz in matched_var1_indices and idx in matched_var1_indices[kommkz]:
|
||||||
|
continue
|
||||||
|
|
||||||
|
self.logger.info(f"[KOMM] ➕ Var1: New in EspoCRM '{value[:30]}...', type={espo_item.get('type')}")
|
||||||
self.logger.info(f"[KOMM] 🔍 kommKz detected: espo_type={espo_type}, kommKz={kommkz}")
|
self.logger.info(f"[KOMM] 🔍 kommKz detected: espo_type={espo_type}, kommKz={kommkz}")
|
||||||
|
|
||||||
# Suche leeren Slot
|
# Suche leeren Slot
|
||||||
|
|||||||
Reference in New Issue
Block a user