From c2c9cfe709f9a818c85bca12deb713d6b89ba652 Mon Sep 17 00:00:00 2001 From: bsiggel Date: Wed, 11 Mar 2026 19:55:29 +0100 Subject: [PATCH] Remove Advoware and x.AI related fields, tooltips, and options from CDokumente JSON files. Add UpdateJunctionSyncStatus hook to manage sync status for related entities on document updates. Update configuration timestamps in state and config files. --- .../CDokumente/UpdateJunctionSyncStatus.php | 155 ++++++++++++++++++ .../Resources/i18n/de_DE/CDokumente.json | 26 --- .../Resources/i18n/en_US/CDokumente.json | 27 +-- .../metadata/entityDefs/CDokumente.json | 69 -------- data/config.php | 2 +- data/state.php | 4 +- 6 files changed, 159 insertions(+), 124 deletions(-) create mode 100644 custom/Espo/Custom/Hooks/CDokumente/UpdateJunctionSyncStatus.php diff --git a/custom/Espo/Custom/Hooks/CDokumente/UpdateJunctionSyncStatus.php b/custom/Espo/Custom/Hooks/CDokumente/UpdateJunctionSyncStatus.php new file mode 100644 index 00000000..dd7daa89 --- /dev/null +++ b/custom/Espo/Custom/Hooks/CDokumente/UpdateJunctionSyncStatus.php @@ -0,0 +1,155 @@ +isNew()) { + return; + } + + // Überspringe, wenn keine relevanten Felder geändert wurden + if (!$this->hasRelevantChanges($entity)) { + return; + } + + try { + // Update AdvowareAkten Junction-Tables + $this->updateAdvowareAktenJunctions($entity); + + // Update AIKnowledge Junction-Tables + $this->updateAIKnowledgeJunctions($entity); + + } catch (\Exception $e) { + // Fehler loggen, aber nicht werfen (um Save nicht zu blockieren) + $GLOBALS['log']->error('CDokumente UpdateJunctionSyncStatus Hook Error: ' . $e->getMessage()); + } + } + + /** + * Prüft ob relevante Felder geändert wurden + */ + private function hasRelevantChanges(Entity $entity): bool + { + // Relevante Felder für Sync-Status + $relevantFields = [ + 'name', + 'description', + 'dokument', + 'dokumentId', + 'preview', + 'previewId', + 'fileStatus' + ]; + + foreach ($relevantFields as $field) { + if ($entity->isAttributeChanged($field)) { + return true; + } + } + + return false; + } + + /** + * Update AdvowareAkten Junction-Tables + */ + private function updateAdvowareAktenJunctions(Entity $entity): void + { + $updateQuery = $this->entityManager->getQueryBuilder() + ->update() + ->in('CAdvowareAktenDokumente') + ->set(['syncstatus' => 'unclean']) + ->where([ + 'cDokumenteId' => $entity->getId(), + 'deleted' => false + ]) + ->build(); + + $this->entityManager->getQueryExecutor()->execute($updateQuery); + + // Hole alle betroffenen AdvowareAkten IDs + $selectQuery = $this->entityManager->getQueryBuilder() + ->select(['cAdvowareAktenId']) + ->from('CAdvowareAktenDokumente') + ->where([ + 'cDokumenteId' => $entity->getId(), + 'deleted' => false + ]) + ->build(); + + $pdoStatement = $this->entityManager->getQueryExecutor()->execute($selectQuery); + $rows = $pdoStatement->fetchAll(\PDO::FETCH_ASSOC); + + // Trigger Update auf jeder AdvowareAkte (um CheckGlobalSyncStatus Hook auszulösen) + foreach ($rows as $row) { + $aktenId = $row['cAdvowareAktenId'] ?? null; + if ($aktenId) { + $akte = $this->entityManager->getEntity('CAdvowareAkten', $aktenId); + if ($akte) { + // Force Update ohne Hook-Loop + $akte->set('syncStatus', 'unclean'); + $this->entityManager->saveEntity($akte); + } + } + } + } + + /** + * Update AIKnowledge Junction-Tables + */ + private function updateAIKnowledgeJunctions(Entity $entity): void + { + $updateQuery = $this->entityManager->getQueryBuilder() + ->update() + ->in('CAIKnowledgeDokumente') + ->set(['syncstatus' => 'unclean']) + ->where([ + 'cDokumenteId' => $entity->getId(), + 'deleted' => false + ]) + ->build(); + + $this->entityManager->getQueryExecutor()->execute($updateQuery); + + // Hole alle betroffenen AIKnowledge IDs + $selectQuery = $this->entityManager->getQueryBuilder() + ->select(['cAIKnowledgeId']) + ->from('CAIKnowledgeDokumente') + ->where([ + 'cDokumenteId' => $entity->getId(), + 'deleted' => false + ]) + ->build(); + + $pdoStatement = $this->entityManager->getQueryExecutor()->execute($selectQuery); + $rows = $pdoStatement->fetchAll(\PDO::FETCH_ASSOC); + + // Trigger Update auf jeder AIKnowledge (um CheckGlobalSyncStatus Hook auszulösen) + foreach ($rows as $row) { + $knowledgeId = $row['cAIKnowledgeId'] ?? null; + if ($knowledgeId) { + $knowledge = $this->entityManager->getEntity('CAIKnowledge', $knowledgeId); + if ($knowledge) { + // Force Update ohne Hook-Loop + $knowledge->set('syncStatus', 'unclean'); + $this->entityManager->saveEntity($knowledge); + } + } + } + } +} diff --git a/custom/Espo/Custom/Resources/i18n/de_DE/CDokumente.json b/custom/Espo/Custom/Resources/i18n/de_DE/CDokumente.json index abbf6807..4ac7806f 100644 --- a/custom/Espo/Custom/Resources/i18n/de_DE/CDokumente.json +++ b/custom/Espo/Custom/Resources/i18n/de_DE/CDokumente.json @@ -5,12 +5,6 @@ "ydocumentuuid": "Y-Document-UUID", "md5sum": "MD5-Prüfsumme", "sha256": "SHA256-Prüfsumme", - "aktennr": "Advoware Identifikator", - "advowareLastSync": "Advoware letzte Synchronisation", - "syncStatus": "Sync-Status", - "xaiId": "x.AI ID", - "xaiCollections": "x.AI Collections", - "xaiSyncStatus": "Sync-Status", "fileStatus": "Datei-Status", "contactsvmhdokumente": "Freigegebene Nutzer", "vmhMietverhltnisesDokumente": "Mietverhältnisse", @@ -47,29 +41,9 @@ "Create CDokumente": "Dokument erstellen" }, "tooltips": { - "aktennr": "Eindeutige Dokument-Nummer aus Advoware", - "advowareLastSync": "Zeitpunkt der letzten Synchronisation mit Advoware", - "syncStatus": "Status der Advoware-Synchronisation: pending_sync = Warte auf Sync, clean = erfolgreich synchronisiert, unclean = Änderungen ausstehend, failed = Fehler, no_sync = Nicht synchronisiert", - "xaiId": "Eindeutige ID für x.AI Synchronisation", - "xaiCollections": "Liste der x.AI Collections für dieses Dokument", - "xaiSyncStatus": "Status der x.AI Synchronisation: pending_sync = Warte auf Sync, clean = erfolgreich synchronisiert, unclean = Änderungen ausstehend, failed = Fehler, no_sync = Nicht synchronisiert", "fileStatus": "Status der Datei: new = neu hochgeladen, changed = geändert, synced = synchronisiert" }, "options": { - "syncStatus": { - "pending_sync": "Warte auf Sync", - "clean": "Synchronisiert", - "unclean": "Änderungen ausstehend", - "failed": "Fehlgeschlagen", - "no_sync": "Kein Sync" - }, - "xaiSyncStatus": { - "pending_sync": "Warte auf Sync", - "clean": "Synchronisiert", - "unclean": "Abweichungen", - "failed": "Fehlgeschlagen", - "no_sync": "Kein Sync" - }, "fileStatus": { "new": "Neu", "changed": "Geändert", diff --git a/custom/Espo/Custom/Resources/i18n/en_US/CDokumente.json b/custom/Espo/Custom/Resources/i18n/en_US/CDokumente.json index 3a644eb8..3fb02c7b 100644 --- a/custom/Espo/Custom/Resources/i18n/en_US/CDokumente.json +++ b/custom/Espo/Custom/Resources/i18n/en_US/CDokumente.json @@ -14,14 +14,9 @@ "mietobjekt2dokumente": "Properties", "mietinkassosdokumente": "Rent Collection", "kndigungensdokumente": "Terminations", - "aktennr": "Advoware Identifier", - "advowareLastSync": "Advoware Last Sync", - "syncStatus": "Sync Status", - "xaiId": "x.AI ID", - "xaiCollections": "x.AI Collections", - "xaiSyncStatus": "Sync Status", "fileStatus": "File Status", "advowareAktens": "Advoware Akten", + "advowareAktens": "Advoware Akten", "aIKnowledges": "AI Knowledge", "advowareAktenHnr": "Advoware HNR", "advowareAktenSyncstatus": "Advoware Sync Status", @@ -52,29 +47,9 @@ "listForAIKnowledge": "List for AI Knowledge" }, "tooltips": { - "aktennr": "Unique document number from Advoware", - "advowareLastSync": "Time of last synchronization with Advoware", - "syncStatus": "Advoware synchronization status: pending_sync = Waiting for sync, clean = successfully synchronized, unclean = changes pending, failed = error, no_sync = Not synchronized", - "xaiId": "Unique ID for x.AI synchronization", - "xaiCollections": "List of x.AI collections for this document", - "xaiSyncStatus": "x.AI synchronization status: pending_sync = Waiting for sync, clean = successfully synchronized, unclean = changes pending, failed = error, no_sync = Not synchronized", "fileStatus": "File status: new = newly uploaded, changed = modified, synced = synchronized" }, "options": { - "syncStatus": { - "pending_sync": "Waiting for Sync", - "clean": "Synchronized", - "unclean": "Changes Pending", - "failed": "Failed", - "no_sync": "No Sync" - }, - "xaiSyncStatus": { - "pending_sync": "Waiting for Sync", - "clean": "Synchronized", - "unclean": "Changes Pending", - "failed": "Failed", - "no_sync": "No Sync" - }, "fileStatus": { "new": "New", "changed": "Changed", diff --git a/custom/Espo/Custom/Resources/metadata/entityDefs/CDokumente.json b/custom/Espo/Custom/Resources/metadata/entityDefs/CDokumente.json index 777bec6a..f358f3ba 100644 --- a/custom/Espo/Custom/Resources/metadata/entityDefs/CDokumente.json +++ b/custom/Espo/Custom/Resources/metadata/entityDefs/CDokumente.json @@ -75,75 +75,11 @@ "isCustom": true, "copyToClipboard": true }, - "aktennr": { - "type": "int", - "required": false, - "tooltip": true, - "isCustom": true - }, - "advowareLastSync": { - "type": "datetime", - "required": false, - "readOnly": true, - "tooltip": true, - "isCustom": true - }, - "syncStatus": { - "type": "enum", - "required": false, - "options": [ - "pending_sync", - "clean", - "unclean", - "failed", - "no_sync" - ], - "style": { - "pending_sync": "default", - "clean": "success", - "unclean": "warning", - "failed": "danger", - "no_sync": null - }, - "default": "no_sync", - "tooltip": true, - "isCustom": true - }, "puls": { "type": "link", "entity": "CPuls", "isCustom": true }, - "xaiId": { - "type": "varchar", - "maxLength": 255, - "isCustom": true - }, - "xaiCollections": { - "type": "array", - "isCustom": true - }, - "xaiSyncStatus": { - "type": "enum", - "required": false, - "options": [ - "pending_sync", - "clean", - "unclean", - "failed", - "no_sync" - ], - "style": { - "pending_sync": "default", - "clean": "success", - "unclean": "warning", - "failed": "danger", - "no_sync": null - }, - "default": "no_sync", - "tooltip": true, - "isCustom": true - }, "fileStatus": { "type": "enum", "required": false, @@ -362,11 +298,6 @@ "id" ] }, - "aktennr": { - "columns": [ - "aktennr" - ] - }, "md5sum": { "columns": [ "md5sum" diff --git a/data/config.php b/data/config.php index 438a1268..e543a46b 100644 --- a/data/config.php +++ b/data/config.php @@ -360,7 +360,7 @@ return [ 0 => 'youtube.com', 1 => 'google.com' ], - 'microtime' => 1773253602.105787, + 'microtime' => 1773255038.319449, 'siteUrl' => 'https://crm.bitbylaw.com', 'fullTextSearchMinLength' => 4, 'webSocketUrl' => 'ws://api.bitbylaw.com:5000/espocrm/ws', diff --git a/data/state.php b/data/state.php index 2ea8a0e2..d4d116f5 100644 --- a/data/state.php +++ b/data/state.php @@ -1,7 +1,7 @@ 1773253761, - 'microtimeState' => 1773253761.495155, + 'cacheTimestamp' => 1773255038, + 'microtimeState' => 1773255038.505417, 'currencyRates' => [ 'EUR' => 1.0 ],