Add auto-rules management, bulk actions for tickets
- Auto-rules JS: load, render, save, edit, delete, toggle rules - Rules UI: Säännöt view with rule list and form - Bulk actions: checkbox selection in ticket list - Bulk close/delete endpoints (ticket_bulk_status, ticket_bulk_delete) - Bulk toolbar with select all, close selected, delete selected Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
128
api.php
128
api.php
@@ -1534,12 +1534,40 @@ switch ($action) {
|
||||
'from_email' => $email['from_email'],
|
||||
'from_name' => $email['from_name'],
|
||||
'status' => 'uusi',
|
||||
'type' => 'muu',
|
||||
'assigned_to' => '',
|
||||
'customer_id' => '',
|
||||
'customer_name' => '',
|
||||
'created' => $email['date'],
|
||||
'updated' => $email['date'],
|
||||
'message_id' => $email['message_id'],
|
||||
'messages' => [$msg],
|
||||
];
|
||||
|
||||
// Apply auto-rules
|
||||
$rules = $config['ticket_rules'] ?? [];
|
||||
foreach ($rules as $rule) {
|
||||
if (empty($rule['enabled'])) continue;
|
||||
$match = true;
|
||||
if (!empty($rule['from_contains'])) {
|
||||
$needle = strtolower($rule['from_contains']);
|
||||
if (strpos(strtolower($email['from_email'] . ' ' . $email['from_name']), $needle) === false) {
|
||||
$match = false;
|
||||
}
|
||||
}
|
||||
if (!empty($rule['subject_contains'])) {
|
||||
$needle = strtolower($rule['subject_contains']);
|
||||
if (strpos(strtolower($email['subject'] ?? ''), $needle) === false) {
|
||||
$match = false;
|
||||
}
|
||||
}
|
||||
if ($match) {
|
||||
if (!empty($rule['set_status'])) $ticket['status'] = $rule['set_status'];
|
||||
if (!empty($rule['set_type'])) $ticket['type'] = $rule['set_type'];
|
||||
break; // First matching rule wins
|
||||
}
|
||||
}
|
||||
|
||||
$tickets[] = $ticket;
|
||||
$newCount++;
|
||||
}
|
||||
@@ -1802,6 +1830,106 @@ switch ($action) {
|
||||
echo json_encode(['success' => true]);
|
||||
break;
|
||||
|
||||
case 'ticket_rules':
|
||||
requireAuth();
|
||||
$config = loadConfig();
|
||||
echo json_encode($config['ticket_rules'] ?? []);
|
||||
break;
|
||||
|
||||
case 'ticket_rule_save':
|
||||
requireAuth();
|
||||
if ($method !== 'POST') break;
|
||||
$input = json_decode(file_get_contents('php://input'), true);
|
||||
$config = loadConfig();
|
||||
$rules = $config['ticket_rules'] ?? [];
|
||||
|
||||
$rule = [
|
||||
'id' => $input['id'] ?? generateId(),
|
||||
'name' => trim($input['name'] ?? ''),
|
||||
'from_contains' => trim($input['from_contains'] ?? ''),
|
||||
'subject_contains' => trim($input['subject_contains'] ?? ''),
|
||||
'set_status' => $input['set_status'] ?? '',
|
||||
'set_type' => $input['set_type'] ?? '',
|
||||
'enabled' => $input['enabled'] ?? true,
|
||||
];
|
||||
|
||||
if (empty($rule['name'])) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['error' => 'Säännön nimi puuttuu']);
|
||||
break;
|
||||
}
|
||||
|
||||
// Update existing or add new
|
||||
$found = false;
|
||||
foreach ($rules as &$r) {
|
||||
if ($r['id'] === $rule['id']) {
|
||||
$r = $rule;
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
unset($r);
|
||||
if (!$found) $rules[] = $rule;
|
||||
|
||||
$config['ticket_rules'] = $rules;
|
||||
file_put_contents(DATA_DIR . '/config.json', json_encode($config, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
|
||||
addLog('config_update', '', '', 'Tikettisääntö: ' . $rule['name']);
|
||||
echo json_encode($rule);
|
||||
break;
|
||||
|
||||
case 'ticket_bulk_status':
|
||||
requireAuth();
|
||||
if ($method !== 'POST') break;
|
||||
$input = json_decode(file_get_contents('php://input'), true);
|
||||
$ids = $input['ids'] ?? [];
|
||||
$newStatus = $input['status'] ?? '';
|
||||
$validStatuses = ['uusi','kasittelyssa','odottaa','ratkaistu','suljettu'];
|
||||
if (!in_array($newStatus, $validStatuses)) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['error' => 'Virheellinen tila']);
|
||||
break;
|
||||
}
|
||||
$tickets = json_decode(file_get_contents(TICKETS_FILE), true) ?: [];
|
||||
$changed = 0;
|
||||
foreach ($tickets as &$t) {
|
||||
if (in_array($t['id'], $ids)) {
|
||||
$t['status'] = $newStatus;
|
||||
$t['updated'] = date('Y-m-d H:i:s');
|
||||
$changed++;
|
||||
}
|
||||
}
|
||||
unset($t);
|
||||
file_put_contents(TICKETS_FILE, json_encode($tickets, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
|
||||
addLog('ticket_status', '', '', "Massapäivitys: $changed tikettiä → $newStatus");
|
||||
echo json_encode(['success' => true, 'changed' => $changed]);
|
||||
break;
|
||||
|
||||
case 'ticket_bulk_delete':
|
||||
requireAuth();
|
||||
if ($method !== 'POST') break;
|
||||
$input = json_decode(file_get_contents('php://input'), true);
|
||||
$ids = $input['ids'] ?? [];
|
||||
$tickets = json_decode(file_get_contents(TICKETS_FILE), true) ?: [];
|
||||
$before = count($tickets);
|
||||
$tickets = array_values(array_filter($tickets, fn($t) => !in_array($t['id'], $ids)));
|
||||
$deleted = $before - count($tickets);
|
||||
file_put_contents(TICKETS_FILE, json_encode($tickets, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
|
||||
addLog('ticket_delete', '', '', "Massapoisto: $deleted tikettiä");
|
||||
echo json_encode(['success' => true, 'deleted' => $deleted]);
|
||||
break;
|
||||
|
||||
case 'ticket_rule_delete':
|
||||
requireAuth();
|
||||
if ($method !== 'POST') break;
|
||||
$input = json_decode(file_get_contents('php://input'), true);
|
||||
$ruleId = $input['id'] ?? '';
|
||||
$config = loadConfig();
|
||||
$rules = $config['ticket_rules'] ?? [];
|
||||
$config['ticket_rules'] = array_values(array_filter($rules, fn($r) => $r['id'] !== $ruleId));
|
||||
file_put_contents(DATA_DIR . '/config.json', json_encode($config, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
|
||||
echo json_encode(['success' => true]);
|
||||
break;
|
||||
|
||||
default:
|
||||
http_response_code(404);
|
||||
echo json_encode(['error' => 'Tuntematon toiminto']);
|
||||
|
||||
Reference in New Issue
Block a user