Add QR report uploader
This commit is contained in:
260
application/controllers/tools/Qr_report_uploader.php
Normal file
260
application/controllers/tools/Qr_report_uploader.php
Normal file
@@ -0,0 +1,260 @@
|
||||
<?php
|
||||
|
||||
class Qr_report_uploader extends MY_Controller
|
||||
{
|
||||
var $db_onedev;
|
||||
var $db_log;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db_onedev = $this->load->database('onedev', true);
|
||||
$this->db_log = $this->load->database('one_lab_log', true);
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
echo "QR report uploader tool";
|
||||
}
|
||||
|
||||
public function run($limit = 10)
|
||||
{
|
||||
$limit = (int)$limit;
|
||||
if ($limit <= 0) {
|
||||
$limit = 10;
|
||||
}
|
||||
|
||||
$endpointUrl = $this->get_active_endpoint_url();
|
||||
if ($endpointUrl === '') {
|
||||
$this->reply_result([
|
||||
'status' => 'ERR',
|
||||
'message' => 'QR_ReportEndpointUrl aktif tidak ditemukan.',
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
$rows = $this->get_pending_rows($limit);
|
||||
$summary = [
|
||||
'endpoint_url' => $endpointUrl,
|
||||
'limit' => $limit,
|
||||
'total_pending' => count($rows),
|
||||
'uploaded' => 0,
|
||||
'failed' => 0,
|
||||
'failed_permanent' => 0,
|
||||
'skipped' => 0,
|
||||
'details' => [],
|
||||
];
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$result = $this->process_row($row, $endpointUrl);
|
||||
$summary['details'][] = $result;
|
||||
|
||||
if ($result['status'] === 'uploaded') {
|
||||
$summary['uploaded']++;
|
||||
} elseif ($result['status'] === 'failed') {
|
||||
$summary['failed']++;
|
||||
} elseif ($result['status'] === 'failed_permanent') {
|
||||
$summary['failed_permanent']++;
|
||||
} else {
|
||||
$summary['skipped']++;
|
||||
}
|
||||
}
|
||||
|
||||
$this->reply_result([
|
||||
'status' => 'OK',
|
||||
'data' => $summary,
|
||||
]);
|
||||
}
|
||||
|
||||
private function get_pending_rows($limit)
|
||||
{
|
||||
$sql = "SELECT QR_PrintOutID,
|
||||
QR_PrintOutT_OrderHeaderID,
|
||||
QR_PrintOutUUID,
|
||||
QR_PrintOutVerifyURL,
|
||||
QR_PrintOutReportURL,
|
||||
QR_PrintOutUploadStatus,
|
||||
QR_PrintOutRetryCount
|
||||
FROM qr_printout
|
||||
WHERE QR_PrintOutIsActive = 1
|
||||
AND (QR_PrintOutUploadStatus = 'pending' OR QR_PrintOutUploadStatus = 'failed')
|
||||
AND QR_PrintOutRetryCount < 3
|
||||
AND QR_PrintOutReportURL IS NOT NULL
|
||||
AND QR_PrintOutReportURL != ''
|
||||
ORDER BY QR_PrintOutCreatedAt ASC
|
||||
LIMIT ?";
|
||||
$qry = $this->db_onedev->query($sql, [$limit]);
|
||||
if (!$qry) {
|
||||
$this->reply_result([
|
||||
'status' => 'ERR',
|
||||
'message' => 'Gagal mengambil daftar pending.',
|
||||
'db_error' => $this->db_onedev->error(),
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
return $qry->result_array();
|
||||
}
|
||||
|
||||
private function get_active_endpoint_url()
|
||||
{
|
||||
$sql = "SELECT QR_ReportEndpointUrl
|
||||
FROM qr_report_endpoint
|
||||
WHERE QR_ReportEndpointIsActive = 'Y'
|
||||
LIMIT 1";
|
||||
$qry = $this->db_onedev->query($sql);
|
||||
if (!$qry) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$row = $qry->row_array();
|
||||
if (!$row || empty($row['QR_ReportEndpointUrl'])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return rtrim($row['QR_ReportEndpointUrl'], '/') . '/';
|
||||
}
|
||||
|
||||
private function process_row($row, $endpointUrl)
|
||||
{
|
||||
$printoutID = (int)$row['QR_PrintOutID'];
|
||||
$orderHeaderID = (int)$row['QR_PrintOutT_OrderHeaderID'];
|
||||
$reportUrl = $row['QR_PrintOutReportURL'];
|
||||
|
||||
$pdfContent = $this->download_file($reportUrl);
|
||||
if ($pdfContent === false) {
|
||||
return $this->mark_failed($row, $orderHeaderID, '', 'DOWNLOAD_FAILED');
|
||||
}
|
||||
|
||||
if (strpos($pdfContent, '%PDF') === false) {
|
||||
return $this->mark_failed($row, $orderHeaderID, '', 'INVALID_PDF');
|
||||
}
|
||||
|
||||
$payload = json_encode([
|
||||
'qrcode' => $row['QR_PrintOutUUID'],
|
||||
'url' => $row['QR_PrintOutReportURL'],
|
||||
'type' => 'pdf',
|
||||
'name' => $row['QR_PrintOutUUID'] . '.pdf',
|
||||
'base64_file' => base64_encode($pdfContent),
|
||||
], JSON_UNESCAPED_SLASHES);
|
||||
|
||||
$response = $this->post_json($endpointUrl . 'upload', $payload, "secure-token-libCBxciByZXBvcnQ=");
|
||||
$decoded = json_decode($response, true);
|
||||
|
||||
if (is_array($decoded) && isset($decoded['status']) && $decoded['status'] === 'OK') {
|
||||
$this->log_insert_qr($printoutID, $orderHeaderID, $payload, $response);
|
||||
$this->db_onedev->query(
|
||||
"UPDATE qr_printout
|
||||
SET QR_PrintOutUploadStatus = 'uploaded',
|
||||
QR_PrintOutUploadedAt = NOW()
|
||||
WHERE QR_PrintOutID = ?",
|
||||
[$printoutID]
|
||||
);
|
||||
|
||||
return [
|
||||
'printout_id' => $printoutID,
|
||||
'order_header_id' => $orderHeaderID,
|
||||
'status' => 'uploaded',
|
||||
'message' => 'Upload berhasil',
|
||||
];
|
||||
}
|
||||
|
||||
return $this->mark_failed($row, $orderHeaderID, $payload, $response);
|
||||
}
|
||||
|
||||
private function mark_failed($row, $orderHeaderID, $payload, $response)
|
||||
{
|
||||
$printoutID = (int)$row['QR_PrintOutID'];
|
||||
$retry = (int)$row['QR_PrintOutRetryCount'] + 1;
|
||||
$newStatus = $retry >= 3 ? 'failed_permanent' : 'failed';
|
||||
|
||||
if ($payload !== '' || $response !== '') {
|
||||
$this->log_insert_qr($printoutID, $orderHeaderID, $payload, $response);
|
||||
}
|
||||
|
||||
$this->db_onedev->query(
|
||||
"UPDATE qr_printout
|
||||
SET QR_PrintOutUploadStatus = ?,
|
||||
QR_PrintOutRetryCount = ?,
|
||||
QR_PrintOutLastRetryAt = NOW()
|
||||
WHERE QR_PrintOutID = ?",
|
||||
[$newStatus, $retry, $printoutID]
|
||||
);
|
||||
|
||||
return [
|
||||
'printout_id' => $printoutID,
|
||||
'order_header_id' => $orderHeaderID,
|
||||
'status' => $newStatus,
|
||||
'message' => is_string($response) ? $response : 'Upload gagal',
|
||||
];
|
||||
}
|
||||
|
||||
private function log_insert_qr($printoutID, $orderHeaderID, $json, $response)
|
||||
{
|
||||
$sql = "INSERT INTO one_lab_log.log_qr_printout(
|
||||
Log_QR_PrintOutQR_PrintOutID,
|
||||
Log_QR_PrintOutT_OrderHeaderID,
|
||||
Log_QR_PrintOutJSON,
|
||||
Log_QR_PrintOutResponse,
|
||||
Log_QR_PrintOutDateTime
|
||||
) VALUES(?,?,?,?,NOW())";
|
||||
$this->db_onedev->query($sql, [
|
||||
$printoutID,
|
||||
$orderHeaderID,
|
||||
$json,
|
||||
$response,
|
||||
]);
|
||||
}
|
||||
|
||||
private function post_json($url, $data, $token)
|
||||
{
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
'Content-Type: application/json',
|
||||
'Content-Length: ' . strlen($data),
|
||||
"Authorization: Bearer {$token}",
|
||||
]);
|
||||
$result = curl_exec($ch);
|
||||
|
||||
if (curl_error($ch) !== '') {
|
||||
$error = curl_error($ch);
|
||||
curl_close($ch);
|
||||
return "ERROR API [{$url}] : {$error}";
|
||||
}
|
||||
|
||||
curl_close($ch);
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function download_file($url)
|
||||
{
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
|
||||
$result = curl_exec($ch);
|
||||
if (curl_error($ch)) {
|
||||
curl_close($ch);
|
||||
return false;
|
||||
}
|
||||
|
||||
curl_close($ch);
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function reply_result($result)
|
||||
{
|
||||
if ($this->input->is_cli_request()) {
|
||||
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . PHP_EOL;
|
||||
return;
|
||||
}
|
||||
|
||||
echo json_encode($result);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user