109 lines
4.2 KiB
PHP
109 lines
4.2 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
require_once __DIR__ . '/common.php';
|
|
|
|
api_require_method('POST');
|
|
$staff = api_require_staff();
|
|
api_require_permission($staff, 'create_ticket');
|
|
$pdo = get_db();
|
|
|
|
$body = api_request_body();
|
|
$requesterName = trim((string) ($body['requesterName'] ?? ''));
|
|
$requesterEmail = trim((string) ($body['requesterEmail'] ?? ''));
|
|
$subject = trim((string) ($body['subject'] ?? ''));
|
|
$message = sanitize_staff_html(trim((string) ($body['message'] ?? '')));
|
|
$departmentId = (int) ($body['departmentId'] ?? 0);
|
|
$priorityId = (int) ($body['priorityId'] ?? 0);
|
|
$assignedStaffId = ($body['assignedStaffId'] ?? null) !== null ? (int) $body['assignedStaffId'] : null;
|
|
$notifyCustomer = !empty($body['notifyCustomer']);
|
|
|
|
if ($requesterName === '') {
|
|
api_error(422, 'REQUESTER_NAME_REQUIRED', 'Bitte einen Namen angeben.');
|
|
}
|
|
if ($requesterEmail !== '' && !filter_var($requesterEmail, FILTER_VALIDATE_EMAIL)) {
|
|
api_error(422, 'INVALID_EMAIL', 'Bitte eine gültige E-Mail-Adresse angeben (oder leer lassen).');
|
|
}
|
|
if ($subject === '') {
|
|
api_error(422, 'SUBJECT_REQUIRED', 'Bitte einen Betreff angeben.');
|
|
}
|
|
if (trim(strip_tags($message)) === '') {
|
|
api_error(422, 'MESSAGE_REQUIRED', 'Bitte eine Beschreibung eingeben.');
|
|
}
|
|
if ($requesterEmail !== '' && is_banned($requesterEmail)) {
|
|
api_error(403, 'REQUESTER_BANNED', 'Diese E-Mail-Adresse steht auf der Sperrliste.');
|
|
}
|
|
|
|
$departmentIds = staff_department_ids($staff);
|
|
if ($departmentIds !== null && !in_array($departmentId, $departmentIds, true)) {
|
|
api_error(403, 'DEPARTMENT_FORBIDDEN', 'Auf diese Abteilung besteht kein Zugriff.');
|
|
}
|
|
|
|
$deptStmt = $pdo->prepare('SELECT * FROM departments WHERE id = ?');
|
|
$deptStmt->execute([$departmentId]);
|
|
$department = $deptStmt->fetch();
|
|
if ($department && empty($department['is_active'])) {
|
|
api_error(422, 'DEPARTMENT_INACTIVE', 'Diese Abteilung ist deaktiviert. Bitte eine aktive Abteilung wählen.');
|
|
}
|
|
if (!$department) {
|
|
api_error(422, 'INVALID_DEPARTMENT', 'Die Abteilung ist ungültig.');
|
|
}
|
|
|
|
$prioStmt = $pdo->prepare('SELECT * FROM priorities WHERE id = ?');
|
|
$prioStmt->execute([$priorityId]);
|
|
$priority = $prioStmt->fetch();
|
|
if (!$priority) {
|
|
api_error(422, 'INVALID_PRIORITY', 'Die Priorität ist ungültig.');
|
|
}
|
|
|
|
$sla = calc_sla_dates($priority, null, (int) $departmentId, null);
|
|
$now = db_now();
|
|
$ticketNumber = generate_ticket_number($pdo);
|
|
|
|
$userId = null;
|
|
if ($requesterEmail !== '') {
|
|
$userStmt = $pdo->prepare('SELECT id FROM users WHERE LOWER(email) = LOWER(?)');
|
|
$userStmt->execute([$requesterEmail]);
|
|
$userId = $userStmt->fetchColumn() ?: null;
|
|
}
|
|
|
|
$pdo->beginTransaction();
|
|
try {
|
|
$pdo->prepare(
|
|
'INSERT INTO tickets (ticket_number, subject, user_id, requester_name, requester_email, department_id,
|
|
priority_id, status, source, assigned_staff_id,
|
|
first_response_due_at, resolution_due_at, created_at, updated_at)
|
|
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)'
|
|
)->execute([
|
|
$ticketNumber, $subject, $userId, $requesterName, $requesterEmail, $departmentId,
|
|
$priorityId, 'open', 'staff', $assignedStaffId,
|
|
$sla['first_response_due_at'], $sla['resolution_due_at'], $now, $now,
|
|
]);
|
|
$ticketId = (int) $pdo->lastInsertId();
|
|
|
|
$pdo->prepare(
|
|
'INSERT INTO ticket_threads (ticket_id, author_type, staff_id, message, is_internal_note, created_at)
|
|
VALUES (?,?,?,?,0,?)'
|
|
)->execute([$ticketId, 'staff', $staff['id'], $message, $now]);
|
|
|
|
log_activity($pdo, $ticketId, (int) $staff['id'], 'Ticket durch Mitarbeiter erstellt (Mobile App)');
|
|
$pdo->commit();
|
|
} catch (Throwable $e) {
|
|
if ($pdo->inTransaction()) $pdo->rollBack();
|
|
throw $e;
|
|
}
|
|
|
|
if ($requesterEmail !== '' && $notifyCustomer) {
|
|
notify_customer_ticket_created([
|
|
'ticket_number' => $ticketNumber,
|
|
'subject' => $subject,
|
|
'requester_name' => $requesterName,
|
|
'requester_email' => $requesterEmail,
|
|
'department_id' => $departmentId,
|
|
'department_name' => $department['name'],
|
|
]);
|
|
}
|
|
|
|
$ticket = api_find_ticket($pdo, $staff, $ticketNumber);
|
|
webhook_dispatch($pdo, 'ticket.created', (int) $ticket['id']);
|
|
api_json(['ticket' => api_ticket_summary($ticket)], 201);
|