Files
espocrm/custom/Espo/Custom/Hooks/CAkten/UpdateLastSyncFromDocuments.php

97 lines
3.5 KiB
PHP

<?php
namespace Espo\Custom\Hooks\CAkten;
use Espo\ORM\Entity;
use Espo\ORM\Repository\Option\SaveOptions;
use Espo\Core\Hook\Hook\BeforeSave;
/**
* Hook: Aktualisiert lastSync + syncStatus (Advoware) und aiLastSync + aiSyncStatus (AI)
* basierend auf dem neuesten Timestamp und schlechtesten Status der verknüpften Dokumente.
*/
class UpdateLastSyncFromDocuments implements BeforeSave
{
public function __construct(
private \Espo\ORM\EntityManager $entityManager
) {}
public function beforeSave(Entity $entity, SaveOptions $options): void
{
if ($options->get('skipHooks')) {
return;
}
if ($entity->isNew()) {
return;
}
try {
$pdo = $this->entityManager->getPDO();
$aktenId = $entity->getId();
// Einzelne Zeile mit aggregierten Worst-Case-Werten über alle Dokumente.
// CASE-Ausdrücke in MAX() vermeiden das GROUP-BY-Problem bei gemischten
// Aggregat- und Nicht-Aggregat-Spalten.
$stmt = $pdo->prepare(
"SELECT
MAX(last_sync_timestamp) AS maxAdvLastSync,
MAX(ai_last_sync) AS maxAiLastSync,
MAX(CASE
WHEN sync_status = 'failed' THEN 2
WHEN sync_status IN ('new','unclean')
OR sync_status IS NULL OR sync_status = '' THEN 1
ELSE 0
END) AS advWorstLevel,
MAX(CASE
WHEN ai_sync_status = 'failed' THEN 2
WHEN ai_sync_status IN ('new','unclean')
OR ai_sync_status IS NULL OR ai_sync_status = '' THEN 1
ELSE 0
END) AS aiWorstLevel,
COUNT(*) AS docCount
FROM c_dokumente
WHERE c_akten_id = :aktenId AND deleted = 0"
);
$stmt->execute([':aktenId' => $aktenId]);
$row = $stmt->fetch(\PDO::FETCH_ASSOC);
if (!$row || (int)$row['docCount'] === 0) {
$entity->set('syncStatus', 'unclean');
$entity->set('aiSyncStatus', 'unclean');
return;
}
// Timestamps setzen
if (!empty($row['maxAdvLastSync'])) {
$entity->set('lastSync', $row['maxAdvLastSync']);
}
if (!empty($row['maxAiLastSync'])) {
$entity->set('aiLastSync', $row['maxAiLastSync']);
}
// Advoware Status setzen (worst-case über alle Dokumente)
$advLevel = (int)($row['advWorstLevel'] ?? 0);
if ($advLevel >= 2) {
$entity->set('syncStatus', 'failed');
} elseif ($advLevel === 1) {
$entity->set('syncStatus', 'unclean');
} else {
$entity->set('syncStatus', 'synced');
}
// AI Status setzen (worst-case über alle Dokumente)
$aiLevel = (int)($row['aiWorstLevel'] ?? 0);
if ($aiLevel >= 2) {
$entity->set('aiSyncStatus', 'failed');
} elseif ($aiLevel === 1) {
$entity->set('aiSyncStatus', 'unclean');
} else {
$entity->set('aiSyncStatus', 'synced');
}
} catch (\Exception $e) {
$GLOBALS['log']->error('CAkten UpdateLastSyncFromDocuments Hook Error: ' . $e->getMessage());
}
}
}