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:
37
api.php
37
api.php
@@ -280,12 +280,16 @@ class ZammadClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Hae tikettejä (search API palauttaa kaikki joihin on oikeus) */
|
/** 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)) {
|
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 {
|
} else {
|
||||||
$query = '*';
|
$query = '*';
|
||||||
}
|
}
|
||||||
|
if ($updatedSince) {
|
||||||
|
$query .= ' AND updated_at:>=' . $updatedSince;
|
||||||
|
}
|
||||||
return $this->request('GET', 'tickets/search?query=' . urlencode($query) . '&per_page=' . $perPage . '&page=' . $page . '&expand=true');
|
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');
|
$integ = dbGetIntegration($companyId, 'zammad');
|
||||||
if (!$integ || !$integ['enabled']) { http_response_code(400); echo json_encode(['error' => 'Zammad ei käytössä']); break; }
|
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 {
|
try {
|
||||||
$cfg = $integ['config'];
|
$cfg = $integ['config'];
|
||||||
$z = new ZammadClient($cfg['url'], $cfg['token']);
|
$z = new ZammadClient($cfg['url'], $cfg['token']);
|
||||||
$groupIds = $cfg['group_ids'] ?? [];
|
$groupIds = $cfg['group_ids'] ?? [];
|
||||||
$syncedGroupNames = $cfg['group_names'] ?? [];
|
$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
|
// Hae tikettejä Zammadista
|
||||||
$allTickets = [];
|
$allTickets = [];
|
||||||
$page = 1;
|
$page = 1;
|
||||||
|
$maxPages = $fullSync ? 10 : 3;
|
||||||
do {
|
do {
|
||||||
$batch = $z->getTickets($groupIds, $page, 100);
|
$batch = $z->getTickets($groupIds, $page, 100, $lastSync);
|
||||||
if (empty($batch)) break;
|
if (empty($batch)) break;
|
||||||
$allTickets = array_merge($allTickets, $batch);
|
$allTickets = array_merge($allTickets, $batch);
|
||||||
$page++;
|
$page++;
|
||||||
} while (count($batch) >= 100 && $page <= 10);
|
} while (count($batch) >= 100 && $page <= $maxPages);
|
||||||
|
|
||||||
$created = 0;
|
$created = 0;
|
||||||
$updated = 0;
|
$updated = 0;
|
||||||
@@ -5156,11 +5176,18 @@ switch ($action) {
|
|||||||
$created++;
|
$created++;
|
||||||
} else {
|
} else {
|
||||||
$ticketId = $existing['id'];
|
$ticketId = $existing['id'];
|
||||||
|
$zammadUpdated = date('Y-m-d H:i:s', strtotime($zt['updated_at'] ?? 'now'));
|
||||||
// Päivitä status/priority/group
|
// Päivitä status/priority/group
|
||||||
_dbExecute(
|
_dbExecute(
|
||||||
"UPDATE tickets SET status = ?, type = ?, priority = ?, subject = ?, zammad_group = ?, updated = ? WHERE id = ?",
|
"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++;
|
$updated++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2006,13 +2006,13 @@ document.getElementById('btn-fetch-emails').addEventListener('click', async () =
|
|||||||
const result = await apiCall('ticket_fetch', 'POST');
|
const result = await apiCall('ticket_fetch', 'POST');
|
||||||
let statusMsg = `Valmis! ${result.new_tickets} uutta tikettiä, ${result.threaded} ketjutettu viestiä.`;
|
let statusMsg = `Valmis! ${result.new_tickets} uutta tikettiä, ${result.threaded} ketjutettu viestiä.`;
|
||||||
|
|
||||||
// Hae myös Zammadista
|
// Hae myös Zammadista (full sync)
|
||||||
let zammadMsg = '';
|
let zammadMsg = '';
|
||||||
try {
|
try {
|
||||||
status.textContent = 'Synkataan Zammad...';
|
status.textContent = 'Synkataan Zammad...';
|
||||||
const zResult = await apiCall('zammad_sync', 'POST');
|
const zResult = await apiCall('zammad_sync', 'POST', { full: true });
|
||||||
if (zResult.created || zResult.updated || zResult.messages) {
|
if (zResult.created || zResult.updated || zResult.messages_added) {
|
||||||
zammadMsg = ` Zammad: ${zResult.created} uutta, ${zResult.updated} päivitettyä, ${zResult.messages} viestiä.`;
|
zammadMsg = ` Zammad: ${zResult.created} uutta, ${zResult.updated} päivitettyä, ${zResult.messages_added} viestiä.`;
|
||||||
}
|
}
|
||||||
} catch (ze) { /* Zammad ei käytössä tai virhe — ohitetaan */ }
|
} catch (ze) { /* Zammad ei käytössä tai virhe — ohitetaan */ }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user