Optimoi Zammad-sync: inkrementaalinen haku oletuksena

Auto-refresh hakee nyt vain viimeisen synkkauksen jälkeen muuttuneet
tiketit (updated_at + 5min marginaali). Artikkelit haetaan vain
uusille tai muuttuneille tiketeille. "Hae postit" -nappi tekee
edelleen full syncin (full=true). Nopeuttaa autopäivitystä merkittävästi.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-13 00:39:24 +02:00
parent ecc0b06ba5
commit cbcfdaa2a3
2 changed files with 36 additions and 9 deletions

37
api.php
View File

@@ -280,12 +280,16 @@ class ZammadClient {
}
/** Hae tikettejä (search API palauttaa kaikki joihin on oikeus) */
public function getTickets(array $groupIds = [], int $page = 1, int $perPage = 100): array {
public function getTickets(array $groupIds = [], int $page = 1, int $perPage = 100, ?string $updatedSince = null): array {
if (!empty($groupIds)) {
$query = implode(' OR ', array_map(fn($id) => 'group_id:' . $id, $groupIds));
$parts = array_map(fn($id) => 'group_id:' . $id, $groupIds);
$query = '(' . implode(' OR ', $parts) . ')';
} else {
$query = '*';
}
if ($updatedSince) {
$query .= ' AND updated_at:>=' . $updatedSince;
}
return $this->request('GET', 'tickets/search?query=' . urlencode($query) . '&per_page=' . $perPage . '&page=' . $page . '&expand=true');
}
@@ -5094,21 +5098,37 @@ switch ($action) {
$integ = dbGetIntegration($companyId, 'zammad');
if (!$integ || !$integ['enabled']) { http_response_code(400); echo json_encode(['error' => 'Zammad ei käytössä']); break; }
// full=1 pakottaa täyden synkkauksen (esim. "Hae postit" -napista)
$fullSync = ($_GET['full'] ?? $_POST['full'] ?? '') === '1';
$input = json_decode(file_get_contents('php://input'), true) ?: [];
if (!empty($input['full'])) $fullSync = true;
try {
$cfg = $integ['config'];
$z = new ZammadClient($cfg['url'], $cfg['token']);
$groupIds = $cfg['group_ids'] ?? [];
$syncedGroupNames = $cfg['group_names'] ?? [];
// Hae viimeisin synkkausaika — inkrementaalinen haku
$lastSync = null;
if (!$fullSync) {
$row = _dbFetchOne("SELECT MAX(updated) as last_updated FROM tickets WHERE company_id = ? AND source = 'zammad'", [$companyId]);
if ($row && $row['last_updated']) {
// Hae 5 min marginaalilla ettei menetä mitään
$lastSync = date('Y-m-d\TH:i:s', strtotime($row['last_updated']) - 300);
}
}
// Hae tikettejä Zammadista
$allTickets = [];
$page = 1;
$maxPages = $fullSync ? 10 : 3;
do {
$batch = $z->getTickets($groupIds, $page, 100);
$batch = $z->getTickets($groupIds, $page, 100, $lastSync);
if (empty($batch)) break;
$allTickets = array_merge($allTickets, $batch);
$page++;
} while (count($batch) >= 100 && $page <= 10);
} while (count($batch) >= 100 && $page <= $maxPages);
$created = 0;
$updated = 0;
@@ -5156,11 +5176,18 @@ switch ($action) {
$created++;
} else {
$ticketId = $existing['id'];
$zammadUpdated = date('Y-m-d H:i:s', strtotime($zt['updated_at'] ?? 'now'));
// Päivitä status/priority/group
_dbExecute(
"UPDATE tickets SET status = ?, type = ?, priority = ?, subject = ?, zammad_group = ?, updated = ? WHERE id = ?",
[$status, $type, $priority, $zt['title'] ?? '', $group, date('Y-m-d H:i:s', strtotime($zt['updated_at'] ?? 'now')), $ticketId]
[$status, $type, $priority, $zt['title'] ?? '', $group, $zammadUpdated, $ticketId]
);
// Ohita artikkelien haku jos tiketti ei muuttunut (inkrementaalisessa syncissä)
$existingUpdated = $existing['updated'] ?? '';
if (!$fullSync && $existingUpdated === $zammadUpdated) {
$updated++;
continue;
}
$updated++;
}