Refactor document propagation and sync status hooks; deprecate CAkten hooks and implement new logic in CDokumente; update microtime values in config and state files

This commit is contained in:
2026-03-27 10:31:12 +01:00
parent 2a18e62528
commit fa3c92379f
8 changed files with 325 additions and 134 deletions

View File

@@ -29,89 +29,61 @@ class UpdateLastSyncFromDocuments implements BeforeSave
$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,
sync_status,
ai_sync_status
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]);
$rows = $stmt->fetchAll(\PDO::FETCH_ASSOC);
$row = $stmt->fetch(\PDO::FETCH_ASSOC);
if (empty($rows)) {
if (!$row || (int)$row['docCount'] === 0) {
$entity->set('syncStatus', 'unclean');
$entity->set('aiSyncStatus', 'unclean');
return;
}
// Timestamps
$maxAdvLastSync = null;
$maxAiLastSync = null;
// Status-Tracker
$advHasFailed = false;
$advHasUnsynced = false;
$aiHasFailed = false;
$aiHasUnsynced = false;
foreach ($rows as $row) {
// Advoware: neuester Timestamp
if (!empty($row['maxAdvLastSync'])) {
if ($maxAdvLastSync === null || $row['maxAdvLastSync'] > $maxAdvLastSync) {
$maxAdvLastSync = $row['maxAdvLastSync'];
}
}
// AI: neuester Timestamp
if (!empty($row['maxAiLastSync'])) {
if ($maxAiLastSync === null || $row['maxAiLastSync'] > $maxAiLastSync) {
$maxAiLastSync = $row['maxAiLastSync'];
}
}
// Advoware: schlechtester Status
$advStatus = $row['sync_status'] ?? null;
if ($advStatus === 'failed') {
$advHasFailed = true;
} elseif ($advStatus === 'new' || $advStatus === 'unclean' || $advStatus === null || $advStatus === '') {
$advHasUnsynced = true;
}
// AI: schlechtester Status
$aiStatus = $row['ai_sync_status'] ?? null;
if ($aiStatus === 'failed') {
$aiHasFailed = true;
} elseif ($aiStatus === 'new' || $aiStatus === 'unclean' || $aiStatus === null || $aiStatus === '') {
$aiHasUnsynced = true;
}
// Timestamps setzen
if (!empty($row['maxAdvLastSync'])) {
$entity->set('lastSync', $row['maxAdvLastSync']);
}
if (!empty($row['maxAiLastSync'])) {
$entity->set('aiLastSync', $row['maxAiLastSync']);
}
// Advoware Timestamp setzen
if ($maxAdvLastSync !== null) {
$entity->set('lastSync', $maxAdvLastSync);
}
// AI Timestamp setzen
if ($maxAiLastSync !== null) {
$entity->set('aiLastSync', $maxAiLastSync);
}
// Advoware Status setzen (worst-case)
if ($advHasFailed) {
// Advoware Status setzen (worst-case über alle Dokumente)
$advLevel = (int)($row['advWorstLevel'] ?? 0);
if ($advLevel >= 2) {
$entity->set('syncStatus', 'failed');
} elseif ($advHasUnsynced) {
} elseif ($advLevel === 1) {
$entity->set('syncStatus', 'unclean');
} else {
$entity->set('syncStatus', 'synced');
}
// AI Status setzen (worst-case)
if ($aiHasFailed) {
// AI Status setzen (worst-case über alle Dokumente)
$aiLevel = (int)($row['aiWorstLevel'] ?? 0);
if ($aiLevel >= 2) {
$entity->set('aiSyncStatus', 'failed');
} elseif ($aiHasUnsynced) {
} elseif ($aiLevel === 1) {
$entity->set('aiSyncStatus', 'unclean');
} else {
$entity->set('aiSyncStatus', 'synced');