feat(sync): Fix Var6 revert logic for direction='to_advoware' and enhance conflict handling

This commit is contained in:
2026-02-08 22:07:55 +00:00
parent 79e097be6f
commit 8de2654d74
3 changed files with 713 additions and 7 deletions

View File

@@ -117,22 +117,51 @@ class KommunikationSyncManager:
elif direction in ['both', 'to_espocrm'] and espo_wins:
self.logger.info(f"[KOMM] ⚠️ CONFLICT: EspoCRM wins - skipping Advoware→EspoCRM sync")
# FIX: Bei Konflikt müssen Var6-Änderungen (Advoware changed) revertiert werden!
if len(diff['advo_changed']) > 0:
self.logger.info(f"[KOMM] 🔄 Reverting {len(diff['advo_changed'])} Var6 entries to EspoCRM values (EspoCRM wins)...")
for komm, old_value, new_value in diff['advo_changed']:
await self._revert_advoware_change(betnr, komm, old_value, new_value, advo_bet)
result['espocrm_to_advoware']['updated'] += 1
# FIX: Bei Konflikt müssen Var4-Einträge (neu in Advoware) zu Empty Slots gemacht werden!
# Sonst bleiben sie in Advoware aber nicht in EspoCRM → Nicht synchron!
self.logger.info(f"[KOMM] 🔄 Converting {len(diff['advo_new'])} Var4 entries to Empty Slots (EspoCRM wins)...")
for komm in diff['advo_new']:
await self._create_empty_slot(betnr, komm)
result['espocrm_to_advoware']['deleted'] += 1
if len(diff['advo_new']) > 0:
self.logger.info(f"[KOMM] 🔄 Converting {len(diff['advo_new'])} Var4 entries to Empty Slots (EspoCRM wins)...")
for komm in diff['advo_new']:
await self._create_empty_slot(betnr, komm)
result['espocrm_to_advoware']['deleted'] += 1
else:
self.logger.info(f"[KOMM] Skipping Advoware→EspoCRM (direction={direction})")
# FIX: Bei direction='to_advoware' müssen Var6-Änderungen (Advoware changed)
# zurückgesetzt werden auf EspoCRM-Wert!
if direction == 'to_advoware' and len(diff['advo_changed']) > 0:
self.logger.info(f"[KOMM] 🔄 Reverting {len(diff['advo_changed'])} Var6 entries to EspoCRM values (EspoCRM wins)...")
for komm, old_value, new_value in diff['advo_changed']:
# Revert: new_value (Advoware) → old_value (EspoCRM synced value)
await self._revert_advoware_change(betnr, komm, old_value, new_value, advo_bet)
result['espocrm_to_advoware']['updated'] += 1
# Bei direction='to_advoware' müssen auch Var4-Einträge (neu in Advoware)
# zu Empty Slots gemacht werden!
if direction == 'to_advoware' and len(diff['advo_new']) > 0:
self.logger.info(f"[KOMM] 🔄 Converting {len(diff['advo_new'])} Var4 entries to Empty Slots (EspoCRM wins)...")
for komm in diff['advo_new']:
await self._create_empty_slot(betnr, komm)
result['espocrm_to_advoware']['deleted'] += 1
# 2. EspoCRM → Advoware (Var1: Neu in EspoCRM, Var2: Gelöscht in EspoCRM, Var5: Geändert in EspoCRM)
if direction in ['both', 'to_advoware']:
advo_result = await self._apply_espocrm_to_advoware(
betnr, diff, advo_bet
)
result['espocrm_to_advoware'] = advo_result
# FIX: Merge statt überschreiben (Var6/Var4 Counts aus else-Block behalten)
result['espocrm_to_advoware']['created'] += advo_result['created']
result['espocrm_to_advoware']['updated'] += advo_result['updated']
result['espocrm_to_advoware']['deleted'] += advo_result['deleted']
result['espocrm_to_advoware']['errors'].extend(advo_result['errors'])
total_changes = (
result['advoware_to_espocrm']['emails_synced'] +
@@ -592,6 +621,54 @@ class KommunikationSyncManager:
except Exception as e:
self.logger.error(f"[KOMM] Fehler beim Erstellen von Empty Slot: {e}", exc_info=True)
async def _revert_advoware_change(
self,
betnr: int,
advo_komm: Dict,
espo_synced_value: str,
advo_current_value: str,
advo_bet: Dict
) -> None:
"""
Revertiert Var6-Änderung in Advoware zurück auf EspoCRM-Wert
Verwendet bei direction='to_advoware' (EspoCRM wins):
- User hat in Advoware geändert
- Aber EspoCRM soll gewinnen
- → Setze Advoware zurück auf EspoCRM-Wert
Args:
advo_komm: Advoware Kommunikation mit Änderung
espo_synced_value: Der Wert der mit EspoCRM synchronisiert war (aus Marker)
advo_current_value: Der neue Wert in Advoware (User-Änderung)
"""
try:
komm_id = advo_komm['id']
bemerkung = advo_komm.get('bemerkung', '')
marker = parse_marker(bemerkung)
if not marker:
self.logger.error(f"[KOMM] Var6 ohne Marker - sollte nicht passieren! komm_id={komm_id}")
return
kommkz = marker['kommKz']
user_text = marker.get('user_text', '')
# Revert: Setze tlf zurück auf EspoCRM-Wert
new_marker = create_marker(espo_synced_value, kommkz, user_text)
update_data = {
'tlf': espo_synced_value,
'bemerkung': new_marker,
'online': advo_komm.get('online', False)
}
await self.advoware.update_kommunikation(betnr, komm_id, update_data)
self.logger.info(f"[KOMM] ✅ Reverted Var6: '{advo_current_value[:30]}...''{espo_synced_value[:30]}...' (komm_id={komm_id})")
except Exception as e:
self.logger.error(f"[KOMM] Fehler beim Revert von Var6: {e}", exc_info=True)
def _needs_update(self, advo_komm: Dict, espo_item: Dict) -> bool:
"""Prüft ob Update nötig ist"""
current_value = (advo_komm.get('tlf') or '').strip()