130 lines
4.1 KiB
PHP
130 lines
4.1 KiB
PHP
<?php
|
|
// api/executive.php
|
|
session_start();
|
|
require_once dirname(__DIR__) . '/config/database.php';
|
|
require_once dirname(__DIR__) . '/models/Job.php';
|
|
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
|
|
if (!isset($_SESSION['user_id'])) {
|
|
echo json_encode(['success' => false, 'message' => 'Unauthorized']);
|
|
exit;
|
|
}
|
|
|
|
$conn = Database::getInstance();
|
|
$period = $_GET['period'] ?? 'today';
|
|
|
|
try {
|
|
$start_date = '';
|
|
$end_date = date('Y-m-d') . ' 23:59:59';
|
|
|
|
if ($period === 'week') {
|
|
$start_date = date('Y-m-d', strtotime('-7 days')) . ' 00:00:00';
|
|
} elseif ($period === 'month') {
|
|
$start_date = date('Y-m-01') . ' 00:00:00';
|
|
} else { // today
|
|
$start_date = date('Y-m-d') . ' 00:00:00';
|
|
}
|
|
|
|
// 1. SLA & Times
|
|
$sla_target = 15;
|
|
|
|
$query_times = "SELECT
|
|
TIMESTAMPDIFF(MINUTE, created_at, accepted_at) as wait_time,
|
|
TIMESTAMPDIFF(MINUTE, accepted_at, completed_at) as service_time
|
|
FROM jobs
|
|
WHERE status = 'completed' AND created_at BETWEEN :start AND :end";
|
|
$stmt_times = $conn->prepare($query_times);
|
|
$stmt_times->bindParam(':start', $start_date);
|
|
$stmt_times->bindParam(':end', $end_date);
|
|
$stmt_times->execute();
|
|
|
|
$completed_jobs = $stmt_times->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
$total_wait = 0;
|
|
$total_service = 0;
|
|
$sla_met = 0;
|
|
|
|
foreach ($completed_jobs as $job) {
|
|
$w = max(0, (int)$job['wait_time']);
|
|
$s = max(0, (int)$job['service_time']);
|
|
|
|
$total_wait += $w;
|
|
$total_service += $s;
|
|
|
|
if ($w <= $sla_target) {
|
|
$sla_met++;
|
|
}
|
|
}
|
|
|
|
$completed_count = count($completed_jobs);
|
|
$avg_wait = $completed_count > 0 ? round($total_wait / $completed_count) : 0;
|
|
$avg_service = $completed_count > 0 ? round($total_service / $completed_count) : 0;
|
|
$sla_percent = $completed_count > 0 ? round(($sla_met / $completed_count) * 100) : 100;
|
|
|
|
// 2. Trend Data (7 days)
|
|
$trend_data = [];
|
|
$trend_labels = [];
|
|
for ($i = 6; $i >= 0; $i--) {
|
|
$d = date('Y-m-d', strtotime("-$i days"));
|
|
$thai_days = ['อา.', 'จ.', 'อ.', 'พ.', 'พฤ.', 'ศ.', 'ส.'];
|
|
$day_index = date('w', strtotime($d));
|
|
|
|
$trend_labels[] = $thai_days[$day_index];
|
|
|
|
$q = "SELECT COUNT(*) as cnt FROM jobs WHERE DATE(created_at) = :d";
|
|
$s = $conn->prepare($q);
|
|
$s->bindParam(':d', $d);
|
|
$s->execute();
|
|
$trend_data[] = $s->fetch(PDO::FETCH_ASSOC)['cnt'];
|
|
}
|
|
|
|
// 3. Department Workload
|
|
$query_dept = "SELECT d.name, COUNT(j.id) as count
|
|
FROM jobs j
|
|
JOIN departments d ON j.from_department_id = d.id
|
|
WHERE j.created_at BETWEEN :start AND :end
|
|
GROUP BY d.id
|
|
ORDER BY count DESC
|
|
LIMIT 5";
|
|
$stmt_dept = $conn->prepare($query_dept);
|
|
$stmt_dept->bindParam(':start', $start_date);
|
|
$stmt_dept->bindParam(':end', $end_date);
|
|
$stmt_dept->execute();
|
|
|
|
$dept_labels = [];
|
|
$dept_data = [];
|
|
while ($row = $stmt_dept->fetch(PDO::FETCH_ASSOC)) {
|
|
$name = mb_strlen($row['name'], 'UTF-8') > 15 ? mb_substr($row['name'], 0, 15, 'UTF-8') . '...' : $row['name'];
|
|
$dept_labels[] = $name;
|
|
$dept_data[] = (int)$row['count'];
|
|
}
|
|
|
|
$jobModel = new Job();
|
|
$staffPerformance = $jobModel->getStaffPerformance($period);
|
|
|
|
echo json_encode([
|
|
'success' => true,
|
|
'kpi' => [
|
|
'sla_percent' => $sla_percent,
|
|
'avg_wait_time' => $avg_wait,
|
|
'avg_service_time' => $avg_service
|
|
],
|
|
'charts' => [
|
|
'trend' => [
|
|
'labels' => $trend_labels,
|
|
'data' => $trend_data
|
|
],
|
|
'departments' => [
|
|
'labels' => $dept_labels,
|
|
'data' => $dept_data
|
|
]
|
|
],
|
|
'staff_performance' => $staffPerformance
|
|
]);
|
|
exit;
|
|
|
|
} catch (Exception $e) {
|
|
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
|
|
}
|