diff --git a/services/advoware_document_sync_utils.py b/services/advoware_document_sync_utils.py index 0af8c35..518b48f 100644 --- a/services/advoware_document_sync_utils.py +++ b/services/advoware_document_sync_utils.py @@ -333,13 +333,10 @@ class AdvowareDocumentSyncUtils: if history_erstellung and history_erstellung != espo_erstellung: updates['advowareErstellungTimestamp'] = history_erstellung - # File is confirmed in-sync (SKIP = no file changes) → reset syncStatus if unclean - if espo_doc.get('syncStatus') != 'synced': - updates['syncStatus'] = 'synced' - # Always update lastSyncTimestamp when metadata changes (EspoCRM format) if len(updates) > 0: - updates['lastSyncTimestamp'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S') + now_str = datetime.now().strftime('%Y-%m-%d %H:%M:%S') + updates['lastSyncTimestamp'] = now_str needs_update = len(updates) > 0 diff --git a/src/steps/akte/akte_sync_event_step.py b/src/steps/akte/akte_sync_event_step.py index f7ebc3e..ca6eeed 100644 --- a/src/steps/akte/akte_sync_event_step.py +++ b/src/steps/akte/akte_sync_event_step.py @@ -225,6 +225,7 @@ async def _run_advoware_sync( all_hnrs = set(espo_by_hnr.keys()) | set(history_by_hnr.keys()) ctx.logger.info(f" Unique HNRs : {len(all_hnrs)}") + now = datetime.now().strftime('%Y-%m-%d %H:%M:%S') # ── 3-way merge per HNR ─────────────────────────────────────────── for hnr in all_hnrs: @@ -247,12 +248,22 @@ async def _run_advoware_sync( ctx.logger.info(f" [{action.action:12s}] {filename} (hnr={hnr}) – {action.reason}") if action.action == 'SKIP': - # Even for unchanged files: sync metadata from History (art, text, hnr, dat) - if espo_doc and history_entry: - needs_meta_update, meta_updates = sync_utils.should_sync_metadata(espo_doc, history_entry) - if needs_meta_update: - await espocrm.update_entity('CDokumente', espo_doc['id'], meta_updates) - ctx.logger.info(f" [META UPDATE ] {filename} (hnr={hnr}) – {list(meta_updates.keys())}") + # Even for unchanged files: sync metadata from History (art, text, dat) + # and always reset syncStatus if not already synced. + if espo_doc: + extra: Dict[str, Any] = {} + if history_entry: + needs_meta_update, meta_updates = sync_utils.should_sync_metadata(espo_doc, history_entry) + else: + needs_meta_update, meta_updates = False, {} + # File confirmed in-sync by 3-way merge → always ensure syncStatus=synced + if espo_doc.get('syncStatus') != 'synced': + extra['syncStatus'] = 'synced' + extra['lastSyncTimestamp'] = now + combined = {**meta_updates, **extra} + if combined: + await espocrm.update_entity('CDokumente', espo_doc['id'], combined) + ctx.logger.info(f" [META UPDATE ] {filename} (hnr={hnr}) – {list(combined.keys())}") results['updated'] += 1 else: results['skipped'] += 1 diff --git a/src/steps/crm/akte/akte_sync_event_step.py b/src/steps/crm/akte/akte_sync_event_step.py index 6a648ec..594ba3a 100644 --- a/src/steps/crm/akte/akte_sync_event_step.py +++ b/src/steps/crm/akte/akte_sync_event_step.py @@ -264,12 +264,22 @@ async def _run_advoware_sync( ctx.logger.info(f" [{action.action:12s}] {filename} (hnr={hnr}) – {action.reason}") if action.action == 'SKIP': - # Even for unchanged files: sync metadata from History (art, text, hnr, dat) - if espo_doc and history_entry: - needs_meta_update, meta_updates = sync_utils.should_sync_metadata(espo_doc, history_entry) - if needs_meta_update: - await espocrm.update_entity('CDokumente', espo_doc['id'], meta_updates) - ctx.logger.info(f" [META UPDATE ] {filename} (hnr={hnr}) – {list(meta_updates.keys())}") + # Even for unchanged files: sync metadata from History (art, text, dat) + # and always reset syncStatus if not already synced. + if espo_doc: + extra: Dict[str, Any] = {} + if history_entry: + needs_meta_update, meta_updates = sync_utils.should_sync_metadata(espo_doc, history_entry) + else: + needs_meta_update, meta_updates = False, {} + # File confirmed in-sync by 3-way merge → always ensure syncStatus=synced + if espo_doc.get('syncStatus') != 'synced': + extra['syncStatus'] = 'synced' + extra['lastSyncTimestamp'] = now + combined = {**meta_updates, **extra} + if combined: + await espocrm.update_entity('CDokumente', espo_doc['id'], combined) + ctx.logger.info(f" [META UPDATE ] {filename} (hnr={hnr}) – {list(combined.keys())}") results['updated'] += 1 else: results['skipped'] += 1 @@ -361,10 +371,10 @@ async def _run_advoware_sync( if erstellung_dat: update_data['advowareErstellungTimestamp'] = erstellung_dat - # Mark for re-sync to xAI only if file content actually changed + # Mark for re-sync to AI if file content actually changed # (USN can change without content change, e.g. metadata-only updates) content_changed = blake3_hash != espo_doc.get('syncedHash', '') - if content_changed and espo_doc.get('aiSyncStatus') == 'synced': + if content_changed and espo_doc.get('aiSyncStatus') in ('synced', 'failed'): update_data['aiSyncStatus'] = 'unclean' await espocrm.update_entity('CDokumente', espo_doc['id'], update_data) results['updated'] += 1 @@ -786,13 +796,18 @@ async def _run_ragflow_sync( ctx.logger.info(f" ✅ RAGflow-ID: {new_ragflow_id}") now_str = datetime.now().strftime('%Y-%m-%d %H:%M:%S') - await espocrm.update_entity('CDokumente', doc_id, { + # Reset aiParsingStatus so the parsing cron re-polls the new upload + is_new_upload = new_ragflow_id != (ragflow_doc.get('id') if ragflow_doc else None) + espo_update: Dict[str, Any] = { 'aiFileId': new_ragflow_id, 'aiCollectionId': dataset_id, 'aiSyncHash': blake3_hash, 'aiSyncStatus': 'synced', 'aiLastSync': now_str, - }) + } + if is_new_upload: + espo_update['aiParsingStatus'] = 'unknown' + await espocrm.update_entity('CDokumente', doc_id, espo_update) synced += 1 except Exception as e: