API
This commit is contained in:
@@ -7,9 +7,15 @@ require_once __DIR__ . '/resolve_table_operator.php';
|
|||||||
|
|
||||||
$kdsSecret = 'karczma_kuchnia';
|
$kdsSecret = 'karczma_kuchnia';
|
||||||
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
function verifyKdsSecret(): bool
|
||||||
|
{
|
||||||
|
global $kdsSecret;
|
||||||
$secret = isset($_GET['kds_secret']) ? trim((string) $_GET['kds_secret']) : '';
|
$secret = isset($_GET['kds_secret']) ? trim((string) $_GET['kds_secret']) : '';
|
||||||
if ($secret !== $kdsSecret) {
|
return $secret === $kdsSecret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||||
|
if (!verifyKdsSecret()) {
|
||||||
http_response_code(403);
|
http_response_code(403);
|
||||||
echo json_encode([
|
echo json_encode([
|
||||||
'status' => 'error',
|
'status' => 'error',
|
||||||
@@ -28,20 +34,25 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
|||||||
message_text,
|
message_text,
|
||||||
otwierajacy_imie,
|
otwierajacy_imie,
|
||||||
otwierajacy_nazwisko,
|
otwierajacy_nazwisko,
|
||||||
api_sent,
|
created_at,
|
||||||
status_kds,
|
updated_at
|
||||||
created_at
|
|
||||||
FROM guest_action_queue
|
FROM guest_action_queue
|
||||||
WHERE status_kds = 0
|
WHERE status_kds = 0
|
||||||
AND created_at >= DATE_SUB(NOW(), INTERVAL 12 HOUR)
|
|
||||||
ORDER BY created_at ASC
|
ORDER BY created_at ASC
|
||||||
LIMIT 50
|
LIMIT 100
|
||||||
");
|
");
|
||||||
$rows = $stmt->fetchAll();
|
$rows = $stmt->fetchAll();
|
||||||
|
|
||||||
|
foreach ($rows as &$row) {
|
||||||
|
$row['id'] = (int) $row['id'];
|
||||||
|
}
|
||||||
|
unset($row);
|
||||||
|
|
||||||
echo json_encode([
|
echo json_encode([
|
||||||
'status' => 'success',
|
'status' => 'success',
|
||||||
'count' => count($rows),
|
'count' => count($rows),
|
||||||
|
'polled_at' => date('Y-m-d H:i:s'),
|
||||||
|
'poll_interval_seconds' => 30,
|
||||||
'data' => $rows,
|
'data' => $rows,
|
||||||
], JSON_UNESCAPED_UNICODE);
|
], JSON_UNESCAPED_UNICODE);
|
||||||
} catch (Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
@@ -54,6 +65,70 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'PATCH') {
|
||||||
|
if (!verifyKdsSecret()) {
|
||||||
|
http_response_code(403);
|
||||||
|
echo json_encode([
|
||||||
|
'status' => 'error',
|
||||||
|
'message' => 'Forbidden',
|
||||||
|
], JSON_UNESCAPED_UNICODE);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$rawBody = file_get_contents('php://input');
|
||||||
|
$data = json_decode($rawBody, true);
|
||||||
|
if (!is_array($data)) {
|
||||||
|
http_response_code(400);
|
||||||
|
echo json_encode([
|
||||||
|
'status' => 'error',
|
||||||
|
'message' => 'Invalid JSON payload',
|
||||||
|
], JSON_UNESCAPED_UNICODE);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$id = isset($data['id']) ? (int) $data['id'] : 0;
|
||||||
|
if ($id < 1) {
|
||||||
|
http_response_code(422);
|
||||||
|
echo json_encode([
|
||||||
|
'status' => 'error',
|
||||||
|
'message' => 'id is required',
|
||||||
|
], JSON_UNESCAPED_UNICODE);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$pdo = getAnalyticsPdo();
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
UPDATE guest_action_queue
|
||||||
|
SET status_kds = 1
|
||||||
|
WHERE id = :id
|
||||||
|
AND status_kds = 0
|
||||||
|
");
|
||||||
|
$stmt->execute([':id' => $id]);
|
||||||
|
|
||||||
|
if ($stmt->rowCount() === 0) {
|
||||||
|
http_response_code(404);
|
||||||
|
echo json_encode([
|
||||||
|
'status' => 'error',
|
||||||
|
'message' => 'Queue item not found or already dismissed',
|
||||||
|
], JSON_UNESCAPED_UNICODE);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'status' => 'success',
|
||||||
|
'id' => $id,
|
||||||
|
], JSON_UNESCAPED_UNICODE);
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode([
|
||||||
|
'status' => 'error',
|
||||||
|
'message' => 'Queue dismiss failed',
|
||||||
|
], JSON_UNESCAPED_UNICODE);
|
||||||
|
}
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||||
http_response_code(405);
|
http_response_code(405);
|
||||||
echo json_encode([
|
echo json_encode([
|
||||||
|
|||||||
+6
-10
@@ -100,7 +100,7 @@ requireAdminAuth(true);
|
|||||||
<div class="card col-12">
|
<div class="card col-12">
|
||||||
<h3>Ostatnie otwarcia stron stolików</h3>
|
<h3>Ostatnie otwarcia stron stolików</h3>
|
||||||
<table>
|
<table>
|
||||||
<thead><tr><th>Kiedy</th><th>Stolik</th><th>Strefa</th><th>Menu</th><th>Urządzenie</th><th>Przeglądarka</th><th>IP</th></tr></thead>
|
<thead><tr><th>Kiedy</th><th>Stolik</th><th>Strefa</th><th>W aplikacji</th><th>Urządzenie</th><th>Przeglądarka</th><th>IP</th></tr></thead>
|
||||||
<tbody id="recentOpensBody"><tr><td colspan="7" class="muted">Ładowanie...</td></tr></tbody>
|
<tbody id="recentOpensBody"><tr><td colspan="7" class="muted">Ładowanie...</td></tr></tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@@ -129,7 +129,7 @@ requireAdminAuth(true);
|
|||||||
<li><strong>Przywołania kelnera</strong> - ile razy gość poprosił o podejście obsługi.</li>
|
<li><strong>Przywołania kelnera</strong> - ile razy gość poprosił o podejście obsługi.</li>
|
||||||
<li><strong>Top stoliki</strong> - które stoliki są najczęściej otwierane i używane.</li>
|
<li><strong>Top stoliki</strong> - które stoliki są najczęściej otwierane i używane.</li>
|
||||||
<li><strong>Lejek użycia</strong> - droga użytkownika: wejście -> start aplikacji -> menu -> rachunek.</li>
|
<li><strong>Lejek użycia</strong> - droga użytkownika: wejście -> start aplikacji -> menu -> rachunek.</li>
|
||||||
<li><strong>Kolumna Menu (✓/✗)</strong> - ✓ oznacza wejście do menu w tej sesji; ✗ oznacza brak wejścia do menu (w tym zatrzymanie na geo).</li>
|
<li><strong>Kolumna W aplikacji (✓/✗)</strong> - ✓ oznacza przejście przez ekran lokalizacji (widok statusu zamówień); ✗ oznacza zatrzymanie na geo.</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -200,15 +200,11 @@ requireAdminAuth(true);
|
|||||||
const when = dt && !Number.isNaN(dt.getTime()) ? dt.toLocaleString("pl-PL") : (r.created_at || "-");
|
const when = dt && !Number.isNaN(dt.getTime()) ? dt.toLocaleString("pl-PL") : (r.created_at || "-");
|
||||||
const device = r.device_type || "-";
|
const device = r.device_type || "-";
|
||||||
const browser = r.browser || "-";
|
const browser = r.browser || "-";
|
||||||
const enteredMenu = Number(r.entered_menu) === 1;
|
|
||||||
const reachedApp = Number(r.reached_app) === 1;
|
const reachedApp = Number(r.reached_app) === 1;
|
||||||
let menuCell = `<span class="status-fail" title="Zatrzymano na ekranie lokalizacji">✗</span>`;
|
const appCell = reachedApp
|
||||||
if (enteredMenu) {
|
? `<span class="status-ok" title="Przeszedł lokalizację — widok statusu zamówień">✓</span>`
|
||||||
menuCell = `<span class="status-ok" title="Wszedł do menu">✓</span>`;
|
: `<span class="status-fail" title="Zatrzymano na ekranie lokalizacji">✗</span>`;
|
||||||
} else if (reachedApp) {
|
return `<tr><td>${when}</td><td>${r.table_id || "-"}</td><td>${r.zone || "-"}</td><td>${appCell}</td><td>${device}</td><td>${browser}</td><td>${r.ip_address || "-"}</td></tr>`;
|
||||||
menuCell = `<span class="status-fail" title="Wszedł do aplikacji, ale nie otworzył menu">✗</span>`;
|
|
||||||
}
|
|
||||||
return `<tr><td>${when}</td><td>${r.table_id || "-"}</td><td>${r.zone || "-"}</td><td>${menuCell}</td><td>${device}</td><td>${browser}</td><td>${r.ip_address || "-"}</td></tr>`;
|
|
||||||
}).join("")
|
}).join("")
|
||||||
: `<tr><td colspan="7" class="muted">Brak danych</td></tr>`;
|
: `<tr><td colspan="7" class="muted">Brak danych</td></tr>`;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
<?php
|
||||||
|
require_once __DIR__ . '/../config/database.php';
|
||||||
|
|
||||||
|
$pdo = getAnalyticsPdo();
|
||||||
|
|
||||||
|
try {
|
||||||
|
$pdo->exec('DROP TABLE IF EXISTS kds_orders');
|
||||||
|
echo "Usunięto tabelę kds_orders (jeśli istniała).\n";
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
echo "Uwaga: nie udało się usunąć kds_orders: {$e->getMessage()}\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdo->exec("DELETE FROM guest_action_queue WHERE message_text LIKE '[DEMO]%'");
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
INSERT INTO guest_action_queue (
|
||||||
|
table_id,
|
||||||
|
message_type,
|
||||||
|
message_text,
|
||||||
|
otwierajacy_imie,
|
||||||
|
otwierajacy_nazwisko,
|
||||||
|
api_sent,
|
||||||
|
status_kds,
|
||||||
|
created_at
|
||||||
|
) VALUES (
|
||||||
|
:table_id,
|
||||||
|
:message_type,
|
||||||
|
:message_text,
|
||||||
|
:otwierajacy_imie,
|
||||||
|
:otwierajacy_nazwisko,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
NOW(3)
|
||||||
|
)
|
||||||
|
");
|
||||||
|
|
||||||
|
$samples = [
|
||||||
|
[
|
||||||
|
'table_id' => '12',
|
||||||
|
'message_type' => 'waiter_call',
|
||||||
|
'message_text' => '[DEMO] Przywołanie kelnera',
|
||||||
|
'otwierajacy_imie' => 'Jan',
|
||||||
|
'otwierajacy_nazwisko' => 'Kowalski',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'table_id' => 'taras 5',
|
||||||
|
'message_type' => 'bill_request',
|
||||||
|
'message_text' => '[DEMO] Prośba o rachunek | forma płatności: karta | dokument: paragon',
|
||||||
|
'otwierajacy_imie' => 'Anna',
|
||||||
|
'otwierajacy_nazwisko' => 'Nowak',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($samples as $sample) {
|
||||||
|
$stmt->execute($sample);
|
||||||
|
echo "Wstawiono demo: {$sample['message_type']} / stolik {$sample['table_id']}\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "KDS feed: GET api/guest_action_queue.php?kds_secret=karczma_kuchnia\n";
|
||||||
Reference in New Issue
Block a user